Skip to content

Commit 00f0bf7

Browse files
feat(core.identity): Added new method for verify password against the identity name (#5949)
* Added new method for verify password against the identity name * Fixed copyright * Fixed copyright * Reverted * Fixed since tag location * Update kura/org.eclipse.kura.api/src/main/java/org/eclipse/kura/identity/PasswordStrengthVerificationService.java Co-authored-by: Matteo Maiero <[email protected]> * Added empty check * checkstyle fix * Password is not stored as string in validateNewPassword * Added ignore case to the new validator * Update kura/org.eclipse.kura.core.identity/src/main/java/org/eclipse/kura/core/identity/PasswordStrengthVerificationServiceImpl.java Co-authored-by: Matteo Maiero <[email protected]> * Update kura/test/org.eclipse.kura.core.identity.test/src/main/java/org/eclipse/kura/core/identity/test/PasswordStrengthVerificationServiceImplTest.java Co-authored-by: Matteo Maiero <[email protected]> * Removed requireNoWhitespaceCharacters Added null check on validateNewPassword * Fixed Typo Signed-off-by: MMaiero <[email protected]> * Additional typo fix Signed-off-by: MMaiero <[email protected]> --------- Signed-off-by: MMaiero <[email protected]> Co-authored-by: Matteo Maiero <[email protected]>
1 parent d597953 commit 00f0bf7

File tree

8 files changed

+155
-47
lines changed

8 files changed

+155
-47
lines changed

kura/org.eclipse.kura.api/src/main/java/org/eclipse/kura/identity/PasswordStrengthVerificationService.java

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
/*******************************************************************************
2-
* Copyright (c) 2024 Eurotech and/or its affiliates and others
3-
*
2+
* Copyright (c) 2024, 2025 Eurotech and/or its affiliates and others
3+
*
44
* This program and the accompanying materials are made
55
* available under the terms of the Eclipse Public License 2.0
66
* which is available at https://www.eclipse.org/legal/epl-2.0/
7-
*
7+
*
88
* SPDX-License-Identifier: EPL-2.0
9-
*
9+
*
1010
* Contributors:
1111
* Eurotech
1212
******************************************************************************/
@@ -29,19 +29,39 @@ public interface PasswordStrengthVerificationService {
2929
* Checks whether the provided password satisfies the password strength
3030
* requirements currently configured on the system.
3131
*
32-
* @param password the password to be verified.
33-
* @throws KuraException if the password does not satisfy the current password
34-
* strength requirements.
32+
* @param password
33+
* the password to be verified.
34+
* @throws KuraException
35+
* if the password does not satisfy the current password
36+
* strength requirements.
3537
*/
3638
public void checkPasswordStrength(final char[] password) throws KuraException;
3739

40+
/**
41+
* Similar to {@link #checkPasswordStrength(char[])} checks whether
42+
* the provided password satisfies the password strength requirements currently configured
43+
* on the system and in addition verifies that the password
44+
* does not match the identityName ignoring the characters case.
45+
*
46+
* @param identityName
47+
* the name of the identity
48+
* @param password
49+
* the password to be verified.
50+
* @since 3.0
51+
* @throws KuraException
52+
* if the password does not satisfy the current password
53+
* strength requirements.
54+
*/
55+
public void checkPasswordStrength(String identityName, final char[] password) throws KuraException;
56+
3857
/**
3958
* Returns the password strength requirements that the framework should enforce
4059
* for new passwords.
4160
*
4261
* @return the password strength requirements.
43-
* @throws KuraException if a failure occurs while retrieving the password
44-
* strength requirements.
62+
* @throws KuraException
63+
* if a failure occurs while retrieving the password
64+
* strength requirements.
4565
*/
4666
public PasswordStrengthRequirements getPasswordStrengthRequirements() throws KuraException;
4767
}

kura/org.eclipse.kura.core.identity/src/main/java/org/eclipse/kura/core/identity/IdentityServiceImpl.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2024 Eurotech and/or its affiliates and others
2+
* Copyright (c) 2024, 2025 Eurotech and/or its affiliates and others
33
*
44
* This program and the accompanying materials are made
55
* available under the terms of the Eclipse Public License 2.0
@@ -441,7 +441,8 @@ private void validatePasswordConfiguration(final IdentityConfiguration identityC
441441

442442
if (newPassword.isPresent()) {
443443

444-
ValidationUtil.validateNewPassword(newPassword.get(), passwordStrengthVerificationService);
444+
ValidationUtil.validateNewPassword(identityConfiguration.getName(), newPassword.get(),
445+
passwordStrengthVerificationService);
445446

446447
} else if (!this.userAdminHelper.getUser(identityConfiguration.getName())
447448
.filter(u -> u.getCredentials().get(PASSWORD_PROPERTY) != null).isPresent()) {

kura/org.eclipse.kura.core.identity/src/main/java/org/eclipse/kura/core/identity/PasswordStrengthVerificationServiceImpl.java

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,14 +57,31 @@ public PasswordStrengthRequirements getPasswordStrengthRequirements() {
5757

5858
@Override
5959
public void checkPasswordStrength(char[] password) throws KuraException {
60-
final PasswordStrengthRequirements currentRequirements = getPasswordStrengthRequirements();
60+
List<Validator<String>> validators = buildValidators(null);
61+
checkPasswordStrength(password, validators);
62+
}
63+
64+
@Override
65+
public void checkPasswordStrength(String identityName, char[] password) throws KuraException {
66+
List<Validator<String>> validators = buildValidators(identityName);
67+
checkPasswordStrength(password, validators);
68+
}
6169

62-
ValidatorOptions validatorOptions = new ValidatorOptions(currentRequirements.getPasswordMinimumLength(),
63-
currentRequirements.digitsRequired(), currentRequirements.bothCasesRequired(),
70+
private List<Validator<String>> buildValidators(String identityName) {
71+
PasswordStrengthRequirements currentRequirements = getPasswordStrengthRequirements();
72+
ValidatorOptions validatorOptions = new ValidatorOptions(currentRequirements.getPasswordMinimumLength(), //
73+
currentRequirements.digitsRequired(), //
74+
currentRequirements.bothCasesRequired(), //
6475
currentRequirements.specialCharactersRequired());
6576

66-
final List<Validator<String>> validators = PasswordStrengthValidators.fromConfig(validatorOptions);
77+
List<Validator<String>> validators = new ArrayList<>(PasswordStrengthValidators.fromConfig(validatorOptions));
78+
if (identityName != null && !identityName.trim().isEmpty()) {
79+
validators.add(PasswordStrengthValidators.requireDifferentNameAndPassword(identityName));
80+
}
81+
return validators;
82+
}
6783

84+
private void checkPasswordStrength(char[] password, List<Validator<String>> validators) throws KuraException {
6885
final List<String> errors = new ArrayList<>();
6986

7087
for (final Validator<String> validator : validators) {

kura/org.eclipse.kura.core.identity/src/main/java/org/eclipse/kura/core/identity/ValidationUtil.java

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2024 Eurotech and/or its affiliates and others
2+
* Copyright (c) 2024, 2025 Eurotech and/or its affiliates and others
33
*
44
* This program and the accompanying materials are made
55
* available under the terms of the Eclipse Public License 2.0
@@ -33,19 +33,30 @@ private ValidationUtil() {
3333

3434
public static void validateNewPassword(final char[] password,
3535
final PasswordStrengthVerificationService passwordStrengthVerificationService) throws KuraException {
36-
if (password.length == 0) {
36+
if (password == null || password.length == 0) {
3737
throw new KuraException(KuraErrorCode.INVALID_PARAMETER, "New password cannot be empty");
3838
}
3939

40-
final String asString = new String(password);
40+
requireMaximumLength(NEW_PASSWORD, password, 255);
4141

42-
requireMaximumLength(NEW_PASSWORD, asString, 255);
43-
44-
requireNoWhitespaceCharacters(NEW_PASSWORD, asString);
42+
requireNoWhitespaceCharacters(NEW_PASSWORD, password);
4543

4644
passwordStrengthVerificationService.checkPasswordStrength(password);
4745
}
4846

47+
public static void validateNewPassword(String identityName, final char[] password,
48+
final PasswordStrengthVerificationService passwordStrengthVerificationService) throws KuraException {
49+
if (password == null || password.length == 0) {
50+
throw new KuraException(KuraErrorCode.INVALID_PARAMETER, "New password cannot be empty");
51+
}
52+
53+
requireMaximumLength(NEW_PASSWORD, password, 255);
54+
55+
requireNoWhitespaceCharacters(NEW_PASSWORD, password);
56+
57+
passwordStrengthVerificationService.checkPasswordStrength(identityName, password);
58+
}
59+
4960
public static void validateNewIdentityName(final String identityName) throws KuraException {
5061
requireMinimumLength(IDENTITY_NAME, identityName, 3);
5162

@@ -79,10 +90,18 @@ private static void requireMaximumLength(final String parameterName, final Strin
7990
}
8091
}
8192

82-
private static void requireNoWhitespaceCharacters(final String parameterName, final String value)
93+
private static void requireMaximumLength(final String parameterName, final char[] value, final int length)
94+
throws KuraException {
95+
if (value.length > length) {
96+
throw new KuraException(KuraErrorCode.INVALID_PARAMETER,
97+
parameterName + " must be at most " + length + " characters long");
98+
}
99+
}
100+
101+
private static void requireNoWhitespaceCharacters(final String parameterName, final char[] value)
83102
throws KuraException {
84-
for (int i = 0; i < value.length(); i++) {
85-
if (Character.isWhitespace(value.codePointAt(i))) {
103+
for (int i = 0; i < value.length; i++) {
104+
if (Character.isWhitespace(value[i])) {
86105
throw new KuraException(KuraErrorCode.INVALID_PARAMETER,
87106
parameterName + " cannot contain whitespace characters");
88107
}

kura/org.eclipse.kura.util/src/main/java/org/eclipse/kura/util/validation/PasswordStrengthValidators.java

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2023 Eurotech and/or its affiliates and others
2+
* Copyright (c) 2023, 2025 Eurotech and/or its affiliates and others
33
*
44
* This program and the accompanying materials are made
55
* available under the terms of the Eclipse Public License 2.0
@@ -80,6 +80,12 @@ private static Validator<String> containsBothCases(final Messages messages) {
8080
};
8181
}
8282

83+
public static Validator<String> requireDifferentNameAndPassword(final String identityName) {
84+
85+
return new PredicateValidator(v -> !v.equalsIgnoreCase(identityName),
86+
new DefaultMessages().pwdNotEqualsUsername());
87+
}
88+
8389
public interface Messages {
8490

8591
public String pwdStrengthDigitsRequired();
@@ -89,6 +95,8 @@ public interface Messages {
8995
public String pwdStrengthBothCasesRequired();
9096

9197
public String pwdStrengthMinLength(final int value);
98+
99+
public String pwdNotEqualsUsername();
92100
}
93101

94102
private static class DefaultMessages implements Messages {
@@ -112,6 +120,11 @@ public String pwdStrengthBothCasesRequired() {
112120
public String pwdStrengthMinLength(final int value) {
113121
return "Password length must be at least " + value + " characters";
114122
}
123+
124+
@Override
125+
public String pwdNotEqualsUsername() {
126+
return "The identity name cannot be the same as the password";
127+
}
115128
}
116129

117130
}

kura/test/org.eclipse.kura.core.identity.test/src/main/java/org/eclipse/kura/core/identity/test/IdentityServiceImplTest.java

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -348,7 +348,7 @@ public void shouldRemoveUserPassword() {
348348
@Test
349349
public void shouldSetNeedPasswordChange() {
350350
givenUserAdminUsers("kura.user.foo");
351-
givenPasswordStrenghtVerificationOptions("new.password.min.length", 8, "new.password.require.digits", false,
351+
givenPasswordStrengthVerificationOptions("new.password.min.length", 8, "new.password.require.digits", false,
352352
"new.password.require.special.characters", false, "new.password.require.both.cases", false);
353353

354354
whenIdentityConfigurationIsUpdated(new IdentityConfiguration("foo", singletonList(
@@ -363,7 +363,7 @@ public void shouldSetNeedPasswordChange() {
363363
public void shouldUnsetNeedPasswordChange() {
364364
givenUserAdminUsers("kura.user.foo");
365365
givenUserAdminProperty("kura.user.foo", "kura.need.password.change", "true");
366-
givenPasswordStrenghtVerificationOptions("new.password.min.length", 8, "new.password.require.digits", false,
366+
givenPasswordStrengthVerificationOptions("new.password.min.length", 8, "new.password.require.digits", false,
367367
"new.password.require.special.characters", false, "new.password.require.both.cases", false);
368368

369369
whenIdentityConfigurationIsUpdated(new IdentityConfiguration("foo", singletonList(
@@ -507,10 +507,20 @@ public void shouldNotAllowPasswordContainingTab() {
507507
thenExceptionIsThrown(KuraException.class);
508508
}
509509

510+
@Test
511+
public void shouldNotAllowPasswordEqualsToIdentityName() {
512+
givenUserAdminUsers("kura.user.foo");
513+
514+
whenIdentityConfigurationIsUpdated(new IdentityConfiguration("foo", singletonList(
515+
new PasswordConfiguration(false, true, Optional.of("foo".toCharArray()), Optional.empty()))));
516+
517+
thenExceptionIsThrown(KuraException.class);
518+
}
519+
510520
@Test
511521
public void shouldAllow255CharsPassword() {
512522
givenUserAdminUsers("kura.user.foo");
513-
givenPasswordStrenghtVerificationOptions("new.password.min.length", 8, "new.password.require.digits", false,
523+
givenPasswordStrengthVerificationOptions("new.password.min.length", 8, "new.password.require.digits", false,
514524
"new.password.require.special.characters", false, "new.password.require.both.cases", false);
515525

516526
whenIdentityConfigurationIsUpdated(new IdentityConfiguration("foo", singletonList(
@@ -522,7 +532,7 @@ public void shouldAllow255CharsPassword() {
522532
@Test
523533
public void shouldNotAllowTooLongPassword() {
524534
givenUserAdminUsers("kura.user.foo");
525-
givenPasswordStrenghtVerificationOptions("new.password.min.length", 8, "new.password.require.digits", false,
535+
givenPasswordStrengthVerificationOptions("new.password.min.length", 8, "new.password.require.digits", false,
526536
"new.password.require.special.characters", false, "new.password.require.both.cases", false);
527537

528538
whenIdentityConfigurationIsUpdated(new IdentityConfiguration("foo", singletonList(
@@ -533,7 +543,7 @@ public void shouldNotAllowTooLongPassword() {
533543

534544
@Test
535545
public void shouldNotAllowPasswordNotSatisfyingPasswordStrengthRequirements() {
536-
givenPasswordStrenghtVerificationOptions("new.password.min.length", 3, "new.password.require.digits", false,
546+
givenPasswordStrengthVerificationOptions("new.password.min.length", 3, "new.password.require.digits", false,
537547
"new.password.require.special.characters", false, "new.password.require.both.cases", false);
538548
givenUserAdminUsers("kura.user.foo");
539549

kura/test/org.eclipse.kura.core.identity.test/src/main/java/org/eclipse/kura/core/identity/test/IdentityServiceTestBase.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ public abstract class IdentityServiceTestBase {
3131

3232
private final ConfigurationService configurationService;
3333

34-
protected void givenPasswordStrenghtVerificationOptions(final Object... values) {
34+
protected void givenPasswordStrengthVerificationOptions(final Object... values) {
3535

3636
final Iterator<Object> iter = Arrays.asList(values).iterator();
3737

0 commit comments

Comments
 (0)