Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

25124 enforcing password requirements #9423

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
69 commits
Select commit Hold shift + click to select a range
12a3ac5
initial configurations flags on rhnconfiguration table
Serp1co Sep 2, 2024
4d0a7db
password checker wip
Serp1co Sep 2, 2024
69466d2
password checks with hashmap for errors and conversion to actionerrors
Serp1co Sep 2, 2024
87bd87d
unused imports removed
Serp1co Sep 2, 2024
ac2d2b1
functional user password matcher
Serp1co Sep 5, 2024
5341db2
Working password validation with all cases
Serp1co Sep 5, 2024
8e96041
better patterns for validating password
Serp1co Sep 5, 2024
d802ac2
passwordcheckfail to validatorerror and refactoring to keep same ok/k…
Serp1co Sep 10, 2024
81587fe
moved password classes into own package (to be moved into suse packag…
Serp1co Sep 12, 2024
b13dafb
removed user defaults for password policy settings
Serp1co Sep 12, 2024
2c73c4a
changed defaults
Serp1co Sep 12, 2024
0ae9d20
test and commands fix on validation
Serp1co Sep 12, 2024
ca411fc
spark controllers
Serp1co Sep 13, 2024
e078daf
password policy settings wip
Serp1co Sep 17, 2024
6817cc1
ui for password policy
Serp1co Oct 9, 2024
4b3a8ae
controller for updating password policy
Serp1co Oct 23, 2024
58c71a9
Merge branch 'uyuni-project:master' into 25124-enforcing-password-req…
Serp1co Oct 29, 2024
7fc237a
password policy test, controller, sql, jade template
Serp1co Oct 29, 2024
33ed665
missing translation
Serp1co Oct 30, 2024
d49165e
Merge remote-tracking branch 'serp1co-uyuni/25124-enforcing-password-…
Serp1co Oct 30, 2024
b39df7a
missing file
Serp1co Nov 4, 2024
2f4f2d4
removal of old popover (not functioning)
Serp1co Nov 10, 2024
ea27809
removed prototyping comment
Serp1co Nov 10, 2024
befca7b
missing copyrights
Serp1co Nov 10, 2024
c8db592
password policy defaults as old defaults
Serp1co Nov 10, 2024
b83e04e
checkstyle
Serp1co Nov 10, 2024
602777f
unused import and javadoc
Serp1co Nov 11, 2024
a69e965
isuyuni flag removal
Serp1co Nov 11, 2024
6e22817
migration sql and default values equals between both files
Serp1co Nov 11, 2024
468c6e0
changelog
Serp1co Nov 12, 2024
6628a53
password policy and default configuration settings migration and updates
Serp1co Dec 2, 2024
1ba0043
configuration table refactoring
Serp1co Dec 2, 2024
9612c97
password policy refactoring
Serp1co Dec 2, 2024
2374021
password policy refactoring
Serp1co Dec 2, 2024
0de3f7e
password policy refactoring
Serp1co Dec 2, 2024
d3ba906
default settings migration
Serp1co Dec 2, 2024
3b59c93
changelogs
Serp1co Dec 2, 2024
3b9a20f
alter trigger on migration for indempotency
Serp1co Dec 2, 2024
9902dcc
string values because table is varchar
Serp1co Dec 2, 2024
e3bcbbf
trigger for update date to keep indempotency
Serp1co Dec 4, 2024
6ddbc00
linting
Serp1co Dec 4, 2024
a9ad188
default db values update
Serp1co Dec 5, 2024
6d1d323
default db values update
Serp1co Dec 5, 2024
db5c80b
js linting
Serp1co Dec 6, 2024
8ccfc3c
better buttons
Serp1co Dec 11, 2024
b9a3859
import sorting
Serp1co Dec 11, 2024
4245c17
linting
Serp1co Dec 11, 2024
7c6cfae
linting
Serp1co Dec 11, 2024
3c53a2d
linting
Serp1co Dec 11, 2024
dbb51d0
changelogs
Serp1co Dec 11, 2024
0ccfad9
changelogs
Serp1co Dec 11, 2024
943ed8a
better button layouts
Serp1co Dec 11, 2024
7166fc8
cucumber default password
Serp1co Dec 16, 2024
008ed61
changed plurals
Serp1co Dec 16, 2024
e04d191
reset button secondary, align buttons to forms
Serp1co Jan 21, 2025
522026c
linting
mcalmer Jan 29, 2025
6e90f7b
move values from configuration file into DB
mcalmer Jan 29, 2025
9fdf8e2
removed old configurations
Serp1co Jan 29, 2025
f393c8d
changelogs
Serp1co Jan 29, 2025
5a1f110
Merge remote-tracking branch 'serp1co-uyuni/master' into 25124-enforc…
Serp1co Jan 31, 2025
c1cf5d1
Merge pull request #1 from mcalmer/migrate-values-from-config
Serp1co Feb 10, 2025
2b6ed78
Merge branch 'master' into 25124-enforcing-password-requirements
Serp1co Feb 10, 2025
9f80c23
checkstyle
Serp1co Feb 10, 2025
de4573b
removed old pswchecker on orgcreate and null defaults for org in rhnc…
Serp1co Feb 11, 2025
563d70c
moved sql to new schema migration
Serp1co Feb 12, 2025
8a172b6
sonarcloud + changes to naming patterns because of sonarcloud
Serp1co Feb 12, 2025
c935518
sonarcloud + changes to naming patterns because of sonarcloud
Serp1co Feb 12, 2025
a32b505
default settings with description
Serp1co Feb 12, 2025
9fb81c0
missing default tests
Serp1co Feb 12, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 0 additions & 16 deletions java/code/src/com/redhat/rhn/common/conf/UserDefaults.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@
*/
public class UserDefaults {
private static UserDefaults instance = new UserDefaults();
public static final String MAX_PASSWORD_LENGTH = "max_passwd_len";
public static final String MIN_PASSWORD_LENGTH = "min_passwd_len";
public static final String MAX_USER_LENGTH = "max_user_len";
public static final String MIN_USER_LENGTH = "min_user_len";
public static final String MAX_EMAIL_LENGTH = "min_email_len";
Expand All @@ -33,20 +31,6 @@ public static UserDefaults get() {
return instance;
}

/**
* @return the max password length
*/
public int getMaxPasswordLength() {
return Config.get().getInt(MAX_PASSWORD_LENGTH, 32);
}

/**
* @return the min password length
*/
public int getMinPasswordLength() {
return Config.get().getInt(MIN_PASSWORD_LENGTH, 5);
}

/**
* @return the max login name length
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import com.redhat.rhn.domain.cloudpayg.PaygCredentialsProduct;
import com.redhat.rhn.domain.cloudpayg.PaygSshData;
import com.redhat.rhn.domain.common.ProvisionState;
import com.redhat.rhn.domain.common.RhnConfiguration;
import com.redhat.rhn.domain.config.ConfigChannel;
import com.redhat.rhn.domain.config.ConfigChannelType;
import com.redhat.rhn.domain.config.ConfigFile;
Expand Down Expand Up @@ -254,6 +255,7 @@ private AnnotationRegistry() {
ProjectSource.class,
ProvisionState.class,
PtfFilter.class,
RhnConfiguration.class,
RecurringConfigChannel.class,
RecurringHighstate.class,
RecurringInternalState.class,
Expand Down
8 changes: 6 additions & 2 deletions java/code/src/com/redhat/rhn/common/util/CryptHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@

package com.redhat.rhn.common.util;

import com.redhat.rhn.common.conf.UserDefaults;
import com.redhat.rhn.domain.common.RhnConfiguration;
import com.redhat.rhn.domain.common.RhnConfigurationFactory;

import org.apache.commons.lang3.RandomStringUtils;

Expand Down Expand Up @@ -122,7 +123,10 @@ public static String getRandomPasswordForPamAuth() {
// we set use pam authentication, yet the password field
// in the database is NOT NULL. So we have to create this
// stupid HACK! Actually this is beyond HACK.
return RandomStringUtils.random(UserDefaults.get().getMaxPasswordLength(), 0, 0,
RhnConfigurationFactory factory = RhnConfigurationFactory.getSingleton();
return RandomStringUtils.random(
factory.getIntegerConfiguration(RhnConfiguration.KEYS.PSW_CHECK_LENGTH_MAX).getValue(),
0, 0,
true, true, null, new SecureRandom());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,196 @@
/*
* Copyright (c) 2024 SUSE LLC
*
* This software is licensed to you under the GNU General Public License,
* version 2 (GPLv2). There is NO WARRANTY for this software, express or
* implied, including the implied warranties of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2
* along with this software; if not, see
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
*
* Red Hat trademarks are not licensed under GPLv2. No permission is
* granted to use or replicate Red Hat trademarks that are incorporated
* in this software or its documentation.
*/

package com.redhat.rhn.common.util.validation.password;

import com.redhat.rhn.domain.common.RhnConfiguration;
import com.redhat.rhn.domain.common.RhnConfigurationFactory;

public class PasswordPolicy {
private boolean upperCharFlag;
private boolean lowerCharFlag;
private boolean digitFlag;
private boolean specialCharFlag;
private String specialChars;
private boolean consecutiveCharsFlag;
private boolean restrictedOccurrenceFlag;
private int maxCharacterOccurrence;
private int minLength;
private int maxLength;

/**
* Class that holds the settings for the user password checks
* @param upperCharFlagIn check upper char in password
* @param lowerCharFlagIn check lower char in password
* @param digitFlagIn check digit in password
* @param specialCharFlagIn check special char in password
* @param specialCharsIn string with special chars
* @param consecutiveCharsFlagIn check consecutive characters
* @param restrictedOccurrenceFlagIn check restricted occurrence
* @param maxCharacterOccurrenceIn max number of occurrence
* @param minLengthIn minimum password length
* @param maxLengthIn maximum password length
*/
public PasswordPolicy(
boolean upperCharFlagIn, boolean lowerCharFlagIn,
boolean digitFlagIn, boolean specialCharFlagIn,
String specialCharsIn, boolean consecutiveCharsFlagIn,
boolean restrictedOccurrenceFlagIn, int maxCharacterOccurrenceIn,
int minLengthIn, int maxLengthIn
) {
upperCharFlag = upperCharFlagIn;
lowerCharFlag = lowerCharFlagIn;
digitFlag = digitFlagIn;
specialCharFlag = specialCharFlagIn;
specialChars = specialCharsIn;
consecutiveCharsFlag = consecutiveCharsFlagIn;
restrictedOccurrenceFlag = restrictedOccurrenceFlagIn;
maxCharacterOccurrence = maxCharacterOccurrenceIn;
minLength = minLengthIn;
maxLength = maxLengthIn;
}

/**
* Class that holds the settings for the user password checks
*/
public PasswordPolicy() {
}

/**
* Helper method to build checks settings from SatConfiguration
* @return the settings for the user password settings
*/
public static PasswordPolicy buildFromFactory() {
RhnConfigurationFactory factory = RhnConfigurationFactory.getSingleton();
return new PasswordPolicy(
factory.getBooleanConfiguration(RhnConfiguration.KEYS.PSW_CHECK_UPPER_CHAR_FLAG).getValue(),
factory.getBooleanConfiguration(RhnConfiguration.KEYS.PSW_CHECK_LOWER_CHAR_FLAG).getValue(),
factory.getBooleanConfiguration(RhnConfiguration.KEYS.PSW_CHECK_DIGIT_FLAG).getValue(),
factory.getBooleanConfiguration(RhnConfiguration.KEYS.PSW_CHECK_SPECIAL_CHAR_FLAG).getValue(),
factory.getStringConfiguration(RhnConfiguration.KEYS.PSW_CHECK_SPECIAL_CHARACTERS).getValue(),
factory.getBooleanConfiguration(RhnConfiguration.KEYS.PSW_CHECK_CONSECUTIVE_CHAR_FLAG).getValue(),
factory.getBooleanConfiguration(RhnConfiguration.KEYS.PSW_CHECK_RESTRICTED_OCCURRENCE_FLAG).getValue(),
factory.getIntegerConfiguration(RhnConfiguration.KEYS.PSW_CHECK_MAX_OCCURRENCE).getValue(),
factory.getIntegerConfiguration(RhnConfiguration.KEYS.PSW_CHECK_LENGTH_MIN).getValue(),
factory.getIntegerConfiguration(RhnConfiguration.KEYS.PSW_CHECK_LENGTH_MAX).getValue()
);
}


/**
* Helper method to get the defaults checks settings from SatConfiguration
* @return the default settings for the user password settings
*/
public static PasswordPolicy buildFromDefaults() {
RhnConfigurationFactory factory = RhnConfigurationFactory.getSingleton();
return new PasswordPolicy(
factory.getBooleanConfiguration(
RhnConfiguration.KEYS.PSW_CHECK_UPPER_CHAR_FLAG).getDefaultValue(),
factory.getBooleanConfiguration(RhnConfiguration.KEYS.PSW_CHECK_LOWER_CHAR_FLAG).getDefaultValue(),
factory.getBooleanConfiguration(RhnConfiguration.KEYS.PSW_CHECK_DIGIT_FLAG).getDefaultValue(),
factory.getBooleanConfiguration(
RhnConfiguration.KEYS.PSW_CHECK_SPECIAL_CHAR_FLAG).getDefaultValue(),
factory.getStringConfiguration(
RhnConfiguration.KEYS.PSW_CHECK_SPECIAL_CHARACTERS).getDefaultValue(),
factory.getBooleanConfiguration(
RhnConfiguration.KEYS.PSW_CHECK_CONSECUTIVE_CHAR_FLAG).getDefaultValue(),
factory.getBooleanConfiguration(
RhnConfiguration.KEYS.PSW_CHECK_RESTRICTED_OCCURRENCE_FLAG).getDefaultValue(),
factory.getIntegerConfiguration(RhnConfiguration.KEYS.PSW_CHECK_MAX_OCCURRENCE).getDefaultValue(),
factory.getIntegerConfiguration(RhnConfiguration.KEYS.PSW_CHECK_LENGTH_MIN).getDefaultValue(),
factory.getIntegerConfiguration(RhnConfiguration.KEYS.PSW_CHECK_LENGTH_MAX).getDefaultValue()
);
}

public boolean isUpperCharFlag() {
return upperCharFlag;
}

public void setUpperCharFlag(boolean upperCharFlagIn) {
upperCharFlag = upperCharFlagIn;
}

public boolean isLowerCharFlag() {
return lowerCharFlag;
}

public void setLowerCharFlag(boolean lowerCharFlagIn) {
lowerCharFlag = lowerCharFlagIn;
}

public boolean isDigitFlag() {
return digitFlag;
}

public void setDigitFlag(boolean digitFlagIn) {
digitFlag = digitFlagIn;
}

public boolean isSpecialCharFlag() {
return specialCharFlag;
}

public void setSpecialCharFlag(boolean specialCharFlagIn) {
specialCharFlag = specialCharFlagIn;
}

public String getSpecialChars() {
return specialChars;
}

public void setSpecialChars(String specialCharsIn) {
specialChars = specialCharsIn;
}

public boolean isConsecutiveCharsFlag() {
return consecutiveCharsFlag;
}

public void setConsecutiveCharsFlag(boolean consecutiveCharsFlagIn) {
consecutiveCharsFlag = consecutiveCharsFlagIn;
}

public boolean isRestrictedOccurrenceFlag() {
return restrictedOccurrenceFlag;
}

public void setRestrictedOccurrenceFlag(boolean restrictedOccurrenceFlagIn) {
restrictedOccurrenceFlag = restrictedOccurrenceFlagIn;
}

public int getMaxCharacterOccurrence() {
return maxCharacterOccurrence;
}

public void setMaxCharacterOccurrence(int maxCharacterOccurrenceIn) {
maxCharacterOccurrence = maxCharacterOccurrenceIn;
}

public int getMinLength() {
return minLength;
}

public void setMinLength(int minLengthIn) {
minLength = minLengthIn;
}

public int getMaxLength() {
return maxLength;
}

public void setMaxLength(int maxLengthIn) {
maxLength = maxLengthIn;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* Copyright (c) 2024 SUSE LLC
*
* This software is licensed to you under the GNU General Public License,
* version 2 (GPLv2). There is NO WARRANTY for this software, express or
* implied, including the implied warranties of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2
* along with this software; if not, see
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
*
* Red Hat trademarks are not licensed under GPLv2. No permission is
* granted to use or replicate Red Hat trademarks that are incorporated
* in this software or its documentation.
*/

package com.redhat.rhn.common.util.validation.password;

import com.redhat.rhn.common.localization.LocalizationService;
import com.redhat.rhn.common.validator.ValidatorError;

public class PasswordPolicyCheckFail {
private final String localizedMessageId;
private final String configurationParameter;

protected PasswordPolicyCheckFail(String localizedMessageIdIn, String configurationParameterIn) {
localizedMessageId = localizedMessageIdIn;
configurationParameter = configurationParameterIn;
}

public String getLocalizedMessageId() {
return localizedMessageId;
}

public String getConfigurationParameter() {
return configurationParameter;
}

public String getLocalizedErrorMessage() {
return LocalizationService.getInstance().getMessage(getLocalizedMessageId(), getConfigurationParameter());
}

/**
* Helper method for converting to ValidatorError for UserCommands
* @return the validator error
*/
public ValidatorError toValidatorError() {
return new ValidatorError(getLocalizedMessageId(), getConfigurationParameter());
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* Copyright (c) 2024 SUSE LLC
*
* This software is licensed to you under the GNU General Public License,
* version 2 (GPLv2). There is NO WARRANTY for this software, express or
* implied, including the implied warranties of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2
* along with this software; if not, see
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
*
* Red Hat trademarks are not licensed under GPLv2. No permission is
* granted to use or replicate Red Hat trademarks that are incorporated
* in this software or its documentation.
*/

package com.redhat.rhn.common.util.validation.password;

import java.util.List;
import java.util.stream.Collectors;

public class PasswordValidationException extends IllegalArgumentException {
private final transient List<PasswordPolicyCheckFail> validationErrors;

/**
* Exception class for password validation
* @param validationErrorsIn a list of validation errors
*/
public PasswordValidationException(List<PasswordPolicyCheckFail> validationErrorsIn) {
validationErrors = validationErrorsIn;
}

public List<PasswordPolicyCheckFail> getValidationErrors() {
return validationErrors;
}

@Override
public String getMessage() {
return "Password validation errors: " + getValidationErrors().stream()
.map(PasswordPolicyCheckFail::getLocalizedMessageId)
.collect(Collectors.joining("; "));
}
}
Loading
Loading