use of password.pwm.util.java.TimeDuration in project pwm by pwm-project.
the class DataStoreRecordStore method cleanup.
@Override
public void cleanup(final TimeDuration maxRecordAge) {
if (TimeDuration.fromCurrent(eldestRecord).isShorterThan(maxRecordAge)) {
return;
}
eldestRecord = Instant.now();
final long startTime = System.currentTimeMillis();
final int recordsExamined = 0;
int recordsRemoved = 0;
boolean complete = false;
while (!complete && intruderManager.status() == PwmService.STATUS.OPEN) {
final List<String> recordsToRemove = discoverPurgableKeys(maxRecordAge);
if (recordsToRemove.isEmpty()) {
complete = true;
}
try {
for (final String key : recordsToRemove) {
dataStore.remove(key);
}
} catch (PwmException e) {
LOGGER.error("unable to perform removal of identified stale records: " + e.getMessage());
}
recordsRemoved += recordsToRemove.size();
recordsToRemove.clear();
}
final TimeDuration totalDuration = TimeDuration.fromCurrent(startTime);
LOGGER.trace("completed cleanup of intruder table in " + totalDuration.asCompactString() + ", recordsExamined=" + recordsExamined + ", recordsRemoved=" + recordsRemoved);
}
use of password.pwm.util.java.TimeDuration 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.util.java.TimeDuration in project pwm by pwm-project.
the class IntruderManager method init.
@Override
@SuppressWarnings("checkstyle:MethodLength")
public void init(final PwmApplication pwmApplication) throws PwmException {
this.pwmApplication = pwmApplication;
final Configuration config = pwmApplication.getConfig();
status = STATUS.OPENING;
if (pwmApplication.getLocalDB() == null || pwmApplication.getLocalDB().status() != LocalDB.Status.OPEN) {
final ErrorInformation errorInformation = new ErrorInformation(PwmError.ERROR_SERVICE_NOT_AVAILABLE, "unable to start IntruderManager, LocalDB unavailable");
LOGGER.error(errorInformation.toDebugStr());
startupError = errorInformation;
status = STATUS.CLOSED;
return;
}
if (!pwmApplication.getConfig().readSettingAsBoolean(PwmSetting.INTRUDER_ENABLE)) {
final ErrorInformation errorInformation = new ErrorInformation(PwmError.ERROR_SERVICE_NOT_AVAILABLE, "intruder module not enabled");
LOGGER.debug(errorInformation.toDebugStr());
status = STATUS.CLOSED;
return;
}
final DataStore dataStore;
{
final IntruderStorageMethod intruderStorageMethod = pwmApplication.getConfig().readSettingAsEnum(PwmSetting.INTRUDER_STORAGE_METHOD, IntruderStorageMethod.class);
final String debugMsg;
final DataStorageMethod storageMethodUsed;
switch(intruderStorageMethod) {
case AUTO:
dataStore = DataStoreFactory.autoDbOrLocalDBstore(pwmApplication, DatabaseTable.INTRUDER, LocalDB.DB.INTRUDER);
if (dataStore instanceof DatabaseDataStore) {
debugMsg = "starting using auto-configured data store, Remote Database selected";
storageMethodUsed = DataStorageMethod.DB;
} else {
debugMsg = "starting using auto-configured data store, LocalDB selected";
storageMethodUsed = DataStorageMethod.LOCALDB;
}
break;
case DATABASE:
dataStore = new DatabaseDataStore(pwmApplication.getDatabaseService(), DatabaseTable.INTRUDER);
debugMsg = "starting using Remote Database data store";
storageMethodUsed = DataStorageMethod.DB;
break;
case LOCALDB:
dataStore = new LocalDBDataStore(pwmApplication.getLocalDB(), LocalDB.DB.INTRUDER);
debugMsg = "starting using LocalDB data store";
storageMethodUsed = DataStorageMethod.LOCALDB;
break;
default:
startupError = new ErrorInformation(PwmError.ERROR_UNKNOWN, "unknown storageMethod selected: " + intruderStorageMethod);
status = STATUS.CLOSED;
return;
}
LOGGER.info(debugMsg);
serviceInfo = new ServiceInfoBean(Collections.singletonList(storageMethodUsed));
}
final RecordStore recordStore;
{
recordStore = new DataStoreRecordStore(dataStore, this);
final String threadName = JavaHelper.makeThreadName(pwmApplication, this.getClass()) + " timer";
timer = new Timer(threadName, true);
final long maxRecordAge = Long.parseLong(pwmApplication.getConfig().readAppProperty(AppProperty.INTRUDER_RETENTION_TIME_MS));
final long cleanerRunFrequency = Long.parseLong(pwmApplication.getConfig().readAppProperty(AppProperty.INTRUDER_CLEANUP_FREQUENCY_MS));
timer.schedule(new TimerTask() {
@Override
public void run() {
try {
recordStore.cleanup(new TimeDuration(maxRecordAge));
} catch (Exception e) {
LOGGER.error("error cleaning recordStore: " + e.getMessage(), e);
}
}
}, 1000, cleanerRunFrequency);
}
try {
{
final IntruderSettings settings = new IntruderSettings();
settings.setCheckCount((int) config.readSettingAsLong(PwmSetting.INTRUDER_USER_MAX_ATTEMPTS));
settings.setResetDuration(new TimeDuration(1000 * config.readSettingAsLong(PwmSetting.INTRUDER_USER_RESET_TIME)));
settings.setCheckDuration(new TimeDuration(1000 * config.readSettingAsLong(PwmSetting.INTRUDER_USER_CHECK_TIME)));
if (settings.getCheckCount() == 0 || settings.getCheckDuration().getTotalMilliseconds() == 0 || settings.getResetDuration().getTotalMilliseconds() == 0) {
LOGGER.info("intruder user checking will remain disabled due to configuration settings");
} else {
recordManagers.put(RecordType.USERNAME, new RecordManagerImpl(RecordType.USERNAME, recordStore, settings));
recordManagers.put(RecordType.USER_ID, new RecordManagerImpl(RecordType.USER_ID, recordStore, settings));
}
}
{
final IntruderSettings settings = new IntruderSettings();
settings.setCheckCount((int) config.readSettingAsLong(PwmSetting.INTRUDER_ATTRIBUTE_MAX_ATTEMPTS));
settings.setResetDuration(new TimeDuration(1000 * config.readSettingAsLong(PwmSetting.INTRUDER_ATTRIBUTE_RESET_TIME)));
settings.setCheckDuration(new TimeDuration(1000 * config.readSettingAsLong(PwmSetting.INTRUDER_ATTRIBUTE_CHECK_TIME)));
if (settings.getCheckCount() == 0 || settings.getCheckDuration().getTotalMilliseconds() == 0 || settings.getResetDuration().getTotalMilliseconds() == 0) {
LOGGER.info("intruder user checking will remain disabled due to configuration settings");
} else {
recordManagers.put(RecordType.ATTRIBUTE, new RecordManagerImpl(RecordType.ATTRIBUTE, recordStore, settings));
}
}
{
final IntruderSettings settings = new IntruderSettings();
settings.setCheckCount((int) config.readSettingAsLong(PwmSetting.INTRUDER_TOKEN_DEST_MAX_ATTEMPTS));
settings.setResetDuration(new TimeDuration(1000 * config.readSettingAsLong(PwmSetting.INTRUDER_TOKEN_DEST_RESET_TIME)));
settings.setCheckDuration(new TimeDuration(1000 * config.readSettingAsLong(PwmSetting.INTRUDER_TOKEN_DEST_CHECK_TIME)));
if (settings.getCheckCount() == 0 || settings.getCheckDuration().getTotalMilliseconds() == 0 || settings.getResetDuration().getTotalMilliseconds() == 0) {
LOGGER.info("intruder user checking will remain disabled due to configuration settings");
} else {
recordManagers.put(RecordType.TOKEN_DEST, new RecordManagerImpl(RecordType.TOKEN_DEST, recordStore, settings));
}
}
{
final IntruderSettings settings = new IntruderSettings();
settings.setCheckCount((int) config.readSettingAsLong(PwmSetting.INTRUDER_ADDRESS_MAX_ATTEMPTS));
settings.setResetDuration(new TimeDuration(1000 * config.readSettingAsLong(PwmSetting.INTRUDER_ADDRESS_RESET_TIME)));
settings.setCheckDuration(new TimeDuration(1000 * config.readSettingAsLong(PwmSetting.INTRUDER_ADDRESS_CHECK_TIME)));
if (settings.getCheckCount() == 0 || settings.getCheckDuration().getTotalMilliseconds() == 0 || settings.getResetDuration().getTotalMilliseconds() == 0) {
LOGGER.info("intruder address checking will remain disabled due to configuration settings");
} else {
recordManagers.put(RecordType.ADDRESS, new RecordManagerImpl(RecordType.ADDRESS, recordStore, settings));
}
}
status = STATUS.OPEN;
} catch (Exception e) {
final ErrorInformation errorInformation = new ErrorInformation(PwmError.ERROR_SERVICE_NOT_AVAILABLE, "unexpected error starting intruder manager: " + e.getMessage());
LOGGER.error(errorInformation.toDebugStr());
startupError = errorInformation;
close();
}
}
use of password.pwm.util.java.TimeDuration in project pwm by pwm-project.
the class PwNotifyEngine method executeJob.
void executeJob() throws ChaiUnavailableException, ChaiOperationException, PwmOperationalException, PwmUnrecoverableException {
startTime = Instant.now();
examinedCount = 0;
noticeCount = 0;
try {
internalLog.delete(0, internalLog.length());
running = true;
if (!canRunOnThisServer()) {
return;
}
if (JavaHelper.isEmpty(permissionList)) {
log("no users are included in permission list setting " + PwmSetting.PW_EXPY_NOTIFY_PERMISSION.toMenuLocationDebug(null, null) + ", exiting.");
return;
}
log("starting job, beginning ldap search");
final Iterator<UserIdentity> workQueue = LdapOperationsHelper.readAllUsersFromLdap(pwmApplication, null, null, settings.getMaxLdapSearchSize());
log("ldap search complete, examining users...");
while (workQueue.hasNext()) {
if (!checkIfRunningOnMaster()) {
final String msg = "job interrupted, server is no longer the cluster master.";
log(msg);
throw PwmUnrecoverableException.newException(PwmError.ERROR_SERVICE_NOT_AVAILABLE, msg);
}
checkIfRunningOnMaster();
examinedCount++;
final List<UserIdentity> batch = new ArrayList<>();
final int batchSize = settings.getBatchCount();
while (batch.size() < batchSize && workQueue.hasNext()) {
batch.add(workQueue.next());
}
final Instant startBatch = Instant.now();
examinedCount += batch.size();
noticeCount += processBatch(batch);
eventRateMeter.markEvents(batchSize);
final TimeDuration batchTime = TimeDuration.fromCurrent(startBatch);
final TimeDuration pauseTime = new TimeDuration(settings.getBatchTimeMultiplier().multiply(new BigDecimal(batchTime.getTotalMilliseconds())).longValue(), TimeUnit.MILLISECONDS);
pauseTime.pause();
debugOutputTask.conditionallyExecuteTask();
}
log("job complete, " + examinedCount + " users evaluated in " + TimeDuration.fromCurrent(startTime).asCompactString() + ", sent " + noticeCount + " notices.");
} finally {
running = false;
}
}
use of password.pwm.util.java.TimeDuration in project pwm by pwm-project.
the class PasswordUtility method isPasswordWithinMinimumLifetimeImpl.
public static boolean isPasswordWithinMinimumLifetimeImpl(final ChaiUser chaiUser, final SessionLabel sessionLabel, final PwmPasswordPolicy passwordPolicy, final Instant lastModified, final PasswordStatus passwordStatus) throws PwmUnrecoverableException {
// for oracle DS; this check is also handled in UserAuthenticator.
try {
if (DirectoryVendor.ORACLE_DS == chaiUser.getChaiProvider().getDirectoryVendor()) {
final String oracleDSPrePasswordAllowChangeTime = chaiUser.readStringAttribute("passwordAllowChangeTime");
if (oracleDSPrePasswordAllowChangeTime != null && !oracleDSPrePasswordAllowChangeTime.isEmpty()) {
final Instant date = OracleDSEntries.convertZuluToDate(oracleDSPrePasswordAllowChangeTime);
if (Instant.now().isBefore(date)) {
LOGGER.debug("discovered oracleds allowed change time is set to: " + JavaHelper.toIsoDate(date) + ", won't permit password change");
final String errorMsg = "change not permitted until " + JavaHelper.toIsoDate(date);
final ErrorInformation errorInformation = new ErrorInformation(PwmError.PASSWORD_TOO_SOON, errorMsg);
throw new PwmUnrecoverableException(errorInformation);
}
}
return false;
}
} catch (ChaiException e) {
LOGGER.debug(sessionLabel, "unexpected error reading OracleDS password allow modification time: " + e.getMessage());
}
final TimeDuration minimumLifetime;
{
final int minimumLifetimeSeconds = passwordPolicy.getRuleHelper().readIntValue(PwmPasswordRule.MinimumLifetime);
if (minimumLifetimeSeconds < 1) {
return false;
}
if (lastModified == null) {
LOGGER.debug(sessionLabel, "skipping minimum lifetime check, password last set time is unknown");
return false;
}
minimumLifetime = new TimeDuration(minimumLifetimeSeconds, TimeUnit.SECONDS);
}
final TimeDuration passwordAge = TimeDuration.fromCurrent(lastModified);
LOGGER.trace(sessionLabel, "beginning check for minimum lifetime, lastModified=" + JavaHelper.toIsoDate(lastModified) + ", minimumLifetimeSeconds=" + minimumLifetime.asCompactString() + ", passwordAge=" + passwordAge.asCompactString());
if (lastModified.isAfter(Instant.now())) {
LOGGER.debug(sessionLabel, "skipping minimum lifetime check, password lastModified time is in the future");
return false;
}
final boolean passwordTooSoon = passwordAge.isShorterThan(minimumLifetime);
if (!passwordTooSoon) {
LOGGER.trace(sessionLabel, "minimum lifetime check passed, password age ");
return false;
}
if (passwordStatus.isExpired() || passwordStatus.isPreExpired() || passwordStatus.isWarnPeriod()) {
LOGGER.debug(sessionLabel, "current password is too young, but skipping enforcement of minimum lifetime check because current password is expired");
return false;
}
return true;
}
Aggregations