diff options
| author | rtkay123 <dev@kanjala.com> | 2026-02-09 17:54:46 +0200 |
|---|---|---|
| committer | rtkay123 <dev@kanjala.com> | 2026-02-09 17:54:46 +0200 |
| commit | a9630ecdc459068ca51ee2d7be3837d609840842 (patch) | |
| tree | 3bf6d1da4aefbaa351a36a0c63228bcdcf6b4917 /lib | |
| parent | d2339ca8869af12c0fd8cf6fc87986f06b487de9 (diff) | |
| download | sellershut-a9630ecdc459068ca51ee2d7be3837d609840842.tar.bz2 sellershut-a9630ecdc459068ca51ee2d7be3837d609840842.zip | |
feat: connect to database
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/auth-service/Cargo.toml | 1 | ||||
| -rw-r--r-- | lib/auth-service/src/service/mod.rs | 31 | ||||
| -rw-r--r-- | lib/shared-svc/Cargo.toml | 6 | ||||
| -rw-r--r-- | lib/shared-svc/src/cache/key.rs | 27 | ||||
| -rw-r--r-- | lib/shared-svc/src/cache/mod.rs | 3 | ||||
| -rw-r--r-- | lib/shared-svc/src/database/mod.rs | 16 | ||||
| -rw-r--r-- | lib/shared-svc/src/lib.rs | 9 |
7 files changed, 82 insertions, 11 deletions
diff --git a/lib/auth-service/Cargo.toml b/lib/auth-service/Cargo.toml index e972312..d35d17e 100644 --- a/lib/auth-service/Cargo.toml +++ b/lib/auth-service/Cargo.toml @@ -11,6 +11,7 @@ async-session = "3.0.0" async-trait.workspace = true oauth2 = "5.0.0" secrecy = "0.10.3" +serde_json = "1.0.149" shared-svc = { workspace = true, features = ["cache"] } sqlx.workspace = true thiserror.workspace = true diff --git a/lib/auth-service/src/service/mod.rs b/lib/auth-service/src/service/mod.rs index 3d45523..5150221 100644 --- a/lib/auth-service/src/service/mod.rs +++ b/lib/auth-service/src/service/mod.rs @@ -1,17 +1,20 @@ use async_session::{Result, Session, SessionStore}; use async_trait::async_trait; -use shared_svc::cache::RedisManager; -use tracing::instrument; +use shared_svc::cache::{CacheKey, RedisManager, redis::AsyncCommands}; +use sqlx::PgPool; +use tracing::{debug, instrument}; #[derive(Debug, Clone)] pub struct AuthService { cache: RedisManager, + database: PgPool, } impl AuthService { - pub fn new(cache: &RedisManager) -> Self { + pub fn new(cache: &RedisManager, database: &PgPool) -> Self { Self { cache: cache.clone(), + database: database.clone(), } } } @@ -32,20 +35,32 @@ impl SessionStore for AuthService { #[doc = ""] #[doc = " The return value is the value of the cookie to store for the"] #[doc = " user that represents this session"] - #[instrument(skip(self))] + #[instrument(err(Debug), skip(self, session), fields(id = session.id()))] async fn store_session(&self, session: Session) -> Result<Option<String>> { - todo!() + debug!("storing session"); + let mut client = self.cache.get().await?; + let bytes = serde_json::to_vec(&session)?; + client + .set_ex::<_, _, ()>(CacheKey::Session(session.id()), bytes, 3600) + .await?; + Ok(session.into_cookie_value()) } #[doc = " Remove a session from the session store"] - #[instrument(skip(self))] + #[instrument(err(Debug), skip(self, session), fields(id = session.id()))] async fn destroy_session(&self, session: Session) -> Result { - todo!() + debug!("destroying session"); + let mut client = self.cache.get().await?; + client.del::<_, ()>(CacheKey::Session(session.id())).await?; + Ok(()) } #[doc = " Empties the entire store, destroying all sessions"] #[instrument(skip(self))] async fn clear_store(&self) -> Result { - todo!() + debug!("clearing store"); + let mut client = self.cache.get().await?; + client.del::<_, ()>(CacheKey::Session("").key()).await?; + Ok(()) } } diff --git a/lib/shared-svc/Cargo.toml b/lib/shared-svc/Cargo.toml index d95d3ef..85a1c82 100644 --- a/lib/shared-svc/Cargo.toml +++ b/lib/shared-svc/Cargo.toml @@ -11,18 +11,20 @@ bb8-redis = { version = "0.26.0", optional = true } log = "0.4.29" redis = { version = "1.0.3", optional = true } secrecy.workspace = true +sqlx = { workspace = true, optional = true } thiserror.workspace = true tokio = { workspace = true, optional = true } tracing.workspace = true url.workspace = true [features] -default = [] +default = ["cache", "database"] cache = [ - "bb8-redis", + "dep:bb8-redis", "redis/cluster-async", "redis/connection-manager", "redis/sentinel", "redis/tokio-comp", "tokio/sync" ] +database = ["dep:sqlx"] diff --git a/lib/shared-svc/src/cache/key.rs b/lib/shared-svc/src/cache/key.rs new file mode 100644 index 0000000..756b7d0 --- /dev/null +++ b/lib/shared-svc/src/cache/key.rs @@ -0,0 +1,27 @@ +use redis::{ToRedisArgs, ToSingleRedisArg}; + +#[derive(Clone, Copy)] +pub enum CacheKey<'a> { + Session(&'a str), +} + +impl CacheKey<'_> { + pub fn key(&self) -> &str { + match self { + CacheKey::Session(_) => "session:*", + } + } +} + +impl ToRedisArgs for CacheKey<'_> { + fn write_redis_args<W>(&self, out: &mut W) + where + W: ?Sized + redis::RedisWrite, + { + out.write_arg_fmt(match self { + CacheKey::Session(id) => format!("session:{id}"), + }) + } +} + +impl ToSingleRedisArg for CacheKey<'_> {} diff --git a/lib/shared-svc/src/cache/mod.rs b/lib/shared-svc/src/cache/mod.rs index cd15463..90cab04 100644 --- a/lib/shared-svc/src/cache/mod.rs +++ b/lib/shared-svc/src/cache/mod.rs @@ -1,6 +1,9 @@ mod cluster; mod config; +mod key; mod sentinel; +pub use key::*; +pub use redis; pub use sentinel::SentinelConfig; pub use config::*; diff --git a/lib/shared-svc/src/database/mod.rs b/lib/shared-svc/src/database/mod.rs new file mode 100644 index 0000000..bbc1ba3 --- /dev/null +++ b/lib/shared-svc/src/database/mod.rs @@ -0,0 +1,16 @@ +use sqlx::PgPool; +use tracing::{debug, error}; +use url::Url; + +use crate::ServiceError; + +pub async fn connect(url: &Url, pool_size: u32) -> Result<PgPool, ServiceError> { + let host = url.host_str(); + debug!(host = host, "connecting to database"); + + Ok(sqlx::postgres::PgPoolOptions::new() + .max_connections(pool_size) + .connect(url.as_str()) + .await + .inspect_err(|e| error!("{e}"))?) +} diff --git a/lib/shared-svc/src/lib.rs b/lib/shared-svc/src/lib.rs index 92d9c32..d4852a5 100644 --- a/lib/shared-svc/src/lib.rs +++ b/lib/shared-svc/src/lib.rs @@ -1,12 +1,19 @@ #[cfg(feature = "cache")] pub mod cache; +#[cfg(feature = "database")] +pub mod database; + use thiserror::Error; #[derive(Error, Debug)] pub enum ServiceError { - #[error("data store disconnected")] + #[error("cache error")] + #[cfg(feature = "cache")] Cache(#[from] redis::RedisError), + #[error("database error")] + #[cfg(feature = "database")] + Database(#[from] sqlx::Error), #[error("the data for key `{0}` is not available")] Redaction(String), #[error("invalid header (expected {expected:?}, found {found:?})")] |
