conrad_core/
database.rs

1use crate::{errors::AuthError, User, UserId};
2use async_trait::async_trait;
3use std::error::Error;
4
5#[async_trait]
6pub trait DatabaseAdapter<U> {
7    async fn create_user_and_key(
8        &self,
9        user_attributes: &U,
10        key: &KeySchema,
11    ) -> Result<(), CreateUserError>;
12    async fn read_user(&self, user_id: &UserId) -> Result<User<U>, UserError>;
13    async fn create_session(&self, session_data: &SessionSchema) -> Result<(), CreateSessionError>;
14    async fn read_sessions(&self, user_id: &UserId) -> Result<Vec<SessionSchema>, GeneralError>;
15    async fn delete_session(&self, session_id: &str) -> Result<(), GeneralError>;
16    async fn read_session(&self, session_id: &str) -> Result<SessionSchema, SessionError>;
17    async fn read_key(&self, key_id: &str) -> Result<KeySchema, KeyError>;
18    async fn update_user(&self, user_id: &UserId, user_attributes: &U) -> Result<(), UserError>;
19    async fn delete_sessions_by_user_id(&self, user_id: &UserId) -> Result<(), GeneralError>;
20    async fn delete_keys(&self, user_id: &UserId) -> Result<(), GeneralError>;
21    async fn delete_user(&self, user_id: &UserId) -> Result<(), GeneralError>;
22    async fn create_key(&self, key: &KeySchema) -> Result<(), CreateKeyError>;
23    async fn delete_non_primary_key(&self, key_id: &str) -> Result<(), GeneralError>;
24    async fn read_keys_by_user_id(&self, user_id: &UserId) -> Result<Vec<KeySchema>, GeneralError>;
25    async fn update_key_password(
26        &self,
27        key_id: &str,
28        hashed_password: Option<&str>,
29    ) -> Result<(), KeyError>;
30    async fn read_session_and_user_by_session_id(
31        &self,
32        session_id: &str,
33    ) -> Result<DatabaseUserSession<U>, SessionError>;
34}
35
36#[derive(Clone, Debug)]
37pub struct KeySchema {
38    pub id: String,
39    pub hashed_password: Option<String>,
40    pub user_id: UserId,
41    pub primary_key: bool,
42    pub expires: Option<i64>,
43}
44
45#[derive(Clone, Debug)]
46pub struct SessionData {
47    pub session_id: String,
48    pub active_period_expires_at: i64,
49    pub idle_period_expires_at: i64,
50}
51
52#[derive(Clone, Debug)]
53pub struct SessionSchema {
54    pub session_data: SessionData,
55    pub user_id: UserId,
56}
57
58#[derive(Debug)]
59pub enum CreateUserError {
60    UserAlreadyExists,
61    DatabaseError(Box<dyn Error>),
62}
63
64#[derive(Debug)]
65pub enum UserError {
66    UserDoesNotExist,
67    DatabaseError(Box<dyn Error>),
68}
69
70#[derive(Debug, Clone)]
71pub struct DatabaseUserSession<U> {
72    pub user: User<U>,
73    pub session: SessionSchema,
74}
75
76#[derive(Debug)]
77pub enum SessionError {
78    SessionNotFound,
79    DatabaseError(Box<dyn Error>),
80}
81
82#[derive(Debug)]
83pub enum CreateSessionError {
84    InvalidUserId,
85    DuplicateSessionId,
86    DatabaseError(Box<dyn Error>),
87}
88
89#[derive(Debug)]
90pub enum GeneralError {
91    DatabaseError(Box<dyn Error>),
92}
93
94impl From<GeneralError> for AuthError {
95    fn from(value: GeneralError) -> Self {
96        match value {
97            GeneralError::DatabaseError(err) => AuthError::DatabaseError(err),
98        }
99    }
100}
101
102#[derive(Debug)]
103pub enum CreateKeyError {
104    DatabaseError(Box<dyn Error>),
105    UserDoesNotExist,
106    KeyAlreadyExists,
107}
108
109#[derive(Debug)]
110pub enum KeyError {
111    DatabaseError(Box<dyn Error>),
112    KeyDoesNotExist,
113}