use of password.pwm.bean.PasswordStatus in project pwm by pwm-project.
the class LDAPStatusChecker method doLdapTestUserCheck.
@SuppressWarnings("checkstyle:MethodLength")
public List<HealthRecord> doLdapTestUserCheck(final Configuration config, final LdapProfile ldapProfile, final PwmApplication pwmApplication) {
String testUserDN = ldapProfile.readSettingAsString(PwmSetting.LDAP_TEST_USER_DN);
String proxyUserDN = ldapProfile.readSettingAsString(PwmSetting.LDAP_PROXY_USER_DN);
final PasswordData proxyUserPW = ldapProfile.readSettingAsPassword(PwmSetting.LDAP_PROXY_USER_PASSWORD);
final List<HealthRecord> returnRecords = new ArrayList<>();
if (testUserDN == null || testUserDN.length() < 1) {
return returnRecords;
}
try {
testUserDN = ldapProfile.readCanonicalDN(pwmApplication, testUserDN);
proxyUserDN = ldapProfile.readCanonicalDN(pwmApplication, proxyUserDN);
} catch (PwmUnrecoverableException e) {
final String msgString = e.getMessage();
LOGGER.trace(SessionLabel.HEALTH_SESSION_LABEL, "unexpected error while testing test user (during object creation): message=" + msgString + " debug info: " + JavaHelper.readHostileExceptionMessage(e));
returnRecords.add(HealthRecord.forMessage(HealthMessage.LDAP_TestUserUnexpected, PwmSetting.LDAP_TEST_USER_DN.toMenuLocationDebug(ldapProfile.getIdentifier(), PwmConstants.DEFAULT_LOCALE), msgString));
return returnRecords;
}
if (proxyUserDN.equalsIgnoreCase(testUserDN)) {
returnRecords.add(HealthRecord.forMessage(HealthMessage.LDAP_ProxyTestSameUser, PwmSetting.LDAP_TEST_USER_DN.toMenuLocationDebug(ldapProfile.getIdentifier(), PwmConstants.DEFAULT_LOCALE), PwmSetting.LDAP_PROXY_USER_DN.toMenuLocationDebug(ldapProfile.getIdentifier(), PwmConstants.DEFAULT_LOCALE)));
return returnRecords;
}
ChaiUser theUser = null;
ChaiProvider chaiProvider = null;
try {
try {
chaiProvider = LdapOperationsHelper.createChaiProvider(pwmApplication, SessionLabel.HEALTH_SESSION_LABEL, ldapProfile, config, proxyUserDN, proxyUserPW);
theUser = chaiProvider.getEntryFactory().newChaiUser(testUserDN);
} catch (ChaiUnavailableException e) {
returnRecords.add(HealthRecord.forMessage(HealthMessage.LDAP_TestUserUnavailable, PwmSetting.LDAP_TEST_USER_DN.toMenuLocationDebug(ldapProfile.getIdentifier(), PwmConstants.DEFAULT_LOCALE), e.getMessage()));
return returnRecords;
} catch (Throwable e) {
final String msgString = e.getMessage();
LOGGER.trace(SessionLabel.HEALTH_SESSION_LABEL, "unexpected error while testing test user (during object creation): message=" + msgString + " debug info: " + JavaHelper.readHostileExceptionMessage(e));
returnRecords.add(HealthRecord.forMessage(HealthMessage.LDAP_TestUserUnexpected, PwmSetting.LDAP_TEST_USER_DN.toMenuLocationDebug(ldapProfile.getIdentifier(), PwmConstants.DEFAULT_LOCALE), msgString));
return returnRecords;
}
try {
theUser.readObjectClass();
} catch (ChaiException e) {
returnRecords.add(HealthRecord.forMessage(HealthMessage.LDAP_TestUserError, PwmSetting.LDAP_TEST_USER_DN.toMenuLocationDebug(ldapProfile.getIdentifier(), PwmConstants.DEFAULT_LOCALE), e.getMessage()));
return returnRecords;
}
LOGGER.trace(SessionLabel.HEALTH_SESSION_LABEL, "beginning process to check ldap test user password read/write operations for profile " + ldapProfile.getIdentifier());
try {
final boolean readPwdEnabled = pwmApplication.getConfig().readSettingAsBoolean(PwmSetting.EDIRECTORY_READ_USER_PWD) && theUser.getChaiProvider().getDirectoryVendor() == DirectoryVendor.EDIRECTORY;
if (readPwdEnabled) {
try {
theUser.readPassword();
} catch (Exception e) {
LOGGER.debug(SessionLabel.HEALTH_SESSION_LABEL, "error reading user password from directory " + e.getMessage());
returnRecords.add(HealthRecord.forMessage(HealthMessage.LDAP_TestUserReadPwError, PwmSetting.EDIRECTORY_READ_USER_PWD.toMenuLocationDebug(null, PwmConstants.DEFAULT_LOCALE), PwmSetting.LDAP_TEST_USER_DN.toMenuLocationDebug(ldapProfile.getIdentifier(), PwmConstants.DEFAULT_LOCALE), e.getMessage()));
return returnRecords;
}
} else {
final Locale locale = PwmConstants.DEFAULT_LOCALE;
final UserIdentity userIdentity = new UserIdentity(testUserDN, ldapProfile.getIdentifier());
final PwmPasswordPolicy passwordPolicy = PasswordUtility.readPasswordPolicyForUser(pwmApplication, null, userIdentity, theUser, locale);
boolean doPasswordChange = true;
final int minLifetimeSeconds = passwordPolicy.getRuleHelper().readIntValue(PwmPasswordRule.MinimumLifetime);
if (minLifetimeSeconds > 0) {
final Instant pwdLastModified = PasswordUtility.determinePwdLastModified(pwmApplication, SessionLabel.HEALTH_SESSION_LABEL, userIdentity);
final PasswordStatus passwordStatus;
{
final UserInfo userInfo = UserInfoFactory.newUserInfo(pwmApplication, SessionLabel.HEALTH_SESSION_LABEL, locale, userIdentity, chaiProvider);
passwordStatus = userInfo.getPasswordStatus();
}
{
final boolean withinMinLifetime = PasswordUtility.isPasswordWithinMinimumLifetimeImpl(theUser, SessionLabel.HEALTH_SESSION_LABEL, passwordPolicy, pwdLastModified, passwordStatus);
if (withinMinLifetime) {
LOGGER.trace(SessionLabel.HEALTH_SESSION_LABEL, "skipping test user password set due to password being within minimum lifetime");
doPasswordChange = false;
}
}
}
if (doPasswordChange) {
final PasswordData newPassword = RandomPasswordGenerator.createRandomPassword(null, passwordPolicy, pwmApplication);
try {
theUser.setPassword(newPassword.getStringValue());
LOGGER.debug(SessionLabel.HEALTH_SESSION_LABEL, "set random password on test user " + userIdentity.toDisplayString());
} catch (ChaiException e) {
returnRecords.add(HealthRecord.forMessage(HealthMessage.LDAP_TestUserWritePwError, PwmSetting.LDAP_TEST_USER_DN.toMenuLocationDebug(ldapProfile.getIdentifier(), PwmConstants.DEFAULT_LOCALE), e.getMessage()));
return returnRecords;
}
}
}
} catch (Exception e) {
final String msg = "error setting test user password: " + JavaHelper.readHostileExceptionMessage(e);
LOGGER.error(SessionLabel.HEALTH_SESSION_LABEL, msg, e);
returnRecords.add(HealthRecord.forMessage(HealthMessage.LDAP_TestUserUnexpected, PwmSetting.LDAP_TEST_USER_DN.toMenuLocationDebug(ldapProfile.getIdentifier(), PwmConstants.DEFAULT_LOCALE), msg));
return returnRecords;
}
try {
final UserIdentity userIdentity = new UserIdentity(theUser.getEntryDN(), ldapProfile.getIdentifier());
final UserInfo userInfo = UserInfoFactory.newUserInfo(pwmApplication, SessionLabel.HEALTH_SESSION_LABEL, PwmConstants.DEFAULT_LOCALE, userIdentity, chaiProvider);
userInfo.getPasswordStatus();
userInfo.getAccountExpirationTime();
userInfo.getResponseInfoBean();
userInfo.getPasswordPolicy();
userInfo.getChallengeProfile();
userInfo.getProfileIDs();
userInfo.getOtpUserRecord();
userInfo.getUserGuid();
userInfo.getUsername();
userInfo.getUserEmailAddress();
userInfo.getUserSmsNumber();
} catch (PwmUnrecoverableException e) {
returnRecords.add(new HealthRecord(HealthStatus.WARN, makeLdapTopic(ldapProfile, config), "unable to read test user data: " + e.getMessage()));
return returnRecords;
}
} finally {
if (chaiProvider != null) {
try {
chaiProvider.close();
} catch (Exception e) {
// ignore
}
}
}
returnRecords.add(HealthRecord.forMessage(HealthMessage.LDAP_TestUserOK, ldapProfile.getDisplayName(PwmConstants.DEFAULT_LOCALE)));
return returnRecords;
}
use of password.pwm.bean.PasswordStatus in project pwm by pwm-project.
the class UserInfoReader method getPasswordStatus.
@Override
public PasswordStatus getPasswordStatus() throws PwmUnrecoverableException {
final Configuration config = pwmApplication.getConfig();
final PasswordStatus.PasswordStatusBuilder passwordStatusBuilder = PasswordStatus.builder();
final String userDN = chaiUser.getEntryDN();
final PwmPasswordPolicy passwordPolicy = selfCachedReference.getPasswordPolicy();
final long startTime = System.currentTimeMillis();
LOGGER.trace(sessionLabel, "beginning password status check process for " + userDN);
// check if password meets existing policy.
if (passwordPolicy.getRuleHelper().readBooleanValue(PwmPasswordRule.EnforceAtLogin)) {
if (currentPassword != null) {
try {
final PwmPasswordRuleValidator passwordRuleValidator = new PwmPasswordRuleValidator(pwmApplication, passwordPolicy);
passwordRuleValidator.testPassword(currentPassword, null, selfCachedReference, chaiUser);
} catch (PwmDataValidationException | PwmUnrecoverableException e) {
LOGGER.debug(sessionLabel, "user " + userDN + " password does not conform to current password policy (" + e.getMessage() + "), marking as requiring change.");
passwordStatusBuilder.violatesPolicy(true);
} catch (ChaiUnavailableException e) {
throw PwmUnrecoverableException.fromChaiException(e);
}
}
}
boolean ldapPasswordExpired = false;
try {
ldapPasswordExpired = chaiUser.isPasswordExpired();
if (ldapPasswordExpired) {
LOGGER.trace(sessionLabel, "password for " + userDN + " appears to be expired");
} else {
LOGGER.trace(sessionLabel, "password for " + userDN + " does not appear to be expired");
}
} catch (ChaiOperationException e) {
LOGGER.info(sessionLabel, "error reading LDAP attributes for " + userDN + " while reading isPasswordExpired(): " + e.getMessage());
} catch (ChaiUnavailableException e) {
throw PwmUnrecoverableException.fromChaiException(e);
}
final Instant ldapPasswordExpirationTime = selfCachedReference.getPasswordExpirationTime();
boolean preExpired = false;
if (ldapPasswordExpirationTime != null) {
final TimeDuration expirationInterval = TimeDuration.fromCurrent(ldapPasswordExpirationTime);
LOGGER.trace(sessionLabel, "read password expiration time: " + JavaHelper.toIsoDate(ldapPasswordExpirationTime) + ", " + expirationInterval.asCompactString() + " from now");
final TimeDuration diff = TimeDuration.fromCurrent(ldapPasswordExpirationTime);
// now check to see if the user's expire time is within the 'preExpireTime' setting.
final long preExpireMs = config.readSettingAsLong(PwmSetting.PASSWORD_EXPIRE_PRE_TIME) * 1000;
if (diff.getTotalMilliseconds() > 0 && diff.getTotalMilliseconds() < preExpireMs) {
LOGGER.debug(sessionLabel, "user " + userDN + " password will expire within " + diff.asCompactString() + ", marking as pre-expired");
preExpired = true;
} else if (ldapPasswordExpired) {
preExpired = true;
LOGGER.debug(sessionLabel, "user " + userDN + " password is expired, marking as pre-expired.");
}
// now check to see if the user's expire time is within the 'preWarnTime' setting.
final long preWarnMs = config.readSettingAsLong(PwmSetting.PASSWORD_EXPIRE_WARN_TIME) * 1000;
// don't check if the 'preWarnTime' setting is zero or less than the expirePreTime
if (!ldapPasswordExpired && !preExpired) {
if (!(preWarnMs == 0 || preWarnMs < preExpireMs)) {
if (diff.getTotalMilliseconds() > 0 && diff.getTotalMilliseconds() < preWarnMs) {
LOGGER.debug(sessionLabel, "user " + userDN + " password will expire within " + diff.asCompactString() + ", marking as within warn period");
passwordStatusBuilder.warnPeriod(true);
}
}
}
passwordStatusBuilder.preExpired(preExpired);
}
LOGGER.debug(sessionLabel, "completed user password status check for " + userDN + " " + passwordStatusBuilder + " (" + TimeDuration.fromCurrent(startTime).asCompactString() + ")");
passwordStatusBuilder.expired(ldapPasswordExpired);
return passwordStatusBuilder.build();
}
use of password.pwm.bean.PasswordStatus in project pwm by pwm-project.
the class UserInfoReader method isRequiresNewPassword.
@Override
public boolean isRequiresNewPassword() throws PwmUnrecoverableException {
final PasswordStatus passwordStatus = selfCachedReference.getPasswordStatus();
final List<UserPermission> updateProfilePermission = pwmApplication.getConfig().readSettingAsUserPermission(PwmSetting.QUERY_MATCH_CHANGE_PASSWORD);
if (!LdapPermissionTester.testUserPermissions(pwmApplication, sessionLabel, userIdentity, updateProfilePermission)) {
LOGGER.debug(sessionLabel, "checkPassword: " + userIdentity.toString() + " user does not have permission to change password");
return false;
}
if (passwordStatus.isExpired()) {
LOGGER.debug(sessionLabel, "checkPassword: password is expired, marking new password as required");
return true;
}
if (passwordStatus.isPreExpired()) {
LOGGER.debug(sessionLabel, "checkPassword: password is pre-expired, marking new password as required");
return true;
}
if (passwordStatus.isWarnPeriod()) {
LOGGER.debug(sessionLabel, "checkPassword: password is within warn period, marking new password as required");
return true;
}
if (passwordStatus.isViolatesPolicy()) {
LOGGER.debug(sessionLabel, "checkPassword: current password violates password policy, marking new password as required");
return true;
}
return false;
}
use of password.pwm.bean.PasswordStatus in project pwm by pwm-project.
the class ForgottenPasswordServlet method nextStep.
@Override
@SuppressWarnings("checkstyle:MethodLength")
protected void nextStep(final PwmRequest pwmRequest) throws IOException, ServletException, PwmUnrecoverableException, ChaiUnavailableException {
final PwmApplication pwmApplication = pwmRequest.getPwmApplication();
final Configuration config = pwmRequest.getConfig();
final ForgottenPasswordBean forgottenPasswordBean = forgottenPasswordBean(pwmRequest);
final ForgottenPasswordBean.RecoveryFlags recoveryFlags = forgottenPasswordBean.getRecoveryFlags();
final ForgottenPasswordBean.Progress progress = forgottenPasswordBean.getProgress();
// check for identified user;
if (forgottenPasswordBean.getUserIdentity() == null && !forgottenPasswordBean.isBogusUser()) {
pwmRequest.addFormInfoToRequestAttr(PwmSetting.FORGOTTEN_PASSWORD_SEARCH_FORM, false, false);
pwmRequest.forwardToJsp(JspUrl.RECOVER_PASSWORD_SEARCH);
return;
}
final ForgottenPasswordProfile forgottenPasswordProfile = ForgottenPasswordUtil.forgottenPasswordProfile(pwmRequest.getPwmApplication(), forgottenPasswordBean);
{
final Map<String, ForgottenPasswordProfile> profileIDList = pwmRequest.getConfig().getForgottenPasswordProfiles();
final String profileDebugMsg = forgottenPasswordProfile != null && profileIDList != null && profileIDList.size() > 1 ? " profile=" + forgottenPasswordProfile.getIdentifier() + ", " : "";
LOGGER.trace(pwmRequest, "entering forgotten password progress engine: " + profileDebugMsg + "flags=" + JsonUtil.serialize(recoveryFlags) + ", " + "progress=" + JsonUtil.serialize(progress));
}
if (forgottenPasswordProfile == null) {
throw new PwmUnrecoverableException(new ErrorInformation(PwmError.ERROR_NO_PROFILE_ASSIGNED));
}
// check for previous authentication
if (recoveryFlags.getRequiredAuthMethods().contains(IdentityVerificationMethod.PREVIOUS_AUTH) || recoveryFlags.getOptionalAuthMethods().contains(IdentityVerificationMethod.PREVIOUS_AUTH)) {
if (!progress.getSatisfiedMethods().contains(IdentityVerificationMethod.PREVIOUS_AUTH)) {
final UserIdentity userIdentity = forgottenPasswordBean.getUserIdentity();
final String userGuid = LdapOperationsHelper.readLdapGuidValue(pwmApplication, pwmRequest.getSessionLabel(), userIdentity, true);
if (ForgottenPasswordUtil.checkAuthRecord(pwmRequest, userGuid)) {
LOGGER.debug(pwmRequest, "marking " + IdentityVerificationMethod.PREVIOUS_AUTH + " method as satisfied");
progress.getSatisfiedMethods().add(IdentityVerificationMethod.PREVIOUS_AUTH);
}
}
}
// dispatch required auth methods.
for (final IdentityVerificationMethod method : recoveryFlags.getRequiredAuthMethods()) {
if (!progress.getSatisfiedMethods().contains(method)) {
forwardUserBasedOnRecoveryMethod(pwmRequest, method);
return;
}
}
// redirect if an verification method is in progress
if (progress.getInProgressVerificationMethod() != null) {
if (progress.getSatisfiedMethods().contains(progress.getInProgressVerificationMethod())) {
progress.setInProgressVerificationMethod(null);
} else {
pwmRequest.setAttribute(PwmRequestAttribute.ForgottenPasswordOptionalPageView, "true");
forwardUserBasedOnRecoveryMethod(pwmRequest, progress.getInProgressVerificationMethod());
return;
}
}
// check if more optional methods required
if (recoveryFlags.getMinimumOptionalAuthMethods() > 0) {
final Set<IdentityVerificationMethod> satisfiedOptionalMethods = ForgottenPasswordUtil.figureSatisfiedOptionalAuthMethods(recoveryFlags, progress);
if (satisfiedOptionalMethods.size() < recoveryFlags.getMinimumOptionalAuthMethods()) {
final Set<IdentityVerificationMethod> remainingAvailableOptionalMethods = ForgottenPasswordUtil.figureRemainingAvailableOptionalAuthMethods(pwmRequest, forgottenPasswordBean);
if (remainingAvailableOptionalMethods.isEmpty()) {
final String errorMsg = "additional optional verification methods are needed, however all available optional verification methods have been satisfied by user";
final ErrorInformation errorInformation = new ErrorInformation(PwmError.ERROR_RECOVERY_SEQUENCE_INCOMPLETE, errorMsg);
LOGGER.error(pwmRequest, errorInformation);
pwmRequest.respondWithError(errorInformation);
return;
} else {
if (remainingAvailableOptionalMethods.size() == 1) {
final IdentityVerificationMethod remainingMethod = remainingAvailableOptionalMethods.iterator().next();
LOGGER.debug(pwmRequest, "only 1 remaining available optional verification method, will redirect to " + remainingMethod.toString());
forwardUserBasedOnRecoveryMethod(pwmRequest, remainingMethod);
progress.setInProgressVerificationMethod(remainingMethod);
return;
}
}
processVerificationChoice(pwmRequest);
return;
}
}
if (progress.getSatisfiedMethods().isEmpty()) {
final String errorMsg = "forgotten password recovery sequence completed, but user has not actually satisfied any verification methods";
final ErrorInformation errorInformation = new ErrorInformation(PwmError.ERROR_RECOVERY_SEQUENCE_INCOMPLETE, errorMsg);
LOGGER.error(pwmRequest, errorInformation);
clearForgottenPasswordBean(pwmRequest);
throw new PwmUnrecoverableException(errorInformation);
}
{
final int satisfiedMethods = progress.getSatisfiedMethods().size();
final int totalMethodsNeeded = recoveryFlags.getRequiredAuthMethods().size() + recoveryFlags.getMinimumOptionalAuthMethods();
if (satisfiedMethods < totalMethodsNeeded) {
final String errorMsg = "forgotten password recovery sequence completed " + satisfiedMethods + " methods, " + " but policy requires a total of " + totalMethodsNeeded + " methods";
final ErrorInformation errorInformation = new ErrorInformation(PwmError.ERROR_RECOVERY_SEQUENCE_INCOMPLETE, errorMsg);
LOGGER.error(pwmRequest, errorInformation);
clearForgottenPasswordBean(pwmRequest);
throw new PwmUnrecoverableException(errorInformation);
}
}
if (!forgottenPasswordBean.getProgress().isAllPassed()) {
forgottenPasswordBean.getProgress().setAllPassed(true);
StatisticsManager.incrementStat(pwmRequest, Statistic.RECOVERY_SUCCESSES);
}
final UserInfo userInfo = ForgottenPasswordUtil.readUserInfo(pwmRequest, forgottenPasswordBean);
if (userInfo == null) {
throw PwmUnrecoverableException.newException(PwmError.ERROR_UNKNOWN, "unable to load userInfo while processing forgotten password controller");
}
// check if user's pw is within min lifetime window
final RecoveryMinLifetimeOption minLifetimeOption = forgottenPasswordProfile.readSettingAsEnum(PwmSetting.RECOVERY_MINIMUM_PASSWORD_LIFETIME_OPTIONS, RecoveryMinLifetimeOption.class);
if (minLifetimeOption == RecoveryMinLifetimeOption.NONE || (!userInfo.isPasswordLocked() && minLifetimeOption == RecoveryMinLifetimeOption.UNLOCKONLY)) {
if (userInfo.isWithinPasswordMinimumLifetime()) {
PasswordUtility.throwPasswordTooSoonException(userInfo, pwmRequest.getSessionLabel());
}
}
final boolean disallowAllButUnlock = minLifetimeOption == RecoveryMinLifetimeOption.UNLOCKONLY && userInfo.isPasswordLocked();
LOGGER.trace(pwmRequest, "all recovery checks passed, proceeding to configured recovery action");
final RecoveryAction recoveryAction = ForgottenPasswordUtil.getRecoveryAction(config, forgottenPasswordBean);
if (recoveryAction == RecoveryAction.SENDNEWPW || recoveryAction == RecoveryAction.SENDNEWPW_AND_EXPIRE) {
if (disallowAllButUnlock) {
PasswordUtility.throwPasswordTooSoonException(userInfo, pwmRequest.getSessionLabel());
}
ForgottenPasswordUtil.doActionSendNewPassword(pwmRequest);
return;
}
if (forgottenPasswordProfile.readSettingAsBoolean(PwmSetting.RECOVERY_ALLOW_UNLOCK)) {
final PasswordStatus passwordStatus = userInfo.getPasswordStatus();
if (!passwordStatus.isExpired() && !passwordStatus.isPreExpired()) {
if (userInfo.isPasswordLocked()) {
pwmRequest.setAttribute(PwmRequestAttribute.ForgottenPasswordInhibitPasswordReset, Boolean.TRUE);
pwmRequest.forwardToJsp(JspUrl.RECOVER_PASSWORD_ACTION_CHOICE);
return;
}
}
}
this.executeResetPassword(pwmRequest);
}
use of password.pwm.bean.PasswordStatus in project pwm by pwm-project.
the class ChangePasswordServletUtil method determineIfCurrentPasswordRequired.
static boolean determineIfCurrentPasswordRequired(final PwmApplication pwmApplication, final PwmSession pwmSession) throws PwmUnrecoverableException {
final RequireCurrentPasswordMode currentSetting = pwmApplication.getConfig().readSettingAsEnum(PwmSetting.PASSWORD_REQUIRE_CURRENT, RequireCurrentPasswordMode.class);
if (currentSetting == RequireCurrentPasswordMode.FALSE) {
return false;
}
if (pwmSession.getLoginInfoBean().getType() == AuthenticationType.AUTH_FROM_PUBLIC_MODULE) {
LOGGER.debug(pwmSession, "skipping user current password requirement, authentication type is " + AuthenticationType.AUTH_FROM_PUBLIC_MODULE);
return false;
}
{
final PasswordData currentPassword = pwmSession.getLoginInfoBean().getUserCurrentPassword();
if (currentPassword == null) {
LOGGER.debug(pwmSession, "skipping user current password requirement, current password is not known to application");
return false;
}
}
if (currentSetting == RequireCurrentPasswordMode.TRUE) {
return true;
}
final PasswordStatus passwordStatus = pwmSession.getUserInfo().getPasswordStatus();
return currentSetting == RequireCurrentPasswordMode.NOTEXPIRED && !passwordStatus.isExpired() && !passwordStatus.isPreExpired() && !passwordStatus.isViolatesPolicy() && !pwmSession.getUserInfo().isRequiresNewPassword();
}
Aggregations