From 5e37eb4d1d5cd320972a3e604479e248fd70e69e Mon Sep 17 00:00:00 2001 From: RIHTARSIC Joze <joze.rihtarsic@ext.ec.europa.eu> Date: Wed, 29 May 2024 18:37:11 +0200 Subject: [PATCH] [EDELIVERY-13367] SA report --- .../password-change-dialog.component.ts | 2 +- .../smp/config/enums/SMPPropertyEnum.java | 2 +- .../smp/services/ui/UIUserService.java | 9 +++++++++ .../ui/UIUserServiceIntegrationTest.java | 18 ++++++++++++++++++ 4 files changed, 29 insertions(+), 2 deletions(-) diff --git a/smp-angular/src/app/common/dialogs/password-change-dialog/password-change-dialog.component.ts b/smp-angular/src/app/common/dialogs/password-change-dialog/password-change-dialog.component.ts index a2c20e30e..3da5f58d4 100644 --- a/smp-angular/src/app/common/dialogs/password-change-dialog/password-change-dialog.component.ts +++ b/smp-angular/src/app/common/dialogs/password-change-dialog/password-change-dialog.component.ts @@ -47,7 +47,7 @@ export class PasswordChangeDialogComponent { let currentPasswdFormControl: UntypedFormControl = new UntypedFormControl({value: null, readonly: false}, this.securityService.getCurrentUser().casAuthenticated && this.adminUser ? null : [Validators.required]); let newPasswdFormControl: UntypedFormControl = new UntypedFormControl({value: null, readonly: false}, - [Validators.required, Validators.pattern(this.passwordValidationRegExp), equal(currentPasswdFormControl, false)]); + [Validators.required, Validators.pattern(this.passwordValidationRegExp)]); let confirmNewPasswdFormControl: UntypedFormControl = new UntypedFormControl({value: null, readonly: false}, [Validators.required, equal(newPasswdFormControl, true)]); diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/config/enums/SMPPropertyEnum.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/config/enums/SMPPropertyEnum.java index 1c4d8c55a..bf5c78633 100644 --- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/config/enums/SMPPropertyEnum.java +++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/config/enums/SMPPropertyEnum.java @@ -154,7 +154,7 @@ public enum SMPPropertyEnum { "Password minimum complexity rules!", OPTIONAL, NOT_ENCRYPTED, NO_RESTART_NEEDED, REGEXP), - PASSWORD_POLICY_MESSAGE("smp.passwordPolicy.validationMessage", "Minimum length: 16 characters;Maximum length: 32 characters;At least one letter in lowercase;At least one letter in uppercase;At least one digit;At least one special character", + PASSWORD_POLICY_MESSAGE("smp.passwordPolicy.validationMessage", "Minimum length: 16 characters;Maximum length: 32 characters;At least one letter in lowercase;At least one letter in uppercase;At least one digit;At least one special character;Must not be same as existing password", "The error message shown to the user in case the password does not follow the regex put in the domibus.passwordPolicy.pattern property", OPTIONAL, NOT_ENCRYPTED, NO_RESTART_NEEDED, STRING), PASSWORD_POLICY_VALID_DAYS("smp.passwordPolicy.validDays", "90", "Number of days password is valid", diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UIUserService.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UIUserService.java index 62599cc6e..829d46433 100644 --- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UIUserService.java +++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UIUserService.java @@ -246,6 +246,15 @@ public class UIUserService extends UIServiceBase<DBUser, UserRO> { CredentialType.USERNAME_PASSWORD, CredentialTargetType.UI)); + // check if new password is the same as the old one + // but allow admin to overwrite it + if (!adminUpdate + && StringUtils.isNotBlank(dbCredential.getValue()) + && BCrypt.checkpw(password, dbCredential.getValue())) { + LOG.info(SMPLogger.SECURITY_MARKER, "Change/set password failed because 'new' password match the old password for user: [{}]", userID); + throw new SMPRuntimeException(ErrorCode.INVALID_REQUEST, "PasswordChange", configurationService.getPasswordPolicyValidationMessage()); + } + dbCredential.setValue(BCryptPasswordHash.hashPassword(password)); OffsetDateTime currentTime = OffsetDateTime.now(); dbCredential.setChangedOn(currentTime); diff --git a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/ui/UIUserServiceIntegrationTest.java b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/ui/UIUserServiceIntegrationTest.java index 3ef1ec67c..fe9c78cb2 100644 --- a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/ui/UIUserServiceIntegrationTest.java +++ b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/ui/UIUserServiceIntegrationTest.java @@ -250,6 +250,24 @@ class UIUserServiceIntegrationTest extends AbstractJunit5BaseDao { testInstance.updateUserPassword(authorizedUserId, userToUpdateId, authorizedPassword, newPassword); } + @Test + void testUpdateUserPasswordFaileSame() { + DBUser user = TestDBUtils.createDBUserByUsername(UUID.randomUUID().toString()); + DBCredential credential = TestDBUtils.createDBCredentialForUser(user, null, null, null); + credential.setValue(BCrypt.hashpw("TTTTtttt1111$$$$$", BCrypt.gensalt())); + userDao.persistFlushDetach(user); + credentialDao.persistFlushDetach(credential); + + long authorizedUserId = user.getId(); + long userToUpdateId = user.getId(); + String authorizedPassword = "TTTTtttt1111$$$$$"; + String newPassword = "TTTTtttt1111$$$$$"; + + SMPRuntimeException result = assertThrows(SMPRuntimeException.class, + () -> testInstance.updateUserPassword(authorizedUserId, userToUpdateId, authorizedPassword, newPassword)); + MatcherAssert.assertThat(result.getMessage(), CoreMatchers.containsString("Must not be same as existing password")); + } + @Test void testUpdateUserPasswordByAdminUserNotExists() { // system admin -- GitLab