951a522
use std::sync::Arc;
use config::AppConfig;
use export::{AppDatabase, AppRedis, AppState};
use models::users::access_scope::AccessKeyScope;
use crate::errors::AuthError;
pub mod agreements;
pub mod notifications;
pub mod preferences;
pub mod profile;
pub mod reports;
pub mod suspensions;
pub mod users;
pub struct VerifiedAccessKey {
pub user_id: i64,
pub scope: AccessKeyScope,
}
#[derive(Clone)]
pub struct AuthService {
pub state: AppState,
}
impl AuthService {
pub fn new(state: AppState) -> Self {
Self { state }
}
pub fn config(&self) -> &AppConfig {
&self.state.config
}
pub fn db(&self) -> &Arc<AppDatabase> {
&self.state.database
}
pub fn redis(&self) -> &AppRedis {
&self.state.redis
}
/// Pick the mail language for one recipient.
pub async fn mail_locale(
&self,
uid: Option<i64>,
accept_language: Option<&str>,
) -> i18n::UiLocale {
let fallback = i18n::UiLocale::parse(self.config().email.default_locale())
.unwrap_or(i18n::UiLocale::En);
match uid {
Some(uid) => i18n::resolve_user_locale(self.db().read(), uid, fallback).await,
None => i18n::negotiate_accept_language(accept_language, fallback),
}
}
pub async fn verify_access_token(
&self,
token: &str,
) -> Result<Option<VerifiedAccessKey>, AuthError> {
let Some(client) = self.state.kenauth.as_ref() else {
return Ok(None);
};
let principal = match client.verify_access_key(token, Vec::new()).await {
Ok(Some(principal)) => principal,
Ok(None) => return Ok(None),
Err(error) => return Err(AuthError::Internal(error.to_string())),
};
let write = principal.scopes.iter().any(|scope| *scope == 12);
Ok(Some(VerifiedAccessKey {
user_id: principal.user_id,
scope: if write {
AccessKeyScope::Write
} else {
AccessKeyScope::Read
},
}))
}
}