Skip to content

Commit

Permalink
KEYCLOAK-1697 Fix UserProvider.searchForUsersByAttribute
Browse files Browse the repository at this point in the history
  • Loading branch information
mposolda committed Sep 3, 2015
1 parent 493fd0a commit 89660d0
Show file tree
Hide file tree
Showing 8 changed files with 34 additions and 55 deletions.
Expand Up @@ -314,8 +314,8 @@ public List<UserModel> query(RealmModel realm, int first, int max) {
} }


@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
Expand Down
Expand Up @@ -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);
Expand Down
Expand Up @@ -255,22 +255,18 @@ public List<UserModel> searchForUserByAttributes(Map<String, String> attributes,
} }


@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
Expand Down
Expand Up @@ -235,8 +235,8 @@ public List<UserModel> searchForUserByAttributes(Map<String, String> attributes,
} }


@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
Expand Down
Expand Up @@ -13,6 +13,7 @@
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;
Expand Down Expand Up @@ -400,32 +401,15 @@ public List<UserModel> searchForUserByAttributes(Map<String, String> attributes,
} }


@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;
Expand Down
Expand Up @@ -21,6 +21,7 @@
* @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)")
}) })
Expand Down
Expand Up @@ -231,13 +231,10 @@ public List<UserModel> searchForUserByAttributes(Map<String, String> attributes,
} }


@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);
Expand Down
Expand Up @@ -193,8 +193,8 @@ public void testUserMultipleAttributes() throws Exception {
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");
Expand All @@ -210,20 +210,21 @@ public void testSearchByUserAttributes() throws Exception {


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));

users = session.users().searchForUserByUserAttribute("key2", "value22", realm);
Assert.assertEquals(1, users.size());
Assert.assertTrue(users.contains(user2));


attributes.put("key3", "value3"); users = session.users().searchForUserByUserAttribute("key3", "value3", realm);
users = session.users().searchForUserByUserAttributes(attributes, realm);
Assert.assertEquals(0, users.size()); Assert.assertEquals(0, users.size());
} }


Expand Down

0 comments on commit 89660d0

Please sign in to comment.