use chrono::{DateTime, Utc};
use crate::entity::{
AuthAccount, AuthApiKey, AuthInvitation, AuthMember, AuthOrganization, AuthPasskey,
AuthSession, AuthTwoFactor, AuthUser, AuthVerification,
};
use crate::types::{
Account, ApiKey, CreateAccount, CreateApiKey, CreateInvitation, CreateMember,
CreateOrganization, CreatePasskey, CreateSession, CreateTwoFactor, CreateUser,
CreateVerification, Invitation, InvitationStatus, Member, Organization, Passkey, Session,
TwoFactor, UpdateAccount, UpdateApiKey, UpdateOrganization, UpdateUser, User, Verification,
};
pub trait MemoryUser: AuthUser {
fn from_create(id: String, create: &CreateUser, now: DateTime<Utc>) -> Self;
fn apply_update(&mut self, update: &UpdateUser);
}
pub trait MemorySession: AuthSession {
fn from_create(id: String, token: String, create: &CreateSession, now: DateTime<Utc>) -> Self;
fn set_expires_at(&mut self, at: DateTime<Utc>);
fn set_active_organization_id(&mut self, org_id: Option<String>);
fn set_updated_at(&mut self, at: DateTime<Utc>);
}
pub trait MemoryAccount: AuthAccount {
fn from_create(id: String, create: &CreateAccount, now: DateTime<Utc>) -> Self;
fn apply_update(&mut self, update: &UpdateAccount);
}
pub trait MemoryVerification: AuthVerification {
fn from_create(id: String, create: &CreateVerification, now: DateTime<Utc>) -> Self;
}
pub trait MemoryOrganization: AuthOrganization {
fn from_create(id: String, create: &CreateOrganization, now: DateTime<Utc>) -> Self;
fn apply_update(&mut self, update: &UpdateOrganization);
}
pub trait MemoryMember: AuthMember {
fn from_create(id: String, create: &CreateMember, now: DateTime<Utc>) -> Self;
fn set_role(&mut self, role: String);
}
pub trait MemoryInvitation: AuthInvitation {
fn from_create(id: String, create: &CreateInvitation, now: DateTime<Utc>) -> Self;
fn set_status(&mut self, status: InvitationStatus);
}
pub trait MemoryTwoFactor: AuthTwoFactor {
fn from_create(id: String, create: &CreateTwoFactor, now: DateTime<Utc>) -> Self;
fn set_backup_codes(&mut self, codes: String);
}
impl MemoryUser for User {
fn from_create(id: String, create: &CreateUser, now: DateTime<Utc>) -> Self {
User {
id,
name: create.name.clone(),
email: create.email.clone(),
email_verified: create.email_verified.unwrap_or(false),
image: create.image.clone(),
created_at: now,
updated_at: now,
username: create.username.clone(),
display_username: create.display_username.clone(),
two_factor_enabled: false,
role: create.role.clone(),
banned: false,
ban_reason: None,
ban_expires: None,
metadata: create.metadata.clone().unwrap_or(serde_json::json!({})),
}
}
fn apply_update(&mut self, update: &UpdateUser) {
if let Some(email) = &update.email {
self.email = Some(email.clone());
}
if let Some(name) = &update.name {
self.name = Some(name.clone());
}
if let Some(image) = &update.image {
self.image = Some(image.clone());
}
if let Some(email_verified) = update.email_verified {
self.email_verified = email_verified;
}
if let Some(username) = &update.username {
self.username = Some(username.clone());
}
if let Some(display_username) = &update.display_username {
self.display_username = Some(display_username.clone());
}
if let Some(role) = &update.role {
self.role = Some(role.clone());
}
if let Some(banned) = update.banned {
self.banned = banned;
if !banned {
self.ban_reason = None;
self.ban_expires = None;
}
}
if let Some(ban_reason) = &update.ban_reason {
self.ban_reason = Some(ban_reason.clone());
}
if let Some(ban_expires) = update.ban_expires {
self.ban_expires = Some(ban_expires);
}
if let Some(two_factor_enabled) = update.two_factor_enabled {
self.two_factor_enabled = two_factor_enabled;
}
if let Some(metadata) = &update.metadata {
self.metadata = metadata.clone();
}
self.updated_at = Utc::now();
}
}
impl MemorySession for Session {
fn from_create(id: String, token: String, create: &CreateSession, now: DateTime<Utc>) -> Self {
Session {
id,
token,
expires_at: create.expires_at,
created_at: now,
updated_at: now,
ip_address: create.ip_address.clone(),
user_agent: create.user_agent.clone(),
user_id: create.user_id.clone(),
impersonated_by: create.impersonated_by.clone(),
active_organization_id: create.active_organization_id.clone(),
active: true,
}
}
fn set_expires_at(&mut self, at: DateTime<Utc>) {
self.expires_at = at;
}
fn set_active_organization_id(&mut self, org_id: Option<String>) {
self.active_organization_id = org_id;
}
fn set_updated_at(&mut self, at: DateTime<Utc>) {
self.updated_at = at;
}
}
impl MemoryAccount for Account {
fn from_create(id: String, create: &CreateAccount, now: DateTime<Utc>) -> Self {
Account {
id,
account_id: create.account_id.clone(),
provider_id: create.provider_id.clone(),
user_id: create.user_id.clone(),
access_token: create.access_token.clone(),
refresh_token: create.refresh_token.clone(),
id_token: create.id_token.clone(),
access_token_expires_at: create.access_token_expires_at,
refresh_token_expires_at: create.refresh_token_expires_at,
scope: create.scope.clone(),
password: create.password.clone(),
created_at: now,
updated_at: now,
}
}
fn apply_update(&mut self, update: &UpdateAccount) {
if let Some(access_token) = &update.access_token {
self.access_token = Some(access_token.clone());
}
if let Some(refresh_token) = &update.refresh_token {
self.refresh_token = Some(refresh_token.clone());
}
if let Some(id_token) = &update.id_token {
self.id_token = Some(id_token.clone());
}
if let Some(at) = update.access_token_expires_at {
self.access_token_expires_at = Some(at);
}
if let Some(at) = update.refresh_token_expires_at {
self.refresh_token_expires_at = Some(at);
}
if let Some(scope) = &update.scope {
self.scope = Some(scope.clone());
}
if let Some(password) = &update.password {
self.password = Some(password.clone());
}
self.updated_at = Utc::now();
}
}
impl MemoryVerification for Verification {
fn from_create(id: String, create: &CreateVerification, now: DateTime<Utc>) -> Self {
Verification {
id,
identifier: create.identifier.clone(),
value: create.value.clone(),
expires_at: create.expires_at,
created_at: now,
updated_at: now,
}
}
}
impl MemoryOrganization for Organization {
fn from_create(id: String, create: &CreateOrganization, now: DateTime<Utc>) -> Self {
Organization {
id,
name: create.name.clone(),
slug: create.slug.clone(),
logo: create.logo.clone(),
metadata: create.metadata.clone(),
created_at: now,
updated_at: now,
}
}
fn apply_update(&mut self, update: &UpdateOrganization) {
if let Some(name) = &update.name {
self.name = name.clone();
}
if let Some(slug) = &update.slug {
self.slug = slug.clone();
}
if let Some(logo) = &update.logo {
self.logo = Some(logo.clone());
}
if let Some(metadata) = &update.metadata {
self.metadata = Some(metadata.clone());
}
self.updated_at = Utc::now();
}
}
impl MemoryMember for Member {
fn from_create(id: String, create: &CreateMember, now: DateTime<Utc>) -> Self {
Member {
id,
organization_id: create.organization_id.clone(),
user_id: create.user_id.clone(),
role: create.role.clone(),
created_at: now,
}
}
fn set_role(&mut self, role: String) {
self.role = role;
}
}
impl MemoryInvitation for Invitation {
fn from_create(id: String, create: &CreateInvitation, now: DateTime<Utc>) -> Self {
Invitation {
id,
organization_id: create.organization_id.clone(),
email: create.email.clone(),
role: create.role.clone(),
status: InvitationStatus::Pending,
inviter_id: create.inviter_id.clone(),
expires_at: create.expires_at,
created_at: now,
}
}
fn set_status(&mut self, status: InvitationStatus) {
self.status = status;
}
}
impl MemoryTwoFactor for TwoFactor {
fn from_create(id: String, create: &CreateTwoFactor, now: DateTime<Utc>) -> Self {
TwoFactor {
id,
secret: create.secret.clone(),
backup_codes: create.backup_codes.clone(),
user_id: create.user_id.clone(),
created_at: now,
updated_at: now,
}
}
fn set_backup_codes(&mut self, codes: String) {
self.backup_codes = Some(codes);
}
}
pub trait MemoryApiKey: AuthApiKey {
fn from_create(id: String, input: &CreateApiKey, now: DateTime<Utc>) -> Self;
fn apply_update(&mut self, update: &UpdateApiKey);
}
pub trait MemoryPasskey: AuthPasskey {
fn from_create(id: String, input: &CreatePasskey, now: DateTime<Utc>) -> Self;
fn set_counter(&mut self, counter: u64);
fn set_name(&mut self, name: String);
}
impl MemoryApiKey for ApiKey {
fn from_create(id: String, input: &CreateApiKey, now: DateTime<Utc>) -> Self {
let now_str = now.to_rfc3339();
ApiKey {
id,
name: input.name.clone(),
start: input.start.clone(),
prefix: input.prefix.clone(),
key_hash: input.key_hash.clone(),
user_id: input.user_id.clone(),
refill_interval: input.refill_interval,
refill_amount: input.refill_amount,
last_refill_at: None,
enabled: input.enabled,
rate_limit_enabled: input.rate_limit_enabled,
rate_limit_time_window: input.rate_limit_time_window,
rate_limit_max: input.rate_limit_max,
request_count: Some(0),
remaining: input.remaining,
last_request: None,
expires_at: input.expires_at.clone(),
created_at: now_str.clone(),
updated_at: now_str,
permissions: input.permissions.clone(),
metadata: input.metadata.clone(),
}
}
fn apply_update(&mut self, update: &UpdateApiKey) {
if let Some(name) = &update.name {
self.name = Some(name.clone());
}
if let Some(enabled) = update.enabled {
self.enabled = enabled;
}
if let Some(remaining) = update.remaining {
self.remaining = Some(remaining);
}
if let Some(rate_limit_enabled) = update.rate_limit_enabled {
self.rate_limit_enabled = rate_limit_enabled;
}
if let Some(rate_limit_time_window) = update.rate_limit_time_window {
self.rate_limit_time_window = Some(rate_limit_time_window);
}
if let Some(rate_limit_max) = update.rate_limit_max {
self.rate_limit_max = Some(rate_limit_max);
}
if let Some(refill_interval) = update.refill_interval {
self.refill_interval = Some(refill_interval);
}
if let Some(refill_amount) = update.refill_amount {
self.refill_amount = Some(refill_amount);
}
if let Some(permissions) = &update.permissions {
self.permissions = Some(permissions.clone());
}
if let Some(metadata) = &update.metadata {
self.metadata = Some(metadata.clone());
}
if let Some(expires_at) = &update.expires_at {
self.expires_at = expires_at.clone();
}
if let Some(last_request) = &update.last_request {
self.last_request = last_request.clone();
}
if let Some(request_count) = update.request_count {
self.request_count = Some(request_count);
}
if let Some(last_refill_at) = &update.last_refill_at {
self.last_refill_at = last_refill_at.clone();
}
self.updated_at = Utc::now().to_rfc3339();
}
}
impl MemoryPasskey for Passkey {
fn from_create(id: String, input: &CreatePasskey, now: DateTime<Utc>) -> Self {
Self {
id,
name: input.name.clone(),
public_key: input.public_key.clone(),
user_id: input.user_id.clone(),
credential_id: input.credential_id.clone(),
counter: input.counter,
device_type: input.device_type.clone(),
backed_up: input.backed_up,
transports: input.transports.clone(),
created_at: now,
}
}
fn set_counter(&mut self, counter: u64) {
self.counter = counter;
}
fn set_name(&mut self, name: String) {
self.name = name;
}
}