KEYCLOAK-1697 Fix UserProvider.searchForUsersByAttribute
This commit is contained in:
parent
493fd0ad6a
commit
89660d06e5
8 changed files with 34 additions and 55 deletions
|
@ -314,8 +314,8 @@ public class UserFederationManager implements UserProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<UserModel> searchForUserByUserAttributes(Map<String, String> attributes, RealmModel realm) {
|
public List<UserModel> searchForUserByUserAttribute(String attrName, String attrValue, RealmModel realm) {
|
||||||
return session.userStorage().searchForUserByUserAttributes(attributes, realm);
|
return session.userStorage().searchForUserByUserAttribute(attrName, attrValue, realm);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -37,7 +37,7 @@ public interface UserProvider extends Provider {
|
||||||
List<UserModel> searchForUserByAttributes(Map<String, String> attributes, RealmModel realm, int firstResult, int maxResults);
|
List<UserModel> searchForUserByAttributes(Map<String, String> attributes, RealmModel realm, int firstResult, int maxResults);
|
||||||
|
|
||||||
// Searching by UserModel.attribute (not property)
|
// Searching by UserModel.attribute (not property)
|
||||||
List<UserModel> searchForUserByUserAttributes(Map<String, String> attributes, RealmModel realm);
|
List<UserModel> searchForUserByUserAttribute(String attrName, String attrValue, RealmModel realm);
|
||||||
|
|
||||||
Set<FederatedIdentityModel> getFederatedIdentities(UserModel user, RealmModel realm);
|
Set<FederatedIdentityModel> getFederatedIdentities(UserModel user, RealmModel realm);
|
||||||
FederatedIdentityModel getFederatedIdentity(UserModel user, String socialProvider, RealmModel realm);
|
FederatedIdentityModel getFederatedIdentity(UserModel user, String socialProvider, RealmModel realm);
|
||||||
|
|
|
@ -255,22 +255,18 @@ public class FileUserProvider implements UserProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<UserModel> searchForUserByUserAttributes(Map<String, String> attributes, RealmModel realm) {
|
public List<UserModel> searchForUserByUserAttribute(String attrName, String attrValue, RealmModel realm) {
|
||||||
Collection<UserModel> users = inMemoryModel.getUsers(realm.getId());
|
Collection<UserModel> users = inMemoryModel.getUsers(realm.getId());
|
||||||
|
|
||||||
for (Map.Entry<String, String> entry : attributes.entrySet()) {
|
List<UserModel> matchedUsers = new ArrayList<>();
|
||||||
|
for (UserModel user : users) {
|
||||||
List<UserModel> matchedUsers = new ArrayList<>();
|
List<String> vals = user.getAttribute(attrName);
|
||||||
for (UserModel user : users) {
|
if (vals.contains(attrValue)) {
|
||||||
List<String> vals = user.getAttribute(entry.getKey());
|
matchedUsers.add(user);
|
||||||
if (vals.contains(entry.getValue())) {
|
|
||||||
matchedUsers.add(user);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
users = matchedUsers;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return (List<UserModel>) users;
|
return matchedUsers;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -235,8 +235,8 @@ public class DefaultCacheUserProvider implements CacheUserProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<UserModel> searchForUserByUserAttributes(Map<String, String> attributes, RealmModel realm) {
|
public List<UserModel> searchForUserByUserAttribute(String attrName, String attrValue, RealmModel realm) {
|
||||||
return getDelegate().searchForUserByUserAttributes(attributes, realm);
|
return getDelegate().searchForUserByUserAttribute(attrName, attrValue, realm);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -13,6 +13,7 @@ import org.keycloak.models.UserFederationProviderModel;
|
||||||
import org.keycloak.models.UserModel;
|
import org.keycloak.models.UserModel;
|
||||||
import org.keycloak.models.UserProvider;
|
import org.keycloak.models.UserProvider;
|
||||||
import org.keycloak.models.jpa.entities.FederatedIdentityEntity;
|
import org.keycloak.models.jpa.entities.FederatedIdentityEntity;
|
||||||
|
import org.keycloak.models.jpa.entities.UserAttributeEntity;
|
||||||
import org.keycloak.models.jpa.entities.UserEntity;
|
import org.keycloak.models.jpa.entities.UserEntity;
|
||||||
import org.keycloak.models.utils.CredentialValidation;
|
import org.keycloak.models.utils.CredentialValidation;
|
||||||
import org.keycloak.models.utils.KeycloakModelUtils;
|
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||||
|
@ -400,32 +401,15 @@ public class JpaUserProvider implements UserProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<UserModel> searchForUserByUserAttributes(Map<String, String> attributes, RealmModel realm) {
|
public List<UserModel> searchForUserByUserAttribute(String attrName, String attrValue, RealmModel realm) {
|
||||||
StringBuilder builder = new StringBuilder("select attr.user,count(attr.user) from UserAttributeEntity attr where attr.user.realmId = :realmId");
|
TypedQuery<UserAttributeEntity> query = em.createNamedQuery("getAttributesByNameAndValue", UserAttributeEntity.class);
|
||||||
boolean first = true;
|
query.setParameter("name", attrName);
|
||||||
for (Map.Entry<String, String> entry : attributes.entrySet()) {
|
query.setParameter("value", attrValue);
|
||||||
String attrName = entry.getKey();
|
List<UserAttributeEntity> results = query.getResultList();
|
||||||
if (first) {
|
|
||||||
builder.append(" and ");
|
|
||||||
first = false;
|
|
||||||
} else {
|
|
||||||
builder.append(" or ");
|
|
||||||
}
|
|
||||||
builder.append(" ( attr.name like :").append(attrName);
|
|
||||||
builder.append(" and attr.value like :").append(attrName).append("val )");
|
|
||||||
}
|
|
||||||
builder.append(" group by attr.user having count(attr.user) = " + attributes.size());
|
|
||||||
Query query = em.createQuery(builder.toString());
|
|
||||||
query.setParameter("realmId", realm.getId());
|
|
||||||
for (Map.Entry<String, String> entry : attributes.entrySet()) {
|
|
||||||
query.setParameter(entry.getKey(), entry.getKey());
|
|
||||||
query.setParameter(entry.getKey() + "val", entry.getValue());
|
|
||||||
}
|
|
||||||
List results = query.getResultList();
|
|
||||||
|
|
||||||
List<UserModel> users = new ArrayList<UserModel>();
|
List<UserModel> users = new ArrayList<UserModel>();
|
||||||
for (Object o : results) {
|
for (UserAttributeEntity attr : results) {
|
||||||
UserEntity user = (UserEntity) ((Object[])o)[0];
|
UserEntity user = attr.getUser();
|
||||||
users.add(new UserAdapter(realm, em, user));
|
users.add(new UserAdapter(realm, em, user));
|
||||||
}
|
}
|
||||||
return users;
|
return users;
|
||||||
|
|
|
@ -21,6 +21,7 @@ import java.util.Set;
|
||||||
* @version $Revision: 1 $
|
* @version $Revision: 1 $
|
||||||
*/
|
*/
|
||||||
@NamedQueries({
|
@NamedQueries({
|
||||||
|
@NamedQuery(name="getAttributesByNameAndValue", query="select attr from UserAttributeEntity attr where attr.name = :name and attr.value = :value"),
|
||||||
@NamedQuery(name="deleteUserAttributesByRealm", query="delete from UserAttributeEntity attr where attr.user IN (select u from UserEntity u where u.realmId=:realmId)"),
|
@NamedQuery(name="deleteUserAttributesByRealm", query="delete from UserAttributeEntity attr where attr.user IN (select u from UserEntity u where u.realmId=:realmId)"),
|
||||||
@NamedQuery(name="deleteUserAttributesByRealmAndLink", query="delete from UserAttributeEntity attr where attr.user IN (select u from UserEntity u where u.realmId=:realmId and u.federationLink=:link)")
|
@NamedQuery(name="deleteUserAttributesByRealmAndLink", query="delete from UserAttributeEntity attr where attr.user IN (select u from UserEntity u where u.realmId=:realmId and u.federationLink=:link)")
|
||||||
})
|
})
|
||||||
|
|
|
@ -231,13 +231,10 @@ public class MongoUserProvider implements UserProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<UserModel> searchForUserByUserAttributes(Map<String, String> attributes, RealmModel realm) {
|
public List<UserModel> searchForUserByUserAttribute(String attrName, String attrValue, RealmModel realm) {
|
||||||
QueryBuilder queryBuilder = new QueryBuilder()
|
QueryBuilder queryBuilder = new QueryBuilder()
|
||||||
.and("realmId").is(realm.getId());
|
.and("realmId").is(realm.getId());
|
||||||
|
queryBuilder.and("attributes." + attrName).is(attrValue);
|
||||||
for (Map.Entry<String, String> entry : attributes.entrySet()) {
|
|
||||||
queryBuilder.and("attributes." + entry.getKey()).is(entry.getValue());
|
|
||||||
}
|
|
||||||
|
|
||||||
List<MongoUserEntity> users = getMongoStore().loadEntities(MongoUserEntity.class, queryBuilder.get(), invocationContext);
|
List<MongoUserEntity> users = getMongoStore().loadEntities(MongoUserEntity.class, queryBuilder.get(), invocationContext);
|
||||||
return convertUserEntities(realm, users);
|
return convertUserEntities(realm, users);
|
||||||
|
|
|
@ -193,8 +193,8 @@ public class UserModelTest extends AbstractModelTest {
|
||||||
Assert.assertEquals("val23", attrVals.get(0));
|
Assert.assertEquals("val23", attrVals.get(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Test
|
@Test
|
||||||
public void testSearchByUserAttributes() throws Exception {
|
public void testSearchByUserAttribute() throws Exception {
|
||||||
RealmModel realm = realmManager.createRealm("original");
|
RealmModel realm = realmManager.createRealm("original");
|
||||||
UserModel user1 = session.users().addUser(realm, "user1");
|
UserModel user1 = session.users().addUser(realm, "user1");
|
||||||
UserModel user2 = session.users().addUser(realm, "user2");
|
UserModel user2 = session.users().addUser(realm, "user2");
|
||||||
|
@ -210,20 +210,21 @@ public class UserModelTest extends AbstractModelTest {
|
||||||
|
|
||||||
commit();
|
commit();
|
||||||
|
|
||||||
Map<String, String> attributes = new HashMap<String, String>();
|
List<UserModel> users = session.users().searchForUserByUserAttribute("key1", "value1", realm);
|
||||||
attributes.put("key1", "value1");
|
|
||||||
List<UserModel> users = session.users().searchForUserByUserAttributes(attributes, realm);
|
|
||||||
Assert.assertEquals(2, users.size());
|
Assert.assertEquals(2, users.size());
|
||||||
Assert.assertTrue(users.contains(user1));
|
Assert.assertTrue(users.contains(user1));
|
||||||
Assert.assertTrue(users.contains(user2));
|
Assert.assertTrue(users.contains(user2));
|
||||||
|
|
||||||
attributes.put("key2", "value21");
|
users = session.users().searchForUserByUserAttribute("key2", "value21", realm);
|
||||||
users = session.users().searchForUserByUserAttributes(attributes, realm);
|
Assert.assertEquals(2, users.size());
|
||||||
Assert.assertEquals(1, users.size());
|
|
||||||
Assert.assertTrue(users.contains(user1));
|
Assert.assertTrue(users.contains(user1));
|
||||||
|
Assert.assertTrue(users.contains(user3));
|
||||||
|
|
||||||
attributes.put("key3", "value3");
|
users = session.users().searchForUserByUserAttribute("key2", "value22", realm);
|
||||||
users = session.users().searchForUserByUserAttributes(attributes, realm);
|
Assert.assertEquals(1, users.size());
|
||||||
|
Assert.assertTrue(users.contains(user2));
|
||||||
|
|
||||||
|
users = session.users().searchForUserByUserAttribute("key3", "value3", realm);
|
||||||
Assert.assertEquals(0, users.size());
|
Assert.assertEquals(0, users.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue