Create password policies configurations (#6567)

Co-authored-by: João Paraquetti <joao@scclouds.com.br>
This commit is contained in:
João Jandre 2022-08-03 11:09:00 -03:00 committed by GitHub
parent ddb11b1b96
commit 117ce1aac4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 549 additions and 0 deletions

View File

@ -301,6 +301,9 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
@Inject
private RoleService roleService;
@Inject
private PasswordPolicy passwordPolicy;
private final ScheduledExecutorService _executor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("AccountChecker"));
private int _allowedLoginAttempts;
@ -1368,6 +1371,9 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
if (StringUtils.isBlank(newPassword)) {
throw new InvalidParameterValueException("Password cannot be empty or blank.");
}
passwordPolicy.verifyIfPasswordCompliesWithPasswordPolicies(newPassword, user.getUsername(), getAccount(user.getAccountId()).getDomainId());
Account callingAccount = getCurrentCallingAccount();
boolean isRootAdminExecutingPasswordUpdate = callingAccount.getId() == Account.ACCOUNT_ID_SYSTEM || isRootAdmin(callingAccount.getId());
boolean isDomainAdmin = isDomainAdmin(callingAccount.getId());
@ -2342,6 +2348,8 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
s_logger.debug("Creating user: " + userName + ", accountId: " + accountId + " timezone:" + timezone);
}
passwordPolicy.verifyIfPasswordCompliesWithPasswordPolicies(password, userName, getAccount(accountId).getDomainId());
String encodedPassword = null;
for (UserAuthenticator authenticator : _userPasswordEncoders) {
encodedPassword = authenticator.encode(password);

View File

@ -0,0 +1,91 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package com.cloud.user;
import org.apache.cloudstack.framework.config.ConfigKey;
public interface PasswordPolicy {
ConfigKey<Integer> PasswordPolicyMinimumSpecialCharacters = new ConfigKey<>(
"Advanced",
Integer.class,
"password.policy.minimum.special.characters",
"0",
"Minimum number of special characters that the user's password must have. The value 0 means the user's password does not require any special characters.",
true,
ConfigKey.Scope.Domain);
ConfigKey<Integer> PasswordPolicyMinimumLength = new ConfigKey<>(
"Advanced",
Integer.class,
"password.policy.minimum.length",
"0",
"Minimum length that the user's password must have. The value 0 means the user's password can have any length.",
true,
ConfigKey.Scope.Domain);
ConfigKey<Integer> PasswordPolicyMinimumUppercaseLetters = new ConfigKey<>(
"Advanced",
Integer.class,
"password.policy.minimum.uppercase.letters",
"0",
"Minimum number of uppercase letters that the user's password must have. The value 0 means the user's password does not require any uppercase letters.",
true,
ConfigKey.Scope.Domain);
ConfigKey<Integer> PasswordPolicyMinimumLowercaseLetters = new ConfigKey<>(
"Advanced",
Integer.class,
"password.policy.minimum.lowercase.letters",
"0",
"Minimum number of lowercase letters that the user's password must have. The value 0 means the user's password does not require any lowercase letters.",
true,
ConfigKey.Scope.Domain);
ConfigKey<Integer> PasswordPolicyMinimumDigits = new ConfigKey<>(
"Advanced",
Integer.class,
"password.policy.minimum.digits",
"0",
"Minimum number of digits that the user's password must have. The value 0 means the user's password does not require any digits.",
true,
ConfigKey.Scope.Domain);
ConfigKey<Boolean> PasswordPolicyAllowPasswordToContainUsername = new ConfigKey<>(
"Advanced",
Boolean.class,
"password.policy.allowPasswordToContainUsername",
"true",
"Indicates if the user's password may contain their username. Set 'true' (default) if it is allowed, otherwise set 'false'.",
true,
ConfigKey.Scope.Domain);
ConfigKey<String> PasswordPolicyRegex = new ConfigKey<>(
"Advanced",
String.class,
"password.policy.regex",
".+",
"A regular expression that the user's password must match. The default expression '.+' will match with any password.",
true,
ConfigKey.Scope.Domain);
/**
* Checks if a given user's password complies with the configured password policies.
* If it does not comply, a {@link com.cloud.exception.InvalidParameterValueException} will be thrown.
* */
void verifyIfPasswordCompliesWithPasswordPolicies(String password, String username, Long domainID);
}

View File

@ -0,0 +1,245 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package com.cloud.user;
import com.cloud.exception.InvalidParameterValueException;
import org.apache.cloudstack.framework.config.ConfigKey;
import org.apache.cloudstack.framework.config.Configurable;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
public class PasswordPolicyImpl implements PasswordPolicy, Configurable {
private Logger logger = Logger.getLogger(PasswordPolicyImpl.class);
public void verifyIfPasswordCompliesWithPasswordPolicies(String password, String username, Long domainId) {
int numberOfSpecialCharactersInPassword = 0;
int numberOfUppercaseLettersInPassword = 0;
int numberOfLowercaseLettersInPassword = 0;
int numberOfDigitsInPassword = 0;
char[] splitPassword = password.toCharArray();
for (char character: splitPassword) {
if (!Character.isLetterOrDigit(character)) {
numberOfSpecialCharactersInPassword++;
} else if (Character.isUpperCase(character)) {
numberOfUppercaseLettersInPassword++;
} else if (Character.isLowerCase(character)) {
numberOfLowercaseLettersInPassword++;
} else if (Character.isDigit(character)) {
numberOfDigitsInPassword++;
}
}
validateIfPasswordContainsTheMinimumNumberOfSpecialCharacters(numberOfSpecialCharactersInPassword, username, domainId);
validateIfPasswordContainsTheMinimumNumberOfUpperCaseLetters(numberOfUppercaseLettersInPassword, username, domainId);
validateIfPasswordContainsTheMinimumNumberOfLowerCaseLetters(numberOfLowercaseLettersInPassword, username, domainId);
validateIfPasswordContainsTheMinimumNumberOfDigits(numberOfDigitsInPassword, username, domainId);
validateIfPasswordContainsTheMinimumLength(password, username, domainId);
validateIfPasswordContainsTheUsername(password, username, domainId);
validateIfPasswordMatchesRegex(password, username, domainId);
}
protected void validateIfPasswordContainsTheMinimumNumberOfSpecialCharacters(int numberOfSpecialCharactersInPassword, String username, Long domainId) {
Integer passwordPolicyMinimumSpecialCharacters = getPasswordPolicyMinimumSpecialCharacters(domainId);
logger.trace(String.format("Validating if the new password for user [%s] contains the minimum number of special characters [%s] defined in the configuration [%s].",
username, passwordPolicyMinimumSpecialCharacters, PasswordPolicyMinimumSpecialCharacters.key()));
if (passwordPolicyMinimumSpecialCharacters == 0) {
logger.trace(String.format("The minimum number of special characters for a user's password is 0; therefore, we will not validate the number of special characters for"
+ " the new password of user [%s].", username));
return;
}
if (numberOfSpecialCharactersInPassword < passwordPolicyMinimumSpecialCharacters) {
logger.error(String.format("User [%s] informed [%d] special characters for their new password; however, the minimum number of special characters is [%d]. "
+ "Refusing the user's new password.", username, numberOfSpecialCharactersInPassword, passwordPolicyMinimumSpecialCharacters));
throw new InvalidParameterValueException(String.format("User password should contain at least [%d] special characters.", passwordPolicyMinimumSpecialCharacters));
}
logger.trace(String.format("The new password for user [%s] complies with the policy of minimum special characters [%s].", username,
PasswordPolicyMinimumSpecialCharacters.key()));
}
protected void validateIfPasswordContainsTheMinimumNumberOfUpperCaseLetters(int numberOfUppercaseLettersInPassword, String username, Long domainId) {
Integer passwordPolicyMinimumUpperCaseLetters = getPasswordPolicyMinimumUpperCaseLetters(domainId);
logger.trace(String.format("Validating if the new password for user [%s] contains the minimum number of upper case letters [%s] defined in the configuration [%s].",
username, passwordPolicyMinimumUpperCaseLetters, PasswordPolicyMinimumUppercaseLetters.key()));
if (passwordPolicyMinimumUpperCaseLetters == 0) {
logger.trace(String.format("The minimum number of upper case letters for a user's password is 0; therefore, we will not validate the number of upper case letters for"
+ " the new password of user [%s].", username));
return;
}
if (numberOfUppercaseLettersInPassword < passwordPolicyMinimumUpperCaseLetters) {
logger.error(String.format("User [%s] informed [%d] upper case letters for their new password; however, the minimum number of upper case letters is [%d]. "
+ "Refusing the user's new password.", username, numberOfUppercaseLettersInPassword, passwordPolicyMinimumUpperCaseLetters));
throw new InvalidParameterValueException(String.format("User password should contain at least [%d] upper case letters.", passwordPolicyMinimumUpperCaseLetters));
}
logger.trace(String.format("The new password for user [%s] complies with the policy of minimum upper case letters [%s].", username,
PasswordPolicyMinimumUppercaseLetters.key()));
}
protected void validateIfPasswordContainsTheMinimumNumberOfLowerCaseLetters(int numberOfLowercaseLettersInPassword, String username, Long domainId) {
Integer passwordPolicyMinimumLowerCaseLetters = getPasswordPolicyMinimumLowerCaseLetters(domainId);
logger.trace(String.format("Validating if the new password for user [%s] contains the minimum number of lower case letters [%s] defined in the configuration [%s].",
username, passwordPolicyMinimumLowerCaseLetters, PasswordPolicyMinimumLowercaseLetters.key()));
if (passwordPolicyMinimumLowerCaseLetters == 0) {
logger.trace(String.format("The minimum number of lower case letters for a user's password is 0; therefore, we will not validate the number of lower case letters for"
+ " the new password of user [%s].", username));
return;
}
if (numberOfLowercaseLettersInPassword < passwordPolicyMinimumLowerCaseLetters) {
logger.error(String.format("User [%s] informed [%d] lower case letters for their new password; however, the minimum number of lower case letters is [%d]. "
+ "Refusing the user's new password.", username, numberOfLowercaseLettersInPassword, passwordPolicyMinimumLowerCaseLetters));
throw new InvalidParameterValueException(String.format("User password should contain at least [%d] lower case letters.", passwordPolicyMinimumLowerCaseLetters));
}
logger.trace(String.format("The new password for user [%s] complies with the policy of minimum lower case letters [%s].", username,
PasswordPolicyMinimumLowercaseLetters.key()));
}
protected void validateIfPasswordContainsTheMinimumNumberOfDigits(int numberOfDigitsInPassword, String username, Long domainId) {
Integer passwordPolicyMinimumDigits = getPasswordPolicyMinimumDigits(domainId);
logger.trace(String.format("Validating if the new password for user [%s] contains the minimum number of digits [%s] defined in the configuration [%s].",
username, passwordPolicyMinimumDigits, PasswordPolicyMinimumDigits.key()));
if (passwordPolicyMinimumDigits == 0) {
logger.trace(String.format("The minimum number of digits for a user's password is 0; therefore, we will not validate the number of digits for the new password of"
+ " user [%s].", username));
return;
}
if (numberOfDigitsInPassword < passwordPolicyMinimumDigits) {
logger.error(String.format("User [%s] informed [%d] digits for their new password; however, the minimum number of digits is [%d]. "
+ "Refusing the user's new password.", username, numberOfDigitsInPassword, passwordPolicyMinimumDigits));
throw new InvalidParameterValueException(String.format("User password should contain at least [%d] digits.", passwordPolicyMinimumDigits));
}
logger.trace(String.format("The new password for user [%s] complies with the policy of minimum digits [%s].", username, PasswordPolicyMinimumDigits.key()));
}
protected void validateIfPasswordContainsTheMinimumLength(String password, String username, Long domainId) {
Integer passwordPolicyMinimumLength = getPasswordPolicyMinimumLength(domainId);
logger.trace(String.format("Validating if the new password for user [%s] contains the minimum length [%s] defined in the configuration [%s].", username,
passwordPolicyMinimumLength, PasswordPolicyMinimumLength.key()));
if (passwordPolicyMinimumLength == 0) {
logger.trace(String.format("The minimum length of a user's password is 0; therefore, we will not validate the length of the new password of user [%s].", username));
return;
}
Integer passwordLength = password.length();
if (passwordLength < passwordPolicyMinimumLength) {
logger.error(String.format("User [%s] informed [%d] characters for their new password; however, the minimum password length is [%d]. Refusing the user's new password.",
username, passwordLength, passwordPolicyMinimumLength));
throw new InvalidParameterValueException(String.format("User password should contain at least [%d] characters.", passwordPolicyMinimumLength));
}
logger.trace(String.format("The new password for user [%s] complies with the policy of minimum length [%s].", username, PasswordPolicyMinimumLength.key()));
}
protected void validateIfPasswordContainsTheUsername(String password, String username, Long domainId) {
logger.trace(String.format("Validating if the new password for user [%s] contains their username.", username));
if (getPasswordPolicyAllowPasswordToContainUsername(domainId)) {
logger.trace(String.format("Allow password to contain username is true; therefore, we will not validate if the password contains the username of user [%s].", username));
return;
}
if (StringUtils.containsIgnoreCase(password, username)) {
logger.error(String.format("User [%s] informed a new password that contains their username; however, the this is not allowed as configured in [%s]. "
+ "Refusing the user's new password.", username, PasswordPolicyAllowPasswordToContainUsername.key()));
throw new InvalidParameterValueException("User password should not contain their username.");
}
logger.trace(String.format("The new password for user [%s] complies with the policy of allowing passwords to contain username [%s].", username,
PasswordPolicyAllowPasswordToContainUsername.key()));
}
protected void validateIfPasswordMatchesRegex(String password, String username, Long domainId) {
String passwordPolicyRegex = getPasswordPolicyRegex(domainId);
logger.trace(String.format("Validating if the new password for user [%s] matches regex [%s] defined in the configuration [%s].",
username, passwordPolicyRegex, PasswordPolicyRegex.key()));
if (passwordPolicyRegex == null){
logger.trace(String.format("Regex is null; therefore, we will not validate if the new password matches with regex for user [%s].", username));
return;
}
if (!password.matches(passwordPolicyRegex)){
logger.error(String.format("User [%s] informed a new password that does not match with regex [%s]. Refusing the user's new password.", username, passwordPolicyRegex));
throw new InvalidParameterValueException("User password does not match with password policy regex.");
}
logger.trace(String.format("The new password for user [%s] complies with the policy of matching regex [%s].", username,
PasswordPolicyRegex.key()));
}
@Override
public String getConfigComponentName() {
return PasswordPolicyImpl.class.getSimpleName();
}
@Override
public ConfigKey<?>[] getConfigKeys() {
return new ConfigKey<?>[]{PasswordPolicyMinimumLength, PasswordPolicyMinimumSpecialCharacters, PasswordPolicyMinimumUppercaseLetters, PasswordPolicyMinimumLowercaseLetters,
PasswordPolicyMinimumDigits, PasswordPolicyAllowPasswordToContainUsername, PasswordPolicyRegex
};
}
public Integer getPasswordPolicyMinimumLength(Long domainId) {
return PasswordPolicyMinimumLength.valueIn(domainId);
}
public Integer getPasswordPolicyMinimumSpecialCharacters(Long domainId) {
return PasswordPolicyMinimumSpecialCharacters.valueIn(domainId);
}
public Integer getPasswordPolicyMinimumUpperCaseLetters(Long domainId) {
return PasswordPolicyMinimumUppercaseLetters.valueIn(domainId);
}
public Integer getPasswordPolicyMinimumLowerCaseLetters(Long domainId) {
return PasswordPolicyMinimumLowercaseLetters.valueIn(domainId);
}
public Integer getPasswordPolicyMinimumDigits(Long domainId) {
return PasswordPolicyMinimumDigits.valueIn(domainId);
}
public Boolean getPasswordPolicyAllowPasswordToContainUsername(Long domainId) {
return PasswordPolicyAllowPasswordToContainUsername.valueIn(domainId);
}
public String getPasswordPolicyRegex(Long domainId) {
return PasswordPolicyRegex.valueIn(domainId);
}
}

View File

@ -52,6 +52,8 @@
<property name="services" value="#{apiCommandsRegistry.registered}" />
</bean>
<bean id="passwordPolicies" class="com.cloud.user.PasswordPolicyImpl" />
<bean id="managementServerImpl" class="com.cloud.server.ManagementServerImpl">
<property name="lockControllerListener" ref="lockControllerListener" />
<property name="userAuthenticators"

View File

@ -89,6 +89,9 @@ public class AccountManagerImplTest extends AccountManagetImplTestBase {
@Mock
private Project project;
@Mock
PasswordPolicyImpl passwordPolicyMock;
@Before
public void beforeTest() {
@ -561,6 +564,10 @@ public class AccountManagerImplTest extends AccountManagetImplTestBase {
Mockito.doReturn(false).when(accountManagerImpl).isDomainAdmin(accountMockId);
Mockito.lenient().doReturn(true).when(accountManagerImpl).isResourceDomainAdmin(accountMockId);
Mockito.doReturn(accountMock).when(accountManagerImpl).getAccount(Mockito.anyLong());
Mockito.lenient().doNothing().when(passwordPolicyMock).verifyIfPasswordCompliesWithPasswordPolicies(Mockito.anyString(), Mockito.anyString(), Mockito.anyLong());
accountManagerImpl.validateUserPasswordAndUpdateIfNeeded("newPassword", userVoMock, " ");
}
@ -572,6 +579,10 @@ public class AccountManagerImplTest extends AccountManagetImplTestBase {
Mockito.lenient().doNothing().when(accountManagerImpl).validateCurrentPassword(Mockito.eq(userVoMock), Mockito.anyString());
Mockito.doReturn(accountMock).when(accountManagerImpl).getAccount(Mockito.anyLong());
Mockito.lenient().doNothing().when(passwordPolicyMock).verifyIfPasswordCompliesWithPasswordPolicies(Mockito.anyString(), Mockito.anyString(), Mockito.anyLong());
accountManagerImpl.validateUserPasswordAndUpdateIfNeeded("newPassword", userVoMock, null);
}
@ -587,6 +598,10 @@ public class AccountManagerImplTest extends AccountManagetImplTestBase {
Mockito.lenient().doNothing().when(accountManagerImpl).validateCurrentPassword(Mockito.eq(userVoMock), Mockito.anyString());
Mockito.doReturn(accountMock).when(accountManagerImpl).getAccount(Mockito.anyLong());
Mockito.lenient().doNothing().when(passwordPolicyMock).verifyIfPasswordCompliesWithPasswordPolicies(Mockito.anyString(), Mockito.anyString(), Mockito.anyLong());
accountManagerImpl.validateUserPasswordAndUpdateIfNeeded(newPassword, userVoMock, null);
Mockito.verify(accountManagerImpl, Mockito.times(0)).validateCurrentPassword(Mockito.eq(userVoMock), Mockito.anyString());
@ -605,6 +620,10 @@ public class AccountManagerImplTest extends AccountManagetImplTestBase {
Mockito.lenient().doNothing().when(accountManagerImpl).validateCurrentPassword(Mockito.eq(userVoMock), Mockito.anyString());
Mockito.doReturn(accountMock).when(accountManagerImpl).getAccount(Mockito.anyLong());
Mockito.lenient().doNothing().when(passwordPolicyMock).verifyIfPasswordCompliesWithPasswordPolicies(Mockito.anyString(), Mockito.anyString(), Mockito.anyLong());
accountManagerImpl.validateUserPasswordAndUpdateIfNeeded(newPassword, userVoMock, null);
Mockito.verify(accountManagerImpl, Mockito.times(0)).validateCurrentPassword(Mockito.eq(userVoMock), Mockito.anyString());
@ -623,12 +642,33 @@ public class AccountManagerImplTest extends AccountManagetImplTestBase {
Mockito.doNothing().when(accountManagerImpl).validateCurrentPassword(Mockito.eq(userVoMock), Mockito.anyString());
String currentPassword = "theCurrentPassword";
Mockito.doReturn(accountMock).when(accountManagerImpl).getAccount(Mockito.anyLong());
Mockito.lenient().doNothing().when(passwordPolicyMock).verifyIfPasswordCompliesWithPasswordPolicies(Mockito.anyString(), Mockito.anyString(), Mockito.anyLong());
accountManagerImpl.validateUserPasswordAndUpdateIfNeeded(newPassword, userVoMock, currentPassword);
Mockito.verify(accountManagerImpl, Mockito.times(1)).validateCurrentPassword(userVoMock, currentPassword);
Mockito.verify(userVoMock, Mockito.times(1)).setPassword(expectedUserPasswordAfterEncoded);
}
@Test (expected = InvalidParameterValueException.class)
public void validateUserPasswordAndUpdateIfNeededTestIfVerifyIfPasswordCompliesWithPasswordPoliciesThrowsException() {
String newPassword = "newPassword";
String currentPassword = "theCurrentPassword";
Mockito.doReturn(accountMock).when(accountManagerImpl).getAccount(Mockito.anyLong());
Mockito.doReturn("user").when(userVoMock).getUsername();
Mockito.doThrow(new InvalidParameterValueException("")).when(passwordPolicyMock).verifyIfPasswordCompliesWithPasswordPolicies(Mockito.anyString(), Mockito.anyString(),
Mockito.anyLong());
accountManagerImpl.validateUserPasswordAndUpdateIfNeeded(newPassword, userVoMock, currentPassword);
}
private String configureUserMockAuthenticators(String newPassword) {
accountManagerImpl._userPasswordEncoders = new ArrayList<>();
UserAuthenticator authenticatorMock1 = Mockito.mock(UserAuthenticator.class);

View File

@ -0,0 +1,163 @@
// Licensed to the Apache Software Foundation (ASF) under one or more
// contributor license agreements. See the NOTICE file distributed with
// this work for additional information regarding copyright ownership.
// The ASF licenses this file to You under the Apache License, Version 2.0
// (the "License"); you may not use this file except in compliance with
// the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.cloud.user;
import com.cloud.exception.InvalidParameterValueException;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.mockito.Spy;
import org.mockito.junit.MockitoJUnitRunner;
@RunWith(MockitoJUnitRunner.class)
public class PasswordPolicyImplTest {
@Spy
private PasswordPolicyImpl passwordPolicySpy;
@Test
public void validateSpecialCharactersTestWithEnoughSpecialCharacters() {
Mockito.doReturn(3).when(passwordPolicySpy).getPasswordPolicyMinimumSpecialCharacters(null);
passwordPolicySpy.validateIfPasswordContainsTheMinimumNumberOfSpecialCharacters(3, "user", null);
}
@Test (expected = InvalidParameterValueException.class)
public void validateSpecialCharactersTestWithoutEnoughSpecialCharacters() {
Mockito.doReturn(4).when(passwordPolicySpy).getPasswordPolicyMinimumSpecialCharacters(null);
passwordPolicySpy.validateIfPasswordContainsTheMinimumNumberOfSpecialCharacters(3, "user", null);
}
@Test
public void validateSpecialCharactersTestWithNoMinimumSpecialCharacters() {
Mockito.doReturn(0).when(passwordPolicySpy).getPasswordPolicyMinimumSpecialCharacters(null);
passwordPolicySpy.validateIfPasswordContainsTheMinimumNumberOfSpecialCharacters(3, "user", null);
}
@Test
public void validateUpperCaseLettersTestWithEnoughUpperCaseLetters() {
Mockito.doReturn(3).when(passwordPolicySpy).getPasswordPolicyMinimumUpperCaseLetters(null);
passwordPolicySpy.validateIfPasswordContainsTheMinimumNumberOfUpperCaseLetters(3, "user", null);
}
@Test (expected = InvalidParameterValueException.class)
public void validateUpperCaseLettersTestWithoutEnoughUpperCaseLetters() {
Mockito.doReturn(4).when(passwordPolicySpy).getPasswordPolicyMinimumUpperCaseLetters(null);
passwordPolicySpy.validateIfPasswordContainsTheMinimumNumberOfUpperCaseLetters(3, "user", null);
}
@Test
public void validateUpperCaseLettersTestWithNoMinimumUpperCaseLetters() {
Mockito.doReturn(0).when(passwordPolicySpy).getPasswordPolicyMinimumUpperCaseLetters(null);
passwordPolicySpy.validateIfPasswordContainsTheMinimumNumberOfUpperCaseLetters(3, "user", null);
}
@Test
public void validateLowerCaseLettersTestWithEnoughLowerCaseLetters() {
Mockito.doReturn(3).when(passwordPolicySpy).getPasswordPolicyMinimumLowerCaseLetters(null);
passwordPolicySpy.validateIfPasswordContainsTheMinimumNumberOfLowerCaseLetters(3, "user", null);
}
@Test (expected = InvalidParameterValueException.class)
public void validateLowerCaseLettersTestWithoutEnoughLowerCaseLetters() {
Mockito.doReturn(4).when(passwordPolicySpy).getPasswordPolicyMinimumLowerCaseLetters(null);
passwordPolicySpy.validateIfPasswordContainsTheMinimumNumberOfLowerCaseLetters(3, "user", null);
}
@Test
public void validateLowerCaseLettersTestWithNoMinimumLowerCaseLetters() {
Mockito.doReturn(0).when(passwordPolicySpy).getPasswordPolicyMinimumLowerCaseLetters(null);
passwordPolicySpy.validateIfPasswordContainsTheMinimumNumberOfLowerCaseLetters(3, "user", null);
}
@Test
public void validateDigitsTestWithEnoughDigits() {
Mockito.doReturn(3).when(passwordPolicySpy).getPasswordPolicyMinimumDigits(null);
passwordPolicySpy.validateIfPasswordContainsTheMinimumNumberOfDigits(3, "user", null);
}
@Test (expected = InvalidParameterValueException.class)
public void validateDigitsTestWithoutDigits() {
Mockito.doReturn(4).when(passwordPolicySpy).getPasswordPolicyMinimumDigits(null);
passwordPolicySpy.validateIfPasswordContainsTheMinimumNumberOfDigits(3, "user", null);
}
@Test
public void validateDigitsTestWithNoMinimumDigits() {
Mockito.doReturn(0).when(passwordPolicySpy).getPasswordPolicyMinimumDigits(null);
passwordPolicySpy.validateIfPasswordContainsTheMinimumNumberOfDigits(3, "user", null);
}
@Test
public void validateMinimumLengthTestWithEnoughMinimumLength() {
Mockito.doReturn(5).when(passwordPolicySpy).getPasswordPolicyMinimumLength(null);
passwordPolicySpy.validateIfPasswordContainsTheMinimumLength("12345", "user", null);
}
@Test (expected = InvalidParameterValueException.class)
public void validateMinimumLengthTestWithoutMinimumLength() {
Mockito.doReturn(5).when(passwordPolicySpy).getPasswordPolicyMinimumLength(null);
passwordPolicySpy.validateIfPasswordContainsTheMinimumLength("1234", "user", null);
}
@Test
public void validateMinimumLengthTestWithNoMinimumLength() {
Mockito.doReturn(0).when(passwordPolicySpy).getPasswordPolicyMinimumLength(null);
passwordPolicySpy.validateIfPasswordContainsTheMinimumLength("123456", "user", null);
}
@Test
public void validateUsernameInPasswordTestUsernameInPasswordAllowedAndWithoutUsernameInPassword() {
Mockito.doReturn(true).when(passwordPolicySpy).getPasswordPolicyAllowPasswordToContainUsername(null);
passwordPolicySpy.validateIfPasswordContainsTheUsername("123456", "user", null);
}
@Test
public void validateUsernameInPasswordTestUsernameInPasswordAllowedAndWithUsernameInPassword() {
Mockito.doReturn(true).when(passwordPolicySpy).getPasswordPolicyAllowPasswordToContainUsername(null);
passwordPolicySpy.validateIfPasswordContainsTheUsername("user123", "user", null);
}
@Test
public void validateUsernameInPasswordTestUsernameInPasswordNotAllowedAndWithoutUsernameInPassword() {
Mockito.doReturn(false).when(passwordPolicySpy).getPasswordPolicyAllowPasswordToContainUsername(null);
passwordPolicySpy.validateIfPasswordContainsTheUsername("123456", "user", null);
}
@Test (expected = InvalidParameterValueException.class)
public void validateUsernameInPasswordTestUsernameInPasswordNotAllowedAndWithUsernameInPassword() {
Mockito.doReturn(false).when(passwordPolicySpy).getPasswordPolicyAllowPasswordToContainUsername(null);
passwordPolicySpy.validateIfPasswordContainsTheUsername("user123", "user", null);
}
@Test
public void validateRegexTestWithRegexAndComplyingPassword() {
Mockito.doReturn("[a-z]+").when(passwordPolicySpy).getPasswordPolicyRegex(null);
passwordPolicySpy.validateIfPasswordMatchesRegex("abcd", "user", null);
}
@Test (expected = InvalidParameterValueException.class)
public void validateRegexTestWithRegexAndWithoutComplyingPassword() {
Mockito.doReturn("[a-z]+").when(passwordPolicySpy).getPasswordPolicyRegex(null);
passwordPolicySpy.validateIfPasswordMatchesRegex("abcd123", "user", null);
}
@Test
public void validateRegexTestWithoutRegex() {
Mockito.doReturn(null).when(passwordPolicySpy).getPasswordPolicyRegex(null);
passwordPolicySpy.validateIfPasswordMatchesRegex("abcd123", "user", null);
}
}