KEYCLOAK-13163 Fixed searching for user with fine-grained permissions
This commit is contained in:
parent
8cfd4d60e6
commit
99aba33980
7 changed files with 48 additions and 18 deletions
|
@ -336,19 +336,7 @@ public class LDAPStorageProvider implements UserStorageProvider,
|
|||
@Override
|
||||
public List<UserModel> searchForUser(String search, RealmModel realm, int firstResult, int maxResults) {
|
||||
Map<String, String> attributes = new HashMap<String, String>();
|
||||
int spaceIndex = search.lastIndexOf(' ');
|
||||
if (spaceIndex > -1) {
|
||||
String firstName = search.substring(0, spaceIndex).trim();
|
||||
String lastName = search.substring(spaceIndex).trim();
|
||||
attributes.put(UserModel.FIRST_NAME, firstName);
|
||||
attributes.put(UserModel.LAST_NAME, lastName);
|
||||
} else if (search.indexOf('@') > -1) {
|
||||
attributes.put(UserModel.USERNAME, search.trim().toLowerCase());
|
||||
attributes.put(UserModel.EMAIL, search.trim().toLowerCase());
|
||||
} else {
|
||||
attributes.put(UserModel.LAST_NAME, search.trim());
|
||||
attributes.put(UserModel.USERNAME, search.trim().toLowerCase());
|
||||
}
|
||||
attributes.put(UserModel.SEARCH,search);
|
||||
return searchForUser(attributes, realm, firstResult, maxResults);
|
||||
}
|
||||
|
||||
|
@ -359,6 +347,23 @@ public class LDAPStorageProvider implements UserStorageProvider,
|
|||
|
||||
@Override
|
||||
public List<UserModel> searchForUser(Map<String, String> params, RealmModel realm, int firstResult, int maxResults) {
|
||||
String search = params.get(UserModel.SEARCH);
|
||||
if(search!=null) {
|
||||
int spaceIndex = search.lastIndexOf(' ');
|
||||
if (spaceIndex > -1) {
|
||||
String firstName = search.substring(0, spaceIndex).trim();
|
||||
String lastName = search.substring(spaceIndex).trim();
|
||||
params.put(UserModel.FIRST_NAME, firstName);
|
||||
params.put(UserModel.LAST_NAME, lastName);
|
||||
} else if (search.indexOf('@') > -1) {
|
||||
params.put(UserModel.USERNAME, search.trim().toLowerCase());
|
||||
params.put(UserModel.EMAIL, search.trim().toLowerCase());
|
||||
} else {
|
||||
params.put(UserModel.LAST_NAME, search.trim());
|
||||
params.put(UserModel.USERNAME, search.trim().toLowerCase());
|
||||
}
|
||||
}
|
||||
|
||||
List<UserModel> searchResults =new LinkedList<UserModel>();
|
||||
|
||||
List<LDAPObject> ldapUsers = searchLDAP(realm, params, maxResults + firstResult);
|
||||
|
|
|
@ -849,6 +849,21 @@ public class JpaUserProvider implements UserProvider, UserCredentialStore {
|
|||
}
|
||||
|
||||
switch (key) {
|
||||
case UserModel.SEARCH:
|
||||
List<Predicate> orPredicates = new ArrayList();
|
||||
|
||||
orPredicates.add(builder.like(builder.lower(root.get(UserModel.USERNAME)), "%" + value.toLowerCase() + "%"));
|
||||
orPredicates.add(builder.like(builder.lower(root.get(UserModel.EMAIL)), "%" + value.toLowerCase() + "%"));
|
||||
orPredicates.add(builder.like(
|
||||
builder.lower(builder.concat(builder.concat(
|
||||
builder.coalesce(root.get(UserModel.FIRST_NAME), builder.literal("")), " "),
|
||||
builder.coalesce(root.get(UserModel.LAST_NAME), builder.literal("")))),
|
||||
"%" + value.toLowerCase() + "%"));
|
||||
|
||||
predicates.add(builder.or(orPredicates.toArray(new Predicate[orPredicates.size()])));
|
||||
|
||||
break;
|
||||
|
||||
case UserModel.USERNAME:
|
||||
case UserModel.FIRST_NAME:
|
||||
case UserModel.LAST_NAME:
|
||||
|
|
|
@ -37,6 +37,7 @@ public interface UserModel extends RoleMapperModel {
|
|||
String LOCALE = "locale";
|
||||
String INCLUDE_SERVICE_ACCOUNT = "keycloak.session.realm.users.query.include_service_account";
|
||||
String GROUPS = "keycloak.session.realm.users.query.groups";
|
||||
String SEARCH = "keycloak.session.realm.users.query.search";
|
||||
|
||||
interface UserRemovedEvent extends ProviderEvent {
|
||||
RealmModel getRealm();
|
||||
|
|
|
@ -214,7 +214,9 @@ public class UsersResource {
|
|||
userModels = Arrays.asList(userModel);
|
||||
}
|
||||
} else {
|
||||
userModels = session.users().searchForUser(search.trim(), realm, firstResult, maxResults);
|
||||
Map<String, String> attributes = new HashMap<>();
|
||||
attributes.put(UserModel.SEARCH, search.trim());
|
||||
return searchForUser(attributes, realm, userPermissionEvaluator, briefRepresentation, firstResult, maxResults, false);
|
||||
}
|
||||
} else if (last != null || first != null || email != null || username != null) {
|
||||
Map<String, String> attributes = new HashMap<>();
|
||||
|
|
|
@ -345,6 +345,7 @@ public class UserMapStorage implements UserLookupProvider, UserStorageProvider,
|
|||
|
||||
switch (key) {
|
||||
case UserModel.USERNAME:
|
||||
case UserModel.SEARCH:
|
||||
userStream = userStream.filter(s -> s.toLowerCase().contains(value.toLowerCase()));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,6 +37,7 @@ import java.util.Collections;
|
|||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
|
@ -191,9 +192,10 @@ public class UserPropertyFileStorage implements UserLookupProvider, UserStorageP
|
|||
|
||||
@Override
|
||||
public List<UserModel> searchForUser(Map<String, String> attributes, RealmModel realm, int firstResult, int maxResults) {
|
||||
String username = attributes.get(UserModel.USERNAME);
|
||||
if (username == null) return Collections.EMPTY_LIST;
|
||||
return searchForUser(username, realm, firstResult, maxResults);
|
||||
String search = Optional.ofNullable(attributes.get(UserModel.USERNAME))
|
||||
.orElseGet(()-> attributes.get(UserModel.SEARCH));
|
||||
if (search == null) return Collections.EMPTY_LIST;
|
||||
return searchForUser(search, realm, firstResult, maxResults);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -894,7 +894,6 @@ public class FineGrainAdminUnitTest extends AbstractKeycloakTest {
|
|||
GroupModel customerAGroup = session.realms().createGroup(realm, "Customer A");
|
||||
UserModel customerAManager = session.users().addUser(realm, "customer-a-manager");
|
||||
session.userCredentialManager().updateCredential(realm, customerAManager, UserCredentialModel.password("password"));
|
||||
customerAManager.joinGroup(customerAGroup);
|
||||
ClientModel realmAdminClient = realm.getClientByClientId(Constants.REALM_MANAGEMENT_CLIENT_ID);
|
||||
customerAManager.grantRole(realmAdminClient.getRole(AdminRoles.QUERY_USERS));
|
||||
customerAManager.setEnabled(true);
|
||||
|
@ -969,6 +968,11 @@ public class FineGrainAdminUnitTest extends AbstractKeycloakTest {
|
|||
Assert.assertEquals(20, result.size());
|
||||
Assert.assertThat(result, Matchers.everyItem(Matchers.hasProperty("username", Matchers.startsWith("b"))));
|
||||
|
||||
result = client.realm("test").users().search("test", -1, 20, false);
|
||||
|
||||
Assert.assertEquals(20, result.size());
|
||||
Assert.assertThat(result, Matchers.everyItem(Matchers.hasProperty("username", Matchers.startsWith("b"))));
|
||||
|
||||
result = client.realm("test").users().search("a", -1, 20, false);
|
||||
|
||||
Assert.assertEquals(0, result.size());
|
||||
|
|
Loading…
Reference in a new issue