|
@@ -33,7 +33,6 @@ import password.pwm.AppProperty;
|
|
import password.pwm.PwmApplication;
|
|
import password.pwm.PwmApplication;
|
|
import password.pwm.PwmConstants;
|
|
import password.pwm.PwmConstants;
|
|
import password.pwm.bean.UserIdentity;
|
|
import password.pwm.bean.UserIdentity;
|
|
-import password.pwm.config.Configuration;
|
|
|
|
import password.pwm.config.PwmSetting;
|
|
import password.pwm.config.PwmSetting;
|
|
import password.pwm.config.value.data.FormConfiguration;
|
|
import password.pwm.config.value.data.FormConfiguration;
|
|
import password.pwm.error.ErrorInformation;
|
|
import password.pwm.error.ErrorInformation;
|
|
@@ -42,6 +41,7 @@ import password.pwm.error.PwmOperationalException;
|
|
import password.pwm.error.PwmUnrecoverableException;
|
|
import password.pwm.error.PwmUnrecoverableException;
|
|
import password.pwm.http.PwmRequest;
|
|
import password.pwm.http.PwmRequest;
|
|
import password.pwm.http.PwmURL;
|
|
import password.pwm.http.PwmURL;
|
|
|
|
+import password.pwm.http.servlet.helpdesk.HelpdeskServletUtil;
|
|
import password.pwm.i18n.Display;
|
|
import password.pwm.i18n.Display;
|
|
import password.pwm.ldap.LdapOperationsHelper;
|
|
import password.pwm.ldap.LdapOperationsHelper;
|
|
import password.pwm.ldap.LdapPermissionTester;
|
|
import password.pwm.ldap.LdapPermissionTester;
|
|
@@ -69,11 +69,11 @@ import java.io.Serializable;
|
|
import java.time.Instant;
|
|
import java.time.Instant;
|
|
import java.util.ArrayList;
|
|
import java.util.ArrayList;
|
|
import java.util.Collections;
|
|
import java.util.Collections;
|
|
-import java.util.HashSet;
|
|
|
|
import java.util.LinkedHashMap;
|
|
import java.util.LinkedHashMap;
|
|
import java.util.List;
|
|
import java.util.List;
|
|
import java.util.Locale;
|
|
import java.util.Locale;
|
|
import java.util.Map;
|
|
import java.util.Map;
|
|
|
|
+import java.util.Objects;
|
|
import java.util.Set;
|
|
import java.util.Set;
|
|
import java.util.TreeMap;
|
|
import java.util.TreeMap;
|
|
import java.util.concurrent.ArrayBlockingQueue;
|
|
import java.util.concurrent.ArrayBlockingQueue;
|
|
@@ -104,12 +104,11 @@ class PeopleSearchDataReader
|
|
}
|
|
}
|
|
|
|
|
|
SearchResultBean makeSearchResultBean(
|
|
SearchResultBean makeSearchResultBean(
|
|
- final String searchData,
|
|
|
|
- final boolean includeDisplayName
|
|
|
|
|
|
+ final SearchRequestBean searchRequestBean
|
|
)
|
|
)
|
|
throws PwmUnrecoverableException
|
|
throws PwmUnrecoverableException
|
|
{
|
|
{
|
|
- final CacheKey cacheKey = makeCacheKey( SearchResultBean.class.getSimpleName(), searchData + "|" + includeDisplayName );
|
|
|
|
|
|
+ final CacheKey cacheKey = makeCacheKey( SearchResultBean.class.getSimpleName(), JsonUtil.serialize( searchRequestBean ) );
|
|
|
|
|
|
{
|
|
{
|
|
// try to serve from cache first
|
|
// try to serve from cache first
|
|
@@ -127,12 +126,14 @@ class PeopleSearchDataReader
|
|
}
|
|
}
|
|
|
|
|
|
// if not in cache, build results from ldap
|
|
// if not in cache, build results from ldap
|
|
- final SearchResultBean searchResultBean = makeSearchResultsImpl( pwmRequest, searchData, includeDisplayName )
|
|
|
|
|
|
+ final SearchResultBean searchResultBean = makeSearchResultsImpl( searchRequestBean )
|
|
.toBuilder().fromCache( false ).build();
|
|
.toBuilder().fromCache( false ).build();
|
|
|
|
|
|
StatisticsManager.incrementStat( pwmRequest, Statistic.PEOPLESEARCH_SEARCHES );
|
|
StatisticsManager.incrementStat( pwmRequest, Statistic.PEOPLESEARCH_SEARCHES );
|
|
storeDataInCache( pwmRequest.getPwmApplication(), cacheKey, searchResultBean );
|
|
storeDataInCache( pwmRequest.getPwmApplication(), cacheKey, searchResultBean );
|
|
- LOGGER.trace( pwmRequest, "returning " + searchResultBean.getSearchResults().size() + " results for search request '" + searchData + "'" );
|
|
|
|
|
|
+ LOGGER.trace( pwmRequest, "returning " + searchResultBean.getSearchResults().size()
|
|
|
|
+ + " results for search request "
|
|
|
|
+ + JsonUtil.serialize( searchRequestBean ) );
|
|
return searchResultBean;
|
|
return searchResultBean;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -369,12 +370,6 @@ class PeopleSearchDataReader
|
|
keyString );
|
|
keyString );
|
|
}
|
|
}
|
|
|
|
|
|
- private static Set<String> getSearchAttributes( final Configuration configuration )
|
|
|
|
- {
|
|
|
|
- final List<String> searchResultForm = configuration.readSettingAsStringArray( PwmSetting.PEOPLE_SEARCH_SEARCH_ATTRIBUTES );
|
|
|
|
- return Collections.unmodifiableSet( new HashSet<>( searchResultForm ) );
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
private OrgChartReferenceBean makeOrgChartReferenceForIdentity(
|
|
private OrgChartReferenceBean makeOrgChartReferenceForIdentity(
|
|
final UserIdentity userIdentity
|
|
final UserIdentity userIdentity
|
|
)
|
|
)
|
|
@@ -553,7 +548,7 @@ class PeopleSearchDataReader
|
|
)
|
|
)
|
|
throws PwmUnrecoverableException
|
|
throws PwmUnrecoverableException
|
|
{
|
|
{
|
|
- final Set<String> searchAttributes = getSearchAttributes( pwmRequest.getConfig() );
|
|
|
|
|
|
+ final Set<String> searchAttributes = peopleSearchConfiguration.getSearchAttributes();
|
|
final Map<String, AttributeDetailBean> returnObj = new LinkedHashMap<>();
|
|
final Map<String, AttributeDetailBean> returnObj = new LinkedHashMap<>();
|
|
for ( final FormConfiguration formConfiguration : detailForm )
|
|
for ( final FormConfiguration formConfiguration : detailForm )
|
|
{
|
|
{
|
|
@@ -648,7 +643,7 @@ class PeopleSearchDataReader
|
|
final Instant startTime = Instant.now();
|
|
final Instant startTime = Instant.now();
|
|
final CacheLoader<Boolean> cacheLoader = () ->
|
|
final CacheLoader<Boolean> cacheLoader = () ->
|
|
{
|
|
{
|
|
- final String filterSetting = getSearchFilter( pwmRequest.getConfig() );
|
|
|
|
|
|
+ final String filterSetting = makeSimpleSearchFilter( );
|
|
String filterString = filterSetting.replace( PwmConstants.VALUE_REPLACEMENT_USERNAME, "*" );
|
|
String filterString = filterSetting.replace( PwmConstants.VALUE_REPLACEMENT_USERNAME, "*" );
|
|
while ( filterString.contains( "**" ) )
|
|
while ( filterString.contains( "**" ) )
|
|
{
|
|
{
|
|
@@ -674,16 +669,16 @@ class PeopleSearchDataReader
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- private static String getSearchFilter( final Configuration configuration )
|
|
|
|
|
|
+ private String makeSimpleSearchFilter()
|
|
{
|
|
{
|
|
- final String configuredFilter = configuration.readSettingAsString( PwmSetting.PEOPLE_SEARCH_SEARCH_FILTER );
|
|
|
|
|
|
+ final String configuredFilter = pwmRequest.getConfig().readSettingAsString( PwmSetting.PEOPLE_SEARCH_SEARCH_FILTER );
|
|
if ( configuredFilter != null && !configuredFilter.isEmpty() )
|
|
if ( configuredFilter != null && !configuredFilter.isEmpty() )
|
|
{
|
|
{
|
|
return configuredFilter;
|
|
return configuredFilter;
|
|
}
|
|
}
|
|
|
|
|
|
- final List<String> defaultObjectClasses = configuration.readSettingAsStringArray( PwmSetting.DEFAULT_OBJECT_CLASSES );
|
|
|
|
- final Set<String> searchAttributes = getSearchAttributes( configuration );
|
|
|
|
|
|
+ final List<String> defaultObjectClasses = pwmRequest.getConfig().readSettingAsStringArray( PwmSetting.DEFAULT_OBJECT_CLASSES );
|
|
|
|
+ final Set<String> searchAttributes = peopleSearchConfiguration.getSearchAttributes();
|
|
final StringBuilder filter = new StringBuilder();
|
|
final StringBuilder filter = new StringBuilder();
|
|
|
|
|
|
//open AND clause for objectclasses and attributes
|
|
//open AND clause for objectclasses and attributes
|
|
@@ -709,6 +704,14 @@ class PeopleSearchDataReader
|
|
return filter.toString();
|
|
return filter.toString();
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ private String makeAdvancedFilter( final Map<String, String> attributesInSearchRequest )
|
|
|
|
+ {
|
|
|
|
+ final List<String> defaultObjectClasses = pwmRequest.getConfig().readSettingAsStringArray( PwmSetting.DEFAULT_OBJECT_CLASSES );
|
|
|
|
+ final List<FormConfiguration> searchAttributes = peopleSearchConfiguration.getSearchForm();
|
|
|
|
+
|
|
|
|
+ return HelpdeskServletUtil.makeAdvancedSearchFilter( defaultObjectClasses, searchAttributes, attributesInSearchRequest );
|
|
|
|
+ }
|
|
|
|
+
|
|
private boolean useProxy( )
|
|
private boolean useProxy( )
|
|
{
|
|
{
|
|
|
|
|
|
@@ -772,48 +775,85 @@ class PeopleSearchDataReader
|
|
}
|
|
}
|
|
|
|
|
|
private SearchResultBean makeSearchResultsImpl(
|
|
private SearchResultBean makeSearchResultsImpl(
|
|
- final PwmRequest pwmRequest,
|
|
|
|
- final String username,
|
|
|
|
- final boolean includeDisplayName
|
|
|
|
|
|
+ final SearchRequestBean searchRequest
|
|
)
|
|
)
|
|
throws PwmUnrecoverableException
|
|
throws PwmUnrecoverableException
|
|
{
|
|
{
|
|
- final Instant startTime = Instant.now();
|
|
|
|
|
|
+ Objects.requireNonNull( searchRequest );
|
|
|
|
|
|
- if ( username == null || username.length() < 1 )
|
|
|
|
- {
|
|
|
|
- return SearchResultBean.builder().searchResults( Collections.emptyList() ).build();
|
|
|
|
- }
|
|
|
|
|
|
+ final Instant startTime = Instant.now();
|
|
|
|
|
|
- final boolean useProxy = useProxy();
|
|
|
|
- final UserSearchEngine userSearchEngine = pwmRequest.getPwmApplication().getUserSearchEngine();
|
|
|
|
|
|
+ final SearchRequestBean.SearchMode searchMode = searchRequest.getMode() == null
|
|
|
|
+ ? SearchRequestBean.SearchMode.simple
|
|
|
|
+ : searchRequest.getMode();
|
|
|
|
|
|
final SearchConfiguration searchConfiguration;
|
|
final SearchConfiguration searchConfiguration;
|
|
{
|
|
{
|
|
final SearchConfiguration.SearchConfigurationBuilder builder = SearchConfiguration.builder();
|
|
final SearchConfiguration.SearchConfigurationBuilder builder = SearchConfiguration.builder();
|
|
builder.contexts( pwmRequest.getConfig().readSettingAsStringArray( PwmSetting.PEOPLE_SEARCH_SEARCH_BASE ) );
|
|
builder.contexts( pwmRequest.getConfig().readSettingAsStringArray( PwmSetting.PEOPLE_SEARCH_SEARCH_BASE ) );
|
|
builder.enableContextValidation( false );
|
|
builder.enableContextValidation( false );
|
|
- builder.username( username );
|
|
|
|
builder.enableValueEscaping( false );
|
|
builder.enableValueEscaping( false );
|
|
- builder.filter( getSearchFilter( pwmRequest.getConfig() ) );
|
|
|
|
builder.enableSplitWhitespace( true );
|
|
builder.enableSplitWhitespace( true );
|
|
|
|
|
|
- if ( !useProxy )
|
|
|
|
|
|
+ if ( !useProxy() )
|
|
{
|
|
{
|
|
builder.ldapProfile( pwmRequest.getPwmSession().getUserInfo().getUserIdentity().getLdapProfileID() );
|
|
builder.ldapProfile( pwmRequest.getPwmSession().getUserInfo().getUserIdentity().getLdapProfileID() );
|
|
builder.chaiProvider( pwmRequest.getPwmSession().getSessionManager().getChaiProvider() );
|
|
builder.chaiProvider( pwmRequest.getPwmSession().getSessionManager().getChaiProvider() );
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ switch ( searchMode )
|
|
|
|
+ {
|
|
|
|
+ case simple:
|
|
|
|
+ {
|
|
|
|
+ if ( StringUtil.isEmpty( searchRequest.getUsername() ) )
|
|
|
|
+ {
|
|
|
|
+ return SearchResultBean.builder().searchResults( Collections.emptyList() ).build();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ builder.filter( makeSimpleSearchFilter() );
|
|
|
|
+ builder.username( searchRequest.getUsername() );
|
|
|
|
+ }
|
|
|
|
+ break;
|
|
|
|
+
|
|
|
|
+ case advanced:
|
|
|
|
+ {
|
|
|
|
+ if ( JavaHelper.isEmpty( searchRequest.nonEmptySearchValues() ) )
|
|
|
|
+ {
|
|
|
|
+ return SearchResultBean.builder().searchResults( Collections.emptyList() ).build();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ final Map<FormConfiguration, String> formValues = new LinkedHashMap<>();
|
|
|
|
+ final Map<String, String> requestSearchValues = SearchRequestBean.searchValueToMap( searchRequest.getSearchValues() );
|
|
|
|
+ for ( final FormConfiguration formConfiguration : peopleSearchConfiguration.getSearchForm() )
|
|
|
|
+ {
|
|
|
|
+ final String attribute = formConfiguration.getName();
|
|
|
|
+ final String value = requestSearchValues.get( attribute );
|
|
|
|
+ if ( !StringUtil.isEmpty( value ) )
|
|
|
|
+ {
|
|
|
|
+ formValues.put( formConfiguration, value );
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ builder.filter( makeAdvancedFilter( requestSearchValues ) );
|
|
|
|
+ builder.formValues( formValues );
|
|
|
|
+ }
|
|
|
|
+ break;
|
|
|
|
+
|
|
|
|
+ default:
|
|
|
|
+ JavaHelper.unhandledSwitchStatement( searchMode );
|
|
|
|
+ }
|
|
|
|
+
|
|
searchConfiguration = builder.build();
|
|
searchConfiguration = builder.build();
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ final UserSearchEngine userSearchEngine = pwmRequest.getPwmApplication().getUserSearchEngine();
|
|
|
|
+
|
|
final UserSearchResults results;
|
|
final UserSearchResults results;
|
|
final boolean sizeExceeded;
|
|
final boolean sizeExceeded;
|
|
try
|
|
try
|
|
{
|
|
{
|
|
- final List<FormConfiguration> searchForm = pwmRequest.getConfig().readSettingAsForm(
|
|
|
|
- PwmSetting.PEOPLE_SEARCH_RESULT_FORM );
|
|
|
|
- final int maxResults = ( int ) pwmRequest.getConfig().readSettingAsLong(
|
|
|
|
- PwmSetting.PEOPLE_SEARCH_RESULT_LIMIT );
|
|
|
|
|
|
+ final List<FormConfiguration> searchForm = peopleSearchConfiguration.getResultForm();
|
|
|
|
+ final int maxResults = peopleSearchConfiguration.getResultLimit();
|
|
final Locale locale = pwmRequest.getLocale();
|
|
final Locale locale = pwmRequest.getLocale();
|
|
results = userSearchEngine.performMultiUserSearchFromForm( locale, searchConfiguration, maxResults, searchForm, pwmRequest.getSessionLabel() );
|
|
results = userSearchEngine.performMultiUserSearchFromForm( locale, searchConfiguration, maxResults, searchForm, pwmRequest.getSessionLabel() );
|
|
sizeExceeded = results.isSizeExceeded();
|
|
sizeExceeded = results.isSizeExceeded();
|
|
@@ -826,7 +866,7 @@ class PeopleSearchDataReader
|
|
}
|
|
}
|
|
|
|
|
|
final List<Map<String, Object>> resultOutput = new ArrayList<>( results.resultsAsJsonOutput( pwmRequest.getPwmApplication(), null ) );
|
|
final List<Map<String, Object>> resultOutput = new ArrayList<>( results.resultsAsJsonOutput( pwmRequest.getPwmApplication(), null ) );
|
|
- if ( includeDisplayName )
|
|
|
|
|
|
+ if ( searchRequest.isIncludeDisplayName() )
|
|
{
|
|
{
|
|
for ( final Map<String, Object> map : resultOutput )
|
|
for ( final Map<String, Object> map : resultOutput )
|
|
{
|
|
{
|