Users in role Rest API returns empty when User federation used (#23318)
* Users in role Rest API returns empty when User federation used Co-authored-by: Shankar Yadav <ET1024@neeyamoworks.com> Co-authored-by: Martin Kanis <mkanis@redhat.com> Co-authored-by: Michal Hajas <mhajas@redhat.com>
This commit is contained in:
parent
9627187447
commit
10a2c96c72
5 changed files with 61 additions and 1 deletions
|
@ -475,6 +475,15 @@ public class JpaUserFederatedStorageProvider implements
|
|||
return closing(paginateQuery(query, firstResult, max).getResultStream());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<String> getRoleMembersStream(RealmModel realm, RoleModel role, Integer firstResult, Integer max) {
|
||||
TypedQuery<String> query = em.createNamedQuery("fedRoleMembership", String.class);
|
||||
query.setParameter("roleId", role.getId());
|
||||
query.setParameter("realmId", realm.getId());
|
||||
|
||||
return closing(paginateQuery(query, firstResult, max).getResultStream());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<String> getRequiredActionsStream(RealmModel realm, String userId) {
|
||||
return this.getRequiredActionEntitiesStream(realm, userId, LockModeType.NONE).
|
||||
|
|
|
@ -40,7 +40,7 @@ import java.io.Serializable;
|
|||
@NamedQuery(name="deleteFederatedUserRoleMappingsByRealmAndLink", query="delete from FederatedUserRoleMappingEntity mapping where mapping.userId IN (select u.id from UserEntity u where u.realmId=:realmId and u.federationLink=:link)"),
|
||||
@NamedQuery(name="deleteFederatedUserRoleMappingsByRole", query="delete from FederatedUserRoleMappingEntity m where m.roleId = :roleId"),
|
||||
@NamedQuery(name="deleteFederatedUserRoleMappingsByUser", query="delete from FederatedUserRoleMappingEntity m where m.userId = :userId and m.realmId = :realmId"),
|
||||
|
||||
@NamedQuery(name="fedRoleMembership", query="select m.userId FROM FederatedUserRoleMappingEntity m where m.roleId = :roleId AND m.realmId = :realmId"),
|
||||
})
|
||||
@Table(name="FED_USER_ROLE_MAPPING")
|
||||
@Entity
|
||||
|
|
|
@ -423,6 +423,10 @@ public class UserStorageManager extends AbstractStorageManager<UserStorageProvid
|
|||
if (provider instanceof UserQueryMethodsProvider) {
|
||||
return ((UserQueryMethodsProvider)provider).getRoleMembersStream(realm, role, firstResultInQuery, maxResultsInQuery);
|
||||
}
|
||||
else if (provider instanceof UserFederatedStorageProvider) {
|
||||
return ((UserFederatedStorageProvider)provider).getRoleMembersStream(realm, role, firstResultInQuery, maxResultsInQuery).
|
||||
map(id -> getUserById(realm, id));
|
||||
}
|
||||
return Stream.empty();
|
||||
}, realm, firstResult, maxResults);
|
||||
return importValidation(realm, results);
|
||||
|
|
|
@ -40,6 +40,17 @@ public interface UserRoleMappingsFederatedStorage {
|
|||
|
||||
void deleteRoleMapping(RealmModel realm, String userId, RoleModel role);
|
||||
|
||||
/**
|
||||
* Obtains the federated users that are members of the given {@code role} in the specified {@code realm}.
|
||||
*
|
||||
* @param realm a reference to the realm.
|
||||
* @param role a reference to the role whose federated members are being searched.
|
||||
* @param firstResult first result to return. Ignored if negative or {@code null}.
|
||||
* @param max maximum number of results to return. Ignored if negative or {@code null}.
|
||||
* @return a non-null {@code Stream} of federated user ids that are members of the role in the realm.
|
||||
*/
|
||||
Stream<String> getRoleMembersStream(RealmModel realm, RoleModel role, Integer firstResult, Integer max);
|
||||
|
||||
/**
|
||||
* @deprecated This interface is no longer necessary; collection-based methods were removed from the parent interface
|
||||
* and therefore the parent interface can be used directly
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package org.keycloak.testsuite.federation.storage;
|
||||
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.hamcrest.Matchers;
|
||||
import org.jboss.arquillian.graphene.page.Page;
|
||||
import org.junit.After;
|
||||
import org.junit.Assert;
|
||||
|
@ -20,6 +21,7 @@ import org.keycloak.credential.CredentialProvider;
|
|||
import org.keycloak.credential.CredentialProviderFactory;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.RoleModel;
|
||||
import org.keycloak.models.UserModel;
|
||||
import org.keycloak.models.cache.CachedUserModel;
|
||||
import org.keycloak.models.credential.OTPCredentialModel;
|
||||
|
@ -867,6 +869,40 @@ public class UserStorageTest extends AbstractAuthTest {
|
|||
adminClient.realms().create(repOrig);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRoleMembership() {
|
||||
RoleRepresentation role1 = new RoleRepresentation();
|
||||
role1.setName("role1");
|
||||
RoleRepresentation role2 = new RoleRepresentation();
|
||||
role2.setName("role2");
|
||||
testRealmResource().roles().create(role1);
|
||||
testRealmResource().roles().create(role2);
|
||||
|
||||
UserRepresentation thor = ApiUtil.findUserByUsername(testRealmResource(), "thor");
|
||||
ApiUtil.assignRealmRoles(testRealmResource(), thor.getId(), "role1", "role2");
|
||||
|
||||
UserRepresentation zeus = ApiUtil.findUserByUsername(testRealmResource(), "zeus");
|
||||
ApiUtil.assignRealmRoles(testRealmResource(), zeus.getId(), "role1");
|
||||
|
||||
|
||||
testingClient.server().run(session -> {
|
||||
RealmModel realm = session.realms().getRealmByName("test");
|
||||
RoleModel roleModel1 = session.roles().getRealmRole(realm, "role1");
|
||||
RoleModel roleModel2 = session.roles().getRealmRole(realm, "role2");
|
||||
|
||||
List<String> users = session.users().getRoleMembersStream(realm, roleModel1).map(UserModel::getUsername).collect(Collectors.toList());
|
||||
Assert.assertEquals(2, users.size());
|
||||
Assert.assertThat(users, Matchers.containsInAnyOrder("thor", "zeus"));
|
||||
|
||||
users = session.users().getRoleMembersStream(realm, roleModel2).map(UserModel::getUsername).collect(Collectors.toList());
|
||||
Assert.assertEquals(1, users.size());
|
||||
Assert.assertThat(users, Matchers.containsInAnyOrder("thor"));
|
||||
});
|
||||
|
||||
testRealmResource().roles().get("role1").remove();
|
||||
testRealmResource().roles().get("role2").remove();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void testEntityRemovalHooksCascade() {
|
||||
|
|
Loading…
Reference in a new issue