From b6304193f0c4f9c4e433cb6226c8ca771df45de7 Mon Sep 17 00:00:00 2001 From: Aravinth Manivannan Date: Thu, 16 May 2024 19:49:42 +0530 Subject: [PATCH] feat: register user service --- .../services/create_user/command.rs | 1 - .../application/services/create_user/error.rs | 1 - .../application/services/create_user/mod.rs | 3 - .../services/create_user/service.rs | 1 - .../services/register_user/command.rs | 76 +++++++++++++++++++ .../services/register_user/error.rs | 3 + .../services/register_user/events.rs | 11 +++ .../application/services/register_user/mod.rs | 17 +++++ .../services/register_user/service.rs | 57 ++++++++++++++ 9 files changed, 164 insertions(+), 6 deletions(-) delete mode 100644 src/identity/application/services/create_user/command.rs delete mode 100644 src/identity/application/services/create_user/error.rs delete mode 100644 src/identity/application/services/create_user/mod.rs delete mode 100644 src/identity/application/services/create_user/service.rs create mode 100644 src/identity/application/services/register_user/command.rs create mode 100644 src/identity/application/services/register_user/error.rs create mode 100644 src/identity/application/services/register_user/events.rs create mode 100644 src/identity/application/services/register_user/mod.rs create mode 100644 src/identity/application/services/register_user/service.rs diff --git a/src/identity/application/services/create_user/command.rs b/src/identity/application/services/create_user/command.rs deleted file mode 100644 index 8b13789..0000000 --- a/src/identity/application/services/create_user/command.rs +++ /dev/null @@ -1 +0,0 @@ - diff --git a/src/identity/application/services/create_user/error.rs b/src/identity/application/services/create_user/error.rs deleted file mode 100644 index 8b13789..0000000 --- a/src/identity/application/services/create_user/error.rs +++ /dev/null @@ -1 +0,0 @@ - diff --git a/src/identity/application/services/create_user/mod.rs b/src/identity/application/services/create_user/mod.rs deleted file mode 100644 index b0fe443..0000000 --- a/src/identity/application/services/create_user/mod.rs +++ /dev/null @@ -1,3 +0,0 @@ -mod command; -mod service; -mod error; diff --git a/src/identity/application/services/create_user/service.rs b/src/identity/application/services/create_user/service.rs deleted file mode 100644 index 8b13789..0000000 --- a/src/identity/application/services/create_user/service.rs +++ /dev/null @@ -1 +0,0 @@ - diff --git a/src/identity/application/services/register_user/command.rs b/src/identity/application/services/register_user/command.rs new file mode 100644 index 0000000..f4af68e --- /dev/null +++ b/src/identity/application/services/register_user/command.rs @@ -0,0 +1,76 @@ +// 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, Eq, PartialEq, Ord, PartialOrd, Getters)] +pub struct RegisterUserCommand { + username: String, + email: String, + hashed_password: String, +} + +impl RegisterUserCommand { + pub fn new( + username: String, + email: String, + password: String, + confirm_password: String, + config: &argon2_creds::Config, + ) -> Self { + let username = config.username(&username).unwrap(); + config.email(&email).unwrap(); + + if password != confirm_password { + todo!("Passwords Don't match"); + } + let hashed_password: String = config.password(&password).unwrap(); + + Self { + username, + email, + hashed_password, + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_cmd() { + let config = argon2_creds::Config::default(); + RegisterUserCommand::new( + "realaravinth".into(), + "realaravinth@example.com".into(), + "asdfasdfasdfasdf".into(), + "asdfasdfasdfasdf".into(), + &config, + ); + let result = std::panic::catch_unwind(|| + RegisterUserCommand::new( + "username".into(), + "username@example.com".into(), + "password".into(), + "password".into(), + &config, + ) + ); // TODO: check for error, and not panic when err handling is implemented + assert!(result.is_err()); // Blacklist error + + let result = std::panic::catch_unwind(|| + RegisterUserCommand::new( + "realaravinth".into(), + "realaravinth@example.com".into(), + "password".into(), + "mismatch_password".into(), + &config, + ) + ); // TODO: check for error, and not panic when err handling is implemented + assert!(result.is_err()); + + } +} diff --git a/src/identity/application/services/register_user/error.rs b/src/identity/application/services/register_user/error.rs new file mode 100644 index 0000000..56f60de --- /dev/null +++ b/src/identity/application/services/register_user/error.rs @@ -0,0 +1,3 @@ +// SPDX-FileCopyrightText: 2024 Aravinth Manivannan +// +// SPDX-License-Identifier: AGPL-3.0-or-later diff --git a/src/identity/application/services/register_user/events.rs b/src/identity/application/services/register_user/events.rs new file mode 100644 index 0000000..09acb18 --- /dev/null +++ b/src/identity/application/services/register_user/events.rs @@ -0,0 +1,11 @@ +use derive_getters::Getters; +use derive_builder::Builder; +use serde::{Deserialize, Serialize}; + +#[derive(Clone, Debug, Builder, Serialize, Deserialize, Getters, Eq, PartialEq, Ord, PartialOrd)] +pub struct UserRegisteredEvent { + username: String, + email: String, + hashed_password: String, + is_verified: bool, +} diff --git a/src/identity/application/services/register_user/mod.rs b/src/identity/application/services/register_user/mod.rs new file mode 100644 index 0000000..5dc6f6b --- /dev/null +++ b/src/identity/application/services/register_user/mod.rs @@ -0,0 +1,17 @@ +// SPDX-FileCopyrightText: 2024 Aravinth Manivannan +// +// SPDX-License-Identifier: AGPL-3.0-or-later + +pub mod command; +pub mod error; +pub mod events; +pub mod service; + +#[async_trait::async_trait] +pub trait RegisterUserUseCase { + async fn register_user( + &self, + cmd: command::RegisterUserCommand, + //) -> errors::ProcessAuthorizationServiceResult; + ) -> events::UserRegisteredEvent; +} diff --git a/src/identity/application/services/register_user/service.rs b/src/identity/application/services/register_user/service.rs new file mode 100644 index 0000000..44a2b66 --- /dev/null +++ b/src/identity/application/services/register_user/service.rs @@ -0,0 +1,57 @@ +// SPDX-FileCopyrightText: 2024 Aravinth Manivannan +// +// SPDX-License-Identifier: AGPL-3.0-or-later + +// - Hash password +// - Add user record +// - Send verification email +// - If UID == 0; set admin + +use super::*; + +struct RegisterUserService; + +#[async_trait::async_trait] +impl RegisterUserUseCase for RegisterUserService { + async fn register_user( + &self, + cmd: command::RegisterUserCommand, + //) -> errors::ProcessAuthorizationServiceResult; + ) -> events::UserRegisteredEvent { + + events::UserRegisteredEventBuilder::default() + .username(cmd.username().into()) + .email(cmd.email().into()) + .hashed_password(cmd.hashed_password().into()) + .is_verified(false) + .build().unwrap() + + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[actix_rt::test] + async fn test_service() { + let username = "realaravinth"; + let email = format!("{username}@example.com"); + let password = "password"; + let config = argon2_creds::Config::default(); + let cmd = command::RegisterUserCommand::new( + username.into(), + email.clone(), + password.into(), + password.into(), + &config, + ); + + let s = RegisterUserService; + let res = s.register_user(cmd.clone()).await; + assert_eq!(res.username(), cmd.username()); + assert_eq!(res.email(), cmd.email()); + assert!(argon2_creds::Config::verify(res.hashed_password(), password).unwrap()) + + } +}