feat(db): Added database setup and basic types (#5)
All checks were successful
CI / Format (push) Successful in 3s
CI / Clippy (push) Successful in 2m21s
CI / Security Audit (push) Successful in 1m44s
CI / Tests (push) Successful in 2m55s
CI / Deploy (push) Successful in 2s

Co-authored-by: Sharang Parnerkar <parnerkarsharang@gmail.com>
Reviewed-on: #5
This commit was merged in pull request #5.
This commit is contained in:
2026-02-20 14:58:14 +00:00
parent 5ce600e32b
commit e68f840f2b
23 changed files with 1375 additions and 480 deletions

View File

@@ -1,8 +1,8 @@
use std::{ops::Deref, sync::Arc};
use axum::extract::FromRequestParts;
use serde::{Deserialize, Serialize};
/// Cheap-to-clone handle to per-session user data.
#[derive(Debug, Clone)]
pub struct UserState(Arc<UserStateInner>);
@@ -19,39 +19,28 @@ impl From<UserStateInner> for UserState {
}
}
/// Per-session user data stored in the tower-sessions session store.
///
/// Persisted across requests for the lifetime of the session.
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct UserStateInner {
/// Subject in Oauth
/// Subject identifier from Keycloak (unique user ID).
pub sub: String,
/// Access Token
/// OAuth2 access token.
pub access_token: String,
/// Refresh Token
/// OAuth2 refresh token.
pub refresh_token: String,
/// User
/// Basic user profile.
pub user: User,
}
/// Basic user profile stored alongside the session.
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct User {
/// Email
/// Email address.
pub email: String,
/// Avatar Url
/// Display name (preferred_username or full name from Keycloak).
pub name: String,
/// Avatar / profile picture URL.
pub avatar_url: String,
}
impl<S> FromRequestParts<S> for UserState
where
S: std::marker::Sync + std::marker::Send,
{
type Rejection = super::Error;
async fn from_request_parts(
parts: &mut axum::http::request::Parts,
_: &S,
) -> Result<Self, super::Error> {
parts
.extensions
.get::<UserState>()
.cloned()
.ok_or(super::Error::StateError("Unable to get extension".into()))
}
}