diff options
-rw-r--r-- | contrib/docker-compose/init-db/init.sql | 1 | ||||
-rw-r--r-- | crates/auth/auth.toml | 6 | ||||
-rw-r--r-- | crates/auth/src/cnfg.rs | 1 | ||||
-rw-r--r-- | crates/auth/src/main.rs | 21 | ||||
-rw-r--r-- | crates/auth/src/server/grpc/interceptor.rs | 8 | ||||
-rw-r--r-- | crates/auth/src/server/routes/authorised.rs | 24 | ||||
-rw-r--r-- | crates/auth/src/state.rs | 21 |
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, )) |