use crate::core::Instant;
use crate::types::AnyError;
use crate::user::{ShortUser, UserIdRef};
use async_trait::async_trait;
use auto_impl::auto_impl;
use etwin_core::{declare_new_enum, declare_new_uuid};
#[cfg(feature = "serde")]
use etwin_serde_tools::{Deserialize, Serialize};
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize), serde(tag = "type"))]
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum AuthContext {
System(SystemAuthContext),
Guest(GuestAuthContext),
User(UserAuthContext),
}
impl AuthContext {
pub const fn guest() -> Self {
Self::Guest(GuestAuthContext {
scope: AuthScope::Default,
})
}
}
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "serde", serde(tag = "type", rename = "System"))]
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct SystemAuthContext {}
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "serde", serde(tag = "type", rename = "Guest"))]
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct GuestAuthContext {
pub scope: AuthScope,
}
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "serde", serde(tag = "type", rename = "User"))]
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct UserAuthContext {
pub scope: AuthScope,
pub user: ShortUser,
pub is_administrator: bool,
pub is_tester: bool,
}
declare_new_enum!(
pub enum AuthScope {
#[str("Default")]
Default,
}
pub type ParseError = AuthScopeParseError;
);
declare_new_uuid! {
pub struct SessionId(Uuid);
pub type ParseError = SessionIdParseError;
const SQL_NAME = "session_id";
}
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct CreateSessionOptions {
pub user: UserIdRef,
}
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct RawSession {
pub id: SessionId,
pub user: UserIdRef,
pub created_at: Instant,
pub updated_at: Instant,
}
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Session {
pub id: SessionId,
pub user: UserIdRef,
pub created_at: Instant,
pub updated_at: Instant,
}
#[async_trait]
#[auto_impl(&, Arc)]
pub trait AuthStore: Send + Sync {
async fn create_session(&self, options: &CreateSessionOptions) -> Result<RawSession, AnyError>;
async fn get_and_touch_session(&self, session: SessionId) -> Result<Option<RawSession>, AnyError>;
}