Search in sources :

Example 61 with UserIdentity

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);
    }
}
Also used : PwmException(password.pwm.error.PwmException) ErrorInformation(password.pwm.error.ErrorInformation) ChaiUnavailableException(com.novell.ldapchai.exception.ChaiUnavailableException) ChaiUser(com.novell.ldapchai.ChaiUser) UserIdentity(password.pwm.bean.UserIdentity) ChaiOperationException(com.novell.ldapchai.exception.ChaiOperationException) PwmOperationalException(password.pwm.error.PwmOperationalException)

Example 62 with UserIdentity

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));
}
Also used : ErrorInformation(password.pwm.error.ErrorInformation) UserIdentity(password.pwm.bean.UserIdentity) Map(java.util.Map) LinkedHashMap(java.util.LinkedHashMap) TreeMap(java.util.TreeMap) DuplicateMode(password.pwm.config.option.DuplicateMode) PwmOperationalException(password.pwm.error.PwmOperationalException)

Example 63 with UserIdentity

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);
}
Also used : Instant(java.time.Instant) UserIdentity(password.pwm.bean.UserIdentity) ArrayList(java.util.ArrayList) PwmUnrecoverableException(password.pwm.error.PwmUnrecoverableException) LdapProfile(password.pwm.config.profile.LdapProfile) LinkedHashMap(java.util.LinkedHashMap) ErrorInformation(password.pwm.error.ErrorInformation) Map(java.util.Map) LinkedHashMap(java.util.LinkedHashMap) TreeMap(java.util.TreeMap)

Example 64 with UserIdentity

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));
}
Also used : ErrorInformation(password.pwm.error.ErrorInformation) ChaiProvider(com.novell.ldapchai.provider.ChaiProvider) ChaiUser(com.novell.ldapchai.ChaiUser) UserIdentity(password.pwm.bean.UserIdentity) ChaiOperationException(com.novell.ldapchai.exception.ChaiOperationException) LdapProfile(password.pwm.config.profile.LdapProfile) PwmOperationalException(password.pwm.error.PwmOperationalException)

Example 65 with UserIdentity

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;
}
Also used : ChaiUnavailableException(com.novell.ldapchai.exception.ChaiUnavailableException) Instant(java.time.Instant) UserIdentity(password.pwm.bean.UserIdentity) PwmUnrecoverableException(password.pwm.error.PwmUnrecoverableException) SearchHelper(com.novell.ldapchai.util.SearchHelper) PwmOperationalException(password.pwm.error.PwmOperationalException) LinkedHashMap(java.util.LinkedHashMap) ErrorInformation(password.pwm.error.ErrorInformation) TimeDuration(password.pwm.util.java.TimeDuration) ChaiOperationException(com.novell.ldapchai.exception.ChaiOperationException) Map(java.util.Map) LinkedHashMap(java.util.LinkedHashMap) TreeMap(java.util.TreeMap)

Aggregations

UserIdentity (password.pwm.bean.UserIdentity)101 ErrorInformation (password.pwm.error.ErrorInformation)62 PwmUnrecoverableException (password.pwm.error.PwmUnrecoverableException)48 PwmOperationalException (password.pwm.error.PwmOperationalException)45 ChaiUser (com.novell.ldapchai.ChaiUser)30 PwmApplication (password.pwm.PwmApplication)27 Map (java.util.Map)21 PwmSession (password.pwm.http.PwmSession)20 UserSearchEngine (password.pwm.ldap.search.UserSearchEngine)19 PwmException (password.pwm.error.PwmException)18 ChaiUnavailableException (com.novell.ldapchai.exception.ChaiUnavailableException)17 LinkedHashMap (java.util.LinkedHashMap)17 HelpdeskProfile (password.pwm.config.profile.HelpdeskProfile)17 ChaiOperationException (com.novell.ldapchai.exception.ChaiOperationException)16 Instant (java.time.Instant)16 FormConfiguration (password.pwm.config.value.data.FormConfiguration)16 SearchConfiguration (password.pwm.ldap.search.SearchConfiguration)16 ArrayList (java.util.ArrayList)15 UserInfo (password.pwm.ldap.UserInfo)15 RestResultBean (password.pwm.ws.server.RestResultBean)15