diff options
| author | rtkay123 <dev@kanjala.com> | 2026-04-12 14:17:49 +0200 |
|---|---|---|
| committer | rtkay123 <dev@kanjala.com> | 2026-04-12 14:17:49 +0200 |
| commit | d9375b82c3bb3a917e1795be4dcd7ed849b32ca2 (patch) | |
| tree | 308245b0e578179bf0ff047ddc453ab1934a0795 | |
| parent | 34b2f8ff6a99471fbb72ed7c52a92b92645b0652 (diff) | |
| download | sellershut-d9375b82c3bb3a917e1795be4dcd7ed849b32ca2.tar.bz2 sellershut-d9375b82c3bb3a917e1795be4dcd7ed849b32ca2.zip | |
build: migrations
| -rw-r--r-- | Cargo.lock | 9 | ||||
| -rw-r--r-- | Cargo.toml | 2 | ||||
| -rw-r--r-- | crates/api-auth/src/discord/mod.rs | 14 | ||||
| -rw-r--r-- | crates/api-auth/src/lib.rs | 1 | ||||
| -rw-r--r-- | crates/api-core/src/models/user.rs | 10 | ||||
| -rw-r--r-- | crates/sellershut/Cargo.toml | 4 | ||||
| -rw-r--r-- | crates/sellershut/src/server/api/routes/auth/authorised.rs | 4 | ||||
| -rw-r--r-- | crates/users/Cargo.toml | 3 | ||||
| -rw-r--r-- | crates/users/src/error.rs | 13 | ||||
| -rw-r--r-- | crates/users/src/lib.rs | 17 | ||||
| -rw-r--r-- | migrations/20260412121213_profile.sql | 5 | ||||
| -rw-r--r-- | migrations/20260412121235_account.sql | 12 |
12 files changed, 74 insertions, 20 deletions
@@ -3040,6 +3040,15 @@ dependencies = [ ] [[package]] +name = "users" +version = "0.0.0" +dependencies = [ + "api-core", + "async-trait", + "thiserror 2.0.18", +] + +[[package]] name = "utf8_iter" version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -9,9 +9,11 @@ documentation = "https://books.kanjala.com/sellershut" homepage = "https://git.kanjala.com/sellershut" [workspace.dependencies] +anyhow = "1.0.102" api-core = { path = "./crates/api-core", version = "0.0.0" } async-trait = "0.1.89" axum = "0.8.8" +clap = "4.6.0" futures-util = "0.3.32" redis = { version = "1.1.0", default-features = false } reqwest = { version = "0.13.2", default-features = false } diff --git a/crates/api-auth/src/discord/mod.rs b/crates/api-auth/src/discord/mod.rs index ffa5a68..ba26f8b 100644 --- a/crates/api-auth/src/discord/mod.rs +++ b/crates/api-auth/src/discord/mod.rs @@ -1,4 +1,5 @@ use api_core::models::user::User; +use async_session::Session; use async_trait::async_trait; use serde::{Deserialize, Serialize}; use sh_util::cache::RedisManager; @@ -25,7 +26,11 @@ impl TryFrom<DiscordUser> for User { match (&user_data.email, user_data.verified) { (None, _) => Err(AuthError::MissingEmail), (_, false) => Err(AuthError::EmailNotVerified), - (Some(_), true) => Ok(Self {}), + (Some(_), true) => Ok(Self { + id: user_data.id, + username: user_data.username, + email: user_data.email.ok_or(AuthError::MissingEmail)?, + }), } } } @@ -67,7 +72,10 @@ impl OauthDriver for AuthServiceDiscord { crate::util::create_oauth_session(&self.client, &self.cache, &["identify", "email"]).await } - async fn save_session(&self, _user: &User) -> Result<(), AuthError> { - todo!() + async fn save_session(&self, user: &User) -> Result<(), AuthError> { + let mut session = Session::new(); + session.insert("user", user).expect("serialisable user"); + + Ok(()) } } diff --git a/crates/api-auth/src/lib.rs b/crates/api-auth/src/lib.rs index 24b966c..234a85b 100644 --- a/crates/api-auth/src/lib.rs +++ b/crates/api-auth/src/lib.rs @@ -2,6 +2,7 @@ pub mod discord; pub mod client; +#[cfg(feature = "discord")] pub(crate) mod util; mod error; diff --git a/crates/api-core/src/models/user.rs b/crates/api-core/src/models/user.rs index 7b70234..b05c41c 100644 --- a/crates/api-core/src/models/user.rs +++ b/crates/api-core/src/models/user.rs @@ -1,4 +1,8 @@ -use serde::Deserialize; +use serde::{Deserialize, Serialize}; -#[derive(Deserialize)] -pub struct User {} +#[derive(Deserialize, Serialize)] +pub struct User { + pub id: String, + pub username: String, + pub email: String, +} diff --git a/crates/sellershut/Cargo.toml b/crates/sellershut/Cargo.toml index 1151373..2580a73 100644 --- a/crates/sellershut/Cargo.toml +++ b/crates/sellershut/Cargo.toml @@ -9,13 +9,13 @@ homepage.workspace = true description = "A federated marketplace platform" [dependencies] -anyhow = "1.0.102" +anyhow.workspace = true api-auth = { path = "../api-auth", features = ["discord", "utoipa"] } api-core = { workspace = true, features = ["auth-discord", "utoipa"] } axum = { version = "0.8.8", features = ["macros"] } axum-extra = { version = "0.12.5", features = ["typed-header"] } bon = "3.9.1" -clap = { version = "4.6.0", features = ["derive", "env"] } +clap = { workspace = true, features = ["derive", "env"] } reqwest.workspace = true secrecy = { workspace = true, features = ["serde"] } serde = { workspace = true, features = ["derive"] } diff --git a/crates/sellershut/src/server/api/routes/auth/authorised.rs b/crates/sellershut/src/server/api/routes/auth/authorised.rs index a7e4c90..4a646a9 100644 --- a/crates/sellershut/src/server/api/routes/auth/authorised.rs +++ b/crates/sellershut/src/server/api/routes/auth/authorised.rs @@ -59,7 +59,9 @@ pub async fn authorised( client.validate_session(&cookie, ¶ms.state).await?; - let _user = client.get_user(&state.http_client, ¶ms.code).await?; + let user = client.get_user(&state.http_client, ¶ms.code).await?; + + client.save_session(&user).await?; Ok(String::default()) } diff --git a/crates/users/Cargo.toml b/crates/users/Cargo.toml index e21ca6c..4c0098e 100644 --- a/crates/users/Cargo.toml +++ b/crates/users/Cargo.toml @@ -8,3 +8,6 @@ documentation.workspace = true homepage.workspace = true [dependencies] +api-core = { workspace = true, features = ["users"] } +async-trait.workspace = true +thiserror.workspace = true diff --git a/crates/users/src/error.rs b/crates/users/src/error.rs new file mode 100644 index 0000000..1ff28ee --- /dev/null +++ b/crates/users/src/error.rs @@ -0,0 +1,13 @@ +use thiserror::Error; + +#[derive(Error, Debug)] +pub enum UserError { + #[error("data store disconnected")] + Disconnect(#[from] std::io::Error), + #[error("the data for key `{0}` is not available")] + Redaction(String), + #[error("invalid header (expected {expected:?}, found {found:?})")] + InvalidHeader { expected: String, found: String }, + #[error("unknown data store error")] + Unknown, +} diff --git a/crates/users/src/lib.rs b/crates/users/src/lib.rs index b93cf3f..9a268e7 100644 --- a/crates/users/src/lib.rs +++ b/crates/users/src/lib.rs @@ -1,14 +1,9 @@ -pub fn add(left: u64, right: u64) -> u64 { - left + right -} +pub mod error; +use api_core::models::user::User; -#[cfg(test)] -mod tests { - use super::*; +use crate::error::UserError; - #[test] - fn it_works() { - let result = add(2, 2); - assert_eq!(result, 4); - } +#[async_trait::async_trait] +pub trait UsersDriver: Send + Sync { + async fn get_user_by_email(&self, email: &str) -> Result<Option<User>, UserError>; } diff --git a/migrations/20260412121213_profile.sql b/migrations/20260412121213_profile.sql new file mode 100644 index 0000000..8a6a39a --- /dev/null +++ b/migrations/20260412121213_profile.sql @@ -0,0 +1,5 @@ +create table profile ( + data jsonb not null, + id text generated always as (data->>'id') stored, + primary key (id) +); diff --git a/migrations/20260412121235_account.sql b/migrations/20260412121235_account.sql new file mode 100644 index 0000000..583a0c4 --- /dev/null +++ b/migrations/20260412121235_account.sql @@ -0,0 +1,12 @@ +create extension if not exists citext; + +create table account ( + provider_id text not null, + provider_user_id text not null, + email citext not null, + user_data jsonb not null, + user_id text not null references profile(id) on delete cascade, + primary key (provider_id, provider_user_id) +); + +create index account_email_idx on account (email); |
