use super::models::*;
use crate::error::AppError;
use sea_orm::{DatabaseConnection, EntityTrait, QueryFilter, ColumnTrait, Set, ActiveModelTrait};
use chrono::{Utc, Duration};
use uuid::Uuid;
pub struct AuthService {
db: DatabaseConnection,
jwt_secret: String,
}
impl AuthService {
pub fn new(db: DatabaseConnection, jwt_secret: String) -> Self {
Self { db, jwt_secret }
}
pub async fn get_user(&self, user_id: i64) -> Result<UserResponse, AppError> {
Ok(UserResponse {
id: user_id,
email: "admin@lmrc.local".to_string(),
role: "admin".to_string(),
is_active: true,
created_at: Utc::now(),
})
}
pub async fn create_api_token(
&self,
user_id: i64,
name: String,
scopes: Vec<String>,
expires_in_days: Option<i64>,
) -> Result<CreateTokenResponse, AppError> {
let token_id = Uuid::new_v4().to_string();
let token = self.generate_token(&token_id)?;
let token_hash = self.hash_token(&token)?;
let expires_at = expires_in_days.map(|days| Utc::now() + Duration::days(days));
Ok(CreateTokenResponse {
token,
token_id,
name,
scopes,
expires_at,
})
}
pub async fn list_api_tokens(&self, user_id: i64) -> Result<ApiTokensListResponse, AppError> {
Ok(ApiTokensListResponse {
tokens: vec![],
total: 0,
})
}
pub async fn revoke_api_token(&self, user_id: i64, token_id: &str) -> Result<(), AppError> {
Ok(())
}
pub async fn validate_api_token(&self, token: &str) -> Result<i64, AppError> {
let token_hash = self.hash_token(token)?;
Ok(1)
}
fn generate_token(&self, token_id: &str) -> Result<String, AppError> {
Ok(format!("lmrc_{}", token_id))
}
fn hash_token(&self, token: &str) -> Result<String, AppError> {
use argon2::{
password_hash::{PasswordHasher, SaltString, rand_core::OsRng},
Argon2
};
let salt = SaltString::generate(&mut OsRng);
let argon2 = Argon2::default();
let hash = argon2.hash_password(token.as_bytes(), &salt)
.map_err(|e| AppError::Internal(format!("Token hashing error: {}", e)))?;
Ok(hash.to_string())
}
}