private static Date determinePwdLastModified( final PwmApplication pwmApplication, final SessionLabel sessionLabel, final ChaiUser theUser, final UserIdentity userIdentity) throws ChaiUnavailableException, PwmUnrecoverableException { // fetch last password modification time from pwm last update attribute operation try { final Date chaiReadDate = theUser.readPasswordModificationDate(); if (chaiReadDate != null) { LOGGER.trace( sessionLabel, "read last user password change timestamp (via chai) as: " + PwmConstants.DEFAULT_DATETIME_FORMAT.format(chaiReadDate)); return chaiReadDate; } } catch (ChaiOperationException e) { LOGGER.error( sessionLabel, "unexpected error reading password last modified timestamp: " + e.getMessage()); } final LdapProfile ldapProfile = pwmApplication.getConfig().getLdapProfiles().get(userIdentity.getLdapProfileID()); final String pwmLastSetAttr = ldapProfile.readSettingAsString(PwmSetting.PASSWORD_LAST_UPDATE_ATTRIBUTE); if (pwmLastSetAttr != null && pwmLastSetAttr.length() > 0) { try { final Date pwmPwdLastModified = theUser.readDateAttribute(pwmLastSetAttr); LOGGER.trace( sessionLabel, "read pwmPasswordChangeTime as: " + (pwmPwdLastModified == null ? "n/a" : PwmConstants.DEFAULT_DATETIME_FORMAT.format(pwmPwdLastModified))); return pwmPwdLastModified; } catch (ChaiOperationException e) { LOGGER.error( sessionLabel, "error parsing password last modified PWM password value for user " + theUser.getEntryDN() + "; error: " + e.getMessage()); } } LOGGER.debug(sessionLabel, "unable to determine time of user's last password modification"); return null; }
public static Map<String, Date> readIndividualReplicaLastPasswordTimes( final PwmApplication pwmApplication, final SessionLabel sessionLabel, final UserIdentity userIdentity) throws PwmUnrecoverableException { final Map<String, Date> returnValue = new LinkedHashMap<>(); final ChaiProvider chaiProvider = pwmApplication.getProxyChaiProvider(userIdentity.getLdapProfileID()); final Collection<ChaiConfiguration> perReplicaConfigs = ChaiUtility.splitConfigurationPerReplica( chaiProvider.getChaiConfiguration(), Collections.singletonMap(ChaiSetting.FAILOVER_CONNECT_RETRIES, "1")); for (final ChaiConfiguration loopConfiguration : perReplicaConfigs) { final String loopReplicaUrl = loopConfiguration.getSetting(ChaiSetting.BIND_DN); ChaiProvider loopProvider = null; try { loopProvider = ChaiProviderFactory.createProvider(loopConfiguration); final Date lastModifiedDate = determinePwdLastModified(pwmApplication, sessionLabel, userIdentity); returnValue.put(loopReplicaUrl, lastModifiedDate); } catch (ChaiUnavailableException e) { LOGGER.error(sessionLabel, "unreachable server during replica password sync check"); e.printStackTrace(); } finally { if (loopProvider != null) { try { loopProvider.close(); } catch (Exception e) { final String errorMsg = "error closing loopProvider to " + loopReplicaUrl + " while checking individual password sync status"; LOGGER.error(sessionLabel, errorMsg); } } } } return returnValue; }