feat: identity: update_email service

This commit is contained in:
Aravinth Manivannan 2024-05-18 00:10:38 +05:30
parent 458afd3577
commit c43814d8f0
Signed by: realaravinth
GPG key ID: F8F50389936984FF
4 changed files with 148 additions and 0 deletions

View file

@ -0,0 +1,68 @@
// SPDX-FileCopyrightText: 2024 Aravinth Manivannan <realaravinth@batsense.net>
//
// SPDX-License-Identifier: AGPL-3.0-or-later
use derive_getters::Getters;
use serde::{Deserialize, Serialize};
use super::*;
#[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq, Ord, PartialOrd, Getters)]
pub struct UpdateEmailCommand {
new_email: String,
}
impl UpdateEmailCommand {
pub fn new(
new_email: String,
supplied_password: String,
actual_password_hash: &str,
config: &argon2_creds::Config,
) -> IdentityCommandResult<Self> {
if !argon2_creds::Config::verify(actual_password_hash, &supplied_password).unwrap() {
return Err(IdentityCommandError::WrongPassword);
}
config.email(&new_email)?;
Ok(Self { new_email })
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_cmd() {
let config = argon2_creds::Config::default();
let password = "adsfasdfasd";
let username = "realaravinth";
let new_email = format!("newemail@example.com");
let hashed_password = config.password(password).unwrap();
assert_eq!(
UpdateEmailCommand::new(
new_email.clone(),
password.into(),
&hashed_password,
&config
)
.unwrap()
.new_email,
new_email
);
// email is not valid email
assert_eq!(
UpdateEmailCommand::new(username.into(), password.into(), &hashed_password, &config)
.err(),
Some(IdentityCommandError::BadEmail)
);
// wrong password
assert_eq!(
UpdateEmailCommand::new(username.into(), username.into(), &hashed_password, &config)
.err(),
Some(IdentityCommandError::WrongPassword)
);
}
}

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 EmailUpdatedEvent {
email: String,
}
impl EmailUpdatedEvent {
pub fn new(email: String) -> Self {
Self { email }
}
}

View file

@ -0,0 +1,18 @@
// 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 UpdateEmailUseCase {
async fn update_email(
&self,
cmd: command::UpdateEmailCommand,
//) -> errors::ProcessAuthorizationServiceResult<String>;
) -> events::EmailUpdatedEvent;
}

View file

@ -0,0 +1,45 @@
// SPDX-FileCopyrightText: 2024 Aravinth Manivannan <realaravinth@batsense.net>
//
// SPDX-License-Identifier: AGPL-3.0-or-later
use super::*;
struct UpdateEmailService;
#[async_trait::async_trait]
impl UpdateEmailUseCase for UpdateEmailService {
async fn update_email(
&self,
cmd: command::UpdateEmailCommand,
//) -> errors::ProcessAuthorizationServiceResult<String>;
) -> events::EmailUpdatedEvent {
// TODO: check if email exists in DB
events::EmailUpdatedEvent::new(cmd.new_email().into())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[actix_rt::test]
async fn test_service() {
let username = "realaravinth";
let new_email = format!("{username}@example.com");
let password = "password";
let config = argon2_creds::Config::default();
let hashed_password = config.password(password).unwrap();
let cmd = command::UpdateEmailCommand::new(
new_email.clone(),
password.into(),
&hashed_password,
&config,
)
.unwrap();
let s = UpdateEmailService;
let res = s.update_email(cmd.clone()).await;
assert_eq!(res.email(), cmd.new_email());
}
}