summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrtkay123 <dev@kanjala.com>2025-07-26 18:42:32 +0200
committerrtkay123 <dev@kanjala.com>2025-07-26 18:42:32 +0200
commit236876f1d0539ac22a3977fd8599933725ad0f90 (patch)
tree5c216d71ac065621348ce05e7c6c7f7ce81c85d3
parentcf77963db4f2b55048d725bd6250a490b0b82d64 (diff)
downloadsellershut-236876f1d0539ac22a3977fd8599933725ad0f90.tar.bz2
sellershut-236876f1d0539ac22a3977fd8599933725ad0f90.zip
feat(auth): create user
-rw-r--r--contrib/docker-compose/init-db/init.sql1
-rw-r--r--crates/auth/auth.toml6
-rw-r--r--crates/auth/src/cnfg.rs1
-rw-r--r--crates/auth/src/main.rs21
-rw-r--r--crates/auth/src/server/grpc/interceptor.rs8
-rw-r--r--crates/auth/src/server/routes/authorised.rs24
-rw-r--r--crates/auth/src/state.rs21
7 files changed, 64 insertions, 18 deletions
diff --git a/contrib/docker-compose/init-db/init.sql b/contrib/docker-compose/init-db/init.sql
index 54ec5d6..a8b648d 100644
--- a/contrib/docker-compose/init-db/init.sql
+++ b/contrib/docker-compose/init-db/init.sql
@@ -1,2 +1,3 @@
create database sellershut;
create database auth;
+create database profiles;
diff --git a/crates/auth/auth.toml b/crates/auth/auth.toml
index 4c1c0ca..3af6fc0 100644
--- a/crates/auth/auth.toml
+++ b/crates/auth/auth.toml
@@ -5,13 +5,13 @@ port = 1304
[nats]
hosts = ["nats://localhost:4222"]
+[misc]
+profile-endpoint = "http://localhost:1610"
+
[misc.oauth]
session-lifespan = 3600 # seconds
jwt-encoding-key = "secret"
-[misc.nats]
-subject = "users"
-
[misc.oauth.discord]
# query param for provider
redirect-url = "http://127.0.0.1:1304/auth/authorised?provider=discord"
diff --git a/crates/auth/src/cnfg.rs b/crates/auth/src/cnfg.rs
index c895d05..9b765a5 100644
--- a/crates/auth/src/cnfg.rs
+++ b/crates/auth/src/cnfg.rs
@@ -4,6 +4,7 @@ use serde::Deserialize;
#[serde(rename_all = "kebab-case")]
pub struct LocalConfig {
pub oauth: OauthConfig,
+ pub profile_endpoint: String,
}
#[derive(Deserialize, Clone)]
diff --git a/crates/auth/src/main.rs b/crates/auth/src/main.rs
index 53a18dd..3f68e2f 100644
--- a/crates/auth/src/main.rs
+++ b/crates/auth/src/main.rs
@@ -10,13 +10,17 @@ use std::net::{Ipv6Addr, SocketAddr};
use clap::Parser;
use reqwest::header::CONTENT_TYPE;
use sellershut_core::auth::{AUTH_FILE_DESCRIPTOR_SET, auth_server::AuthServer};
-use stack_up::{Configuration, Services, tracing::Tracing};
+use stack_up::{Configuration, tracing::Tracing};
use tokio::{signal, task::AbortHandle};
use tonic::service::Routes;
use tower::{make::Shared, steer::Steer};
use tracing::{info, trace};
-use crate::{error::AppError, server::grpc::interceptor::MyInterceptor, state::AppState};
+use crate::{
+ error::AppError,
+ server::grpc::interceptor::MyInterceptor,
+ state::{AppState, Services},
+};
/// auth-service
#[derive(Parser, Debug)]
@@ -50,16 +54,21 @@ async fn main() -> Result<(), AppError> {
let _tracing = Tracing::builder().build(&config.monitoring);
- let services = Services::builder()
+ let mut services = stack_up::Services::builder()
.postgres(&config.database)
.await
.inspect_err(|e| tracing::error!("database: {e}"))?
.build();
+ let postgres = services
+ .postgres
+ .take()
+ .ok_or_else(|| anyhow::anyhow!("database is not ready"))?;
+
+ let services = Services { postgres };
+
trace!("running migrations");
- sqlx::migrate!("./migrations")
- .run(&services.postgres)
- .await?;
+ sqlx::migrate!("./migrations").run(&services.postgres).await?;
let (state, deletion_task) = AppState::create(services, &config).await?;
diff --git a/crates/auth/src/server/grpc/interceptor.rs b/crates/auth/src/server/grpc/interceptor.rs
index 6fbe7fa..155a306 100644
--- a/crates/auth/src/server/grpc/interceptor.rs
+++ b/crates/auth/src/server/grpc/interceptor.rs
@@ -1,6 +1,12 @@
-use tonic::{Status, service::Interceptor};
+use tonic::{
+ Status,
+ service::{Interceptor, interceptor::InterceptedService},
+ transport::Channel,
+};
use tracing::Span;
+pub type Intercepted = InterceptedService<Channel, MyInterceptor>;
+
#[derive(Clone, Copy)]
pub struct MyInterceptor;
diff --git a/crates/auth/src/server/routes/authorised.rs b/crates/auth/src/server/routes/authorised.rs
index 83f73cf..32dd929 100644
--- a/crates/auth/src/server/routes/authorised.rs
+++ b/crates/auth/src/server/routes/authorised.rs
@@ -9,6 +9,7 @@ use axum::{
use axum_extra::{TypedHeader, headers};
use oauth2::{AuthorizationCode, TokenResponse};
use reqwest::{StatusCode, header::SET_COOKIE};
+use sellershut_core::profile::CreateUserRequest;
use serde::{Deserialize, Serialize};
use sqlx::types::uuid;
use time::OffsetDateTime;
@@ -136,12 +137,6 @@ pub async fn login_authorised(
",
uuid,
user_data.email,
- // user_data.avatar.as_ref().map(|value| {
- // format!(
- // "https://cdn.discordapp.com/avatars/{}/{value}",
- // user_data.id
- // )
- // })
)
.fetch_one(&mut *transaction)
.await?;
@@ -185,6 +180,17 @@ pub async fn login_authorised(
),
)?;
+ let user_request = CreateUserRequest{
+ email: user_data.email.to_owned(),
+ avatar: user_data.avatar.as_ref().map(|value| {
+ format!(
+ "https://cdn.discordapp.com/avatars/{}/{value}",
+ user_data.id
+ )
+ })
+ };
+
+
store
.create(&mut Record {
id: session_id,
@@ -210,6 +216,10 @@ pub async fn login_authorised(
let cookie = format!("{SESSION_COOKIE}={session_id}; SameSite=Lax; HttpOnly; Secure; Path=/");
+ let mut profile_client = state.profile_client.clone();
+ let resp = profile_client.create_user(user_request).await?.into_inner();
+ let user_id = resp.temp_id;
+
let mut headers = HeaderMap::new();
headers.insert(
SET_COOKIE,
@@ -218,5 +228,5 @@ pub async fn login_authorised(
transaction.commit().await?;
- Ok((headers, Redirect::to("/")).into_response())
+ Ok((headers, Redirect::to(&format!("/?user={user_id}&token={token}"))).into_response())
}
diff --git a/crates/auth/src/state.rs b/crates/auth/src/state.rs
index 927823c..5905948 100644
--- a/crates/auth/src/state.rs
+++ b/crates/auth/src/state.rs
@@ -1,15 +1,20 @@
use std::{ops::Deref, sync::Arc};
-use stack_up::{Configuration, Services};
+use sellershut_core::profile::profile_client::ProfileClient;
+use sqlx::PgPool;
+use stack_up::Configuration;
use tokio::task::JoinHandle;
+use tonic::transport::Endpoint;
use tower_sessions::{CachingSessionStore, ExpiredDeletion, session_store};
use tower_sessions_moka_store::MokaStore;
use tower_sessions_sqlx_store::PostgresStore;
+use tracing::error;
use crate::{
client::{OauthClient, discord::discord_client},
cnfg::LocalConfig,
error::AppError,
+ server::grpc::interceptor::{Intercepted, MyInterceptor},
};
#[derive(Clone)]
@@ -23,12 +28,18 @@ impl Deref for AppHandle {
}
}
+#[derive(Clone)]
+pub struct Services {
+ pub postgres: PgPool,
+}
+
pub struct AppState {
pub services: Services,
pub local_config: LocalConfig,
pub discord_client: OauthClient,
pub http_client: reqwest::Client,
pub session_store: CachingSessionStore<MokaStore, PostgresStore>,
+ pub profile_client: ProfileClient<Intercepted>,
}
impl AppState {
@@ -52,6 +63,13 @@ impl AppState {
let discord_client = discord_client(&local_config.oauth.discord)?;
+ let channel = Endpoint::new(local_config.profile_endpoint.to_string())?
+ .connect()
+ .await
+ .inspect_err(|e| error!("could not connect to profile service: {e}"))?;
+
+ let profile_client = ProfileClient::with_interceptor(channel, MyInterceptor);
+
Ok((
AppHandle(Arc::new(Self {
services,
@@ -59,6 +77,7 @@ impl AppState {
discord_client,
http_client: reqwest::Client::new(),
session_store: store,
+ profile_client,
})),
deletion_task,
))