From f1ddd5016fb8e9c96ba929ef028e5ee4e0637b3f Mon Sep 17 00:00:00 2001 From: Leon Graser Date: Fri, 22 Nov 2019 17:02:06 +0100 Subject: [PATCH] KEYCLOAK-11821 Add account api roles to the client on creation Co-authored-by: stianst --- .../migration/migrators/MigrateTo9_0_0.java | 19 +++++++++++++++++- .../services/managers/RealmManager.java | 8 ++++++++ .../keycloak/testsuite/admin/ClientTest.java | 6 ++++-- .../migration/AbstractMigrationTest.java | 20 +++++++++++++++++++ .../account/messages/messages_en.properties | 2 ++ 5 files changed, 52 insertions(+), 3 deletions(-) diff --git a/server-spi-private/src/main/java/org/keycloak/migration/migrators/MigrateTo9_0_0.java b/server-spi-private/src/main/java/org/keycloak/migration/migrators/MigrateTo9_0_0.java index e0bce1b464..cddb7f5bc0 100644 --- a/server-spi-private/src/main/java/org/keycloak/migration/migrators/MigrateTo9_0_0.java +++ b/server-spi-private/src/main/java/org/keycloak/migration/migrators/MigrateTo9_0_0.java @@ -25,6 +25,7 @@ import org.keycloak.models.Constants; import org.keycloak.models.KeycloakSession; import org.keycloak.models.ProtocolMapperModel; import org.keycloak.models.RealmModel; +import org.keycloak.models.RoleModel; import org.keycloak.models.utils.KeycloakModelUtils; import org.keycloak.representations.idm.RealmRepresentation; @@ -45,7 +46,7 @@ public class MigrateTo9_0_0 implements Migration { @Override public void migrate(KeycloakSession session) { - session.realms().getRealms().stream().forEach(realm -> addAccountConsoleClient(realm)); + session.realms().getRealms().stream().forEach(realm -> migrateRealmCommon(realm)); } @Override @@ -55,6 +56,22 @@ public class MigrateTo9_0_0 implements Migration { protected void migrateRealmCommon(RealmModel realm) { addAccountConsoleClient(realm); + addAccountApiRoles(realm); + } + + private void addAccountApiRoles(RealmModel realm) { + ClientModel accountClient = realm.getClientByClientId(Constants.ACCOUNT_MANAGEMENT_CLIENT_ID); + RoleModel viewAppRole = accountClient.addRole(AccountRoles.VIEW_APPLICATIONS); + viewAppRole.setDescription("${role_" + AccountRoles.VIEW_APPLICATIONS + "}"); + LOG.debugf("Added the role %s to the '%s' client.", AccountRoles.VIEW_APPLICATIONS, Constants.ACCOUNT_MANAGEMENT_CLIENT_ID); + RoleModel viewConsentRole = accountClient.addRole(AccountRoles.VIEW_CONSENT); + viewConsentRole.setDescription("${role_" + AccountRoles.VIEW_CONSENT + "}"); + LOG.debugf("Added the role %s to the '%s' client.", AccountRoles.VIEW_CONSENT, Constants.ACCOUNT_MANAGEMENT_CLIENT_ID); + RoleModel manageConsentRole = accountClient.addRole(AccountRoles.MANAGE_CONSENT); + manageConsentRole.setDescription("${role_" + AccountRoles.MANAGE_CONSENT + "}"); + LOG.debugf("Added the role %s to the '%s' client.", AccountRoles.MANAGE_CONSENT, Constants.ACCOUNT_MANAGEMENT_CLIENT_ID); + manageConsentRole.addCompositeRole(viewConsentRole); + LOG.debugf("Added the %s role as a composite role to %s", AccountRoles.VIEW_CONSENT, AccountRoles.MANAGE_CONSENT); } protected void addAccountConsoleClient(RealmModel realm) { 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 18114939cd..b7b40999e4 100755 --- a/services/src/main/java/org/keycloak/services/managers/RealmManager.java +++ b/services/src/main/java/org/keycloak/services/managers/RealmManager.java @@ -17,6 +17,7 @@ package org.keycloak.services.managers; import org.keycloak.Config; +import org.keycloak.common.Profile; import org.keycloak.common.enums.SslRequired; import org.keycloak.migration.MigrationModelManager; import org.keycloak.models.AccountRoles; @@ -428,6 +429,13 @@ public class RealmManager { manageAccountLinks.setDescription("${role_" + AccountRoles.MANAGE_ACCOUNT_LINKS + "}"); RoleModel manageAccount = accountClient.getRole(AccountRoles.MANAGE_ACCOUNT); manageAccount.addCompositeRole(manageAccountLinks); + RoleModel viewAppRole = accountClient.addRole(AccountRoles.VIEW_APPLICATIONS); + viewAppRole.setDescription("${role_" + AccountRoles.VIEW_APPLICATIONS + "}"); + RoleModel viewConsentRole = accountClient.addRole(AccountRoles.VIEW_CONSENT); + viewConsentRole.setDescription("${role_" + AccountRoles.VIEW_CONSENT + "}"); + RoleModel manageConsentRole = accountClient.addRole(AccountRoles.MANAGE_CONSENT); + manageConsentRole.setDescription("${role_" + AccountRoles.MANAGE_CONSENT + "}"); + manageConsentRole.addCompositeRole(viewConsentRole); ClientModel accountConsoleClient = realm.getClientByClientId(Constants.ACCOUNT_CONSOLE_CLIENT_ID); if (accountConsoleClient == null) { diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/ClientTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/ClientTest.java index 794d82832c..8a90557ed0 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/ClientTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/ClientTest.java @@ -478,7 +478,8 @@ public class ClientTest extends AbstractAdminTest { Assert.assertNames(scopesResource.clientLevel(accountMgmtId).listAll(), AccountRoles.VIEW_PROFILE); Assert.assertNames(scopesResource.clientLevel(accountMgmtId).listEffective(), AccountRoles.VIEW_PROFILE); - Assert.assertNames(scopesResource.clientLevel(accountMgmtId).listAvailable(), AccountRoles.MANAGE_ACCOUNT, AccountRoles.MANAGE_ACCOUNT_LINKS); + Assert.assertNames(scopesResource.clientLevel(accountMgmtId).listAvailable(), AccountRoles.MANAGE_ACCOUNT, AccountRoles.MANAGE_ACCOUNT_LINKS, + AccountRoles.VIEW_APPLICATIONS, AccountRoles.VIEW_CONSENT, AccountRoles.MANAGE_CONSENT); Assert.assertNames(scopesResource.getAll().getRealmMappings(), "role1"); Assert.assertNames(scopesResource.getAll().getClientMappings().get(Constants.ACCOUNT_MANAGEMENT_CLIENT_ID).getMappings(), AccountRoles.VIEW_PROFILE); @@ -493,7 +494,8 @@ public class ClientTest extends AbstractAdminTest { Assert.assertNames(scopesResource.realmLevel().listEffective()); Assert.assertNames(scopesResource.realmLevel().listAvailable(), "offline_access", Constants.AUTHZ_UMA_AUTHORIZATION, "role1", "role2"); Assert.assertNames(scopesResource.clientLevel(accountMgmtId).listAll()); - Assert.assertNames(scopesResource.clientLevel(accountMgmtId).listAvailable(), AccountRoles.VIEW_PROFILE, AccountRoles.MANAGE_ACCOUNT, AccountRoles.MANAGE_ACCOUNT_LINKS); + Assert.assertNames(scopesResource.clientLevel(accountMgmtId).listAvailable(), AccountRoles.VIEW_PROFILE, AccountRoles.MANAGE_ACCOUNT, AccountRoles.MANAGE_ACCOUNT_LINKS, + AccountRoles.VIEW_APPLICATIONS, AccountRoles.VIEW_CONSENT, AccountRoles.MANAGE_CONSENT); Assert.assertNames(scopesResource.clientLevel(accountMgmtId).listEffective()); } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/migration/AbstractMigrationTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/migration/AbstractMigrationTest.java index c4abe8042f..ee45ef5fd6 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/migration/AbstractMigrationTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/migration/AbstractMigrationTest.java @@ -33,6 +33,7 @@ import org.keycloak.broker.provider.util.SimpleHttp; import org.keycloak.common.constants.KerberosConstants; import org.keycloak.component.PrioritizedComponentModel; import org.keycloak.keys.KeyProvider; +import org.keycloak.models.AccountRoles; import org.keycloak.models.AdminRoles; import org.keycloak.models.AuthenticationExecutionModel; import org.keycloak.models.Constants; @@ -278,6 +279,25 @@ public abstract class AbstractMigrationTest extends AbstractKeycloakTest { testAlwaysDisplayInConsole(); testFirstBrokerLoginFlowMigrated(masterRealm); testFirstBrokerLoginFlowMigrated(migrationRealm); + testAccountClient(masterRealm); + testAccountClient(migrationRealm); + } + + private void testAccountClient(RealmResource realm) { + ClientRepresentation accountClient = realm.clients().findByClientId(ACCOUNT_MANAGEMENT_CLIENT_ID).get(0); + + ClientResource accountResource = realm.clients().get(accountClient.getId()); + RoleRepresentation viewAppRole = accountResource.roles().get(AccountRoles.VIEW_APPLICATIONS).toRepresentation(); + assertNotNull(viewAppRole); + RoleRepresentation viewConsentRole = accountResource.roles().get(AccountRoles.VIEW_CONSENT).toRepresentation(); + assertNotNull(viewConsentRole); + RoleResource manageConsentResource = accountResource.roles().get(AccountRoles.MANAGE_CONSENT); + RoleRepresentation manageConsentRole = manageConsentResource.toRepresentation(); + assertNotNull(manageConsentRole); + assertTrue(manageConsentRole.isComposite()); + Set composites = manageConsentResource.getRoleComposites(); + assertEquals(1, composites.size()); + assertEquals(viewConsentRole.getId(), composites.iterator().next().getId()); } private void testAdminClientUrls(RealmResource realm) { diff --git a/themes/src/main/resources/theme/base/account/messages/messages_en.properties b/themes/src/main/resources/theme/base/account/messages/messages_en.properties index 77ebc10aa4..562fd8ba2a 100755 --- a/themes/src/main/resources/theme/base/account/messages/messages_en.properties +++ b/themes/src/main/resources/theme/base/account/messages/messages_en.properties @@ -71,6 +71,7 @@ role_view-applications=View applications role_view-clients=View clients role_view-events=View events role_view-identity-providers=View identity providers +role_view-consent=View consents role_manage-realm=Manage realm role_manage-users=Manage users role_manage-applications=Manage applications @@ -80,6 +81,7 @@ role_manage-events=Manage events role_view-profile=View profile role_manage-account=Manage account role_manage-account-links=Manage account links +role_manage-consent=Manage consents role_read-token=Read token role_offline-access=Offline access role_uma_authorization=Obtain permissions