public UserCacheRecord next() { try { UserCacheRecord returnBean = null; while (returnBean == null && this.storageKeyIterator.hasNext()) { UserCacheService.StorageKey key = this.storageKeyIterator.next(); returnBean = userCacheService.readStorageKey(key); if (returnBean != null) { if (returnBean.getCacheTimestamp() == null) { LOGGER.debug( PwmConstants.REPORTING_SESSION_LABEL, "purging record due to missing cache timestamp: " + JsonUtil.serialize(returnBean)); userCacheService.removeStorageKey(key); } else if (TimeDuration.fromCurrent(returnBean.getCacheTimestamp()) .isLongerThan(settings.getMaxCacheAge())) { LOGGER.debug( PwmConstants.REPORTING_SESSION_LABEL, "purging record due to old age timestamp: " + JsonUtil.serialize(returnBean)); userCacheService.removeStorageKey(key); } else { return returnBean; } } } } catch (LocalDBException e) { throw new IllegalStateException( "unexpected iterator traversal error while reading LocalDB: " + e.getMessage()); } return null; }
private static List<UserIdentity> readAllUsersFromLdap( final PwmApplication pwmApplication, final String searchFilter, final int maxResults) throws ChaiUnavailableException, ChaiOperationException, PwmUnrecoverableException, PwmOperationalException { final UserSearchEngine userSearchEngine = new UserSearchEngine(pwmApplication, null); final UserSearchEngine.SearchConfiguration searchConfiguration = new UserSearchEngine.SearchConfiguration(); searchConfiguration.setEnableValueEscaping(false); searchConfiguration.setSearchTimeout( Long.parseLong( pwmApplication.getConfig().readAppProperty(AppProperty.REPORTING_LDAP_SEARCH_TIMEOUT))); if (searchFilter == null) { searchConfiguration.setUsername("*"); } else { searchConfiguration.setFilter(searchFilter); } LOGGER.debug( PwmConstants.REPORTING_SESSION_LABEL, "beginning UserReportService user search using parameters: " + (JsonUtil.serialize(searchConfiguration))); final Map<UserIdentity, Map<String, String>> searchResults = userSearchEngine.performMultiUserSearch( searchConfiguration, maxResults, Collections.<String>emptyList()); LOGGER.debug( PwmConstants.REPORTING_SESSION_LABEL, "user search found " + searchResults.size() + " users for reporting"); final List<UserIdentity> returnList = new ArrayList<>(searchResults.keySet()); Collections.shuffle(returnList); return returnList; }
public String getStatistic(final Statistic statistic) { switch (statistic.getType()) { case INCREMENTOR: return valueMap.containsKey(statistic) ? valueMap.get(statistic) : "0"; case AVERAGE: final String avgStrValue = valueMap.get(statistic); AverageBean avgBean = new AverageBean(); if (avgStrValue != null && avgStrValue.length() > 0) { try { avgBean = JsonUtil.deserialize(avgStrValue, AverageBean.class); } catch (Exception e) { LOGGER.trace( "unable to parse statistics value for stat " + statistic.toString() + ", value=" + avgStrValue); } } return avgBean.getAverage().toString(); default: return ""; } }
private void restBrowseLdap(final PwmRequest pwmRequest, final ConfigGuideBean configGuideBean) throws IOException, ServletException, PwmUnrecoverableException { final StoredConfigurationImpl storedConfiguration = StoredConfigurationImpl.copy(configGuideBean.getStoredConfiguration()); if (configGuideBean.getStep() == STEP.LDAP_ADMIN) { storedConfiguration.resetSetting(PwmSetting.LDAP_PROXY_USER_DN, LDAP_PROFILE_KEY, null); storedConfiguration.resetSetting(PwmSetting.LDAP_PROXY_USER_PASSWORD, LDAP_PROFILE_KEY, null); } final Date startTime = new Date(); final Map<String, String> inputMap = pwmRequest.readBodyAsJsonStringMap(PwmHttpRequestWrapper.Flag.BypassValidation); final String profile = inputMap.get("profile"); final String dn = inputMap.containsKey("dn") ? inputMap.get("dn") : ""; final LdapBrowser ldapBrowser = new LdapBrowser(storedConfiguration); final LdapBrowser.LdapBrowseResult result = ldapBrowser.doBrowse(profile, dn); ldapBrowser.close(); LOGGER.trace( pwmRequest, "performed ldapBrowse operation in " + TimeDuration.fromCurrent(startTime).asCompactString() + ", result=" + JsonUtil.serialize(result)); pwmRequest.outputJsonResult(new RestResultBean(result)); }
public void establishEndpointSession() throws PwmUnrecoverableException { LOGGER.debug("establishing endpoint connection to " + endpointURL); final String m1 = id + salt; final String m1Hash = SecureEngine.hash(m1, PwmHashAlgorithm.SHA256).toLowerCase(); final String m2 = secret + m1Hash; final String m2Hash = SecureEngine.hash(m2, PwmHashAlgorithm.SHA256).toLowerCase(); final HashMap<String, Object> initConnectMap = new HashMap<>(); initConnectMap.put("salt", salt); initConnectMap.put("endpoint_secret_hash", m2Hash); initConnectMap.put("session_data", new HashMap<String, String>()); final PwmHttpClientResponse response = makeApiRequest(HttpMethod.POST, "/endpoints/" + id + "/sessions", initConnectMap); final String body = response.getBody(); final Map<String, String> responseValues = JsonUtil.deserializeStringMap(body); endpoint_session_id = responseValues.get("endpoint_session_id"); LOGGER.debug( "endpoint connection established to " + endpointURL + ", endpoint_session_id=" + endpoint_session_id); }
private void updateCacheFromLdap() throws ChaiUnavailableException, ChaiOperationException, PwmOperationalException, PwmUnrecoverableException { LOGGER.debug( PwmConstants.REPORTING_SESSION_LABEL, "beginning process to updating user cache records from ldap"); if (status != STATUS.OPEN) { return; } cancelFlag = false; reportStatus = new ReportStatusInfo(settings.getSettingsHash()); reportStatus.setInProgress(true); reportStatus.setStartDate(new Date()); try { final Queue<UserIdentity> allUsers = new LinkedList<>(getListOfUsers()); reportStatus.setTotal(allUsers.size()); while (status == STATUS.OPEN && !allUsers.isEmpty() && !cancelFlag) { final Date startUpdateTime = new Date(); final UserIdentity userIdentity = allUsers.poll(); try { if (updateCachedRecordFromLdap(userIdentity)) { reportStatus.setUpdated(reportStatus.getUpdated() + 1); } } catch (Exception e) { String errorMsg = "error while updating report cache for " + userIdentity.toString() + ", cause: "; errorMsg += e instanceof PwmException ? ((PwmException) e).getErrorInformation().toDebugStr() : e.getMessage(); final ErrorInformation errorInformation; errorInformation = new ErrorInformation(PwmError.ERROR_REPORTING_ERROR, errorMsg); LOGGER.error(PwmConstants.REPORTING_SESSION_LABEL, errorInformation.toDebugStr()); reportStatus.setLastError(errorInformation); reportStatus.setErrors(reportStatus.getErrors() + 1); } reportStatus.setCount(reportStatus.getCount() + 1); reportStatus.getEventRateMeter().markEvents(1); final TimeDuration totalUpdateTime = TimeDuration.fromCurrent(startUpdateTime); if (settings.isAutoCalcRest()) { avgTracker.addSample(totalUpdateTime.getTotalMilliseconds()); Helper.pause(avgTracker.avgAsLong()); } else { Helper.pause(settings.getRestTime().getTotalMilliseconds()); } } if (cancelFlag) { reportStatus.setLastError( new ErrorInformation( PwmError.ERROR_SERVICE_NOT_AVAILABLE, "report cancelled by operator")); } } finally { reportStatus.setFinishDate(new Date()); reportStatus.setInProgress(false); } LOGGER.debug( PwmConstants.REPORTING_SESSION_LABEL, "update user cache process completed: " + JsonUtil.serialize(reportStatus)); }
public void shutdown() { LOGGER.warn("shutting down"); { // send system audit event final SystemAuditRecord auditRecord = SystemAuditRecord.create(AuditEvent.SHUTDOWN, null, getInstanceID()); try { getAuditManager().submit(auditRecord); } catch (PwmException e) { LOGGER.warn("unable to submit alert event " + JsonUtil.serialize(auditRecord)); } } { final List<Class> reverseServiceList = new ArrayList<Class>(PWM_SERVICE_CLASSES); Collections.reverse(reverseServiceList); for (final Class serviceClass : reverseServiceList) { if (pwmServices.containsKey(serviceClass)) { LOGGER.trace("closing service " + serviceClass.getName()); final PwmService loopService = pwmServices.get(serviceClass); LOGGER.trace("successfully closed service " + serviceClass.getName()); try { loopService.close(); } catch (Exception e) { LOGGER.error( "error closing " + loopService.getClass().getSimpleName() + ": " + e.getMessage(), e); } } } } if (localDBLogger != null) { try { localDBLogger.close(); } catch (Exception e) { LOGGER.error("error closing localDBLogger: " + e.getMessage(), e); } localDBLogger = null; } if (localDB != null) { try { localDB.close(); } catch (Exception e) { LOGGER.fatal("error closing localDB: " + e, e); } localDB = null; } LOGGER.info( PwmConstants.PWM_APP_NAME + " " + PwmConstants.SERVLET_VERSION + " closed for bidness, cya!"); }
private void saveTempData() { try { final String jsonInfo = JsonUtil.serialize(reportStatus); pwmApplication.writeAppAttribute(PwmApplication.AppAttribute.REPORT_STATUS, jsonInfo); } catch (Exception e) { LOGGER.error( PwmConstants.REPORTING_SESSION_LABEL, "error writing cached report dredge info into memory: " + e.getMessage()); } }
@Override void doCommand() throws Exception { final PwmApplication pwmApplication = cliEnvironment.getPwmApplication(); final File outputFile = (File) cliEnvironment.getOptions().get(CliParameters.REQUIRED_NEW_OUTPUT_FILE.getName()); Helper.pause(2000); final long startTime = System.currentTimeMillis(); final UserSearchEngine userSearchEngine = new UserSearchEngine(pwmApplication, SessionLabel.SYSTEM_LABEL); final UserSearchEngine.SearchConfiguration searchConfiguration = new UserSearchEngine.SearchConfiguration(); searchConfiguration.setEnableValueEscaping(false); searchConfiguration.setUsername("*"); final String systemRecordDelimiter = System.getProperty("line.separator"); final Writer writer = new BufferedWriter(new PrintWriter(outputFile, PwmConstants.DEFAULT_CHARSET.toString())); final Map<UserIdentity, Map<String, String>> results = userSearchEngine.performMultiUserSearch( searchConfiguration, Integer.MAX_VALUE, Collections.<String>emptyList()); out( "searching " + results.size() + " users for stored responses to write to " + outputFile.getAbsolutePath() + "...."); int counter = 0; for (final UserIdentity identity : results.keySet()) { final ChaiUser user = pwmApplication.getProxiedChaiUser(identity); final ResponseSet responseSet = pwmApplication.getCrService().readUserResponseSet(null, identity, user); if (responseSet != null) { counter++; out("found responses for '" + user + "', writing to output."); final RestChallengesServer.JsonChallengesData outputData = new RestChallengesServer.JsonChallengesData(); outputData.challenges = responseSet.asChallengeBeans(true); outputData.helpdeskChallenges = responseSet.asHelpdeskChallengeBeans(true); outputData.minimumRandoms = responseSet.getChallengeSet().minimumResponses(); outputData.username = identity.toDelimitedKey(); writer.write(JsonUtil.serialize(outputData)); writer.write(systemRecordDelimiter); } else { out("skipping '" + user.toString() + "', no stored responses."); } } writer.close(); out( "output complete, " + counter + " responses exported in " + TimeDuration.fromCurrent(startTime).asCompactString()); }
PwmHttpClientResponse makeApiRequest( final HttpMethod method, final String urlPart, final Serializable body) throws PwmUnrecoverableException { final Map<String, String> headers = new HashMap<>(); headers.put(PwmConstants.HttpHeader.Content_Type.getHttpName(), "application/json"); if (locale != null) { headers.put(PwmConstants.HttpHeader.Accept_Language.getHttpName(), locale.toLanguageTag()); } final PwmHttpClientRequest pwmHttpClientRequest = new PwmHttpClientRequest( method, getEndpointURL() + urlPart, JsonUtil.serialize(body), headers); return pwmHttpClient.makeRequest(pwmHttpClientRequest); }
public synchronized void updateAverageValue(final Statistic statistic, final long timeDuration) { if (Statistic.Type.AVERAGE != statistic.getType()) { LOGGER.error("attempt to update average value of non-average stat " + statistic); return; } final String avgStrValue = valueMap.get(statistic); AverageBean avgBean = new AverageBean(); if (avgStrValue != null && avgStrValue.length() > 0) { try { avgBean = JsonUtil.deserialize(avgStrValue, AverageBean.class); } catch (Exception e) { LOGGER.trace( "unable to parse statistics value for stat " + statistic.toString() + ", value=" + avgStrValue); } } avgBean.appendValue(timeDuration); valueMap.put(statistic, JsonUtil.serialize(avgBean)); }
@Override public boolean contains(final DatabaseTable table, final String key) throws DatabaseException { final boolean result = get(table, key) != null; if (traceLogging) { final Map<String, Object> debugOutput = new LinkedHashMap<>(); debugOutput.put("table", table); debugOutput.put("key", key); debugOutput.put("result", result); LOGGER.trace( "contains operation result: " + JsonUtil.serializeMap(debugOutput, JsonUtil.Flag.PrettyPrint)); } updateStats(true, false); return result; }
private UserCacheRecord read(StorageKey key) throws LocalDBException { final String jsonValue = localDB.get(DB, key.getKey()); if (jsonValue != null && !jsonValue.isEmpty()) { try { return JsonUtil.deserialize(jsonValue, UserCacheRecord.class); } catch (JsonSyntaxException e) { LOGGER.error( "error reading record from cache store for key=" + key.getKey() + ", error: " + e.getMessage()); localDB.remove(DB, key.getKey()); } } return null; }
public List<NAAFChainBean> readChains(final String username) throws PwmUnrecoverableException { final Map<String, String> urlParams = new LinkedHashMap<>(); urlParams.put("username", username); urlParams.put("application", "NAM"); urlParams.put("is_trusted", "true"); urlParams.put("endpoint_session_id", this.getEndpoint_session_id()); final String url = PwmURL.appendAndEncodeUrlParameters("/logon/chains", urlParams); final PwmHttpClientResponse response = makeApiRequest(HttpMethod.POST, url, null); final NAAFChainInformationResponseBean naafChainInformationResponseBean = JsonUtil.deserialize(response.getBody(), NAAFChainInformationResponseBean.class); return naafChainInformationResponseBean.getChains(); }
@Override public String get(final DatabaseTable table, final String key) throws DatabaseException { if (traceLogging) { LOGGER.trace("attempting get operation for table=" + table + ", key=" + key); } preOperationCheck(); final StringBuilder sb = new StringBuilder(); sb.append("SELECT * FROM ").append(table.toString()).append(" WHERE " + KEY_COLUMN + " = ?"); PreparedStatement statement = null; ResultSet resultSet = null; String returnValue = null; try { statement = connection.prepareStatement(sb.toString()); statement.setString(1, key); statement.setMaxRows(1); resultSet = statement.executeQuery(); if (resultSet.next()) { returnValue = resultSet.getString(VALUE_COLUMN); } } catch (SQLException e) { final ErrorInformation errorInformation = new ErrorInformation( PwmError.ERROR_DB_UNAVAILABLE, "get operation failed: " + e.getMessage()); lastError = errorInformation; throw new DatabaseException(errorInformation); } finally { close(statement); close(resultSet); } if (traceLogging) { final LinkedHashMap<String, Object> debugOutput = new LinkedHashMap<>(); debugOutput.put("table", table); debugOutput.put("key", key); debugOutput.put("result", returnValue); LOGGER.trace( "get operation result: " + JsonUtil.serializeMap(debugOutput, JsonUtil.Flag.PrettyPrint)); } updateStats(true, false); return returnValue; }
private void writeDbValues() { if (localDB != null) { try { localDB.put(LocalDB.DB.PWM_STATS, DB_KEY_CUMULATIVE, statsCummulative.output()); localDB.put(LocalDB.DB.PWM_STATS, currentDailyKey.toString(), statsDaily.output()); for (final Statistic.EpsType loopEpsType : Statistic.EpsType.values()) { for (final Statistic.EpsDuration loopEpsDuration : Statistic.EpsDuration.values()) { final String key = "EPS-" + loopEpsType.toString(); final String mapKey = loopEpsType.toString() + loopEpsDuration.toString(); final String value = JsonUtil.serialize(this.epsMeterMap.get(mapKey)); localDB.put(LocalDB.DB.PWM_STATS, key, value); } } } catch (LocalDBException e) { LOGGER.error("error outputting pwm statistics: " + e.getMessage()); } } }
@Override public String toDebugString(boolean prettyFormat, Locale locale) { if (prettyFormat && values != null && !values.isEmpty()) { final StringBuilder sb = new StringBuilder(); for (final String localeKey : values.keySet()) { if (!values.get(localeKey).isEmpty()) { sb.append("Locale: ") .append(LocaleHelper.debugLabel(LocaleHelper.parseLocaleString(localeKey))) .append("\n"); for (final String value : values.get(localeKey)) { sb.append(" ").append(value).append("\n"); } } } return sb.toString(); } else { return JsonUtil.serializeMap(values); } }
@Override public boolean remove(final DatabaseTable table, final String key) throws DatabaseException { if (traceLogging) { LOGGER.trace("attempting remove operation for table=" + table + ", key=" + key); } boolean result = contains(table, key); if (result) { final StringBuilder sqlText = new StringBuilder(); sqlText.append("DELETE FROM ").append(table.toString()).append(" WHERE " + KEY_COLUMN + "=?"); PreparedStatement statement = null; try { statement = connection.prepareStatement(sqlText.toString()); statement.setString(1, key); statement.executeUpdate(); LOGGER.trace("remove operation succeeded for table=" + table + ", key=" + key); } catch (SQLException e) { final ErrorInformation errorInformation = new ErrorInformation( PwmError.ERROR_DB_UNAVAILABLE, "remove operation failed: " + e.getMessage()); lastError = errorInformation; throw new DatabaseException(errorInformation); } finally { close(statement); } } if (traceLogging) { final Map<String, Object> debugOutput = new LinkedHashMap<>(); debugOutput.put("table", table); debugOutput.put("key", key); debugOutput.put("result", result); LOGGER.trace( "remove operation result: " + JsonUtil.serializeMap(debugOutput, JsonUtil.Flag.PrettyPrint)); } updateStats(true, false); return result; }
public static StatisticsBundle input(final String inputString) { final Map<Statistic, String> srcMap = new HashMap<>(); final Map<String, String> loadedMap = JsonUtil.deserializeStringMap(inputString); for (final String key : loadedMap.keySet()) { try { srcMap.put(Statistic.valueOf(key), loadedMap.get(key)); } catch (IllegalArgumentException e) { LOGGER.error("error parsing statistic key '" + key + "', reason: " + e.getMessage()); } } final StatisticsBundle bundle = new StatisticsBundle(); for (final Statistic loopStat : Statistic.values()) { final String value = srcMap.get(loopStat); if (value != null && !value.equals("")) { bundle.valueMap.put(loopStat, value); } } return bundle; }
private void initTempData() throws LocalDBException, PwmUnrecoverableException { final String cleanFlag = pwmApplication.readAppAttribute(PwmApplication.AppAttribute.REPORT_CLEAN_FLAG); if (!"true".equals(cleanFlag)) { LOGGER.error(PwmConstants.REPORTING_SESSION_LABEL, "did not shut down cleanly"); reportStatus = new ReportStatusInfo(settings.getSettingsHash()); reportStatus.setTotal(userCacheService.size()); } else { try { final String jsonInfo = pwmApplication.readAppAttribute(PwmApplication.AppAttribute.REPORT_STATUS); if (jsonInfo != null && !jsonInfo.isEmpty()) { reportStatus = JsonUtil.deserialize(jsonInfo, ReportStatusInfo.class); } } catch (Exception e) { LOGGER.error( PwmConstants.REPORTING_SESSION_LABEL, "error loading cached report status info into memory: " + e.getMessage()); } } reportStatus = reportStatus == null ? new ReportStatusInfo(settings.getSettingsHash()) : reportStatus; // safety final String currentSettingCache = settings.getSettingsHash(); if (reportStatus.getSettingsHash() != null && !reportStatus.getSettingsHash().equals(currentSettingCache)) { LOGGER.error( PwmConstants.REPORTING_SESSION_LABEL, "configuration has changed, will clear cached report data"); clear(); } reportStatus.setInProgress(false); pwmApplication.writeAppAttribute(PwmApplication.AppAttribute.REPORT_CLEAN_FLAG, "false"); }
public static PasswordCheckInfo checkEnteredPassword( final PwmApplication pwmApplication, final Locale locale, final ChaiUser user, final UserInfoBean userInfoBean, final LoginInfoBean loginInfoBean, final PasswordData password, final PasswordData confirmPassword) throws PwmUnrecoverableException, ChaiUnavailableException { if (userInfoBean == null) { throw new NullPointerException("userInfoBean cannot be null"); } boolean pass = false; String userMessage = ""; int errorCode = 0; final boolean passwordIsCaseSensitive = userInfoBean.getPasswordPolicy() == null || userInfoBean .getPasswordPolicy() .getRuleHelper() .readBooleanValue(PwmPasswordRule.CaseSensitive); final CachePolicy cachePolicy; { final long cacheLifetimeMS = Long.parseLong( pwmApplication .getConfig() .readAppProperty(AppProperty.CACHE_PWRULECHECK_LIFETIME_MS)); cachePolicy = CachePolicy.makePolicyWithExpirationMS(cacheLifetimeMS); } if (password == null) { userMessage = new ErrorInformation(PwmError.PASSWORD_MISSING) .toUserStr(locale, pwmApplication.getConfig()); } else { final CacheService cacheService = pwmApplication.getCacheService(); final CacheKey cacheKey = user != null && userInfoBean.getUserIdentity() != null ? CacheKey.makeCacheKey( PasswordUtility.class, userInfoBean.getUserIdentity(), user.getEntryDN() + ":" + password.hash()) : null; if (pwmApplication.getConfig().isDevDebugMode()) { LOGGER.trace("generated cacheKey for password check request: " + cacheKey); } try { if (cacheService != null && cacheKey != null) { final String cachedValue = cacheService.get(cacheKey); if (cachedValue != null) { if (NEGATIVE_CACHE_HIT.equals(cachedValue)) { pass = true; } else { LOGGER.trace("cache hit!"); final ErrorInformation errorInformation = JsonUtil.deserialize(cachedValue, ErrorInformation.class); throw new PwmDataValidationException(errorInformation); } } } if (!pass) { final PwmPasswordRuleValidator pwmPasswordRuleValidator = new PwmPasswordRuleValidator( pwmApplication, userInfoBean.getPasswordPolicy(), locale); final PasswordData oldPassword = loginInfoBean == null ? null : loginInfoBean.getUserCurrentPassword(); pwmPasswordRuleValidator.testPassword(password, oldPassword, userInfoBean, user); pass = true; if (cacheService != null && cacheKey != null) { cacheService.put(cacheKey, cachePolicy, NEGATIVE_CACHE_HIT); } } } catch (PwmDataValidationException e) { errorCode = e.getError().getErrorCode(); userMessage = e.getErrorInformation().toUserStr(locale, pwmApplication.getConfig()); pass = false; if (cacheService != null && cacheKey != null) { final String jsonPayload = JsonUtil.serialize(e.getErrorInformation()); cacheService.put(cacheKey, cachePolicy, jsonPayload); } } } final PasswordCheckInfo.MATCH_STATUS matchStatus = figureMatchStatus(passwordIsCaseSensitive, password, confirmPassword); if (pass) { switch (matchStatus) { case EMPTY: userMessage = new ErrorInformation(PwmError.PASSWORD_MISSING_CONFIRM) .toUserStr(locale, pwmApplication.getConfig()); break; case MATCH: userMessage = new ErrorInformation(PwmError.PASSWORD_MEETS_RULES) .toUserStr(locale, pwmApplication.getConfig()); break; case NO_MATCH: userMessage = new ErrorInformation(PwmError.PASSWORD_DOESNOTMATCH) .toUserStr(locale, pwmApplication.getConfig()); break; default: userMessage = ""; } } final int strength = judgePasswordStrength(password == null ? null : password.getStringValue()); return new PasswordCheckInfo(userMessage, pass, strength, matchStatus, errorCode); }
@Override void doCommand() throws Exception { final PwmApplication pwmApplication = cliEnvironment.getPwmApplication(); final File inputFile = (File) cliEnvironment.getOptions().get(CliParameters.REQUIRED_EXISTING_INPUT_FILE.getName()); final BufferedReader reader = new BufferedReader( new InputStreamReader( new FileInputStream(inputFile), PwmConstants.DEFAULT_CHARSET.toString())); out("importing stored responses from " + inputFile.getAbsolutePath() + "...."); int counter = 0; String line; final long startTime = System.currentTimeMillis(); while ((line = reader.readLine()) != null) { counter++; final RestChallengesServer.JsonChallengesData inputData; inputData = JsonUtil.deserialize(line, RestChallengesServer.JsonChallengesData.class); final UserIdentity userIdentity = UserIdentity.fromDelimitedKey(inputData.username); final ChaiUser user = pwmApplication.getProxiedChaiUser(userIdentity); if (user.isValid()) { out("writing responses to user '" + user.getEntryDN() + "'"); try { final ChallengeProfile challengeProfile = pwmApplication .getCrService() .readUserChallengeProfile( null, userIdentity, user, PwmPasswordPolicy.defaultPolicy(), PwmConstants.DEFAULT_LOCALE); final ChallengeSet challengeSet = challengeProfile.getChallengeSet(); final String userGuid = LdapOperationsHelper.readLdapGuidValue(pwmApplication, null, userIdentity, false); final ResponseInfoBean responseInfoBean = inputData.toResponseInfoBean( PwmConstants.DEFAULT_LOCALE, challengeSet.getIdentifier()); pwmApplication.getCrService().writeResponses(user, userGuid, responseInfoBean); } catch (Exception e) { out( "error writing responses to user '" + user.getEntryDN() + "', error: " + e.getMessage()); return; } } else { out("user '" + user.getEntryDN() + "' is not a valid userDN"); return; } } out( "output complete, " + counter + " responses imported in " + TimeDuration.fromCurrent(startTime).asCompactString()); }
public String output() { return JsonUtil.serializeMap(valueMap); }
private void write(StorageKey key, UserCacheRecord cacheBean) throws LocalDBException { final String jsonValue = JsonUtil.serialize(cacheBean); localDB.put(DB, key.getKey(), jsonValue); }
public void init(PwmApplication pwmApplication) throws PwmException { for (final Statistic.EpsType type : Statistic.EpsType.values()) { for (final Statistic.EpsDuration duration : Statistic.EpsDuration.values()) { epsMeterMap.put( type.toString() + duration.toString(), new EventRateMeter(duration.getTimeDuration())); } } status = STATUS.OPENING; this.localDB = pwmApplication.getLocalDB(); this.pwmApplication = pwmApplication; if (localDB == null) { LOGGER.error("LocalDB is not available, will remain closed"); status = STATUS.CLOSED; return; } { final String storedCummulativeBundleStr = localDB.get(LocalDB.DB.PWM_STATS, DB_KEY_CUMULATIVE); if (storedCummulativeBundleStr != null && storedCummulativeBundleStr.length() > 0) { statsCummulative = StatisticsBundle.input(storedCummulativeBundleStr); } } { for (final Statistic.EpsType loopEpsType : Statistic.EpsType.values()) { for (final Statistic.EpsType loopEpsDuration : Statistic.EpsType.values()) { final String key = "EPS-" + loopEpsType.toString() + loopEpsDuration.toString(); final String storedValue = localDB.get(LocalDB.DB.PWM_STATS, key); if (storedValue != null && storedValue.length() > 0) { try { final EventRateMeter eventRateMeter = JsonUtil.deserialize(storedValue, EventRateMeter.class); epsMeterMap.put(loopEpsType.toString() + loopEpsDuration.toString(), eventRateMeter); } catch (Exception e) { LOGGER.error( "unexpected error reading last EPS rate for " + loopEpsType + " from LocalDB: " + e.getMessage()); } } } } } { final String storedInitialString = localDB.get(LocalDB.DB.PWM_STATS, DB_KEY_INITIAL_DAILY_KEY); if (storedInitialString != null && storedInitialString.length() > 0) { initialDailyKey = new DailyKey(storedInitialString); } } { currentDailyKey = new DailyKey(new Date()); final String storedDailyStr = localDB.get(LocalDB.DB.PWM_STATS, currentDailyKey.toString()); if (storedDailyStr != null && storedDailyStr.length() > 0) { statsDaily = StatisticsBundle.input(storedDailyStr); } } try { localDB.put( LocalDB.DB.PWM_STATS, DB_KEY_TEMP, PwmConstants.DEFAULT_DATETIME_FORMAT.format(new Date())); } catch (IllegalStateException e) { LOGGER.error("unable to write to localDB, will remain closed, error: " + e.getMessage()); status = STATUS.CLOSED; return; } localDB.put(LocalDB.DB.PWM_STATS, DB_KEY_VERSION, DB_VALUE_VERSION); localDB.put(LocalDB.DB.PWM_STATS, DB_KEY_INITIAL_DAILY_KEY, initialDailyKey.toString()); { // setup a timer to roll over at 0 Zula and one to write current stats every 10 seconds final String threadName = Helper.makeThreadName(pwmApplication, this.getClass()) + " timer"; daemonTimer = new Timer(threadName, true); daemonTimer.schedule(new FlushTask(), 10 * 1000, DB_WRITE_FREQUENCY_MS); daemonTimer.schedule(new NightlyTask(), Helper.nextZuluZeroTime()); } if (pwmApplication.getApplicationMode() == PwmApplication.MODE.RUNNING) { if (pwmApplication.getConfig().readSettingAsBoolean(PwmSetting.PUBLISH_STATS_ENABLE)) { long lastPublishTimestamp = pwmApplication.getInstallTime().getTime(); { final String lastPublishDateStr = localDB.get(LocalDB.DB.PWM_STATS, KEY_CLOUD_PUBLISH_TIMESTAMP); if (lastPublishDateStr != null && lastPublishDateStr.length() > 0) { try { lastPublishTimestamp = Long.parseLong(lastPublishDateStr); } catch (Exception e) { LOGGER.error( "unexpected error reading last publish timestamp from PwmDB: " + e.getMessage()); } } } final Date nextPublishTime = new Date( lastPublishTimestamp + PwmConstants.STATISTICS_PUBLISH_FREQUENCY_MS + (long) PwmRandom.getInstance().nextInt(3600 * 1000)); daemonTimer.schedule( new PublishTask(), nextPublishTime, PwmConstants.STATISTICS_PUBLISH_FREQUENCY_MS); } } status = STATUS.OPEN; }
private void publishStatisticsToCloud() throws URISyntaxException, IOException, PwmUnrecoverableException { final StatsPublishBean statsPublishData; { final StatisticsBundle bundle = getStatBundleForKey(KEY_CUMULATIVE); final Map<String, String> statData = new HashMap<>(); for (final Statistic loopStat : Statistic.values()) { statData.put(loopStat.getKey(), bundle.getStatistic(loopStat)); } final Configuration config = pwmApplication.getConfig(); final List<String> configuredSettings = new ArrayList<>(); for (final PwmSetting pwmSetting : config.nonDefaultSettings()) { if (!pwmSetting.getCategory().hasProfiles() && !config.isDefaultValue(pwmSetting)) { configuredSettings.add(pwmSetting.getKey()); } } final Map<String, String> otherData = new HashMap<>(); otherData.put( StatsPublishBean.KEYS.SITE_URL.toString(), config.readSettingAsString(PwmSetting.PWM_SITE_URL)); otherData.put( StatsPublishBean.KEYS.SITE_DESCRIPTION.toString(), config.readSettingAsString(PwmSetting.PUBLISH_STATS_SITE_DESCRIPTION)); otherData.put( StatsPublishBean.KEYS.INSTALL_DATE.toString(), PwmConstants.DEFAULT_DATETIME_FORMAT.format(pwmApplication.getInstallTime())); try { otherData.put( StatsPublishBean.KEYS.LDAP_VENDOR.toString(), pwmApplication .getProxyChaiProvider(config.getDefaultLdapProfile().getIdentifier()) .getDirectoryVendor() .toString()); } catch (Exception e) { LOGGER.trace("unable to read ldap vendor type for stats publication: " + e.getMessage()); } statsPublishData = new StatsPublishBean( pwmApplication.getInstanceID(), new Date(), statData, configuredSettings, PwmConstants.BUILD_NUMBER, PwmConstants.BUILD_VERSION, otherData); } final URI requestURI = new URI(PwmConstants.PWM_URL_CLOUD + "/rest/pwm/statistics"); final HttpPost httpPost = new HttpPost(requestURI.toString()); final String jsonDataString = JsonUtil.serialize(statsPublishData); httpPost.setEntity(new StringEntity(jsonDataString)); httpPost.setHeader("Accept", PwmConstants.AcceptValue.json.getHeaderValue()); httpPost.setHeader("Content-Type", PwmConstants.ContentTypeValue.json.getHeaderValue()); LOGGER.debug( "preparing to send anonymous statistics to " + requestURI.toString() + ", data to send: " + jsonDataString); final HttpResponse httpResponse = PwmHttpClient.getHttpClient(pwmApplication.getConfig()).execute(httpPost); if (httpResponse.getStatusLine().getStatusCode() != HttpStatus.SC_OK) { throw new IOException( "http response error code: " + httpResponse.getStatusLine().getStatusCode()); } LOGGER.info("published anonymous statistics to " + requestURI.toString()); try { localDB.put( LocalDB.DB.PWM_STATS, KEY_CLOUD_PUBLISH_TIMESTAMP, String.valueOf(System.currentTimeMillis())); } catch (LocalDBException e) { LOGGER.error( "unexpected error trying to save last statistics published time to LocalDB: " + e.getMessage()); } }
public List<HealthRecord> healthCheck() { if (status == PwmService.STATUS.CLOSED) { return Collections.emptyList(); } final List<HealthRecord> returnRecords = new ArrayList<>(); try { preOperationCheck(); } catch (DatabaseException e) { lastError = e.getErrorInformation(); returnRecords.add( new HealthRecord( HealthStatus.WARN, HealthTopic.Database, "Database server is not available: " + e.getErrorInformation().toDebugStr())); return returnRecords; } try { final Map<String, String> tempMap = new HashMap<>(); tempMap.put("instance", instanceID); tempMap.put("date", (new java.util.Date()).toString()); this.put( DatabaseTable.PWM_META, DatabaseAccessorImpl.KEY_TEST, JsonUtil.serializeMap(tempMap)); } catch (PwmException e) { returnRecords.add( new HealthRecord( HealthStatus.WARN, HealthTopic.Database, "Error writing to database: " + e.getErrorInformation().toDebugStr())); return returnRecords; } if (lastError != null) { final TimeDuration errorAge = TimeDuration.fromCurrent(lastError.getDate().getTime()); if (errorAge.isShorterThan(TimeDuration.HOUR)) { returnRecords.add( new HealthRecord( HealthStatus.CAUTION, HealthTopic.Database, "Database server was recently unavailable (" + errorAge.asLongString(PwmConstants.DEFAULT_LOCALE) + " ago at " + lastError.getDate().toString() + "): " + lastError.toDebugStr())); } } if (returnRecords.isEmpty()) { returnRecords.add( new HealthRecord( HealthStatus.GOOD, HealthTopic.Database, "Database connection to " + this.dbConfiguration.getConnectionString() + " okay")); } return returnRecords; }
private Connection openDB(final DBConfiguration dbConfiguration) throws DatabaseException { final String connectionURL = dbConfiguration.getConnectionString(); final String jdbcClassName = dbConfiguration.getDriverClassname(); try { final byte[] jdbcDriverBytes = dbConfiguration.getJdbcDriver(); if (jdbcDriverBytes != null) { LOGGER.debug("loading JDBC database driver stored in configuration"); final JarClassLoader jarClassLoader = new JarClassLoader(); jarClassLoader.add(new ByteArrayInputStream(jdbcDriverBytes)); final JclObjectFactory jclObjectFactory = JclObjectFactory.getInstance(); // Create object of loaded class driver = (Driver) jclObjectFactory.create(jarClassLoader, jdbcClassName); LOGGER.debug( "successfully loaded JDBC database driver '" + jdbcClassName + "' from application configuration"); } } catch (Throwable e) { final String errorMsg = "error registering JDBC database driver stored in configuration: " + e.getMessage(); final ErrorInformation errorInformation = new ErrorInformation(PwmError.ERROR_DB_UNAVAILABLE, errorMsg); LOGGER.error(errorMsg, e); throw new DatabaseException(errorInformation); } if (driver == null) { try { LOGGER.debug("loading JDBC database driver from classpath: " + jdbcClassName); driver = (Driver) Class.forName(jdbcClassName).newInstance(); LOGGER.debug("successfully loaded JDBC database driver from classpath: " + jdbcClassName); } catch (Throwable e) { final String errorMsg = e.getClass().getName() + " error loading JDBC database driver from classpath: " + e.getMessage(); final ErrorInformation errorInformation = new ErrorInformation(PwmError.ERROR_DB_UNAVAILABLE, errorMsg); throw new DatabaseException(errorInformation); } } try { LOGGER.debug("opening connection to database " + connectionURL); final Properties connectionProperties = new Properties(); if (dbConfiguration.getUsername() != null && !dbConfiguration.getUsername().isEmpty()) { connectionProperties.setProperty("user", dbConfiguration.getUsername()); } if (dbConfiguration.getPassword() != null) { connectionProperties.setProperty( "password", dbConfiguration.getPassword().getStringValue()); } final Connection connection = driver.connect(connectionURL, connectionProperties); final Map<PwmAboutProperty, String> debugProps = getConnectionDebugProperties(connection); ; LOGGER.debug( "successfully opened connection to database " + connectionURL + ", properties: " + JsonUtil.serializeMap(debugProps)); connection.setAutoCommit(true); return connection; } catch (Throwable e) { final String errorMsg = "error connecting to database: " + Helper.readHostileExceptionMessage(e); final ErrorInformation errorInformation = new ErrorInformation(PwmError.ERROR_DB_UNAVAILABLE, errorMsg); if (e instanceof IOException) { LOGGER.error(errorInformation); } else { LOGGER.error(errorMsg, e); } throw new DatabaseException(errorInformation); } }
private void postInitTasks() { final Date startTime = new Date(); LOGGER.debug("loaded configuration: \n" + configuration.toDebugString()); // detect if config has been modified since previous startup try { final String previousHash = readAppAttribute(AppAttribute.CONFIG_HASH); final String currentHash = configuration.configurationHash(); if (previousHash == null || !previousHash.equals(currentHash)) { writeAppAttribute(AppAttribute.CONFIG_HASH, currentHash); LOGGER.warn( "configuration checksum does not match previously seen checksum, configuration has been modified since last startup"); if (this.getAuditManager() != null) { final String modifyMessage = "configuration was modified directly (not using ConfigEditor UI)"; this.getAuditManager() .submit( SystemAuditRecord.create( AuditEvent.MODIFY_CONFIGURATION, modifyMessage, this.getInstanceID())); } } } catch (Exception e) { LOGGER.debug( "unable to detect if configuration has been modified since previous startup: " + e.getMessage()); } if (this.getConfig() != null) { final Map<AppProperty, String> nonDefaultProperties = getConfig().readAllNonDefaultAppProperties(); if (nonDefaultProperties != null && !nonDefaultProperties.isEmpty()) { final Map<String, String> tempMap = new LinkedHashMap<>(); for (final AppProperty loopProperty : nonDefaultProperties.keySet()) { tempMap.put(loopProperty.getKey(), nonDefaultProperties.get(loopProperty)); } LOGGER.trace( "non-default app properties read from configuration: " + JsonUtil.serializeMap(tempMap)); } else { LOGGER.trace("no non-default app properties in configuration"); } } // send system audit event final SystemAuditRecord auditRecord = SystemAuditRecord.create(AuditEvent.STARTUP, null, getInstanceID()); try { getAuditManager().submit(auditRecord); } catch (PwmException e) { LOGGER.warn("unable to submit alert event " + JsonUtil.serialize(auditRecord)); } try { Map<PwmAboutProperty, String> infoMap = Helper.makeInfoBean(this); LOGGER.trace("application info: " + JsonUtil.serializeMap(infoMap)); } catch (Exception e) { LOGGER.error("error generating about application bean: " + e.getMessage()); } try { this.getIntruderManager() .clear(RecordType.USERNAME, PwmConstants.CONFIGMANAGER_INTRUDER_USERNAME); } catch (Exception e) { LOGGER.debug( "error while clearing configmanager-intruder-username from intruder table: " + e.getMessage()); } LOGGER.trace( "completed post init tasks in " + TimeDuration.fromCurrent(startTime).asCompactString()); }
@Override public boolean put(final DatabaseTable table, final String key, final String value) throws DatabaseException { preOperationCheck(); if (traceLogging) { LOGGER.trace("attempting put operation for table=" + table + ", key=" + key); } if (!contains(table, key)) { final String sqlText = "INSERT INTO " + table.toString() + "(" + KEY_COLUMN + ", " + VALUE_COLUMN + ") VALUES(?,?)"; PreparedStatement statement = null; try { statement = connection.prepareStatement(sqlText); statement.setString(1, key); statement.setString(2, value); statement.executeUpdate(); } catch (SQLException e) { final ErrorInformation errorInformation = new ErrorInformation( PwmError.ERROR_DB_UNAVAILABLE, "put operation failed: " + e.getMessage()); lastError = errorInformation; throw new DatabaseException(errorInformation); } finally { close(statement); } return false; } final String sqlText = "UPDATE " + table.toString() + " SET " + VALUE_COLUMN + "=? WHERE " + KEY_COLUMN + "=?"; PreparedStatement statement = null; try { statement = connection.prepareStatement(sqlText); statement.setString(1, value); statement.setString(2, key); statement.executeUpdate(); } catch (SQLException e) { final ErrorInformation errorInformation = new ErrorInformation( PwmError.ERROR_DB_UNAVAILABLE, "put operation failed: " + e.getMessage()); lastError = errorInformation; throw new DatabaseException(errorInformation); } finally { close(statement); } if (traceLogging) { final Map<String, Object> debugOutput = new LinkedHashMap<>(); debugOutput.put("table", table); debugOutput.put("key", key); debugOutput.put("value", value); LOGGER.trace( "put operation result: " + JsonUtil.serializeMap(debugOutput, JsonUtil.Flag.PrettyPrint)); } updateStats(false, true); return true; }