From aaf78297c954ce161d2db130d57dbc403e041a71 Mon Sep 17 00:00:00 2001 From: Pedro Igor Date: Tue, 11 Sep 2018 17:44:56 -0300 Subject: [PATCH] [KEYCLOAK-7987] - Can't set authorization enabled when using kcreg --- .../models/utils/ModelToRepresentation.java | 14 ++- .../models/utils/RepresentationToModel.java | 33 ++++++- .../admin/AuthorizationService.java | 4 +- .../admin/ResourceServerService.java | 24 +---- .../exportimport/util/ExportUtils.java | 2 +- .../exportimport/util/ImportUtils.java | 5 +- .../AbstractClientRegistrationProvider.java | 14 ++- .../oidc/DescriptionConverter.java | 3 + .../oidc/OIDCClientRegistrationProvider.java | 7 ++ .../services/managers/RealmManager.java | 17 ++++ .../resources/admin/ClientResource.java | 7 +- .../resources/admin/ClientsResource.java | 13 +-- .../admin/permissions/RealmPermissions.java | 2 +- .../authorization/AuthorizationTest.java | 24 ++++- .../cli/registration/KcRegCreateTest.java | 93 +++++++++++++++++++ .../exportimport/ExportImportUtil.java | 2 +- .../DefaultAuthorizationSettingsTest.java | 2 +- .../testsuite/model/ClientModelTest.java | 2 +- 18 files changed, 214 insertions(+), 54 deletions(-) diff --git a/server-spi-private/src/main/java/org/keycloak/models/utils/ModelToRepresentation.java b/server-spi-private/src/main/java/org/keycloak/models/utils/ModelToRepresentation.java index 0b75af39a9..dd7eef72bb 100755 --- a/server-spi-private/src/main/java/org/keycloak/models/utils/ModelToRepresentation.java +++ b/server-spi-private/src/main/java/org/keycloak/models/utils/ModelToRepresentation.java @@ -17,8 +17,6 @@ package org.keycloak.models.utils; -import com.fasterxml.jackson.core.type.TypeReference; -import java.io.IOException; import org.keycloak.authorization.AuthorizationProvider; import org.keycloak.authorization.model.PermissionTicket; import org.keycloak.authorization.model.Policy; @@ -26,6 +24,7 @@ import org.keycloak.authorization.model.Resource; import org.keycloak.authorization.model.ResourceServer; import org.keycloak.authorization.model.Scope; import org.keycloak.authorization.policy.provider.PolicyProviderFactory; +import org.keycloak.common.Profile; import org.keycloak.common.util.MultivaluedHashMap; import org.keycloak.common.util.Time; import org.keycloak.component.ComponentModel; @@ -490,7 +489,7 @@ public class ModelToRepresentation { } - public static ClientRepresentation toRepresentation(ClientModel clientModel) { + public static ClientRepresentation toRepresentation(ClientModel clientModel, KeycloakSession session) { ClientRepresentation rep = new ClientRepresentation(); rep.setId(clientModel.getId()); String providerId = StorageId.resolveProviderId(clientModel); @@ -548,6 +547,15 @@ public class ModelToRepresentation { rep.setProtocolMappers(mappings); } + if (Profile.isFeatureEnabled(Profile.Feature.AUTHORIZATION)) { + AuthorizationProvider authorization = session.getProvider(AuthorizationProvider.class); + ResourceServer resourceServer = authorization.getStoreFactory().getResourceServerStore().findById(clientModel.getId()); + + if (resourceServer != null) { + rep.setAuthorizationServicesEnabled(true); + } + } + return rep; } diff --git a/server-spi-private/src/main/java/org/keycloak/models/utils/RepresentationToModel.java b/server-spi-private/src/main/java/org/keycloak/models/utils/RepresentationToModel.java index 58c1dcf7bd..4081661a7e 100755 --- a/server-spi-private/src/main/java/org/keycloak/models/utils/RepresentationToModel.java +++ b/server-spi-private/src/main/java/org/keycloak/models/utils/RepresentationToModel.java @@ -47,6 +47,7 @@ import org.keycloak.authorization.store.ResourceServerStore; import org.keycloak.authorization.store.ResourceStore; import org.keycloak.authorization.store.ScopeStore; import org.keycloak.authorization.store.StoreFactory; +import org.keycloak.common.Profile; import org.keycloak.common.enums.SslRequired; import org.keycloak.common.util.Base64; import org.keycloak.common.util.MultivaluedHashMap; @@ -1248,6 +1249,7 @@ public class RepresentationToModel { } client.updateClient(); + resourceRep.setId(client.getId()); return client; } @@ -1990,7 +1992,7 @@ public class RepresentationToModel { } } - public static void toModel(ResourceServerRepresentation rep, AuthorizationProvider authorization) { + public static ResourceServer toModel(ResourceServerRepresentation rep, AuthorizationProvider authorization) { ResourceServerStore resourceServerStore = authorization.getStoreFactory().getResourceServerStore(); ResourceServer resourceServer; ResourceServer existing = resourceServerStore.findById(rep.getClientId()); @@ -2032,6 +2034,8 @@ public class RepresentationToModel { } importPolicies(authorization, resourceServer, rep.getPolicies(), null); + + return resourceServer; } private static Policy importPolicies(AuthorizationProvider authorization, ResourceServer resourceServer, List policiesToImport, String parentPolicyName) { @@ -2560,4 +2564,31 @@ public class RepresentationToModel { return m; } + public static ResourceServer createResourceServer(ClientModel client, KeycloakSession session, boolean addDefaultRoles) { + AuthorizationProvider authorization = session.getProvider(AuthorizationProvider.class); + UserModel serviceAccount = session.users().getServiceAccount(client); + + if (serviceAccount == null) { + client.setServiceAccountsEnabled(true); + } + + if (addDefaultRoles) { + RoleModel umaProtectionRole = client.getRole(Constants.AUTHZ_UMA_PROTECTION); + + if (umaProtectionRole == null) { + umaProtectionRole = client.addRole(Constants.AUTHZ_UMA_PROTECTION); + } + + if (serviceAccount != null) { + serviceAccount.grantRole(umaProtectionRole); + } + } + + ResourceServerRepresentation representation = new ResourceServerRepresentation(); + + representation.setAllowRemoteResourceManagement(true); + representation.setClientId(client.getId()); + + return toModel(representation, authorization); + } } diff --git a/services/src/main/java/org/keycloak/authorization/admin/AuthorizationService.java b/services/src/main/java/org/keycloak/authorization/admin/AuthorizationService.java index 72772e29da..e141784a5d 100644 --- a/services/src/main/java/org/keycloak/authorization/admin/AuthorizationService.java +++ b/services/src/main/java/org/keycloak/authorization/admin/AuthorizationService.java @@ -57,9 +57,7 @@ public class AuthorizationService { } public void enable(boolean newClient) { - if (!isEnabled()) { - this.resourceServer = resourceServer().create(newClient); - } + this.resourceServer = resourceServer().create(newClient); } public void disable() { diff --git a/services/src/main/java/org/keycloak/authorization/admin/ResourceServerService.java b/services/src/main/java/org/keycloak/authorization/admin/ResourceServerService.java index 9bdb352623..c31d393ead 100644 --- a/services/src/main/java/org/keycloak/authorization/admin/ResourceServerService.java +++ b/services/src/main/java/org/keycloak/authorization/admin/ResourceServerService.java @@ -38,9 +38,7 @@ import org.keycloak.events.admin.OperationType; import org.keycloak.events.admin.ResourceType; import org.keycloak.exportimport.util.ExportUtils; import org.keycloak.models.ClientModel; -import org.keycloak.models.Constants; import org.keycloak.models.KeycloakSession; -import org.keycloak.models.RoleModel; import org.keycloak.models.UserModel; import org.keycloak.models.utils.ModelToRepresentation; import org.keycloak.models.utils.RepresentationToModel; @@ -77,10 +75,6 @@ public class ResourceServerService { } public ResourceServer create(boolean newClient) { - if (resourceServer != null) { - throw new IllegalStateException("Resource server already created"); - } - this.auth.realm().requireManageAuthorization(); UserModel serviceAccount = this.session.users().getServiceAccount(client); @@ -89,8 +83,10 @@ public class ResourceServerService { throw new RuntimeException("Client does not have a service account."); } - this.resourceServer = this.authorization.getStoreFactory().getResourceServerStore().create(this.client.getId()); - createDefaultRoles(serviceAccount); + if (this.resourceServer == null) { + this.resourceServer = RepresentationToModel.createResourceServer(client, session, true); + } + createDefaultPermission(createDefaultResource(), createDefaultPolicy()); audit(OperationType.CREATE, session.getContext().getUri(), newClient); @@ -226,18 +222,6 @@ public class ResourceServerService { return defaultResource; } - private void createDefaultRoles(UserModel serviceAccount) { - RoleModel umaProtectionRole = client.getRole(Constants.AUTHZ_UMA_PROTECTION); - - if (umaProtectionRole == null) { - umaProtectionRole = client.addRole(Constants.AUTHZ_UMA_PROTECTION); - } - - if (!serviceAccount.hasRole(umaProtectionRole)) { - serviceAccount.grantRole(umaProtectionRole); - } - } - private void audit(OperationType operation, UriInfo uriInfo, boolean newClient) { if (newClient) { adminEvent.resource(ResourceType.AUTHORIZATION_RESOURCE_SERVER).operation(operation).resourcePath(uriInfo, client.getId()) diff --git a/services/src/main/java/org/keycloak/exportimport/util/ExportUtils.java b/services/src/main/java/org/keycloak/exportimport/util/ExportUtils.java index 5b9fb901fe..652cda2b8b 100755 --- a/services/src/main/java/org/keycloak/exportimport/util/ExportUtils.java +++ b/services/src/main/java/org/keycloak/exportimport/util/ExportUtils.java @@ -299,7 +299,7 @@ public class ExportUtils { * @return full ApplicationRepresentation */ public static ClientRepresentation exportClient(KeycloakSession session, ClientModel client) { - ClientRepresentation clientRep = ModelToRepresentation.toRepresentation(client); + ClientRepresentation clientRep = ModelToRepresentation.toRepresentation(client, session); clientRep.setSecret(client.getSecret()); clientRep.setAuthorizationSettings(exportAuthorizationSettings(session,client)); return clientRep; diff --git a/services/src/main/java/org/keycloak/exportimport/util/ImportUtils.java b/services/src/main/java/org/keycloak/exportimport/util/ImportUtils.java index 0996c9cd54..7eb44cf3b9 100755 --- a/services/src/main/java/org/keycloak/exportimport/util/ImportUtils.java +++ b/services/src/main/java/org/keycloak/exportimport/util/ImportUtils.java @@ -23,6 +23,7 @@ import com.fasterxml.jackson.core.JsonToken; import com.fasterxml.jackson.databind.ObjectMapper; import org.jboss.logging.Logger; import org.keycloak.Config; +import org.keycloak.common.constants.ServiceAccountConstants; import org.keycloak.exportimport.ExportImportConfig; import org.keycloak.exportimport.Strategy; import org.keycloak.models.KeycloakSession; @@ -261,7 +262,9 @@ public class ImportUtils { private static void importUsers(KeycloakSession session, RealmProvider model, String realmName, List userReps) { RealmModel realm = model.getRealmByName(realmName); for (UserRepresentation user : userReps) { - RepresentationToModel.createUser(session, realm, user); + if (!user.getUsername().startsWith(ServiceAccountConstants.SERVICE_ACCOUNT_USER_PREFIX)) { + RepresentationToModel.createUser(session, realm, user); + } } } diff --git a/services/src/main/java/org/keycloak/services/clientregistration/AbstractClientRegistrationProvider.java b/services/src/main/java/org/keycloak/services/clientregistration/AbstractClientRegistrationProvider.java index 0f6ec8f589..bbd10a9229 100755 --- a/services/src/main/java/org/keycloak/services/clientregistration/AbstractClientRegistrationProvider.java +++ b/services/src/main/java/org/keycloak/services/clientregistration/AbstractClientRegistrationProvider.java @@ -71,9 +71,17 @@ public abstract class AbstractClientRegistrationProvider implements ClientRegist RealmModel realm = session.getContext().getRealm(); ClientModel clientModel = new ClientManager(new RealmManager(session)).createClient(session, realm, client, true); + if (clientModel.isServiceAccountsEnabled()) { + new ClientManager(new RealmManager(session)).enableServiceAccount(clientModel); + } + + if (Boolean.TRUE.equals(client.getAuthorizationServicesEnabled())) { + RepresentationToModel.createResourceServer(clientModel, session, true); + } + ClientRegistrationPolicyManager.triggerAfterRegister(context, registrationAuth, clientModel); - client = ModelToRepresentation.toRepresentation(clientModel); + client = ModelToRepresentation.toRepresentation(clientModel, session); client.setSecret(clientModel.getSecret()); @@ -98,7 +106,7 @@ public abstract class AbstractClientRegistrationProvider implements ClientRegist ClientModel client = session.getContext().getRealm().getClientByClientId(clientId); auth.requireView(client); - ClientRepresentation rep = ModelToRepresentation.toRepresentation(client); + ClientRepresentation rep = ModelToRepresentation.toRepresentation(client, session); if (client.getSecret() != null) { rep.setSecret(client.getSecret()); } @@ -135,7 +143,7 @@ public abstract class AbstractClientRegistrationProvider implements ClientRegist } RepresentationToModel.updateClient(rep, client); - rep = ModelToRepresentation.toRepresentation(client); + rep = ModelToRepresentation.toRepresentation(client, session); if (auth.isRegistrationAccessToken()) { String registrationAccessToken = ClientRegistrationTokenUtils.updateRegistrationAccessToken(session, client, auth.getRegistrationAuth()); diff --git a/services/src/main/java/org/keycloak/services/clientregistration/oidc/DescriptionConverter.java b/services/src/main/java/org/keycloak/services/clientregistration/oidc/DescriptionConverter.java index 519fe2adc0..2cae02c0bc 100644 --- a/services/src/main/java/org/keycloak/services/clientregistration/oidc/DescriptionConverter.java +++ b/services/src/main/java/org/keycloak/services/clientregistration/oidc/DescriptionConverter.java @@ -253,6 +253,9 @@ public class DescriptionConverter { if (client.isServiceAccountsEnabled()) { grantTypes.add(OAuth2Constants.CLIENT_CREDENTIALS); } + if (client.getAuthorizationServicesEnabled() != null && client.getAuthorizationServicesEnabled()) { + grantTypes.add(OAuth2Constants.UMA_GRANT_TYPE); + } grantTypes.add(OAuth2Constants.REFRESH_TOKEN); return grantTypes; } diff --git a/services/src/main/java/org/keycloak/services/clientregistration/oidc/OIDCClientRegistrationProvider.java b/services/src/main/java/org/keycloak/services/clientregistration/oidc/OIDCClientRegistrationProvider.java index 3dd657f38a..246d60efe5 100755 --- a/services/src/main/java/org/keycloak/services/clientregistration/oidc/OIDCClientRegistrationProvider.java +++ b/services/src/main/java/org/keycloak/services/clientregistration/oidc/OIDCClientRegistrationProvider.java @@ -17,6 +17,7 @@ package org.keycloak.services.clientregistration.oidc; import org.jboss.logging.Logger; +import org.keycloak.OAuth2Constants; import org.keycloak.common.util.Time; import org.keycloak.models.ClientModel; import org.keycloak.models.KeycloakSession; @@ -72,6 +73,12 @@ public class OIDCClientRegistrationProvider extends AbstractClientRegistrationPr try { ClientRepresentation client = DescriptionConverter.toInternal(session, clientOIDC); + List grantTypes = clientOIDC.getGrantTypes(); + + if (grantTypes != null && grantTypes.contains(OAuth2Constants.UMA_GRANT_TYPE)) { + client.setAuthorizationServicesEnabled(true); + } + OIDCClientRegistrationContext oidcContext = new OIDCClientRegistrationContext(session, client, this, clientOIDC); client = create(oidcContext); diff --git a/services/src/main/java/org/keycloak/services/managers/RealmManager.java b/services/src/main/java/org/keycloak/services/managers/RealmManager.java index b12e2eca20..e1c0f14bd0 100755 --- a/services/src/main/java/org/keycloak/services/managers/RealmManager.java +++ b/services/src/main/java/org/keycloak/services/managers/RealmManager.java @@ -507,6 +507,23 @@ public class RealmManager { } RepresentationToModel.importRealm(session, rep, realm, skipUserDependent); + List clients = rep.getClients(); + + if (clients != null) { + ClientManager clientManager = new ClientManager(new RealmManager(session)); + + for (ClientRepresentation client : clients) { + ClientModel clientModel = realm.getClientById(client.getId()); + + if (clientModel.isServiceAccountsEnabled()) { + clientManager.enableServiceAccount(clientModel); + } + + if (Boolean.TRUE.equals(client.getAuthorizationServicesEnabled())) { + RepresentationToModel.createResourceServer(clientModel, session, true); + } + } + } setupAdminConsoleLocaleMapper(realm); diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ClientResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ClientResource.java index 1baf71066b..a03eea5d29 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/ClientResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/ClientResource.java @@ -170,11 +170,8 @@ public class ClientResource { public ClientRepresentation getClient() { auth.clients().requireView(client); - ClientRepresentation representation = ModelToRepresentation.toRepresentation(client); + ClientRepresentation representation = ModelToRepresentation.toRepresentation(client, session); - if (Profile.isFeatureEnabled(Profile.Feature.AUTHORIZATION)) { - representation.setAuthorizationServicesEnabled(authorization().isEnabled()); - } representation.setAccess(auth.clients().getAccess(client)); return representation; @@ -253,7 +250,7 @@ public class ClientResource { String token = ClientRegistrationTokenUtils.updateRegistrationAccessToken(session, realm, client, RegistrationAuth.AUTHENTICATED); - ClientRepresentation rep = ModelToRepresentation.toRepresentation(client); + ClientRepresentation rep = ModelToRepresentation.toRepresentation(client, session); rep.setRegistrationAccessToken(token); adminEvent.operation(OperationType.ACTION).resourcePath(session.getContext().getUri()).representation(rep).success(); diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ClientsResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ClientsResource.java index 1ab8d3e587..4b7079c360 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/ClientsResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/ClientsResource.java @@ -104,16 +104,7 @@ public class ClientsResource { boolean view = auth.clients().canView(); for (ClientModel clientModel : clientModels) { if (view || auth.clients().canView(clientModel)) { - ClientRepresentation representation = ModelToRepresentation.toRepresentation(clientModel); - - if (Profile.isFeatureEnabled(Profile.Feature.AUTHORIZATION)) { - AuthorizationService authorizationService = getAuthorizationService(clientModel); - - if (authorizationService.isEnabled()) { - representation.setAuthorizationServicesEnabled(true); - } - } - + ClientRepresentation representation = ModelToRepresentation.toRepresentation(clientModel, session); rep.add(representation); representation.setAccess(auth.clients().getAccess(clientModel)); } else if (!viewableOnly) { @@ -128,7 +119,7 @@ public class ClientsResource { ClientModel clientModel = realm.getClientByClientId(clientId); if (clientModel != null) { if (auth.clients().canView(clientModel)) { - ClientRepresentation representation = ModelToRepresentation.toRepresentation(clientModel); + ClientRepresentation representation = ModelToRepresentation.toRepresentation(clientModel, session); representation.setAccess(auth.clients().getAccess(clientModel)); rep.add(representation); } else if (!viewableOnly && auth.clients().canList()){ diff --git a/services/src/main/java/org/keycloak/services/resources/admin/permissions/RealmPermissions.java b/services/src/main/java/org/keycloak/services/resources/admin/permissions/RealmPermissions.java index 3fc752fd0b..ce04d6d7c1 100644 --- a/services/src/main/java/org/keycloak/services/resources/admin/permissions/RealmPermissions.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/permissions/RealmPermissions.java @@ -62,7 +62,7 @@ class RealmPermissions implements RealmPermissionEvaluator { } public boolean canManageAuthorizationDefault() { - return root.hasOneAdminRole(AdminRoles.MANAGE_AUTHORIZATION); + return root.hasOneAdminRole(AdminRoles.MANAGE_AUTHORIZATION, AdminRoles.MANAGE_CLIENTS); } public boolean canViewAuthorizationDefault() { diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/authorization/AuthorizationTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/authorization/AuthorizationTest.java index f642979893..89dd1b661e 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/authorization/AuthorizationTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/authorization/AuthorizationTest.java @@ -18,12 +18,16 @@ package org.keycloak.testsuite.admin.client.authorization; +import org.junit.Assert; import org.junit.Test; import org.keycloak.admin.client.resource.ClientResource; import org.keycloak.admin.client.resource.RealmResource; +import org.keycloak.common.constants.ServiceAccountConstants; import org.keycloak.representations.adapters.config.PolicyEnforcerConfig; 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.representations.idm.authorization.JSPolicyRepresentation; import org.keycloak.representations.idm.authorization.PolicyRepresentation; import org.keycloak.representations.idm.authorization.ResourceRepresentation; @@ -44,11 +48,21 @@ public class AuthorizationTest extends AbstractAuthorizationTest { public void testEnableAuthorizationServices() { ClientResource clientResource = getClientResource(); ClientRepresentation resourceServer = getResourceServer(); + RealmResource realm = realmsResouce().realm(getRealmId()); + + UserRepresentation serviceAccount = realm.users().search(ServiceAccountConstants.SERVICE_ACCOUNT_USER_PREFIX + resourceServer.getClientId()).get(0); + Assert.assertNotNull(serviceAccount); + List serviceAccountRoles = realm.users().get(serviceAccount.getId()).roles().clientLevel(resourceServer.getId()).listAll(); + Assert.assertTrue(serviceAccountRoles.stream().anyMatch(roleRepresentation -> "uma_protection".equals(roleRepresentation.getName()))); enableAuthorizationServices(false); enableAuthorizationServices(true); - clientResource.authorization().resources().create(new ResourceRepresentation("Should be removed")); + serviceAccount = clientResource.getServiceAccountUser(); + Assert.assertNotNull(serviceAccount); + realm = realmsResouce().realm(getRealmId()); + serviceAccountRoles = realm.users().get(serviceAccount.getId()).roles().clientLevel(resourceServer.getId()).listAll(); + Assert.assertTrue(serviceAccountRoles.stream().anyMatch(roleRepresentation -> "uma_protection".equals(roleRepresentation.getName()))); JSPolicyRepresentation policy = new JSPolicyRepresentation(); @@ -59,7 +73,7 @@ public class AuthorizationTest extends AbstractAuthorizationTest { List defaultResources = clientResource.authorization().resources().resources(); - assertEquals(2, defaultResources.size()); + assertEquals(1, defaultResources.size()); List defaultPolicies = clientResource.authorization().policies().policies(); @@ -71,6 +85,7 @@ public class AuthorizationTest extends AbstractAuthorizationTest { ResourceServerRepresentation settings = clientResource.authorization().getSettings(); assertEquals(PolicyEnforcerConfig.EnforcementMode.ENFORCING.name(), settings.getPolicyEnforcementMode().name()); + assertTrue(settings.isAllowRemoteResourceManagement()); assertEquals(resourceServer.getId(), settings.getClientId()); defaultResources = clientResource.authorization().resources().resources(); @@ -79,6 +94,11 @@ public class AuthorizationTest extends AbstractAuthorizationTest { defaultPolicies = clientResource.authorization().policies().policies(); assertEquals(2, defaultPolicies.size()); + + serviceAccount = clientResource.getServiceAccountUser(); + Assert.assertNotNull(serviceAccount); + serviceAccountRoles = realm.users().get(serviceAccount.getId()).roles().clientLevel(resourceServer.getId()).listAll(); + Assert.assertTrue(serviceAccountRoles.stream().anyMatch(roleRepresentation -> "uma_protection".equals(roleRepresentation.getName()))); } // KEYCLOAK-6321 diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cli/registration/KcRegCreateTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cli/registration/KcRegCreateTest.java index 40783a43a1..fa5a1dfcfb 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cli/registration/KcRegCreateTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cli/registration/KcRegCreateTest.java @@ -1,10 +1,20 @@ package org.keycloak.testsuite.cli.registration; +import org.hamcrest.Matchers; import org.junit.Assert; import org.junit.Test; +import org.keycloak.OAuth2Constants; +import org.keycloak.admin.client.resource.ClientResource; +import org.keycloak.admin.client.resource.ClientsResource; +import org.keycloak.admin.client.resource.RealmResource; import org.keycloak.client.registration.cli.config.ConfigData; import org.keycloak.client.registration.cli.config.FileConfigHandler; +import org.keycloak.common.constants.ServiceAccountConstants; import org.keycloak.representations.idm.ClientRepresentation; +import org.keycloak.representations.idm.RoleRepresentation; +import org.keycloak.representations.idm.UserRepresentation; +import org.keycloak.representations.idm.authorization.PolicyEnforcementMode; +import org.keycloak.representations.idm.authorization.ResourceServerRepresentation; import org.keycloak.representations.oidc.OIDCClientRepresentation; import org.keycloak.testsuite.cli.KcRegExec; import org.keycloak.testsuite.util.TempFileResource; @@ -13,6 +23,7 @@ import org.keycloak.util.JsonSerialization; import java.io.File; import java.io.IOException; import java.util.Arrays; +import java.util.List; import static org.keycloak.testsuite.cli.KcRegExec.execute; @@ -215,4 +226,86 @@ public class KcRegCreateTest extends AbstractRegCliTest { Assert.assertNull("initial token == null", config.ensureRealmConfigData(serverUrl, realm).getInitialToken()); } } + + @Test + public void testCreateWithAuthorizationServices() throws IOException { + FileConfigHandler handler = initCustomConfigFile(); + + try (TempFileResource configFile = new TempFileResource(handler.getConfigFile())) { + + KcRegExec exe = execute("config credentials -x --config '" + configFile.getName() + + "' --server " + serverUrl + " --realm master --user admin --password admin"); + assertExitCodeAndStreamSizes(exe, 0, 0, 1); + + String token = issueInitialAccessToken("test"); + exe = execute("create --config '" + configFile.getName() + "' --server " + serverUrl + " --realm test -s clientId=authz-client -s authorizationServicesEnabled=true -t " + token); + assertExitCodeAndStreamSizes(exe, 0, 0, 1); + + RealmResource realm = adminClient.realm("test"); + ClientsResource clients = realm.clients(); + ClientRepresentation clientRep = clients.findByClientId("authz-client").get(0); + + ClientResource client = clients.get(clientRep.getId()); + + clientRep = client.toRepresentation(); + Assert.assertTrue(clientRep.getAuthorizationServicesEnabled()); + + ResourceServerRepresentation settings = client.authorization().getSettings(); + + Assert.assertEquals(PolicyEnforcementMode.ENFORCING, settings.getPolicyEnforcementMode()); + Assert.assertTrue(settings.isAllowRemoteResourceManagement()); + + List roles = client.roles().list(); + + Assert.assertEquals(1, roles.size()); + Assert.assertEquals("uma_protection", roles.get(0).getName()); + + // create using oidc endpoint - autodetect format + String content = " {\n" + + " \"redirect_uris\" : [ \"http://localhost:8980/myapp/*\" ],\n" + + " \"grant_types\" : [ \"authorization_code\", \"client_credentials\", \"refresh_token\", \"" + OAuth2Constants.UMA_GRANT_TYPE + "\" ],\n" + + " \"response_types\" : [ \"code\", \"none\" ],\n" + + " \"client_name\" : \"My Reg Authz\",\n" + + " \"client_uri\" : \"http://localhost:8980/myapp\"\n" + + " }"; + + try (TempFileResource tmpFile = new TempFileResource(initTempFile(".json", content))) { + + exe = execute("create --config '" + configFile.getName() + "' -s 'client_name=My Reg Authz' --realm test -t " + token + + " -s 'redirect_uris=[\"http://localhost:8980/myapp5/*\"]' -s client_uri=http://localhost:8980/myapp5" + + " -o -f - < '" + tmpFile.getName() + "'"); + + assertExitCodeAndStdErrSize(exe, 0, 0); + + OIDCClientRepresentation oidcClient = JsonSerialization.readValue(exe.stdout(), OIDCClientRepresentation.class); + + Assert.assertNotNull("clientId", oidcClient.getClientId()); + Assert.assertEquals("redirect_uris", Arrays.asList("http://localhost:8980/myapp5/*"), oidcClient.getRedirectUris()); + Assert.assertThat("grant_types", oidcClient.getGrantTypes(), Matchers.containsInAnyOrder("authorization_code", "client_credentials", "refresh_token", OAuth2Constants.UMA_GRANT_TYPE)); + Assert.assertEquals("response_types", Arrays.asList("code", "none"), oidcClient.getResponseTypes()); + Assert.assertEquals("client_name", "My Reg Authz", oidcClient.getClientName()); + Assert.assertEquals("client_uri", "http://localhost:8980/myapp5", oidcClient.getClientUri()); + + client = clients.get(oidcClient.getClientId()); + + clientRep = client.toRepresentation(); + Assert.assertTrue(clientRep.getAuthorizationServicesEnabled()); + + settings = client.authorization().getSettings(); + + Assert.assertEquals(PolicyEnforcementMode.ENFORCING, settings.getPolicyEnforcementMode()); + Assert.assertTrue(settings.isAllowRemoteResourceManagement()); + + roles = client.roles().list(); + + Assert.assertEquals(1, roles.size()); + Assert.assertEquals("uma_protection", roles.get(0).getName()); + + UserRepresentation serviceAccount = realm.users().search(ServiceAccountConstants.SERVICE_ACCOUNT_USER_PREFIX + clientRep.getClientId()).get(0); + Assert.assertNotNull(serviceAccount); + List serviceAccountRoles = realm.users().get(serviceAccount.getId()).roles().clientLevel(clientRep.getId()).listAll(); + Assert.assertTrue(serviceAccountRoles.stream().anyMatch(roleRepresentation -> "uma_protection".equals(roleRepresentation.getName()))); + } + } + } } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/exportimport/ExportImportUtil.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/exportimport/ExportImportUtil.java index ec8455f36a..f0a58f22d4 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/exportimport/ExportImportUtil.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/exportimport/ExportImportUtil.java @@ -315,7 +315,7 @@ public class ExportImportUtil { Assert.assertNull(findMapperByName(applicationMappers, OIDCLoginProtocol.LOGIN_PROTOCOL, "given name")); Assert.assertNull(findMapperByName(applicationMappers, OIDCLoginProtocol.LOGIN_PROTOCOL, KerberosConstants.GSS_DELEGATION_CREDENTIAL_DISPLAY_NAME)); - Assert.assertEquals(1, otherApp.getProtocolMappers().size()); + Assert.assertEquals(4, otherApp.getProtocolMappers().size()); List otherAppMappers = otherApp.getProtocolMappers(); Assert.assertNull(findMapperByName(otherAppMappers, OIDCLoginProtocol.LOGIN_PROTOCOL, "username")); ProtocolMapperRepresentation gssCredentialMapper = findMapperByName(otherAppMappers, OIDCLoginProtocol.LOGIN_PROTOCOL, KerberosConstants.GSS_DELEGATION_CREDENTIAL_DISPLAY_NAME); diff --git a/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/DefaultAuthorizationSettingsTest.java b/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/DefaultAuthorizationSettingsTest.java index f4b5b68595..c493b10b11 100644 --- a/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/DefaultAuthorizationSettingsTest.java +++ b/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/DefaultAuthorizationSettingsTest.java @@ -40,7 +40,7 @@ public class DefaultAuthorizationSettingsTest extends AbstractAuthorizationSetti AuthorizationSettingsForm settings = authorizationPage.settings(); assertEquals(PolicyEnforcerConfig.EnforcementMode.ENFORCING, settings.getEnforcementMode()); - assertEquals(false, settings.isAllowRemoteResourceManagement()); + assertEquals(true, settings.isAllowRemoteResourceManagement()); Resources resources = authorizationPage.authorizationTabs().resources(); ResourceRepresentation resource = resources.resources().findByName("Default Resource"); diff --git a/testsuite/integration-deprecated/src/test/java/org/keycloak/testsuite/model/ClientModelTest.java b/testsuite/integration-deprecated/src/test/java/org/keycloak/testsuite/model/ClientModelTest.java index 959c3f5dde..5c2e2e5598 100755 --- a/testsuite/integration-deprecated/src/test/java/org/keycloak/testsuite/model/ClientModelTest.java +++ b/testsuite/integration-deprecated/src/test/java/org/keycloak/testsuite/model/ClientModelTest.java @@ -179,7 +179,7 @@ public class ClientModelTest extends AbstractModelTest { @Test public void json() { - ClientRepresentation representation = ModelToRepresentation.toRepresentation(client); + ClientRepresentation representation = ModelToRepresentation.toRepresentation(client, session); representation.setId(null); for (ProtocolMapperRepresentation protocolMapper : representation.getProtocolMappers()) { protocolMapper.setId(null);