use of password.pwm.bean.UserIdentity in project pwm by pwm-project.
the class UserSearchEngine method resolveUsername.
public UserIdentity resolveUsername(final String username, final String context, final String profile, final SessionLabel sessionLabel) throws PwmUnrecoverableException, PwmOperationalException {
// check if username is a key
{
UserIdentity inputIdentity = null;
try {
inputIdentity = UserIdentity.fromKey(username, pwmApplication);
} catch (PwmException e) {
/* input is not a userIdentity */
}
if (inputIdentity != null) {
try {
final ChaiUser theUser = pwmApplication.getProxiedChaiUser(inputIdentity);
if (theUser.exists()) {
final String canonicalDN;
canonicalDN = theUser.readCanonicalDN();
return new UserIdentity(canonicalDN, inputIdentity.getLdapProfileID());
}
} catch (ChaiOperationException e) {
throw new PwmOperationalException(new ErrorInformation(PwmError.ERROR_CANT_MATCH_USER, e.getMessage()));
} catch (ChaiUnavailableException e) {
throw PwmUnrecoverableException.fromChaiException(e);
}
}
}
try {
// see if we need to do a contextless search.
if (checkIfStringIsDN(username, sessionLabel)) {
return resolveUserDN(username);
} else {
final SearchConfiguration.SearchConfigurationBuilder builder = SearchConfiguration.builder();
builder.username(username);
if (context != null) {
builder.contexts(Collections.singletonList(context));
}
if (profile != null) {
builder.ldapProfile(profile);
}
final SearchConfiguration searchConfiguration = builder.build();
return performSingleUserSearch(searchConfiguration, sessionLabel);
}
} catch (PwmOperationalException e) {
throw new PwmOperationalException(new ErrorInformation(PwmError.ERROR_CANT_MATCH_USER, e.getErrorInformation().getDetailedErrorMsg(), e.getErrorInformation().getFieldValues()));
} catch (ChaiUnavailableException e) {
throw PwmUnrecoverableException.fromChaiException(e);
}
}
use of password.pwm.bean.UserIdentity in project pwm by pwm-project.
the class UserSearchEngine method performSingleUserSearch.
public UserIdentity performSingleUserSearch(final SearchConfiguration searchConfiguration, final SessionLabel sessionLabel) throws PwmUnrecoverableException, PwmOperationalException {
final long startTime = System.currentTimeMillis();
final DuplicateMode dupeMode = pwmApplication.getConfig().readSettingAsEnum(PwmSetting.LDAP_DUPLICATE_MODE, DuplicateMode.class);
final int searchCount = (dupeMode == DuplicateMode.FIRST_ALL) ? 1 : 2;
final Map<UserIdentity, Map<String, String>> searchResults = performMultiUserSearch(searchConfiguration, searchCount, Collections.emptyList(), sessionLabel);
final List<UserIdentity> results = searchResults == null ? Collections.emptyList() : new ArrayList<>(searchResults.keySet());
if (results.isEmpty()) {
final String errorMessage;
if (searchConfiguration.getUsername() != null && searchConfiguration.getUsername().length() > 0) {
errorMessage = "an ldap user for username value '" + searchConfiguration.getUsername() + "' was not found";
} else {
errorMessage = "an ldap user was not found";
}
throw new PwmOperationalException(new ErrorInformation(PwmError.ERROR_CANT_MATCH_USER, errorMessage));
} else if (results.size() == 1) {
final String userDN = results.get(0).getUserDN();
LOGGER.debug(sessionLabel, "found userDN: " + userDN + " (" + TimeDuration.fromCurrent(startTime).asCompactString() + ")");
return results.get(0);
}
if (dupeMode == DuplicateMode.FIRST_PROFILE) {
final String profile1 = results.get(0).getLdapProfileID();
final String profile2 = results.get(1).getLdapProfileID();
final boolean sameProfile = (profile1 == null && profile2 == null) || (profile1 != null && profile1.equals(profile2));
if (sameProfile) {
final String errorMessage = "multiple user matches in single profile";
throw new PwmOperationalException(new ErrorInformation(PwmError.ERROR_CANT_MATCH_USER, errorMessage));
}
LOGGER.trace(sessionLabel, "found multiple matches, but will use first match since second match" + " is in a different profile and dupeMode is set to " + DuplicateMode.FIRST_PROFILE);
return results.get(0);
}
final String errorMessage = "multiple user matches found";
throw new PwmOperationalException(new ErrorInformation(PwmError.ERROR_CANT_MATCH_USER, errorMessage));
}
use of password.pwm.bean.UserIdentity in project pwm by pwm-project.
the class UserSearchEngine method performMultiUserSearch.
public Map<UserIdentity, Map<String, String>> performMultiUserSearch(final SearchConfiguration searchConfiguration, final int maxResults, final Collection<String> returnAttributes, final SessionLabel sessionLabel) throws PwmUnrecoverableException, PwmOperationalException {
final Collection<LdapProfile> ldapProfiles;
if (searchConfiguration.getLdapProfile() != null && !searchConfiguration.getLdapProfile().isEmpty()) {
if (pwmApplication.getConfig().getLdapProfiles().containsKey(searchConfiguration.getLdapProfile())) {
ldapProfiles = Collections.singletonList(pwmApplication.getConfig().getLdapProfiles().get(searchConfiguration.getLdapProfile()));
} else {
LOGGER.debug(sessionLabel, "attempt to search for users in unknown ldap profile '" + searchConfiguration.getLdapProfile() + "', skipping search");
return Collections.emptyMap();
}
} else {
ldapProfiles = pwmApplication.getConfig().getLdapProfiles().values();
}
final boolean ignoreUnreachableProfiles = pwmApplication.getConfig().readSettingAsBoolean(PwmSetting.LDAP_IGNORE_UNREACHABLE_PROFILES);
final List<String> errors = new ArrayList<>();
final long profileRetryDelayMS = Long.parseLong(pwmApplication.getConfig().readAppProperty(AppProperty.LDAP_PROFILE_RETRY_DELAY));
final List<UserSearchJob> searchJobs = new ArrayList<>();
for (final LdapProfile ldapProfile : ldapProfiles) {
boolean skipProfile = false;
final Instant lastLdapFailure = pwmApplication.getLdapConnectionService().getLastLdapFailureTime(ldapProfile);
if (ldapProfiles.size() > 1 && lastLdapFailure != null && TimeDuration.fromCurrent(lastLdapFailure).isShorterThan(profileRetryDelayMS)) {
LOGGER.info("skipping user search on ldap profile " + ldapProfile.getIdentifier() + " due to recent unreachable status (" + TimeDuration.fromCurrent(lastLdapFailure).asCompactString() + ")");
skipProfile = true;
}
if (!skipProfile) {
try {
searchJobs.addAll(this.makeSearchJobs(ldapProfile, searchConfiguration, maxResults, returnAttributes));
} catch (PwmUnrecoverableException e) {
if (e.getError() == PwmError.ERROR_DIRECTORY_UNAVAILABLE) {
pwmApplication.getLdapConnectionService().setLastLdapFailure(ldapProfile, e.getErrorInformation());
if (ignoreUnreachableProfiles) {
errors.add(e.getErrorInformation().getDetailedErrorMsg());
if (errors.size() >= ldapProfiles.size()) {
final String errorMsg = "all ldap profiles are unreachable; errors: " + JsonUtil.serializeCollection(errors);
throw new PwmUnrecoverableException(new ErrorInformation(PwmError.ERROR_DIRECTORY_UNAVAILABLE, errorMsg));
}
}
} else {
throw e;
}
}
}
}
final Map<UserIdentity, Map<String, String>> resultsMap = new LinkedHashMap<>(executeSearchJobs(searchJobs, sessionLabel, searchCounter.getAndIncrement()));
final Map<UserIdentity, Map<String, String>> returnMap = trimOrderedMap(resultsMap, maxResults);
return Collections.unmodifiableMap(returnMap);
}
use of password.pwm.bean.UserIdentity in project pwm by pwm-project.
the class UserSearchEngine method resolveUserDN.
private UserIdentity resolveUserDN(final String userDN) throws PwmUnrecoverableException, ChaiUnavailableException, PwmOperationalException {
final Collection<LdapProfile> ldapProfiles = pwmApplication.getConfig().getLdapProfiles().values();
for (final LdapProfile ldapProfile : ldapProfiles) {
final ChaiProvider provider = pwmApplication.getProxyChaiProvider(ldapProfile.getIdentifier());
final ChaiUser user = provider.getEntryFactory().newChaiUser(userDN);
if (user.exists()) {
try {
return new UserIdentity(user.readCanonicalDN(), ldapProfile.getIdentifier());
} catch (ChaiOperationException e) {
LOGGER.error("unexpected error reading canonical userDN for '" + userDN + "', error: " + e.getMessage());
}
}
}
throw new PwmOperationalException(new ErrorInformation(PwmError.ERROR_CANT_MATCH_USER));
}
use of password.pwm.bean.UserIdentity in project pwm by pwm-project.
the class UserSearchEngine method executeSearch.
private Map<UserIdentity, Map<String, String>> executeSearch(final UserSearchJob userSearchJob, final SessionLabel sessionLabel, final int searchID, final int jobID) throws PwmOperationalException, PwmUnrecoverableException {
debugOutputTask.conditionallyExecuteTask();
final SearchHelper searchHelper = new SearchHelper();
searchHelper.setMaxResults(userSearchJob.getMaxResults());
searchHelper.setFilter(userSearchJob.getSearchFilter());
searchHelper.setAttributes(userSearchJob.getReturnAttributes());
searchHelper.setTimeLimit((int) userSearchJob.getTimeoutMs());
final String debugInfo;
{
final Map<String, String> props = new LinkedHashMap<>();
props.put("profile", userSearchJob.getLdapProfile().getIdentifier());
props.put("base", userSearchJob.getContext());
props.put("maxCount", String.valueOf(searchHelper.getMaxResults()));
debugInfo = "[" + StringUtil.mapToString(props) + "]";
}
log(PwmLogLevel.TRACE, sessionLabel, searchID, jobID, "performing ldap search for user; " + debugInfo);
final Instant startTime = Instant.now();
final Map<String, Map<String, String>> results;
try {
results = userSearchJob.getChaiProvider().search(userSearchJob.getContext(), searchHelper);
} catch (ChaiUnavailableException e) {
throw new PwmUnrecoverableException(new ErrorInformation(PwmError.ERROR_DIRECTORY_UNAVAILABLE, e.getMessage()));
} catch (ChaiOperationException e) {
throw new PwmOperationalException(PwmError.forChaiError(e.getErrorCode()), "ldap error during searchID=" + searchID + ", error=" + e.getMessage());
}
final TimeDuration searchDuration = TimeDuration.fromCurrent(startTime);
if (pwmApplication.getStatisticsManager() != null && pwmApplication.getStatisticsManager().status() == PwmService.STATUS.OPEN) {
pwmApplication.getStatisticsManager().updateAverageValue(Statistic.AVG_LDAP_SEARCH_TIME, searchDuration.getTotalMilliseconds());
}
if (results.isEmpty()) {
log(PwmLogLevel.TRACE, sessionLabel, searchID, jobID, "no matches from search (" + searchDuration.asCompactString() + "); " + debugInfo);
return Collections.emptyMap();
}
log(PwmLogLevel.TRACE, sessionLabel, searchID, jobID, "found " + results.size() + " results in " + searchDuration.asCompactString() + "; " + debugInfo);
final Map<UserIdentity, Map<String, String>> returnMap = new LinkedHashMap<>();
for (final Map.Entry<String, Map<String, String>> entry : results.entrySet()) {
final String userDN = entry.getKey();
final Map<String, String> attributeMap = entry.getValue();
final UserIdentity userIdentity = new UserIdentity(userDN, userSearchJob.getLdapProfile().getIdentifier());
returnMap.put(userIdentity, attributeMap);
}
return returnMap;
}
Aggregations