feat: identity: update password cmd and service
This commit is contained in:
parent
09d3e5331c
commit
8085f5e54b
5 changed files with 169 additions and 4 deletions
|
@ -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)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
|
|
17
src/identity/application/services/update_password/events.rs
Normal file
17
src/identity/application/services/update_password/events.rs
Normal 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 }
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,3 +1,18 @@
|
||||||
mod command;
|
// SPDX-FileCopyrightText: 2024 Aravinth Manivannan <realaravinth@batsense.net>
|
||||||
mod error;
|
//
|
||||||
mod service;
|
// 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;
|
||||||
|
}
|
||||||
|
|
|
@ -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());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue