Skip to content

Commit 117ce1a

Browse files
JoaoJandreJoão Paraquetti
andauthored
Create password policies configurations (#6567)
Co-authored-by: João Paraquetti <joao@scclouds.com.br>
1 parent ddb11b1 commit 117ce1a

File tree

6 files changed

+549
-0
lines changed

6 files changed

+549
-0
lines changed

server/src/main/java/com/cloud/user/AccountManagerImpl.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,9 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
301301
@Inject
302302
private RoleService roleService;
303303

304+
@Inject
305+
private PasswordPolicy passwordPolicy;
306+
304307
private final ScheduledExecutorService _executor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("AccountChecker"));
305308

306309
private int _allowedLoginAttempts;
@@ -1368,6 +1371,9 @@ protected void validateUserPasswordAndUpdateIfNeeded(String newPassword, UserVO
13681371
if (StringUtils.isBlank(newPassword)) {
13691372
throw new InvalidParameterValueException("Password cannot be empty or blank.");
13701373
}
1374+
1375+
passwordPolicy.verifyIfPasswordCompliesWithPasswordPolicies(newPassword, user.getUsername(), getAccount(user.getAccountId()).getDomainId());
1376+
13711377
Account callingAccount = getCurrentCallingAccount();
13721378
boolean isRootAdminExecutingPasswordUpdate = callingAccount.getId() == Account.ACCOUNT_ID_SYSTEM || isRootAdmin(callingAccount.getId());
13731379
boolean isDomainAdmin = isDomainAdmin(callingAccount.getId());
@@ -2342,6 +2348,8 @@ protected UserVO createUser(long accountId, String userName, String password, St
23422348
s_logger.debug("Creating user: " + userName + ", accountId: " + accountId + " timezone:" + timezone);
23432349
}
23442350

2351+
passwordPolicy.verifyIfPasswordCompliesWithPasswordPolicies(password, userName, getAccount(accountId).getDomainId());
2352+
23452353
String encodedPassword = null;
23462354
for (UserAuthenticator authenticator : _userPasswordEncoders) {
23472355
encodedPassword = authenticator.encode(password);
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
// Licensed to the Apache Software Foundation (ASF) under one
2+
// or more contributor license agreements. See the NOTICE file
3+
// distributed with this work for additional information
4+
// regarding copyright ownership. The ASF licenses this file
5+
// to you under the Apache License, Version 2.0 (the
6+
// "License"); you may not use this file except in compliance
7+
// with the License. You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing,
12+
// software distributed under the License is distributed on an
13+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
// KIND, either express or implied. See the License for the
15+
// specific language governing permissions and limitations
16+
// under the License.
17+
package com.cloud.user;
18+
19+
import org.apache.cloudstack.framework.config.ConfigKey;
20+
21+
public interface PasswordPolicy {
22+
23+
ConfigKey<Integer> PasswordPolicyMinimumSpecialCharacters = new ConfigKey<>(
24+
"Advanced",
25+
Integer.class,
26+
"password.policy.minimum.special.characters",
27+
"0",
28+
"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.",
29+
true,
30+
ConfigKey.Scope.Domain);
31+
32+
ConfigKey<Integer> PasswordPolicyMinimumLength = new ConfigKey<>(
33+
"Advanced",
34+
Integer.class,
35+
"password.policy.minimum.length",
36+
"0",
37+
"Minimum length that the user's password must have. The value 0 means the user's password can have any length.",
38+
true,
39+
ConfigKey.Scope.Domain);
40+
41+
ConfigKey<Integer> PasswordPolicyMinimumUppercaseLetters = new ConfigKey<>(
42+
"Advanced",
43+
Integer.class,
44+
"password.policy.minimum.uppercase.letters",
45+
"0",
46+
"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.",
47+
true,
48+
ConfigKey.Scope.Domain);
49+
50+
ConfigKey<Integer> PasswordPolicyMinimumLowercaseLetters = new ConfigKey<>(
51+
"Advanced",
52+
Integer.class,
53+
"password.policy.minimum.lowercase.letters",
54+
"0",
55+
"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.",
56+
true,
57+
ConfigKey.Scope.Domain);
58+
59+
ConfigKey<Integer> PasswordPolicyMinimumDigits = new ConfigKey<>(
60+
"Advanced",
61+
Integer.class,
62+
"password.policy.minimum.digits",
63+
"0",
64+
"Minimum number of digits that the user's password must have. The value 0 means the user's password does not require any digits.",
65+
true,
66+
ConfigKey.Scope.Domain);
67+
68+
ConfigKey<Boolean> PasswordPolicyAllowPasswordToContainUsername = new ConfigKey<>(
69+
"Advanced",
70+
Boolean.class,
71+
"password.policy.allowPasswordToContainUsername",
72+
"true",
73+
"Indicates if the user's password may contain their username. Set 'true' (default) if it is allowed, otherwise set 'false'.",
74+
true,
75+
ConfigKey.Scope.Domain);
76+
77+
ConfigKey<String> PasswordPolicyRegex = new ConfigKey<>(
78+
"Advanced",
79+
String.class,
80+
"password.policy.regex",
81+
".+",
82+
"A regular expression that the user's password must match. The default expression '.+' will match with any password.",
83+
true,
84+
ConfigKey.Scope.Domain);
85+
86+
/**
87+
* Checks if a given user's password complies with the configured password policies.
88+
* If it does not comply, a {@link com.cloud.exception.InvalidParameterValueException} will be thrown.
89+
* */
90+
void verifyIfPasswordCompliesWithPasswordPolicies(String password, String username, Long domainID);
91+
}

0 commit comments

Comments
 (0)