forked from lavina/lavina
48 lines
1.4 KiB
Rust
48 lines
1.4 KiB
Rust
|
use anyhow::Result;
|
||
|
|
||
|
use crate::prelude::log;
|
||
|
use crate::repo::Storage;
|
||
|
|
||
|
pub enum Verdict {
|
||
|
Authenticated,
|
||
|
UserNotFound,
|
||
|
InvalidPassword,
|
||
|
}
|
||
|
|
||
|
pub enum UpdatePasswordResult {
|
||
|
PasswordUpdated,
|
||
|
UserNotFound,
|
||
|
}
|
||
|
|
||
|
pub struct Authenticator<'a> {
|
||
|
storage: &'a Storage,
|
||
|
}
|
||
|
impl<'a> Authenticator<'a> {
|
||
|
pub fn new(storage: &'a Storage) -> Self {
|
||
|
Self { storage }
|
||
|
}
|
||
|
|
||
|
pub async fn authenticate(&self, login: &str, provided_password: &str) -> Result<Verdict> {
|
||
|
let Some(stored_user) = self.storage.retrieve_user_by_name(login).await? else {
|
||
|
return Ok(Verdict::UserNotFound);
|
||
|
};
|
||
|
let Some(expected_password) = stored_user.password else {
|
||
|
log::debug!("Password not defined for user '{}'", login);
|
||
|
return Ok(Verdict::InvalidPassword);
|
||
|
};
|
||
|
if expected_password == provided_password {
|
||
|
return Ok(Verdict::Authenticated);
|
||
|
}
|
||
|
Ok(Verdict::InvalidPassword)
|
||
|
}
|
||
|
|
||
|
pub async fn set_password(&self, login: &str, provided_password: &str) -> Result<UpdatePasswordResult> {
|
||
|
let Some(_) = self.storage.retrieve_user_by_name(login).await? else {
|
||
|
return Ok(UpdatePasswordResult::UserNotFound);
|
||
|
};
|
||
|
self.storage.set_password(login, provided_password).await?;
|
||
|
log::info!("Password changed for player {login}");
|
||
|
Ok(UpdatePasswordResult::PasswordUpdated)
|
||
|
}
|
||
|
}
|