use crate::core::error::Result;
use crate::core::models::User;
use async_trait::async_trait;
use std::time::Duration;
#[derive(Debug, Clone)]
pub enum Credentials {
EmailPassword { email: String, password: String },
ApiKey(String),
SessionToken(String),
}
#[derive(Debug, Clone)]
pub struct AuthResponse {
pub session_token: String,
pub user: User,
pub expires_in: Option<Duration>,
}
#[async_trait]
pub trait AuthProvider: Send + Sync {
async fn authenticate(&self, credentials: &Credentials) -> Result<AuthResponse>;
async fn refresh_session(&self, session_token: &str) -> Result<AuthResponse>;
async fn validate_token(&self, session_token: &str) -> Result<bool>;
async fn logout(&self, session_token: &str) -> Result<()>;
async fn get_user(&self, session_token: &str) -> Result<User>;
}
#[derive(Debug, Clone)]
pub struct MockAuthProvider {
pub should_succeed: bool,
pub mock_user: Option<User>,
pub mock_token: String,
}
impl Default for MockAuthProvider {
fn default() -> Self {
Self {
should_succeed: true,
mock_user: Some(User {
id: crate::core::models::common::UserId(1),
email: "test@example.com".to_string(),
first_name: "Test".to_string(),
last_name: "User".to_string(),
is_active: true,
is_superuser: false,
is_qbnewb: false,
date_joined: chrono::Utc::now(),
last_login: None,
locale: None,
google_auth: false,
ldap_auth: false,
common_name: Some("Test User".to_string()),
group_ids: Vec::new(),
login_attributes: None,
user_group_memberships: Vec::new(),
}),
mock_token: "mock_session_token_123".to_string(),
}
}
}
#[async_trait]
impl AuthProvider for MockAuthProvider {
async fn authenticate(&self, _credentials: &Credentials) -> Result<AuthResponse> {
if !self.should_succeed {
return Err(crate::core::error::Error::Authentication(
"Mock authentication failed".to_string(),
));
}
Ok(AuthResponse {
session_token: self.mock_token.clone(),
user: self.mock_user.clone().unwrap_or_else(|| User {
id: crate::core::models::common::UserId(1),
email: "mock@example.com".to_string(),
first_name: "Mock".to_string(),
last_name: "User".to_string(),
is_active: true,
is_superuser: false,
is_qbnewb: false,
date_joined: chrono::Utc::now(),
last_login: None,
locale: None,
google_auth: false,
ldap_auth: false,
common_name: Some("Mock User".to_string()),
group_ids: Vec::new(),
login_attributes: None,
user_group_memberships: Vec::new(),
}),
expires_in: Some(Duration::from_secs(3600)),
})
}
async fn refresh_session(&self, _session_token: &str) -> Result<AuthResponse> {
self.authenticate(&Credentials::SessionToken(self.mock_token.clone()))
.await
}
async fn validate_token(&self, session_token: &str) -> Result<bool> {
Ok(self.should_succeed && session_token == self.mock_token)
}
async fn logout(&self, _session_token: &str) -> Result<()> {
if !self.should_succeed {
return Err(crate::core::error::Error::Authentication(
"Mock logout failed".to_string(),
));
}
Ok(())
}
async fn get_user(&self, _session_token: &str) -> Result<User> {
if !self.should_succeed {
return Err(crate::core::error::Error::Authentication(
"Mock get_user failed".to_string(),
));
}
self.mock_user
.clone()
.ok_or_else(|| crate::core::error::Error::Authentication("No user found".to_string()))
}
}