From 8398104fd50b236619a0c20b7c9b7991ea855917 Mon Sep 17 00:00:00 2001 From: rtkay123 Date: Sat, 26 Jul 2025 10:19:44 +0200 Subject: feat(api): connect to auth service --- crates/auth/auth.toml | 6 ++++++ crates/auth/src/main.rs | 6 +----- crates/auth/src/server/routes/authorised.rs | 5 ++--- crates/sellershut/Cargo.toml | 2 ++ crates/sellershut/sellershut.toml | 1 + crates/sellershut/src/cnfg.rs | 1 + crates/sellershut/src/server/middleware.rs | 1 + .../src/server/middleware/grpc_interceptor.rs | 16 ++++++++++++++++ .../sellershut/src/server/middleware/sign_request.rs | 16 +++++++++++++++- crates/sellershut/src/state.rs | 19 ++++++++++++++++++- 10 files changed, 63 insertions(+), 10 deletions(-) create mode 100644 crates/sellershut/src/server/middleware/grpc_interceptor.rs diff --git a/crates/auth/auth.toml b/crates/auth/auth.toml index 17a696f..4c1c0ca 100644 --- a/crates/auth/auth.toml +++ b/crates/auth/auth.toml @@ -2,10 +2,16 @@ env = "development" port = 1304 +[nats] +hosts = ["nats://localhost:4222"] + [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/main.rs b/crates/auth/src/main.rs index 72f991f..53a18dd 100644 --- a/crates/auth/src/main.rs +++ b/crates/auth/src/main.rs @@ -16,11 +16,7 @@ use tonic::service::Routes; use tower::{make::Shared, steer::Steer}; use tracing::{info, trace}; -use crate::{ - error::AppError, - server::{grpc::interceptor::MyInterceptor, routes::authorised::AuthRequest}, - state::AppState, -}; +use crate::{error::AppError, server::grpc::interceptor::MyInterceptor, state::AppState}; /// auth-service #[derive(Parser, Debug)] diff --git a/crates/auth/src/server/routes/authorised.rs b/crates/auth/src/server/routes/authorised.rs index 50fcfc8..83f73cf 100644 --- a/crates/auth/src/server/routes/authorised.rs +++ b/crates/auth/src/server/routes/authorised.rs @@ -91,6 +91,8 @@ pub async fn login_authorised( .await .context("failed to deserialise response as JSON")?; + dbg!(&user_data); + let user_data: User = serde_json::from_value(user_data)?; if !user_data.verified { @@ -122,10 +124,8 @@ pub async fn login_authorised( .await?; let user = if let Some(user) = user { - println!("some"); user } else { - println!("none"); let uuid = uuid::Uuid::now_v7(); let user = sqlx::query_as!( DbUser, @@ -170,7 +170,6 @@ pub async fn login_authorised( let claims = Claims { sub: user.id, - // Mandatory expiry time as UTC timestamp exp: exp.unix_timestamp(), iss: "sellershut".to_owned(), sid: session_id.to_string(), diff --git a/crates/sellershut/Cargo.toml b/crates/sellershut/Cargo.toml index 34e7b8b..d742086 100644 --- a/crates/sellershut/Cargo.toml +++ b/crates/sellershut/Cargo.toml @@ -19,12 +19,14 @@ enum_delegate = "0.2.0" futures-util.workspace = true nanoid.workspace = true openssl = "0.10.73" +sellershut-core = { workspace = true, features = ["auth"] } serde = { workspace = true, features = ["derive"] } serde_json.workspace = true sha2 = "0.10.9" sqlx = { workspace = true, features = ["macros", "migrate", "runtime-tokio", "time", "tls-rustls", "uuid"] } time = { workspace = true, features = ["parsing", "serde"] } tokio = { workspace = true, features = ["macros", "rt-multi-thread", "signal"] } +tonic.workspace = true tower = { workspace = true, features = ["util"] } tower-http = { workspace = true, features = ["map-request-body", "trace", "util"] } tracing.workspace = true diff --git a/crates/sellershut/sellershut.toml b/crates/sellershut/sellershut.toml index 77a8a25..76f354a 100644 --- a/crates/sellershut/sellershut.toml +++ b/crates/sellershut/sellershut.toml @@ -5,6 +5,7 @@ port = 2210 [misc] hostname = "localhost" instance-name = "sellershut" +auth-endpoint = "http://localhost:1304" [monitoring] log-level = "sellershut=trace,info" diff --git a/crates/sellershut/src/cnfg.rs b/crates/sellershut/src/cnfg.rs index 4ad7a06..82cd34b 100644 --- a/crates/sellershut/src/cnfg.rs +++ b/crates/sellershut/src/cnfg.rs @@ -5,4 +5,5 @@ use serde::Deserialize; pub struct LocalConfig { pub hostname: String, pub instance_name: String, + pub auth_endpoint: String, } diff --git a/crates/sellershut/src/server/middleware.rs b/crates/sellershut/src/server/middleware.rs index aa73518..161b9a8 100644 --- a/crates/sellershut/src/server/middleware.rs +++ b/crates/sellershut/src/server/middleware.rs @@ -1 +1,2 @@ +pub mod grpc_interceptor; pub mod sign_request; diff --git a/crates/sellershut/src/server/middleware/grpc_interceptor.rs b/crates/sellershut/src/server/middleware/grpc_interceptor.rs new file mode 100644 index 0000000..f8759cf --- /dev/null +++ b/crates/sellershut/src/server/middleware/grpc_interceptor.rs @@ -0,0 +1,16 @@ +use tonic::{ + Status, + service::{Interceptor, interceptor::InterceptedService}, + transport::Channel, +}; + +pub type Intercepted = InterceptedService; + +#[derive(Clone, Copy)] +pub struct MyInterceptor; + +impl Interceptor for MyInterceptor { + fn call(&mut self, mut request: tonic::Request<()>) -> Result, Status> { + Ok(request) + } +} diff --git a/crates/sellershut/src/server/middleware/sign_request.rs b/crates/sellershut/src/server/middleware/sign_request.rs index 4eb3bd3..5c9663b 100644 --- a/crates/sellershut/src/server/middleware/sign_request.rs +++ b/crates/sellershut/src/server/middleware/sign_request.rs @@ -4,7 +4,7 @@ use activitypub_federation::{config::FederationConfig, traits::Object}; use axum::{ body::Body, extract::Request, - http::{HeaderValue, StatusCode}, + http::{HeaderValue, StatusCode, header::AUTHORIZATION}, response::Response, }; use futures_util::future::BoxFuture; @@ -64,6 +64,13 @@ where fn call(&mut self, request: Request) -> Self::Future { let mut inner = self.inner.clone(); let uri = request.uri().clone(); + + let token = request + .headers() + .get(AUTHORIZATION) + .and_then(|value| value.to_str().ok().map(ToOwned::to_owned)) + .unwrap_or_default(); + let (parts, body) = request.into_parts(); let state = self.state.to_request_data(); let domain = self.state.domain().to_owned(); @@ -74,6 +81,13 @@ where *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; Ok(response) }; + + if token.is_empty() { + let mut response = axum::response::Response::default(); + *response.status_mut() = StatusCode::UNAUTHORIZED; + return Ok(response); + } + let bytes = match axum::body::to_bytes(body, usize::MAX).await { Ok(b) => b, Err(e) => { diff --git a/crates/sellershut/src/state.rs b/crates/sellershut/src/state.rs index 3ee3248..959d0f3 100644 --- a/crates/sellershut/src/state.rs +++ b/crates/sellershut/src/state.rs @@ -1,9 +1,17 @@ use std::{ops::Deref, sync::Arc}; use activitypub_federation::config::FederationConfig; +use sellershut_core::auth::auth_client::AuthClient; use stack_up::{Configuration, Environment, Services}; +use tonic::transport::Endpoint; +use tracing::error; -use crate::{cnfg::LocalConfig, entity::user::User, error::AppError}; +use crate::{ + cnfg::LocalConfig, + entity::user::User, + error::AppError, + server::middleware::grpc_interceptor::{Intercepted, MyInterceptor}, +}; #[derive(Clone)] pub struct AppHandle(Arc); @@ -20,6 +28,7 @@ pub struct AppState { pub services: Services, pub environment: Environment, pub protocol: Arc, + pub auth_client: AuthClient, } impl AppState { @@ -37,6 +46,13 @@ impl AppState { ) .await?; + let channel = Endpoint::new(hut_config.auth_endpoint.to_string())? + .connect() + .await + .inspect_err(|e| error!("could not connect to auth service: {e}"))?; + + let auth_client = AuthClient::with_interceptor(channel, MyInterceptor); + let config = FederationConfig::builder() .domain(&hut_config.hostname) .signed_fetch_actor(&user) @@ -48,6 +64,7 @@ impl AppState { Environment::Production => "https", } .into(), + auth_client, }))) // .url_verifier(Box::new(MyUrlVerifier())) .debug(configuration.application.env == Environment::Development) -- cgit v1.2.3