feat: identity: update password cmd and service

This commit is contained in:
Aravinth Manivannan 2024-05-17 23:58:30 +05:30
parent 09d3e5331c
commit 8085f5e54b
Signed by: realaravinth
GPG key ID: F8F50389936984FF
5 changed files with 169 additions and 4 deletions

View file

@ -1 +1,90 @@
// SPDX-FileCopyrightText: 2024 Aravinth Manivannan <realaravinth@batsense.net>
//
// SPDX-License-Identifier: AGPL-3.0-or-later
use super::*;
use derive_getters::Getters;
use serde::{Deserialize, Serialize};
#[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq, Ord, PartialOrd, Getters)]
pub struct UpdatePasswordCommand {
hashed_new_passowrd: String,
}
impl UpdatePasswordCommand {
pub fn new(
_username: String,
supplied_old_password: String,
supplied_new_password: String,
supplied_confirm_new_password: String,
actual_password_hash: &str,
config: &argon2_creds::Config,
) -> IdentityCommandResult<Self> {
if supplied_new_password != supplied_confirm_new_password {
return Err(IdentityCommandError::PasswordsDontMatch);
}
if !argon2_creds::Config::verify(actual_password_hash, &supplied_old_password)? {
return Err(IdentityCommandError::WrongPassword);
}
let hashed_new_passowrd: String = config.password(&supplied_new_password)?;
Ok(Self {
hashed_new_passowrd,
})
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_cmd() {
let config = argon2_creds::Config::default();
let username = "realaravinth";
let password = "adsfasdfasd";
let hashed_password = config.password(password).unwrap();
let new_password = "adsfasdfasd_asdfasdf";
argon2_creds::Config::verify(
&UpdatePasswordCommand::new(
username.into(),
password.into(),
new_password.into(),
new_password.into(),
&hashed_password,
&config,
)
.unwrap()
.hashed_new_passowrd,
new_password.into(),
)
.unwrap();
// Wrong password
assert_eq!(
UpdatePasswordCommand::new(
username.into(),
new_password.into(),
new_password.into(),
new_password.into(),
&hashed_password,
&config,
)
.err(),
Some(IdentityCommandError::WrongPassword)
);
// password don't match
assert_eq!(
UpdatePasswordCommand::new(
username.into(),
password.into(),
password.into(),
new_password.into(),
&hashed_password,
&config,
)
.err(),
Some(IdentityCommandError::PasswordsDontMatch)
);
}
}

View file

@ -0,0 +1,17 @@
// SPDX-FileCopyrightText: 2024 Aravinth Manivannan <realaravinth@batsense.net>
//
// SPDX-License-Identifier: AGPL-3.0-or-later
use derive_getters::Getters;
use serde::{Deserialize, Serialize};
#[derive(Clone, Debug, Serialize, Deserialize, Getters, Eq, PartialEq, Ord, PartialOrd)]
pub struct PasswordUpdatedEvent {
hashed_password: String,
}
impl PasswordUpdatedEvent {
pub fn new(hashed_password: String) -> Self {
Self { hashed_password }
}
}

View file

@ -1,3 +1,18 @@
mod command;
mod error;
mod service;
// SPDX-FileCopyrightText: 2024 Aravinth Manivannan <realaravinth@batsense.net>
//
// SPDX-License-Identifier: AGPL-3.0-or-later
pub mod command;
pub mod events;
pub mod service;
use super::errors::*;
#[async_trait::async_trait]
pub trait UpdatePasswordUseCase {
async fn update_password(
&self,
cmd: command::UpdatePasswordCommand,
//) -> errors::ProcessAuthorizationServiceResult<String>;
) -> events::PasswordUpdatedEvent;
}

View file

@ -1 +1,46 @@
// SPDX-FileCopyrightText: 2024 Aravinth Manivannan <realaravinth@batsense.net>
//
// SPDX-License-Identifier: AGPL-3.0-or-later
use super::*;
struct UpdatePasswordService;
#[async_trait::async_trait]
impl UpdatePasswordUseCase for UpdatePasswordService {
async fn update_password(
&self,
cmd: command::UpdatePasswordCommand,
//) -> errors::ProcessAuthorizationServiceResult<String>;
) -> events::PasswordUpdatedEvent {
events::PasswordUpdatedEvent::new(cmd.hashed_new_passowrd().into())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[actix_rt::test]
async fn test_service() {
let username = "realaravinth";
let password = "password";
let new_password = format!("{username}@example.com");
let config = argon2_creds::Config::default();
let hashed_password = config.password(password).unwrap();
let cmd = command::UpdatePasswordCommand::new(
username.into(),
password.into(),
new_password.clone(),
new_password.into(),
&hashed_password,
&config,
)
.unwrap();
let s = UpdatePasswordService;
let res = s.update_password(cmd.clone()).await;
assert_eq!(res.hashed_password(), cmd.hashed_new_passowrd());
}
}