diff options
| -rw-r--r-- | Cargo.lock | 2 | ||||
| -rw-r--r-- | Cargo.toml | 3 | ||||
| -rw-r--r-- | misc/compose.yaml | 12 | ||||
| -rw-r--r-- | src/config/mod.rs | 1 | ||||
| -rw-r--r-- | src/server/driver/auth.rs | 29 | ||||
| -rw-r--r-- | src/server/entity/auth/mod.rs | 8 | ||||
| -rw-r--r-- | src/server/entity/mod.rs | 1 | ||||
| -rw-r--r-- | src/server/mod.rs | 5 | ||||
| -rw-r--r-- | src/server/routes/auth/mod.rs | 26 |
9 files changed, 81 insertions, 6 deletions
@@ -2783,7 +2783,9 @@ dependencies = [ "rand 0.9.2", "secrecy", "serde", + "serde_json", "sqlx 0.8.6", + "time", "tokio", "toml", "tower", @@ -16,6 +16,7 @@ oauth2 = "5.0.0" rand = "0.9.2" secrecy = "0.10.3" serde = "1.0.228" +serde_json = "1.0.149" thiserror = "2.0.18" tracing = "0.1.44" url = "2.5.8" @@ -42,6 +43,8 @@ clap = { version = "4.5.56", features = ["derive", "env"] } oauth2.workspace = true secrecy = { workspace = true, features = ["serde"] } serde = { workspace = true, features = ["derive"] } +serde_json.workspace = true +time = "0.3.46" tokio = { version = "1.49.0", features = ["rt-multi-thread", "macros", "signal"] } toml = "0.9.11" tower = "0.5.3" diff --git a/misc/compose.yaml b/misc/compose.yaml index 1fccb81..8ef5d6c 100644 --- a/misc/compose.yaml +++ b/misc/compose.yaml @@ -27,6 +27,18 @@ services: - 8080:8080 networks: - sellershut + depends_on: + database: + condition: service_healthy + restart: true + + cache: + image: docker.io/valkey/valkey:9.0.1-alpine + restart: always + ports: + - 6379:6379 + networks: + - sellershut volumes: db: diff --git a/src/config/mod.rs b/src/config/mod.rs index 0c53f08..7495b22 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -195,7 +195,6 @@ impl Config { if let Some(db_url) = &cli.db { dsn.url = db_url.clone(); } - } } diff --git a/src/server/driver/auth.rs b/src/server/driver/auth.rs index 28e9285..958698b 100644 --- a/src/server/driver/auth.rs +++ b/src/server/driver/auth.rs @@ -4,9 +4,10 @@ use async_trait::async_trait; use bon::Builder; use oauth2::{AuthUrl, ClientId, ClientSecret, EndpointNotSet, EndpointSet, RedirectUrl, TokenUrl}; use secrecy::{ExposeSecret, SecretString}; +use time::OffsetDateTime; use tracing::{instrument, trace}; -use crate::server::driver::Services; +use crate::server::{driver::Services, entity}; pub(super) static COOKIE_NAME: &str = "SESSION"; pub(super) static CSRF_TOKEN: &str = "csrf_token"; @@ -48,9 +49,31 @@ impl SessionStore for Services { #[instrument(skip(self))] async fn load_session(&self, cookie_value: String) -> Result<Option<Session>> { let id = Session::id_from_cookie_value(&cookie_value)?; - let mut connection = self.database.acquire().await?; - todo!() + let result = sqlx::query_as!( + entity::auth::Session, + "select + * + from + session + where + id = $1 + and + ( + expires + is null + or + expires > $2 + ) + ", + id, + OffsetDateTime::now_utc() + ) + .fetch_optional(&self.database) + .await? + .map(|value| serde_json::from_str(&value.session)); + + Ok(result.transpose()?) } #[instrument(skip(self, session), fields(id = session.id()))] diff --git a/src/server/entity/auth/mod.rs b/src/server/entity/auth/mod.rs new file mode 100644 index 0000000..8791048 --- /dev/null +++ b/src/server/entity/auth/mod.rs @@ -0,0 +1,8 @@ +use time::OffsetDateTime; + +pub struct Session { + pub id: String, + pub expires: Option<OffsetDateTime>, + pub ap_id: String, + pub session: String, +} diff --git a/src/server/entity/mod.rs b/src/server/entity/mod.rs new file mode 100644 index 0000000..0e4a05d --- /dev/null +++ b/src/server/entity/mod.rs @@ -0,0 +1 @@ +pub mod auth; diff --git a/src/server/mod.rs b/src/server/mod.rs index 7357957..b4a591c 100644 --- a/src/server/mod.rs +++ b/src/server/mod.rs @@ -1,4 +1,5 @@ pub mod driver; +pub mod entity; pub mod error; mod middleware; pub mod routes; @@ -49,7 +50,9 @@ pub async fn router(config: &Config, state: AppState) -> anyhow::Result<Router<( let stubs = OpenApiRouter::with_openapi(doc).routes(utoipa_axum::routes!(routes::health_check)); #[cfg(feature = "oauth")] - let stubs = stubs.routes(utoipa_axum::routes!(routes::auth::auth)); + let stubs = stubs + .routes(utoipa_axum::routes!(routes::auth::authorised)) + .routes(utoipa_axum::routes!(routes::auth::auth)); let (router, _api) = stubs.split_for_parts(); diff --git a/src/server/routes/auth/mod.rs b/src/server/routes/auth/mod.rs index f0da7cd..485983a 100644 --- a/src/server/routes/auth/mod.rs +++ b/src/server/routes/auth/mod.rs @@ -55,9 +55,33 @@ pub async fn auth( Query(params): Query<Params>, data: Data<AppState>, ) -> Result<impl IntoResponse, AppError> { + match params.provider { + #[cfg(feature = "oauth-discord")] + OauthProvider::Discord => discord::discord_auth(data), + } + .await +} +#[utoipa::path( + method(get), + path = "/auth/authorised", + params( + Params + ), + tag = AUTH, + responses( + (status = OK, description = "Auth redirect url", body = str, content_type = "text/plain") + ) +)] +#[axum::debug_handler] +#[cfg(feature = "oauth")] +pub async fn authorised( + Query(params): Query<Params>, + data: Data<AppState>, +) -> Result<impl IntoResponse, AppError> { match params.provider { #[cfg(feature = "oauth-discord")] OauthProvider::Discord => discord::discord_auth(data), - }.await + } + .await } |
