Skip to content

Commit 03f97ec

Browse files
committed
wip
1 parent 45aba38 commit 03f97ec

File tree

2 files changed

+71
-9
lines changed

2 files changed

+71
-9
lines changed

src/services/user.rs

+44-9
Original file line numberDiff line numberDiff line change
@@ -410,9 +410,26 @@ impl ListingService {
410410
pub struct AdminActionsService {
411411
authorization_service: Arc<authorization::Service>,
412412
user_authentication_repository: Arc<DbUserAuthenticationRepository>,
413+
user_profile_repository: Arc<DbUserProfileRepository>,
414+
mailer: Arc<mailer::Service>,
413415
}
414416

415417
impl AdminActionsService {
418+
#[must_use]
419+
pub fn new(
420+
authorization_service: Arc<authorization::Service>,
421+
user_authentication_repository: Arc<DbUserAuthenticationRepository>,
422+
user_profile_repository: Arc<DbUserProfileRepository>,
423+
mailer: Arc<mailer::Service>,
424+
) -> Self {
425+
Self {
426+
authorization_service,
427+
user_authentication_repository,
428+
user_profile_repository,
429+
mailer,
430+
}
431+
}
432+
416433
/// Resets the password of the selected user.
417434
///
418435
/// # Errors
@@ -426,25 +443,43 @@ impl AdminActionsService {
426443
/// * An error if unable to successfully hash the password.
427444
/// * An error if unable to change the password in the database.
428445
/// * An error if it is not possible to authorize the action
429-
pub async fn reset_user_password(&self, maybe_user_id: Option<UserId>, user_info: UserProfile) -> Result<(), ServiceError> {
446+
pub async fn reset_user_password(
447+
&self,
448+
maybe_admin_user_id: Option<UserId>,
449+
reset_password_user_id: UserId,
450+
) -> Result<(), ServiceError> {
430451
self.authorization_service
431452
.authorize(ACTION::ResetUserPassword, maybe_user_id)
432453
.await?;
433454

434-
info!("Resetting user password for user ID: {}", user_info.username);
455+
if let Some(email) = Some(&user_info.email) {
456+
if user_info.email_verified {
457+
info!("Resetting user password for user ID: {}", user_info.username);
435458

436-
let new_password = generate_random_password();
459+
let new_password = generate_random_password();
437460

438-
let password_hash = hash_password(&new_password)?;
461+
let password_hash = hash_password(&new_password)?;
439462

440-
self.user_authentication_repository
441-
.change_password(user_info.user_id, &password_hash)
442-
.await?;
463+
self.user_authentication_repository
464+
.change_password(user_info.user_id, &password_hash)
465+
.await?;
443466

444-
Ok(())
467+
let mail_res = self
468+
.mailer
469+
.send_reset_password_mail(email, &user_info.username, &new_password)
470+
.await;
471+
472+
if mail_res.is_err() {
473+
return Err(ServiceError::FailedToSendResetPassword);
474+
}
475+
476+
()
477+
}
478+
return Err(ServiceError::VerifiedEmailMissing);
479+
}
480+
Err(ServiceError::EmailMissing)
445481
}
446482
}
447-
448483
#[cfg_attr(test, automock)]
449484
#[async_trait]
450485
pub trait Repository: Sync + Send {

src/web/api/server/v1/contexts/user/handlers.rs

+27
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,33 @@ pub async fn change_password_handler(
151151
}
152152
}
153153

154+
/// It changes the user's password.
155+
///
156+
/// # Errors
157+
///
158+
/// It returns an error if:
159+
///
160+
/// - The user account is not found.
161+
#[allow(clippy::unused_async)]
162+
#[allow(clippy::missing_panics_doc)]
163+
pub async fn reset_password_handler(
164+
State(app_data): State<Arc<AppData>>,
165+
ExtractOptionalLoggedInUser(maybe_user_id): ExtractOptionalLoggedInUser,
166+
extract::Json(change_password_form): extract::Json<ChangePasswordForm>,
167+
) -> Response {
168+
match app_data
169+
.profile_service
170+
.change_password(maybe_user_id, &change_password_form)
171+
.await
172+
{
173+
Ok(()) => Json(OkResponseData {
174+
data: format!("Password changed for user with ID: {}", maybe_user_id.unwrap()),
175+
})
176+
.into_response(),
177+
Err(error) => error.into_response(),
178+
}
179+
}
180+
154181
/// It bans a user from the index.
155182
///
156183
/// # Errors

0 commit comments

Comments
 (0)