litellm_rs/auth/
user_management.rs1use super::system::AuthSystem;
4use crate::core::models::user::types::User;
5use crate::utils::auth::crypto::password::{hash_password, verify_password};
6use crate::utils::error::gateway_error::{GatewayError, Result};
7use tracing::info;
8
9impl AuthSystem {
10 pub async fn create_user(
12 &self,
13 username: String,
14 email: String,
15 password: String,
16 ) -> Result<User> {
17 info!("Creating new user: {}", username);
18
19 let password_hash = hash_password(&password)?;
21
22 let user = User::new(username, email, password_hash);
24
25 self.storage.db().create_user(&user).await
27 }
28
29 pub async fn login(&self, username: &str, password: &str) -> Result<(User, String)> {
31 let user = self.verify_login_credentials(username, password).await?;
32 self.finish_login(user, None).await
33 }
34
35 pub(crate) async fn login_with_active_team(
37 &self,
38 username: &str,
39 password: &str,
40 team_id: uuid::Uuid,
41 ) -> Result<(User, String)> {
42 let user = self.verify_login_credentials(username, password).await?;
43 let verified_team = self
44 .validate_active_team(user.id(), team_id)
45 .await?
46 .ok_or_else(|| GatewayError::bad_request("Invalid active team selection"))?;
47 self.finish_login(user, Some(verified_team)).await
48 }
49
50 async fn verify_login_credentials(&self, username: &str, password: &str) -> Result<User> {
51 info!("User login attempt: {}", username);
52
53 let user = self
55 .storage
56 .db()
57 .find_user_by_username(username)
58 .await?
59 .ok_or_else(|| GatewayError::auth("Invalid username or password"))?;
60
61 if !verify_password(password, &user.password_hash)? {
63 return Err(GatewayError::auth("Invalid username or password"));
64 }
65
66 if !user.is_active() {
68 return Err(GatewayError::auth("Account is not active"));
69 }
70
71 Ok(user)
72 }
73
74 async fn finish_login(
75 &self,
76 user: User,
77 verified_team: Option<crate::auth::jwt::types::VerifiedActiveTeam>,
78 ) -> Result<(User, String)> {
79 let session_id = uuid::Uuid::new_v4();
81 let permissions = self.get_user_permissions(&user).await?;
82 let session_token = match verified_team {
83 Some(ref verified_team) => {
84 self.jwt
85 .create_access_token_for_verified_team(
86 user.id(),
87 user.role.to_string(),
88 permissions,
89 verified_team,
90 Some(session_id),
91 )
92 .await?
93 }
94 None => {
95 self.jwt
96 .create_access_token(
97 user.id(),
98 user.role.to_string(),
99 permissions,
100 None,
101 Some(session_id),
102 )
103 .await?
104 }
105 };
106
107 self.storage.db().update_user_last_login(user.id()).await?;
109
110 info!("User logged in successfully: {}", user.username);
111 Ok((user, session_token))
112 }
113
114 pub async fn logout(&self, session_token: &str) -> Result<()> {
116 info!("User logout");
117
118 if let Ok(claims) = self.jwt.verify_access_token(session_token).await
120 && claims.session_id.is_some()
121 {
122 info!("Session invalidated");
125 }
126
127 Ok(())
128 }
129}