From 096630708d27bca324cc83f1a830d4b9bbbb7917 Mon Sep 17 00:00:00 2001 From: rtkay123 Date: Tue, 15 Jul 2025 08:56:52 +0200 Subject: feat: read identifiers from config --- Cargo.lock | 1 + Cargo.toml | 1 + sellershut.toml | 4 ++++ src/cnfg.rs | 8 ++++++++ src/entity/user.rs | 35 ++++++++++++++++++++++++++++++++--- src/main.rs | 3 ++- src/server/routes.rs | 2 +- src/server/routes/users/get_outbox.rs | 4 ++-- src/server/routes/users/get_user.rs | 4 ++-- src/server/routes/users/webfinger.rs | 4 ++-- src/state.rs | 17 ++++++++++++----- 11 files changed, 67 insertions(+), 16 deletions(-) create mode 100644 src/cnfg.rs diff --git a/Cargo.lock b/Cargo.lock index eaa2246..d8adbd6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2053,6 +2053,7 @@ dependencies = [ "clap", "config", "serde", + "serde_json", "sqlx", "stack-up", "tokio", diff --git a/Cargo.toml b/Cargo.toml index 4dd7120..08bf4ed 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,6 +15,7 @@ axum = { version = "0.8.4", features = ["macros"] } clap = { version = "4.5.41", features = ["derive"] } config = { version = "0.15.13", default-features = false, features = ["toml"] } serde = { version = "1.0.219", features = ["derive"] } +serde_json = "1.0.140" sqlx = { version = "0.8.6", features = ["macros", "migrate", "runtime-tokio", "time", "tls-rustls", "uuid"] } tokio = { version = "1.46.1", features = ["macros", "rt-multi-thread", "signal"] } tower-http = { version = "0.6.6", features = ["trace"] } diff --git a/sellershut.toml b/sellershut.toml index d1f54ce..77a8a25 100644 --- a/sellershut.toml +++ b/sellershut.toml @@ -2,6 +2,10 @@ env = "development" port = 2210 +[misc] +hostname = "localhost" +instance-name = "sellershut" + [monitoring] log-level = "sellershut=trace,info" diff --git a/src/cnfg.rs b/src/cnfg.rs new file mode 100644 index 0000000..4ad7a06 --- /dev/null +++ b/src/cnfg.rs @@ -0,0 +1,8 @@ +use serde::Deserialize; + +#[derive(Deserialize, Clone)] +#[serde(rename_all = "kebab-case")] +pub struct LocalConfig { + pub hostname: String, + pub instance_name: String, +} diff --git a/src/entity/user.rs b/src/entity/user.rs index da22f00..aa1207d 100644 --- a/src/entity/user.rs +++ b/src/entity/user.rs @@ -8,7 +8,7 @@ use activitypub_federation::{ }; use async_trait::async_trait; use serde::{Deserialize, Serialize}; -use stack_up::Services; +use stack_up::{Environment, Services}; use tracing::trace; use url::Url; use uuid::Uuid; @@ -56,10 +56,39 @@ impl TryFrom for User { } impl User { - pub async fn new(username: &str, services: &Services) -> Result { + pub async fn new( + username: &str, + hostname: &str, + services: &Services, + environment: Environment, + ) -> Result { + trace!(username = ?username, "checking for system user"); + + let user = sqlx::query_as!( + DbUser, + "select * from account where username = $1 and local = $2", + username, + true + ) + .fetch_optional(&services.postgres) + .await?; + + if let Some(user) = user { + trace!(username = ?username, "system user exists"); + return Self::try_from(user); + } else { + trace!(username = ?username, "system user does not exist. creating"); + } + trace!("creating keypair for new user"); let keys = generate_actor_keypair()?; - let stub = &format!("http://localhost/users/{username}"); + let stub = &format!( + "{}://{hostname}/users/{username}", + match environment { + Environment::Development => "http", + Environment::Production => "https", + } + ); let id = Uuid::now_v7(); trace!(id = ?id, "creating a new user"); diff --git a/src/main.rs b/src/main.rs index 68aedc4..f0540bf 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,3 +1,4 @@ +mod cnfg; mod entity; mod error; mod server; @@ -44,7 +45,7 @@ async fn main() -> Result<(), AppError> { .inspect_err(|e| error!("database: {e}"))? .build(); - let state = AppState::new(services, &config).await?; + let state = AppState::create(services, &config).await?; let addr = SocketAddr::from((Ipv6Addr::UNSPECIFIED, config.application.port)); diff --git a/src/server/routes.rs b/src/server/routes.rs index 85cc100..9e1b9a9 100644 --- a/src/server/routes.rs +++ b/src/server/routes.rs @@ -26,7 +26,7 @@ mod tests { #[sqlx::test] async fn health_check(pool: PgPool) { let services = Services { postgres: pool }; - let state = AppState::new(services, &test_config()).await.unwrap(); + let state = AppState::create(services, &test_config()).await.unwrap(); let app = server::router(state); let response = app diff --git a/src/server/routes/users/get_outbox.rs b/src/server/routes/users/get_outbox.rs index d5a4af5..75467af 100644 --- a/src/server/routes/users/get_outbox.rs +++ b/src/server/routes/users/get_outbox.rs @@ -40,7 +40,7 @@ mod tests { #[sqlx::test] async fn get_user(pool: PgPool) { let services = Services { postgres: pool }; - let state = AppState::new(services, &test_config()).await.unwrap(); + let state = AppState::create(services, &test_config()).await.unwrap(); let app = server::router(state); let response = app @@ -59,7 +59,7 @@ mod tests { #[sqlx::test] async fn get_user_not_found(pool: PgPool) { let services = Services { postgres: pool }; - let state = AppState::new(services, &test_config()).await.unwrap(); + let state = AppState::create(services, &test_config()).await.unwrap(); let app = server::router(state); let response = app diff --git a/src/server/routes/users/get_user.rs b/src/server/routes/users/get_user.rs index 4079731..fc2803e 100644 --- a/src/server/routes/users/get_user.rs +++ b/src/server/routes/users/get_user.rs @@ -63,7 +63,7 @@ mod tests { #[sqlx::test] async fn get_user(pool: PgPool) { let services = Services { postgres: pool }; - let state = AppState::new(services, &test_config()).await.unwrap(); + let state = AppState::create(services, &test_config()).await.unwrap(); let app = server::router(state); let response = app @@ -82,7 +82,7 @@ mod tests { #[sqlx::test] async fn get_user_not_found(pool: PgPool) { let services = Services { postgres: pool }; - let state = AppState::new(services, &test_config()).await.unwrap(); + let state = AppState::create(services, &test_config()).await.unwrap(); let app = server::router(state); let response = app diff --git a/src/server/routes/users/webfinger.rs b/src/server/routes/users/webfinger.rs index 8efeda6..c395d59 100644 --- a/src/server/routes/users/webfinger.rs +++ b/src/server/routes/users/webfinger.rs @@ -49,7 +49,7 @@ mod tests { #[sqlx::test] async fn webfinger_ok(pool: PgPool) { let services = Services { postgres: pool }; - let state = AppState::new(services, &test_config()).await.unwrap(); + let state = AppState::create(services, &test_config()).await.unwrap(); let app = server::router(state); let response = app @@ -68,7 +68,7 @@ mod tests { #[sqlx::test] async fn webfinger_err(pool: PgPool) { let services = Services { postgres: pool }; - let state = AppState::new(services, &test_config()).await.unwrap(); + let state = AppState::create(services, &test_config()).await.unwrap(); let app = server::router(state); let response = app diff --git a/src/state.rs b/src/state.rs index 5ced62e..1ae6caa 100644 --- a/src/state.rs +++ b/src/state.rs @@ -3,7 +3,7 @@ use std::{ops::Deref, sync::Arc}; use activitypub_federation::config::FederationConfig; use stack_up::{Configuration, Environment, Services}; -use crate::{entity::user::User, error::AppError}; +use crate::{cnfg::LocalConfig, entity::user::User, error::AppError}; #[derive(Clone)] pub struct AppHandle(Arc); @@ -21,15 +21,22 @@ pub struct AppState { } impl AppState { - pub async fn new( + pub async fn create( services: Services, configuration: &Configuration, ) -> Result, AppError> { - let user = User::new("sellershut", &services).await?; - let domain = "localhost"; + let warden_config: LocalConfig = serde_json::from_value(configuration.misc.clone())?; + + let user = User::new( + &warden_config.instance_name, + &warden_config.hostname, + &services, + configuration.application.env, + ) + .await?; let config = FederationConfig::builder() - .domain(domain) + .domain(&warden_config.hostname) .signed_fetch_actor(&user) .app_data(AppHandle(Arc::new(Self { services }))) // .url_verifier(Box::new(MyUrlVerifier())) -- cgit v1.2.3