Migrate FineGrainAdminUnitTest.java to the new testsuite

Part of: #34494

Signed-off-by: Lukas Hanusovsky <lhanusov@redhat.com>
This commit is contained in:
Lukas Hanusovsky 2025-06-05 08:36:44 +02:00 committed by Stian Thorgersen
parent 4fd047c58e
commit 17beaa1359
10 changed files with 1402 additions and 1372 deletions

View File

@ -49,6 +49,11 @@ public class AdminClientBuilder {
return this;
}
public AdminClientBuilder authorization(String accessToken) {
delegate.authorization(accessToken);
return this;
}
public AdminClientBuilder autoClose() {
this.close = true;
return this;

View File

@ -0,0 +1,357 @@
package org.keycloak.tests.admin.finegrainedadminv1;
import org.jboss.logging.Logger;
import org.junit.jupiter.api.Assertions;
import org.keycloak.admin.client.Keycloak;
import org.keycloak.authorization.model.Policy;
import org.keycloak.authorization.model.ResourceServer;
import org.keycloak.client.cli.util.ConfigUtil;
import org.keycloak.common.Profile;
import org.keycloak.models.AdminRoles;
import org.keycloak.models.ClientModel;
import org.keycloak.models.GroupModel;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel;
import org.keycloak.models.RoleModel;
import org.keycloak.models.UserCredentialModel;
import org.keycloak.models.UserModel;
import org.keycloak.models.utils.KeycloakModelUtils;
import org.keycloak.representations.idm.authorization.ClientPolicyRepresentation;
import org.keycloak.representations.idm.authorization.DecisionStrategy;
import org.keycloak.representations.idm.authorization.Logic;
import org.keycloak.representations.idm.authorization.UserPolicyRepresentation;
import org.keycloak.services.resources.admin.fgap.AdminPermissionManagement;
import org.keycloak.services.resources.admin.fgap.AdminPermissions;
import org.keycloak.testframework.admin.AdminClientFactory;
import org.keycloak.testframework.annotations.InjectAdminClient;
import org.keycloak.testframework.annotations.InjectAdminClientFactory;
import org.keycloak.testframework.annotations.InjectRealm;
import org.keycloak.testframework.injection.LifeCycle;
import org.keycloak.testframework.oauth.OAuthClient;
import org.keycloak.testframework.oauth.annotations.InjectOAuthClient;
import org.keycloak.testframework.realm.ManagedRealm;
import org.keycloak.testframework.remote.runonserver.InjectRunOnServer;
import org.keycloak.testframework.remote.runonserver.RunOnServerClient;
import org.keycloak.testframework.server.KeycloakServerConfig;
import org.keycloak.testframework.server.KeycloakServerConfigBuilder;
public class AbstractFineGrainedAdminTest {
@InjectRealm(lifecycle = LifeCycle.METHOD)
ManagedRealm managedRealm;
@InjectRealm(ref = "master", attachTo = "master")
ManagedRealm masterRealm;
@InjectAdminClientFactory
AdminClientFactory adminClientFactory;
@InjectRunOnServer
RunOnServerClient runOnServer;
@InjectAdminClient
Keycloak adminClient;
@InjectOAuthClient
OAuthClient oauth;
private static final Logger LOGGER = Logger.getLogger(FineGrainedAdminWithTokenExchangeTest.class);
public static final String REALM_NAME = "default";
public static final String CLIENT_NAME = "application";
public static void setupPolices(KeycloakSession session) {
RealmModel realm = session.realms().getRealmByName(REALM_NAME);
AdminPermissionManagement permissions = AdminPermissions.management(session, realm);
RoleModel realmRole = realm.addRole("realm-role");
RoleModel realmRole2 = realm.addRole("realm-role2");
ClientModel client1 = realm.addClient(CLIENT_NAME);
realm.addClientScope("scope");
client1.setFullScopeAllowed(false);
RoleModel client1Role = client1.addRole("client-role");
GroupModel group = realm.createGroup("top");
RoleModel mapperRole = realm.addRole("mapper");
RoleModel managerRole = realm.addRole("manager");
RoleModel compositeRole = realm.addRole("composite-role");
compositeRole.addCompositeRole(mapperRole);
compositeRole.addCompositeRole(managerRole);
// realm-role and application.client-role will have a role policy associated with their map-role permission
{
permissions.roles().setPermissionsEnabled(client1Role, true);
Policy mapRolePermission = permissions.roles().mapRolePermission(client1Role);
ResourceServer server = permissions.roles().resourceServer(client1Role);
Policy mapperPolicy = permissions.roles().rolePolicy(server, mapperRole);
mapRolePermission.addAssociatedPolicy(mapperPolicy);
}
{
permissions.roles().setPermissionsEnabled(realmRole, true);
Policy mapRolePermission = permissions.roles().mapRolePermission(realmRole);
ResourceServer server = permissions.roles().resourceServer(realmRole);
Policy mapperPolicy = permissions.roles().rolePolicy(server, mapperRole);
mapRolePermission.addAssociatedPolicy(mapperPolicy);
}
// realmRole2 will have an empty map-role policy
{
permissions.roles().setPermissionsEnabled(realmRole2, true);
}
// setup Users manage policies
{
permissions.users().setPermissionsEnabled(true);
ResourceServer server = permissions.realmResourceServer();
Policy managerPolicy = permissions.roles().rolePolicy(server, managerRole);
Policy permission = permissions.users().managePermission();
permission.addAssociatedPolicy(managerPolicy);
permission.setDecisionStrategy(DecisionStrategy.AFFIRMATIVE);
}
{
permissions.groups().setPermissionsEnabled(group, true);
}
{
permissions.clients().setPermissionsEnabled(client1, true);
}
// setup Users impersonate policy
{
ClientModel realmManagementClient = realm.getClientByClientId("realm-management");
RoleModel adminRole = realmManagementClient.getRole(AdminRoles.REALM_ADMIN);
permissions.users().setPermissionsEnabled(true);
ResourceServer server = permissions.realmResourceServer();
Policy adminPolicy = permissions.roles().rolePolicy(server, adminRole);
adminPolicy.setLogic(Logic.NEGATIVE);
Policy permission = permissions.users().userImpersonatedPermission();
permission.addAssociatedPolicy(adminPolicy);
permission.setDecisionStrategy(DecisionStrategy.UNANIMOUS);
}
}
public static void setupUsers(KeycloakSession session) {
RealmModel realm = session.realms().getRealmByName(REALM_NAME);
ClientModel client = realm.getClientByClientId(CLIENT_NAME);
RoleModel realmRole = realm.getRole("realm-role");
RoleModel realmRole2 = realm.getRole("realm-role2");
RoleModel clientRole = client.getRole("client-role");
RoleModel mapperRole = realm.getRole("mapper");
RoleModel managerRole = realm.getRole("manager");
RoleModel compositeRole = realm.getRole("composite-role");
ClientModel realmManagementClient = realm.getClientByClientId("realm-management");
RoleModel adminRole = realmManagementClient.getRole(AdminRoles.REALM_ADMIN);
RoleModel queryGroupsRole = realmManagementClient.getRole(AdminRoles.QUERY_GROUPS);
RoleModel queryUsersRole = realmManagementClient.getRole(AdminRoles.QUERY_USERS);
RoleModel queryClientsRole = realmManagementClient.getRole(AdminRoles.QUERY_CLIENTS);
UserModel nomapAdmin = session.users().addUser(realm, "nomap-admin");
nomapAdmin.setFirstName("No Map");
nomapAdmin.setLastName("Admin");
nomapAdmin.setEmail("nomap@admin");
nomapAdmin.setEnabled(true);
nomapAdmin.credentialManager().updateCredential(UserCredentialModel.password("password"));
nomapAdmin.grantRole(adminRole);
UserModel anotherAdmin = session.users().addUser(realm, "anotherAdmin");
anotherAdmin.setFirstName("Another");
anotherAdmin.setLastName("Admin");
anotherAdmin.setEmail("another@admin");
anotherAdmin.setEnabled(true);
anotherAdmin.credentialManager().updateCredential(UserCredentialModel.password("password"));
anotherAdmin.grantRole(adminRole);
UserModel authorizedUser = session.users().addUser(realm, "authorized");
authorizedUser.setFirstName("Authorized");
authorizedUser.setLastName("User");
authorizedUser.setEmail("authorized@user");
authorizedUser.setEnabled(true);
authorizedUser.credentialManager().updateCredential(UserCredentialModel.password("password"));
authorizedUser.grantRole(mapperRole);
authorizedUser.grantRole(managerRole);
UserModel authorizedComposite = session.users().addUser(realm, "authorizedComposite");
authorizedComposite.setFirstName("Authorized");
authorizedComposite.setLastName("Composite");
authorizedComposite.setEmail("authorized@Composite");
authorizedComposite.setEnabled(true);
authorizedComposite.credentialManager().updateCredential(UserCredentialModel.password("password"));
authorizedComposite.grantRole(compositeRole);
UserModel unauthorizedUser = session.users().addUser(realm, "unauthorized");
unauthorizedUser.setFirstName("Unauthorized");
unauthorizedUser.setLastName("User");
unauthorizedUser.setEmail("unauthorized@user");
unauthorizedUser.setEnabled(true);
unauthorizedUser.credentialManager().updateCredential(UserCredentialModel.password("password"));
UserModel unauthorizedMapper = session.users().addUser(realm, "unauthorizedMapper");
unauthorizedMapper.setFirstName("Unauthorized");
unauthorizedMapper.setLastName("Mapper");
unauthorizedMapper.setEmail("unauthorized@Mapper");
unauthorizedMapper.setEnabled(true);
unauthorizedMapper.credentialManager().updateCredential(UserCredentialModel.password("password"));
unauthorizedMapper.grantRole(managerRole);
UserModel user1 = session.users().addUser(realm, "user1");
user1.setFirstName("User");
user1.setLastName("One");
user1.setEmail("user@one");
user1.setEnabled(true);
// group management
AdminPermissionManagement permissions = AdminPermissions.management(session, realm);
GroupModel group = KeycloakModelUtils.findGroupByPath(session, realm, "top");
UserModel groupMember = session.users().addUser(realm, "groupMember");
groupMember.setFirstName("Group");
groupMember.setLastName("Member");
groupMember.setEmail("group@member");
groupMember.joinGroup(group);
groupMember.setEnabled(true);
UserModel groupManager = session.users().addUser(realm, "groupManager");
groupManager.setFirstName("Group");
groupManager.setLastName("Manager");
groupManager.setEmail("group@manager");
groupManager.grantRole(queryGroupsRole);
groupManager.grantRole(queryUsersRole);
groupManager.setEnabled(true);
groupManager.grantRole(mapperRole);
groupManager.credentialManager().updateCredential(UserCredentialModel.password("password"));
UserModel groupManagerNoMapper = session.users().addUser(realm, "noMapperGroupManager");
groupManagerNoMapper.setFirstName("No Mapper");
groupManagerNoMapper.setLastName("Group Manager");
groupManagerNoMapper.setEmail("nomapper@groupmanager");
groupManagerNoMapper.setEnabled(true);
groupManagerNoMapper.credentialManager().updateCredential(UserCredentialModel.password("password"));
groupManagerNoMapper.grantRole(queryGroupsRole);
groupManagerNoMapper.grantRole(queryUsersRole);
UserPolicyRepresentation groupManagerRep = new UserPolicyRepresentation();
groupManagerRep.setName("groupManagers");
groupManagerRep.addUser("groupManager");
groupManagerRep.addUser("noMapperGroupManager");
ResourceServer server = permissions.realmResourceServer();
Policy groupManagerPolicy = permissions.authz().getStoreFactory().getPolicyStore().create(server, groupManagerRep);
permissions.groups().manageMembersPermission(group).addAssociatedPolicy(groupManagerPolicy);
permissions.groups().manageMembershipPermission(group).addAssociatedPolicy(groupManagerPolicy);
permissions.groups().viewPermission(group).addAssociatedPolicy(groupManagerPolicy);
UserModel clientMapper = session.users().addUser(realm, "clientMapper");
clientMapper.setFirstName("Client");
clientMapper.setLastName("Mapper");
clientMapper.setEmail("client@mapper");
clientMapper.setEnabled(true);
clientMapper.grantRole(managerRole);
clientMapper.grantRole(queryUsersRole);
clientMapper.credentialManager().updateCredential(UserCredentialModel.password("password"));
Policy clientMapperPolicy = permissions.clients().mapRolesPermission(client);
UserPolicyRepresentation userRep = new UserPolicyRepresentation();
userRep.setName("userClientMapper");
userRep.addUser("clientMapper");
Policy userPolicy = permissions.authz().getStoreFactory().getPolicyStore().create(permissions.clients().resourceServer(client), userRep);
clientMapperPolicy.addAssociatedPolicy(userPolicy);
UserModel clientManager = session.users().addUser(realm, "clientManager");
clientManager.setFirstName("Client");
clientManager.setLastName("Manager");
clientManager.setEmail("client@manager");
clientManager.setEnabled(true);
clientManager.grantRole(queryClientsRole);
clientManager.credentialManager().updateCredential(UserCredentialModel.password("password"));
Policy clientManagerPolicy = permissions.clients().managePermission(client);
userRep = new UserPolicyRepresentation();
userRep.setName("clientManager");
userRep.addUser("clientManager");
userPolicy = permissions.authz().getStoreFactory().getPolicyStore().create(permissions.clients().resourceServer(client), userRep);
clientManagerPolicy.addAssociatedPolicy(userPolicy);
UserModel clientConfigurer = session.users().addUser(realm, "clientConfigurer");
clientConfigurer.setFirstName("Client");
clientConfigurer.setLastName("Configurer");
clientConfigurer.setEmail("client@configurer");
clientConfigurer.setEnabled(true);
clientConfigurer.grantRole(queryClientsRole);
clientConfigurer.credentialManager().updateCredential(UserCredentialModel.password("password"));
Policy clientConfigurePolicy = permissions.clients().configurePermission(client);
userRep = new UserPolicyRepresentation();
userRep.setName("clientConfigure");
userRep.addUser("clientConfigurer");
userPolicy = permissions.authz().getStoreFactory().getPolicyStore().create(permissions.clients().resourceServer(client), userRep);
clientConfigurePolicy.addAssociatedPolicy(userPolicy);
UserModel groupViewer = session.users().addUser(realm, "groupViewer");
groupViewer.setFirstName("Group");
groupViewer.setLastName("Viewer");
groupViewer.setEmail("group@viewer");
groupViewer.grantRole(queryGroupsRole);
groupViewer.grantRole(queryUsersRole);
groupViewer.setEnabled(true);
groupViewer.credentialManager().updateCredential(UserCredentialModel.password("password"));
UserPolicyRepresentation groupViewMembersRep = new UserPolicyRepresentation();
groupViewMembersRep.setName("groupMemberViewers");
groupViewMembersRep.addUser("groupViewer");
Policy groupViewMembersPolicy = permissions.authz().getStoreFactory().getPolicyStore().create(server, groupViewMembersRep);
Policy groupViewMembersPermission = permissions.groups().viewMembersPermission(group);
groupViewMembersPermission.addAssociatedPolicy(groupViewMembersPolicy);
}
protected String checkTokenExchange(boolean shouldPass) {
runOnServer.run(AbstractFineGrainedAdminTest::setupTokenExchange);
oauth.realm("master");
oauth.client("tokenexclient", "password");
String exchanged = null;
String token = oauth.doPasswordGrantRequest("admin", "admin").getAccessToken();
Assertions.assertNotNull(token);
try {
exchanged = oauth.tokenExchangeRequest(token).audience("admin-cli").send().getAccessToken();
} catch (AssertionError e) {
LOGGER.info("Error message is expected from oauth: " + e.getMessage());
}
if (shouldPass)
Assertions.assertNotNull(exchanged);
else
Assertions.assertNull(exchanged);
return exchanged;
}
private static void setupTokenExchange(KeycloakSession session) {
RealmModel realm = session.realms().getRealmByName("master");
ClientModel client = session.clients().getClientByClientId(realm, "tokenexclient");
if (client != null) {
return;
}
ClientModel tokenexclient = realm.addClient("tokenexclient");
tokenexclient.setEnabled(true);
tokenexclient.addRedirectUri("http://localhost:*");
tokenexclient.setPublicClient(false);
tokenexclient.setSecret("password");
tokenexclient.setDirectAccessGrantsEnabled(true);
// permission for client to client exchange to "target" client
ClientModel adminCli = realm.getClientByClientId(ConfigUtil.DEFAULT_CLIENT);
AdminPermissionManagement management = AdminPermissions.management(session, realm);
management.clients().setPermissionsEnabled(adminCli, true);
ClientPolicyRepresentation clientRep = new ClientPolicyRepresentation();
clientRep.setName("to");
clientRep.addClient(tokenexclient.getId());
ResourceServer server = management.realmResourceServer();
Policy clientPolicy = management.authz().getStoreFactory().getPolicyStore().create(server, clientRep);
management.clients().exchangeToPermission(adminCli).addAssociatedPolicy(clientPolicy);
}
public static class FineGrainedAdminServerConf implements KeycloakServerConfig {
@Override
public KeycloakServerConfigBuilder configure(KeycloakServerConfigBuilder config) {
config.features(Profile.Feature.ADMIN_FINE_GRAINED_AUTHZ);
return config;
}
}
}

View File

@ -0,0 +1,109 @@
package org.keycloak.tests.admin.finegrainedadminv1;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.keycloak.admin.client.Keycloak;
import org.keycloak.authorization.model.Resource;
import org.keycloak.models.AdminRoles;
import org.keycloak.models.ClientModel;
import org.keycloak.models.Constants;
import org.keycloak.models.GroupModel;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel;
import org.keycloak.models.RoleModel;
import org.keycloak.models.UserCredentialModel;
import org.keycloak.models.UserModel;
import org.keycloak.models.utils.KeycloakModelUtils;
import org.keycloak.representations.idm.ClientRepresentation;
import org.keycloak.representations.idm.RoleRepresentation;
import org.keycloak.services.resources.admin.fgap.AdminPermissionManagement;
import org.keycloak.services.resources.admin.fgap.AdminPermissions;
import org.keycloak.testframework.annotations.KeycloakIntegrationTest;
import java.util.LinkedList;
import java.util.List;
@KeycloakIntegrationTest(config = AbstractFineGrainedAdminTest.FineGrainedAdminServerConf.class)
public class FineGrainedAdminDefaultRealmTest extends AbstractFineGrainedAdminTest {
// KEYCLOAK-5152
@Test
public void testRealmWithComposites() {
runOnServer.run(FineGrainedAdminDefaultRealmTest::setup5152);
try (Keycloak realmClient = adminClientFactory.create().realm(REALM_NAME)
.username("realm-admin").password("password").clientId(Constants.ADMIN_CLI_CLIENT_ID).build()) {
RoleRepresentation composite = new RoleRepresentation();
composite.setName("composite");
composite.setComposite(true);
realmClient.realm(REALM_NAME).roles().create(composite);
composite = managedRealm.admin().roles().get("composite").toRepresentation();
ClientRepresentation client = managedRealm.admin().clients().findByClientId(Constants.REALM_MANAGEMENT_CLIENT_ID).get(0);
RoleRepresentation viewUsers = managedRealm.admin().clients().get(client.getId()).roles().get(AdminRoles.CREATE_CLIENT).toRepresentation();
List<RoleRepresentation> composites = new LinkedList<>();
composites.add(viewUsers);
realmClient.realm(REALM_NAME).rolesById().addComposites(composite.getId(), composites);
}
}
@Test
public void testRemoveCleanup() {
runOnServer.run(FineGrainedAdminDefaultRealmTest::setupDeleteTest);
runOnServer.run(FineGrainedAdminDefaultRealmTest::invokeDelete);
}
public static void setup5152(KeycloakSession session) {
RealmModel realm = session.realms().getRealmByName(REALM_NAME);
ClientModel realmAdminClient = realm.getClientByClientId(Constants.REALM_MANAGEMENT_CLIENT_ID);
RoleModel realmAdminRole = realmAdminClient.getRole(AdminRoles.REALM_ADMIN);
UserModel realmUser = session.users().addUser(realm, "realm-admin");
realmUser.setFirstName("Realm");
realmUser.setLastName("Admin");
realmUser.setEmail("realm@admin");
realmUser.grantRole(realmAdminRole);
realmUser.setEnabled(true);
realmUser.credentialManager().updateCredential(UserCredentialModel.password("password"));
}
// test role deletion that it cleans up authz objects
public static void setupDeleteTest(KeycloakSession session ) {
RealmModel realm = session.realms().getRealmByName(REALM_NAME);
RoleModel removedRole = realm.addRole("removedRole");
ClientModel client = realm.addClient("removedClient");
RoleModel removedClientRole = client.addRole("removedClientRole");
GroupModel removedGroup = realm.createGroup("removedGroup");
AdminPermissionManagement management = AdminPermissions.management(session, realm);
management.roles().setPermissionsEnabled(removedRole, true);
management.roles().setPermissionsEnabled(removedClientRole, true);
management.groups().setPermissionsEnabled(removedGroup, true);
management.clients().setPermissionsEnabled(client, true);
management.users().setPermissionsEnabled(true);
}
public static void invokeDelete(KeycloakSession session) {
RealmModel realm = session.realms().getRealmByName(REALM_NAME);
AdminPermissionManagement management = AdminPermissions.management(session, realm);
List<Resource> byResourceServer = management.authz().getStoreFactory().getResourceStore().findByResourceServer(management.realmResourceServer());
Assertions.assertEquals(5, byResourceServer.size());
RoleModel removedRole = realm.getRole("removedRole");
realm.removeRole(removedRole);
ClientModel client = realm.getClientByClientId("removedClient");
RoleModel removedClientRole = client.getRole("removedClientRole");
client.removeRole(removedClientRole);
GroupModel group = KeycloakModelUtils.findGroupByPath(session, realm, "removedGroup");
realm.removeGroup(group);
byResourceServer = management.authz().getStoreFactory().getResourceStore().findByResourceServer(management.realmResourceServer());
Assertions.assertEquals(2, byResourceServer.size());
realm.removeClient(client.getId());
byResourceServer = management.authz().getStoreFactory().getResourceStore().findByResourceServer(management.realmResourceServer());
Assertions.assertEquals(1, byResourceServer.size());
management.users().setPermissionsEnabled(false);
Resource userResource = management.authz().getStoreFactory().getResourceStore().findByName(management.realmResourceServer(), "Users");
Assertions.assertNull(userResource);
byResourceServer = management.authz().getStoreFactory().getResourceStore().findByResourceServer(management.realmResourceServer());
Assertions.assertEquals(0, byResourceServer.size());
}
}

View File

@ -0,0 +1,172 @@
package org.keycloak.tests.admin.finegrainedadminv1;
import jakarta.ws.rs.core.Response;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.keycloak.admin.client.Keycloak;
import org.keycloak.models.AdminRoles;
import org.keycloak.models.Constants;
import org.keycloak.representations.idm.ClientRepresentation;
import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.representations.idm.RoleRepresentation;
import org.keycloak.representations.idm.UserRepresentation;
import org.keycloak.testframework.annotations.KeycloakIntegrationTest;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.hasItem;
@KeycloakIntegrationTest(config = AbstractFineGrainedAdminTest.FineGrainedAdminServerConf.class)
public class FineGrainedAdminMasterRealmTest extends AbstractFineGrainedAdminTest {
@Test
public void testMasterRealm() throws Exception {
// test that master realm can still perform operations when policies are in place
//
runOnServer.run(FineGrainedAdminRestTest::setupPolices);
runOnServer.run(FineGrainedAdminRestTest::setupUsers);
UserRepresentation user1 = managedRealm.admin().users().search("user1").get(0);
RoleRepresentation realmRole = managedRealm.admin().roles().get("realm-role").toRepresentation();
List<RoleRepresentation> realmRoleSet = new LinkedList<>();
realmRoleSet.add(realmRole);
RoleRepresentation realmRole2 = managedRealm.admin().roles().get("realm-role2").toRepresentation();
List<RoleRepresentation> realmRole2Set = new LinkedList<>();
realmRole2Set.add(realmRole);
ClientRepresentation client = managedRealm.admin().clients().findByClientId(CLIENT_NAME).get(0);
RoleRepresentation clientRole = managedRealm.admin().clients().get(client.getId()).roles().get("client-role").toRepresentation();
List<RoleRepresentation> clientRoleSet = new LinkedList<>();
clientRoleSet.add(clientRole);
adminClient.realm(REALM_NAME).users().get(user1.getId()).roles().realmLevel().add(realmRoleSet);
List<RoleRepresentation> roles = managedRealm.admin().users().get(user1.getId()).roles().realmLevel().listAll();
Assertions.assertTrue(roles.stream().anyMatch((r) -> {
return r.getName().equals("realm-role");
}));
adminClient.realm(REALM_NAME).users().get(user1.getId()).roles().realmLevel().remove(realmRoleSet);
roles = managedRealm.admin().users().get(user1.getId()).roles().realmLevel().listAll();
Assertions.assertTrue(roles.stream().noneMatch((r) -> {
return r.getName().equals("realm-role");
}));
adminClient.realm(REALM_NAME).users().get(user1.getId()).roles().clientLevel(client.getId()).add(clientRoleSet);
roles = managedRealm.admin().users().get(user1.getId()).roles().clientLevel(client.getId()).listAll();
Assertions.assertTrue(roles.stream().anyMatch((r) -> {
return r.getName().equals("client-role");
}));
adminClient.realm(REALM_NAME).users().get(user1.getId()).roles().clientLevel(client.getId()).remove(clientRoleSet);
roles = managedRealm.admin().users().get(user1.getId()).roles().clientLevel(client.getId()).listAll();
Assertions.assertTrue(roles.stream().noneMatch((r) -> {
return r.getName().equals("client-role");
}));
}
// KEYCLOAK-5152
@Test
public void testMasterRealmWithComposites() throws Exception {
RoleRepresentation composite = new RoleRepresentation();
composite.setName("composite");
composite.setComposite(true);
managedRealm.admin().roles().create(composite);
composite = managedRealm.admin().roles().get("composite").toRepresentation();
ClientRepresentation client = managedRealm.admin().clients().findByClientId(Constants.REALM_MANAGEMENT_CLIENT_ID).get(0);
RoleRepresentation createClient = managedRealm.admin().clients().get(client.getId()).roles().get(AdminRoles.CREATE_CLIENT).toRepresentation();
RoleRepresentation queryRealms = managedRealm.admin().clients().get(client.getId()).roles().get(AdminRoles.QUERY_REALMS).toRepresentation();
List<RoleRepresentation> composites = new LinkedList<>();
composites.add(createClient);
composites.add(queryRealms);
managedRealm.admin().rolesById().addComposites(composite.getId(), composites);
}
// KEYCLOAK-5211
@Test
public void testCreateRealmCreateClient() throws Exception {
ClientRepresentation rep = new ClientRepresentation();
rep.setName("fullScopedClient");
rep.setClientId("fullScopedClient");
rep.setFullScopeAllowed(true);
rep.setSecret("618268aa-51e6-4e64-93c4-3c0bc65b8171");
rep.setProtocol("openid-connect");
rep.setPublicClient(false);
rep.setEnabled(true);
masterRealm.admin().clients().create(rep);
Keycloak realmClient = adminClientFactory.create().realm("master")
.username("admin").password("admin").clientId("fullScopedClient").clientSecret("618268aa-51e6-4e64-93c4-3c0bc65b8171").build();
try {
RealmRepresentation newRealm=new RealmRepresentation();
newRealm.setRealm("anotherRealm");
newRealm.setId("anotherRealm");
newRealm.setEnabled(true);
realmClient.realms().create(newRealm);
ClientRepresentation newClient = new ClientRepresentation();
newClient.setName("newClient");
newClient.setClientId("newClient");
newClient.setFullScopeAllowed(true);
newClient.setSecret("secret");
newClient.setProtocol("openid-connect");
newClient.setPublicClient(false);
newClient.setEnabled(true);
Response response = realmClient.realm("anotherRealm").clients().create(newClient);
Assertions.assertEquals(403, response.getStatus());
response.close();
realmClient.close();
//creating new client to refresh token
realmClient = adminClientFactory.create().realm("master")
.username("admin").password("admin").clientId("fullScopedClient").clientSecret("618268aa-51e6-4e64-93c4-3c0bc65b8171").build();
assertThat(realmClient.realms().findAll().stream().map(RealmRepresentation::getRealm).collect(Collectors.toSet()),
hasItem("anotherRealm"));
response = realmClient.realm("anotherRealm").clients().create(newClient);
Assertions.assertEquals(201, response.getStatus());
response.close();
} finally {
adminClient.realm("anotherRealm").remove();
realmClient.close();
}
}
// KEYCLOAK-5211
@Test
public void testCreateRealmCreateClientWithMaster() throws Exception {
ClientRepresentation rep = new ClientRepresentation();
rep.setName("fullScopedClient");
rep.setClientId("fullScopedClient");
rep.setFullScopeAllowed(true);
rep.setSecret("618268aa-51e6-4e64-93c4-3c0bc65b8171");
rep.setProtocol("openid-connect");
rep.setPublicClient(false);
rep.setEnabled(true);
masterRealm.admin().clients().create(rep);
RealmRepresentation newRealm=new RealmRepresentation();
newRealm.setRealm("anotherRealm");
newRealm.setId("anotherRealm");
newRealm.setEnabled(true);
adminClient.realms().create(newRealm);
try {
ClientRepresentation newClient = new ClientRepresentation();
newClient.setName("newClient");
newClient.setClientId("newClient");
newClient.setFullScopeAllowed(true);
newClient.setSecret("secret");
newClient.setProtocol("openid-connect");
newClient.setPublicClient(false);
newClient.setEnabled(true);
Response response = adminClient.realm("anotherRealm").clients().create(newClient);
Assertions.assertEquals(201, response.getStatus());
response.close();
} finally {
adminClient.realm("anotherRealm").remove();
}
}
}

View File

@ -0,0 +1,311 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.keycloak.tests.admin.finegrainedadminv1;
import jakarta.ws.rs.core.Response;
import org.hamcrest.MatcherAssert;
import org.hamcrest.Matchers;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.keycloak.admin.client.Keycloak;
import org.keycloak.models.Constants;
import org.keycloak.representations.idm.ClientRepresentation;
import org.keycloak.representations.idm.ClientScopeRepresentation;
import org.keycloak.representations.idm.RoleRepresentation;
import org.keycloak.representations.idm.UserRepresentation;
import org.keycloak.testframework.annotations.KeycloakIntegrationTest;
import org.keycloak.testframework.realm.GroupConfigBuilder;
import org.keycloak.testframework.realm.UserConfigBuilder;
import org.keycloak.tests.utils.admin.ApiUtil;
import jakarta.ws.rs.ClientErrorException;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
@KeycloakIntegrationTest(config = AbstractFineGrainedAdminTest.FineGrainedAdminServerConf.class)
public class FineGrainedAdminRestTest extends AbstractFineGrainedAdminTest {
@Test
public void testRestEvaluation() throws Exception {
String groupId = ApiUtil.getCreatedId(managedRealm.admin().groups().add(GroupConfigBuilder.create().name("restricted-group").build()));
runOnServer.run(FineGrainedAdminRestTest::setupPolices);
runOnServer.run(FineGrainedAdminRestTest::setupUsers);
UserRepresentation user1 = managedRealm.admin().users().search("user1").get(0);
UserRepresentation anotherAdmin = managedRealm.admin().users().search("anotherAdmin").get(0);
UserRepresentation groupMember = managedRealm.admin().users().search("groupMember").get(0);
RoleRepresentation realmRole = managedRealm.admin().roles().get("realm-role").toRepresentation();
List<RoleRepresentation> realmRoleSet = new LinkedList<>();
realmRoleSet.add(realmRole);
RoleRepresentation realmRole2 = managedRealm.admin().roles().get("realm-role2").toRepresentation();
List<RoleRepresentation> realmRole2Set = new LinkedList<>();
realmRole2Set.add(realmRole2);
ClientRepresentation client = managedRealm.admin().clients().findByClientId(CLIENT_NAME).get(0);
ClientScopeRepresentation scope = managedRealm.admin().clientScopes().findAll().get(0);
RoleRepresentation clientRole = managedRealm.admin().clients().get(client.getId()).roles().get("client-role").toRepresentation();
List<RoleRepresentation> clientRoleSet = new LinkedList<>();
clientRoleSet.add(clientRole);
// test configure client
{
try (Keycloak realmClient = adminClientFactory.create()
.realm(REALM_NAME).username("clientConfigurer").password("password").clientId(Constants.ADMIN_CLI_CLIENT_ID).build()) {
client.setAdminUrl("http://nowhere");
realmClient.realm(REALM_NAME).clients().get(client.getId()).update(client);
client.setFullScopeAllowed(true);
try {
realmClient.realm(REALM_NAME).clients().get(client.getId()).update(client);
Assertions.fail("should fail with forbidden exception");
} catch (ClientErrorException e) {
Assertions.assertEquals(403, e.getResponse().getStatus());
}
client.setFullScopeAllowed(false);
realmClient.realm(REALM_NAME).clients().get(client.getId()).update(client);
try {
realmClient.realm(REALM_NAME).clients().get(client.getId()).addDefaultClientScope(scope.getId());
Assertions.fail("should fail with forbidden exception");
} catch (ClientErrorException e) {
Assertions.assertEquals(403, e.getResponse().getStatus());
}
try {
realmClient.realm(REALM_NAME).clients().get(client.getId()).getScopeMappings().realmLevel().add(realmRoleSet);
Assertions.fail("should fail with forbidden exception");
} catch (ClientErrorException e) {
Assertions.assertEquals(403, e.getResponse().getStatus());
}
}
}
// test illegal impersonation
{
Keycloak realmClient = adminClientFactory.create()
.realm(REALM_NAME).username("nomap-admin").password("password").clientId(Constants.ADMIN_CLI_CLIENT_ID).build();
try {
realmClient.realm(REALM_NAME).users().get(user1.getId()).impersonate();
realmClient.close(); // just in case of cookie settings
realmClient = adminClientFactory.create()
.realm(REALM_NAME).username("nomap-admin").password("password").clientId(Constants.ADMIN_CLI_CLIENT_ID).build();
try {
realmClient.realm(REALM_NAME).users().get(anotherAdmin.getId()).impersonate();
Assertions.fail("should fail with forbidden exception");
} catch (ClientErrorException e) {
Assertions.assertEquals(403, e.getResponse().getStatus());
}
} finally {
realmClient.close();
}
}
{
try (Keycloak realmClient = adminClientFactory.create()
.realm(REALM_NAME).username("authorized").password("password").clientId(Constants.ADMIN_CLI_CLIENT_ID).build()) {
realmClient.realm(REALM_NAME).users().get(user1.getId()).roles().realmLevel().add(realmRoleSet);
List<RoleRepresentation> roles = managedRealm.admin().users().get(user1.getId()).roles().realmLevel().listAll();
Assertions.assertTrue(roles.stream().anyMatch((r) -> {
return r.getName().equals("realm-role");
}));
realmClient.realm(REALM_NAME).users().get(user1.getId()).roles().realmLevel().remove(realmRoleSet);
roles = managedRealm.admin().users().get(user1.getId()).roles().realmLevel().listAll();
Assertions.assertTrue(roles.stream().noneMatch((r) -> {
return r.getName().equals("realm-role");
}));
realmClient.realm(REALM_NAME).users().get(user1.getId()).roles().clientLevel(client.getId()).add(clientRoleSet);
roles = managedRealm.admin().users().get(user1.getId()).roles().clientLevel(client.getId()).listAll();
Assertions.assertTrue(roles.stream().anyMatch((r) -> {
return r.getName().equals("client-role");
}));
realmClient.realm(REALM_NAME).users().get(user1.getId()).roles().clientLevel(client.getId()).remove(clientRoleSet);
roles = managedRealm.admin().users().get(user1.getId()).roles().clientLevel(client.getId()).listAll();
Assertions.assertTrue(roles.stream().noneMatch((r) -> {
return r.getName().equals("client-role");
}));
}
}
{
try (Keycloak realmClient = adminClientFactory.create()
.realm(REALM_NAME).username("authorizedComposite").password("password").clientId(Constants.ADMIN_CLI_CLIENT_ID).build()) {
realmClient.realm(REALM_NAME).users().get(user1.getId()).roles().realmLevel().add(realmRoleSet);
List<RoleRepresentation> roles = managedRealm.admin().users().get(user1.getId()).roles().realmLevel().listAll();
Assertions.assertTrue(roles.stream().anyMatch((r) -> {
return r.getName().equals("realm-role");
}));
realmClient.realm(REALM_NAME).users().get(user1.getId()).roles().realmLevel().remove(realmRoleSet);
roles = managedRealm.admin().users().get(user1.getId()).roles().realmLevel().listAll();
Assertions.assertTrue(roles.stream().noneMatch((r) -> {
return r.getName().equals("realm-role");
}));
realmClient.realm(REALM_NAME).users().get(user1.getId()).roles().clientLevel(client.getId()).add(clientRoleSet);
roles = managedRealm.admin().users().get(user1.getId()).roles().clientLevel(client.getId()).listAll();
Assertions.assertTrue(roles.stream().anyMatch((r) -> {
return r.getName().equals("client-role");
}));
realmClient.realm(REALM_NAME).users().get(user1.getId()).roles().clientLevel(client.getId()).remove(clientRoleSet);
roles = managedRealm.admin().users().get(user1.getId()).roles().clientLevel(client.getId()).listAll();
Assertions.assertTrue(roles.stream().noneMatch((r) -> {
return r.getName().equals("client-role");
}));
}
}
{
try (Keycloak realmClient = adminClientFactory.create()
.realm(REALM_NAME).username("unauthorized").password("password").clientId(Constants.ADMIN_CLI_CLIENT_ID).build()) {
realmClient.realm(REALM_NAME).users().get(user1.getId()).roles().realmLevel().add(realmRoleSet);
Assertions.fail("should fail with forbidden exception");
} catch (ClientErrorException e) {
Assertions.assertEquals(403, e.getResponse().getStatus());
}
}
{
try (Keycloak realmClient = adminClientFactory.create()
.realm(REALM_NAME).username("unauthorizedMapper").password("password").clientId(Constants.ADMIN_CLI_CLIENT_ID).build()) {
realmClient.realm(REALM_NAME).users().get(user1.getId()).roles().realmLevel().add(realmRoleSet);
Assertions.fail("should fail with forbidden exception");
} catch (ClientErrorException e) {
Assertions.assertEquals(403, e.getResponse().getStatus());
}
}
{
try (Keycloak realmClient = adminClientFactory.create()
.realm(REALM_NAME).username("groupManager").password("password").clientId(Constants.ADMIN_CLI_CLIENT_ID).build()) {
realmClient.realm(REALM_NAME).users().get(groupMember.getId()).roles().clientLevel(client.getId()).add(clientRoleSet);
List<RoleRepresentation> roles = realmClient.realm(REALM_NAME).users().get(groupMember.getId()).roles().clientLevel(client.getId()).listAll();
Assertions.assertTrue(roles.stream().anyMatch((r) -> {
return r.getName().equals("client-role");
}));
realmClient.realm(REALM_NAME).users().get(groupMember.getId()).roles().clientLevel(client.getId()).remove(clientRoleSet);
roles = realmClient.realm(REALM_NAME).users().get(groupMember.getId()).roles().realmLevel().listAvailable();
Assertions.assertEquals(1, roles.size());
realmClient.realm(REALM_NAME).users().get(groupMember.getId()).roles().realmLevel().add(realmRoleSet);
realmClient.realm(REALM_NAME).users().get(groupMember.getId()).roles().realmLevel().remove(realmRoleSet);
try {
realmClient.realm(REALM_NAME).users().get(groupMember.getId()).roles().realmLevel().add(realmRole2Set);
Assertions.fail("should fail with forbidden exception");
} catch (ClientErrorException e) {
Assertions.assertEquals(403, e.getResponse().getStatus());
}
try {
realmClient.realm(REALM_NAME).users().get(user1.getId()).roles().realmLevel().add(realmRoleSet);
Assertions.fail("should fail with forbidden exception");
} catch (ClientErrorException e) {
Assertions.assertEquals(403, e.getResponse().getStatus());
}
}
}
// test client.mapRoles
{
try (Keycloak realmClient = adminClientFactory
.create().realm(REALM_NAME).username("clientMapper").password("password").clientId(Constants.ADMIN_CLI_CLIENT_ID).build()) {
List<RoleRepresentation> roles = realmClient.realm(REALM_NAME).users().get(user1.getId()).roles().clientLevel(client.getId()).listAll();
Assertions.assertTrue(roles.isEmpty());
realmClient.realm(REALM_NAME).users().get(user1.getId()).roles().clientLevel(client.getId()).add(clientRoleSet);
roles = realmClient.realm(REALM_NAME).users().get(user1.getId()).roles().clientLevel(client.getId()).listAll();
Assertions.assertTrue(roles.stream().anyMatch((r) -> {
return r.getName().equals("client-role");
}));
roles = realmClient.realm(REALM_NAME).users().get(user1.getId()).roles().realmLevel().listAvailable();
Assertions.assertTrue(roles.isEmpty());
try {
realmClient.realm(REALM_NAME).users().get(user1.getId()).roles().realmLevel().add(realmRoleSet);
Assertions.fail("should fail with forbidden exception");
} catch (ClientErrorException e) {
Assertions.assertEquals(403, e.getResponse().getStatus());
}
}
}
// KEYCLOAK-5878
{
try (Keycloak realmClient = adminClientFactory.create()
.realm(REALM_NAME).username("groupViewer").password("password").clientId(Constants.ADMIN_CLI_CLIENT_ID).build()) {
// Should only return the list of users that belong to "top" group
List<UserRepresentation> queryUsers = realmClient.realm(REALM_NAME).users().list();
Assertions.assertEquals(queryUsers.size(), 1);
MatcherAssert.assertThat("groupmember", Matchers.equalTo(queryUsers.get(0).getUsername()));
for (UserRepresentation user : queryUsers) {
System.out.println(user.getUsername());
}
}
}
// KEYCLOAK-11261 : user creation via fine grain admin
{
try (Keycloak realmClient = adminClientFactory.create().realm(REALM_NAME)
.username("noMapperGroupManager").password("password").clientId(Constants.ADMIN_CLI_CLIENT_ID).build()) {
// Should only return the list of users that belong to "top" group
List<UserRepresentation> queryUsers = realmClient.realm(REALM_NAME).users().list();
Assertions.assertEquals(1, queryUsers.size());
UserRepresentation newGroupMemberWithoutGroup = UserConfigBuilder.create()
.username("new-group-member").email("new-group-member@keycloak.org").name("New", "Member").build();
Response response1 = realmClient.realm(REALM_NAME).users().create(newGroupMemberWithoutGroup);
Assertions.assertEquals(403, response1.getStatus());
UserRepresentation newEmptyGroupList = UserConfigBuilder.create()
.username("new-group-member").email("new-group-member@keycloak.org").name("New", "Member").build();
newEmptyGroupList.setGroups(Collections.emptyList());
Response response2 = realmClient.realm(REALM_NAME).users().create(newEmptyGroupList);
Assertions.assertEquals(403, response2.getStatus());
UserRepresentation newGroupMemberWithNonExistentGroup = UserConfigBuilder.create()
.username("new-group-member").email("new-group-member@keycloak.org").name("New", "Member").groups("wrong-group").build();
Response response3 = realmClient.realm(REALM_NAME).users().create(newGroupMemberWithNonExistentGroup);
Assertions.assertEquals(403, response3.getStatus());
UserRepresentation newGroupMemberOfNotManagedGroup = UserConfigBuilder.create()
.username("new-group-member").email("new-group-member@keycloak.org").name("New", "Member").groups("restricted-group").build();
Response response4 = realmClient.realm(REALM_NAME).users().create(newGroupMemberOfNotManagedGroup);
Assertions.assertEquals(403, response4.getStatus());
UserRepresentation newGroupMember = UserConfigBuilder.create()
.username("new-group-member").email("new-group-member@keycloak.org").name("New", "Member").groups("top").build();
ApiUtil.createUserWithAdminClient(realmClient.realm(REALM_NAME), newGroupMember);
// Should only return the list of users that belong to "top" group + the new one
queryUsers = realmClient.realm(REALM_NAME).users().list();
Assertions.assertEquals(2, queryUsers.size());
}
}
managedRealm.cleanup().add(r -> r.groups().group(groupId).remove());
}
}

View File

@ -0,0 +1,396 @@
package org.keycloak.tests.admin.finegrainedadminv1;
import org.hamcrest.Matchers;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.keycloak.admin.client.Keycloak;
import org.keycloak.authorization.AuthorizationProvider;
import org.keycloak.authorization.model.Policy;
import org.keycloak.authorization.model.ResourceServer;
import org.keycloak.models.AdminRoles;
import org.keycloak.models.ClientModel;
import org.keycloak.models.Constants;
import org.keycloak.models.GroupModel;
import org.keycloak.models.RealmModel;
import org.keycloak.models.UserCredentialModel;
import org.keycloak.models.UserModel;
import org.keycloak.models.utils.RepresentationToModel;
import org.keycloak.representations.idm.ClientRepresentation;
import org.keycloak.representations.idm.UserRepresentation;
import org.keycloak.representations.idm.authorization.UserPolicyRepresentation;
import org.keycloak.services.resources.admin.fgap.AdminPermissionManagement;
import org.keycloak.services.resources.admin.fgap.AdminPermissions;
import org.keycloak.services.resources.admin.fgap.ClientPermissionManagement;
import org.keycloak.services.resources.admin.fgap.GroupPermissionManagement;
import org.keycloak.testframework.annotations.KeycloakIntegrationTest;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.oneOf;
@KeycloakIntegrationTest(config = AbstractFineGrainedAdminTest.FineGrainedAdminServerConf.class)
public class FineGrainedAdminSearchTest extends AbstractFineGrainedAdminTest {
@Test
public void testUserPagination() {
runOnServer.run(session -> {
RealmModel realm = session.realms().getRealmByName(REALM_NAME);
session.getContext().setRealm(realm);
GroupModel customerAGroup = session.groups().createGroup(realm, "Customer A");
UserModel customerAManager = session.users().addUser(realm, "customer-a-manager");
customerAManager.setFirstName("Customer");
customerAManager.setLastName("A");
customerAManager.setEmail("customer@a");
customerAManager.credentialManager().updateCredential(UserCredentialModel.password("password"));
ClientModel realmAdminClient = realm.getClientByClientId(Constants.REALM_MANAGEMENT_CLIENT_ID);
customerAManager.grantRole(realmAdminClient.getRole(AdminRoles.QUERY_USERS));
customerAManager.setEnabled(true);
UserModel regularAdminUser = session.users().addUser(realm, "regular-admin-user");
regularAdminUser.setFirstName("Regular");
regularAdminUser.setLastName("Admin");
regularAdminUser.setEmail("regular@admin");
regularAdminUser.credentialManager().updateCredential(UserCredentialModel.password("password"));
regularAdminUser.grantRole(realmAdminClient.getRole(AdminRoles.VIEW_USERS));
regularAdminUser.setEnabled(true);
AdminPermissionManagement management = AdminPermissions.management(session, realm);
GroupPermissionManagement groupPermission = management.groups();
groupPermission.setPermissionsEnabled(customerAGroup, true);
UserPolicyRepresentation userPolicyRepresentation = new UserPolicyRepresentation();
userPolicyRepresentation.setName("Only " + customerAManager.getUsername());
userPolicyRepresentation.addUser(customerAManager.getId());
Policy policy = groupPermission.viewMembersPermission(customerAGroup);
AuthorizationProvider provider = session.getProvider(AuthorizationProvider.class);
Policy userPolicy = provider.getStoreFactory().getPolicyStore().create(management.realmResourceServer(), userPolicyRepresentation);
policy.addAssociatedPolicy(RepresentationToModel.toModel(userPolicyRepresentation, provider, userPolicy));
for (int i = 0; i < 20; i++) {
UserModel userModel = session.users().addUser(realm, "a" + i);
userModel.setFirstName("test");
}
for (int i = 20; i < 40; i++) {
UserModel userModel = session.users().addUser(realm, "b" + i);
userModel.setFirstName("test");
userModel.joinGroup(customerAGroup);
}
});
try (Keycloak client = adminClientFactory.create().realm(REALM_NAME)
.username("customer-a-manager").password("password").clientId( Constants.ADMIN_CLI_CLIENT_ID).build()) {
List<UserRepresentation> result = client.realm(REALM_NAME).users().search(null, "test", null, null, -1, 20);
Assertions.assertEquals(20, result.size());
assertThat(result, Matchers.everyItem(Matchers.hasProperty("username", Matchers.startsWith("b"))));
result = client.realm(REALM_NAME).users().search(null, "test", null, null, 20, 40);
Assertions.assertEquals(0, result.size());
}
try (Keycloak client = adminClientFactory.create().realm(REALM_NAME)
.username("regular-admin-user").password("password").clientId( Constants.ADMIN_CLI_CLIENT_ID).build()) {
List<UserRepresentation> result = client.realm(REALM_NAME).users().search(null, "test", null, null, -1, 20);
Assertions.assertEquals(20, result.size());
assertThat(result, Matchers.everyItem(Matchers.hasProperty("username", Matchers.startsWith("a"))));
client.realm(REALM_NAME).users().search(null, null, null, null, -1, -1);
Assertions.assertEquals(20, result.size());
assertThat(result, Matchers.everyItem(Matchers.hasProperty("username", Matchers.startsWith("a"))));
}
try (Keycloak client = adminClientFactory.create().realm(REALM_NAME)
.username("customer-a-manager").password("password").clientId( Constants.ADMIN_CLI_CLIENT_ID).build()) {
List<UserRepresentation> result = client.realm(REALM_NAME).users().search(null, null, null, null, -1, 20);
Assertions.assertEquals(20, result.size());
assertThat(result, Matchers.everyItem(Matchers.hasProperty("username", Matchers.startsWith("b"))));
result = client.realm(REALM_NAME).users().search("test", -1, 20, false);
Assertions.assertEquals(20, result.size());
assertThat(result, Matchers.everyItem(Matchers.hasProperty("username", Matchers.startsWith("b"))));
result = client.realm(REALM_NAME).users().search("a", -1, 20, false);
Assertions.assertEquals(0, result.size());
}
}
@Test
public void testClientsSearch() {
runOnServer.run(session -> {
RealmModel realm = session.realms().getRealmByName(REALM_NAME);
session.getContext().setRealm(realm);
ClientModel realmAdminClient = realm.getClientByClientId(Constants.REALM_MANAGEMENT_CLIENT_ID);
UserModel regularAdminUser = session.users().addUser(realm, "regular-admin-user");
regularAdminUser.setFirstName("Regular");
regularAdminUser.setLastName("Admin");
regularAdminUser.setEmail("regular@admin");
regularAdminUser.credentialManager().updateCredential(UserCredentialModel.password("password"));
regularAdminUser.grantRole(realmAdminClient.getRole(AdminRoles.QUERY_CLIENTS));
regularAdminUser.setEnabled(true);
UserPolicyRepresentation userPolicyRepresentation = new UserPolicyRepresentation();
userPolicyRepresentation.setName("Only " + regularAdminUser.getUsername());
userPolicyRepresentation.addUser(regularAdminUser.getId());
for (int i = 0; i < 30; i++) {
realm.addClient("client-search-" + (i < 10 ? "0" + i : i));
}
AdminPermissionManagement management = AdminPermissions.management(session, realm);
ClientPermissionManagement clientPermission = management.clients();
ClientModel clientModel = realm.getClientByClientId("client-search-09");
clientPermission.setPermissionsEnabled(clientModel, true);
Policy policy = clientPermission.viewPermission(clientModel);
AuthorizationProvider provider = session.getProvider(AuthorizationProvider.class);
Policy userPolicy = provider.getStoreFactory().getPolicyStore()
.create(management.realmResourceServer(), userPolicyRepresentation);
policy.addAssociatedPolicy(RepresentationToModel.toModel(userPolicyRepresentation, provider, userPolicy));
});
try (Keycloak client = adminClientFactory.create().realm(REALM_NAME)
.username("regular-admin-user").password("password").clientId( Constants.ADMIN_CLI_CLIENT_ID).build()) {
List<ClientRepresentation> result = client.realm(REALM_NAME).clients().findAll("client-search-", true, true, 0, 5);
Assertions.assertEquals(1, result.size());
Assertions.assertEquals("client-search-09", result.get(0).getClientId());
}
runOnServer.run(session -> {
RealmModel realm = session.realms().getRealmByName(REALM_NAME);
session.getContext().setRealm(realm);
AdminPermissionManagement management = AdminPermissions.management(session, realm);
ClientPermissionManagement clientPermission = management.clients();
ClientModel clientModel = realm.getClientByClientId("client-search-10");
clientPermission.setPermissionsEnabled(clientModel, true);
Policy policy = clientPermission.viewPermission(clientModel);
AuthorizationProvider provider = session.getProvider(AuthorizationProvider.class);
ClientModel realmAdminClient = realm.getClientByClientId(Constants.REALM_MANAGEMENT_CLIENT_ID);
ResourceServer resourceServer = provider.getStoreFactory().getResourceServerStore().findByClient(realmAdminClient);
policy.addAssociatedPolicy(provider.getStoreFactory().getPolicyStore().findByName(resourceServer, "Only regular-admin-user"));
});
try (Keycloak client = adminClientFactory.create().realm(REALM_NAME)
.username("regular-admin-user").password("password").clientId( Constants.ADMIN_CLI_CLIENT_ID).build()) {
List<ClientRepresentation> result = client.realm(REALM_NAME).clients().findAll("client-search-", true, true, -1, -1);
Assertions.assertEquals(2, result.size());
}
try (Keycloak client = adminClientFactory.create().realm(REALM_NAME)
.username("regular-admin-user").password("password").clientId( Constants.ADMIN_CLI_CLIENT_ID).build()) {
List<ClientRepresentation> result = client.realm(REALM_NAME).clients().findAll(null, true, false, 0, 5);
Assertions.assertEquals(2, result.size());
}
try (Keycloak client = adminClientFactory.create().realm(REALM_NAME)
.username("regular-admin-user").password("password").clientId( Constants.ADMIN_CLI_CLIENT_ID).build()) {
List<ClientRepresentation> result = client.realm(REALM_NAME).clients().findAll(null, true, false, 0, 1);
Assertions.assertEquals(1, result.size());
assertThat(result, Matchers.hasItem(Matchers.hasProperty("clientId", is("client-search-09"))));
result = client.realm(REALM_NAME).clients().findAll(null, true, false, 1, 1);
assertThat(result, Matchers.hasItem(Matchers.hasProperty("clientId", is("client-search-10"))));
Assertions.assertEquals(1, result.size());
result = client.realm(REALM_NAME).clients().findAll(null, true, false, 2, 1);
Assertions.assertTrue(result.isEmpty());
}
try (Keycloak client = adminClientFactory.create().realm(REALM_NAME)
.username("regular-admin-user").password("password").clientId( Constants.ADMIN_CLI_CLIENT_ID).build()) {
List<ClientRepresentation> result = client.realm(REALM_NAME).clients().findAll(null, true, false, -1, -1);
Assertions.assertEquals(2, result.size());
}
runOnServer.run(session -> {
RealmModel realm = session.realms().getRealmByName(REALM_NAME);
session.getContext().setRealm(realm);
AdminPermissionManagement management = AdminPermissions.management(session, realm);
ClientPermissionManagement clientPermission = management.clients();
for (int i = 11; i < 30; i++) {
ClientModel clientModel = realm.getClientByClientId("client-search-" + i);
clientPermission.setPermissionsEnabled(clientModel, true);
Policy policy = clientPermission.viewPermission(clientModel);
AuthorizationProvider provider = session.getProvider(AuthorizationProvider.class);
ClientModel realmAdminClient = realm.getClientByClientId(Constants.REALM_MANAGEMENT_CLIENT_ID);
ResourceServer resourceServer = provider.getStoreFactory().getResourceServerStore().findByClient(realmAdminClient);
policy.addAssociatedPolicy(provider.getStoreFactory().getPolicyStore()
.findByName(resourceServer, "Only regular-admin-user"));
}
});
try (Keycloak client = adminClientFactory.create().realm(REALM_NAME)
.username("regular-admin-user").password("password").clientId( Constants.ADMIN_CLI_CLIENT_ID).build()) {
List<ClientRepresentation> clients = new ArrayList<>();
List<ClientRepresentation> result = client.realm(REALM_NAME).clients().findAll("client-search-", true, true, 0, 10);
clients.addAll(result);
Assertions.assertEquals(10, result.size());
assertThat(result.stream().map(rep -> rep.getClientId()).collect(Collectors.toList()), is(Arrays.asList("client-search-09",
"client-search-10",
"client-search-11",
"client-search-12",
"client-search-13",
"client-search-14",
"client-search-15",
"client-search-16",
"client-search-17",
"client-search-18")));
result = client.realm(REALM_NAME).clients().findAll("client-search-", true, true, 10, 10);
clients.addAll(result);
Assertions.assertEquals(10, result.size());
assertThat(result.stream().map(rep -> rep.getClientId()).collect(Collectors.toList()), is(Arrays.asList("client-search-19",
"client-search-20",
"client-search-21",
"client-search-22",
"client-search-23",
"client-search-24",
"client-search-25",
"client-search-26",
"client-search-27",
"client-search-28")));
result = client.realm(REALM_NAME).clients().findAll("client-search-", true, true, 20, 10);
clients.addAll(result);
Assertions.assertEquals(1, result.size());
assertThat(result, Matchers.hasItems(
Matchers.hasProperty("clientId", is(oneOf("client-search-29")))));
}
}
@Test
public void testClientsSearchAfterFirstPage() {
runOnServer.run(session -> {
RealmModel realm = session.realms().getRealmByName(REALM_NAME);
session.getContext().setRealm(realm);
ClientModel realmAdminClient = realm.getClientByClientId(Constants.REALM_MANAGEMENT_CLIENT_ID);
UserModel regularAdminUser = session.users().addUser(realm, "regular-admin-user");
regularAdminUser.setFirstName("Regular");
regularAdminUser.setLastName("Admin");
regularAdminUser.setEmail("regular@admin");
regularAdminUser.credentialManager().updateCredential(UserCredentialModel.password("password"));
regularAdminUser.grantRole(realmAdminClient.getRole(AdminRoles.QUERY_CLIENTS));
regularAdminUser.setEnabled(true);
UserPolicyRepresentation userPolicyRepresentation = new UserPolicyRepresentation();
userPolicyRepresentation.setName("Only " + regularAdminUser.getUsername());
userPolicyRepresentation.addUser(regularAdminUser.getId());
AdminPermissionManagement management = AdminPermissions.management(session, realm);
ClientPermissionManagement clientPermission = management.clients();
for (int i = 15; i < 30; i++) {
ClientModel clientModel = realm.addClient("client-search-" + (i < 10 ? "0" + i : i));
clientPermission.setPermissionsEnabled(clientModel, true);
Policy policy = clientPermission.viewPermission(clientModel);
AuthorizationProvider provider = session.getProvider(AuthorizationProvider.class);
if (i == 15) {
provider.getStoreFactory().getPolicyStore()
.create(management.realmResourceServer(), userPolicyRepresentation);
}
policy.addAssociatedPolicy(provider.getStoreFactory().getPolicyStore()
.findByName(management.realmResourceServer(), "Only regular-admin-user"));
}
});
try (Keycloak client = adminClientFactory.create().realm(REALM_NAME)
.username("regular-admin-user").password("password").clientId( Constants.ADMIN_CLI_CLIENT_ID).build()) {
List<ClientRepresentation> clients = new ArrayList<>();
List<ClientRepresentation> result = client.realm(REALM_NAME).clients().findAll("client-search-", true, true, 0, 10);
clients.addAll(result);
Assertions.assertEquals(10, result.size());
assertThat(result.stream().map(rep -> rep.getClientId()).collect(Collectors.toList()), is(Arrays.asList(
"client-search-15",
"client-search-16",
"client-search-17",
"client-search-18",
"client-search-19",
"client-search-20",
"client-search-21",
"client-search-22",
"client-search-23",
"client-search-24")));
result = client.realm(REALM_NAME).clients().findAll("client-search-", true, true, 10, 10);
clients.addAll(result);
Assertions.assertEquals(5, result.size());
assertThat(result.stream().map(rep -> rep.getClientId()).collect(Collectors.toList()), is(Arrays.asList(
"client-search-25",
"client-search-26",
"client-search-27",
"client-search-28",
"client-search-29")));
result = client.realm(REALM_NAME).clients().findAll("client-search-", true, true, 20, 10);
clients.addAll(result);
Assertions.assertTrue(result.isEmpty());
}
}
}

View File

@ -0,0 +1,13 @@
package org.keycloak.tests.admin.finegrainedadminv1;
import org.junit.jupiter.api.Test;
import org.keycloak.testframework.annotations.KeycloakIntegrationTest;
@KeycloakIntegrationTest(config = AbstractFineGrainedAdminTest.FineGrainedAdminServerConf.class)
public class FineGrainedAdminWithTokenExchangeDisabledTest extends AbstractFineGrainedAdminTest{
@Test
public void testTokenExchangeDisabled() {
checkTokenExchange(false);
}
}

View File

@ -0,0 +1,36 @@
package org.keycloak.tests.admin.finegrainedadminv1;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.keycloak.admin.client.Keycloak;
import org.keycloak.common.Profile;
import org.keycloak.models.Constants;
import org.keycloak.testframework.annotations.KeycloakIntegrationTest;
import org.keycloak.testframework.server.KeycloakServerConfig;
import org.keycloak.testframework.server.KeycloakServerConfigBuilder;
@KeycloakIntegrationTest(config = FineGrainedAdminWithTokenExchangeTest.FineGrainedWithTokenExchangeServerConf.class)
public class FineGrainedAdminWithTokenExchangeTest extends AbstractFineGrainedAdminTest {
/**
* KEYCLOAK-7406
*/
@Test
public void testWithTokenExchange() {
String exchanged = checkTokenExchange(true);
try (Keycloak client = adminClientFactory.create()
.realm("master").authorization(exchanged).clientId(Constants.ADMIN_CLI_CLIENT_ID).build()) {
Assertions.assertNotNull(client.realm("master").roles().get("offline_access"));
}
}
public static class FineGrainedWithTokenExchangeServerConf implements KeycloakServerConfig {
@Override
public KeycloakServerConfigBuilder configure(KeycloakServerConfigBuilder config) {
config.features(Profile.Feature.TOKEN_EXCHANGE, Profile.Feature.ADMIN_FINE_GRAINED_AUTHZ);
return config;
}
}
}

View File

@ -1,11 +1,10 @@
package org.keycloak.tests.admin;
package org.keycloak.tests.admin.finegrainedadminv1;
import org.junit.jupiter.api.Test;
import org.keycloak.admin.client.Keycloak;
import org.keycloak.admin.client.KeycloakBuilder;
import org.keycloak.admin.client.resource.AuthorizationResource;
import org.keycloak.admin.client.resource.RealmResource;
import org.keycloak.common.Profile;
import org.keycloak.representations.idm.ClientRepresentation;
import org.keycloak.representations.idm.GroupRepresentation;
import org.keycloak.representations.idm.ManagementPermissionRepresentation;
@ -21,8 +20,6 @@ import org.keycloak.testframework.annotations.KeycloakIntegrationTest;
import org.keycloak.testframework.injection.LifeCycle;
import org.keycloak.testframework.realm.ManagedRealm;
import org.keycloak.testframework.realm.UserConfigBuilder;
import org.keycloak.testframework.server.KeycloakServerConfig;
import org.keycloak.testframework.server.KeycloakServerConfigBuilder;
import org.keycloak.testframework.server.KeycloakUrls;
import org.keycloak.testframework.util.ApiUtil;
@ -41,8 +38,8 @@ import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasSize;
@KeycloakIntegrationTest(config = FineGrainedPermissionsV1UsersTest.ServerConfig.class)
public class FineGrainedPermissionsV1UsersTest {
@KeycloakIntegrationTest(config = AbstractFineGrainedAdminTest.FineGrainedAdminServerConf.class)
public class FineGrainedPermissionsV1UsersTest extends AbstractFineGrainedAdminTest {
@InjectRealm(lifecycle = LifeCycle.METHOD)
ManagedRealm realm;
@ -301,13 +298,4 @@ public class FineGrainedPermissionsV1UsersTest {
return grp;
}
public static class ServerConfig implements KeycloakServerConfig {
@Override
public KeycloakServerConfigBuilder configure(KeycloakServerConfigBuilder config) {
return config.features(Profile.Feature.ADMIN_FINE_GRAINED_AUTHZ);
}
}
}