fix: accept user_id from caller

This commit is contained in:
Aravinth Manivannan 2025-01-22 20:09:50 +05:30
parent b31d3cff75
commit 12ba0c8dd2
Signed by: realaravinth
GPG key ID: F8F50389936984FF
5 changed files with 55 additions and 21 deletions

View file

@ -76,6 +76,7 @@ impl From<IdentityError> for WebError {
IdentityError::StoreIDNotFound => Self::StoreIDNotFound, IdentityError::StoreIDNotFound => Self::StoreIDNotFound,
IdentityError::DuplicateStoreID => Self::DuplicateStoreID, IdentityError::DuplicateStoreID => Self::DuplicateStoreID,
IdentityError::DuplicateRoleID => Self::DuplicateRoleID, IdentityError::DuplicateRoleID => Self::DuplicateRoleID,
IdentityError::DuplicateUserID => Self::InternalError,
IdentityError::DuplicateRoleName => Self::DuplicateRoleName, IdentityError::DuplicateRoleName => Self::DuplicateRoleName,
IdentityError::RoleIDNotFound => Self::RoleIDNotFound, IdentityError::RoleIDNotFound => Self::RoleIDNotFound,
IdentityError::RoleNotFound => Self::RoleNotFound, IdentityError::RoleNotFound => Self::RoleNotFound,

View file

@ -32,6 +32,7 @@ pub enum IdentityError {
DuplicateStoreName, DuplicateStoreName,
StoreIDNotFound, StoreIDNotFound,
DuplicateStoreID, DuplicateStoreID,
DuplicateUserID,
DuplicateRoleID, DuplicateRoleID,
DuplicateRoleName, DuplicateRoleName,
RoleIDNotFound, RoleIDNotFound,

View file

@ -307,7 +307,6 @@ impl IdentityServices {
.db_user_id_exists_adapter(out_db_user_id_exists.clone()) .db_user_id_exists_adapter(out_db_user_id_exists.clone())
.db_create_verification_secret_adapter(out_db_create_verification_secret.clone()) .db_create_verification_secret_adapter(out_db_create_verification_secret.clone())
.mailer_account_validation_link_adapter(out_mailer_account_validating_link.clone()) .mailer_account_validation_link_adapter(out_mailer_account_validating_link.clone())
.get_uuid(get_uuid.clone())
.random_string_adapter(random_string.clone()) .random_string_adapter(random_string.clone())
.build() .build()
.unwrap(), .unwrap(),
@ -488,7 +487,8 @@ mod tests {
use random_number::tests::mock_generate_random_number; use random_number::tests::mock_generate_random_number;
use crate::{ use crate::{
tests::bdd::IS_NEVER_CALLED, identity::adapters::output::db::postgres::DBOutPostgresAdapter,
tests::bdd::{IGNORE_CALL_COUNT, IS_NEVER_CALLED},
utils::{random_string::tests::mock_generate_random_string, uuid::tests::mock_get_uuid}, utils::{random_string::tests::mock_generate_random_string, uuid::tests::mock_get_uuid},
}; };

View file

@ -6,6 +6,7 @@ use super::*;
use derive_builder::Builder; use derive_builder::Builder;
use derive_getters::Getters; use derive_getters::Getters;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use uuid::Uuid;
#[derive( #[derive(
Clone, Debug, Serialize, Deserialize, Builder, Eq, PartialEq, Ord, PartialOrd, Getters, Clone, Debug, Serialize, Deserialize, Builder, Eq, PartialEq, Ord, PartialOrd, Getters,
@ -16,6 +17,7 @@ pub struct UnvalidatedRegisterUserCommand {
email: String, email: String,
password: String, password: String,
confirm_password: String, confirm_password: String,
user_id: Uuid,
} }
#[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq, Ord, PartialOrd, Getters)] #[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq, Ord, PartialOrd, Getters)]
@ -24,6 +26,7 @@ pub struct RegisterUserCommand {
last_name: String, last_name: String,
email: String, email: String,
hashed_password: String, hashed_password: String,
user_id: Uuid,
} }
impl UnvalidatedRegisterUserCommand { impl UnvalidatedRegisterUserCommand {
@ -43,6 +46,7 @@ impl UnvalidatedRegisterUserCommand {
last_name: self.last_name, last_name: self.last_name,
email: self.email, email: self.email,
hashed_password, hashed_password,
user_id: self.user_id,
}) })
} }
} }
@ -50,6 +54,7 @@ impl UnvalidatedRegisterUserCommand {
#[cfg(test)] #[cfg(test)]
pub mod tests { pub mod tests {
use super::*; use super::*;
use crate::utils::uuid::tests::UUID;
pub const PASSWORD: &str = "sadfasdfasdf"; pub const PASSWORD: &str = "sadfasdfasdf";
@ -61,6 +66,7 @@ pub mod tests {
let email = "john@example.com"; let email = "john@example.com";
UnvalidatedRegisterUserCommandBuilder::default() UnvalidatedRegisterUserCommandBuilder::default()
.user_id(UUID)
.first_name(first_name.into()) .first_name(first_name.into())
.last_name(last_name.into()) .last_name(last_name.into())
.email(email.into()) .email(email.into())
@ -83,6 +89,7 @@ pub mod tests {
let wrong_password = "sadfasdfasdf--wrong"; let wrong_password = "sadfasdfasdf--wrong";
UnvalidatedRegisterUserCommandBuilder::default() UnvalidatedRegisterUserCommandBuilder::default()
.user_id(UUID)
.first_name(first_name.into()) .first_name(first_name.into())
.last_name(last_name.into()) .last_name(last_name.into())
.email(email.into()) .email(email.into())
@ -95,6 +102,7 @@ pub mod tests {
assert_eq!( assert_eq!(
UnvalidatedRegisterUserCommandBuilder::default() UnvalidatedRegisterUserCommandBuilder::default()
.user_id(UUID)
.first_name(first_name.into()) .first_name(first_name.into())
.last_name(last_name.into()) .last_name(last_name.into())
.email(first_name.into()) .email(first_name.into())

View file

@ -15,13 +15,12 @@ use crate::utils::{random_string::*, uuid::*};
pub const SECRET_LEN: usize = 20; pub const SECRET_LEN: usize = 20;
pub const REGISTRATION_SECRET_PURPOSE: &str = "account_validation"; pub const REGISTRATION_SECRET_PURPOSE: &str = "account_validation";
#[derive(Builder)] #[derive(Builder, Clone)]
pub struct RegisterUserService { pub struct RegisterUserService {
db_email_exists_adapter: EmailExistsOutDBPortObj, db_email_exists_adapter: EmailExistsOutDBPortObj,
db_user_id_exists_adapter: UserIDExistsOutDBPortObj, db_user_id_exists_adapter: UserIDExistsOutDBPortObj,
db_create_verification_secret_adapter: CreateVerificationSecretOutDBPortObj, db_create_verification_secret_adapter: CreateVerificationSecretOutDBPortObj,
mailer_account_validation_link_adapter: AccountValidationLinkOutMailerPortObj, mailer_account_validation_link_adapter: AccountValidationLinkOutMailerPortObj,
get_uuid: GetUUIDInterfaceObj,
random_string_adapter: GenerateRandomStringInterfaceObj, random_string_adapter: GenerateRandomStringInterfaceObj,
} }
@ -40,18 +39,13 @@ impl RegisterUserUseCase for RegisterUserService {
return Err(IdentityError::DuplicateEmail); return Err(IdentityError::DuplicateEmail);
} }
let mut user_id = self.get_uuid.get_uuid();
loop {
if self if self
.db_user_id_exists_adapter .db_user_id_exists_adapter
.user_id_exists(&user_id) .user_id_exists(cmd.user_id())
.await .await
.unwrap() .unwrap()
{ {
user_id = self.get_uuid.get_uuid(); return Err(IdentityError::DuplicateUserID);
} else {
break;
}
} }
let secret = self.random_string_adapter.get_random(SECRET_LEN); let secret = self.random_string_adapter.get_random(SECRET_LEN);
@ -60,7 +54,7 @@ impl RegisterUserUseCase for RegisterUserService {
.create_verification_secret( .create_verification_secret(
CreateSecretMsgBuilder::default() CreateSecretMsgBuilder::default()
.secret(secret.clone()) .secret(secret.clone())
.user_id(user_id) .user_id(*cmd.user_id())
.build() .build()
.unwrap(), .unwrap(),
) )
@ -75,7 +69,7 @@ impl RegisterUserUseCase for RegisterUserService {
Ok(events::UserRegisteredEventBuilder::default() Ok(events::UserRegisteredEventBuilder::default()
.first_name(cmd.first_name().into()) .first_name(cmd.first_name().into())
.last_name(cmd.last_name().into()) .last_name(cmd.last_name().into())
.user_id(user_id) .user_id(*cmd.user_id())
.email(cmd.email().into()) .email(cmd.email().into())
.hashed_password(cmd.hashed_password().into()) .hashed_password(cmd.hashed_password().into())
.is_verified(false) .is_verified(false)
@ -137,7 +131,6 @@ mod tests {
.mailer_account_validation_link_adapter(mock_account_validation_link_mailer_port( .mailer_account_validation_link_adapter(mock_account_validation_link_mailer_port(
IS_CALLED_ONLY_ONCE, IS_CALLED_ONLY_ONCE,
)) ))
.get_uuid(mock_get_uuid(IS_CALLED_ONLY_ONCE))
.build() .build()
.unwrap(); .unwrap();
@ -157,7 +150,7 @@ mod tests {
let s = RegisterUserServiceBuilder::default() let s = RegisterUserServiceBuilder::default()
.db_user_id_exists_adapter(mock_user_id_exists_db_port( .db_user_id_exists_adapter(mock_user_id_exists_db_port(
IGNORE_CALL_COUNT, IS_CALLED_ONLY_ONCE,
RETURNS_FALSE, RETURNS_FALSE,
)) ))
.db_create_verification_secret_adapter(mock_create_verification_secret_db_port( .db_create_verification_secret_adapter(mock_create_verification_secret_db_port(
@ -171,7 +164,6 @@ mod tests {
.mailer_account_validation_link_adapter(mock_account_validation_link_mailer_port( .mailer_account_validation_link_adapter(mock_account_validation_link_mailer_port(
IS_NEVER_CALLED, IS_NEVER_CALLED,
)) ))
.get_uuid(mock_get_uuid(IS_NEVER_CALLED))
.build() .build()
.unwrap(); .unwrap();
@ -180,4 +172,36 @@ mod tests {
Some(IdentityError::DuplicateEmail) Some(IdentityError::DuplicateEmail)
); );
} }
#[actix_rt::test]
async fn test_register_user_service_user_id_exists() {
let cmd = command::RegisterUserCommand::get_command();
let s = RegisterUserServiceBuilder::default()
.db_user_id_exists_adapter(mock_user_id_exists_db_port(
IS_CALLED_ONLY_ONCE,
RETURNS_TRUE,
))
.db_create_verification_secret_adapter(mock_create_verification_secret_db_port(
IS_NEVER_CALLED,
))
.db_email_exists_adapter(mock_email_exists_db_port(
IS_CALLED_ONLY_ONCE,
RETURNS_FALSE,
))
.random_string_adapter(mock_generate_random_string(
IS_NEVER_CALLED,
RETURNS_RANDOM_STRING.into(),
))
.mailer_account_validation_link_adapter(mock_account_validation_link_mailer_port(
IS_NEVER_CALLED,
))
.build()
.unwrap();
assert_eq!(
s.register_user(cmd.clone()).await.err(),
Some(IdentityError::DuplicateUserID)
);
}
} }