diff options
| author | UMTS at Teleco <crt@teleco.ch> | 2025-12-13 02:48:13 +0100 |
|---|---|---|
| committer | UMTS at Teleco <crt@teleco.ch> | 2025-12-13 02:48:13 +0100 |
| commit | e52b8e1c2e110d0feb74feb7905c2ff064b51d55 (patch) | |
| tree | 3090814e422250e07e72cf1c83241ffd95cf20f7 /src/auth/password.rs | |
Diffstat (limited to 'src/auth/password.rs')
| -rw-r--r-- | src/auth/password.rs | 56 |
1 files changed, 56 insertions, 0 deletions
diff --git a/src/auth/password.rs b/src/auth/password.rs new file mode 100644 index 0000000..580ad1f --- /dev/null +++ b/src/auth/password.rs @@ -0,0 +1,56 @@ +// Password authentication module +use crate::models::{Role, User}; +use anyhow::{Context, Result}; +use bcrypt::verify; +use sqlx::MySqlPool; + +pub async fn authenticate_password( + pool: &MySqlPool, + username: &str, + password: &str, +) -> Result<Option<(User, Role)>> { + // Fetch user from database + let user: Option<User> = sqlx::query_as::<_, User>( + r#" + SELECT id, name, username, password, pin_code, login_string, role_id, + email, phone, notes, active, last_login_date, created_date, + password_reset_token, password_reset_expiry + FROM users + WHERE username = ? AND active = TRUE + "#, + ) + .bind(username) + .fetch_optional(pool) + .await + .context("Failed to fetch user from database")?; + + if let Some(user) = user { + // Verify password + let password_valid = + verify(password, &user.password).context("Failed to verify password")?; + + if password_valid { + // Fetch user's role + let role: Role = sqlx::query_as::<_, Role>( + "SELECT id, name, power, created_at FROM roles WHERE id = ?", + ) + .bind(user.role_id) + .fetch_one(pool) + .await + .context("Failed to fetch user role")?; + + // Update last login date + sqlx::query("UPDATE users SET last_login_date = NOW() WHERE id = ?") + .bind(user.id) + .execute(pool) + .await + .context("Failed to update last login date")?; + + Ok(Some((user, role))) + } else { + Ok(None) + } + } else { + Ok(None) + } +} |
