use crate::core::credentials::{Credentials, PlainPassword};
use crate::core::oauth::store::{OAuth2Provider, OAuth2UserInfo};
use std::collections::HashMap;
#[derive(Debug, Clone)]
pub struct User {
pub id: String,
pub credentials: Option<Credentials>,
pub oauth_accounts: HashMap<OAuth2Provider, OAuth2UserInfo>,
pub created_at: chrono::NaiveDateTime,
pub updated_at: chrono::NaiveDateTime,
}
impl Default for User {
fn default() -> Self {
let now = chrono::Utc::now().naive_utc();
Self {
id: String::new(),
credentials: None,
oauth_accounts: HashMap::new(),
created_at: now,
updated_at: now,
}
}
}
impl User {
pub fn new(id: String, credentials: Credentials) -> Self {
let now = chrono::Utc::now().naive_utc();
Self {
id,
credentials: Some(credentials),
oauth_accounts: HashMap::new(),
created_at: now,
updated_at: now,
}
}
pub async fn with_plain_password(
manager: &(dyn crate::core::password::SecurePasswordManager + Send + Sync),
id: String,
identifier: String,
plain_password: PlainPassword,
) -> Result<Self, crate::error::AuthError> {
let credentials =
Credentials::from_plain_password(manager, id.clone(), identifier, plain_password)
.await?;
Ok(Self {
id,
credentials: Some(credentials),
oauth_accounts: HashMap::new(),
created_at: chrono::Utc::now().naive_utc(),
updated_at: chrono::Utc::now().naive_utc(),
})
}
pub fn link_oauth_account(mut self, mut oauth_info: OAuth2UserInfo) -> Self {
oauth_info.user_id = self.id.clone();
self.oauth_accounts.insert(oauth_info.provider, oauth_info);
self.updated_at = chrono::Utc::now().naive_utc();
self
}
pub fn unlink_oauth_account(&mut self, provider: OAuth2Provider) -> bool {
let was_linked = self.oauth_accounts.remove(&provider).is_some();
if was_linked {
self.updated_at = chrono::Utc::now().naive_utc();
}
was_linked
}
pub fn has_oauth_account(&self, provider: OAuth2Provider) -> bool {
self.oauth_accounts.contains_key(&provider)
}
pub fn get_oauth_account(&self, provider: OAuth2Provider) -> Option<&OAuth2UserInfo> {
self.oauth_accounts.get(&provider)
}
pub fn from_oauth(id: String, mut oauth_info: OAuth2UserInfo) -> Self {
oauth_info.user_id = id.clone();
let now = chrono::Utc::now().naive_utc();
let mut oauth_accounts = HashMap::new();
oauth_accounts.insert(oauth_info.provider, oauth_info);
Self {
id,
credentials: None,
oauth_accounts,
created_at: now,
updated_at: now,
}
}
}
pub mod persistence;