From b4e56cc9a1305279cb01c1f798efdd842e24dfb2 Mon Sep 17 00:00:00 2001 From: Aravinth Manivannan Date: Sat, 18 May 2024 00:03:26 +0530 Subject: [PATCH] fix: update_user: delete module. Difficult to maintain consistency in denormalized views --- src/identity/application/services/events.rs | 45 ++++++++++ src/identity/application/services/mod.rs | 29 ++++++- .../services/update_user/command.rs | 1 - .../application/services/update_user/error.rs | 1 - .../application/services/update_user/mod.rs | 3 - .../services/update_user/service.rs | 1 - .../services/update_username/command.rs | 76 ----------------- .../services/update_username/events.rs | 17 ---- .../services/update_username/mod.rs | 16 ---- .../services/update_username/service.rs | 82 ------------------- 10 files changed, 72 insertions(+), 199 deletions(-) create mode 100644 src/identity/application/services/events.rs delete mode 100644 src/identity/application/services/update_user/command.rs delete mode 100644 src/identity/application/services/update_user/error.rs delete mode 100644 src/identity/application/services/update_user/mod.rs delete mode 100644 src/identity/application/services/update_user/service.rs delete mode 100644 src/identity/application/services/update_username/command.rs delete mode 100644 src/identity/application/services/update_username/events.rs delete mode 100644 src/identity/application/services/update_username/mod.rs delete mode 100644 src/identity/application/services/update_username/service.rs diff --git a/src/identity/application/services/events.rs b/src/identity/application/services/events.rs new file mode 100644 index 0000000..163c88e --- /dev/null +++ b/src/identity/application/services/events.rs @@ -0,0 +1,45 @@ +// SPDX-FileCopyrightText: 2024 Aravinth Manivannan +// +// SPDX-License-Identifier: AGPL-3.0-or-later + +use cqrs_es::DomainEvent; +use serde::{Deserialize, Serialize}; + +use super::login::events::*; +use super::register_user::events::*; +use super::set_user_admin::events::*; +use super::update_email::events::*; +use super::update_password::events::*; + +#[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq, Ord, PartialOrd)] +pub enum UserEvent { + UserRegistered(UserRegisteredEvent), + UserDeleted, + Loggedin(LoginEvent), + PasswordUpdated(PasswordUpdatedEvent), + EmailUpdated(EmailUpdatedEvent), + UserVerified, + UserPromotedToAdmin(UserPromotedToAdminEvent), +} + +//TODO: define password type that takes string and converts to hash + +impl DomainEvent for UserEvent { + fn event_version(&self) -> String { + "1.0".to_string() + } + + fn event_type(&self) -> String { + let e: &str = match self { + UserEvent::UserRegistered { .. } => "UserRegisteredAccount", + UserEvent::UserDeleted => "UserDeletedAccount", + UserEvent::Loggedin { .. } => "UserLoggedIn", + UserEvent::PasswordUpdated { .. } => "UserUpdatedAccountPassword", + UserEvent::EmailUpdated { .. } => "UserUpdatedAccountEmail", + UserEvent::UserVerified => "UserIsVerified", + UserEvent::UserPromotedToAdmin { .. } => "UserPromotedToAdmin", + }; + + e.to_string() + } +} diff --git a/src/identity/application/services/mod.rs b/src/identity/application/services/mod.rs index 246817f..2cd7d0c 100644 --- a/src/identity/application/services/mod.rs +++ b/src/identity/application/services/mod.rs @@ -2,8 +2,33 @@ // // SPDX-License-Identifier: AGPL-3.0-or-later -mod create_user; +use serde::{Deserialize, Serialize}; + mod delete_user; mod login; +mod register_user; +mod update_email; mod update_password; -mod update_user; +//mod resend_verification_email +pub mod errors; +pub mod events; +mod mark_user_verified; +mod set_user_admin; + +use delete_user::command::*; +use login::command::*; +use register_user::command::*; +use set_user_admin::command::*; +use update_email::command::*; +use update_password::command::*; + +#[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq, Ord, PartialOrd)] +pub enum UserCommand { + RegisterUser(RegisterUserCommand), + DeleteUser(DeleteUserCommand), + Login(LoginCommand), + UpdatePassword(UpdatePasswordCommand), + UpdateEmail(UpdateEmailCommand), + SetVerified, + SetAdmin(SetAdminCommand), +} diff --git a/src/identity/application/services/update_user/command.rs b/src/identity/application/services/update_user/command.rs deleted file mode 100644 index 8b13789..0000000 --- a/src/identity/application/services/update_user/command.rs +++ /dev/null @@ -1 +0,0 @@ - diff --git a/src/identity/application/services/update_user/error.rs b/src/identity/application/services/update_user/error.rs deleted file mode 100644 index 8b13789..0000000 --- a/src/identity/application/services/update_user/error.rs +++ /dev/null @@ -1 +0,0 @@ - diff --git a/src/identity/application/services/update_user/mod.rs b/src/identity/application/services/update_user/mod.rs deleted file mode 100644 index 0d0d0f7..0000000 --- a/src/identity/application/services/update_user/mod.rs +++ /dev/null @@ -1,3 +0,0 @@ -mod command; -mod error; -mod service; diff --git a/src/identity/application/services/update_user/service.rs b/src/identity/application/services/update_user/service.rs deleted file mode 100644 index 8b13789..0000000 --- a/src/identity/application/services/update_user/service.rs +++ /dev/null @@ -1 +0,0 @@ - diff --git a/src/identity/application/services/update_username/command.rs b/src/identity/application/services/update_username/command.rs deleted file mode 100644 index a0f6cdb..0000000 --- a/src/identity/application/services/update_username/command.rs +++ /dev/null @@ -1,76 +0,0 @@ -// SPDX-FileCopyrightText: 2024 Aravinth Manivannan -// -// 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 UpdateUsernameCommand { - new_username: String, -} - -impl UpdateUsernameCommand { - pub fn new( - new_username: String, - supplied_password: String, - actual_password_hash: &str, - config: &argon2_creds::Config, - ) -> IdentityCommandResult { - if !argon2_creds::Config::verify(actual_password_hash, &supplied_password).unwrap() { - return Err(IdentityCommandError::WrongPassword); - } - let new_username = config.username(&new_username)?; - Ok(Self { new_username }) - } -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_cmd() { - let config = argon2_creds::Config::default(); - let password = "adsfasdfasd"; - let new_username = "realaravinth"; - let hashed_password = config.password(password).unwrap(); - assert_eq!( - UpdateUsernameCommand::new( - new_username.into(), - password.into(), - &hashed_password, - &config - ) - .unwrap() - .new_username, - new_username - ); - - // username is not valid - assert!(matches!( - UpdateUsernameCommand::new( - "username".into(), - password.into(), - &hashed_password, - &config, - ) - .err(), - Some(IdentityCommandError::BadUsername(_)) - )); - - // wrong password - assert_eq!( - UpdateUsernameCommand::new( - new_username.into(), - new_username.into(), - &hashed_password, - &config, - ) - .err(), - Some(IdentityCommandError::WrongPassword) - ); - } -} diff --git a/src/identity/application/services/update_username/events.rs b/src/identity/application/services/update_username/events.rs deleted file mode 100644 index a14a0f9..0000000 --- a/src/identity/application/services/update_username/events.rs +++ /dev/null @@ -1,17 +0,0 @@ -// SPDX-FileCopyrightText: 2024 Aravinth Manivannan -// -// 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 UsernameUpdatedEvent { - username: String, -} - -impl UsernameUpdatedEvent { - pub fn new(username: String) -> Self { - Self { username } - } -} diff --git a/src/identity/application/services/update_username/mod.rs b/src/identity/application/services/update_username/mod.rs deleted file mode 100644 index 64f6317..0000000 --- a/src/identity/application/services/update_username/mod.rs +++ /dev/null @@ -1,16 +0,0 @@ -// SPDX-FileCopyrightText: 2024 Aravinth Manivannan -// -// 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 UpdateUsernameUseCase { - async fn update_username( - &self, - cmd: command::UpdateUsernameCommand, - ) -> IdentityResult; -} diff --git a/src/identity/application/services/update_username/service.rs b/src/identity/application/services/update_username/service.rs deleted file mode 100644 index dda58bd..0000000 --- a/src/identity/application/services/update_username/service.rs +++ /dev/null @@ -1,82 +0,0 @@ -// SPDX-FileCopyrightText: 2024 Aravinth Manivannan -// -// SPDX-License-Identifier: AGPL-3.0-or-later - -use super::*; -use derive_builder::Builder; - -use super::*; -use crate::identity::application::port::output::db::username_exists::*; - -#[derive(Builder)] -pub struct UpdateUsernameService { - db_username_exists_adapter: UsernameExistsOutDBPortObj, -} - -#[async_trait::async_trait] -impl UpdateUsernameUseCase for UpdateUsernameService { - async fn update_username( - &self, - cmd: command::UpdateUsernameCommand, - //) -> errors::ProcessAuthorizationServiceResult; - ) -> IdentityResult { - if self - .db_username_exists_adapter - .username_exists(cmd.new_username()) - .await - .unwrap() - { - return Err(IdentityError::UsernameExists); - } - - Ok(events::UsernameUpdatedEvent::new(cmd.new_username().into())) - } -} - -#[cfg(test)] -mod tests { - use super::*; - use crate::tests::bdd::*; - - #[actix_rt::test] - async fn test_service() { - let new_username = "realaravinth"; - let password = "password"; - let config = argon2_creds::Config::default(); - let hashed_password = config.password(password).unwrap(); - - let cmd = command::UpdateUsernameCommand::new( - new_username.into(), - password.into(), - &hashed_password, - &config, - ) - .unwrap(); - - { - let s = UpdateUsernameServiceBuilder::default() - .db_username_exists_adapter(mock_username_exists_db_port( - IS_CALLED_ONLY_ONCE, - RETURNS_FALSE, - )) - .build() - .unwrap(); - let res = s.update_username(cmd.clone()).await.unwrap(); - assert_eq!(res.username(), cmd.new_username()); - } - - { - let s = UpdateUsernameServiceBuilder::default() - .db_username_exists_adapter(mock_username_exists_db_port( - IS_CALLED_ONLY_ONCE, - RETURNS_TRUE, - )) - .build() - .unwrap(); - assert_eq!( - s.update_username(cmd.clone()).await.err(), - Some(IdentityError::UsernameExists) - ); - } - } -}