From ac1e8e8389988155dc5c9451af8a5aa5b67a556f Mon Sep 17 00:00:00 2001 From: Vlastimil Elias Date: Tue, 7 Apr 2015 14:01:31 +0200 Subject: [PATCH 01/15] KEYCLOAK-1182 - string values for user profile are now sanitized during reading from social providers. Related unit tests added. --- broker/oidc/pom.xml | 5 + .../oidc/AbstractOAuth2IdentityProvider.java | 33 ++++- .../AbstractOAuth2IdentityProviderTest.java | 138 ++++++++++++++++++ 3 files changed, 170 insertions(+), 6 deletions(-) create mode 100644 broker/oidc/src/test/java/org/keycloak/broker/oidc/AbstractOAuth2IdentityProviderTest.java diff --git a/broker/oidc/pom.xml b/broker/oidc/pom.xml index 5bd4d543e6..05a971f106 100755 --- a/broker/oidc/pom.xml +++ b/broker/oidc/pom.xml @@ -52,6 +52,11 @@ jboss-logging provided + + junit + junit + test + diff --git a/broker/oidc/src/main/java/org/keycloak/broker/oidc/AbstractOAuth2IdentityProvider.java b/broker/oidc/src/main/java/org/keycloak/broker/oidc/AbstractOAuth2IdentityProvider.java index 8d57b2c81c..c65e8713ce 100755 --- a/broker/oidc/src/main/java/org/keycloak/broker/oidc/AbstractOAuth2IdentityProvider.java +++ b/broker/oidc/src/main/java/org/keycloak/broker/oidc/AbstractOAuth2IdentityProvider.java @@ -108,11 +108,22 @@ public abstract class AbstractOAuth2IdentityProvider notes = new HashMap<>(); + tested.getFederatedIdentity(notes, "cosi=sss"); + } + + @Test(expected = IdentityBrokerException.class) + public void getFederatedIdentity_responseJSON_tokenNotFound() { + TestProvider tested = getTested(); + Map notes = new HashMap<>(); + tested.getFederatedIdentity(notes, "{\"cosi\":\"sss\"}"); + } + + @Test(expected = IdentityBrokerException.class) + public void getFederatedIdentity_responseJSON_invalidFormat() { + TestProvider tested = getTested(); + Map notes = new HashMap<>(); + tested.getFederatedIdentity(notes, "{\"cosi\":\"sss\""); + } + + @Test(expected = IdentityBrokerException.class) + public void getFederatedIdentity_responseJSON_emptyTokenField() { + TestProvider tested = getTested(); + Map notes = new HashMap<>(); + tested.getFederatedIdentity(notes, "{\"" + + AbstractOAuth2IdentityProvider.OAUTH2_PARAMETER_ACCESS_TOKEN + "\" : \"\"}"); + } + + @Test(expected = IdentityBrokerException.class) + public void getFederatedIdentity_responseJSON_nullTokenField() { + TestProvider tested = getTested(); + Map notes = new HashMap<>(); + tested.getFederatedIdentity(notes, "{\"" + + AbstractOAuth2IdentityProvider.OAUTH2_PARAMETER_ACCESS_TOKEN + "\" : null}"); + } + + @Test + public void getFederatedIdentity_responseJSON() { + TestProvider tested = getTested(); + Map notes = new HashMap<>(); + FederatedIdentity fi = tested.getFederatedIdentity(notes, "{\"" + + AbstractOAuth2IdentityProvider.OAUTH2_PARAMETER_ACCESS_TOKEN + "\" : \"458rt\"}"); + Assert.assertNotNull(fi); + Assert.assertEquals("458rt", fi.getId()); + } + + @Test + public void getFederatedIdentity_responseUrlLine() { + TestProvider tested = getTested(); + Map notes = new HashMap<>(); + FederatedIdentity fi = tested.getFederatedIdentity(notes, "cosi=sss&" + + AbstractOAuth2IdentityProvider.OAUTH2_PARAMETER_ACCESS_TOKEN + "=458rtf&kdesi=ss}"); + Assert.assertNotNull(fi); + Assert.assertEquals("458rtf", fi.getId()); + } + + private TestProvider getTested() { + IdentityProviderModel model = new IdentityProviderModel(); + OAuth2IdentityProviderConfig config = new OAuth2IdentityProviderConfig(model); + return new TestProvider(config); + } + + private static class TestProvider extends AbstractOAuth2IdentityProvider { + + public TestProvider(OAuth2IdentityProviderConfig config) { + super(config); + } + + @Override + protected String getDefaultScopes() { + return "default"; + } + + protected FederatedIdentity doGetFederatedIdentity(String accessToken) { + return new FederatedIdentity(accessToken); + }; + + }; + +} From b0b28a9f387d56018bf34f9a3746018d42480014 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juraci=20Paix=C3=A3o=20Kr=C3=B6hling?= Date: Wed, 8 Apr 2015 14:18:42 +0200 Subject: [PATCH 02/15] KEYCLOAK-1192 KEYCLOAK-1193 KEYCLOAK-1194 - Fixed typos in tooltip and documentation. --- docbook/reference/en/en-US/modules/themes.xml | 6 +++--- .../base/admin/resources/partials/realm-theme-settings.html | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/docbook/reference/en/en-US/modules/themes.xml b/docbook/reference/en/en-US/modules/themes.xml index db3d659a48..cd59f382ad 100755 --- a/docbook/reference/en/en-US/modules/themes.xml +++ b/docbook/reference/en/en-US/modules/themes.xml @@ -80,7 +80,7 @@ [ To deploy a theme as a module you need to create an jar (it's basically just a zip with jar extension) with - the theme resources and a file META/keycloak-server.json that describes the themes contained + the theme resources and a file META/keycloak-themes.json that describes the themes contained in the archive. For example example-theme.jar with the contents: META-INF/keycloak-themes.json @@ -213,7 +213,7 @@ import=common/keycloak theme/example-theme/login/login.ftl theme/example-theme/login/resources/css/styles.css - The contents of META-INF/keycloak-server.json in this case would be: + The contents of META-INF/keycloak-themes.json in this case would be: [ - +
@@ -98,4 +98,4 @@
- \ No newline at end of file + From eb5ae4aae9dafb25fadb48ba82a9fdeceef9b103 Mon Sep 17 00:00:00 2001 From: mposolda Date: Tue, 7 Apr 2015 23:10:23 +0200 Subject: [PATCH 03/15] KEYCLOAK-1007 Fork Picketlink LDAP code. Remove picketlink dependencies from LDAP Federation provider --- dependencies/server-all/pom.xml | 28 - distribution/modules/build.xml | 8 - .../keycloak-ldap-federation/main/module.xml | 5 - .../keycloak-picketlink-api/main/module.xml | 21 - .../keycloak-picketlink-ldap/main/module.xml | 21 - .../keycloak/keycloak-server/main/module.xml | 2 - .../keycloak-services/main/module.xml | 2 - .../WEB-INF/jboss-deployment-structure.xml | 3 - federation/ldap/pom.xml | 27 - .../ldap/LDAPFederationProvider.java | 238 +++--- .../ldap/LDAPFederationProviderFactory.java | 59 +- .../ldap/LDAPIdentityStoreRegistry.java | 165 ++++ .../keycloak/federation/ldap/LDAPUtils.java | 150 ++-- .../ldap/WritableLDAPUserModelDelegate.java | 102 +-- .../idm/model/AbstractAttributedType.java | 85 ++ .../ldap/idm/model/AbstractIdentityType.java | 70 ++ .../federation/ldap/idm/model/Attribute.java | 80 ++ .../ldap/idm/model/AttributeProperty.java | 31 + .../ldap/idm/model/AttributedType.java | 75 ++ .../ldap/idm/model/IdentityType.java | 100 +++ .../federation/ldap/idm/model/LDAPUser.java | 85 ++ .../ldap/idm/query/AttributeParameter.java | 21 + .../federation/ldap/idm/query/Condition.java | 18 + .../ldap/idm/query/IdentityQuery.java | 225 ++++++ .../ldap/idm/query/IdentityQueryBuilder.java | 124 +++ .../ldap/idm/query/QueryParameter.java | 12 + .../federation/ldap/idm/query/Sort.java | 23 + .../idm/query/internal/BetweenCondition.java | 33 + .../query/internal/DefaultIdentityQuery.java | 207 +++++ .../query/internal/DefaultQueryBuilder.java | 89 ++ .../idm/query/internal/EqualCondition.java | 36 + .../query/internal/GreaterThanCondition.java | 34 + .../ldap/idm/query/internal/InCondition.java | 28 + .../idm/query/internal/LessThanCondition.java | 34 + .../idm/query/internal/LikeCondition.java | 28 + .../ldap/idm/store/IdentityStore.java | 81 ++ .../idm/store/ldap/LDAPIdentityStore.java | 761 ++++++++++++++++++ .../ldap/LDAPIdentityStoreConfiguration.java | 188 +++++ .../store/ldap/LDAPMappingConfiguration.java | 231 ++++++ .../idm/store/ldap/LDAPOperationManager.java | 606 ++++++++++++++ .../ldap/idm/store/ldap/LDAPUtil.java | 158 ++++ .../org/keycloak/models/LDAPConstants.java | 35 + .../reflection/NamedPropertyCriteria.java | 40 + .../reflection/TypedPropertyCriteria.java | 71 ++ picketlink/keycloak-picketlink-api/pom.xml | 55 -- .../picketlink/PartitionManagerProvider.java | 14 - .../PartitionManagerProviderFactory.java | 9 - .../picketlink/PartitionManagerSpi.java | 25 - .../services/org.keycloak.provider.Spi | 1 - picketlink/keycloak-picketlink-ldap/pom.xml | 66 -- .../picketlink/idm/KeycloakEventBridge.java | 63 -- .../idm/LDAPKeycloakCredentialHandler.java | 51 -- .../ldap/LDAPPartitionManagerProvider.java | 26 - .../LDAPPartitionManagerProviderFactory.java | 43 - .../ldap/PartitionManagerRegistry.java | 163 ---- ...picketlink.PartitionManagerProviderFactory | 1 - picketlink/pom.xml | 24 - pom.xml | 1 - services/pom.xml | 6 - .../FederationProvidersIntegrationTest.java | 36 +- .../federation/SyncProvidersTest.java | 31 +- 61 files changed, 4042 insertions(+), 1013 deletions(-) delete mode 100755 distribution/modules/src/main/resources/modules/org/keycloak/keycloak-picketlink-api/main/module.xml delete mode 100755 distribution/modules/src/main/resources/modules/org/keycloak/keycloak-picketlink-ldap/main/module.xml create mode 100644 federation/ldap/src/main/java/org/keycloak/federation/ldap/LDAPIdentityStoreRegistry.java create mode 100644 federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/model/AbstractAttributedType.java create mode 100644 federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/model/AbstractIdentityType.java create mode 100644 federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/model/Attribute.java create mode 100644 federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/model/AttributeProperty.java create mode 100644 federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/model/AttributedType.java create mode 100644 federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/model/IdentityType.java create mode 100644 federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/model/LDAPUser.java create mode 100644 federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/query/AttributeParameter.java create mode 100644 federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/query/Condition.java create mode 100644 federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/query/IdentityQuery.java create mode 100644 federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/query/IdentityQueryBuilder.java create mode 100644 federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/query/QueryParameter.java create mode 100644 federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/query/Sort.java create mode 100644 federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/query/internal/BetweenCondition.java create mode 100644 federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/query/internal/DefaultIdentityQuery.java create mode 100644 federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/query/internal/DefaultQueryBuilder.java create mode 100644 federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/query/internal/EqualCondition.java create mode 100644 federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/query/internal/GreaterThanCondition.java create mode 100644 federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/query/internal/InCondition.java create mode 100644 federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/query/internal/LessThanCondition.java create mode 100644 federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/query/internal/LikeCondition.java create mode 100644 federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/store/IdentityStore.java create mode 100644 federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/store/ldap/LDAPIdentityStore.java create mode 100644 federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/store/ldap/LDAPIdentityStoreConfiguration.java create mode 100644 federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/store/ldap/LDAPMappingConfiguration.java create mode 100644 federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/store/ldap/LDAPOperationManager.java create mode 100644 federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/store/ldap/LDAPUtil.java create mode 100644 model/api/src/main/java/org/keycloak/models/utils/reflection/NamedPropertyCriteria.java create mode 100644 model/api/src/main/java/org/keycloak/models/utils/reflection/TypedPropertyCriteria.java delete mode 100755 picketlink/keycloak-picketlink-api/pom.xml delete mode 100644 picketlink/keycloak-picketlink-api/src/main/java/org/keycloak/picketlink/PartitionManagerProvider.java delete mode 100644 picketlink/keycloak-picketlink-api/src/main/java/org/keycloak/picketlink/PartitionManagerProviderFactory.java delete mode 100644 picketlink/keycloak-picketlink-api/src/main/java/org/keycloak/picketlink/PartitionManagerSpi.java delete mode 100644 picketlink/keycloak-picketlink-api/src/main/resources/META-INF/services/org.keycloak.provider.Spi delete mode 100755 picketlink/keycloak-picketlink-ldap/pom.xml delete mode 100755 picketlink/keycloak-picketlink-ldap/src/main/java/org/keycloak/picketlink/idm/KeycloakEventBridge.java delete mode 100755 picketlink/keycloak-picketlink-ldap/src/main/java/org/keycloak/picketlink/idm/LDAPKeycloakCredentialHandler.java delete mode 100644 picketlink/keycloak-picketlink-ldap/src/main/java/org/keycloak/picketlink/ldap/LDAPPartitionManagerProvider.java delete mode 100755 picketlink/keycloak-picketlink-ldap/src/main/java/org/keycloak/picketlink/ldap/LDAPPartitionManagerProviderFactory.java delete mode 100755 picketlink/keycloak-picketlink-ldap/src/main/java/org/keycloak/picketlink/ldap/PartitionManagerRegistry.java delete mode 100644 picketlink/keycloak-picketlink-ldap/src/main/resources/META-INF/services/org.keycloak.picketlink.PartitionManagerProviderFactory delete mode 100755 picketlink/pom.xml diff --git a/dependencies/server-all/pom.xml b/dependencies/server-all/pom.xml index 9d8921f8ed..d124ea5447 100755 --- a/dependencies/server-all/pom.xml +++ b/dependencies/server-all/pom.xml @@ -144,34 +144,6 @@ keycloak-kerberos-federation ${project.version} - - org.picketlink - picketlink-common - - - org.picketlink - picketlink-idm-api - - - org.picketlink - picketlink-idm-impl - - - org.picketlink - picketlink-idm-simple-schema - - - - - org.keycloak - keycloak-picketlink-api - ${project.version} - - - org.keycloak - keycloak-picketlink-ldap - ${project.version} - diff --git a/distribution/modules/build.xml b/distribution/modules/build.xml index 9f65cb95d4..df4bef5917 100755 --- a/distribution/modules/build.xml +++ b/distribution/modules/build.xml @@ -259,14 +259,6 @@ - - - - - - - - diff --git a/distribution/modules/src/main/resources/modules/org/keycloak/keycloak-ldap-federation/main/module.xml b/distribution/modules/src/main/resources/modules/org/keycloak/keycloak-ldap-federation/main/module.xml index 29dfd9c7d7..5f88f37e82 100755 --- a/distribution/modules/src/main/resources/modules/org/keycloak/keycloak-ldap-federation/main/module.xml +++ b/distribution/modules/src/main/resources/modules/org/keycloak/keycloak-ldap-federation/main/module.xml @@ -10,14 +10,9 @@ - - - - - diff --git a/distribution/modules/src/main/resources/modules/org/keycloak/keycloak-picketlink-api/main/module.xml b/distribution/modules/src/main/resources/modules/org/keycloak/keycloak-picketlink-api/main/module.xml deleted file mode 100755 index b51112b48a..0000000000 --- a/distribution/modules/src/main/resources/modules/org/keycloak/keycloak-picketlink-api/main/module.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - diff --git a/distribution/modules/src/main/resources/modules/org/keycloak/keycloak-picketlink-ldap/main/module.xml b/distribution/modules/src/main/resources/modules/org/keycloak/keycloak-picketlink-ldap/main/module.xml deleted file mode 100755 index 429188fbb2..0000000000 --- a/distribution/modules/src/main/resources/modules/org/keycloak/keycloak-picketlink-ldap/main/module.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - diff --git a/distribution/modules/src/main/resources/modules/org/keycloak/keycloak-server/main/module.xml b/distribution/modules/src/main/resources/modules/org/keycloak/keycloak-server/main/module.xml index f553d24263..ddf24752d0 100755 --- a/distribution/modules/src/main/resources/modules/org/keycloak/keycloak-server/main/module.xml +++ b/distribution/modules/src/main/resources/modules/org/keycloak/keycloak-server/main/module.xml @@ -48,8 +48,6 @@ - - diff --git a/distribution/modules/src/main/resources/modules/org/keycloak/keycloak-services/main/module.xml b/distribution/modules/src/main/resources/modules/org/keycloak/keycloak-services/main/module.xml index 86e86f492e..9864a070c1 100755 --- a/distribution/modules/src/main/resources/modules/org/keycloak/keycloak-services/main/module.xml +++ b/distribution/modules/src/main/resources/modules/org/keycloak/keycloak-services/main/module.xml @@ -49,10 +49,8 @@ - - diff --git a/distribution/subsystem-war/src/main/webapp/WEB-INF/jboss-deployment-structure.xml b/distribution/subsystem-war/src/main/webapp/WEB-INF/jboss-deployment-structure.xml index 6caa2c81e5..aae18bf302 100755 --- a/distribution/subsystem-war/src/main/webapp/WEB-INF/jboss-deployment-structure.xml +++ b/distribution/subsystem-war/src/main/webapp/WEB-INF/jboss-deployment-structure.xml @@ -40,9 +40,6 @@ - - - diff --git a/federation/ldap/pom.xml b/federation/ldap/pom.xml index a48b36daef..72803ab6e6 100755 --- a/federation/ldap/pom.xml +++ b/federation/ldap/pom.xml @@ -31,12 +31,6 @@ ${project.version} provided - - org.keycloak - keycloak-picketlink-api - ${project.version} - provided - org.jboss.resteasy resteasy-jaxrs @@ -61,27 +55,6 @@ jboss-logging provided - - - org.picketlink - picketlink-common - provided - - - org.picketlink - picketlink-idm-api - provided - - - org.picketlink - picketlink-idm-impl - provided - - - org.picketlink - picketlink-idm-simple-schema - provided - diff --git a/federation/ldap/src/main/java/org/keycloak/federation/ldap/LDAPFederationProvider.java b/federation/ldap/src/main/java/org/keycloak/federation/ldap/LDAPFederationProvider.java index f48880cfc9..370e0f07f8 100755 --- a/federation/ldap/src/main/java/org/keycloak/federation/ldap/LDAPFederationProvider.java +++ b/federation/ldap/src/main/java/org/keycloak/federation/ldap/LDAPFederationProvider.java @@ -3,6 +3,10 @@ package org.keycloak.federation.ldap; import org.jboss.logging.Logger; import org.keycloak.federation.kerberos.impl.KerberosUsernamePasswordAuthenticator; import org.keycloak.federation.kerberos.impl.SPNEGOAuthenticator; +import org.keycloak.federation.ldap.idm.model.LDAPUser; +import org.keycloak.federation.ldap.idm.query.IdentityQuery; +import org.keycloak.federation.ldap.idm.query.IdentityQueryBuilder; +import org.keycloak.federation.ldap.idm.store.ldap.LDAPIdentityStore; import org.keycloak.federation.ldap.kerberos.LDAPProviderKerberosConfig; import org.keycloak.models.CredentialValidationOutput; import org.keycloak.models.KeycloakSession; @@ -16,12 +20,6 @@ import org.keycloak.models.UserFederationProvider; import org.keycloak.models.UserFederationProviderModel; import org.keycloak.models.UserModel; import org.keycloak.constants.KerberosConstants; -import org.picketlink.idm.IdentityManagementException; -import org.picketlink.idm.IdentityManager; -import org.picketlink.idm.PartitionManager; -import org.picketlink.idm.model.basic.BasicModel; -import org.picketlink.idm.model.basic.User; -import org.picketlink.idm.query.IdentityQuery; import java.util.Arrays; import java.util.HashMap; @@ -38,23 +36,21 @@ import java.util.Set; */ public class LDAPFederationProvider implements UserFederationProvider { private static final Logger logger = Logger.getLogger(LDAPFederationProvider.class); - public static final String LDAP_ID = "LDAP_ID"; - public static final String SYNC_REGISTRATIONS = "syncRegistrations"; protected LDAPFederationProviderFactory factory; protected KeycloakSession session; protected UserFederationProviderModel model; - protected PartitionManager partitionManager; + protected LDAPIdentityStore ldapIdentityStore; protected EditMode editMode; protected LDAPProviderKerberosConfig kerberosConfig; protected final Set supportedCredentialTypes = new HashSet(); - public LDAPFederationProvider(LDAPFederationProviderFactory factory, KeycloakSession session, UserFederationProviderModel model, PartitionManager partitionManager) { + public LDAPFederationProvider(LDAPFederationProviderFactory factory, KeycloakSession session, UserFederationProviderModel model, LDAPIdentityStore ldapIdentityStore) { this.factory = factory; this.session = session; this.model = model; - this.partitionManager = partitionManager; + this.ldapIdentityStore = ldapIdentityStore; this.kerberosConfig = new LDAPProviderKerberosConfig(model); String editModeString = model.getConfig().get(LDAPConstants.EDIT_MODE); if (editModeString == null) { @@ -69,16 +65,6 @@ public class LDAPFederationProvider implements UserFederationProvider { } } - private ModelException convertIDMException(IdentityManagementException ie) { - Throwable realCause = ie; - while (realCause.getCause() != null) { - realCause = realCause.getCause(); - } - - // Use the message from the realCause - return new ModelException(realCause.getMessage(), ie); - } - public KeycloakSession getSession() { return session; } @@ -87,8 +73,8 @@ public class LDAPFederationProvider implements UserFederationProvider { return model; } - public PartitionManager getPartitionManager() { - return partitionManager; + public LDAPIdentityStore getLdapIdentityStore() { + return this.ldapIdentityStore; } @Override @@ -125,22 +111,18 @@ public class LDAPFederationProvider implements UserFederationProvider { @Override public boolean synchronizeRegistrations() { - return "true".equalsIgnoreCase(model.getConfig().get(SYNC_REGISTRATIONS)) && editMode == EditMode.WRITABLE; + return "true".equalsIgnoreCase(model.getConfig().get(LDAPConstants.SYNC_REGISTRATIONS)) && editMode == EditMode.WRITABLE; } @Override public UserModel register(RealmModel realm, UserModel user) { - if (editMode == EditMode.READ_ONLY || editMode == EditMode.UNSYNCED) throw new IllegalStateException("Registration is not supported by this ldap server");; + if (editMode == EditMode.READ_ONLY || editMode == EditMode.UNSYNCED) throw new IllegalStateException("Registration is not supported by this ldap server"); if (!synchronizeRegistrations()) throw new IllegalStateException("Registration is not supported by this ldap server"); - try { - User picketlinkUser = LDAPUtils.addUser(this.partitionManager, user.getUsername(), user.getFirstName(), user.getLastName(), user.getEmail()); - user.setAttribute(LDAP_ID, picketlinkUser.getId()); - return proxy(user); - } catch (IdentityManagementException ie) { - throw convertIDMException(ie); - } - + LDAPUser ldapUser = LDAPUtils.addUser(this.ldapIdentityStore, user.getUsername(), user.getFirstName(), user.getLastName(), user.getEmail()); + user.setAttribute(LDAPConstants.LDAP_ID, ldapUser.getId()); + user.setAttribute(LDAPConstants.LDAP_ENTRY_DN, ldapUser.getEntryDN()); + return proxy(user); } @Override @@ -150,58 +132,53 @@ public class LDAPFederationProvider implements UserFederationProvider { return false; } - try { - return LDAPUtils.removeUser(partitionManager, user.getUsername()); - } catch (IdentityManagementException ie) { - throw convertIDMException(ie); - } + return LDAPUtils.removeUser(this.ldapIdentityStore, user.getUsername()); } @Override public List searchByAttributes(Map attributes, RealmModel realm, int maxResults) { List searchResults =new LinkedList(); - try { - Map plUsers = searchPicketlink(attributes, maxResults); - for (User user : plUsers.values()) { - if (session.userStorage().getUserByUsername(user.getLoginName(), realm) == null) { - UserModel imported = importUserFromPicketlink(realm, user); - searchResults.add(imported); - } + + Map ldapUsers = searchLDAP(attributes, maxResults); + for (LDAPUser ldapUser : ldapUsers.values()) { + if (session.userStorage().getUserByUsername(ldapUser.getLoginName(), realm) == null) { + UserModel imported = importUserFromLDAP(realm, ldapUser); + searchResults.add(imported); } - } catch (IdentityManagementException ie) { - throw convertIDMException(ie); } + return searchResults; } - protected Map searchPicketlink(Map attributes, int maxResults) { - IdentityManager identityManager = getIdentityManager(); - Map results = new HashMap(); + protected Map searchLDAP(Map attributes, int maxResults) { + + Map results = new HashMap(); if (attributes.containsKey(USERNAME)) { - User user = BasicModel.getUser(identityManager, attributes.get(USERNAME)); + LDAPUser user = LDAPUtils.getUser(this.ldapIdentityStore, attributes.get(USERNAME)); if (user != null) { results.put(user.getLoginName(), user); } } if (attributes.containsKey(EMAIL)) { - User user = queryByEmail(identityManager, attributes.get(EMAIL)); + LDAPUser user = queryByEmail(attributes.get(EMAIL)); if (user != null) { results.put(user.getLoginName(), user); } } if (attributes.containsKey(FIRST_NAME) || attributes.containsKey(LAST_NAME)) { - IdentityQuery query = identityManager.createIdentityQuery(User.class); + IdentityQueryBuilder queryBuilder = this.ldapIdentityStore.createQueryBuilder(); + IdentityQuery query = queryBuilder.createIdentityQuery(LDAPUser.class); if (attributes.containsKey(FIRST_NAME)) { - query.setParameter(User.FIRST_NAME, attributes.get(FIRST_NAME)); + query.where(queryBuilder.equal(LDAPUser.FIRST_NAME, attributes.get(FIRST_NAME))); } if (attributes.containsKey(LAST_NAME)) { - query.setParameter(User.LAST_NAME, attributes.get(LAST_NAME)); + query.where(queryBuilder.equal(LDAPUser.LAST_NAME, attributes.get(LAST_NAME))); } query.setLimit(maxResults); - List agents = query.getResultList(); - for (User user : agents) { + List users = query.getResultList(); + for (LDAPUser user : users) { results.put(user.getLoginName(), user); } } @@ -211,85 +188,69 @@ public class LDAPFederationProvider implements UserFederationProvider { @Override public boolean isValid(UserModel local) { - try { - User picketlinkUser = LDAPUtils.getUser(partitionManager, local.getUsername()); - if (picketlinkUser == null) { - return false; - } - return picketlinkUser.getId().equals(local.getAttribute(LDAP_ID)); - } catch (IdentityManagementException ie) { - throw convertIDMException(ie); + LDAPUser ldapUser = LDAPUtils.getUser(this.ldapIdentityStore, local.getUsername()); + if (ldapUser == null) { + return false; } + return ldapUser.getId().equals(local.getAttribute(LDAPConstants.LDAP_ID)); } @Override public UserModel getUserByUsername(RealmModel realm, String username) { - try { - User picketlinkUser = LDAPUtils.getUser(partitionManager, username); - if (picketlinkUser == null) { - return null; - } - - // KEYCLOAK-808: Should we allow case-sensitivity to be configurable? - if (!username.equals(picketlinkUser.getLoginName())) { - logger.warnf("User found in LDAP but with different username. LDAP username: %s, Searched username: %s", username, picketlinkUser.getLoginName()); - return null; - } - - return importUserFromPicketlink(realm, picketlinkUser); - } catch (IdentityManagementException ie) { - throw convertIDMException(ie); - } - } - - public IdentityManager getIdentityManager() { - return partitionManager.createIdentityManager(); - } - - protected UserModel importUserFromPicketlink(RealmModel realm, User picketlinkUser) { - String email = (picketlinkUser.getEmail() != null && picketlinkUser.getEmail().trim().length() > 0) ? picketlinkUser.getEmail() : null; - - if (picketlinkUser.getLoginName() == null) { - throw new ModelException("User returned from LDAP has null username! Check configuration of your LDAP mappings. ID of user from LDAP: " + picketlinkUser.getId()); + LDAPUser ldapUser = LDAPUtils.getUser(this.ldapIdentityStore, username); + if (ldapUser == null) { + return null; } - UserModel imported = session.userStorage().addUser(realm, picketlinkUser.getLoginName()); + // KEYCLOAK-808: Should we allow case-sensitivity to be configurable? + if (!username.equals(ldapUser.getLoginName())) { + logger.warnf("User found in LDAP but with different username. LDAP username: %s, Searched username: %s", username, ldapUser.getLoginName()); + return null; + } + + return importUserFromLDAP(realm, ldapUser); + } + + protected UserModel importUserFromLDAP(RealmModel realm, LDAPUser ldapUser) { + String email = (ldapUser.getEmail() != null && ldapUser.getEmail().trim().length() > 0) ? ldapUser.getEmail() : null; + + if (ldapUser.getLoginName() == null) { + throw new ModelException("User returned from LDAP has null username! Check configuration of your LDAP mappings. ID of user from LDAP: " + ldapUser.getId()); + } + + UserModel imported = session.userStorage().addUser(realm, ldapUser.getLoginName()); imported.setEnabled(true); imported.setEmail(email); - imported.setFirstName(picketlinkUser.getFirstName()); - imported.setLastName(picketlinkUser.getLastName()); + imported.setFirstName(ldapUser.getFirstName()); + imported.setLastName(ldapUser.getLastName()); imported.setFederationLink(model.getId()); - imported.setAttribute(LDAP_ID, picketlinkUser.getId()); + imported.setAttribute(LDAPConstants.LDAP_ID, ldapUser.getId()); + imported.setAttribute(LDAPConstants.LDAP_ENTRY_DN, ldapUser.getEntryDN()); - logger.debugf("Added new user from LDAP. Username: " + imported.getUsername() + ", Email: ", imported.getEmail() + ", LDAP_ID: " + picketlinkUser.getId()); + logger.debugf("Imported new user from LDAP to Keycloak DB. Username: [%s], Email: [%s], LDAP_ID: [%s], LDAP Entry DN: [%s]", imported.getUsername(), imported.getEmail(), + ldapUser.getId(), ldapUser.getEntryDN()); return proxy(imported); } - protected User queryByEmail(IdentityManager identityManager, String email) throws IdentityManagementException { - return LDAPUtils.getUserByEmail(identityManager, email); + protected LDAPUser queryByEmail(String email) { + return LDAPUtils.getUserByEmail(this.ldapIdentityStore, email); } @Override public UserModel getUserByEmail(RealmModel realm, String email) { - IdentityManager identityManager = getIdentityManager(); - - try { - User picketlinkUser = queryByEmail(identityManager, email); - if (picketlinkUser == null) { - return null; - } - - // KEYCLOAK-808: Should we allow case-sensitivity to be configurable? - if (!email.equals(picketlinkUser.getEmail())) { - logger.warnf("User found in LDAP but with different email. LDAP email: %s, Searched email: %s", email, picketlinkUser.getEmail()); - return null; - } - - return importUserFromPicketlink(realm, picketlinkUser); - } catch (IdentityManagementException ie) { - throw convertIDMException(ie); + LDAPUser ldapUser = queryByEmail(email); + if (ldapUser == null) { + return null; } + + // KEYCLOAK-808: Should we allow case-sensitivity to be configurable? + if (!email.equals(ldapUser.getEmail())) { + logger.warnf("User found in LDAP but with different email. LDAP email: %s, Searched email: %s", email, ldapUser.getEmail()); + return null; + } + + return importUserFromLDAP(realm, ldapUser); } @Override @@ -302,18 +263,14 @@ public class LDAPFederationProvider implements UserFederationProvider { // complete I don't think we have to do anything here } - public boolean validPassword(String username, String password) { + public boolean validPassword(UserModel user, String password) { if (kerberosConfig.isAllowKerberosAuthentication() && kerberosConfig.isUseKerberosForPasswordAuthentication()) { // Use Kerberos JAAS (Krb5LoginModule) KerberosUsernamePasswordAuthenticator authenticator = factory.createKerberosUsernamePasswordAuthenticator(kerberosConfig); - return authenticator.validUser(username, password); + return authenticator.validUser(user.getUsername(), password); } else { // Use Naming LDAP API - try { - return LDAPUtils.validatePassword(partitionManager, username, password); - } catch (IdentityManagementException ie) { - throw convertIDMException(ie); - } + return LDAPUtils.validatePassword(this.ldapIdentityStore, user, password); } } @@ -322,7 +279,7 @@ public class LDAPFederationProvider implements UserFederationProvider { public boolean validCredentials(RealmModel realm, UserModel user, List input) { for (UserCredentialModel cred : input) { if (cred.getType().equals(UserCredentialModel.PASSWORD)) { - return validPassword(user.getUsername(), cred.getValue()); + return validPassword(user, cred.getValue()); } else { return false; // invalid cred type } @@ -353,7 +310,7 @@ public class LDAPFederationProvider implements UserFederationProvider { UserModel user = findOrCreateAuthenticatedUser(realm, username); if (user == null) { - logger.warn("Kerberos/SPNEGO authentication succeeded with username [" + username + "], but couldn't find or create user with federation provider [" + model.getDisplayName() + "]"); + logger.warnf("Kerberos/SPNEGO authentication succeeded with username [%s], but couldn't find or create user with federation provider [%s]", username, model.getDisplayName()); return CredentialValidationOutput.failed(); } else { String delegationCredential = spnegoAuthenticator.getSerializedDelegationCredential(); @@ -375,24 +332,23 @@ public class LDAPFederationProvider implements UserFederationProvider { @Override public void close() { - //To change body of implemented methods use File | Settings | File Templates. } - protected void importPicketlinkUsers(RealmModel realm, List users, UserFederationProviderModel fedModel) { - for (User picketlinkUser : users) { - String username = picketlinkUser.getLoginName(); + protected void importLDAPUsers(RealmModel realm, List ldapUsers, UserFederationProviderModel fedModel) { + for (LDAPUser ldapUser : ldapUsers) { + String username = ldapUser.getLoginName(); UserModel currentUser = session.userStorage().getUserByUsername(username, realm); if (currentUser == null) { // Add new user to Keycloak - importUserFromPicketlink(realm, picketlinkUser); + importUserFromLDAP(realm, ldapUser); } else { - if ((fedModel.getId().equals(currentUser.getFederationLink())) && (picketlinkUser.getId().equals(currentUser.getAttribute(LDAPFederationProvider.LDAP_ID)))) { + if ((fedModel.getId().equals(currentUser.getFederationLink())) && (ldapUser.getId().equals(currentUser.getAttribute(LDAPConstants.LDAP_ID)))) { // Update keycloak user - String email = (picketlinkUser.getEmail() != null && picketlinkUser.getEmail().trim().length() > 0) ? picketlinkUser.getEmail() : null; + String email = (ldapUser.getEmail() != null && ldapUser.getEmail().trim().length() > 0) ? ldapUser.getEmail() : null; currentUser.setEmail(email); - currentUser.setFirstName(picketlinkUser.getFirstName()); - currentUser.setLastName(picketlinkUser.getLastName()); + currentUser.setFirstName(ldapUser.getFirstName()); + currentUser.setLastName(ldapUser.getLastName()); logger.debugf("Updated user from LDAP: %s", currentUser.getUsername()); } else { logger.warnf("User '%s' is not updated during sync as he is not linked to federation provider '%s'", username, fedModel.getDisplayName()); @@ -404,29 +360,29 @@ public class LDAPFederationProvider implements UserFederationProvider { /** * Called after successful kerberos authentication * - * @param realm + * @param realm realm * @param username username without realm prefix - * @return + * @return finded or newly created user */ protected UserModel findOrCreateAuthenticatedUser(RealmModel realm, String username) { UserModel user = session.userStorage().getUserByUsername(username, realm); if (user != null) { - logger.debug("Kerberos authenticated user " + username + " found in Keycloak storage"); + logger.debugf("Kerberos authenticated user [%s] found in Keycloak storage", username); if (!model.getId().equals(user.getFederationLink())) { - logger.warn("User with username " + username + " already exists, but is not linked to provider [" + model.getDisplayName() + "]"); + logger.warnf("User with username [%s] already exists, but is not linked to provider [%s]", username, model.getDisplayName()); return null; } else if (isValid(user)) { return proxy(user); } else { - logger.warn("User with username " + username + " already exists and is linked to provider [" + model.getDisplayName() + - "] but is not valid. Stale LDAP_ID on local user is: " + user.getAttribute(LDAP_ID)); + logger.warnf("User with username [%s] aready exists and is linked to provider [%s] but is not valid. Stale LDAP_ID on local user is: %s", + username, model.getDisplayName(), user.getAttribute(LDAPConstants.LDAP_ID)); logger.warn("Will re-create user"); session.userStorage().removeUser(realm, user); } } // Creating user to local storage - logger.debug("Kerberos authenticated user " + username + " not in Keycloak storage. Creating him"); + logger.debugf("Kerberos authenticated user [%s] not in Keycloak storage. Creating him", username); return getUserByUsername(realm, username); } } diff --git a/federation/ldap/src/main/java/org/keycloak/federation/ldap/LDAPFederationProviderFactory.java b/federation/ldap/src/main/java/org/keycloak/federation/ldap/LDAPFederationProviderFactory.java index c197052df9..a498a93b45 100755 --- a/federation/ldap/src/main/java/org/keycloak/federation/ldap/LDAPFederationProviderFactory.java +++ b/federation/ldap/src/main/java/org/keycloak/federation/ldap/LDAPFederationProviderFactory.java @@ -3,10 +3,15 @@ package org.keycloak.federation.ldap; import org.jboss.logging.Logger; import org.keycloak.Config; import org.keycloak.federation.kerberos.CommonKerberosConfig; -import org.keycloak.federation.kerberos.KerberosConfig; import org.keycloak.federation.kerberos.impl.KerberosServerSubjectAuthenticator; import org.keycloak.federation.kerberos.impl.KerberosUsernamePasswordAuthenticator; import org.keycloak.federation.kerberos.impl.SPNEGOAuthenticator; +import org.keycloak.federation.ldap.idm.model.IdentityType; +import org.keycloak.federation.ldap.idm.model.LDAPUser; +import org.keycloak.federation.ldap.idm.query.Condition; +import org.keycloak.federation.ldap.idm.query.IdentityQuery; +import org.keycloak.federation.ldap.idm.query.IdentityQueryBuilder; +import org.keycloak.federation.ldap.idm.store.ldap.LDAPIdentityStore; import org.keycloak.models.KeycloakSession; import org.keycloak.models.KeycloakSessionFactory; import org.keycloak.models.KeycloakSessionTask; @@ -16,16 +21,6 @@ import org.keycloak.models.UserFederationProvider; import org.keycloak.models.UserFederationProviderFactory; import org.keycloak.models.UserFederationProviderModel; import org.keycloak.models.utils.KeycloakModelUtils; -import org.keycloak.picketlink.PartitionManagerProvider; -import org.picketlink.idm.IdentityManager; -import org.picketlink.idm.PartitionManager; -import org.picketlink.idm.model.IdentityType; -import org.picketlink.idm.model.basic.User; -import org.picketlink.idm.query.AttributeParameter; -import org.picketlink.idm.query.Condition; -import org.picketlink.idm.query.IdentityQuery; -import org.picketlink.idm.query.IdentityQueryBuilder; -import org.picketlink.idm.query.QueryParameter; import java.util.Collections; import java.util.Date; @@ -41,6 +36,8 @@ public class LDAPFederationProviderFactory implements UserFederationProviderFact private static final Logger logger = Logger.getLogger(LDAPFederationProviderFactory.class); public static final String PROVIDER_NAME = "ldap"; + private LDAPIdentityStoreRegistry ldapStoreRegistry; + @Override public UserFederationProvider create(KeycloakSession session) { throw new IllegalAccessError("Illegal to call this method"); @@ -48,13 +45,13 @@ public class LDAPFederationProviderFactory implements UserFederationProviderFact @Override public LDAPFederationProvider getInstance(KeycloakSession session, UserFederationProviderModel model) { - PartitionManagerProvider idmProvider = session.getProvider(PartitionManagerProvider.class); - PartitionManager partition = idmProvider.getPartitionManager(model); - return new LDAPFederationProvider(this, session, model, partition); + LDAPIdentityStore ldapIdentityStore = this.ldapStoreRegistry.getLdapStore(model); + return new LDAPFederationProvider(this, session, model, ldapIdentityStore); } @Override public void init(Config.Scope config) { + this.ldapStoreRegistry = new LDAPIdentityStoreRegistry(); } @Override @@ -64,7 +61,7 @@ public class LDAPFederationProviderFactory implements UserFederationProviderFact @Override public void close() { - + this.ldapStoreRegistry = null; } @Override @@ -81,9 +78,8 @@ public class LDAPFederationProviderFactory implements UserFederationProviderFact public void syncAllUsers(KeycloakSessionFactory sessionFactory, String realmId, UserFederationProviderModel model) { logger.infof("Sync all users from LDAP to local store: realm: %s, federation provider: %s, current time: " + new Date(), realmId, model.getDisplayName()); - PartitionManagerProvider idmProvider = sessionFactory.create().getProvider(PartitionManagerProvider.class); - PartitionManager partitionMgr = idmProvider.getPartitionManager(model); - IdentityQuery userQuery = partitionMgr.createIdentityManager().createIdentityQuery(User.class); + LDAPIdentityStore ldapIdentityStore = this.ldapStoreRegistry.getLdapStore(model); + IdentityQuery userQuery = ldapIdentityStore.createQueryBuilder().createIdentityQuery(LDAPUser.class); syncImpl(sessionFactory, userQuery, realmId, model); // TODO: Remove all existing keycloak users, which have federation links, but are not in LDAP. Perhaps don't check users, which were just added or updated during this sync? @@ -91,26 +87,23 @@ public class LDAPFederationProviderFactory implements UserFederationProviderFact @Override public void syncChangedUsers(KeycloakSessionFactory sessionFactory, String realmId, UserFederationProviderModel model, Date lastSync) { - logger.infof("Sync changed users from LDAP to local store: realm: %s, federation provider: %s, current time: " + new Date() + ", last sync time: " + lastSync, realmId, model.getDisplayName()); + logger.infof("Sync changed users from LDAP to local store: realm: %s, federation provider: %s, current time: %s, last sync time: " + lastSync, realmId, model.getDisplayName(), new Date().toString()); - PartitionManagerProvider idmProvider = sessionFactory.create().getProvider(PartitionManagerProvider.class); - PartitionManager partitionMgr = idmProvider.getPartitionManager(model); + LDAPIdentityStore ldapIdentityStore = this.ldapStoreRegistry.getLdapStore(model); // Sync newly created users - IdentityManager identityManager = partitionMgr.createIdentityManager(); - IdentityQueryBuilder queryBuilder = identityManager.getQueryBuilder(); + IdentityQueryBuilder queryBuilder = ldapIdentityStore.createQueryBuilder(); Condition condition = queryBuilder.greaterThanOrEqualTo(IdentityType.CREATED_DATE, lastSync); - IdentityQuery userQuery = queryBuilder.createIdentityQuery(User.class).where(condition); + IdentityQuery userQuery = queryBuilder.createIdentityQuery(LDAPUser.class).where(condition); syncImpl(sessionFactory, userQuery, realmId, model); // Sync updated users - queryBuilder = identityManager.getQueryBuilder(); condition = queryBuilder.greaterThanOrEqualTo(LDAPUtils.MODIFY_DATE, lastSync); - userQuery = queryBuilder.createIdentityQuery(User.class).where(condition); + userQuery = queryBuilder.createIdentityQuery(LDAPUser.class).where(condition); syncImpl(sessionFactory, userQuery, realmId, model); } - protected void syncImpl(KeycloakSessionFactory sessionFactory, IdentityQuery userQuery, final String realmId, final UserFederationProviderModel fedModel) { + protected void syncImpl(KeycloakSessionFactory sessionFactory, IdentityQuery userQuery, final String realmId, final UserFederationProviderModel fedModel) { boolean pagination = Boolean.parseBoolean(fedModel.getConfig().get(LDAPConstants.PAGINATION)); if (pagination) { @@ -119,36 +112,36 @@ public class LDAPFederationProviderFactory implements UserFederationProviderFact boolean nextPage = true; while (nextPage) { userQuery.setLimit(pageSize); - final List users = userQuery.getResultList(); + final List users = userQuery.getResultList(); nextPage = userQuery.getPaginationContext() != null; KeycloakModelUtils.runJobInTransaction(sessionFactory, new KeycloakSessionTask() { @Override public void run(KeycloakSession session) { - importPicketlinkUsers(session, realmId, fedModel, users); + importLdapUsers(session, realmId, fedModel, users); } }); } } else { // LDAP pagination not available. Do everything in single transaction - final List users = userQuery.getResultList(); + final List users = userQuery.getResultList(); KeycloakModelUtils.runJobInTransaction(sessionFactory, new KeycloakSessionTask() { @Override public void run(KeycloakSession session) { - importPicketlinkUsers(session, realmId, fedModel, users); + importLdapUsers(session, realmId, fedModel, users); } }); } } - protected void importPicketlinkUsers(KeycloakSession session, String realmId, UserFederationProviderModel fedModel, List users) { + protected void importLdapUsers(KeycloakSession session, String realmId, UserFederationProviderModel fedModel, List ldapUsers) { RealmModel realm = session.realms().getRealm(realmId); LDAPFederationProvider ldapFedProvider = getInstance(session, fedModel); - ldapFedProvider.importPicketlinkUsers(realm, users, fedModel); + ldapFedProvider.importLDAPUsers(realm, ldapUsers, fedModel); } protected SPNEGOAuthenticator createSPNEGOAuthenticator(String spnegoToken, CommonKerberosConfig kerberosConfig) { diff --git a/federation/ldap/src/main/java/org/keycloak/federation/ldap/LDAPIdentityStoreRegistry.java b/federation/ldap/src/main/java/org/keycloak/federation/ldap/LDAPIdentityStoreRegistry.java new file mode 100644 index 0000000000..22aa55a6e9 --- /dev/null +++ b/federation/ldap/src/main/java/org/keycloak/federation/ldap/LDAPIdentityStoreRegistry.java @@ -0,0 +1,165 @@ +package org.keycloak.federation.ldap; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Properties; +import java.util.concurrent.ConcurrentHashMap; + +import org.jboss.logging.Logger; +import org.keycloak.federation.ldap.idm.model.LDAPUser; +import org.keycloak.federation.ldap.idm.store.ldap.LDAPIdentityStore; +import org.keycloak.federation.ldap.idm.store.ldap.LDAPIdentityStoreConfiguration; +import org.keycloak.federation.ldap.idm.store.ldap.LDAPMappingConfiguration; +import org.keycloak.models.LDAPConstants; +import org.keycloak.models.UserFederationProviderModel; + +/** + * @author Marek Posolda + */ +public class LDAPIdentityStoreRegistry { + + private static final Logger logger = Logger.getLogger(LDAPIdentityStoreRegistry.class); + + private Map ldapStores = new ConcurrentHashMap(); + + public LDAPIdentityStore getLdapStore(UserFederationProviderModel model) { + LDAPIdentityStoreContext context = ldapStores.get(model.getId()); + + // Ldap config might have changed for the realm. In this case, we must re-initialize + Map config = model.getConfig(); + if (context == null || !config.equals(context.config)) { + logLDAPConfig(model.getId(), config); + + LDAPIdentityStore store = createLdapIdentityStore(config); + context = new LDAPIdentityStoreContext(config, store); + ldapStores.put(model.getId(), context); + } + return context.store; + } + + // Don't log LDAP password + private void logLDAPConfig(String fedProviderId, Map ldapConfig) { + Map copy = new HashMap(ldapConfig); + copy.remove(LDAPConstants.BIND_CREDENTIAL); + logger.infof("Creating new LDAP based partition manager for the Federation provider: " + fedProviderId + ", LDAP Configuration: " + copy); + } + + /** + * @param ldapConfig from realm + * @return PartitionManager instance based on LDAP store + */ + public static LDAPIdentityStore createLdapIdentityStore(Map ldapConfig) { + Properties connectionProps = new Properties(); + if (ldapConfig.containsKey(LDAPConstants.CONNECTION_POOLING)) { + connectionProps.put("com.sun.jndi.ldap.connect.pool", ldapConfig.get(LDAPConstants.CONNECTION_POOLING)); + } + + checkSystemProperty("com.sun.jndi.ldap.connect.pool.authentication", "none simple"); + checkSystemProperty("com.sun.jndi.ldap.connect.pool.initsize", "1"); + checkSystemProperty("com.sun.jndi.ldap.connect.pool.maxsize", "1000"); + checkSystemProperty("com.sun.jndi.ldap.connect.pool.prefsize", "5"); + checkSystemProperty("com.sun.jndi.ldap.connect.pool.timeout", "300000"); + checkSystemProperty("com.sun.jndi.ldap.connect.pool.protocol", "plain"); + checkSystemProperty("com.sun.jndi.ldap.connect.pool.debug", "off"); + + String vendor = ldapConfig.get(LDAPConstants.VENDOR); + + boolean activeDirectory = vendor != null && vendor.equals(LDAPConstants.VENDOR_ACTIVE_DIRECTORY); + + String ldapLoginNameMapping = ldapConfig.get(LDAPConstants.USERNAME_LDAP_ATTRIBUTE); + if (ldapLoginNameMapping == null) { + ldapLoginNameMapping = activeDirectory ? LDAPConstants.CN : LDAPConstants.UID; + } + + String ldapFirstNameMapping = activeDirectory ? "givenName" : LDAPConstants.CN; + String createTimestampMapping = activeDirectory ? "whenCreated" : LDAPConstants.CREATE_TIMESTAMP; + String modifyTimestampMapping = activeDirectory ? "whenChanged" : LDAPConstants.MODIFY_TIMESTAMP; + String[] userObjectClasses = getUserObjectClasses(ldapConfig); + + boolean pagination = ldapConfig.containsKey(LDAPConstants.PAGINATION) ? Boolean.parseBoolean(ldapConfig.get(LDAPConstants.PAGINATION)) : false; + boolean userAccountControlsAfterPasswordUpdate = ldapConfig.containsKey(LDAPConstants.USER_ACCOUNT_CONTROLS_AFTER_PASSWORD_UPDATE) ? + Boolean.parseBoolean(ldapConfig.get(LDAPConstants.USER_ACCOUNT_CONTROLS_AFTER_PASSWORD_UPDATE)) : false; + + // Differences of unique attribute among various vendors + String uniqueIdentifierAttributeName = LDAPConstants.ENTRY_UUID; + if (vendor != null) { + switch (vendor) { + case LDAPConstants.VENDOR_RHDS: + uniqueIdentifierAttributeName = "nsuniqueid"; + break; + case LDAPConstants.VENDOR_TIVOLI: + uniqueIdentifierAttributeName = "uniqueidentifier"; + break; + case LDAPConstants.VENDOR_ACTIVE_DIRECTORY: + uniqueIdentifierAttributeName = LDAPConstants.OBJECT_GUID; + } + } + + LDAPIdentityStoreConfiguration ldapStoreConfig = new LDAPIdentityStoreConfiguration() + .setConnectionProperties(connectionProps) + .setBaseDN(ldapConfig.get(LDAPConstants.BASE_DN)) + .setBindDN(ldapConfig.get(LDAPConstants.BIND_DN)) + .setBindCredential(ldapConfig.get(LDAPConstants.BIND_CREDENTIAL)) + .setLdapURL(ldapConfig.get(LDAPConstants.CONNECTION_URL)) + .setActiveDirectory(activeDirectory) + .setPagination(pagination) + .setUniqueIdentifierAttributeName(uniqueIdentifierAttributeName) + .setFactoryName("com.sun.jndi.ldap.LdapCtxFactory") + .setAuthType("simple") + .setUserAccountControlsAfterPasswordUpdate(userAccountControlsAfterPasswordUpdate); + + LDAPMappingConfiguration ldapUserMappingConfig = ldapStoreConfig + .mappingConfig(LDAPUser.class) + .setBaseDN(ldapConfig.get(LDAPConstants.USER_DN_SUFFIX)) + .setObjectClasses(new HashSet(Arrays.asList(userObjectClasses))) + .setIdPropertyName("loginName") + .addAttributeMapping("loginName", ldapLoginNameMapping) + .addAttributeMapping("firstName", ldapFirstNameMapping) + .addAttributeMapping("lastName", LDAPConstants.SN) + .addAttributeMapping("email", LDAPConstants.EMAIL) + .addReadOnlyAttributeMapping("createdDate", createTimestampMapping) + .addReadOnlyAttributeMapping("modifyDate", modifyTimestampMapping); + + if (activeDirectory && ldapLoginNameMapping.equals("sAMAccountName")) { + ldapUserMappingConfig.setBindingPropertyName("fullName"); + ldapUserMappingConfig.addAttributeMapping("fullName", LDAPConstants.CN); + logger.infof("Using 'cn' attribute for DN of user and 'sAMAccountName' for username"); + } + + return new LDAPIdentityStore(ldapStoreConfig); + } + + private static void checkSystemProperty(String name, String defaultValue) { + if (System.getProperty(name) == null) { + System.setProperty(name, defaultValue); + } + } + + // Parse array of strings like [ "inetOrgPerson", "organizationalPerson" ] from the string like: "inetOrgPerson, organizationalPerson" + private static String[] getUserObjectClasses(Map ldapConfig) { + String objClassesCfg = ldapConfig.get(LDAPConstants.USER_OBJECT_CLASSES); + String objClassesStr = (objClassesCfg != null && objClassesCfg.length() > 0) ? objClassesCfg.trim() : "inetOrgPerson, organizationalPerson"; + + String[] objectClasses = objClassesStr.split(","); + + // Trim them + String[] userObjectClasses = new String[objectClasses.length]; + for (int i=0 ; i config, LDAPIdentityStore store) { + this.config = config; + this.store = store; + } + + private Map config; + private LDAPIdentityStore store; + } +} diff --git a/federation/ldap/src/main/java/org/keycloak/federation/ldap/LDAPUtils.java b/federation/ldap/src/main/java/org/keycloak/federation/ldap/LDAPUtils.java index db0e9b8ab1..97535926c9 100755 --- a/federation/ldap/src/main/java/org/keycloak/federation/ldap/LDAPUtils.java +++ b/federation/ldap/src/main/java/org/keycloak/federation/ldap/LDAPUtils.java @@ -1,22 +1,21 @@ package org.keycloak.federation.ldap; +import org.keycloak.federation.ldap.idm.model.Attribute; +import org.keycloak.federation.ldap.idm.model.LDAPUser; +import org.keycloak.federation.ldap.idm.query.AttributeParameter; +import org.keycloak.federation.ldap.idm.query.IdentityQuery; +import org.keycloak.federation.ldap.idm.query.IdentityQueryBuilder; +import org.keycloak.federation.ldap.idm.query.QueryParameter; +import org.keycloak.federation.ldap.idm.store.ldap.LDAPIdentityStore; +import org.keycloak.models.LDAPConstants; import org.keycloak.models.ModelDuplicateException; -import org.picketlink.idm.IdentityManagementException; -import org.picketlink.idm.IdentityManager; -import org.picketlink.idm.PartitionManager; -import org.picketlink.idm.credential.Credentials; -import org.picketlink.idm.credential.Password; -import org.picketlink.idm.credential.UsernamePasswordCredentials; -import org.picketlink.idm.model.Attribute; -import org.picketlink.idm.model.basic.BasicModel; -import org.picketlink.idm.model.basic.User; -import org.picketlink.idm.query.AttributeParameter; -import org.picketlink.idm.query.QueryParameter; +import org.keycloak.models.UserModel; import java.util.List; /** - * Allow to directly call some operations against Picketlink IDM PartitionManager (hence LDAP). + * Allow to directly call some operations against LDAPIdentityStore. + * TODO: Is this class still needed? * * @author Marek Posolda */ @@ -24,99 +23,102 @@ public class LDAPUtils { public static QueryParameter MODIFY_DATE = new AttributeParameter("modifyDate"); - public static User addUser(PartitionManager partitionManager, String username, String firstName, String lastName, String email) { - IdentityManager identityManager = getIdentityManager(partitionManager); - - if (BasicModel.getUser(identityManager, username) != null) { + public static LDAPUser addUser(LDAPIdentityStore ldapIdentityStore, String username, String firstName, String lastName, String email) { + if (getUser(ldapIdentityStore, username) != null) { throw new ModelDuplicateException("User with same username already exists"); } - if (getUserByEmail(identityManager, email) != null) { + if (getUserByEmail(ldapIdentityStore, email) != null) { throw new ModelDuplicateException("User with same email already exists"); } - User picketlinkUser = new User(username); - picketlinkUser.setFirstName(firstName); - picketlinkUser.setLastName(lastName); - picketlinkUser.setEmail(email); - picketlinkUser.setAttribute(new Attribute("fullName", getFullName(username, firstName, lastName))); - identityManager.add(picketlinkUser); - return picketlinkUser; + LDAPUser ldapUser = new LDAPUser(username); + ldapUser.setFirstName(firstName); + ldapUser.setLastName(lastName); + ldapUser.setEmail(email); + ldapUser.setAttribute(new Attribute("fullName", getFullName(username, firstName, lastName))); + ldapIdentityStore.add(ldapUser); + return ldapUser; } - public static User updateUser(PartitionManager partitionManager, String username, String firstName, String lastName, String email) { - IdentityManager idmManager = getIdentityManager(partitionManager); - User picketlinkUser = BasicModel.getUser(idmManager, username); - picketlinkUser.setFirstName(firstName); - picketlinkUser.setLastName(lastName); - picketlinkUser.setEmail(email); - idmManager.update(picketlinkUser); - return picketlinkUser; + public static LDAPUser updateUser(LDAPIdentityStore ldapIdentityStore, String username, String firstName, String lastName, String email) { + LDAPUser ldapUser = getUser(ldapIdentityStore, username); + ldapUser.setFirstName(firstName); + ldapUser.setLastName(lastName); + ldapUser.setEmail(email); + ldapIdentityStore.update(ldapUser); + return ldapUser; } - public static void updatePassword(PartitionManager partitionManager, User picketlinkUser, String password) { - IdentityManager idmManager = getIdentityManager(partitionManager); - idmManager.updateCredential(picketlinkUser, new Password(password.toCharArray())); + public static void updatePassword(LDAPIdentityStore ldapIdentityStore, UserModel user, String password) { + LDAPUser ldapUser = convertUserForPasswordUpdate(user); + + ldapIdentityStore.updatePassword(ldapUser, password); } - public static boolean validatePassword(PartitionManager partitionManager, String username, String password) { - IdentityManager idmManager = getIdentityManager(partitionManager); + public static void updatePassword(LDAPIdentityStore ldapIdentityStore, LDAPUser user, String password) { + ldapIdentityStore.updatePassword(user, password); + } - UsernamePasswordCredentials credential = new UsernamePasswordCredentials(); - credential.setUsername(username); - credential.setPassword(new Password(password.toCharArray())); - idmManager.validateCredentials(credential); - if (credential.getStatus() == Credentials.Status.VALID) { - return true; - } else { - return false; + public static boolean validatePassword(LDAPIdentityStore ldapIdentityStore, UserModel user, String password) { + LDAPUser ldapUser = convertUserForPasswordUpdate(user); + + return ldapIdentityStore.validatePassword(ldapUser, password); + } + + public static boolean validatePassword(LDAPIdentityStore ldapIdentityStore, LDAPUser user, String password) { + return ldapIdentityStore.validatePassword(user, password); + } + + public static LDAPUser getUser(LDAPIdentityStore ldapIdentityStore, String username) { + return ldapIdentityStore.getUser(username); + } + + // Put just username and entryDN as these are needed by LDAPIdentityStore for passwordUpdate + private static LDAPUser convertUserForPasswordUpdate(UserModel kcUser) { + LDAPUser ldapUser = new LDAPUser(kcUser.getUsername()); + String ldapEntryDN = kcUser.getAttribute(LDAPConstants.LDAP_ENTRY_DN); + if (ldapEntryDN != null) { + ldapUser.setEntryDN(ldapEntryDN); } - } - - public static User getUser(PartitionManager partitionManager, String username) { - IdentityManager idmManager = getIdentityManager(partitionManager); - return BasicModel.getUser(idmManager, username); + return ldapUser; } - public static User getUserByEmail(IdentityManager idmManager, String email) throws IdentityManagementException { - List agents = idmManager.createIdentityQuery(User.class) - .setParameter(User.EMAIL, email).getResultList(); + public static LDAPUser getUserByEmail(LDAPIdentityStore ldapIdentityStore, String email) { + IdentityQueryBuilder queryBuilder = ldapIdentityStore.createQueryBuilder(); + IdentityQuery query = queryBuilder.createIdentityQuery(LDAPUser.class) + .where(queryBuilder.equal(LDAPUser.EMAIL, email)); + List users = query.getResultList(); - if (agents.isEmpty()) { + if (users.isEmpty()) { return null; - } else if (agents.size() == 1) { - return agents.get(0); + } else if (users.size() == 1) { + return users.get(0); } else { - throw new IdentityManagementException("Error - multiple users found with same email"); + throw new ModelDuplicateException("Error - multiple users found with same email " + email); } } - public static boolean removeUser(PartitionManager partitionManager, String username) { - IdentityManager idmManager = getIdentityManager(partitionManager); - User picketlinkUser = BasicModel.getUser(idmManager, username); - if (picketlinkUser == null) { + public static boolean removeUser(LDAPIdentityStore ldapIdentityStore, String username) { + LDAPUser ldapUser = getUser(ldapIdentityStore, username); + if (ldapUser == null) { return false; } - idmManager.remove(picketlinkUser); + ldapIdentityStore.remove(ldapUser); return true; } - public static void removeAllUsers(PartitionManager partitionManager) { - IdentityManager idmManager = getIdentityManager(partitionManager); - List users = idmManager.createIdentityQuery(User.class).getResultList(); + public static void removeAllUsers(LDAPIdentityStore ldapIdentityStore) { + List allUsers = getAllUsers(ldapIdentityStore); - for (User user : users) { - idmManager.remove(user); + for (LDAPUser user : allUsers) { + ldapIdentityStore.remove(user); } } - public static List getAllUsers(PartitionManager partitionManager) { - IdentityManager idmManager = getIdentityManager(partitionManager); - return idmManager.createIdentityQuery(User.class).getResultList(); - } - - private static IdentityManager getIdentityManager(PartitionManager partitionManager) { - return partitionManager.createIdentityManager(); + public static List getAllUsers(LDAPIdentityStore ldapIdentityStore) { + IdentityQuery userQuery = ldapIdentityStore.createQueryBuilder().createIdentityQuery(LDAPUser.class); + return userQuery.getResultList(); } // Needed for ActiveDirectory updates diff --git a/federation/ldap/src/main/java/org/keycloak/federation/ldap/WritableLDAPUserModelDelegate.java b/federation/ldap/src/main/java/org/keycloak/federation/ldap/WritableLDAPUserModelDelegate.java index 9a68f6a1ca..4debf0eaed 100755 --- a/federation/ldap/src/main/java/org/keycloak/federation/ldap/WritableLDAPUserModelDelegate.java +++ b/federation/ldap/src/main/java/org/keycloak/federation/ldap/WritableLDAPUserModelDelegate.java @@ -1,16 +1,11 @@ package org.keycloak.federation.ldap; import org.jboss.logging.Logger; -import org.keycloak.models.ModelException; +import org.keycloak.federation.ldap.idm.model.LDAPUser; +import org.keycloak.federation.ldap.idm.store.ldap.LDAPIdentityStore; import org.keycloak.models.UserCredentialModel; import org.keycloak.models.UserModel; import org.keycloak.models.utils.UserModelDelegate; -import org.picketlink.idm.IdentityManagementException; -import org.picketlink.idm.IdentityManager; -import org.picketlink.idm.credential.Password; -import org.picketlink.idm.credential.TOTPCredential; -import org.picketlink.idm.model.basic.BasicModel; -import org.picketlink.idm.model.basic.User; /** * @author Bill Burke @@ -28,52 +23,43 @@ public class WritableLDAPUserModelDelegate extends UserModelDelegate implements @Override public void setUsername(String username) { - IdentityManager identityManager = provider.getIdentityManager(); + LDAPIdentityStore ldapIdentityStore = provider.getLdapIdentityStore(); - try { - User picketlinkUser = BasicModel.getUser(identityManager, delegate.getUsername()); - if (picketlinkUser == null) { - throw new IllegalStateException("User not found in LDAP storage!"); - } - picketlinkUser.setLoginName(username); - identityManager.update(picketlinkUser); - } catch (IdentityManagementException ie) { - throw new ModelException(ie); + LDAPUser ldapUser = LDAPUtils.getUser(ldapIdentityStore, delegate.getUsername()); + if (ldapUser == null) { + throw new IllegalStateException("User not found in LDAP storage!"); } + ldapUser.setLoginName(username); + ldapIdentityStore.update(ldapUser); + delegate.setUsername(username); } @Override public void setLastName(String lastName) { - IdentityManager identityManager = provider.getIdentityManager(); + LDAPIdentityStore ldapIdentityStore = provider.getLdapIdentityStore(); - try { - User picketlinkUser = BasicModel.getUser(identityManager, delegate.getUsername()); - if (picketlinkUser == null) { - throw new IllegalStateException("User not found in LDAP storage!"); - } - picketlinkUser.setLastName(lastName); - identityManager.update(picketlinkUser); - } catch (IdentityManagementException ie) { - throw new ModelException(ie); + LDAPUser ldapUser = LDAPUtils.getUser(ldapIdentityStore, delegate.getUsername()); + if (ldapUser == null) { + throw new IllegalStateException("User not found in LDAP storage!"); } + ldapUser.setLastName(lastName); + ldapIdentityStore.update(ldapUser); + delegate.setLastName(lastName); } @Override public void setFirstName(String first) { - IdentityManager identityManager = provider.getIdentityManager(); + LDAPIdentityStore ldapIdentityStore = provider.getLdapIdentityStore(); - try { - User picketlinkUser = BasicModel.getUser(identityManager, delegate.getUsername()); - if (picketlinkUser == null) { - throw new IllegalStateException("User not found in LDAP storage!"); - } - picketlinkUser.setFirstName(first); - identityManager.update(picketlinkUser); - } catch (IdentityManagementException ie) { - throw new ModelException(ie); + LDAPUser ldapUser = LDAPUtils.getUser(ldapIdentityStore, delegate.getUsername()); + if (ldapUser == null) { + throw new IllegalStateException("User not found in LDAP storage!"); } + ldapUser.setFirstName(first); + ldapIdentityStore.update(ldapUser); + delegate.setFirstName(first); } @@ -83,41 +69,31 @@ public class WritableLDAPUserModelDelegate extends UserModelDelegate implements delegate.updateCredential(cred); return; } - IdentityManager identityManager = provider.getIdentityManager(); - try { - User picketlinkUser = BasicModel.getUser(identityManager, getUsername()); - if (picketlinkUser == null) { - logger.debugf("User '%s' doesn't exists. Skip password update", getUsername()); - throw new IllegalStateException("User doesn't exist in LDAP storage"); - } - if (cred.getType().equals(UserCredentialModel.PASSWORD)) { - identityManager.updateCredential(picketlinkUser, new Password(cred.getValue().toCharArray())); - } else if (cred.getType().equals(UserCredentialModel.TOTP)) { - TOTPCredential credential = new TOTPCredential(cred.getValue()); - credential.setDevice(cred.getDevice()); - identityManager.updateCredential(picketlinkUser, credential); - } - } catch (IdentityManagementException ie) { - throw new ModelException(ie); + LDAPIdentityStore ldapIdentityStore = provider.getLdapIdentityStore(); + LDAPUser ldapUser = LDAPUtils.getUser(ldapIdentityStore, delegate.getUsername()); + if (ldapUser == null) { + throw new IllegalStateException("User " + delegate.getUsername() + " not found in LDAP storage!"); } + if (cred.getType().equals(UserCredentialModel.PASSWORD)) { + LDAPUtils.updatePassword(ldapIdentityStore, delegate, cred.getValue()); + } else { + logger.warnf("Don't know how to update credential of type [%s] for user [%s]", cred.getType(), delegate.getUsername()); + } } @Override public void setEmail(String email) { - IdentityManager identityManager = provider.getIdentityManager(); + LDAPIdentityStore ldapIdentityStore = provider.getLdapIdentityStore(); - try { - User picketlinkUser = BasicModel.getUser(identityManager, delegate.getUsername()); - if (picketlinkUser == null) { - throw new IllegalStateException("User not found in LDAP storage!"); - } - picketlinkUser.setEmail(email); - identityManager.update(picketlinkUser); - } catch (IdentityManagementException ie) { - throw new ModelException(ie); + LDAPUser ldapUser = LDAPUtils.getUser(ldapIdentityStore, delegate.getUsername()); + if (ldapUser == null) { + throw new IllegalStateException("User not found in LDAP storage!"); } + ldapUser.setEmail(email); + ldapIdentityStore.update(ldapUser); + delegate.setEmail(email); } diff --git a/federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/model/AbstractAttributedType.java b/federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/model/AbstractAttributedType.java new file mode 100644 index 0000000000..7e6d80b0f1 --- /dev/null +++ b/federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/model/AbstractAttributedType.java @@ -0,0 +1,85 @@ +package org.keycloak.federation.ldap.idm.model; + +import java.io.Serializable; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +import static java.util.Collections.unmodifiableCollection; +import static java.util.Collections.unmodifiableMap; + +/** + * Abstract base class for all AttributedType implementations + * + * @author Shane Bryzak + * + */ +public abstract class AbstractAttributedType implements AttributedType { + private static final long serialVersionUID = -6118293036241099199L; + + private String id; + private String entryDN; + + private Map> attributes = + new HashMap>(); + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getEntryDN() { + return entryDN; + } + + public void setEntryDN(String entryDN) { + this.entryDN = entryDN; + } + + public void setAttribute(Attribute attribute) { + attributes.put(attribute.getName(), attribute); + } + + public void removeAttribute(String name) { + attributes.remove(name); + } + + @SuppressWarnings("unchecked") + public Attribute getAttribute(String name) { + return (Attribute) attributes.get(name); + } + + public Collection> getAttributes() { + return unmodifiableCollection(attributes.values()); + } + + public Map> getAttributesMap() { + return unmodifiableMap(attributes); + } + + @Override + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + + if (!getClass().isInstance(obj)) { + return false; + } + + AttributedType other = (AttributedType) obj; + + return getId() != null && other.getId() != null && getId().equals(other.getId()); + } + + @Override + public int hashCode() { + int result = getId() != null ? getId().hashCode() : 0; + result = 31 * result + (getId() != null ? getId().hashCode() : 0); + return result; + } + +} \ No newline at end of file diff --git a/federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/model/AbstractIdentityType.java b/federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/model/AbstractIdentityType.java new file mode 100644 index 0000000000..8ee8bd6bd1 --- /dev/null +++ b/federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/model/AbstractIdentityType.java @@ -0,0 +1,70 @@ +package org.keycloak.federation.ldap.idm.model; + +import java.util.Date; + +/** + * Abstract base class for IdentityType implementations + * + * @author Shane Bryzak + */ +public abstract class AbstractIdentityType extends AbstractAttributedType implements IdentityType { + + private static final long serialVersionUID = 2843998332737143820L; + + private boolean enabled = true; + private Date createdDate = new Date(); + private Date expirationDate = null; + + public boolean isEnabled() { + return this.enabled; + } + + @Override + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } + + @Override + @AttributeProperty + public Date getExpirationDate() { + return this.expirationDate; + } + + @Override + public void setExpirationDate(Date expirationDate) { + this.expirationDate = expirationDate; + } + + @Override + @AttributeProperty + public Date getCreatedDate() { + return this.createdDate; + } + + @Override + public void setCreatedDate(Date createdDate) { + this.createdDate = createdDate; + } + + @Override + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + + if (!getClass().isInstance(obj)) { + return false; + } + + IdentityType other = (IdentityType) obj; + + return (getId() != null && other.getId() != null) + && (getId().equals(other.getId())); + } + + @Override + public int hashCode() { + return super.hashCode(); + } +} + diff --git a/federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/model/Attribute.java b/federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/model/Attribute.java new file mode 100644 index 0000000000..82dac06b87 --- /dev/null +++ b/federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/model/Attribute.java @@ -0,0 +1,80 @@ +package org.keycloak.federation.ldap.idm.model; + +import java.io.Serializable; + +/** + * Represents an attribute value, a type of metadata that can be associated with an IdentityType + * + * @author Shane Bryzak + * + * @param + */ +public class Attribute implements Serializable { + + private static final long serialVersionUID = 237211288303510728L; + + /** + * The name of the attribute + */ + private String name; + + /** + * The attribute value. + */ + private T value; + + /** + * Indicates whether this Attribute has a read-only value + */ + private boolean readOnly = false; + + /** + * Indicates whether the Attribute value has been loaded + */ + private boolean loaded = false; + + public Attribute(String name, T value) { + this.name = name; + this.value = value; + } + + public Attribute(String name, T value, boolean readOnly) { + this(name, value); + this.readOnly = readOnly; + } + + public String getName() { + return name; + } + + public T getValue() { + return value; + } + + public boolean isReadOnly() { + return readOnly; + } + + public boolean isLoaded() { + return loaded; + } + + public void setLoaded(boolean value) { + this.loaded = value; + } + + /** + * Sets the value for this attribute. If the Attribute value is readOnly, a RuntimeException is thrown. + * + * @param value + */ + public void setValue(T value) { + if (readOnly) { + throw new RuntimeException("Error setting Attribute value [" + name + " ] - value is read only."); + } + this.value = value; + } +} + + + diff --git a/federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/model/AttributeProperty.java b/federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/model/AttributeProperty.java new file mode 100644 index 0000000000..33b8706fca --- /dev/null +++ b/federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/model/AttributeProperty.java @@ -0,0 +1,31 @@ +package org.keycloak.federation.ldap.idm.model; + +import java.lang.annotation.Documented; +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +/** + * Marks a property of an IdentityType, Partition or Relationship as being an attribute of that + * IdentityType, Partition or Relationship. + * + * @author Shane Bryzak + */ +@Target({METHOD, FIELD}) +@Documented +@Retention(RUNTIME) +@Inherited +public @interface AttributeProperty { + + /** + *

Managed properties are stored as ad-hoc attributes and mapped from and to a specific property of a type.

+ * + * @return + */ + boolean managed() default false; + +} diff --git a/federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/model/AttributedType.java b/federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/model/AttributedType.java new file mode 100644 index 0000000000..5c374278c2 --- /dev/null +++ b/federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/model/AttributedType.java @@ -0,0 +1,75 @@ +package org.keycloak.federation.ldap.idm.model; + +import java.io.Serializable; +import java.util.Collection; + +import org.keycloak.federation.ldap.idm.query.AttributeParameter; +import org.keycloak.federation.ldap.idm.query.QueryParameter; + +/** + * + * @author Shane Bryzak + * + */ +public interface AttributedType extends Serializable { + + /** + * A query parameter used to set the id value. + */ + QueryParameter ID = new AttributeParameter("id"); + + /** + * Returns the unique identifier for this instance + * @return + */ + String getId(); + + /** + * Sets the unique identifier for this instance + * @return + */ + void setId(String id); + + /** + * Set the specified attribute. This operation will overwrite any previous value. + * + * @param attribute to be set + */ + void setAttribute(Attribute attribute); + + /** + * Remove the attribute with given name + * + * @param name of attribute + */ + void removeAttribute(String name); + + + // LDAP specific stuff + void setEntryDN(String entryDN); + String getEntryDN(); + + + /** + * Return the attribute value with the specified name + * + * @param name of attribute + * @return attribute value or null if attribute with given name doesn't exist. If given attribute has many values method + * will return first one + */ + Attribute getAttribute(String name); + + /** + * Returns a Map containing all attribute values for this IdentityType instance. + * + * @return map of attribute names and their values + */ + Collection> getAttributes(); + + public final class QUERY_ATTRIBUTE { + public static AttributeParameter byName(String name) { + return new AttributeParameter(name); + } + } +} + diff --git a/federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/model/IdentityType.java b/federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/model/IdentityType.java new file mode 100644 index 0000000000..f8ae8a1833 --- /dev/null +++ b/federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/model/IdentityType.java @@ -0,0 +1,100 @@ +package org.keycloak.federation.ldap.idm.model; + +import java.util.Date; + +import org.keycloak.federation.ldap.idm.query.AttributeParameter; +import org.keycloak.federation.ldap.idm.query.QueryParameter; + +/** + * This interface is the base for all identity model objects. It declares a number of + * properties that must be supported by all identity types, in addition to defining the API + * for identity attribute management. + * + * @author Shane Bryzak + */ +public interface IdentityType extends AttributedType { + + /** + * A query parameter used to set the enabled value. + */ + QueryParameter ENABLED = new AttributeParameter("enabled"); + + /** + * A query parameter used to set the createdDate value + */ + QueryParameter CREATED_DATE = new AttributeParameter("createdDate"); + + /** + * A query parameter used to set the created after date + */ + QueryParameter CREATED_AFTER = new AttributeParameter("createdDate"); + + /** + * A query parameter used to set the modified after date + */ + QueryParameter MODIFIED_AFTER = new AttributeParameter("modifyDate"); + + /** + * A query parameter used to set the created before date + */ + QueryParameter CREATED_BEFORE = new AttributeParameter("createdDate"); + + /** + * A query parameter used to set the expiryDate value + */ + QueryParameter EXPIRY_DATE = new AttributeParameter("expirationDate"); + + /** + * A query parameter used to set the expiration after date + */ + QueryParameter EXPIRY_AFTER = new AttributeParameter("expirationDate"); + + /** + * A query parameter used to set the expiration before date + */ + QueryParameter EXPIRY_BEFORE = new AttributeParameter("expirationDate"); + + /** + * Indicates the current enabled status of this IdentityType. + * + * @return A boolean value indicating whether this IdentityType is enabled. + */ + boolean isEnabled(); + + /** + *

Sets the current enabled status of this {@link IdentityType}.

+ * + * @param enabled + */ + void setEnabled(boolean enabled); + + /** + * Returns the date that this IdentityType instance was created. + * + * @return Date value representing the creation date + */ + Date getCreatedDate(); + + /** + *

Sets the date that this {@link IdentityType} was created.

+ * + * @param createdDate + */ + void setCreatedDate(Date createdDate); + + /** + * Returns the date that this IdentityType expires, or null if there is no expiry date. + * + * @return + */ + Date getExpirationDate(); + + /** + *

Sets the date that this {@link IdentityType} expires.

+ * + * @param expirationDate + */ + void setExpirationDate(Date expirationDate); + +} + diff --git a/federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/model/LDAPUser.java b/federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/model/LDAPUser.java new file mode 100644 index 0000000000..4ce7ef9516 --- /dev/null +++ b/federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/model/LDAPUser.java @@ -0,0 +1,85 @@ +package org.keycloak.federation.ldap.idm.model; + + +import org.keycloak.federation.ldap.idm.query.QueryParameter; + +/** + * This class represents a User; a human agent that may authenticate with the application + * + * @author Shane Bryzak + */ +public class LDAPUser extends AbstractIdentityType { + + private static final long serialVersionUID = 4117586097100398485L; + + public static final QueryParameter LOGIN_NAME = AttributedType.QUERY_ATTRIBUTE.byName("loginName"); + + /** + * A query parameter used to set the firstName value. + */ + public static final QueryParameter FIRST_NAME = QUERY_ATTRIBUTE.byName("firstName"); + + /** + * A query parameter used to set the lastName value. + */ + public static final QueryParameter LAST_NAME = QUERY_ATTRIBUTE.byName("lastName"); + + /** + * A query parameter used to set the email value. + */ + public static final QueryParameter EMAIL = QUERY_ATTRIBUTE.byName("email"); + + @AttributeProperty + private String loginName; + + @AttributeProperty + private String firstName; + + @AttributeProperty + private String lastName; + + @AttributeProperty + private String email; + + public LDAPUser() { + + } + + public LDAPUser(String loginName) { + this.loginName = loginName; + } + + public String getLoginName() { + return loginName; + } + + public void setLoginName(String loginName) { + this.loginName = loginName; + } + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + public String getEmail() { + return this.email; + } + + public void setEmail(String email) { + this.email = email; + } + +} + diff --git a/federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/query/AttributeParameter.java b/federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/query/AttributeParameter.java new file mode 100644 index 0000000000..c5feea9319 --- /dev/null +++ b/federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/query/AttributeParameter.java @@ -0,0 +1,21 @@ +package org.keycloak.federation.ldap.idm.query; + +/** + *

This class can be used to define a query parameter for properties annotated with + * {@link org.keycloak.federation.ldap.idm.model.AttributeProperty}. + *

+ * + * @author pedroigor + */ +public class AttributeParameter implements QueryParameter { + + private final String name; + + public AttributeParameter(String name) { + this.name = name; + } + + public String getName() { + return this.name; + } +} diff --git a/federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/query/Condition.java b/federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/query/Condition.java new file mode 100644 index 0000000000..85d81d8915 --- /dev/null +++ b/federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/query/Condition.java @@ -0,0 +1,18 @@ +package org.keycloak.federation.ldap.idm.query; + +/** + *

A {@link Condition} is used to specify how a specific {@link QueryParameter} + * is defined in order to filter query results.

+ * + * @author Pedro Igor + */ +public interface Condition { + + /** + *

The {@link QueryParameter} restricted by this condition.

+ * + * @return + */ + QueryParameter getParameter(); + +} \ No newline at end of file diff --git a/federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/query/IdentityQuery.java b/federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/query/IdentityQuery.java new file mode 100644 index 0000000000..1a77727fa8 --- /dev/null +++ b/federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/query/IdentityQuery.java @@ -0,0 +1,225 @@ +package org.keycloak.federation.ldap.idm.query; + +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.keycloak.federation.ldap.idm.model.IdentityType; + +/** + *

An {@link IdentityQuery} is responsible for querying the underlying identity stores for instances of + * a given {@link IdentityType}.

+ * + *

Instances of this class are obtained using the {@link IdentityQueryBuilder#createIdentityQuery(Class)} + * method.

+ * + *
+ *      IdentityManager identityManager = getIdentityManager();
+ *
+ *      // here we get the query builder
+ *      IdentityQueryBuilder builder = identityManager.getQueryBuilder();
+ *
+ *      // create a condition
+ *      Condition condition = builder.equal(User.LOGIN_NAME, "john");
+ *
+ *      // create a query for a specific identity type using the previously created condition
+ *      IdentityQuery query = builder.createIdentityQuery(User.class).where(condition);
+ *
+ *      // execute the query
+ *      List result = query.getResultList();
+ * 
+ * + *

When preparing a query you may want to create conditions to filter its results and configure how they must be retrieved. + * For that, you can use the {@link IdentityQueryBuilder}, which provides useful methods for creating + * different expressions and conditions.

+ * + * @author Shane Bryzak + * @author Pedro Igor + */ +public interface IdentityQuery { + + /** + * @see #setPaginationContext(Object object) + */ + Object getPaginationContext(); + + /** + * Used for pagination models like LDAP when search will return some object (like cookie) for searching on next page + * + * @param object to be used for search next page + * + * @return this query + */ + IdentityQuery setPaginationContext(Object object); + + /** + * @deprecated Will be removed soon. + * + * @see #setSortParameters(QueryParameter...) + */ + @Deprecated + QueryParameter[] getSortParameters(); + + /** + * Parameters used to sort the results. First parameter has biggest priority. For example: setSortParameter(User.LAST_NAME, + * User.FIRST_NAME) means that results will be sorted primarily by lastName and firstName will be used to sort only records with + * same lastName + * + * @param sortParameters parameters to specify sort criteria + * + * @deprecated Use {@link IdentityQuery#sortBy(Sort...)} instead. Where you can create sort conditions + * from the {@link IdentityQueryBuilder}. + * + * @return this query + */ + @Deprecated + IdentityQuery setSortParameters(QueryParameter... sortParameters); + + /** + * @deprecated Use {@link IdentityQuery#getSorting()} for a list of sorting conditions. Will be removed soon. + * + * @return true if sorting will be ascending + * + * @see #setSortAscending(boolean) + */ + @Deprecated + boolean isSortAscending(); + + /** + * Specify if sorting will be ascending (true) or descending (false) + * + * @param sortAscending to specify if sorting will be ascending or descending + * + * @deprecated Use {@link IdentityQuery#sortBy(Sort...)} instead. Where you can create sort conditions + * from the {@link IdentityQueryBuilder}. + * + * @return this query + */ + @Deprecated + IdentityQuery setSortAscending(boolean sortAscending); + + /** + *

Set a query parameter to this query in order to filter the results.

+ * + *

This method always create an equality condition. For more conditions options take a look at {@link + * IdentityQueryBuilder} and use the {@link IdentityQuery#where(Condition...)} + * instead.

+ * + * @param param The query parameter. + * @param value The value to match for equality. + * + * @return + * + * @deprecated Use {@link IdentityQuery#where(Condition...)} to specify query conditions. + */ + @Deprecated + IdentityQuery setParameter(QueryParameter param, Object... value); + + /** + *

Add to this query the conditions that will be used to filter results.

+ * + *

Any condition previously added to this query will be preserved and the new conditions added. If you want to clear the + * conditions you must create a new query instance.

+ * + * @param condition One or more conditions created from {@link IdentityQueryBuilder}. + * + * @return + */ + IdentityQuery where(Condition... condition); + + /** + *

Add to this query the sorting conditions to be applied to the results.

+ * + * @param sorts The ordering conditions. + * + * @return + */ + IdentityQuery sortBy(Sort... sorts); + + /** + *

The type used to create this query.

+ * + * @return + */ + Class getIdentityType(); + + /** + *

Returns a map with all the parameter set for this query.

+ * + * @return + * + * @deprecated Use {@link IdentityQuery#getConditions()} instead. Will be removed. + */ + @Deprecated + Map getParameters(); + + /** + *

Returns a set containing all conditions used by this query to filter its results.

+ * + * @return + */ + Set getConditions(); + + /** + *

Returns a set containing all sorting conditions used to filter the results.

+ * + * @return + */ + Set getSorting(); + + /** + *

Returns the value used to restrict the given query parameter.

+ * + * @param queryParameter + * + * @return + */ + @Deprecated + Object[] getParameter(QueryParameter queryParameter); + + @Deprecated + Map getParameters(Class type); + + int getOffset(); + + /** + *

Set the position of the first result to retrieve.

+ * + * @param offset + * + * @return + */ + IdentityQuery setOffset(int offset); + + /** + *

Returns the number of instances to retrieve.

+ * + * @return + */ + int getLimit(); + + /** + *

Set the maximum number of results to retrieve.

+ * + * @param limit the number of instances to retrieve. + * + * @return + */ + IdentityQuery setLimit(int limit); + + /** + *

Execute the query against the underlying identity stores and returns a list containing all instances of + * the type (defined when creating this query instance) that match the conditions previously specified.

+ * + * @return + */ + List getResultList(); + + /** + * Count of all query results. It takes into account query parameters, but it doesn't take into account pagination parameter + * like offset and limit + * + * @return count of all query results + */ + int getResultCount(); +} diff --git a/federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/query/IdentityQueryBuilder.java b/federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/query/IdentityQueryBuilder.java new file mode 100644 index 0000000000..022063521b --- /dev/null +++ b/federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/query/IdentityQueryBuilder.java @@ -0,0 +1,124 @@ +package org.keycloak.federation.ldap.idm.query; + +import org.keycloak.federation.ldap.idm.model.IdentityType; + +/** + *

The {@link IdentityQueryBuilder} is responsible for creating {@link IdentityQuery} instances and also + * provide methods to create conditions, orderings, sorting, etc.

+ * + * @author Pedro Igor + */ +public interface IdentityQueryBuilder { + + /** + *

Create a condition for testing the whether the query parameter satisfies the given pattern..

+ * + * @param parameter The query parameter. + * @param pattern The pattern to match. + * + * @return + */ + Condition like(QueryParameter parameter, String pattern); + + /** + *

Create a condition for testing the arguments for equality.

+ * + * @param parameter The query parameter. + * @param value The value to compare. + * + * @return + */ + Condition equal(QueryParameter parameter, Object value); + + /** + *

Create a condition for testing whether the query parameter is grater than the given value..

+ * + * @param parameter The query parameter. + * @param x The value to compare. + * + * @return + */ + Condition greaterThan(QueryParameter parameter, Object x); + + /** + *

Create a condition for testing whether the query parameter is grater than or equal to the given value..

+ * + * @param parameter The query parameter. + * @param x The value to compare. + * + * @return + */ + Condition greaterThanOrEqualTo(QueryParameter parameter, Object x); + + /** + *

Create a condition for testing whether the query parameter is less than the given value..

+ * + * @param parameter The query parameter. + * @param x The value to compare. + * + * @return + */ + Condition lessThan(QueryParameter parameter, Object x); + + /** + *

Create a condition for testing whether the query parameter is less than or equal to the given value..

+ * + * @param parameter The query parameter. + * @param x The value to compare. + * + * @return + */ + Condition lessThanOrEqualTo(QueryParameter parameter, Object x); + + /** + *

Create a condition for testing whether the query parameter is between the given values.

+ * + * @param parameter The query parameter. + * @param x The first value. + * @param x The second value. + * + * @return + */ + Condition between(QueryParameter parameter, Object x, Object y); + + /** + *

Create a condition for testing whether the query parameter is contained in a list of values.

+ * + * @param parameter The query parameter. + * @param values A list of values. + * + * @return + */ + Condition in(QueryParameter parameter, Object... values); + + /** + *

Create an ascending order for the given parameter. Once created, you can use it to sort the results of a + * query.

+ * + * @param parameter The query parameter to sort. + * + * @return + */ + Sort asc(QueryParameter parameter); + + /** + *

Create an descending order for the given parameter. Once created, you can use it to sort the results of a + * query.

+ * + * @param parameter The query parameter to sort. + * + * @return + */ + Sort desc(QueryParameter parameter); + + /** + *

Create an {@link IdentityQuery} that can be used to query for {@link + * IdentityType} instances of a the given identityType.

+ * + * @param identityType The type to search. If you provide the {@link IdentityType} + * base interface any of its sub-types will be returned. + * + * @return + */ + IdentityQuery createIdentityQuery(Class identityType); +} diff --git a/federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/query/QueryParameter.java b/federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/query/QueryParameter.java new file mode 100644 index 0000000000..ae2bbdf910 --- /dev/null +++ b/federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/query/QueryParameter.java @@ -0,0 +1,12 @@ +package org.keycloak.federation.ldap.idm.query; + +/** + * A marker interface indicating that the implementing class can be used as a + * parameter within an IdentityQuery or RelationshipQuery + * + * @author Shane Bryzak + * + */ +public interface QueryParameter { + +} diff --git a/federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/query/Sort.java b/federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/query/Sort.java new file mode 100644 index 0000000000..dfd331ed59 --- /dev/null +++ b/federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/query/Sort.java @@ -0,0 +1,23 @@ +package org.keycloak.federation.ldap.idm.query; + +/** + * @author Pedro Igor + */ +public class Sort { + + private final QueryParameter parameter; + private final boolean asc; + + public Sort(QueryParameter parameter, boolean asc) { + this.parameter = parameter; + this.asc = asc; + } + + public QueryParameter getParameter() { + return this.parameter; + } + + public boolean isAscending() { + return asc; + } +} diff --git a/federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/query/internal/BetweenCondition.java b/federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/query/internal/BetweenCondition.java new file mode 100644 index 0000000000..672fdaa72b --- /dev/null +++ b/federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/query/internal/BetweenCondition.java @@ -0,0 +1,33 @@ +package org.keycloak.federation.ldap.idm.query.internal; + +import org.keycloak.federation.ldap.idm.query.Condition; +import org.keycloak.federation.ldap.idm.query.QueryParameter; + +/** + * @author Pedro Igor + */ +public class BetweenCondition implements Condition { + + private final Comparable x; + private final Comparable y; + private final QueryParameter parameter; + + public BetweenCondition(QueryParameter parameter, Comparable x, Comparable y) { + this.parameter = parameter; + this.x = x; + this.y = y; + } + + @Override + public QueryParameter getParameter() { + return this.parameter; + } + + public Comparable getX() { + return this.x; + } + + public Comparable getY() { + return this.y; + } +} diff --git a/federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/query/internal/DefaultIdentityQuery.java b/federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/query/internal/DefaultIdentityQuery.java new file mode 100644 index 0000000000..21b02537da --- /dev/null +++ b/federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/query/internal/DefaultIdentityQuery.java @@ -0,0 +1,207 @@ +package org.keycloak.federation.ldap.idm.query.internal; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.keycloak.federation.ldap.idm.model.IdentityType; +import org.keycloak.federation.ldap.idm.query.Condition; +import org.keycloak.federation.ldap.idm.query.IdentityQuery; +import org.keycloak.federation.ldap.idm.query.IdentityQueryBuilder; +import org.keycloak.federation.ldap.idm.query.QueryParameter; +import org.keycloak.federation.ldap.idm.query.Sort; +import org.keycloak.federation.ldap.idm.store.IdentityStore; +import org.keycloak.models.ModelException; + +import static java.util.Collections.unmodifiableSet; + +/** + * Default IdentityQuery implementation. + * + * @param + * + * @author Shane Bryzak + */ +public class DefaultIdentityQuery implements IdentityQuery { + + private final Map parameters = new LinkedHashMap(); + private final Class identityType; + private final IdentityStore identityStore; + private final IdentityQueryBuilder queryBuilder; + private int offset; + private int limit; + private Object paginationContext; + private QueryParameter[] sortParameters; + private boolean sortAscending = true; + private final Set conditions = new LinkedHashSet(); + private final Set ordering = new LinkedHashSet(); + + public DefaultIdentityQuery(IdentityQueryBuilder queryBuilder, Class identityType, IdentityStore identityStore) { + this.queryBuilder = queryBuilder; + this.identityStore = identityStore; + this.identityType = identityType; + } + + @Override + public IdentityQuery setParameter(QueryParameter queryParameter, Object... value) { + if (value == null || value.length == 0) { + throw new ModelException("Query Parameter values null or empty"); + } + + parameters.put(queryParameter, value); + + if (IdentityType.CREATED_AFTER.equals(queryParameter) || IdentityType.EXPIRY_AFTER.equals(queryParameter)) { + this.conditions.add(queryBuilder.greaterThanOrEqualTo(queryParameter, value[0])); + } else if (IdentityType.CREATED_BEFORE.equals(queryParameter) || IdentityType.EXPIRY_BEFORE.equals(queryParameter)) { + this.conditions.add(queryBuilder.lessThanOrEqualTo(queryParameter, value[0])); + } else { + this.conditions.add(queryBuilder.equal(queryParameter, value[0])); + } + + return this; + } + + @Override + public IdentityQuery where(Condition... condition) { + this.conditions.addAll(Arrays.asList(condition)); + return this; + } + + @Override + public IdentityQuery sortBy(Sort... sorts) { + this.ordering.addAll(Arrays.asList(sorts)); + return this; + } + + @Override + public Set getSorting() { + return unmodifiableSet(this.ordering); + } + + @Override + public Class getIdentityType() { + return identityType; + } + + @Override + public Map getParameters() { + return parameters; + } + + @Override + public Object[] getParameter(QueryParameter queryParameter) { + return this.parameters.get(queryParameter); + } + + @Override + public Map getParameters(Class type) { + Map typedParameters = new HashMap(); + + Set> entrySet = this.parameters.entrySet(); + + for (Map.Entry entry : entrySet) { + if (type.isInstance(entry.getKey())) { + typedParameters.put(entry.getKey(), entry.getValue()); + } + } + + return typedParameters; + } + + @Override + public int getLimit() { + return limit; + } + + @Override + public int getOffset() { + return offset; + } + + @Override + public Object getPaginationContext() { + return paginationContext; + } + + @Override + public QueryParameter[] getSortParameters() { + return sortParameters; + } + + @Override + public boolean isSortAscending() { + return sortAscending; + } + + @Override + public List getResultList() { + + // remove this statement once deprecated methods on IdentityQuery are removed + if (this.sortParameters != null) { + for (QueryParameter parameter : this.sortParameters) { + if (isSortAscending()) { + sortBy(this.queryBuilder.asc(parameter)); + } else { + sortBy(this.queryBuilder.desc(parameter)); + } + } + } + + List result = new ArrayList(); + + try { + for (T identityType : identityStore.fetchQueryResults(this)) { + result.add(identityType); + } + } catch (Exception e) { + throw new ModelException("LDAP Query failed", e); + } + + return result; + } + + @Override + public int getResultCount() { + return identityStore.countQueryResults(this); + } + + @Override + public IdentityQuery setOffset(int offset) { + this.offset = offset; + return this; + } + + @Override + public IdentityQuery setLimit(int limit) { + this.limit = limit; + return this; + } + + @Override + public IdentityQuery setSortParameters(QueryParameter... sortParameters) { + this.sortParameters = sortParameters; + return this; + } + + @Override + public IdentityQuery setSortAscending(boolean sortAscending) { + this.sortAscending = sortAscending; + return this; + } + + @Override + public IdentityQuery setPaginationContext(Object object) { + this.paginationContext = object; + return this; + } + + @Override + public Set getConditions() { + return unmodifiableSet(this.conditions); + } +} diff --git a/federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/query/internal/DefaultQueryBuilder.java b/federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/query/internal/DefaultQueryBuilder.java new file mode 100644 index 0000000000..5d3b72e165 --- /dev/null +++ b/federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/query/internal/DefaultQueryBuilder.java @@ -0,0 +1,89 @@ +package org.keycloak.federation.ldap.idm.query.internal; + +import org.keycloak.federation.ldap.idm.model.IdentityType; +import org.keycloak.federation.ldap.idm.query.Condition; +import org.keycloak.federation.ldap.idm.query.IdentityQuery; +import org.keycloak.federation.ldap.idm.query.IdentityQueryBuilder; +import org.keycloak.federation.ldap.idm.query.QueryParameter; +import org.keycloak.federation.ldap.idm.query.Sort; +import org.keycloak.federation.ldap.idm.store.IdentityStore; +import org.keycloak.models.ModelException; + +/** + * @author Pedro Igor + */ +public class DefaultQueryBuilder implements IdentityQueryBuilder { + + private final IdentityStore identityStore; + + public DefaultQueryBuilder(IdentityStore identityStore) { + this.identityStore = identityStore; + } + + @Override + public Condition like(QueryParameter parameter, String pattern) { + return new LikeCondition(parameter, pattern); + } + + @Override + public Condition equal(QueryParameter parameter, Object value) { + return new EqualCondition(parameter, value); + } + + @Override + public Condition greaterThan(QueryParameter parameter, Object x) { + throwExceptionIfNotComparable(x); + return new GreaterThanCondition(parameter, (Comparable) x, false); + } + + @Override + public Condition greaterThanOrEqualTo(QueryParameter parameter, Object x) { + throwExceptionIfNotComparable(x); + return new GreaterThanCondition(parameter, (Comparable) x, true); + } + + @Override + public Condition lessThan(QueryParameter parameter, Object x) { + throwExceptionIfNotComparable(x); + return new LessThanCondition(parameter, (Comparable) x, false); + } + + @Override + public Condition lessThanOrEqualTo(QueryParameter parameter, Object x) { + throwExceptionIfNotComparable(x); + return new LessThanCondition(parameter, (Comparable) x, true); + } + + @Override + public Condition between(QueryParameter parameter, Object x, Object y) { + throwExceptionIfNotComparable(x); + throwExceptionIfNotComparable(y); + return new BetweenCondition(parameter, (Comparable) x, (Comparable) y); + } + + @Override + public Condition in(QueryParameter parameter, Object... x) { + return new InCondition(parameter, x); + } + + @Override + public Sort asc(QueryParameter parameter) { + return new Sort(parameter, true); + } + + @Override + public Sort desc(QueryParameter parameter) { + return new Sort(parameter, false); + } + + @Override + public IdentityQuery createIdentityQuery(Class identityType) { + return new DefaultIdentityQuery(this, identityType, this.identityStore); + } + + private void throwExceptionIfNotComparable(Object x) { + if (!Comparable.class.isInstance(x)) { + throw new ModelException("Query parameter value [" + x + "] must be " + Comparable.class + "."); + } + } +} \ No newline at end of file diff --git a/federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/query/internal/EqualCondition.java b/federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/query/internal/EqualCondition.java new file mode 100644 index 0000000000..a3fee26e13 --- /dev/null +++ b/federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/query/internal/EqualCondition.java @@ -0,0 +1,36 @@ +package org.keycloak.federation.ldap.idm.query.internal; + +import org.keycloak.federation.ldap.idm.query.AttributeParameter; +import org.keycloak.federation.ldap.idm.query.Condition; +import org.keycloak.federation.ldap.idm.query.QueryParameter; + +/** + * @author Pedro Igor + */ +public class EqualCondition implements Condition { + + private final QueryParameter parameter; + private final Object value; + + public EqualCondition(QueryParameter parameter, Object value) { + this.parameter = parameter; + this.value = value; + } + + @Override + public QueryParameter getParameter() { + return this.parameter; + } + + public Object getValue() { + return this.value; + } + + @Override + public String toString() { + return "EqualCondition{" + + "parameter=" + ((AttributeParameter) parameter).getName() + + ", value=" + value + + '}'; + } +} diff --git a/federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/query/internal/GreaterThanCondition.java b/federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/query/internal/GreaterThanCondition.java new file mode 100644 index 0000000000..cbdf5407b6 --- /dev/null +++ b/federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/query/internal/GreaterThanCondition.java @@ -0,0 +1,34 @@ +package org.keycloak.federation.ldap.idm.query.internal; + +import org.keycloak.federation.ldap.idm.query.Condition; +import org.keycloak.federation.ldap.idm.query.QueryParameter; + +/** + * @author Pedro Igor + */ +public class GreaterThanCondition implements Condition { + + private final boolean orEqual; + + private final QueryParameter parameter; + private final Comparable value; + + public GreaterThanCondition(QueryParameter parameter, Comparable value, boolean orEqual) { + this.parameter = parameter; + this.value = value; + this.orEqual = orEqual; + } + + @Override + public QueryParameter getParameter() { + return this.parameter; + } + + public Comparable getValue() { + return this.value; + } + + public boolean isOrEqual() { + return this.orEqual; + } +} \ No newline at end of file diff --git a/federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/query/internal/InCondition.java b/federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/query/internal/InCondition.java new file mode 100644 index 0000000000..54d22342a9 --- /dev/null +++ b/federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/query/internal/InCondition.java @@ -0,0 +1,28 @@ +package org.keycloak.federation.ldap.idm.query.internal; + +import org.keycloak.federation.ldap.idm.query.Condition; +import org.keycloak.federation.ldap.idm.query.QueryParameter; + +/** + * @author Pedro Igor + */ +public class InCondition implements Condition { + + private final QueryParameter parameter; + private final Object[] value; + + public InCondition(QueryParameter parameter, Object[] value) { + this.parameter = parameter; + this.value = value; + } + + @Override + public QueryParameter getParameter() { + return this.parameter; + } + + public Object[] getValue() { + return this.value; + } +} + diff --git a/federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/query/internal/LessThanCondition.java b/federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/query/internal/LessThanCondition.java new file mode 100644 index 0000000000..5906a5ced0 --- /dev/null +++ b/federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/query/internal/LessThanCondition.java @@ -0,0 +1,34 @@ +package org.keycloak.federation.ldap.idm.query.internal; + +import org.keycloak.federation.ldap.idm.query.Condition; +import org.keycloak.federation.ldap.idm.query.QueryParameter; + +/** + * @author Pedro Igor + */ +public class LessThanCondition implements Condition { + + private final boolean orEqual; + + private final QueryParameter parameter; + private final Comparable value; + + public LessThanCondition(QueryParameter parameter, Comparable value, boolean orEqual) { + this.parameter = parameter; + this.value = value; + this.orEqual = orEqual; + } + + @Override + public QueryParameter getParameter() { + return this.parameter; + } + + public Comparable getValue() { + return this.value; + } + + public boolean isOrEqual() { + return this.orEqual; + } +} diff --git a/federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/query/internal/LikeCondition.java b/federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/query/internal/LikeCondition.java new file mode 100644 index 0000000000..6c6810362b --- /dev/null +++ b/federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/query/internal/LikeCondition.java @@ -0,0 +1,28 @@ +package org.keycloak.federation.ldap.idm.query.internal; + +import org.keycloak.federation.ldap.idm.query.Condition; +import org.keycloak.federation.ldap.idm.query.QueryParameter; + +/** + * @author Pedro Igor + */ +public class LikeCondition implements Condition { + + private final QueryParameter parameter; + private final Object value; + + public LikeCondition(QueryParameter parameter, Object value) { + this.parameter = parameter; + this.value = value; + } + + @Override + public QueryParameter getParameter() { + return this.parameter; + } + + public Object getValue() { + return this.value; + } + +} diff --git a/federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/store/IdentityStore.java b/federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/store/IdentityStore.java new file mode 100644 index 0000000000..7fef705c86 --- /dev/null +++ b/federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/store/IdentityStore.java @@ -0,0 +1,81 @@ +package org.keycloak.federation.ldap.idm.store; + +import java.util.List; + +import org.keycloak.federation.ldap.idm.model.AttributedType; +import org.keycloak.federation.ldap.idm.model.IdentityType; +import org.keycloak.federation.ldap.idm.model.LDAPUser; +import org.keycloak.federation.ldap.idm.query.IdentityQuery; +import org.keycloak.federation.ldap.idm.store.ldap.LDAPIdentityStoreConfiguration; + +/** + * IdentityStore representation providing minimal SPI + * + * TODO: Rather remove this abstraction + * + * @author Boleslaw Dawidowicz + * @author Shane Bryzak + */ +public interface IdentityStore { + + /** + * Returns the configuration for this IdentityStore instance + * + * @return + */ + LDAPIdentityStoreConfiguration getConfig(); + + // General + + /** + * Persists the specified IdentityType + * + * @param value + */ + void add(AttributedType value); + + /** + * Updates the specified IdentityType + * + * @param value + */ + void update(AttributedType value); + + /** + * Removes the specified IdentityType + * + * @param value + */ + void remove(AttributedType value); + + // Identity query + + List fetchQueryResults(IdentityQuery identityQuery); + + int countQueryResults(IdentityQuery identityQuery); + +// // Relationship query +// +// List fetchQueryResults(RelationshipQuery query); +// +// int countQueryResults(RelationshipQuery query); + + // Credentials + + /** + * Validates the specified credentials. + * + * @param user Keycloak user + * @param password Ldap password + */ + boolean validatePassword(LDAPUser user, String password); + + /** + * Updates the specified credential value. + * + * @param user Keycloak user + * @param password Ldap password + */ + void updatePassword(LDAPUser user, String password); + +} diff --git a/federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/store/ldap/LDAPIdentityStore.java b/federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/store/ldap/LDAPIdentityStore.java new file mode 100644 index 0000000000..8b912406ac --- /dev/null +++ b/federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/store/ldap/LDAPIdentityStore.java @@ -0,0 +1,761 @@ +package org.keycloak.federation.ldap.idm.store.ldap; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.NoSuchElementException; + +import javax.naming.NamingEnumeration; +import javax.naming.NamingException; +import javax.naming.directory.Attribute; +import javax.naming.directory.Attributes; +import javax.naming.directory.BasicAttribute; +import javax.naming.directory.BasicAttributes; +import javax.naming.directory.DirContext; +import javax.naming.directory.ModificationItem; +import javax.naming.directory.SearchResult; + +import org.jboss.logging.Logger; +import org.keycloak.federation.ldap.idm.model.AttributedType; +import org.keycloak.federation.ldap.idm.model.IdentityType; +import org.keycloak.federation.ldap.idm.model.LDAPUser; +import org.keycloak.federation.ldap.idm.query.AttributeParameter; +import org.keycloak.federation.ldap.idm.query.Condition; +import org.keycloak.federation.ldap.idm.query.IdentityQuery; +import org.keycloak.federation.ldap.idm.query.IdentityQueryBuilder; +import org.keycloak.federation.ldap.idm.query.QueryParameter; +import org.keycloak.federation.ldap.idm.query.internal.BetweenCondition; +import org.keycloak.federation.ldap.idm.query.internal.DefaultQueryBuilder; +import org.keycloak.federation.ldap.idm.query.internal.EqualCondition; +import org.keycloak.federation.ldap.idm.query.internal.GreaterThanCondition; +import org.keycloak.federation.ldap.idm.query.internal.InCondition; +import org.keycloak.federation.ldap.idm.query.internal.LessThanCondition; +import org.keycloak.federation.ldap.idm.query.internal.LikeCondition; +import org.keycloak.federation.ldap.idm.store.IdentityStore; +import org.keycloak.models.LDAPConstants; +import org.keycloak.models.ModelDuplicateException; +import org.keycloak.models.ModelException; +import org.keycloak.models.utils.reflection.NamedPropertyCriteria; +import org.keycloak.models.utils.reflection.Property; +import org.keycloak.models.utils.reflection.PropertyQueries; +import org.keycloak.models.utils.reflection.TypedPropertyCriteria; +import org.keycloak.util.reflections.Reflections; + +/** + * An IdentityStore implementation backed by an LDAP directory + * + * @author Shane Bryzak + * @author Anil Saldhana + * @author Pedro Silva + */ +public class LDAPIdentityStore implements IdentityStore { + + private static final Logger logger = Logger.getLogger(LDAPIdentityStore.class); + + public static final String EMPTY_ATTRIBUTE_VALUE = " "; + + private final LDAPIdentityStoreConfiguration config; + private final LDAPOperationManager operationManager; + + public LDAPIdentityStore(LDAPIdentityStoreConfiguration config) { + this.config = config; + + try { + this.operationManager = new LDAPOperationManager(getConfig()); + } catch (NamingException e) { + throw new ModelException("Couldn't init operation manager", e); + } + } + + @Override + public LDAPIdentityStoreConfiguration getConfig() { + return this.config; + } + + @Override + public void add(AttributedType attributedType) { + // id will be assigned by the ldap server + attributedType.setId(null); + + String entryDN = getBindingDN(attributedType, true); + this.operationManager.createSubContext(entryDN, extractAttributes(attributedType, true)); + addToParentAsMember(attributedType); + attributedType.setId(getEntryIdentifier(attributedType)); + + attributedType.setEntryDN(entryDN); + + if (logger.isTraceEnabled()) { + logger.tracef("Type with identifier [%s] successfully added to identity store [%s].", attributedType.getId(), this); + } + } + + @Override + public void update(AttributedType attributedType) { + BasicAttributes updatedAttributes = extractAttributes(attributedType, false); + NamingEnumeration attributes = updatedAttributes.getAll(); + + this.operationManager.modifyAttributes(getBindingDN(attributedType, true), attributes); + + if (logger.isTraceEnabled()) { + logger.tracef("Type with identifier [%s] successfully updated to identity store [%s].", attributedType.getId(), this); + } + } + + @Override + public void remove(AttributedType attributedType) { + LDAPMappingConfiguration mappingConfig = getMappingConfig(attributedType.getClass()); + + this.operationManager.removeEntryById(getBaseDN(attributedType), attributedType.getId(), mappingConfig); + + if (logger.isTraceEnabled()) { + logger.tracef("Type with identifier [%s] successfully removed from identity store [%s].", attributedType.getId(), this); + } + } + + @Override + public List fetchQueryResults(IdentityQuery identityQuery) { + List results = new ArrayList(); + + try { + if (identityQuery.getSorting() != null && !identityQuery.getSorting().isEmpty()) { + throw new ModelException("LDAP Identity Store does not support sorted queries."); + } + + for (Condition condition : identityQuery.getConditions()) { + + if (IdentityType.ID.equals(condition.getParameter())) { + if (EqualCondition.class.isInstance(condition)) { + EqualCondition equalCondition = (EqualCondition) condition; + SearchResult search = this.operationManager + .lookupById(getConfig().getBaseDN(), equalCondition.getValue().toString(), null); + + if (search != null) { + results.add((V) populateAttributedType(search, null)); + } + } + + return results; + } + } + + if (!IdentityType.class.equals(identityQuery.getIdentityType())) { + // the ldap store does not support queries based on root types. Except if based on the identifier. + LDAPMappingConfiguration ldapEntryConfig = getMappingConfig(identityQuery.getIdentityType()); + StringBuilder filter = createIdentityTypeSearchFilter(identityQuery, ldapEntryConfig); + String baseDN = getBaseDN(ldapEntryConfig); + List search; + + if (getConfig().isPagination() && identityQuery.getLimit() > 0) { + search = this.operationManager.searchPaginated(baseDN, filter.toString(), ldapEntryConfig, identityQuery); + } else { + search = this.operationManager.search(baseDN, filter.toString(), ldapEntryConfig); + } + + for (SearchResult result : search) { + if (!result.getNameInNamespace().equals(baseDN)) { + results.add((V) populateAttributedType(result, null)); + } + } + } + } catch (Exception e) { + throw new ModelException("Querying of identity type failed " + identityQuery, e); + } + + return results; + } + + @Override + public int countQueryResults(IdentityQuery identityQuery) { + int limit = identityQuery.getLimit(); + int offset = identityQuery.getOffset(); + + identityQuery.setLimit(0); + identityQuery.setOffset(0); + + int resultCount = identityQuery.getResultList().size(); + + identityQuery.setLimit(limit); + identityQuery.setOffset(offset); + + return resultCount; + } + + public IdentityQueryBuilder createQueryBuilder() { + return new DefaultQueryBuilder(this); + } + + // *************** CREDENTIALS AND USER SPECIFIC STUFF + + @Override + public boolean validatePassword(LDAPUser user, String password) { + String userDN = getEntryDNOfUser(user); + + if (logger.isDebugEnabled()) { + logger.debugf("Using DN [%s] for authentication of user [%s]", userDN, user.getLoginName()); + } + + if (operationManager.authenticate(userDN, password)) { + return true; + } + + return false; + } + + @Override + public void updatePassword(LDAPUser user, String password) { + String userDN = getEntryDNOfUser(user); + + if (logger.isDebugEnabled()) { + logger.debugf("Using DN [%s] for updating LDAP password of user [%s]", userDN, user.getLoginName()); + } + + if (getConfig().isActiveDirectory()) { + updateADPassword(userDN, password); + } else { + ModificationItem[] mods = new ModificationItem[1]; + + try { + BasicAttribute mod0 = new BasicAttribute(LDAPConstants.USER_PASSWORD_ATTRIBUTE, password); + + mods[0] = new ModificationItem(DirContext.REPLACE_ATTRIBUTE, mod0); + + operationManager.modifyAttribute(userDN, mod0); + } catch (Exception e) { + throw new ModelException("Error updating password.", e); + } + } + } + + + private void updateADPassword(String userDN, String password) { + try { + // Replace the "unicdodePwd" attribute with a new value + // Password must be both Unicode and a quoted string + String newQuotedPassword = "\"" + password + "\""; + byte[] newUnicodePassword = newQuotedPassword.getBytes("UTF-16LE"); + + BasicAttribute unicodePwd = new BasicAttribute("unicodePwd", newUnicodePassword); + + List modItems = new ArrayList(); + modItems.add(new ModificationItem(DirContext.REPLACE_ATTRIBUTE, unicodePwd)); + + // Used in ActiveDirectory to put account into "enabled" state (aka userAccountControl=512, see http://support.microsoft.com/kb/305144/en ) after password update. If value is -1, it's ignored + if (getConfig().isUserAccountControlsAfterPasswordUpdate()) { + BasicAttribute userAccountControl = new BasicAttribute("userAccountControl", "512"); + modItems.add(new ModificationItem(DirContext.REPLACE_ATTRIBUTE, userAccountControl)); + + logger.debugf("Attribute userAccountControls will be switched to 512 after password update of user [%s]", userDN); + } + + operationManager.modifyAttributes(userDN, modItems.toArray(new ModificationItem[] {})); + } catch (Exception e) { + throw new ModelException(e); + } + } + + + private String getEntryDNOfUser(LDAPUser user) { + // First try if user already has entryDN on him + String entryDN = user.getEntryDN(); + if (entryDN != null) { + return entryDN; + } + + // Need to find user in LDAP + String username = user.getLoginName(); + user = getUser(username); + if (user == null) { + throw new ModelException("No LDAP user found with username " + username); + } + + return user.getEntryDN(); + } + + + public LDAPUser getUser(String username) { + + if (isNullOrEmpty(username)) { + return null; + } + + IdentityQueryBuilder queryBuilder = createQueryBuilder(); + List agents = queryBuilder.createIdentityQuery(LDAPUser.class) + .where(queryBuilder.equal(LDAPUser.LOGIN_NAME, username)).getResultList(); + + if (agents.isEmpty()) { + return null; + } else if (agents.size() == 1) { + return agents.get(0); + } else { + throw new ModelDuplicateException("Error - multiple Agent objects found with same login name"); + } + } + + // ************ END CREDENTIALS AND USER SPECIFIC STUFF + + + private String getBaseDN(final LDAPMappingConfiguration ldapEntryConfig) { + String baseDN = getConfig().getBaseDN(); + + if (ldapEntryConfig.getBaseDN() != null) { + baseDN = ldapEntryConfig.getBaseDN(); + } + + return baseDN; + } + + protected StringBuilder createIdentityTypeSearchFilter(final IdentityQuery identityQuery, final LDAPMappingConfiguration ldapEntryConfig) { + StringBuilder filter = new StringBuilder(); + + for (Condition condition : identityQuery.getConditions()) { + QueryParameter queryParameter = condition.getParameter(); + + if (!IdentityType.ID.equals(queryParameter)) { + if (AttributeParameter.class.isInstance(queryParameter)) { + AttributeParameter attributeParameter = (AttributeParameter) queryParameter; + String attributeName = ldapEntryConfig.getMappedProperties().get(attributeParameter.getName()); + + if (attributeName != null) { + if (EqualCondition.class.isInstance(condition)) { + EqualCondition equalCondition = (EqualCondition) condition; + Object parameterValue = equalCondition.getValue(); + + if (Date.class.isInstance(parameterValue)) { + parameterValue = LDAPUtil.formatDate((Date) parameterValue); + } + + filter.append("(").append(attributeName).append(LDAPConstants.EQUAL).append(parameterValue).append(")"); + } else if (LikeCondition.class.isInstance(condition)) { + LikeCondition likeCondition = (LikeCondition) condition; + String parameterValue = (String) likeCondition.getValue(); + + } else if (GreaterThanCondition.class.isInstance(condition)) { + GreaterThanCondition greaterThanCondition = (GreaterThanCondition) condition; + Comparable parameterValue = (Comparable) greaterThanCondition.getValue(); + + if (Date.class.isInstance(parameterValue)) { + parameterValue = LDAPUtil.formatDate((Date) parameterValue); + } + + if (greaterThanCondition.isOrEqual()) { + filter.append("(").append(attributeName).append(">=").append(parameterValue).append(")"); + } else { + filter.append("(").append(attributeName).append(">").append(parameterValue).append(")"); + } + } else if (LessThanCondition.class.isInstance(condition)) { + LessThanCondition lessThanCondition = (LessThanCondition) condition; + Comparable parameterValue = (Comparable) lessThanCondition.getValue(); + + if (Date.class.isInstance(parameterValue)) { + parameterValue = LDAPUtil.formatDate((Date) parameterValue); + } + + if (lessThanCondition.isOrEqual()) { + filter.append("(").append(attributeName).append("<=").append(parameterValue).append(")"); + } else { + filter.append("(").append(attributeName).append("<").append(parameterValue).append(")"); + } + } else if (BetweenCondition.class.isInstance(condition)) { + BetweenCondition betweenCondition = (BetweenCondition) condition; + Comparable x = betweenCondition.getX(); + Comparable y = betweenCondition.getY(); + + if (Date.class.isInstance(x)) { + x = LDAPUtil.formatDate((Date) x); + } + + if (Date.class.isInstance(y)) { + y = LDAPUtil.formatDate((Date) y); + } + + filter.append("(").append(x).append("<=").append(attributeName).append("<=").append(y).append(")"); + } else if (InCondition.class.isInstance(condition)) { + InCondition inCondition = (InCondition) condition; + Object[] valuesToCompare = inCondition.getValue(); + + filter.append("(&("); + + for (int i = 0; i< valuesToCompare.length; i++) { + Object value = valuesToCompare[i]; + + filter.append("(").append(attributeName).append(LDAPConstants.EQUAL).append(value).append(")"); + } + + filter.append("))"); + } else { + throw new ModelException("Unsupported query condition [" + condition + "]."); + } + } + } + } + } + + + filter.insert(0, "(&("); + filter.append(getObjectClassesFilter(ldapEntryConfig)); + filter.append("))"); + + return filter; + } + + private StringBuilder getObjectClassesFilter(final LDAPMappingConfiguration ldapEntryConfig) { + StringBuilder builder = new StringBuilder(); + + if (ldapEntryConfig != null && !ldapEntryConfig.getObjectClasses().isEmpty()) { + for (String objectClass : ldapEntryConfig.getObjectClasses()) { + builder.append("(").append(LDAPConstants.OBJECT_CLASS).append(LDAPConstants.EQUAL).append(objectClass).append(")"); + } + } else { + builder.append("(").append(LDAPConstants.OBJECT_CLASS).append(LDAPConstants.EQUAL).append("*").append(")"); + } + + return builder; + } + + private AttributedType populateAttributedType(SearchResult searchResult, AttributedType attributedType) { + return populateAttributedType(searchResult, attributedType, 0); + } + + private AttributedType populateAttributedType(SearchResult searchResult, AttributedType attributedType, int hierarchyDepthCount) { + try { + String entryDN = searchResult.getNameInNamespace(); + Attributes attributes = searchResult.getAttributes(); + + if (attributedType == null) { + attributedType = Reflections.newInstance(getConfig().getSupportedTypeByBaseDN(entryDN, getEntryObjectClasses(attributes))); + } + + attributedType.setEntryDN(entryDN); + + LDAPMappingConfiguration mappingConfig = getMappingConfig(attributedType.getClass()); + + if (hierarchyDepthCount > mappingConfig.getHierarchySearchDepth()) { + return null; + } + + if (logger.isTraceEnabled()) { + logger.tracef("Populating attributed type [%s] from DN [%s]", attributedType, entryDN); + } + + NamingEnumeration ldapAttributes = attributes.getAll(); + + while (ldapAttributes.hasMore()) { + Attribute ldapAttribute = ldapAttributes.next(); + Object attributeValue; + + try { + attributeValue = ldapAttribute.get(); + } catch (NoSuchElementException nsee) { + continue; + } + + String ldapAttributeName = ldapAttribute.getID(); + + if (ldapAttributeName.toLowerCase().equals(getConfig().getUniqueIdentifierAttributeName().toLowerCase())) { + attributedType.setId(this.operationManager.decodeEntryUUID(attributeValue)); + } else { + String attributeName = findAttributeName(mappingConfig.getMappedProperties(), ldapAttributeName); + + if (attributeName != null) { + // Find if it's java property or attribute + Property property = PropertyQueries + .createQuery(attributedType.getClass()) + .addCriteria(new NamedPropertyCriteria(attributeName)).getFirstResult(); + + if (property != null) { + if (logger.isTraceEnabled()) { + logger.tracef("Populating property [%s] from ldap attribute [%s] with value [%s] from DN [%s].", property.getName(), ldapAttributeName, attributeValue, entryDN); + } + + if (property.getJavaClass().equals(Date.class)) { + property.setValue(attributedType, LDAPUtil.parseDate(attributeValue.toString())); + } else { + property.setValue(attributedType, attributeValue); + } + } else { + if (logger.isTraceEnabled()) { + logger.tracef("Populating attribute [%s] from ldap attribute [%s] with value [%s] from DN [%s].", attributeName, ldapAttributeName, attributeValue, entryDN); + } + + attributedType.setAttribute(new org.keycloak.federation.ldap.idm.model.Attribute(attributeName, (Serializable) attributeValue)); + } + } + } + } + + if (IdentityType.class.isInstance(attributedType)) { + IdentityType identityType = (IdentityType) attributedType; + + String createdTimestamp = attributes.get(LDAPConstants.CREATE_TIMESTAMP).get().toString(); + + identityType.setCreatedDate(LDAPUtil.parseDate(createdTimestamp)); + } + + LDAPMappingConfiguration entryConfig = getMappingConfig(attributedType.getClass()); + + if (mappingConfig.getParentMembershipAttributeName() != null) { + StringBuilder filter = new StringBuilder("(&"); + String entryBaseDN = entryDN.substring(entryDN.indexOf(LDAPConstants.COMMA) + 1); + + filter + .append("(") + .append(getObjectClassesFilter(entryConfig)) + .append(")") + .append("(") + .append(mappingConfig.getParentMembershipAttributeName()) + .append(LDAPConstants.EQUAL).append("") + .append(getBindingDN(attributedType, false)) + .append(LDAPConstants.COMMA) + .append(entryBaseDN) + .append(")"); + + filter.append(")"); + + if (logger.isTraceEnabled()) { + logger.tracef("Searching parent entry for DN [%s] using filter [%s].", entryBaseDN, filter.toString()); + } + + List search = this.operationManager.search(getConfig().getBaseDN(), filter.toString(), entryConfig); + + if (!search.isEmpty()) { + SearchResult next = search.get(0); + + Property parentProperty = PropertyQueries + .createQuery(attributedType.getClass()) + .addCriteria(new TypedPropertyCriteria(attributedType.getClass())).getFirstResult(); + + if (parentProperty != null) { + String parentDN = next.getNameInNamespace(); + String parentBaseDN = parentDN.substring(parentDN.indexOf(",") + 1); + Class baseDNType = getConfig().getSupportedTypeByBaseDN(parentBaseDN, getEntryObjectClasses(attributes)); + + if (parentProperty.getJavaClass().isAssignableFrom(baseDNType)) { + if (logger.isTraceEnabled()) { + logger.tracef("Found parent [%s] for entry for DN [%s].", parentDN, entryDN); + } + + int hierarchyDepthCount1 = ++hierarchyDepthCount; + + parentProperty.setValue(attributedType, populateAttributedType(next, null, hierarchyDepthCount1)); + } + } + } else { + if (logger.isTraceEnabled()) { + logger.tracef("No parent entry found for DN [%s] using filter [%s].", entryDN, filter.toString()); + } + } + } + } catch (Exception e) { + throw new ModelException("Could not populate attribute type " + attributedType + ".", e); + } + + return attributedType; + } + + private String findAttributeName(Map attrMapping, String ldapAttributeName) { + for (Map.Entry currentAttr : attrMapping.entrySet()) { + if (currentAttr.getValue().equalsIgnoreCase(ldapAttributeName)) { + return currentAttr.getKey(); + } + } + + return null; + } + + private List getEntryObjectClasses(final Attributes attributes) throws NamingException { + Attribute objectClassesAttribute = attributes.get(LDAPConstants.OBJECT_CLASS); + List objectClasses = new ArrayList(); + + if (objectClassesAttribute == null) { + return objectClasses; + } + + NamingEnumeration all = objectClassesAttribute.getAll(); + + while (all.hasMore()) { + objectClasses.add(all.next().toString()); + } + + return objectClasses; + } + + protected BasicAttributes extractAttributes(AttributedType attributedType, boolean isCreate) { + BasicAttributes entryAttributes = new BasicAttributes(); + LDAPMappingConfiguration mappingConfig = getMappingConfig(attributedType.getClass()); + Map mappedProperties = mappingConfig.getMappedProperties(); + + for (String propertyName : mappedProperties.keySet()) { + if (!mappingConfig.getReadOnlyAttributes().contains(propertyName) && (isCreate || !mappingConfig.getBindingProperty().getName().equals(propertyName))) { + Property property = PropertyQueries + .createQuery(attributedType.getClass()) + .addCriteria(new NamedPropertyCriteria(propertyName)).getFirstResult(); + + Object propertyValue = null; + if (property != null) { + // Mapped Java property on the object + propertyValue = property.getValue(attributedType); + } else { + // Not mapped property. So fallback to attribute + org.keycloak.federation.ldap.idm.model.Attribute attribute = attributedType.getAttribute(propertyName); + if (attribute != null) { + propertyValue = attribute.getValue(); + } + } + + if (AttributedType.class.isInstance(propertyValue)) { + AttributedType referencedType = (AttributedType) propertyValue; + propertyValue = getBindingDN(referencedType, true); + } else { + if (propertyValue == null || isNullOrEmpty(propertyValue.toString())) { + propertyValue = EMPTY_ATTRIBUTE_VALUE; + } + } + + entryAttributes.put(mappedProperties.get(propertyName), propertyValue); + } + } + + // Don't extract object classes for update + if (isCreate) { + LDAPMappingConfiguration ldapEntryConfig = getMappingConfig(attributedType.getClass()); + + BasicAttribute objectClassAttribute = new BasicAttribute(LDAPConstants.OBJECT_CLASS); + + for (String objectClassValue : ldapEntryConfig.getObjectClasses()) { + objectClassAttribute.add(objectClassValue); + + if (objectClassValue.equals(LDAPConstants.GROUP_OF_NAMES) + || objectClassValue.equals(LDAPConstants.GROUP_OF_ENTRIES) + || objectClassValue.equals(LDAPConstants.GROUP_OF_UNIQUE_NAMES)) { + entryAttributes.put(LDAPConstants.MEMBER, EMPTY_ATTRIBUTE_VALUE); + } + } + + entryAttributes.put(objectClassAttribute); + } + + return entryAttributes; + } + + // TODO: Move class StringUtil from SAML module + public static boolean isNullOrEmpty(String str) { + return str == null || str.isEmpty(); + } + + private LDAPMappingConfiguration getMappingConfig(Class attributedType) { + LDAPMappingConfiguration mappingConfig = getConfig().getMappingConfig(attributedType); + + if (mappingConfig == null) { + throw new ModelException("Not mapped type [" + attributedType + "]."); + } + + return mappingConfig; + } + + public String getBindingDN(AttributedType attributedType, boolean appendBaseDN) { + LDAPMappingConfiguration mappingConfig = getMappingConfig(attributedType.getClass()); + Property idProperty = mappingConfig.getIdProperty(); + + String baseDN; + + if (mappingConfig.getBaseDN() == null || !appendBaseDN) { + baseDN = ""; + } else { + baseDN = LDAPConstants.COMMA + getBaseDN(attributedType); + } + + Property bindingProperty = mappingConfig.getBindingProperty(); + String bindingAttribute; + String dn; + + if (bindingProperty == null) { + bindingAttribute = mappingConfig.getMappedProperties().get(idProperty.getName()); + dn = idProperty.getValue(attributedType); + } else { + bindingAttribute = mappingConfig.getMappedProperties().get(bindingProperty.getName()); + dn = mappingConfig.getBindingProperty().getValue(attributedType); + } + + return bindingAttribute + LDAPConstants.EQUAL + dn + baseDN; + } + + private String getBaseDN(AttributedType attributedType) { + LDAPMappingConfiguration mappingConfig = getMappingConfig(attributedType.getClass()); + String baseDN = mappingConfig.getBaseDN(); + String parentDN = mappingConfig.getParentMapping().get(mappingConfig.getIdProperty().getValue(attributedType)); + + if (parentDN != null) { + baseDN = parentDN; + } else { + Property parentProperty = PropertyQueries + .createQuery(attributedType.getClass()) + .addCriteria(new TypedPropertyCriteria(attributedType.getClass())).getFirstResult(); + + if (parentProperty != null) { + AttributedType parentType = parentProperty.getValue(attributedType); + + if (parentType != null) { + Property parentIdProperty = getMappingConfig(parentType.getClass()).getIdProperty(); + + String parentId = parentIdProperty.getValue(parentType); + + String parentBaseDN = mappingConfig.getParentMapping().get(parentId); + + if (parentBaseDN != null) { + baseDN = parentBaseDN; + } else { + baseDN = getBaseDN(parentType); + } + } + } + } + + if (baseDN == null) { + baseDN = getConfig().getBaseDN(); + } + + return baseDN; + } + + protected void addToParentAsMember(final AttributedType attributedType) { + LDAPMappingConfiguration entryConfig = getMappingConfig(attributedType.getClass()); + + if (entryConfig.getParentMembershipAttributeName() != null) { + Property parentProperty = PropertyQueries + .createQuery(attributedType.getClass()) + .addCriteria(new TypedPropertyCriteria(attributedType.getClass())) + .getFirstResult(); + + if (parentProperty != null) { + AttributedType parentType = parentProperty.getValue(attributedType); + + if (parentType != null) { + Attributes attributes = this.operationManager.getAttributes(parentType.getId(), getBaseDN(parentType), entryConfig); + Attribute attribute = attributes.get(entryConfig.getParentMembershipAttributeName()); + + attribute.add(getBindingDN(attributedType, true)); + + this.operationManager.modifyAttribute(getBindingDN(parentType, true), attribute); + } + } + } + } + + protected String getEntryIdentifier(final AttributedType attributedType) { + try { + // we need this to retrieve the entry's identifier from the ldap server + List search = this.operationManager.search(getBaseDN(attributedType), "(" + getBindingDN(attributedType, false) + ")", getMappingConfig(attributedType.getClass())); + Attribute id = search.get(0).getAttributes().get(getConfig().getUniqueIdentifierAttributeName()); + + if (id == null) { + throw new ModelException("Could not retrieve identifier for entry [" + getBindingDN(attributedType, true) + "]."); + } + + return this.operationManager.decodeEntryUUID(id.get()); + } catch (NamingException ne) { + throw new ModelException("Could not add type [" + attributedType + "].", ne); + } + } +} diff --git a/federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/store/ldap/LDAPIdentityStoreConfiguration.java b/federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/store/ldap/LDAPIdentityStoreConfiguration.java new file mode 100644 index 0000000000..0c0a2e178e --- /dev/null +++ b/federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/store/ldap/LDAPIdentityStoreConfiguration.java @@ -0,0 +1,188 @@ +package org.keycloak.federation.ldap.idm.store.ldap; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Properties; + +import org.keycloak.federation.ldap.idm.model.AttributedType; +import org.keycloak.models.LDAPConstants; +import org.keycloak.models.ModelException; + +/** + * A configuration for the LDAP store. + * + * @author anil saldhana + * @since Sep 6, 2012 + */ + +public class LDAPIdentityStoreConfiguration { + + private String ldapURL; + private String factoryName = "com.sun.jndi.ldap.LdapCtxFactory"; + private String authType = "simple"; + private String protocol; + private String bindDN; + private String bindCredential; + private boolean activeDirectory; + private Properties connectionProperties; + private boolean pagination; + private String uniqueIdentifierAttributeName; + private boolean userAccountControlsAfterPasswordUpdate; + + private String baseDN; + private Map, LDAPMappingConfiguration> mappingConfig = new HashMap, LDAPMappingConfiguration>(); + + public String getLdapURL() { + return this.ldapURL; + } + + public String getFactoryName() { + return this.factoryName; + } + + public String getAuthType() { + return this.authType; + } + + public String getBaseDN() { + return this.baseDN; + } + + public String getBindDN() { + return this.bindDN; + } + + public String getBindCredential() { + return this.bindCredential; + } + + public boolean isActiveDirectory() { + return this.activeDirectory; + } + + public Properties getConnectionProperties() { + return this.connectionProperties; + } + + public LDAPMappingConfiguration mappingConfig(Class clazz) { + LDAPMappingConfiguration mappingConfig = new LDAPMappingConfiguration(clazz); + this.mappingConfig.put(clazz, mappingConfig); + return mappingConfig; + } + + public Class getSupportedTypeByBaseDN(String entryDN, List objectClasses) { + String entryBaseDN = entryDN.substring(entryDN.indexOf(LDAPConstants.COMMA) + 1); + + for (LDAPMappingConfiguration mappingConfig : this.mappingConfig.values()) { + if (mappingConfig.getBaseDN() != null) { + + if (mappingConfig.getBaseDN().equalsIgnoreCase(entryDN) + || mappingConfig.getParentMapping().values().contains(entryDN)) { + return mappingConfig.getMappedClass(); + } + + if (mappingConfig.getBaseDN().equalsIgnoreCase(entryBaseDN) + || mappingConfig.getParentMapping().values().contains(entryBaseDN)) { + return mappingConfig.getMappedClass(); + } + } + } + + for (LDAPMappingConfiguration mappingConfig : this.mappingConfig.values()) { + for (String objectClass : objectClasses) { + if (mappingConfig.getObjectClasses().contains(objectClass)) { + return mappingConfig.getMappedClass(); + } + } + } + + throw new ModelException("No type found with Base DN [" + entryDN + "] or objectClasses [" + objectClasses + "."); + } + + public LDAPMappingConfiguration getMappingConfig(Class attributedType) { + for (LDAPMappingConfiguration mappingConfig : this.mappingConfig.values()) { + if (attributedType.equals(mappingConfig.getMappedClass())) { + return mappingConfig; + } + } + + return null; + } + + public String getProtocol() { + return protocol; + } + + public String getUniqueIdentifierAttributeName() { + return uniqueIdentifierAttributeName; + } + + public boolean isPagination() { + return pagination; + } + + public boolean isUserAccountControlsAfterPasswordUpdate() { + return userAccountControlsAfterPasswordUpdate; + } + + public LDAPIdentityStoreConfiguration setLdapURL(String ldapURL) { + this.ldapURL = ldapURL; + return this; + } + + public LDAPIdentityStoreConfiguration setFactoryName(String factoryName) { + this.factoryName = factoryName; + return this; + } + + public LDAPIdentityStoreConfiguration setAuthType(String authType) { + this.authType = authType; + return this; + } + + public LDAPIdentityStoreConfiguration setProtocol(String protocol) { + this.protocol = protocol; + return this; + } + + public LDAPIdentityStoreConfiguration setBindDN(String bindDN) { + this.bindDN = bindDN; + return this; + } + + public LDAPIdentityStoreConfiguration setBindCredential(String bindCredential) { + this.bindCredential = bindCredential; + return this; + } + + public LDAPIdentityStoreConfiguration setActiveDirectory(boolean activeDirectory) { + this.activeDirectory = activeDirectory; + return this; + } + + public LDAPIdentityStoreConfiguration setPagination(boolean pagination) { + this.pagination = pagination; + return this; + } + + public LDAPIdentityStoreConfiguration setConnectionProperties(Properties connectionProperties) { + this.connectionProperties = connectionProperties; + return this; + } + + public LDAPIdentityStoreConfiguration setUniqueIdentifierAttributeName(String uniqueIdentifierAttributeName) { + this.uniqueIdentifierAttributeName = uniqueIdentifierAttributeName; + return this; + } + + public LDAPIdentityStoreConfiguration setUserAccountControlsAfterPasswordUpdate(boolean userAccountControlsAfterPasswordUpdate) { + this.userAccountControlsAfterPasswordUpdate = userAccountControlsAfterPasswordUpdate; + return this; + } + + public LDAPIdentityStoreConfiguration setBaseDN(String baseDN) { + this.baseDN = baseDN; + return this; + } +} diff --git a/federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/store/ldap/LDAPMappingConfiguration.java b/federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/store/ldap/LDAPMappingConfiguration.java new file mode 100644 index 0000000000..033d93bbf2 --- /dev/null +++ b/federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/store/ldap/LDAPMappingConfiguration.java @@ -0,0 +1,231 @@ +package org.keycloak.federation.ldap.idm.store.ldap; + +import java.lang.reflect.AnnotatedElement; +import java.lang.reflect.Member; +import java.lang.reflect.Type; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import org.keycloak.federation.ldap.idm.model.Attribute; +import org.keycloak.federation.ldap.idm.model.AttributedType; +import org.keycloak.federation.ldap.idm.model.IdentityType; +import org.keycloak.models.ModelException; +import org.keycloak.models.utils.reflection.NamedPropertyCriteria; +import org.keycloak.models.utils.reflection.Property; +import org.keycloak.models.utils.reflection.PropertyQueries; + +/** + * @author pedroigor + */ +public class LDAPMappingConfiguration { + + private final Class mappedClass; + private Set objectClasses; + private String baseDN; + private final Map mappedProperties = new HashMap(); + private Property idProperty; + private Class relatedAttributedType; + private String parentMembershipAttributeName; + private Map parentMapping = new HashMap(); + private final Set readOnlyAttributes = new HashSet(); + private int hierarchySearchDepth; + private Property bindingProperty; + + public LDAPMappingConfiguration(Class mappedClass) { + this.mappedClass = mappedClass; + } + + public Class getMappedClass() { + return this.mappedClass; + } + + public Set getObjectClasses() { + return this.objectClasses; + } + + public String getBaseDN() { + return this.baseDN; + } + + public Map getMappedProperties() { + return this.mappedProperties; + } + + public Property getIdProperty() { + return this.idProperty; + } + + public Property getBindingProperty() { + return this.bindingProperty; + } + + public Class getRelatedAttributedType() { + return this.relatedAttributedType; + } + + public String getParentMembershipAttributeName() { + return this.parentMembershipAttributeName; + } + + public Map getParentMapping() { + return this.parentMapping; + } + + public Set getReadOnlyAttributes() { + return this.readOnlyAttributes; + } + + public int getHierarchySearchDepth() { + return this.hierarchySearchDepth; + } + + private Property getBindingProperty(final String bindingPropertyName) { + Property bindingProperty = PropertyQueries + .createQuery(getMappedClass()) + .addCriteria(new NamedPropertyCriteria(bindingPropertyName)).getFirstResult(); + + // We don't have Java property, so actually delegate to setAttribute/getAttribute + if (bindingProperty == null) { + bindingProperty = new Property() { + + @Override + public String getName() { + return bindingPropertyName; + } + + @Override + public Type getBaseType() { + return null; + } + + @Override + public Class getJavaClass() { + return String.class; + } + + @Override + public AnnotatedElement getAnnotatedElement() { + return null; + } + + @Override + public Member getMember() { + return null; + } + + @Override + public String getValue(Object instance) { + if (!(instance instanceof AttributedType)) { + throw new IllegalStateException("Instance [ " + instance + " ] not an instance of AttributedType"); + } + + AttributedType attributedType = (AttributedType) instance; + Attribute attr = attributedType.getAttribute(bindingPropertyName); + return attr!=null ? attr.getValue() : null; + } + + @Override + public void setValue(Object instance, String value) { + if (!(instance instanceof AttributedType)) { + throw new IllegalStateException("Instance [ " + instance + " ] not an instance of AttributedType"); + } + + AttributedType attributedType = (AttributedType) instance; + attributedType.setAttribute(new Attribute(bindingPropertyName, value)); + } + + @Override + public Class getDeclaringClass() { + return null; + } + + @Override + public boolean isReadOnly() { + return false; + } + + @Override + public void setAccessible() { + + } + + @Override + public boolean isAnnotationPresent(Class annotation) { + return false; + } + }; + } + + return bindingProperty; + } + + public LDAPMappingConfiguration setObjectClasses(Set objectClasses) { + this.objectClasses = objectClasses; + return this; + } + + public LDAPMappingConfiguration setBaseDN(String baseDN) { + this.baseDN = baseDN; + return this; + } + + public LDAPMappingConfiguration addAttributeMapping(String userAttributeName, String ldapAttributeName) { + this.mappedProperties.put(userAttributeName, ldapAttributeName); + return this; + } + + public LDAPMappingConfiguration addReadOnlyAttributeMapping(String userAttributeName, String ldapAttributeName) { + this.mappedProperties.put(userAttributeName, ldapAttributeName); + this.readOnlyAttributes.add(userAttributeName); + return this; + } + + public LDAPMappingConfiguration setIdPropertyName(String idPropertyName) { + + if (idPropertyName != null) { + this.idProperty = PropertyQueries + .createQuery(getMappedClass()) + .addCriteria(new NamedPropertyCriteria(idPropertyName)).getFirstResult(); + } else { + this.idProperty = null; + } + + if (IdentityType.class.isAssignableFrom(mappedClass) && idProperty == null) { + throw new ModelException("Id attribute not mapped to any property of [" + mappedClass + "]."); + } + + // Binding property is idProperty by default + if (this.bindingProperty == null) { + this.bindingProperty = this.idProperty; + } + + return this; + } + + public LDAPMappingConfiguration setRelatedAttributedType(Class relatedAttributedType) { + this.relatedAttributedType = relatedAttributedType; + return this; + } + + public LDAPMappingConfiguration setParentMembershipAttributeName(String parentMembershipAttributeName) { + this.parentMembershipAttributeName = parentMembershipAttributeName; + return this; + } + + public LDAPMappingConfiguration setParentMapping(Map parentMapping) { + this.parentMapping = parentMapping; + return this; + } + + public LDAPMappingConfiguration setHierarchySearchDepth(int hierarchySearchDepth) { + this.hierarchySearchDepth = hierarchySearchDepth; + return this; + } + + public LDAPMappingConfiguration setBindingPropertyName(String bindingPropertyName) { + this.bindingProperty = getBindingProperty(bindingPropertyName); + return this; + } +} diff --git a/federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/store/ldap/LDAPOperationManager.java b/federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/store/ldap/LDAPOperationManager.java new file mode 100644 index 0000000000..507d61fc3f --- /dev/null +++ b/federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/store/ldap/LDAPOperationManager.java @@ -0,0 +1,606 @@ +package org.keycloak.federation.ldap.idm.store.ldap; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.Hashtable; +import java.util.List; +import java.util.Map; +import java.util.Properties; + +import javax.naming.Binding; +import javax.naming.Context; +import javax.naming.InitialContext; +import javax.naming.NamingEnumeration; +import javax.naming.NamingException; +import javax.naming.directory.Attribute; +import javax.naming.directory.Attributes; +import javax.naming.directory.DirContext; +import javax.naming.directory.ModificationItem; +import javax.naming.directory.SearchControls; +import javax.naming.directory.SearchResult; +import javax.naming.ldap.Control; +import javax.naming.ldap.InitialLdapContext; +import javax.naming.ldap.LdapContext; +import javax.naming.ldap.PagedResultsControl; +import javax.naming.ldap.PagedResultsResponseControl; + +import org.jboss.logging.Logger; +import org.keycloak.federation.ldap.idm.model.IdentityType; +import org.keycloak.federation.ldap.idm.query.IdentityQuery; +import org.keycloak.models.LDAPConstants; +import org.keycloak.models.ModelException; + +import static javax.naming.directory.SearchControls.SUBTREE_SCOPE; + +/** + *

This class provides a set of operations to manage LDAP trees.

+ * + * @author Anil Saldhana + * @author Pedro Silva + */ +public class LDAPOperationManager { + + private static final Logger logger = Logger.getLogger(LDAPOperationManager.class); + + private final LDAPIdentityStoreConfiguration config; + private final Map connectionProperties; + + public LDAPOperationManager(LDAPIdentityStoreConfiguration config) throws NamingException { + this.config = config; + this.connectionProperties = Collections.unmodifiableMap(createConnectionProperties()); + } + + /** + *

+ * Modifies the given {@link javax.naming.directory.Attribute} instance using the given DN. This method performs a REPLACE_ATTRIBUTE + * operation. + *

+ * + * @param dn + * @param attribute + */ + public void modifyAttribute(String dn, Attribute attribute) { + ModificationItem[] mods = new ModificationItem[]{new ModificationItem(DirContext.REPLACE_ATTRIBUTE, attribute)}; + modifyAttributes(dn, mods); + } + + /** + *

+ * Modifies the given {@link Attribute} instances using the given DN. This method performs a REPLACE_ATTRIBUTE + * operation. + *

+ * + * @param dn + * @param attributes + */ + public void modifyAttributes(String dn, NamingEnumeration attributes) { + try { + List modItems = new ArrayList(); + while (attributes.hasMore()) { + ModificationItem modItem = new ModificationItem(DirContext.REPLACE_ATTRIBUTE, attributes.next()); + modItems.add(modItem); + } + + modifyAttributes(dn, modItems.toArray(new ModificationItem[] {})); + } catch (NamingException ne) { + throw new ModelException("Could not modify attributes on entry from DN [" + dn + "]", ne); + } + + } + + /** + *

+ * Removes the given {@link Attribute} instance using the given DN. This method performs a REMOVE_ATTRIBUTE + * operation. + *

+ * + * @param dn + * @param attribute + */ + public void removeAttribute(String dn, Attribute attribute) { + ModificationItem[] mods = new ModificationItem[]{new ModificationItem(DirContext.REMOVE_ATTRIBUTE, attribute)}; + modifyAttributes(dn, mods); + } + + /** + *

+ * Adds the given {@link Attribute} instance using the given DN. This method performs a ADD_ATTRIBUTE operation. + *

+ * + * @param dn + * @param attribute + */ + public void addAttribute(String dn, Attribute attribute) { + ModificationItem[] mods = new ModificationItem[]{new ModificationItem(DirContext.ADD_ATTRIBUTE, attribute)}; + modifyAttributes(dn, mods); + } + + /** + *

+ * Searches the LDAP tree. + *

+ * + * @param baseDN + * @param id + * + * @return + */ + public void removeEntryById(final String baseDN, final String id, final LDAPMappingConfiguration mappingConfiguration) { + final String filter = getFilterById(baseDN, id); + + try { + final SearchControls cons = getSearchControls(mappingConfiguration); + + execute(new LdapOperation() { + @Override + public SearchResult execute(LdapContext context) throws NamingException { + NamingEnumeration result = context.search(baseDN, filter, cons); + + if (result.hasMore()) { + SearchResult sr = result.next(); + if (logger.isDebugEnabled()) { + logger.debugf("Removing entry [%s] with attributes: [", sr.getNameInNamespace()); + + NamingEnumeration all = sr.getAttributes().getAll(); + + while (all.hasMore()) { + Attribute attribute = all.next(); + + logger.debugf(" %s = %s", attribute.getID(), attribute.get()); + } + + logger.debugf("]"); + } + destroySubcontext(context, sr.getNameInNamespace()); + } + + result.close(); + + return null; + } + }); + } catch (NamingException e) { + throw new ModelException("Could not remove entry from DN [" + baseDN + "] and id [" + id + "]", e); + } + } + + public List search(final String baseDN, final String filter, LDAPMappingConfiguration mappingConfiguration) throws NamingException { + final List result = new ArrayList(); + final SearchControls cons = getSearchControls(mappingConfiguration); + + try { + return execute(new LdapOperation>() { + @Override + public List execute(LdapContext context) throws NamingException { + NamingEnumeration search = context.search(baseDN, filter, cons); + + while (search.hasMoreElements()) { + result.add(search.nextElement()); + } + + search.close(); + + return result; + } + }); + } catch (NamingException e) { + logger.errorf(e, "Could not query server using DN [%s] and filter [%s]", baseDN, filter); + throw e; + } + } + + public List searchPaginated(final String baseDN, final String filter, LDAPMappingConfiguration mappingConfiguration, final IdentityQuery identityQuery) throws NamingException { + final List result = new ArrayList(); + final SearchControls cons = getSearchControls(mappingConfiguration); + + try { + return execute(new LdapOperation>() { + @Override + public List execute(LdapContext context) throws NamingException { + try { + byte[] cookie = (byte[])identityQuery.getPaginationContext(); + PagedResultsControl pagedControls = new PagedResultsControl(identityQuery.getLimit(), cookie, Control.CRITICAL); + context.setRequestControls(new Control[] { pagedControls }); + + NamingEnumeration search = context.search(baseDN, filter, cons); + + while (search.hasMoreElements()) { + result.add(search.nextElement()); + } + + search.close(); + + Control[] responseControls = context.getResponseControls(); + if (responseControls != null) { + for (Control respControl : responseControls) { + if (respControl instanceof PagedResultsResponseControl) { + PagedResultsResponseControl prrc = (PagedResultsResponseControl)respControl; + cookie = prrc.getCookie(); + identityQuery.setPaginationContext(cookie); + } + } + } + + return result; + } catch (IOException ioe) { + logger.errorf(ioe, "Could not query server with paginated query using DN [%s], filter [%s]", baseDN, filter); + throw new NamingException(ioe.getMessage()); + } + } + }); + } catch (NamingException e) { + logger.errorf(e, "Could not query server using DN [%s] and filter [%s]", baseDN, filter); + throw e; + } + } + + private SearchControls getSearchControls(LDAPMappingConfiguration mappingConfiguration) { + final SearchControls cons = new SearchControls(); + + cons.setSearchScope(SUBTREE_SCOPE); + cons.setReturningObjFlag(false); + + List returningAttributes = getReturningAttributes(mappingConfiguration); + + cons.setReturningAttributes(returningAttributes.toArray(new String[returningAttributes.size()])); + return cons; + } + + public String getFilterById(String baseDN, String id) { + String filter = null; + + if (this.config.isActiveDirectory()) { + final String strObjectGUID = ""; + + try { + Attributes attributes = execute(new LdapOperation() { + @Override + public Attributes execute(LdapContext context) throws NamingException { + return context.getAttributes(strObjectGUID); + } + }); + + byte[] objectGUID = (byte[]) attributes.get(LDAPConstants.OBJECT_GUID).get(); + + filter = "(&(objectClass=*)(" + getUniqueIdentifierAttributeName() + LDAPConstants.EQUAL + LDAPUtil.convertObjectGUIToByteString(objectGUID) + "))"; + } catch (NamingException ne) { + return filter; + } + } + + if (filter == null) { + filter = "(&(objectClass=*)(" + getUniqueIdentifierAttributeName() + LDAPConstants.EQUAL + id + "))"; + } + + return filter; + } + + public SearchResult lookupById(final String baseDN, final String id, final LDAPMappingConfiguration mappingConfiguration) { + final String filter = getFilterById(baseDN, id); + + try { + final SearchControls cons = getSearchControls(mappingConfiguration); + + return execute(new LdapOperation() { + @Override + public SearchResult execute(LdapContext context) throws NamingException { + NamingEnumeration search = context.search(baseDN, filter, cons); + + try { + if (search.hasMoreElements()) { + return search.next(); + } + } finally { + if (search != null) { + search.close(); + } + } + + return null; + } + }); + } catch (NamingException e) { + throw new ModelException("Could not query server using DN [" + baseDN + "] and filter [" + filter + "]", e); + } + } + + /** + *

+ * Destroys a subcontext with the given DN from the LDAP tree. + *

+ * + * @param dn + */ + private void destroySubcontext(LdapContext context, final String dn) { + try { + NamingEnumeration enumeration = null; + + try { + enumeration = context.listBindings(dn); + + while (enumeration.hasMore()) { + Binding binding = enumeration.next(); + String name = binding.getNameInNamespace(); + + destroySubcontext(context, name); + } + + context.unbind(dn); + } finally { + try { + enumeration.close(); + } catch (Exception e) { + } + } + } catch (Exception e) { + throw new ModelException("Could not unbind DN [" + dn + "]", e); + } + } + + /** + *

+ * Performs a simple authentication using the given DN and password to bind to the authentication context. + *

+ * + * @param dn + * @param password + * + * @return + */ + public boolean authenticate(String dn, String password) { + InitialContext authCtx = null; + + try { + Hashtable env = new Hashtable(this.connectionProperties); + + env.put(Context.SECURITY_PRINCIPAL, dn); + env.put(Context.SECURITY_CREDENTIALS, password); + + // Never use connection pool to prevent password caching + env.put("com.sun.jndi.ldap.connect.pool", "false"); + + authCtx = new InitialLdapContext(env, null); + + return true; + } catch (Exception e) { + if (logger.isDebugEnabled()) { + logger.debugf(e, "Authentication failed for DN [%s]", dn); + } + + return false; + } finally { + if (authCtx != null) { + try { + authCtx.close(); + } catch (NamingException e) { + + } + } + } + } + + public void modifyAttributes(final String dn, final ModificationItem[] mods) { + try { + if (logger.isDebugEnabled()) { + logger.debugf("Modifying attributes for entry [%s]: [", dn); + + for (ModificationItem item : mods) { + Object values; + + if (item.getAttribute().size() > 0) { + values = item.getAttribute().get(); + } else { + values = "No values"; + } + + logger.debugf(" Op [%s]: %s = %s", item.getModificationOp(), item.getAttribute().getID(), values); + } + + logger.debugf("]"); + } + + execute(new LdapOperation() { + @Override + public Void execute(LdapContext context) throws NamingException { + context.modifyAttributes(dn, mods); + return null; + } + }); + } catch (NamingException e) { + throw new ModelException("Could not modify attribute for DN [" + dn + "]", e); + } + } + + public void createSubContext(final String name, final Attributes attributes) { + try { + if (logger.isDebugEnabled()) { + logger.debugf("Creating entry [%s] with attributes: [", name); + + NamingEnumeration all = attributes.getAll(); + + while (all.hasMore()) { + Attribute attribute = all.next(); + + logger.debugf(" %s = %s", attribute.getID(), attribute.get()); + } + + logger.debugf("]"); + } + + execute(new LdapOperation() { + @Override + public Void execute(LdapContext context) throws NamingException { + DirContext subcontext = context.createSubcontext(name, attributes); + + subcontext.close(); + + return null; + } + }); + } catch (NamingException e) { + throw new ModelException("Error creating subcontext [" + name + "]", e); + } + } + + private String getUniqueIdentifierAttributeName() { + return this.config.getUniqueIdentifierAttributeName(); + } + + private NamingEnumeration createEmptyEnumeration() { + return new NamingEnumeration() { + @Override + public SearchResult next() throws NamingException { + return null; //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + public boolean hasMore() throws NamingException { + return false; //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + public void close() throws NamingException { + //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + public boolean hasMoreElements() { + return false; //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + public SearchResult nextElement() { + return null; //To change body of implemented methods use File | Settings | File Templates. + } + }; + } + + public Attributes getAttributes(final String entryUUID, final String baseDN, LDAPMappingConfiguration mappingConfiguration) { + SearchResult search = lookupById(baseDN, entryUUID, mappingConfiguration); + + if (search == null) { + throw new ModelException("Couldn't find item with entryUUID [" + entryUUID + "] and baseDN [" + baseDN + "]"); + } + + return search.getAttributes(); + } + + public String decodeEntryUUID(final Object entryUUID) { + String id; + + if (this.config.isActiveDirectory()) { + id = LDAPUtil.decodeObjectGUID((byte[]) entryUUID); + } else { + id = entryUUID.toString(); + } + + return id; + } + + private LdapContext createLdapContext() throws NamingException { + return new InitialLdapContext(new Hashtable(this.connectionProperties), null); + } + + private Map createConnectionProperties() { + HashMap env = new HashMap(); + + env.put(Context.INITIAL_CONTEXT_FACTORY, this.config.getFactoryName()); + env.put(Context.SECURITY_AUTHENTICATION, this.config.getAuthType()); + + String protocol = this.config.getProtocol(); + + if (protocol != null) { + env.put(Context.SECURITY_PROTOCOL, protocol); + } + + String bindDN = this.config.getBindDN(); + + char[] bindCredential = null; + + if (this.config.getBindCredential() != null) { + bindCredential = this.config.getBindCredential().toCharArray(); + } + + if (bindDN != null) { + env.put(Context.SECURITY_PRINCIPAL, bindDN); + env.put(Context.SECURITY_CREDENTIALS, bindCredential); + } + + String url = this.config.getLdapURL(); + + if (url == null) { + throw new RuntimeException("url"); + } + + env.put(Context.PROVIDER_URL, url); + + // Just dump the additional properties + Properties additionalProperties = this.config.getConnectionProperties(); + + if (additionalProperties != null) { + for (Object key : additionalProperties.keySet()) { + env.put(key.toString(), additionalProperties.getProperty(key.toString())); + } + } + + if (config.isActiveDirectory()) { + env.put("java.naming.ldap.attributes.binary", LDAPConstants.OBJECT_GUID); + } + + if (logger.isDebugEnabled()) { + logger.debugf("Creating LdapContext using properties: [%s]", env); + } + + return env; + } + + private R execute(LdapOperation operation) throws NamingException { + LdapContext context = null; + + try { + context = createLdapContext(); + return operation.execute(context); + } catch (NamingException ne) { + logger.error("Could not create Ldap context or operation execution error.", ne); + throw ne; + } finally { + if (context != null) { + try { + context.close(); + } catch (NamingException ne) { + logger.error("Could not close Ldap context.", ne); + } + } + } + } + + private interface LdapOperation { + R execute(LdapContext context) throws NamingException; + } + + private List getReturningAttributes(final LDAPMappingConfiguration mappingConfiguration) { + List returningAttributes = new ArrayList(); + + if (mappingConfiguration != null) { + returningAttributes.addAll(mappingConfiguration.getMappedProperties().values()); + + returningAttributes.add(mappingConfiguration.getParentMembershipAttributeName()); + +// for (LDAPMappingConfiguration relationshipConfig : this.config.getRelationshipConfigs()) { +// if (relationshipConfig.getRelatedAttributedType().equals(mappingConfiguration.getMappedClass())) { +// returningAttributes.addAll(relationshipConfig.getMappedProperties().values()); +// } +// } + } else { + returningAttributes.add("*"); + } + + returningAttributes.add(getUniqueIdentifierAttributeName()); + returningAttributes.add(LDAPConstants.CREATE_TIMESTAMP); + returningAttributes.add(LDAPConstants.OBJECT_CLASS); + + return returningAttributes; + } +} \ No newline at end of file diff --git a/federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/store/ldap/LDAPUtil.java b/federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/store/ldap/LDAPUtil.java new file mode 100644 index 0000000000..f08ff855b2 --- /dev/null +++ b/federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/store/ldap/LDAPUtil.java @@ -0,0 +1,158 @@ +package org.keycloak.federation.ldap.idm.store.ldap; + +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.TimeZone; + +import org.keycloak.models.ModelException; + +/** + *

Utility class for working with LDAP.

+ * + * @author Pedro Igor + */ +public class LDAPUtil { + + /** + *

Formats the given date.

+ * + * @param date The Date to format. + * + * @return A String representing the formatted date. + */ + public static final String formatDate(Date date) { + if (date == null) { + throw new IllegalArgumentException("You must provide a date."); + } + + SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss'.0Z'"); + + dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); + + return dateFormat.format(date); + } + + /** + *

+ * Parses dates/time stamps stored in LDAP. Some possible values: + *

+ *
    + *
  • 20020228150820
  • + *
  • 20030228150820Z
  • + *
  • 20050228150820.12
  • + *
  • 20060711011740.0Z
  • + *
+ * + * @param date The date string to parse from. + * + * @return the Date. + */ + public static final Date parseDate(String date) { + SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss"); + + try { + if (date.endsWith("Z")) { + dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); + } else { + dateFormat.setTimeZone(TimeZone.getDefault()); + } + + return dateFormat.parse(date); + } catch (Exception e) { + throw new ModelException("Error converting ldap date.", e); + } + } + + + + /** + *

Creates a byte-based {@link String} representation of a raw byte array representing the value of the + * objectGUID attribute retrieved from Active Directory.

+ * + *

The returned string is useful to perform queries on AD based on the objectGUID value. Eg.:

+ * + *

+ * String filter = "(&(objectClass=*)(objectGUID" + EQUAL + convertObjectGUIToByteString(objectGUID) + "))"; + *

+ * + * @param objectGUID A raw byte array representing the value of the objectGUID attribute retrieved from + * Active Directory. + * + * @return A byte-based String representation in the form of \[0]\[1]\[2]\[3]\[4]\[5]\[6]\[7]\[8]\[9]\[10]\[11]\[12]\[13]\[14]\[15] + */ + public static String convertObjectGUIToByteString(byte[] objectGUID) { + StringBuilder result = new StringBuilder(); + + for (int i = 0; i < objectGUID.length; i++) { + String transformed = prefixZeros((int) objectGUID[i] & 0xFF); + result.append("\\"); + result.append(transformed); + } + + return result.toString(); + } + + /** + *

Decode a raw byte array representing the value of the objectGUID attribute retrieved from Active + * Directory.

+ * + *

The returned string is useful to directly bind an entry. Eg.:

+ * + *

+ * String bindingString = decodeObjectGUID(objectGUID); + *
+ * Attributes attributes = ctx.getAttributes(bindingString); + *

+ * + * @param objectGUID A raw byte array representing the value of the objectGUID attribute retrieved from + * Active Directory. + * + * @return A string representing the decoded value in the form of [3][2][1][0]-[5][4]-[7][6]-[8][9]-[10][11][12][13][14][15]. + */ + public static String decodeObjectGUID(byte[] objectGUID) { + StringBuilder displayStr = new StringBuilder(); + + displayStr.append(convertToDashedString(objectGUID)); + + return displayStr.toString(); + } + + private static String convertToDashedString(byte[] objectGUID) { + StringBuilder displayStr = new StringBuilder(); + + displayStr.append(prefixZeros((int) objectGUID[3] & 0xFF)); + displayStr.append(prefixZeros((int) objectGUID[2] & 0xFF)); + displayStr.append(prefixZeros((int) objectGUID[1] & 0xFF)); + displayStr.append(prefixZeros((int) objectGUID[0] & 0xFF)); + displayStr.append("-"); + displayStr.append(prefixZeros((int) objectGUID[5] & 0xFF)); + displayStr.append(prefixZeros((int) objectGUID[4] & 0xFF)); + displayStr.append("-"); + displayStr.append(prefixZeros((int) objectGUID[7] & 0xFF)); + displayStr.append(prefixZeros((int) objectGUID[6] & 0xFF)); + displayStr.append("-"); + displayStr.append(prefixZeros((int) objectGUID[8] & 0xFF)); + displayStr.append(prefixZeros((int) objectGUID[9] & 0xFF)); + displayStr.append("-"); + displayStr.append(prefixZeros((int) objectGUID[10] & 0xFF)); + displayStr.append(prefixZeros((int) objectGUID[11] & 0xFF)); + displayStr.append(prefixZeros((int) objectGUID[12] & 0xFF)); + displayStr.append(prefixZeros((int) objectGUID[13] & 0xFF)); + displayStr.append(prefixZeros((int) objectGUID[14] & 0xFF)); + displayStr.append(prefixZeros((int) objectGUID[15] & 0xFF)); + + return displayStr.toString(); + } + + private static String prefixZeros(int value) { + if (value <= 0xF) { + StringBuilder sb = new StringBuilder("0"); + sb.append(Integer.toHexString(value)); + return sb.toString(); + } else { + return Integer.toHexString(value); + } + } + + +} diff --git a/model/api/src/main/java/org/keycloak/models/LDAPConstants.java b/model/api/src/main/java/org/keycloak/models/LDAPConstants.java index bf76be7be9..acab3e0d6e 100644 --- a/model/api/src/main/java/org/keycloak/models/LDAPConstants.java +++ b/model/api/src/main/java/org/keycloak/models/LDAPConstants.java @@ -29,5 +29,40 @@ public class LDAPConstants { public static final String BATCH_SIZE_FOR_SYNC = "batchSizeForSync"; public static final int DEFAULT_BATCH_SIZE_FOR_SYNC = 1000; + // Config option to specify if registrations will be synced or not + public static final String SYNC_REGISTRATIONS = "syncRegistrations"; + + // Applicable just for active directory public static final String USER_ACCOUNT_CONTROLS_AFTER_PASSWORD_UPDATE = "userAccountControlsAfterPasswordUpdate"; + + // Custom attributes on UserModel, which is mapped to LDAP + public static final String LDAP_ID = "LDAP_ID"; + public static final String LDAP_ENTRY_DN = "LDAP_ENTRY_DN"; + + + // Those are forked from Picketlink + public static final String GIVENNAME = "givenname"; + public static final String CN = "cn"; + public static final String SN = "sn"; + public static final String EMAIL = "mail"; + public static final String MEMBER = "member"; + public static final String MEMBER_OF = "memberOf"; + public static final String OBJECT_CLASS = "objectclass"; + public static final String UID = "uid"; + public static final String USER_PASSWORD_ATTRIBUTE = "userpassword"; + public static final String GROUP_OF_NAMES = "groupOfNames"; + public static final String GROUP_OF_ENTRIES = "groupOfEntries"; + public static final String GROUP_OF_UNIQUE_NAMES = "groupOfUniqueNames"; + + public static final String COMMA = ","; + public static final String EQUAL = "="; + public static final String SPACE_STRING = " "; + + public static final String CUSTOM_ATTRIBUTE_ENABLED = "enabled"; + public static final String CUSTOM_ATTRIBUTE_CREATE_DATE = "createDate"; + public static final String CUSTOM_ATTRIBUTE_EXPIRY_DATE = "expiryDate"; + public static final String ENTRY_UUID = "entryUUID"; + public static final String OBJECT_GUID = "objectGUID"; + public static final String CREATE_TIMESTAMP = "createTimeStamp"; + public static final String MODIFY_TIMESTAMP = "modifyTimeStamp"; } diff --git a/model/api/src/main/java/org/keycloak/models/utils/reflection/NamedPropertyCriteria.java b/model/api/src/main/java/org/keycloak/models/utils/reflection/NamedPropertyCriteria.java new file mode 100644 index 0000000000..fc3b538d45 --- /dev/null +++ b/model/api/src/main/java/org/keycloak/models/utils/reflection/NamedPropertyCriteria.java @@ -0,0 +1,40 @@ +package org.keycloak.models.utils.reflection; + +import java.beans.Introspector; +import java.lang.reflect.Field; +import java.lang.reflect.Method; + +/** + * A criteria that matches a property based on name + * + * @see PropertyCriteria + */ +public class NamedPropertyCriteria implements PropertyCriteria { + private final String[] propertyNames; + + public NamedPropertyCriteria(String... propertyNames) { + this.propertyNames = propertyNames; + } + + public boolean fieldMatches(Field f) { + for (String propertyName : propertyNames) { + if (propertyName.equals(f.getName())) { + return true; + } + } + return false; + } + + public boolean methodMatches(Method m) { + String[] validPrefix = {"get", "is"}; + for (String propertyName : propertyNames) { + for (String prefix : validPrefix) { + if (m.getName().startsWith(prefix) && + Introspector.decapitalize(m.getName().substring(prefix.length())).equals(propertyName)) { + return true; + } + } + } + return false; + } +} diff --git a/model/api/src/main/java/org/keycloak/models/utils/reflection/TypedPropertyCriteria.java b/model/api/src/main/java/org/keycloak/models/utils/reflection/TypedPropertyCriteria.java new file mode 100644 index 0000000000..93688a4102 --- /dev/null +++ b/model/api/src/main/java/org/keycloak/models/utils/reflection/TypedPropertyCriteria.java @@ -0,0 +1,71 @@ +package org.keycloak.models.utils.reflection; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; + +/** + * A criteria that matches a property based on its type + * + * @see PropertyCriteria + */ +public class TypedPropertyCriteria implements PropertyCriteria { + + /** + *

Different options can be used to match a specific property based on its type. Regardless of the option + * chosen, if the property type equals the propertyClass it will be selected.

  • SUB_TYPE: + * Also consider properties where its type is a subtype of propertyClass. .
  • SUPER_TYPE: Also + * consider properties where its type is a superclass or superinterface of propertyClass. .
+ *

+ */ + public static enum MatchOption { + SUB_TYPE, SUPER_TYPE, ALL + } + + private final Class propertyClass; + private final MatchOption matchOption; + + public TypedPropertyCriteria(Class propertyClass) { + this(propertyClass, null); + } + + public TypedPropertyCriteria(Class propertyClass, MatchOption matchOption) { + if (propertyClass == null) { + throw new IllegalArgumentException("Property class can not be null."); + } + this.propertyClass = propertyClass; + this.matchOption = matchOption; + } + + public boolean fieldMatches(Field f) { + return match(f.getType()); + } + + public boolean methodMatches(Method m) { + return match(m.getReturnType()); + } + + private boolean match(Class type) { + if (propertyClass.equals(type)) { + return true; + } else { + boolean matchSubType = propertyClass.isAssignableFrom(type); + + if (MatchOption.SUB_TYPE == this.matchOption) { + return matchSubType; + } + + boolean matchSuperType = type.isAssignableFrom(propertyClass); + + if (MatchOption.SUPER_TYPE == this.matchOption) { + return matchSuperType; + } + + if (MatchOption.ALL == this.matchOption) { + return matchSubType || matchSuperType; + } + } + + return false; + } +} + diff --git a/picketlink/keycloak-picketlink-api/pom.xml b/picketlink/keycloak-picketlink-api/pom.xml deleted file mode 100755 index 5655ce9516..0000000000 --- a/picketlink/keycloak-picketlink-api/pom.xml +++ /dev/null @@ -1,55 +0,0 @@ - - - - keycloak-picketlink-parent - org.keycloak - 1.2.0.RC1-SNAPSHOT - ../pom.xml - - 4.0.0 - - keycloak-picketlink-api - Keycloak Picketlink API - - - - - org.keycloak - keycloak-core - ${project.version} - provided - - - org.keycloak - keycloak-model-api - ${project.version} - provided - - - org.picketlink - picketlink-idm-api - provided - - - org.jboss.logging - jboss-logging - provided - - - - - - - org.apache.maven.plugins - maven-compiler-plugin - - ${maven.compiler.source} - ${maven.compiler.target} - - - - - - diff --git a/picketlink/keycloak-picketlink-api/src/main/java/org/keycloak/picketlink/PartitionManagerProvider.java b/picketlink/keycloak-picketlink-api/src/main/java/org/keycloak/picketlink/PartitionManagerProvider.java deleted file mode 100644 index 0b22305364..0000000000 --- a/picketlink/keycloak-picketlink-api/src/main/java/org/keycloak/picketlink/PartitionManagerProvider.java +++ /dev/null @@ -1,14 +0,0 @@ -package org.keycloak.picketlink; - -import org.keycloak.models.UserFederationProviderModel; -import org.keycloak.provider.Provider; -import org.picketlink.idm.PartitionManager; - -/** - * - * @author Marek Posolda - */ -public interface PartitionManagerProvider extends Provider { - - PartitionManager getPartitionManager(UserFederationProviderModel model); -} diff --git a/picketlink/keycloak-picketlink-api/src/main/java/org/keycloak/picketlink/PartitionManagerProviderFactory.java b/picketlink/keycloak-picketlink-api/src/main/java/org/keycloak/picketlink/PartitionManagerProviderFactory.java deleted file mode 100644 index 203c7f9c23..0000000000 --- a/picketlink/keycloak-picketlink-api/src/main/java/org/keycloak/picketlink/PartitionManagerProviderFactory.java +++ /dev/null @@ -1,9 +0,0 @@ -package org.keycloak.picketlink; - -import org.keycloak.provider.ProviderFactory; - -/** - * @author Marek Posolda - */ -public interface PartitionManagerProviderFactory extends ProviderFactory { -} diff --git a/picketlink/keycloak-picketlink-api/src/main/java/org/keycloak/picketlink/PartitionManagerSpi.java b/picketlink/keycloak-picketlink-api/src/main/java/org/keycloak/picketlink/PartitionManagerSpi.java deleted file mode 100644 index 721cf12d68..0000000000 --- a/picketlink/keycloak-picketlink-api/src/main/java/org/keycloak/picketlink/PartitionManagerSpi.java +++ /dev/null @@ -1,25 +0,0 @@ -package org.keycloak.picketlink; - -import org.keycloak.provider.Provider; -import org.keycloak.provider.ProviderFactory; -import org.keycloak.provider.Spi; - -/** - * @author Stian Thorgersen - */ -public class PartitionManagerSpi implements Spi { - @Override - public String getName() { - return "picketlink-idm"; - } - - @Override - public Class getProviderClass() { - return PartitionManagerProvider.class; - } - - @Override - public Class getProviderFactoryClass() { - return PartitionManagerProviderFactory.class; - } -} diff --git a/picketlink/keycloak-picketlink-api/src/main/resources/META-INF/services/org.keycloak.provider.Spi b/picketlink/keycloak-picketlink-api/src/main/resources/META-INF/services/org.keycloak.provider.Spi deleted file mode 100644 index 88b1bcc076..0000000000 --- a/picketlink/keycloak-picketlink-api/src/main/resources/META-INF/services/org.keycloak.provider.Spi +++ /dev/null @@ -1 +0,0 @@ -org.keycloak.picketlink.PartitionManagerSpi \ No newline at end of file diff --git a/picketlink/keycloak-picketlink-ldap/pom.xml b/picketlink/keycloak-picketlink-ldap/pom.xml deleted file mode 100755 index 921637699d..0000000000 --- a/picketlink/keycloak-picketlink-ldap/pom.xml +++ /dev/null @@ -1,66 +0,0 @@ - - - - keycloak-picketlink-parent - org.keycloak - 1.2.0.RC1-SNAPSHOT - ../pom.xml - - 4.0.0 - - keycloak-picketlink-ldap - Keycloak Picketlink LDAP - - - - - org.keycloak - keycloak-core - ${project.version} - provided - - - org.keycloak - keycloak-model-api - ${project.version} - provided - - - org.keycloak - keycloak-picketlink-api - ${project.version} - provided - - - org.picketlink - picketlink-idm-api - provided - - - org.picketlink - picketlink-idm-impl - provided - - - org.jboss.logging - jboss-logging - provided - - - - - - - org.apache.maven.plugins - maven-compiler-plugin - - ${maven.compiler.source} - ${maven.compiler.target} - - - - - - diff --git a/picketlink/keycloak-picketlink-ldap/src/main/java/org/keycloak/picketlink/idm/KeycloakEventBridge.java b/picketlink/keycloak-picketlink-ldap/src/main/java/org/keycloak/picketlink/idm/KeycloakEventBridge.java deleted file mode 100755 index 1fd7f159d8..0000000000 --- a/picketlink/keycloak-picketlink-ldap/src/main/java/org/keycloak/picketlink/idm/KeycloakEventBridge.java +++ /dev/null @@ -1,63 +0,0 @@ -package org.keycloak.picketlink.idm; - -import org.jboss.logging.Logger; -import org.picketlink.idm.IdentityManager; -import org.picketlink.idm.PartitionManager; -import org.picketlink.idm.event.CredentialUpdatedEvent; -import org.picketlink.idm.event.EventBridge; -import org.picketlink.idm.internal.ContextualIdentityManager; -import org.picketlink.idm.ldap.internal.LDAPIdentityStore; -import org.picketlink.idm.ldap.internal.LDAPOperationManager; -import org.picketlink.idm.model.basic.User; -import org.picketlink.idm.spi.CredentialStore; -import org.picketlink.idm.spi.IdentityContext; -import org.picketlink.idm.spi.StoreSelector; - -import javax.naming.directory.BasicAttribute; -import javax.naming.directory.DirContext; -import javax.naming.directory.ModificationItem; - -/** - * @author Marek Posolda - */ -public class KeycloakEventBridge implements EventBridge { - - private static final Logger logger = Logger.getLogger(KeycloakEventBridge.class); - - private final boolean updateUserAccountAfterPasswordUpdate; - - public KeycloakEventBridge(boolean updateUserAccountAfterPasswordUpdate) { - this.updateUserAccountAfterPasswordUpdate = updateUserAccountAfterPasswordUpdate; - if (updateUserAccountAfterPasswordUpdate) { - logger.info("userAccountControl attribute will be updated in Active Directory after user registration"); - } - } - - @Override - public void raiseEvent(Object event) { - // Used in ActiveDirectory to put account into "enabled" state (aka userAccountControl=512, see http://support.microsoft.com/kb/305144/en ) after password update. If value is -1, it's ignored - if (updateUserAccountAfterPasswordUpdate && event instanceof CredentialUpdatedEvent) { - CredentialUpdatedEvent credEvent = ((CredentialUpdatedEvent) event); - PartitionManager partitionManager = credEvent.getPartitionMananger(); - ContextualIdentityManager identityManager = (ContextualIdentityManager) partitionManager.createIdentityManager(); - IdentityContext identityCtx = identityManager.getIdentityContext(); - - CredentialStore store = identityManager.getStoreSelector().getStoreForCredentialOperation(identityCtx, credEvent.getCredential().getClass()); - if (store instanceof LDAPIdentityStore) { - LDAPIdentityStore ldapStore = (LDAPIdentityStore)store; - LDAPOperationManager operationManager = ldapStore.getOperationManager(); - User picketlinkUser = (User) credEvent.getAccount(); - String userDN = ldapStore.getBindingDN(picketlinkUser, true); - - ModificationItem[] mods = new ModificationItem[1]; - BasicAttribute mod0 = new BasicAttribute("userAccountControl", "512"); - mods[0] = new ModificationItem(DirContext.REPLACE_ATTRIBUTE, mod0); - operationManager.modifyAttribute(userDN, mod0); - logger.debug("Attribute userAccountControls switched to 512 after password update of user " + picketlinkUser.getLoginName()); - } else { - logger.debug("Store for credential updates is not LDAPIdentityStore. Ignored"); - } - - } - } -} diff --git a/picketlink/keycloak-picketlink-ldap/src/main/java/org/keycloak/picketlink/idm/LDAPKeycloakCredentialHandler.java b/picketlink/keycloak-picketlink-ldap/src/main/java/org/keycloak/picketlink/idm/LDAPKeycloakCredentialHandler.java deleted file mode 100755 index bc5278c316..0000000000 --- a/picketlink/keycloak-picketlink-ldap/src/main/java/org/keycloak/picketlink/idm/LDAPKeycloakCredentialHandler.java +++ /dev/null @@ -1,51 +0,0 @@ -package org.keycloak.picketlink.idm; - -import org.picketlink.idm.IdentityManager; -import org.picketlink.idm.config.LDAPMappingConfiguration; -import org.picketlink.idm.credential.UsernamePasswordCredentials; -import org.picketlink.idm.credential.storage.CredentialStorage; -import org.picketlink.idm.ldap.internal.LDAPIdentityStore; -import org.picketlink.idm.ldap.internal.LDAPPlainTextPasswordCredentialHandler; -import org.picketlink.idm.model.Account; -import org.picketlink.idm.model.basic.BasicModel; -import org.picketlink.idm.model.basic.User; -import org.picketlink.idm.spi.IdentityContext; - -import javax.naming.directory.SearchResult; - -import static org.picketlink.idm.IDMLog.CREDENTIAL_LOGGER; - -/** - * @author Marek Posolda - */ -public class LDAPKeycloakCredentialHandler extends LDAPPlainTextPasswordCredentialHandler { - - // Overridden as in Keycloak, we don't have Agents - @Override - protected User getAccount(IdentityContext context, String loginName) { - IdentityManager identityManager = getIdentityManager(context); - - if (CREDENTIAL_LOGGER.isDebugEnabled()) { - CREDENTIAL_LOGGER.debugf("Trying to find account [%s] using default account type [%s]", loginName, User.class); - } - - return BasicModel.getUser(identityManager, loginName); - } - - - @Override - protected boolean validateCredential(IdentityContext context, CredentialStorage credentialStorage, UsernamePasswordCredentials credentials, LDAPIdentityStore ldapIdentityStore) { - Account account = getAccount(context, credentials.getUsername()); - char[] password = credentials.getPassword().getValue(); - String userDN = (String) account.getAttribute(LDAPIdentityStore.ENTRY_DN_ATTRIBUTE_NAME).getValue(); - if (CREDENTIAL_LOGGER.isDebugEnabled()) { - CREDENTIAL_LOGGER.debugf("Using DN [%s] for authentication of user [%s]", userDN, credentials.getUsername()); - } - - if (ldapIdentityStore.getOperationManager().authenticate(userDN, new String(password))) { - return true; - } - - return false; - } -} diff --git a/picketlink/keycloak-picketlink-ldap/src/main/java/org/keycloak/picketlink/ldap/LDAPPartitionManagerProvider.java b/picketlink/keycloak-picketlink-ldap/src/main/java/org/keycloak/picketlink/ldap/LDAPPartitionManagerProvider.java deleted file mode 100644 index bbb7201e69..0000000000 --- a/picketlink/keycloak-picketlink-ldap/src/main/java/org/keycloak/picketlink/ldap/LDAPPartitionManagerProvider.java +++ /dev/null @@ -1,26 +0,0 @@ -package org.keycloak.picketlink.ldap; - -import org.keycloak.models.UserFederationProviderModel; -import org.keycloak.picketlink.PartitionManagerProvider; -import org.picketlink.idm.PartitionManager; - -/** - * @author Marek Posolda - */ -public class LDAPPartitionManagerProvider implements PartitionManagerProvider { - - private final PartitionManagerRegistry partitionManagerRegistry; - - public LDAPPartitionManagerProvider(PartitionManagerRegistry partitionManagerRegistry) { - this.partitionManagerRegistry = partitionManagerRegistry; - } - - @Override - public PartitionManager getPartitionManager(UserFederationProviderModel model) { - return partitionManagerRegistry.getPartitionManager(model); - } - - @Override - public void close() { - } -} diff --git a/picketlink/keycloak-picketlink-ldap/src/main/java/org/keycloak/picketlink/ldap/LDAPPartitionManagerProviderFactory.java b/picketlink/keycloak-picketlink-ldap/src/main/java/org/keycloak/picketlink/ldap/LDAPPartitionManagerProviderFactory.java deleted file mode 100755 index 851201d8f0..0000000000 --- a/picketlink/keycloak-picketlink-ldap/src/main/java/org/keycloak/picketlink/ldap/LDAPPartitionManagerProviderFactory.java +++ /dev/null @@ -1,43 +0,0 @@ -package org.keycloak.picketlink.ldap; - -import org.keycloak.Config; -import org.keycloak.models.KeycloakSession; -import org.keycloak.models.KeycloakSessionFactory; -import org.keycloak.picketlink.PartitionManagerProvider; -import org.keycloak.picketlink.PartitionManagerProviderFactory; -import org.picketlink.idm.PartitionManager; - -/** - * Obtains {@link PartitionManager} instances from shared {@link PartitionManagerRegistry} and uses UserFederationModel configuration for it - * - * @author Marek Posolda - */ -public class LDAPPartitionManagerProviderFactory implements PartitionManagerProviderFactory { - - private PartitionManagerRegistry partitionManagerRegistry; - - @Override - public PartitionManagerProvider create(KeycloakSession session) { - return new LDAPPartitionManagerProvider(partitionManagerRegistry); - } - - @Override - public void init(Config.Scope config) { - partitionManagerRegistry = new PartitionManagerRegistry(); - } - - @Override - public void postInit(KeycloakSessionFactory factory) { - - } - - @Override - public void close() { - } - - @Override - public String getId() { - return "ldap"; - } - -} diff --git a/picketlink/keycloak-picketlink-ldap/src/main/java/org/keycloak/picketlink/ldap/PartitionManagerRegistry.java b/picketlink/keycloak-picketlink-ldap/src/main/java/org/keycloak/picketlink/ldap/PartitionManagerRegistry.java deleted file mode 100755 index a120ee1876..0000000000 --- a/picketlink/keycloak-picketlink-ldap/src/main/java/org/keycloak/picketlink/ldap/PartitionManagerRegistry.java +++ /dev/null @@ -1,163 +0,0 @@ -package org.keycloak.picketlink.ldap; - -import org.jboss.logging.Logger; -import org.keycloak.models.LDAPConstants; -import org.keycloak.models.UserFederationProviderModel; -import org.keycloak.picketlink.idm.KeycloakEventBridge; -import org.keycloak.picketlink.idm.LDAPKeycloakCredentialHandler; -import org.picketlink.idm.PartitionManager; -import org.picketlink.idm.config.IdentityConfigurationBuilder; -import org.picketlink.idm.config.LDAPMappingConfigurationBuilder; -import org.picketlink.idm.config.LDAPStoreConfigurationBuilder; -import org.picketlink.idm.internal.DefaultPartitionManager; -import org.picketlink.idm.model.basic.User; - -import java.util.HashMap; -import java.util.Map; -import java.util.Properties; -import java.util.concurrent.ConcurrentHashMap; - -import static org.picketlink.common.constants.LDAPConstants.*; - -/** - * @author Marek Posolda - */ -public class PartitionManagerRegistry { - - private static final Logger logger = Logger.getLogger(PartitionManagerRegistry.class); - - private Map partitionManagers = new ConcurrentHashMap(); - - public PartitionManager getPartitionManager(UserFederationProviderModel model) { - PartitionManagerContext context = partitionManagers.get(model.getId()); - - // Ldap config might have changed for the realm. In this case, we must re-initialize - Map config = model.getConfig(); - if (context == null || !config.equals(context.config)) { - logLDAPConfig(model.getId(), config); - - PartitionManager manager = createPartitionManager(config); - context = new PartitionManagerContext(config, manager); - partitionManagers.put(model.getId(), context); - } - return context.partitionManager; - } - - // Don't log LDAP password - private void logLDAPConfig(String fedProviderId, Map ldapConfig) { - Map copy = new HashMap(ldapConfig); - copy.remove(LDAPConstants.BIND_CREDENTIAL); - logger.infof("Creating new LDAP based partition manager for the Federation provider: " + fedProviderId + ", LDAP Configuration: " + copy); - } - - /** - * @param ldapConfig from realm - * @return PartitionManager instance based on LDAP store - */ - public static PartitionManager createPartitionManager(Map ldapConfig) { - IdentityConfigurationBuilder builder = new IdentityConfigurationBuilder(); - - Properties connectionProps = new Properties(); - if (ldapConfig.containsKey(LDAPConstants.CONNECTION_POOLING)) { - connectionProps.put("com.sun.jndi.ldap.connect.pool", ldapConfig.get(LDAPConstants.CONNECTION_POOLING)); - } - - checkSystemProperty("com.sun.jndi.ldap.connect.pool.authentication", "none simple"); - checkSystemProperty("com.sun.jndi.ldap.connect.pool.initsize", "1"); - checkSystemProperty("com.sun.jndi.ldap.connect.pool.maxsize", "1000"); - checkSystemProperty("com.sun.jndi.ldap.connect.pool.prefsize", "5"); - checkSystemProperty("com.sun.jndi.ldap.connect.pool.timeout", "300000"); - checkSystemProperty("com.sun.jndi.ldap.connect.pool.protocol", "plain"); - checkSystemProperty("com.sun.jndi.ldap.connect.pool.debug", "off"); - - String vendor = ldapConfig.get(LDAPConstants.VENDOR); - - boolean activeDirectory = vendor != null && vendor.equals(LDAPConstants.VENDOR_ACTIVE_DIRECTORY); - - String ldapLoginNameMapping = ldapConfig.get(LDAPConstants.USERNAME_LDAP_ATTRIBUTE); - if (ldapLoginNameMapping == null) { - ldapLoginNameMapping = activeDirectory ? CN : UID; - } - - String ldapFirstNameMapping = activeDirectory ? "givenName" : CN; - String createTimestampMapping = activeDirectory ? "whenCreated" : CREATE_TIMESTAMP; - String modifyTimestampMapping = activeDirectory ? "whenChanged" : MODIFY_TIMESTAMP; - String[] userObjectClasses = getUserObjectClasses(ldapConfig); - - boolean pagination = ldapConfig.containsKey(LDAPConstants.PAGINATION) ? Boolean.parseBoolean(ldapConfig.get(LDAPConstants.PAGINATION)) : false; - - // Use same mapping for User and Agent for now - LDAPStoreConfigurationBuilder ldapStoreBuilder = - builder - .named("SIMPLE_LDAP_STORE_CONFIG") - .stores() - .ldap() - .connectionProperties(connectionProps) - .addCredentialHandler(LDAPKeycloakCredentialHandler.class) - .baseDN(ldapConfig.get(LDAPConstants.BASE_DN)) - .bindDN(ldapConfig.get(LDAPConstants.BIND_DN)) - .bindCredential(ldapConfig.get(LDAPConstants.BIND_CREDENTIAL)) - .url(ldapConfig.get(LDAPConstants.CONNECTION_URL)) - .activeDirectory(activeDirectory) - .supportAllFeatures() - .pagination(pagination); - - // RHDS is using "nsuniqueid" as unique identifier instead of "entryUUID" - if (vendor != null && vendor.equals(LDAPConstants.VENDOR_RHDS)) { - ldapStoreBuilder.uniqueIdentifierAttributeName("nsuniqueid"); - } else if (LDAPConstants.VENDOR_TIVOLI.equals(vendor)) { - ldapStoreBuilder.uniqueIdentifierAttributeName("uniqueidentifier"); - } - - LDAPMappingConfigurationBuilder ldapUserMappingBuilder = ldapStoreBuilder - .mapping(User.class) - .baseDN(ldapConfig.get(LDAPConstants.USER_DN_SUFFIX)) - .objectClasses(userObjectClasses) - .attribute("loginName", ldapLoginNameMapping, true) - .attribute("firstName", ldapFirstNameMapping) - .attribute("lastName", SN) - .attribute("email", EMAIL) - .readOnlyAttribute("createdDate", createTimestampMapping) - .readOnlyAttribute("modifyDate", modifyTimestampMapping); - - if (activeDirectory && ldapLoginNameMapping.equals("sAMAccountName")) { - ldapUserMappingBuilder.bindingAttribute("fullName", CN); - logger.infof("Using 'cn' attribute for DN of user and 'sAMAccountName' for username"); - } - - KeycloakEventBridge eventBridge = new KeycloakEventBridge(activeDirectory && "true".equals(ldapConfig.get(LDAPConstants.USER_ACCOUNT_CONTROLS_AFTER_PASSWORD_UPDATE))); - return new DefaultPartitionManager(builder.buildAll(), eventBridge, null); - } - - private static void checkSystemProperty(String name, String defaultValue) { - if (System.getProperty(name) == null) { - System.setProperty(name, defaultValue); - } - } - - // Parse array of strings like [ "inetOrgPerson", "organizationalPerson" ] from the string like: "inetOrgPerson, organizationalPerson" - private static String[] getUserObjectClasses(Map ldapConfig) { - String objClassesCfg = ldapConfig.get(LDAPConstants.USER_OBJECT_CLASSES); - String objClassesStr = (objClassesCfg != null && objClassesCfg.length() > 0) ? objClassesCfg.trim() : "inetOrgPerson, organizationalPerson"; - - String[] objectClasses = objClassesStr.split(","); - - // Trim them - String[] userObjectClasses = new String[objectClasses.length]; - for (int i=0 ; i config, PartitionManager manager) { - this.config = config; - this.partitionManager = manager; - } - - private Map config; - private PartitionManager partitionManager; - } -} diff --git a/picketlink/keycloak-picketlink-ldap/src/main/resources/META-INF/services/org.keycloak.picketlink.PartitionManagerProviderFactory b/picketlink/keycloak-picketlink-ldap/src/main/resources/META-INF/services/org.keycloak.picketlink.PartitionManagerProviderFactory deleted file mode 100644 index 5bfaf9d173..0000000000 --- a/picketlink/keycloak-picketlink-ldap/src/main/resources/META-INF/services/org.keycloak.picketlink.PartitionManagerProviderFactory +++ /dev/null @@ -1 +0,0 @@ -org.keycloak.picketlink.ldap.LDAPPartitionManagerProviderFactory \ No newline at end of file diff --git a/picketlink/pom.xml b/picketlink/pom.xml deleted file mode 100755 index 10f193561d..0000000000 --- a/picketlink/pom.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - keycloak-parent - org.keycloak - 1.2.0.RC1-SNAPSHOT - ../pom.xml - - 4.0.0 - pom - - keycloak-picketlink-parent - Keycloak Picketlink - - - - keycloak-picketlink-api - keycloak-picketlink-ldap - - - - diff --git a/pom.xml b/pom.xml index f3f68b0414..87ac6079b2 100755 --- a/pom.xml +++ b/pom.xml @@ -114,7 +114,6 @@ model integration proxy - picketlink federation services saml diff --git a/services/pom.xml b/services/pom.xml index e5fde97b37..ea6e90e600 100755 --- a/services/pom.xml +++ b/services/pom.xml @@ -102,12 +102,6 @@ ${project.version} provided - - org.keycloak - keycloak-picketlink-api - ${project.version} - provided - org.jboss.spec.javax.servlet jboss-servlet-api_3.0_spec diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/federation/FederationProvidersIntegrationTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/federation/FederationProvidersIntegrationTest.java index cfaae07ec8..929029eef5 100755 --- a/testsuite/integration/src/test/java/org/keycloak/testsuite/federation/FederationProvidersIntegrationTest.java +++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/federation/FederationProvidersIntegrationTest.java @@ -12,6 +12,8 @@ import org.keycloak.OAuth2Constants; import org.keycloak.federation.ldap.LDAPFederationProvider; import org.keycloak.federation.ldap.LDAPFederationProviderFactory; import org.keycloak.federation.ldap.LDAPUtils; +import org.keycloak.federation.ldap.idm.model.LDAPUser; +import org.keycloak.federation.ldap.idm.store.ldap.LDAPIdentityStore; import org.keycloak.models.KeycloakSession; import org.keycloak.models.LDAPConstants; import org.keycloak.models.ModelReadOnlyException; @@ -21,7 +23,6 @@ import org.keycloak.models.UserCredentialValueModel; import org.keycloak.models.UserFederationProvider; import org.keycloak.models.UserFederationProviderModel; import org.keycloak.models.UserModel; -import org.keycloak.picketlink.PartitionManagerProvider; import org.keycloak.representations.idm.CredentialRepresentation; import org.keycloak.services.managers.RealmManager; import org.keycloak.testsuite.OAuthClient; @@ -35,8 +36,6 @@ import org.keycloak.testsuite.rule.LDAPRule; import org.keycloak.testsuite.rule.WebResource; import org.keycloak.testsuite.rule.WebRule; import org.openqa.selenium.WebDriver; -import org.picketlink.idm.PartitionManager; -import org.picketlink.idm.model.basic.User; import java.util.Map; @@ -57,19 +56,19 @@ public class FederationProvidersIntegrationTest { addUser(manager.getSession(), appRealm, "mary", "mary@test.com", "password-app"); Map ldapConfig = ldapRule.getConfig(); - ldapConfig.put(LDAPFederationProvider.SYNC_REGISTRATIONS, "true"); + ldapConfig.put(LDAPConstants.SYNC_REGISTRATIONS, "true"); ldapConfig.put(LDAPConstants.EDIT_MODE, UserFederationProvider.EditMode.WRITABLE.toString()); ldapModel = appRealm.addUserFederationProvider(LDAPFederationProviderFactory.PROVIDER_NAME, ldapConfig, 0, "test-ldap", -1, -1, 0); // Delete all LDAP users and add some new for testing - PartitionManager partitionManager = getPartitionManager(manager.getSession(), ldapModel); - LDAPUtils.removeAllUsers(partitionManager); + LDAPIdentityStore ldapStore = getLdapIdentityStore(manager.getSession(), ldapModel); + LDAPUtils.removeAllUsers(ldapStore); - User john = LDAPUtils.addUser(partitionManager, "johnkeycloak", "John", "Doe", "john@email.org"); - LDAPUtils.updatePassword(partitionManager, john, "Password1"); + LDAPUser john = LDAPUtils.addUser(ldapStore, "johnkeycloak", "John", "Doe", "john@email.org"); + LDAPUtils.updatePassword(ldapStore, john, "Password1"); - User existing = LDAPUtils.addUser(partitionManager, "existing", "Existing", "Foo", "existing@email.org"); + LDAPUser existing = LDAPUtils.addUser(ldapStore, "existing", "Existing", "Foo", "existing@email.org"); } }); @@ -339,13 +338,13 @@ public class FederationProvidersIntegrationTest { @Test public void testSearch() { KeycloakSession session = keycloakRule.startSession(); - PartitionManager partitionManager = getPartitionManager(session, ldapModel); + LDAPIdentityStore ldapStore = getLdapIdentityStore(session, ldapModel); try { RealmModel appRealm = session.realms().getRealmByName("test"); - LDAPUtils.addUser(partitionManager, "username1", "John1", "Doel1", "user1@email.org"); - LDAPUtils.addUser(partitionManager, "username2", "John2", "Doel2", "user2@email.org"); - LDAPUtils.addUser(partitionManager, "username3", "John3", "Doel3", "user3@email.org"); - LDAPUtils.addUser(partitionManager, "username4", "John4", "Doel4", "user4@email.org"); + LDAPUtils.addUser(ldapStore, "username1", "John1", "Doel1", "user1@email.org"); + LDAPUtils.addUser(ldapStore, "username2", "John2", "Doel2", "user2@email.org"); + LDAPUtils.addUser(ldapStore, "username3", "John3", "Doel3", "user3@email.org"); + LDAPUtils.addUser(ldapStore, "username4", "John4", "Doel4", "user4@email.org"); // Users are not at local store at this moment Assert.assertNull(session.userStorage().getUserByUsername("username1", appRealm)); @@ -395,7 +394,7 @@ public class FederationProvidersIntegrationTest { Assert.assertTrue(session.users().validCredentials(appRealm, user, cred)); // LDAP password is still unchanged - Assert.assertTrue(LDAPUtils.validatePassword(getPartitionManager(session, model), "johnkeycloak", "Password1")); + Assert.assertTrue(LDAPUtils.validatePassword(getLdapIdentityStore(session, model), user, "Password1")); // ATM it's not permitted to delete user in unsynced mode. Should be user deleted just locally instead? Assert.assertFalse(session.users().removeUser(appRealm, user)); @@ -412,9 +411,10 @@ public class FederationProvidersIntegrationTest { } } - static PartitionManager getPartitionManager(KeycloakSession keycloakSession, UserFederationProviderModel ldapFedModel) { - PartitionManagerProvider partitionManagerProvider = keycloakSession.getProvider(PartitionManagerProvider.class); - return partitionManagerProvider.getPartitionManager(ldapFedModel); + static LDAPIdentityStore getLdapIdentityStore(KeycloakSession keycloakSession, UserFederationProviderModel ldapFedModel) { + LDAPFederationProviderFactory ldapProviderFactory = (LDAPFederationProviderFactory) keycloakSession.getKeycloakSessionFactory().getProviderFactory(UserFederationProvider.class, ldapFedModel.getProviderName()); + LDAPFederationProvider ldapProvider = ldapProviderFactory.getInstance(keycloakSession, ldapFedModel); + return ldapProvider.getLdapIdentityStore(); } } diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/federation/SyncProvidersTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/federation/SyncProvidersTest.java index 55f68bb656..f628519af7 100755 --- a/testsuite/integration/src/test/java/org/keycloak/testsuite/federation/SyncProvidersTest.java +++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/federation/SyncProvidersTest.java @@ -7,9 +7,10 @@ import org.junit.Test; import org.junit.rules.RuleChain; import org.junit.rules.TestRule; import org.junit.runners.MethodSorters; -import org.keycloak.federation.ldap.LDAPFederationProvider; import org.keycloak.federation.ldap.LDAPFederationProviderFactory; import org.keycloak.federation.ldap.LDAPUtils; +import org.keycloak.federation.ldap.idm.model.LDAPUser; +import org.keycloak.federation.ldap.idm.store.ldap.LDAPIdentityStore; import org.keycloak.models.KeycloakSession; import org.keycloak.models.KeycloakSessionFactory; import org.keycloak.models.LDAPConstants; @@ -25,8 +26,6 @@ import org.keycloak.testsuite.rule.LDAPRule; import org.keycloak.testutils.DummyUserFederationProviderFactory; import org.keycloak.timer.TimerProvider; import org.keycloak.util.Time; -import org.picketlink.idm.PartitionManager; -import org.picketlink.idm.model.basic.User; import java.util.HashMap; import java.util.Map; @@ -50,26 +49,20 @@ public class SyncProvidersTest { Time.setOffset(0); Map ldapConfig = ldapRule.getConfig(); - ldapConfig.put(LDAPFederationProvider.SYNC_REGISTRATIONS, "false"); + ldapConfig.put(LDAPConstants.SYNC_REGISTRATIONS, "false"); ldapConfig.put(LDAPConstants.EDIT_MODE, UserFederationProvider.EditMode.UNSYNCED.toString()); ldapModel = appRealm.addUserFederationProvider(LDAPFederationProviderFactory.PROVIDER_NAME, ldapConfig, 0, "test-ldap", -1, -1, 0); // Delete all LDAP users and add 5 new users for testing - PartitionManager partitionManager = FederationProvidersIntegrationTest.getPartitionManager(manager.getSession(), ldapModel); - LDAPUtils.removeAllUsers(partitionManager); + LDAPIdentityStore ldapStore = FederationProvidersIntegrationTest.getLdapIdentityStore(manager.getSession(), ldapModel); + LDAPUtils.removeAllUsers(ldapStore); - User user1 = LDAPUtils.addUser(partitionManager, "user1", "User1FN", "User1LN", "user1@email.org"); - LDAPUtils.updatePassword(partitionManager, user1, "Password1"); - User user2 = LDAPUtils.addUser(partitionManager, "user2", "User2FN", "User2LN", "user2@email.org"); - LDAPUtils.updatePassword(partitionManager, user2, "Password2"); - User user3 = LDAPUtils.addUser(partitionManager, "user3", "User3FN", "User3LN", "user3@email.org"); - LDAPUtils.updatePassword(partitionManager, user3, "Password3"); - User user4 = LDAPUtils.addUser(partitionManager, "user4", "User4FN", "User4LN", "user4@email.org"); - LDAPUtils.updatePassword(partitionManager, user4, "Password4"); - User user5 = LDAPUtils.addUser(partitionManager, "user5", "User5FN", "User5LN", "user5@email.org"); - LDAPUtils.updatePassword(partitionManager, user5, "Password5"); + for (int i=1 ; i<6 ; i++) { + LDAPUser user = LDAPUtils.addUser(ldapStore, "user" + i, "User" + i + "FN", "User" + i + "LN", "user" + i + "@email.org"); + LDAPUtils.updatePassword(ldapStore, user, "Password1"); + } // Add dummy provider dummyModel = appRealm.addUserFederationProvider(DummyUserFederationProviderFactory.PROVIDER_NAME, new HashMap(), 1, "test-dummy", -1, 1, 0); @@ -122,9 +115,9 @@ public class SyncProvidersTest { sleep(1000); // Add user to LDAP and update 'user5' in LDAP - PartitionManager partitionManager = FederationProvidersIntegrationTest.getPartitionManager(session, ldapModel); - LDAPUtils.addUser(partitionManager, "user6", "User6FN", "User6LN", "user6@email.org"); - LDAPUtils.updateUser(partitionManager, "user5", "User5FNUpdated", "User5LNUpdated", "user5Updated@email.org"); + LDAPIdentityStore ldapStore = FederationProvidersIntegrationTest.getLdapIdentityStore(session, ldapModel); + LDAPUtils.addUser(ldapStore, "user6", "User6FN", "User6LN", "user6@email.org"); + LDAPUtils.updateUser(ldapStore, "user5", "User5FNUpdated", "User5LNUpdated", "user5Updated@email.org"); // Assert still old users in local provider assertUserImported(userProvider, testRealm, "user5", "User5FN", "User5LN", "user5@email.org"); From 6fbc0975c0a8e7b083d268ac352765258a1517cb Mon Sep 17 00:00:00 2001 From: Stian Thorgersen Date: Thu, 9 Apr 2015 10:01:42 +0200 Subject: [PATCH 04/15] KEYCLOAK-1187 First round: Combined ApplicationModel and OAuthClientModel into ClientModel. Removed OAuth Clients from Admin console and renamed Applications to Clients. --- .../SetConsentRequiredOnOAuthClients.java | 84 + .../META-INF/jpa-changelog-1.2.0.RC1.xml | 7 + .../main/resources/META-INF/persistence.xml | 3 +- ...DefaultMongoConnectionFactoryProvider.java | 3 +- .../idm/ApplicationRepresentation.java | 18 + .../exportimport/util/ExportUtils.java | 43 +- .../exportimport/util/ImportUtils.java | 10 +- .../freemarker/model/SessionsBean.java | 20 +- .../resources/theme/base/account/sessions.ftl | 6 - .../theme/base/admin/resources/js/app.js | 196 -- .../resources/js/controllers/oauth-clients.js | 611 ---- .../admin/resources/js/controllers/realm.js | 8 - .../theme/base/admin/resources/js/loaders.js | 47 - .../theme/base/admin/resources/js/services.js | 137 - .../partials/application-clustering-node.html | 2 +- .../partials/application-clustering.html | 4 +- .../partials/application-detail.html | 20 +- .../partials/application-revocation.html | 2 +- .../partials/application-role-detail.html | 6 +- .../partials/application-role-list.html | 2 +- .../partials/application-scope-mappings.html | 4 +- .../partials/oauth-client-claims.html | 19 - .../partials/oauth-client-credentials.html | 29 - .../partials/oauth-client-detail.html | 116 - .../oauth-client-identity-provider.html | 31 - .../partials/oauth-client-installation.html | 26 - .../resources/partials/oauth-client-list.html | 55 - .../partials/oauth-client-mappers-add.html | 49 - .../partials/oauth-client-mappers.html | 47 - .../oauth-client-protocol-mapper-detail.html | 108 - .../partials/oauth-client-revocation.html | 29 - .../partials/oauth-client-scope-mappings.html | 124 - .../admin/resources/partials/realm-menu.html | 9 +- .../partials/session-revocation.html | 2 +- .../templates/kc-navigation-oauth-client.html | 9 - .../main/resources/theme/base/login/login.ftl | 12 +- .../login/messages/messages_de.properties | 2 +- .../login/messages/messages_en.properties | 2 - .../FreeMarkerLoginFormsProvider.java | 35 +- .../login/freemarker/model/ClientBean.java | 16 +- .../model/IdentityProviderBean.java | 4 - .../client/resource/OAuthClientResource.java | 57 - .../client/resource/OAuthClientsResource.java | 30 - .../admin/client/resource/RealmResource.java | 3 - .../java/org/keycloak/models/AdminRoles.java | 4 +- .../org/keycloak/models/ApplicationModel.java | 56 - .../java/org/keycloak/models/ClientModel.java | 62 +- .../org/keycloak/models/OAuthClientModel.java | 10 - .../java/org/keycloak/models/RealmModel.java | 39 +- .../org/keycloak/models/RealmProvider.java | 4 +- .../java/org/keycloak/models/UserModel.java | 2 +- .../keycloak/models/UserSessionProvider.java | 1 - .../models/entities/ApplicationEntity.java | 159 +- .../models/entities/ClientEntity.java | 154 - .../models/entities/OAuthClientEntity.java | 16 - .../keycloak/models/entities/RoleEntity.java | 11 +- .../models/utils/KeycloakModelUtils.java | 6 +- .../models/utils/ModelToRepresentation.java | 101 +- .../models/utils/RepresentationToModel.java | 56 +- .../models/utils/UserModelDelegate.java | 4 +- .../models/file/FileRealmProvider.java | 24 +- .../models/file/FileUserProvider.java | 4 +- .../file/adapter/ApplicationAdapter.java | 322 -- .../models/file/adapter/ClientAdapter.java | 1080 ++++--- .../file/adapter/OAuthClientAdapter.java | 45 - .../models/file/adapter/RealmAdapter.java | 2431 +++++++-------- .../models/file/adapter/RoleAdapter.java | 6 +- .../models/file/adapter/UserAdapter.java | 6 +- .../infinispan/InfinispanRealmCache.java | 26 - .../models/cache/ApplicationAdapter.java | 247 -- .../models/cache/CacheRealmProvider.java | 4 - .../keycloak/models/cache/ClientAdapter.java | 379 ++- .../cache/DefaultCacheRealmProvider.java | 60 +- .../models/cache/MemoryRealmCache.java | 25 - .../models/cache/NoCacheRealmProvider.java | 21 +- .../models/cache/OAuthClientAdapter.java | 56 - .../keycloak/models/cache/RealmAdapter.java | 126 +- .../org/keycloak/models/cache/RealmCache.java | 10 - .../keycloak/models/cache/RoleAdapter.java | 2 +- .../keycloak/models/cache/UserAdapter.java | 8 +- .../cache/entities/CachedApplication.java | 143 +- .../models/cache/entities/CachedClient.java | 152 - .../cache/entities/CachedOAuthClient.java | 17 - .../models/cache/entities/CachedRealm.java | 777 +++-- .../models/jpa/ApplicationAdapter.java | 308 -- .../keycloak/models/jpa/ClientAdapter.java | 339 +- .../keycloak/models/jpa/JpaRealmProvider.java | 29 +- .../keycloak/models/jpa/JpaUserProvider.java | 4 +- .../models/jpa/OAuthClientAdapter.java | 52 - .../org/keycloak/models/jpa/RealmAdapter.java | 2738 ++++++++--------- .../org/keycloak/models/jpa/RoleAdapter.java | 2 +- .../org/keycloak/models/jpa/UserAdapter.java | 8 +- .../jpa/entities/ApplicationEntity.java | 116 - .../models/jpa/entities/ClientEntity.java | 120 +- .../jpa/entities/OAuthClientEntity.java | 29 - .../jpa/entities/ProtocolMapperEntity.java | 2 - .../models/jpa/entities/RealmEntity.java | 12 +- .../models/jpa/entities/RoleEntity.java | 6 +- .../keycloak/adapters/ApplicationAdapter.java | 275 -- .../keycloak/adapters/ClientAdapter.java | 1117 ++++--- .../keycloak/adapters/MongoRealmProvider.java | 20 +- .../keycloak/adapters/MongoUserProvider.java | 4 +- .../keycloak/adapters/OAuthClientAdapter.java | 48 - .../mongo/keycloak/adapters/RealmAdapter.java | 129 +- .../mongo/keycloak/adapters/RoleAdapter.java | 8 +- .../mongo/keycloak/adapters/UserAdapter.java | 6 +- .../entities/MongoOAuthClientEntity.java | 23 - .../keycloak/entities/MongoRealmEntity.java | 3 - .../keycloak/entities/MongoRoleEntity.java | 6 +- .../models/mongo/utils/MongoModelUtils.java | 4 +- .../infinispan/ClientSessionAdapter.java | 2 +- .../sessions/jpa/ClientSessionAdapter.java | 2 +- .../sessions/jpa/JpaUserSessionProvider.java | 1 - .../sessions/mem/ClientSessionAdapter.java | 2 +- .../sessions/mem/MemUserSessionProvider.java | 1 - .../sessions/mongo/ClientSessionAdapter.java | 2 +- .../saml/EntityDescriptorImporterService.java | 4 +- .../keycloak/protocol/saml/SamlProtocol.java | 23 +- .../protocol/saml/SamlProtocolUtils.java | 2 +- .../keycloak/protocol/saml/SamlService.java | 14 +- .../protocol/saml/mappers/RoleNameMapper.java | 10 +- .../AbstractLoginProtocolFactory.java | 8 - .../protocol/oidc/OIDCLoginProtocol.java | 6 +- .../keycloak/protocol/oidc/TokenManager.java | 11 +- .../oidc/endpoints/AuthorizationEndpoint.java | 5 +- .../endpoints/LoginStatusIframeEndpoint.java | 2 +- .../oidc/endpoints/LogoutEndpoint.java | 3 +- .../oidc/endpoints/TokenEndpoint.java | 5 +- .../oidc/endpoints/UserInfoEndpoint.java | 2 +- .../oidc/utils/AuthorizeClientUtil.java | 2 +- .../protocol/oidc/utils/RedirectUtils.java | 9 +- .../services/managers/ApplianceBootstrap.java | 4 +- .../services/managers/ApplicationManager.java | 40 +- .../org/keycloak/services/managers/Auth.java | 7 +- .../managers/AuthenticationManager.java | 15 +- .../services/managers/OAuthClientManager.java | 96 - .../services/managers/RealmManager.java | 11 +- .../managers/ResourceAdminManager.java | 69 +- .../services/resources/AccountService.java | 8 +- .../resources/ClientsManagementService.java | 45 +- .../resources/IdentityBrokerService.java | 8 +- .../resources/LoginActionsService.java | 4 - .../services/resources/RealmsResource.java | 4 +- .../services/resources/admin/AdminAuth.java | 11 +- .../resources/admin/AdminConsole.java | 8 +- .../services/resources/admin/AdminRoot.java | 2 +- .../resources/admin/ApplicationResource.java | 10 +- .../admin/ApplicationsByIdResource.java | 10 +- .../resources/admin/ApplicationsResource.java | 30 +- .../ClientAttributeCertificateResource.java | 2 - .../admin/IdentityProviderResource.java | 14 +- .../resources/admin/OAuthClientResource.java | 206 -- .../admin/OAuthClientsByIdResource.java | 26 - .../resources/admin/OAuthClientsResource.java | 121 - .../admin/ProtocolMappersResource.java | 3 - .../resources/admin/RealmAdminResource.java | 37 +- .../services/resources/admin/RealmAuth.java | 12 +- .../resources/admin/RealmsAdminResource.java | 11 +- .../resources/admin/RoleByIdResource.java | 11 +- .../admin/RoleContainerResource.java | 6 +- .../resources/admin/RoleResource.java | 4 +- .../admin/ScopeMappedApplicationResource.java | 6 +- .../resources/admin/ScopeMappedResource.java | 13 +- .../UserApplicationRoleMappingsResource.java | 16 +- .../resources/admin/UsersResource.java | 15 +- .../testsuite/account/AccountTest.java | 9 +- .../testsuite/account/ProfileTest.java | 7 +- .../adapter/AdapterTestStrategy.java | 10 +- .../adapter/RelativeUriAdapterTest.java | 4 +- .../testsuite/admin/AdminAPITest.java | 4 +- .../testsuite/admin/ApplicationTest.java | 6 - .../testsuite/admin/OAuthClientTest.java | 54 - .../broker/AbstractIdentityProviderTest.java | 44 +- .../broker/ImportIdentityProviderTest.java | 6 +- .../composites/CompositeRoleTest.java | 10 +- .../federation/AbstractKerberosTest.java | 6 +- .../testsuite/jaxrs/JaxrsBasicAuthTest.java | 6 +- .../testsuite/jaxrs/JaxrsFilterTest.java | 4 +- .../keycloak/testsuite/model/AdapterTest.java | 83 +- .../keycloak/testsuite/model/CacheTest.java | 8 +- ...ionModelTest.java => ClientModelTest.java} | 22 +- .../model/CompositeRolesModelTest.java | 6 +- .../keycloak/testsuite/model/ImportTest.java | 34 +- .../testsuite/model/MultipleRealmsTest.java | 27 +- .../testsuite/model/UserModelTest.java | 4 +- .../model/UserSessionProviderTest.java | 44 +- .../testsuite/oauth/AccessTokenTest.java | 14 +- .../oauth/AuthorizationCodeTest.java | 10 +- .../testsuite/oauth/OAuthRedirectUriTest.java | 22 +- ...urceOwnerPasswordCredentialsGrantTest.java | 4 +- .../testsuite/saml/SamlBindingTest.java | 6 +- .../performance/CreateRealmsWorker.java | 4 +- .../test/tools/jobs/CreateUsersJob.java | 4 +- .../test/tools/jobs/DeleteUsersJob.java | 4 +- .../test/tools/jobs/UpdateUsersJob.java | 4 +- .../keycloak/test/tools/jobs/UsersJob.java | 8 +- 196 files changed, 6069 insertions(+), 9521 deletions(-) create mode 100644 connections/jpa-liquibase/src/main/java/org/keycloak/connections/jpa/updater/liquibase/custom/SetConsentRequiredOnOAuthClients.java delete mode 100755 forms/common-themes/src/main/resources/theme/base/admin/resources/js/controllers/oauth-clients.js delete mode 100755 forms/common-themes/src/main/resources/theme/base/admin/resources/partials/oauth-client-claims.html delete mode 100755 forms/common-themes/src/main/resources/theme/base/admin/resources/partials/oauth-client-credentials.html delete mode 100755 forms/common-themes/src/main/resources/theme/base/admin/resources/partials/oauth-client-detail.html delete mode 100755 forms/common-themes/src/main/resources/theme/base/admin/resources/partials/oauth-client-identity-provider.html delete mode 100755 forms/common-themes/src/main/resources/theme/base/admin/resources/partials/oauth-client-installation.html delete mode 100755 forms/common-themes/src/main/resources/theme/base/admin/resources/partials/oauth-client-list.html delete mode 100755 forms/common-themes/src/main/resources/theme/base/admin/resources/partials/oauth-client-mappers-add.html delete mode 100755 forms/common-themes/src/main/resources/theme/base/admin/resources/partials/oauth-client-mappers.html delete mode 100755 forms/common-themes/src/main/resources/theme/base/admin/resources/partials/oauth-client-protocol-mapper-detail.html delete mode 100755 forms/common-themes/src/main/resources/theme/base/admin/resources/partials/oauth-client-revocation.html delete mode 100755 forms/common-themes/src/main/resources/theme/base/admin/resources/partials/oauth-client-scope-mappings.html delete mode 100755 forms/common-themes/src/main/resources/theme/base/admin/resources/templates/kc-navigation-oauth-client.html delete mode 100755 integration/admin-client/src/main/java/org/keycloak/admin/client/resource/OAuthClientResource.java delete mode 100755 integration/admin-client/src/main/java/org/keycloak/admin/client/resource/OAuthClientsResource.java delete mode 100755 model/api/src/main/java/org/keycloak/models/ApplicationModel.java delete mode 100755 model/api/src/main/java/org/keycloak/models/OAuthClientModel.java delete mode 100755 model/api/src/main/java/org/keycloak/models/entities/ClientEntity.java delete mode 100755 model/api/src/main/java/org/keycloak/models/entities/OAuthClientEntity.java delete mode 100755 model/file/src/main/java/org/keycloak/models/file/adapter/ApplicationAdapter.java delete mode 100755 model/file/src/main/java/org/keycloak/models/file/adapter/OAuthClientAdapter.java delete mode 100755 model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/ApplicationAdapter.java delete mode 100755 model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/OAuthClientAdapter.java delete mode 100755 model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/entities/CachedClient.java delete mode 100755 model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/entities/CachedOAuthClient.java delete mode 100755 model/jpa/src/main/java/org/keycloak/models/jpa/ApplicationAdapter.java delete mode 100755 model/jpa/src/main/java/org/keycloak/models/jpa/OAuthClientAdapter.java delete mode 100755 model/jpa/src/main/java/org/keycloak/models/jpa/entities/ApplicationEntity.java delete mode 100755 model/jpa/src/main/java/org/keycloak/models/jpa/entities/OAuthClientEntity.java delete mode 100755 model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/ApplicationAdapter.java delete mode 100755 model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/OAuthClientAdapter.java delete mode 100755 model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/entities/MongoOAuthClientEntity.java delete mode 100755 services/src/main/java/org/keycloak/services/managers/OAuthClientManager.java delete mode 100755 services/src/main/java/org/keycloak/services/resources/admin/OAuthClientResource.java delete mode 100755 services/src/main/java/org/keycloak/services/resources/admin/OAuthClientsByIdResource.java delete mode 100755 services/src/main/java/org/keycloak/services/resources/admin/OAuthClientsResource.java delete mode 100755 testsuite/integration/src/test/java/org/keycloak/testsuite/admin/OAuthClientTest.java rename testsuite/integration/src/test/java/org/keycloak/testsuite/model/{ApplicationModelTest.java => ClientModelTest.java} (77%) diff --git a/connections/jpa-liquibase/src/main/java/org/keycloak/connections/jpa/updater/liquibase/custom/SetConsentRequiredOnOAuthClients.java b/connections/jpa-liquibase/src/main/java/org/keycloak/connections/jpa/updater/liquibase/custom/SetConsentRequiredOnOAuthClients.java new file mode 100644 index 0000000000..6ff8b12e52 --- /dev/null +++ b/connections/jpa-liquibase/src/main/java/org/keycloak/connections/jpa/updater/liquibase/custom/SetConsentRequiredOnOAuthClients.java @@ -0,0 +1,84 @@ +package org.keycloak.connections.jpa.updater.liquibase.custom; + +import liquibase.change.custom.CustomSqlChange; +import liquibase.database.Database; +import liquibase.database.jvm.JdbcConnection; +import liquibase.exception.CustomChangeException; +import liquibase.exception.SetupException; +import liquibase.exception.ValidationErrors; +import liquibase.resource.ResourceAccessor; +import liquibase.snapshot.SnapshotGeneratorFactory; +import liquibase.statement.SqlStatement; +import liquibase.statement.core.UpdateStatement; +import liquibase.structure.core.Table; +import org.keycloak.models.utils.KeycloakModelUtils; + +import java.sql.Connection; +import java.sql.ResultSet; +import java.util.ArrayList; + +/** + * @author Stian Thorgersen + */ +public class SetConsentRequiredOnOAuthClients implements CustomSqlChange { + + private String confirmationMessage; + + @Override + public SqlStatement[] generateStatements(Database database) throws CustomChangeException { + try { + StringBuilder sb = new StringBuilder(); + sb.append("Set consent required for: "); + + Connection connection = ((JdbcConnection) (database.getConnection())).getWrappedConnection(); + ArrayList statements = new ArrayList(); + + String correctedTableName = database.correctObjectName("CLIENT", Table.class); + if (SnapshotGeneratorFactory.getInstance().has(new Table().setName(correctedTableName), database)) { + ResultSet resultSet = connection.createStatement().executeQuery("SELECT * FROM CLIENT"); + while (resultSet.next()) { + String id = resultSet.getString(1); + + UpdateStatement statement = new UpdateStatement(null, null, correctedTableName) + .addNewColumnValue("CONSENT_REQUIRED", true) + .setWhereClause("ID='" + id + "'"); + statements.add(statement); + + if (!resultSet.isFirst()) { + sb.append(", "); + } + sb.append(id); + } + + if (!statements.isEmpty()) { + confirmationMessage = sb.toString(); + } + } + + return statements.toArray(new SqlStatement[statements.size()]); + } catch (Exception e) { + throw new CustomChangeException("Failed to add realm code secret", e); + } + } + + @Override + public String getConfirmationMessage() { + return confirmationMessage; + } + + @Override + public void setUp() throws SetupException { + + } + + @Override + public void setFileOpener(ResourceAccessor resourceAccessor) { + + } + + @Override + public ValidationErrors validate(Database database) { + return null; + } + +} diff --git a/connections/jpa-liquibase/src/main/resources/META-INF/jpa-changelog-1.2.0.RC1.xml b/connections/jpa-liquibase/src/main/resources/META-INF/jpa-changelog-1.2.0.RC1.xml index 7c506009c5..b7349f2231 100755 --- a/connections/jpa-liquibase/src/main/resources/META-INF/jpa-changelog-1.2.0.RC1.xml +++ b/connections/jpa-liquibase/src/main/resources/META-INF/jpa-changelog-1.2.0.RC1.xml @@ -36,5 +36,12 @@ + + + + + + + diff --git a/connections/jpa/src/main/resources/META-INF/persistence.xml b/connections/jpa/src/main/resources/META-INF/persistence.xml index aca54ef9c2..2a066d028d 100755 --- a/connections/jpa/src/main/resources/META-INF/persistence.xml +++ b/connections/jpa/src/main/resources/META-INF/persistence.xml @@ -3,9 +3,8 @@ xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" version="1.0"> - org.keycloak.models.jpa.entities.ApplicationEntity + org.keycloak.models.jpa.entities.ClientEntity org.keycloak.models.jpa.entities.CredentialEntity - org.keycloak.models.jpa.entities.OAuthClientEntity org.keycloak.models.jpa.entities.RealmEntity org.keycloak.models.jpa.entities.RealmAttributeEntity org.keycloak.models.jpa.entities.RequiredCredentialEntity diff --git a/connections/mongo/src/main/java/org/keycloak/connections/mongo/DefaultMongoConnectionFactoryProvider.java b/connections/mongo/src/main/java/org/keycloak/connections/mongo/DefaultMongoConnectionFactoryProvider.java index f5ed855c34..138955bc6c 100755 --- a/connections/mongo/src/main/java/org/keycloak/connections/mongo/DefaultMongoConnectionFactoryProvider.java +++ b/connections/mongo/src/main/java/org/keycloak/connections/mongo/DefaultMongoConnectionFactoryProvider.java @@ -33,8 +33,7 @@ public class DefaultMongoConnectionFactoryProvider implements MongoConnectionPro "org.keycloak.models.entities.RequiredCredentialEntity", "org.keycloak.models.entities.CredentialEntity", "org.keycloak.models.entities.FederatedIdentityEntity", - "org.keycloak.models.mongo.keycloak.entities.MongoApplicationEntity", - "org.keycloak.models.mongo.keycloak.entities.MongoOAuthClientEntity", + "org.keycloak.models.mongo.keycloak.entities.MongoClientEntity", "org.keycloak.models.sessions.mongo.entities.MongoUsernameLoginFailureEntity", "org.keycloak.models.sessions.mongo.entities.MongoUserSessionEntity", "org.keycloak.models.sessions.mongo.entities.MongoClientSessionEntity", diff --git a/core/src/main/java/org/keycloak/representations/idm/ApplicationRepresentation.java b/core/src/main/java/org/keycloak/representations/idm/ApplicationRepresentation.java index e407049dfa..8f38e4b37c 100755 --- a/core/src/main/java/org/keycloak/representations/idm/ApplicationRepresentation.java +++ b/core/src/main/java/org/keycloak/representations/idm/ApplicationRepresentation.java @@ -22,6 +22,8 @@ public class ApplicationRepresentation { protected ClaimRepresentation claims; protected Integer notBefore; protected Boolean bearerOnly; + protected Boolean consentRequired; + protected Boolean directGrantsOnly; protected Boolean publicClient; protected Boolean frontchannelLogout; protected String protocol; @@ -136,6 +138,22 @@ public class ApplicationRepresentation { this.bearerOnly = bearerOnly; } + public Boolean isConsentRequired() { + return consentRequired; + } + + public void setConsentRequired(Boolean consentRequired) { + this.consentRequired = consentRequired; + } + + public Boolean getDirectGrantsOnly() { + return directGrantsOnly; + } + + public void setDirectGrantsOnly(Boolean directGrantsOnly) { + this.directGrantsOnly = directGrantsOnly; + } + public Boolean isPublicClient() { return publicClient; } diff --git a/export-import/export-import-api/src/main/java/org/keycloak/exportimport/util/ExportUtils.java b/export-import/export-import-api/src/main/java/org/keycloak/exportimport/util/ExportUtils.java index 9e683670c5..787f8ca20e 100755 --- a/export-import/export-import-api/src/main/java/org/keycloak/exportimport/util/ExportUtils.java +++ b/export-import/export-import-api/src/main/java/org/keycloak/exportimport/util/ExportUtils.java @@ -6,10 +6,8 @@ import org.codehaus.jackson.JsonFactory; import org.codehaus.jackson.JsonGenerator; import org.codehaus.jackson.map.ObjectMapper; import org.codehaus.jackson.map.SerializationConfig; -import org.keycloak.models.ApplicationModel; import org.keycloak.models.ClientModel; import org.keycloak.models.KeycloakSession; -import org.keycloak.models.OAuthClientModel; import org.keycloak.models.RealmModel; import org.keycloak.models.RoleContainerModel; import org.keycloak.models.RoleModel; @@ -18,9 +16,7 @@ import org.keycloak.models.UserCredentialValueModel; import org.keycloak.models.UserModel; import org.keycloak.models.utils.ModelToRepresentation; import org.keycloak.representations.idm.ApplicationRepresentation; -import org.keycloak.representations.idm.ClaimRepresentation; import org.keycloak.representations.idm.CredentialRepresentation; -import org.keycloak.representations.idm.OAuthClientRepresentation; import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.representations.idm.RoleRepresentation; import org.keycloak.representations.idm.RolesRepresentation; @@ -58,24 +54,14 @@ public class ExportUtils { } // Applications - List applications = realm.getApplications(); + List applications = realm.getClients(); List appReps = new ArrayList(); - for (ApplicationModel app : applications) { + for (ClientModel app : applications) { ApplicationRepresentation appRep = exportApplication(app); appReps.add(appRep); } rep.setApplications(appReps); - // OAuth clients - List oauthClients = realm.getOAuthClients(); - List oauthClientReps = new ArrayList(); - for (OAuthClientModel oauthClient : oauthClients) { - OAuthClientRepresentation clientRep = ModelToRepresentation.toRepresentation(oauthClient); - clientRep.setSecret(oauthClient.getSecret()); - oauthClientReps.add(clientRep); - } - rep.setOauthClients(oauthClientReps); - // Roles List realmRoleReps = null; Map> appRolesReps = new HashMap>(); @@ -84,10 +70,10 @@ public class ExportUtils { if (realmRoles != null && realmRoles.size() > 0) { realmRoleReps = exportRoles(realmRoles); } - for (ApplicationModel app : applications) { + for (ClientModel app : applications) { Set currentAppRoles = app.getRoles(); List currentAppRoleReps = exportRoles(currentAppRoles); - appRolesReps.put(app.getName(), currentAppRoleReps); + appRolesReps.put(app.getClientId(), currentAppRoleReps); } RolesRepresentation rolesRep = new RolesRepresentation(); @@ -100,9 +86,8 @@ public class ExportUtils { rep.setRoles(rolesRep); // Scopes - List allClients = new ArrayList(applications); - allClients.addAll(realm.getOAuthClients()); - Map> appScopeReps = new HashMap>(); + List allClients = new ArrayList<>(applications); + Map> appScopeReps = new HashMap<>(); for (ClientModel client : allClients) { Set clientScopes = client.getScopeMappings(); @@ -114,11 +99,11 @@ public class ExportUtils { } scopeMappingRep.role(scope.getName()); } else { - ApplicationModel app = (ApplicationModel)scope.getContainer(); - String appName = app.getName(); + ClientModel app = (ClientModel)scope.getContainer(); + String appName = app.getClientId(); List currentAppScopes = appScopeReps.get(appName); if (currentAppScopes == null) { - currentAppScopes = new ArrayList(); + currentAppScopes = new ArrayList<>(); appScopeReps.put(appName, currentAppScopes); } @@ -165,7 +150,7 @@ public class ExportUtils { * @param app * @return full ApplicationRepresentation */ - public static ApplicationRepresentation exportApplication(ApplicationModel app) { + public static ApplicationRepresentation exportApplication(ClientModel app) { ApplicationRepresentation appRep = ModelToRepresentation.toRepresentation(app); appRep.setSecret(app.getSecret()); @@ -216,8 +201,8 @@ public class ExportUtils { compositeAppRoles = new HashMap>(); } - ApplicationModel app = (ApplicationModel)crContainer; - String appName = app.getName(); + ClientModel app = (ClientModel)crContainer; + String appName = app.getClientId(); List currentAppComposites = compositeAppRoles.get(appName); if (currentAppComposites == null) { currentAppComposites = new ArrayList(); @@ -269,8 +254,8 @@ public class ExportUtils { if (role.getContainer() instanceof RealmModel) { realmRoleNames.add(role.getName()); } else { - ApplicationModel app = (ApplicationModel)role.getContainer(); - String appName = app.getName(); + ClientModel app = (ClientModel)role.getContainer(); + String appName = app.getClientId(); List currentAppRoles = appRoleNames.get(appName); if (currentAppRoles == null) { currentAppRoles = new ArrayList(); diff --git a/export-import/export-import-api/src/main/java/org/keycloak/exportimport/util/ImportUtils.java b/export-import/export-import-api/src/main/java/org/keycloak/exportimport/util/ImportUtils.java index 5c0a60c890..3bf9d4645c 100755 --- a/export-import/export-import-api/src/main/java/org/keycloak/exportimport/util/ImportUtils.java +++ b/export-import/export-import-api/src/main/java/org/keycloak/exportimport/util/ImportUtils.java @@ -8,7 +8,7 @@ import org.jboss.logging.Logger; import org.keycloak.Config; import org.keycloak.exportimport.Strategy; import org.keycloak.models.AdminRoles; -import org.keycloak.models.ApplicationModel; +import org.keycloak.models.ClientModel; import org.keycloak.models.KeycloakSession; import org.keycloak.models.RealmModel; import org.keycloak.models.RealmProvider; @@ -81,7 +81,7 @@ public class ImportUtils { // We just imported master realm. All 'masterAdminApps' need to be refreshed RealmModel adminRealm = realm; for (RealmModel currentRealm : model.getRealms()) { - ApplicationModel masterApp = adminRealm.getApplicationByName(KeycloakModelUtils.getMasterRealmAdminApplicationName(currentRealm)); + ClientModel masterApp = adminRealm.getClientByClientId(KeycloakModelUtils.getMasterRealmAdminApplicationName(currentRealm)); if (masterApp != null) { currentRealm.setMasterAdminApp(masterApp); } else { @@ -91,7 +91,7 @@ public class ImportUtils { } else { // Need to refresh masterApp for current realm RealmModel adminRealm = model.getRealm(adminRealmId); - ApplicationModel masterApp = adminRealm.getApplicationByName(KeycloakModelUtils.getMasterRealmAdminApplicationName(realm)); + ClientModel masterApp = adminRealm.getClientByClientId(KeycloakModelUtils.getMasterRealmAdminApplicationName(realm)); if (masterApp != null) { realm.setMasterAdminApp(masterApp); } else { @@ -119,7 +119,7 @@ public class ImportUtils { } adminRole.setDescription("${role_"+AdminRoles.ADMIN+"}"); - ApplicationModel realmAdminApp = KeycloakModelUtils.createApplication(adminRealm, KeycloakModelUtils.getMasterRealmAdminApplicationName(realm)); + ClientModel realmAdminApp = KeycloakModelUtils.createApplication(adminRealm, KeycloakModelUtils.getMasterRealmAdminApplicationName(realm)); realmAdminApp.setBearerOnly(true); realm.setMasterAdminApp(realmAdminApp); @@ -220,7 +220,7 @@ public class ImportUtils { private static void importUsers(KeycloakSession session, RealmProvider model, String realmName, List userReps) { RealmModel realm = model.getRealmByName(realmName); - Map apps = realm.getApplicationNameMap(); + Map apps = realm.getClientNameMap(); for (UserRepresentation user : userReps) { RepresentationToModel.createUser(session, realm, user, apps); } diff --git a/forms/account-freemarker/src/main/java/org/keycloak/account/freemarker/model/SessionsBean.java b/forms/account-freemarker/src/main/java/org/keycloak/account/freemarker/model/SessionsBean.java index 03ba5b3a0e..646b44b4fd 100755 --- a/forms/account-freemarker/src/main/java/org/keycloak/account/freemarker/model/SessionsBean.java +++ b/forms/account-freemarker/src/main/java/org/keycloak/account/freemarker/model/SessionsBean.java @@ -1,14 +1,11 @@ package org.keycloak.account.freemarker.model; -import org.keycloak.models.ApplicationModel; import org.keycloak.models.ClientModel; import org.keycloak.models.ClientSessionModel; -import org.keycloak.models.OAuthClientModel; import org.keycloak.models.RealmModel; import org.keycloak.models.UserSessionModel; import org.keycloak.util.Time; -import java.util.ArrayList; import java.util.Date; import java.util.HashSet; import java.util.LinkedList; @@ -63,23 +60,14 @@ public class SessionsBean { return Time.toDate(max); } - public Set getApplications() { - Set apps = new HashSet(); + public Set getClients() { + Set clients = new HashSet(); for (ClientSessionModel clientSession : session.getClientSessions()) { ClientModel client = clientSession.getClient(); - if (client instanceof ApplicationModel) apps.add(client.getClientId()); + clients.add(client.getClientId()); } - return apps; + return clients; } - public List getClients() { - List apps = new ArrayList(); - for (ClientSessionModel clientSession : session.getClientSessions()) { - ClientModel client = clientSession.getClient(); - if (client instanceof OAuthClientModel) apps.add(client.getClientId()); - } - return apps; - } - } } diff --git a/forms/common-themes/src/main/resources/theme/base/account/sessions.ftl b/forms/common-themes/src/main/resources/theme/base/account/sessions.ftl index c781c79381..1c0ef1b0e5 100755 --- a/forms/common-themes/src/main/resources/theme/base/account/sessions.ftl +++ b/forms/common-themes/src/main/resources/theme/base/account/sessions.ftl @@ -14,7 +14,6 @@ ${msg("started")} ${msg("lastAccess")} ${msg("expires")} - ${msg("applications")} ${msg("clients")} @@ -26,11 +25,6 @@ ${session.started?datetime} ${session.lastAccess?datetime} ${session.expires?datetime} - - <#list session.applications as app> - ${app}
- - <#list session.clients as client> ${client}
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/js/app.js b/forms/common-themes/src/main/resources/theme/base/admin/resources/js/app.js index e38c29cf75..f7ea60dddf 100755 --- a/forms/common-themes/src/main/resources/theme/base/admin/resources/js/app.js +++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/js/app.js @@ -512,72 +512,6 @@ module.config([ '$routeProvider', function($routeProvider) { }, controller : 'ApplicationProtocolMapperCreateCtrl' }) - - .when('/realms/:realm/oauth-clients/:oauth/mappers', { - templateUrl : resourceUrl + '/partials/oauth-client-mappers.html', - resolve : { - realm : function(RealmLoader) { - return RealmLoader(); - }, - oauth : function(OAuthClientLoader) { - return OAuthClientLoader(); - }, - serverInfo : function(ServerInfoLoader) { - return ServerInfoLoader(); - } - }, - controller : 'OAuthClientProtocolMapperListCtrl' - }) - .when('/realms/:realm/oauth-clients/:oauth/add-mappers', { - templateUrl : resourceUrl + '/partials/oauth-client-mappers-add.html', - resolve : { - realm : function(RealmLoader) { - return RealmLoader(); - }, - oauth : function(OAuthClientLoader) { - return OAuthClientLoader(); - }, - serverInfo : function(ServerInfoLoader) { - return ServerInfoLoader(); - } - }, - controller : 'OAuthClientAddBuiltinProtocolMapperCtrl' - }) - .when('/realms/:realm/oauth-clients/:oauth/mappers/:id', { - templateUrl : resourceUrl + '/partials/oauth-client-protocol-mapper-detail.html', - resolve : { - realm : function(RealmLoader) { - return RealmLoader(); - }, - oauth : function(OAuthClientLoader) { - return OAuthClientLoader(); - }, - serverInfo : function(ServerInfoLoader) { - return ServerInfoLoader(); - }, - mapper : function(OAuthClientProtocolMapperLoader) { - return OAuthClientProtocolMapperLoader(); - } - - }, - controller : 'OAuthClientProtocolMapperCtrl' - }) - .when('/create/oauth-client/:realm/:oauth/mappers', { - templateUrl : resourceUrl + '/partials/oauth-client-protocol-mapper-detail.html', - resolve : { - realm : function(RealmLoader) { - return RealmLoader(); - }, - serverInfo : function(ServerInfoLoader) { - return ServerInfoLoader(); - }, - oauth : function(OAuthClientLoader) { - return OAuthClientLoader(); - } - }, - controller : 'OAuthClientProtocolMapperCreateCtrl' - }) - .when('/realms/:realm/applications/:application/sessions', { templateUrl : resourceUrl + '/partials/application-sessions.html', resolve : { @@ -807,127 +741,6 @@ module.config([ '$routeProvider', function($routeProvider) { }, controller : 'ApplicationImportCtrl' }) - - // OAUTH Client - - .when('/realms/:realm/oauth-clients/:oauth/claims', { - templateUrl : resourceUrl + '/partials/oauth-client-claims.html', - resolve : { - realm : function(RealmLoader) { - return RealmLoader(); - }, - oauth : function(OAuthClientLoader) { - return OAuthClientLoader(); - }, - claims : function(OAuthClientClaimsLoader) { - return OAuthClientClaimsLoader(); - } - }, - controller : 'OAuthClientClaimsCtrl' - }) - .when('/realms/:realm/oauth-clients/:oauth/revocation', { - templateUrl : resourceUrl + '/partials/oauth-client-revocation.html', - resolve : { - realm : function(RealmLoader) { - return RealmLoader(); - }, - oauth : function(OAuthClientLoader) { - return OAuthClientLoader(); - } - }, - controller : 'OAuthClientRevocationCtrl' - }) - .when('/realms/:realm/oauth-clients/:oauth/credentials', { - templateUrl : resourceUrl + '/partials/oauth-client-credentials.html', - resolve : { - realm : function(RealmLoader) { - return RealmLoader(); - }, - oauth : function(OAuthClientLoader) { - return OAuthClientLoader(); - } - }, - controller : 'OAuthClientCredentialsCtrl' - }) - .when('/realms/:realm/oauth-clients/:oauth/scope-mappings', { - templateUrl : resourceUrl + '/partials/oauth-client-scope-mappings.html', - resolve : { - realm : function(RealmLoader) { - return RealmLoader(); - }, - oauth : function(OAuthClientLoader) { - return OAuthClientLoader(); - }, - applications : function(ApplicationListLoader) { - return ApplicationListLoader(); - } - }, - controller : 'OAuthClientScopeMappingCtrl' - }) - .when('/realms/:realm/oauth-clients/:oauth/installation', { - templateUrl : resourceUrl + '/partials/oauth-client-installation.html', - resolve : { - realm : function(RealmLoader) { - return RealmLoader(); - }, - oauth : function(OAuthClientLoader) { - return OAuthClientLoader(); - }, - installation : function(OAuthClientInstallationLoader) { - return OAuthClientInstallationLoader(); - } - }, - controller : 'OAuthClientInstallationCtrl' - }) - .when('/create/oauth-client/:realm', { - templateUrl : resourceUrl + '/partials/oauth-client-detail.html', - resolve : { - realm : function(RealmLoader) { - return RealmLoader(); - }, - oauth : function() { - return {}; - } - }, - controller : 'OAuthClientDetailCtrl' - }) - .when('/realms/:realm/oauth-clients/:oauth', { - templateUrl : resourceUrl + '/partials/oauth-client-detail.html', - resolve : { - realm : function(RealmLoader) { - return RealmLoader(); - }, - oauth : function(OAuthClientLoader) { - return OAuthClientLoader(); - } - }, - controller : 'OAuthClientDetailCtrl' - }) - .when('/realms/:realm/oauth-clients/:oauth/identity-provider', { - templateUrl : resourceUrl + '/partials/oauth-client-identity-provider.html', - resolve : { - realm : function(RealmLoader) { - return RealmLoader(); - }, - oauth : function(OAuthClientLoader) { - return OAuthClientLoader(); - } - }, - controller : 'OAuthClientIdentityProviderCtrl' - }) - .when('/realms/:realm/oauth-clients', { - templateUrl : resourceUrl + '/partials/oauth-client-list.html', - resolve : { - realm : function(RealmLoader) { - return RealmLoader(); - }, - oauthClients : function(OAuthClientListLoader) { - return OAuthClientListLoader(); - } - }, - controller : 'OAuthClientListCtrl' - }) - .when('/', { templateUrl : resourceUrl + '/partials/home.html', controller : 'HomeCtrl' @@ -1549,15 +1362,6 @@ module.directive('kcNavigationApplication', function () { } }); -module.directive('kcNavigationOauthClient', function () { - return { - scope: true, - restrict: 'E', - replace: true, - templateUrl: resourceUrl + '/templates/kc-navigation-oauth-client.html' - } -}); - /* * Used to select the element (invoke $(elem).select()) on specified action list. * Usages kc-select-action="click mouseover" diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/js/controllers/oauth-clients.js b/forms/common-themes/src/main/resources/theme/base/admin/resources/js/controllers/oauth-clients.js deleted file mode 100755 index a55b9e3754..0000000000 --- a/forms/common-themes/src/main/resources/theme/base/admin/resources/js/controllers/oauth-clients.js +++ /dev/null @@ -1,611 +0,0 @@ -module.controller('OAuthClientClaimsCtrl', function($scope, realm, oauth, claims, - OAuthClientClaims, - $location, Dialog, Notifications) { - $scope.realm = realm; - $scope.oauth = oauth; - $scope.claims = angular.copy(claims); - - $scope.changed = false; - - $scope.$watch('claims', function () { - if (!angular.equals($scope.claims, claims)) { - $scope.changed = true; - } - }, true); - - - $scope.save = function () { - OAuthClientClaims.update({ - realm: realm.realm, - oauth: oauth.id - }, $scope.claims, function () { - $scope.changed = false; - claims = angular.copy($scope.claims); - - Notifications.success("Your claim changes have been saved."); - }); - }; - - $scope.reset = function () { - $location.url("/realms/" + realm.realm + "/oauth-clients/" + oauth.id + "/claims"); - }; - -}); - -module.controller('OAuthClientCredentialsCtrl', function($scope, $location, realm, oauth, OAuthClientCredentials, Notifications) { - $scope.realm = realm; - $scope.oauth = oauth; - - var secret = OAuthClientCredentials.get({ realm : realm.realm, oauth : oauth.id }, - function() { - $scope.secret = secret.value; - } - ); - - $scope.changePassword = function() { - var secret = OAuthClientCredentials.update({ realm : realm.realm, oauth : oauth.id }, - function() { - Notifications.success('The secret has been changed.'); - $scope.secret = secret.value; - }, - function() { - Notifications.error("The secret was not changed due to a problem."); - $scope.secret = "error"; - } - ); - }; - - $scope.$watch(function() { - return $location.path(); - }, function() { - $scope.path = $location.path().substring(1).split("/"); - }); - -}); - -module.controller('OAuthClientListCtrl', function($scope, realm, oauthClients, OAuthClient, $location) { - $scope.realm = realm; - $scope.oauthClients = oauthClients; - $scope.$watch(function() { - return $location.path(); - }, function() { - $scope.path = $location.path().substring(1).split("/"); - }); -}); - -module.controller('OAuthClientDetailCtrl', function($scope, realm, oauth, OAuthClient, $location, Dialog, Notifications) { - $scope.realm = realm; - $scope.create = !oauth.id; - - $scope.accessTypes = [ - "confidential", - "public" - ]; - - $scope.changeAccessType = function() { - if ($scope.accessType == "confidential") { - $scope.oauth.publicClient = false; - } else if ($scope.accessType == "public") { - $scope.oauth.publicClient = true; - } - }; - - - if (!$scope.create) { - $scope.oauth= angular.copy(oauth); - $scope.accessType = $scope.accessTypes[0]; - if (oauth.publicClient) { - $scope.accessType = $scope.accessTypes[1]; - } - } else { - $scope.oauth = { enabled: true }; - $scope.oauth.webOrigins = []; - $scope.oauth.redirectUris = []; - $scope.accessType = $scope.accessTypes[0]; - } - - $scope.$watch(function() { - return $location.path(); - }, function() { - $scope.path = $location.path().substring(1).split("/"); - }); - - $scope.$watch('oauth', function() { - if (!angular.equals($scope.oauth, oauth)) { - $scope.changed = true; - } - }, true); - - $scope.deleteWebOrigin = function(index) { - $scope.oauth.webOrigins.splice(index, 1); - } - $scope.addWebOrigin = function() { - $scope.oauth.webOrigins.push($scope.newWebOrigin); - $scope.newWebOrigin = ""; - } - $scope.deleteRedirectUri = function(index) { - $scope.oauth.redirectUris.splice(index, 1); - } - $scope.addRedirectUri = function() { - $scope.oauth.redirectUris.push($scope.newRedirectUri); - $scope.newRedirectUri = ""; - } - - $scope.save = function() { - if (!$scope.oauth.directGrantsOnly && (!$scope.oauth.redirectUris || $scope.oauth.redirectUris.length == 0)) { - Notifications.error("You must specify at least one redirect uri"); - } else { - if ($scope.create) { - OAuthClient.save({ - realm: realm.realm - }, $scope.oauth, function (data, headers) { - $scope.changed = false; - var l = headers().location; - var name = l.substring(l.lastIndexOf("/") + 1); - $location.url("/realms/" + realm.realm + "/oauth-clients/" + name); - Notifications.success("The oauth client has been created."); - }); - } else { - OAuthClient.update({ - realm : realm.realm, - oauth : oauth.id - }, $scope.oauth, function() { - $scope.changed = false; - oauth = angular.copy($scope.oauth); - $location.url("/realms/" + realm.realm + "/oauth-clients/" + oauth.id); - Notifications.success("Your changes have been saved to the oauth client."); - }); - } - } - }; - - $scope.reset = function() { - $scope.oauth = angular.copy(oauth); - $scope.changed = false; - }; - - $scope.cancel = function() { - $location.url("/realms/" + realm.realm + "/oauth-clients"); - }; - - $scope.remove = function() { - Dialog.confirmDelete($scope.oauth.id, 'oauth', function() { - $scope.oauth.$remove({ - realm : realm.realm, - oauth : $scope.oauth.id - }, function() { - $location.url("/realms/" + realm.realm + "/oauth-clients"); - Notifications.success("The oauth client has been deleted."); - }); - }); - }; - - -}); - -module.controller('OAuthClientScopeMappingCtrl', function($scope, $http, realm, oauth, applications, Notifications, - OAuthClient, - OAuthClientRealmScopeMapping, OAuthClientApplicationScopeMapping, ApplicationRole, - OAuthClientAvailableRealmScopeMapping, OAuthClientAvailableApplicationScopeMapping, - OAuthClientCompositeRealmScopeMapping, OAuthClientCompositeApplicationScopeMapping) { - $scope.realm = realm; - $scope.oauth = angular.copy(oauth); - $scope.selectedRealmRoles = []; - $scope.selectedRealmMappings = []; - $scope.realmMappings = []; - $scope.applications = applications; - $scope.applicationRoles = []; - $scope.applicationComposite = []; - $scope.selectedApplicationRoles = []; - $scope.selectedApplicationMappings = []; - $scope.applicationMappings = []; - $scope.dummymodel = []; - - $scope.changeFullScopeAllowed = function() { - console.log('change full scope'); - OAuthClient.update({ - realm : realm.realm, - oauth : oauth.id - }, $scope.oauth, function() { - $scope.changed = false; - oauth = angular.copy($scope.oauth); - Notifications.success("Scope mappings updated."); - }); - - } - - - function updateRealmRoles() { - $scope.realmRoles = OAuthClientAvailableRealmScopeMapping.query({realm : realm.realm, oauth : oauth.id}); - $scope.realmMappings = OAuthClientRealmScopeMapping.query({realm : realm.realm, oauth : oauth.id}); - $scope.realmComposite = OAuthClientCompositeRealmScopeMapping.query({realm : realm.realm, oauth : oauth.id}); - } - - function updateAppRoles() { - if ($scope.targetApp) { - console.debug($scope.targetApp.name); - $scope.applicationRoles = OAuthClientAvailableApplicationScopeMapping.query({realm : realm.realm, oauth : oauth.id, targetApp : $scope.targetApp.id}); - $scope.applicationMappings = OAuthClientApplicationScopeMapping.query({realm : realm.realm, oauth : oauth.id, targetApp : $scope.targetApp.id}); - $scope.applicationComposite = OAuthClientCompositeApplicationScopeMapping.query({realm : realm.realm, oauth : oauth.id, targetApp : $scope.targetApp.id}); - } else { - $scope.applicationRoles = null; - $scope.applicationMappings = null; - $scope.applicationComposite = null; - } - } - - $scope.changeApplication = function() { - updateAppRoles(); - }; - - $scope.addRealmRole = function() { - $http.post(authUrl + '/admin/realms/' + realm.realm + '/oauth-clients-by-id/' + oauth.id + '/scope-mappings/realm', - $scope.selectedRealmRoles).success(function () { - updateRealmRoles(); - Notifications.success("Scope mappings updated."); - }); - }; - - $scope.deleteRealmRole = function() { - $http.delete(authUrl + '/admin/realms/' + realm.realm + '/oauth-clients-by-id/' + oauth.id + '/scope-mappings/realm', - {data : $scope.selectedRealmMappings, headers : {"content-type" : "application/json"}}).success(function () { - updateRealmRoles(); - Notifications.success("Scope mappings updated."); - - }); - }; - - $scope.addApplicationRole = function() { - $http.post(authUrl + '/admin/realms/' + realm.realm + '/oauth-clients-by-id/' + oauth.id + '/scope-mappings/applications-by-id/' + $scope.targetApp.id, - $scope.selectedApplicationRoles).success(function () { - updateAppRoles(); - Notifications.success("Scope mappings updated."); - - }); - }; - - $scope.deleteApplicationRole = function() { - $http.delete(authUrl + '/admin/realms/' + realm.realm + '/oauth-clients-by-id/' + oauth.id + '/scope-mappings/applications-by-id/' + $scope.targetApp.id, - {data : $scope.selectedApplicationMappings, headers : {"content-type" : "application/json"}}).success(function () { - updateAppRoles(); - Notifications.success("Scope mappings updated."); - - }); - }; - - updateRealmRoles(); -}); - -module.controller('OAuthClientInstallationCtrl', function($scope, realm, installation, oauth, OAuthClientInstallation, $routeParams) { - $scope.realm = realm; - $scope.oauth = oauth; - $scope.installation = installation; - - $scope.download = function() { - saveAs(new Blob([angular.toJson($scope.installation, true)], { type: 'application/json' }), 'keycloak.json'); - } -}); - -module.controller('OAuthClientRevocationCtrl', function($scope, realm, oauth, OAuthClient, $location, Dialog, Notifications) { - $scope.oauth = oauth; - $scope.realm = realm; - var setNotBefore = function() { - if ($scope.oauth.notBefore == 0) { - $scope.notBefore = "None"; - } else { - $scope.notBefore = new Date($scope.oauth.notBefore * 1000); - } - }; - - setNotBefore(); - - var refresh = function() { - OAuthClient.get({ realm : realm.realm, oauth: $scope.oauth.id }, function(updated) { - $scope.oauth = updated; - setNotBefore(); - }) - - }; - - $scope.clear = function() { - $scope.oauth.notBefore = 0; - OAuthClient.update({ realm : realm.realm, oauth: $scope.oauth.id}, $scope.oauth, function () { - $scope.notBefore = "None"; - Notifications.success('Not Before cleared for application.'); - refresh(); - }); - } - $scope.setNotBeforeNow = function() { - $scope.oauth.notBefore = new Date().getTime()/1000; - OAuthClient.update({ realm : realm.realm, oauth: $scope.oauth.id}, $scope.oauth, function () { - Notifications.success('Not Before cleared for application.'); - refresh(); - }); - } -}); - -module.controller('OAuthClientIdentityProviderCtrl', function($scope, $route, realm, oauth, OAuthClient, $location, Notifications) { - $scope.realm = realm; - $scope.oauth = angular.copy(oauth); - var length = 0; - - if ($scope.oauth.identityProviders) { - length = $scope.oauth.identityProviders.length; - } else { - $scope.oauth.identityProviders = new Array(realm.identityProviders.length); - } - - for (j = length; j < realm.identityProviders.length; j++) { - $scope.oauth.identityProviders[j] = {}; - } - - $scope.identityProviders = []; - - for (j = 0; j < realm.identityProviders.length; j++) { - var identityProvider = realm.identityProviders[j]; - var match = false; - var applicationProvider; - - for (i = 0; i < $scope.oauth.identityProviders.length; i++) { - applicationProvider = $scope.oauth.identityProviders[i]; - - if (applicationProvider) { - if (applicationProvider.retrieveToken) { - applicationProvider.retrieveToken = applicationProvider.retrieveToken.toString(); - } else { - applicationProvider.retrieveToken = false.toString(); - } - - if (applicationProvider.id == identityProvider.id) { - $scope.identityProviders[i] = {}; - $scope.identityProviders[i].identityProvider = identityProvider; - $scope.identityProviders[i].retrieveToken = applicationProvider.retrieveToken.toString(); - break; - } - - applicationProvider = null; - } - } - - if (applicationProvider == null) { - var length = $scope.identityProviders.length + $scope.oauth.identityProviders.length; - - $scope.identityProviders[length] = {}; - $scope.identityProviders[length].identityProvider = identityProvider; - $scope.identityProviders[length].retrieveToken = false.toString(); - } - } - - $scope.identityProviders = $scope.identityProviders.filter(function(n){ return n != undefined }); - - var oldCopy = angular.copy($scope.oauth); - - $scope.save = function() { - var selectedProviders = []; - - for (i = 0; i < $scope.oauth.identityProviders.length; i++) { - var appProvider = $scope.oauth.identityProviders[i]; - - if (appProvider.id != null && appProvider.id != false) { - selectedProviders[selectedProviders.length] = appProvider; - } - } - - $scope.oauth.identityProviders = selectedProviders; - - OAuthClient.update({ - realm : realm.realm, - oauth : oauth.id - }, $scope.oauth, function() { - $scope.changed = false; - $route.reload(); - Notifications.success("Your changes have been saved to the application."); - }); - }; - - $scope.reset = function() { - $scope.oauth = angular.copy(oldCopy); - $scope.changed = false; - }; - - $scope.$watch('oauth', function() { - if (!angular.equals($scope.oauth, oldCopy)) { - $scope.changed = true; - } - }, true); -}); - -module.controller('OAuthClientProtocolMapperListCtrl', function($scope, realm, oauth, serverInfo, - OAuthClientProtocolMappersByProtocol, - $http, $location, Dialog, Notifications) { - $scope.realm = realm; - $scope.oauth = oauth; - if (oauth.protocol == null) { - oauth.protocol = 'openid-connect'; - } - - var protocolMappers = serverInfo.protocolMapperTypes[oauth.protocol]; - var mapperTypes = {}; - for (var i = 0; i < protocolMappers.length; i++) { - mapperTypes[protocolMappers[i].id] = protocolMappers[i]; - } - $scope.mapperTypes = mapperTypes; - - - var updateMappers = function() { - $scope.mappers = OAuthClientProtocolMappersByProtocol.query({realm : realm.realm, oauth : oauth.id, protocol : oauth.protocol}); - }; - - updateMappers(); -}); - -module.controller('OAuthClientAddBuiltinProtocolMapperCtrl', function($scope, realm, oauth, serverInfo, - OAuthClientProtocolMappersByProtocol, - $http, $location, Dialog, Notifications) { - $scope.realm = realm; - $scope.oauth = oauth; - if (oauth.protocol == null) { - oauth.protocol = 'openid-connect'; - } - - var protocolMappers = serverInfo.protocolMapperTypes[oauth.protocol]; - var mapperTypes = {}; - for (var i = 0; i < protocolMappers.length; i++) { - mapperTypes[protocolMappers[i].id] = protocolMappers[i]; - } - $scope.mapperTypes = mapperTypes; - - - - - var updateMappers = function() { - var appMappers = OAuthClientProtocolMappersByProtocol.query({realm : realm.realm, oauth : oauth.id, protocol : oauth.protocol}, function() { - var builtinMappers = serverInfo.builtinProtocolMappers[oauth.protocol]; - for (var i = 0; i < appMappers.length; i++) { - for (var j = 0; j < builtinMappers.length; j++) { - if (builtinMappers[j].name == appMappers[i].name - && builtinMappers[j].protocolMapper == appMappers[i].protocolMapper) { - console.log('removing: ' + builtinMappers[j].name); - builtinMappers.splice(j, 1); - break; - } - } - } - for (var j = 0; j < builtinMappers.length; j++) { - console.log('builtin left: ' + builtinMappers[j].name); - } - $scope.mappers = builtinMappers; - for (var i = 0; i < $scope.mappers.length; i++) { - $scope.mappers[i].isChecked = false; - } - - - }); - }; - - updateMappers(); - - $scope.add = function() { - var toAdd = []; - for (var i = 0; i < $scope.mappers.length; i++) { - if ($scope.mappers[i].isChecked) { - delete $scope.mappers[i].isChecked; - toAdd.push($scope.mappers[i]); - } - } - $http.post(authUrl + '/admin/realms/' + realm.realm + '/oauth-clients-by-id/' + oauth.id + '/protocol-mappers/add-models', - toAdd).success(function() { - Notifications.success("Mappers added"); - $location.url('/realms/' + realm.realm + '/oauth-clients/' + oauth.id + '/mappers'); - }).error(function() { - Notifications.error("Error adding mappers"); - $location.url('/realms/' + realm.realm + '/oauth-clients/' + oauth.id + '/mappers'); - }); - }; - -}); - -module.controller('OAuthClientProtocolMapperCtrl', function($scope, realm, serverInfo, oauth, mapper, OAuthClientProtocolMapper, Notifications, Dialog, $location) { - if (oauth.protocol == null) { - oauth.protocol = 'openid-connect'; - } - $scope.realm = realm; - $scope.oauth = oauth; - $scope.create = false; - var protocol = oauth.protocol; - $scope.protocol = oauth.protocol; - $scope.mapper = angular.copy(mapper); - var oldCopy = angular.copy($scope.realm); - $scope.changed = false; - - var protocolMappers = serverInfo.protocolMapperTypes[protocol]; - for (var i = 0; i < protocolMappers.length; i++) { - if (protocolMappers[i].id == mapper.protocolMapper) { - $scope.mapperType = protocolMappers[i]; - } - } - $scope.$watch(function() { - return $location.path(); - }, function() { - $scope.path = $location.path().substring(1).split("/"); - }); - - $scope.$watch('mapper', function() { - if (!angular.equals($scope.mapper, mapper)) { - $scope.changed = true; - } - }, true); - - $scope.save = function() { - OAuthClientProtocolMapper.update({ - realm : realm.realm, - oauth: oauth.id, - id : mapper.id - }, $scope.mapper, function() { - $scope.changed = false; - mapper = angular.copy($scope.mapper); - $location.url("/realms/" + realm.realm + '/oauth-clients/' + oauth.id + "/mappers/" + mapper.id); - Notifications.success("Your changes have been saved."); - }); - }; - - $scope.reset = function() { - $scope.mapper = angular.copy(mapper); - $scope.changed = false; - }; - - $scope.cancel = function() { - //$location.url("/realms"); - window.history.back(); - }; - - $scope.remove = function() { - Dialog.confirmDelete($scope.mapper.name, 'mapper', function() { - OAuthClientProtocolMapper.remove({ realm: realm.realm, oauth: oauth.id, id : $scope.mapper.id }, function() { - Notifications.success("The mapper has been deleted."); - $location.url("/realms/" + realm.realm + '/oauth-clients/' + oauth.id + "/mappers"); - }); - }); - }; - -}); - -module.controller('OAuthClientProtocolMapperCreateCtrl', function($scope, realm, serverInfo, oauth, OAuthClientProtocolMapper, Notifications, Dialog, $location) { - if (oauth.protocol == null) { - oauth.protocol = 'openid-connect'; - } - $scope.realm = realm; - $scope.oauth = oauth; - $scope.create = true; - var protocol = oauth.protocol; - $scope.protocol = protocol; - $scope.mapper = { protocol : oauth.protocol, config: {}}; - $scope.mapperTypes = serverInfo.protocolMapperTypes[protocol]; - - $scope.$watch(function() { - return $location.path(); - }, function() { - $scope.path = $location.path().substring(1).split("/"); - }); - - $scope.save = function() { - $scope.mapper.protocolMapper = $scope.mapperType.id; - OAuthClientProtocolMapper.save({ - realm : realm.realm, oauth: oauth.id - }, $scope.mapper, function(data, headers) { - var l = headers().location; - var id = l.substring(l.lastIndexOf("/") + 1); - $location.url("/realms/" + realm.realm + '/oauth-clients/' + oauth.id + "/mappers/" + id); - Notifications.success("Mapper has been created."); - }); - }; - - $scope.cancel = function() { - //$location.url("/realms"); - window.history.back(); - }; - - -}); - - diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/js/controllers/realm.js b/forms/common-themes/src/main/resources/theme/base/admin/resources/js/controllers/realm.js index bb7620e9e6..750d482547 100755 --- a/forms/common-themes/src/main/resources/theme/base/admin/resources/js/controllers/realm.js +++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/js/controllers/realm.js @@ -53,10 +53,6 @@ module.controller('GlobalCtrl', function($scope, $http, Auth, WhoAmI, Current, $ return getAccess('view-realm') || this.manageRealm; }, - get viewApplications() { - return getAccess('view-applications') || this.manageApplications; - }, - get viewClients() { return getAccess('view-clients') || this.manageClients; }, @@ -73,10 +69,6 @@ module.controller('GlobalCtrl', function($scope, $http, Auth, WhoAmI, Current, $ return getAccess('manage-realm'); }, - get manageApplications() { - return getAccess('manage-applications'); - }, - get manageClients() { return getAccess('manage-clients'); }, diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/js/loaders.js b/forms/common-themes/src/main/resources/theme/base/admin/resources/js/loaders.js index da6873da34..7223ae5592 100755 --- a/forms/common-themes/src/main/resources/theme/base/admin/resources/js/loaders.js +++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/js/loaders.js @@ -89,17 +89,6 @@ module.factory('ApplicationProtocolMapperLoader', function(Loader, ApplicationPr }); }); -module.factory('OAuthClientProtocolMapperLoader', function(Loader, OAuthClientProtocolMapper, $route, $q) { - return Loader.get(OAuthClientProtocolMapper, function() { - return { - realm : $route.current.params.realm, - oauth : $route.current.params.oauth, - id: $route.current.params.id - } - }); -}); - - module.factory('UserLoader', function(Loader, User, $route, $q) { return Loader.get(User, function() { return { @@ -261,42 +250,6 @@ module.factory('RoleMappingLoader', function(Loader, RoleMapping, $route, $q) { }); }); -module.factory('OAuthClientLoader', function(Loader, OAuthClient, $route, $q) { - return Loader.get(OAuthClient, function() { - return { - realm : $route.current.params.realm, - oauth : $route.current.params.oauth - } - }); -}); - -module.factory('OAuthClientClaimsLoader', function(Loader, OAuthClientClaims, $route, $q) { - return Loader.get(OAuthClientClaims, function() { - return { - realm : $route.current.params.realm, - oauth : $route.current.params.oauth - } - }); -}); - - -module.factory('OAuthClientListLoader', function(Loader, OAuthClient, $route, $q) { - return Loader.query(OAuthClient, function() { - return { - realm : $route.current.params.realm - } - }); -}); - -module.factory('OAuthClientInstallationLoader', function(Loader, OAuthClientInstallation, $route, $q) { - return Loader.get(OAuthClientInstallation, function() { - return { - realm : $route.current.params.realm, - oauth : $route.current.params.oauth - } - }); -}); - module.factory('IdentityProviderLoader', function(Loader, IdentityProvider, $route, $q) { return Loader.get(IdentityProvider, function () { return { diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/js/services.js b/forms/common-themes/src/main/resources/theme/base/admin/resources/js/services.js index d7833249cd..805bc01319 100755 --- a/forms/common-themes/src/main/resources/theme/base/admin/resources/js/services.js +++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/js/services.js @@ -202,29 +202,6 @@ module.factory('ApplicationProtocolMapper', function($resource) { }); }); -module.factory('OAuthClientProtocolMapper', function($resource) { - return $resource(authUrl + '/admin/realms/:realm/oauth-clients-by-id/:oauth/protocol-mappers/models/:id', { - realm : '@realm', - oauth: '@oauth', - id : "@id" - }, { - update : { - method : 'PUT' - } - }); -}); - -module.factory('OAuthClientProtocolMappersByProtocol', function($resource) { - return $resource(authUrl + '/admin/realms/:realm/oauth-clients-by-id/:oauth/protocol-mappers/protocol/:protocol', { - realm : '@realm', - oauth : "@oauth", - protocol : "@protocol" - }); -}); - - - - module.factory('User', function($resource) { return $resource(authUrl + '/admin/realms/:realm/users/:userId', { realm : '@realm', @@ -840,120 +817,6 @@ module.factory('ApplicationOrigins', function($resource) { }); }); -module.factory('OAuthClient', function($resource) { - return $resource(authUrl + '/admin/realms/:realm/oauth-clients-by-id/:oauth', { - realm : '@realm', - oauth : '@oauth' - }, { - update : { - method : 'PUT' - } - }); -}); - -module.factory('OAuthClientClaims', function($resource) { - return $resource(authUrl + '/admin/realms/:realm/oauth-clients-by-id/:oauth/claims', { - realm : '@realm', - oauth : "@oauth" - }, { - update : { - method : 'PUT' - } - }); -}); - - -module.factory('OAuthClientCredentials', function($resource) { - return $resource(authUrl + '/admin/realms/:realm/oauth-clients-by-id/:oauth/client-secret', { - realm : '@realm', - oauth : '@oauth' - }, { - update : { - method : 'POST' - } - }); - -}); - -module.factory('OAuthCertificate', function($resource) { - return $resource(authUrl + '/admin/realms/:realm/oauth-clients-by-id/:oauth/certificates', { - realm : '@realm', - oauth : '@oauth' - }); -}); - -module.factory('OAuthCertificateDownload', function($resource) { - return $resource(authUrl + '/admin/realms/:realm/oauth-clients-by-id/:oauth/certificates/download', { - realm : '@realm', - oauth : '@oauth' - }); -}); - - -module.factory('OAuthClientRealmScopeMapping', function($resource) { - return $resource(authUrl + '/admin/realms/:realm/oauth-clients-by-id/:oauth/scope-mappings/realm', { - realm : '@realm', - oauth : '@oauth' - }); -}); - -module.factory('OAuthClientCompositeRealmScopeMapping', function($resource) { - return $resource(authUrl + '/admin/realms/:realm/oauth-clients-by-id/:oauth/scope-mappings/realm/composite', { - realm : '@realm', - oauth : '@oauth' - }); -}); - -module.factory('OAuthClientAvailableRealmScopeMapping', function($resource) { - return $resource(authUrl + '/admin/realms/:realm/oauth-clients-by-id/:oauth/scope-mappings/realm/available', { - realm : '@realm', - oauth : '@oauth' - }); -}); - -module.factory('OAuthClientApplicationScopeMapping', function($resource) { - return $resource(authUrl + '/admin/realms/:realm/oauth-clients-by-id/:oauth/scope-mappings/applications-by-id/:targetApp', { - realm : '@realm', - oauth : '@oauth', - targetApp : '@targetApp' - }); -}); - -module.factory('OAuthClientCompositeApplicationScopeMapping', function($resource) { - return $resource(authUrl + '/admin/realms/:realm/oauth-clients-by-id/:oauth/scope-mappings/applications-by-id/:targetApp/composite', { - realm : '@realm', - oauth : '@oauth', - targetApp : '@targetApp' - }); -}); - -module.factory('OAuthClientAvailableApplicationScopeMapping', function($resource) { - return $resource(authUrl + '/admin/realms/:realm/oauth-clients-by-id/:oauth/scope-mappings/applications-by-id/:targetApp/available', { - realm : '@realm', - oauth : '@oauth', - targetApp : '@targetApp' - }); -}); - - - -module.factory('OAuthClientInstallation', function($resource) { - var url = authUrl + '/admin/realms/:realm/oauth-clients-by-id/:oauth/installation'; - var resource = $resource(authUrl + '/admin/realms/:realm/oauth-clients-by-id/:oauth/installation', { - realm : '@realm', - oauth : '@oauth' - }, { - update : { - method : 'PUT' - } - }); - resource.url = function(parameters) { - return url.replace(':realm', parameters.realm).replace(':oauth', parameters.oauth); - } - return resource; -}); - - module.factory('Current', function(Realm, $route) { var current = {}; diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/application-clustering-node.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/application-clustering-node.html index 74ef211f37..3c4f6145e1 100644 --- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/application-clustering-node.html +++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/application-clustering-node.html @@ -10,7 +10,7 @@

{{application.name}} Clustering

Cluster node on host {{node.host}} not registered!

-
+
Configuration of cluster node
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/application-clustering.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/application-clustering.html index 985260fea5..dd5316e0a4 100644 --- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/application-clustering.html +++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/application-clustering.html @@ -8,7 +8,7 @@
  • Clustering
  • {{application.name}} Clustering

    - + Basic configuration
    @@ -43,7 +43,7 @@ - @@ -57,7 +57,7 @@ - + diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/application-credentials.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-credentials.html similarity index 71% rename from forms/common-themes/src/main/resources/theme/base/admin/resources/partials/application-credentials.html rename to forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-credentials.html index f8cc47acfb..fdb8ceeae3 100755 --- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/application-credentials.html +++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-credentials.html @@ -1,14 +1,14 @@
    - +
    -

    {{application.name}} Credentials

    - +

    {{client.clientId}} Credentials

    +
    Client Secret
    @@ -18,7 +18,7 @@
    -
    +
    diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/application-detail.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-detail.html similarity index 79% rename from forms/common-themes/src/main/resources/theme/base/admin/resources/partials/application-detail.html rename to forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-detail.html index 9c0a2c5959..aa3d9baa53 100755 --- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/application-detail.html +++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-detail.html @@ -1,46 +1,46 @@
    - +
    -

    {{application.name}} Application Settings

    -

    {{realm.realm}} Add Application

    +

    {{client.clientId}} Client Settings

    +

    {{realm.realm}} Add Client

    * Required fields

    - +
    - +
    - +
    - +
    - +
    - +
    - +
    @@ -69,7 +69,7 @@
    - +
    @@ -129,9 +129,9 @@
    - +
    - +
    @@ -153,9 +153,9 @@
    -
    +
    -
    +
    @@ -169,7 +169,7 @@
    + data-ng-class="{'input-below':client.redirectUris.length}" /> @@ -177,33 +177,33 @@
    -
    +
    + data-ng-model="client.baseUrl">
    - +
    + data-ng-model="client.adminUrl">
    - +
    + data-ng-model="client.adminUrl">
    -
    +
    -
    +
    @@ -217,7 +217,7 @@
    + data-ng-class="{'input-below':client.webOrigins.length}" /> @@ -231,30 +231,30 @@
    - +
    - +
    - +
    - +
    - +
    - +
    - +
    - +
    @@ -265,7 +265,7 @@
    - +
    diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/application-identity-provider.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-identity-provider.html similarity index 57% rename from forms/common-themes/src/main/resources/theme/base/admin/resources/partials/application-identity-provider.html rename to forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-identity-provider.html index f4473bf8fa..c24ec4e654 100755 --- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/application-identity-provider.html +++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-identity-provider.html @@ -1,20 +1,20 @@
    - +
    -

    {{application.name}} Identity Provider Settings

    +

    {{client.clientId}} Identity Provider Settings

    {{identityProvider.identityProvider.name}} -
    - +
    +
    - +
    diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/application-import.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-import.html similarity index 87% rename from forms/common-themes/src/main/resources/theme/base/admin/resources/partials/application-import.html rename to forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-import.html index 4399d3c78e..1efd3be6d9 100755 --- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/application-import.html +++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-import.html @@ -1,11 +1,11 @@

    -

    {{application.name}} Application Import

    +

    {{client.clientId}} Client Import

    diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/application-installation.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-installation.html similarity index 73% rename from forms/common-themes/src/main/resources/theme/base/admin/resources/partials/application-installation.html rename to forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-installation.html index 5a98483923..134376ea2d 100755 --- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/application-installation.html +++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-installation.html @@ -1,14 +1,14 @@
    - +
    -

    {{application.name}} Adapter Installation

    +

    {{client.clientId}} Adapter Installation

    diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/application-keys.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-keys.html similarity index 92% rename from forms/common-themes/src/main/resources/theme/base/admin/resources/partials/application-keys.html rename to forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-keys.html index 1acaa54397..e789df5626 100755 --- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/application-keys.html +++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-keys.html @@ -1,13 +1,13 @@
    - +
    -

    {{application.name}} Key Pair and Certificate

    +

    {{client.clientId}} Key Pair and Certificate

    Import Keys and Cert @@ -62,7 +62,7 @@
    - Download Keys and Cert + Download Keys and Cert
    diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-list.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-list.html new file mode 100755 index 0000000000..52cf833ab4 --- /dev/null +++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-list.html @@ -0,0 +1,47 @@ +
    +
    +

    +
    +

    {{realm.realm}} Clients

    +
    +
    Register node manually diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/application-detail.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/application-detail.html index c3b1f9dbdb..9c0a2c5959 100755 --- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/application-detail.html +++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/application-detail.html @@ -15,7 +15,7 @@

    {{realm.realm}} Add Application

    * Required fields

    - +
    @@ -30,6 +30,20 @@
    +
    + +
    + +
    + +
    +
    + +
    + +
    + +
    @@ -244,11 +258,11 @@
    -
    +
    -
    +
    diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/application-revocation.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/application-revocation.html index 41e8c11e38..cfd17cd741 100755 --- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/application-revocation.html +++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/application-revocation.html @@ -18,7 +18,7 @@
    -
    +
    -
    +
    diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/application-role-list.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/application-role-list.html index e10126efd8..b2dc850858 100755 --- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/application-role-list.html +++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/application-role-list.html @@ -12,7 +12,7 @@ - - + @@ -35,6 +36,7 @@ {{identityProvider.alias}} +
    +
    Add Role diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/application-scope-mappings.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/application-scope-mappings.html index 852f1f4116..ce693c1e3b 100755 --- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/application-scope-mappings.html +++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/application-scope-mappings.html @@ -10,7 +10,7 @@

    {{application.name}} Scope Mappings

    - +
    @@ -22,7 +22,7 @@
    -
    +
    Realm Roles
    diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/oauth-client-claims.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/oauth-client-claims.html deleted file mode 100755 index f3302260c2..0000000000 --- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/oauth-client-claims.html +++ /dev/null @@ -1,19 +0,0 @@ -
    -
    - -
    - -

    {{oauth.name}} Allowed Claims

    - -
    -
    - - -
    - -
    -
    diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/oauth-client-credentials.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/oauth-client-credentials.html deleted file mode 100755 index 9b5db3433f..0000000000 --- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/oauth-client-credentials.html +++ /dev/null @@ -1,29 +0,0 @@ -
    -
    - -
    - -

    {{oauth.name}} Credentials

    -
    -
    - Client Secret -
    - -
    - -
    -
    -
    -
    - -
    -
    -
    -
    - diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/oauth-client-detail.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/oauth-client-detail.html deleted file mode 100755 index 46daf9fc06..0000000000 --- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/oauth-client-detail.html +++ /dev/null @@ -1,116 +0,0 @@ -
    -
    - -
    - - -

    {{realm.realm}} Add OAuth Client

    -

    * Required fields

    -

    {{oauth.name}} Settings

    -
    -
    - -
    - -
    - -
    -
    - -
    - -
    - -
    - -
    -
    - -
    -
    - -
    -
    - -
    -
    - -
    - -
    - -
    -
    - -
    -
    - - - - -
    -
    -
    -
    - - - - -
    -
    - -
    -
    - -
    -
    - - - - -
    -
    -
    -
    - - - - -
    -
    - -
    -
    - -
    - - -
    -
    - - - -
    -
    -
    -
    \ No newline at end of file diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/oauth-client-identity-provider.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/oauth-client-identity-provider.html deleted file mode 100755 index 619ce331ea..0000000000 --- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/oauth-client-identity-provider.html +++ /dev/null @@ -1,31 +0,0 @@ -
    -
    - -
    - -

    {{oauth.name}} Identity Provider Settings

    -
    -
    - {{identityProvider.identityProvider.name}} - -
    - -
    -
    - -
    - -
    -
    -
    -
    - - -
    -
    -
    -
    diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/oauth-client-installation.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/oauth-client-installation.html deleted file mode 100755 index 5a8cd4f940..0000000000 --- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/oauth-client-installation.html +++ /dev/null @@ -1,26 +0,0 @@ -
    -
    - -
    - -

    {{oauth.name}} Adapter Installation

    -
    -
    -
    -
    - -
    -
    -
    -
    - -
    - Download -
    - -
    -
    \ No newline at end of file diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/oauth-client-list.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/oauth-client-list.html deleted file mode 100755 index ebf59a4622..0000000000 --- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/oauth-client-list.html +++ /dev/null @@ -1,55 +0,0 @@ -
    -
    -

    -
    -

    {{realm.realm}} OAuth Clients

    - - - - - - - - - - - - - - - - - - - - -
    -
    - - -
    - -
    OAuth Client NameEnabled
    {{client.name}}{{client.enabled}}
    No clients available
    - -
    -
    diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/oauth-client-mappers-add.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/oauth-client-mappers-add.html deleted file mode 100755 index 0b0284e060..0000000000 --- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/oauth-client-mappers-add.html +++ /dev/null @@ -1,49 +0,0 @@ -
    -
    - -
    - -

    Add Builtin Protocol Mappers

    - - - - - - - - - - - - - - - - - - - - - - - -
    -
    - - -
    -
    - -
    -
    NameCategoryTypeAdd
    {{mapper.name}}{{mapperTypes[mapper.protocolMapper].category}}{{mapperTypes[mapper.protocolMapper].name}}
    No mappers available
    -
    -
    diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/oauth-client-mappers.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/oauth-client-mappers.html deleted file mode 100755 index 83a722e7e9..0000000000 --- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/oauth-client-mappers.html +++ /dev/null @@ -1,47 +0,0 @@ -
    -
    - -
    - -

    {{realm.realm}} {{oauth.name}} {{oauth.protocol}} Protocol Mappers

    - - - - - - - - - - - - - - - - - - - - - -
    -
    - - -
    - -
    NameCategoryType
    {{mapper.name}}{{mapperTypes[mapper.protocolMapper].category}}{{mapperTypes[mapper.protocolMapper].name}}
    No mappers available
    -
    -
    diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/oauth-client-protocol-mapper-detail.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/oauth-client-protocol-mapper-detail.html deleted file mode 100755 index 36738b65b6..0000000000 --- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/oauth-client-protocol-mapper-detail.html +++ /dev/null @@ -1,108 +0,0 @@ -
    -
    - -
    - - - -

    {{mapper.name}} Protocol Mapper

    -

    Create Protocol Mapper

    -

    * Required fields

    -
    - -
    -
    - -
    - -
    - -
    -
    - -
    - -
    -
    -
    - -
    - -
    - -
    -
    - -
    - -
    - -
    -
    - - -
    - -
    - -
    -
    - -
    -
    - -
    -
    - -
    -
    - -
    - -
    - -
    -
    - - -
    - -
    -
    - -
    -
    - -
    - -
    - -
    -
    - - -
    - -
    - - - -
    -
    -
    -
    \ No newline at end of file diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/oauth-client-revocation.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/oauth-client-revocation.html deleted file mode 100755 index 1af3cafa1b..0000000000 --- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/oauth-client-revocation.html +++ /dev/null @@ -1,29 +0,0 @@ -
    -
    - -
    - -

    {{oauth.name}} Revocation Policies

    -
    -
    -
    - -
    - -
    - -
    -
    -
    - - -
    -
    -
    -
    diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/oauth-client-scope-mappings.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/oauth-client-scope-mappings.html deleted file mode 100755 index f137b5db37..0000000000 --- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/oauth-client-scope-mappings.html +++ /dev/null @@ -1,124 +0,0 @@ -
    -
    - -
    - -

    {{oauth.name}} Scope Mappings

    -

    -
    -
    -
    - -
    - -
    - -
    -
    -
    -
    -
    - Realm Roles -
    -
    -
    - - -
    -
    - - -
    -
    - - -
    -
    - - -
    -
    - - -
    -
    -
    -
    - -
    - Application Roles -
    - -
    -
    -
    - -
    -
    -
    - -
    -
    -
    -
    - - -
    -
    - - -
    -
    - - -
    -
    - - -
    -
    - - -
    -
    -
    -
    -
    -
    -
    \ No newline at end of file diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-menu.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-menu.html index 098f317201..00d2e31b3b 100755 --- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-menu.html +++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-menu.html @@ -7,12 +7,9 @@ || path[2] == 'keys-settings' || path[2] == 'smtp-settings' || path[2] == 'ldap-settings' || path[2] == 'auth-settings') && path[3] != 'applications') && 'active'"> Settings -
  • Users -
  • -
  • Roles -
  • -
  • Applications
  • -
  • OAuth Clients
  • +
  • Users
  • +
  • Clients
  • +
  • Roles
  • Sessions and Tokens
  • Security Defenses
  • Events
  • diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/session-revocation.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/session-revocation.html index c87af7f9ae..79007bc1dc 100755 --- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/session-revocation.html +++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/session-revocation.html @@ -18,7 +18,7 @@
    -
    +
    +
    + +
    + +
    + +
    OpenID Connect Config diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-identity-provider-saml.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-identity-provider-saml.html index 10327e6c5f..3e151fd75d 100755 --- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-identity-provider-saml.html +++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-identity-provider-saml.html @@ -55,6 +55,13 @@
    +
    + +
    + +
    + +
    SAML Config diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-identity-provider-social.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-identity-provider-social.html index 0a8b56a5c6..809984bcfe 100755 --- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-identity-provider-social.html +++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-identity-provider-social.html @@ -73,6 +73,13 @@ +
    + +
    + +
    + +
    diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-identity-provider.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-identity-provider.html index 1c0ed54a06..778bb2c889 100755 --- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-identity-provider.html +++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-identity-provider.html @@ -12,7 +12,7 @@
    +
    Name ProviderGUI order
    {{identityProvider.providerId}}{{identityProvider.config.guiOrder}}
    diff --git a/forms/login-freemarker/pom.xml b/forms/login-freemarker/pom.xml index e83bc52177..c5b7134db4 100755 --- a/forms/login-freemarker/pom.xml +++ b/forms/login-freemarker/pom.xml @@ -71,6 +71,12 @@ jboss-logging provided + + + junit + junit + test + diff --git a/forms/login-freemarker/src/main/java/org/keycloak/login/freemarker/model/IdentityProviderBean.java b/forms/login-freemarker/src/main/java/org/keycloak/login/freemarker/model/IdentityProviderBean.java index cd11bfda7e..65e02723c7 100755 --- a/forms/login-freemarker/src/main/java/org/keycloak/login/freemarker/model/IdentityProviderBean.java +++ b/forms/login-freemarker/src/main/java/org/keycloak/login/freemarker/model/IdentityProviderBean.java @@ -27,11 +27,15 @@ import org.keycloak.services.resources.flows.Urls; import javax.ws.rs.core.UriInfo; import java.net.URI; +import java.util.Comparator; import java.util.LinkedList; import java.util.List; +import java.util.Set; +import java.util.TreeSet; /** * @author Stian Thorgersen + * @author Vlastimil Elias (velias at redhat dot com) */ public class IdentityProviderBean { @@ -45,23 +49,24 @@ public class IdentityProviderBean { List identityProviders = realm.getIdentityProviders(); if (!identityProviders.isEmpty()) { - providers = new LinkedList(); - + Set orderedSet = new TreeSet<>(IdentityProviderComparator.INSTANCE); for (IdentityProviderModel identityProvider : identityProviders) { if (identityProvider.isEnabled()) { - addIdentityProvider(realm, baseURI, identityProvider); + addIdentityProvider(orderedSet, realm, baseURI, identityProvider); } } - if (!providers.isEmpty()) { + if (!orderedSet.isEmpty()) { + providers = new LinkedList(orderedSet); displaySocial = true; } } } - private void addIdentityProvider(RealmModel realm, URI baseURI, IdentityProviderModel identityProvider) { + private void addIdentityProvider(Set orderedSet, RealmModel realm, URI baseURI, IdentityProviderModel identityProvider) { String loginUrl = Urls.identityProviderAuthnRequest(baseURI, identityProvider.getAlias(), realm.getName()).toString(); - providers.add(new IdentityProvider(identityProvider.getAlias(), identityProvider.getProviderId(), loginUrl)); + orderedSet.add(new IdentityProvider(identityProvider.getAlias(), identityProvider.getProviderId(), loginUrl, + identityProvider.getConfig() != null ? identityProvider.getConfig().get("guiOrder") : null)); } public List getProviders() { @@ -77,12 +82,13 @@ public class IdentityProviderBean { private final String alias; private final String providerId; // This refer to providerType (facebook, google, etc.) private final String loginUrl; + private final String guiOrder; - public IdentityProvider(String alias, String providerId,String loginUrl) { + public IdentityProvider(String alias, String providerId, String loginUrl, String guiOrder) { this.alias = alias; this.providerId = providerId; - this.loginUrl = loginUrl; + this.guiOrder = guiOrder; } public String getAlias() { @@ -96,5 +102,44 @@ public class IdentityProviderBean { public String getProviderId() { return providerId; } + + public String getGuiOrder() { + return guiOrder; + } + } + + public static class IdentityProviderComparator implements Comparator { + + public static IdentityProviderComparator INSTANCE = new IdentityProviderComparator(); + + private IdentityProviderComparator() { + + } + + @Override + public int compare(IdentityProvider o1, IdentityProvider o2) { + + int o1order = parseOrder(o1); + int o2order = parseOrder(o2); + + if (o1order > o2order) + return 1; + else if (o1order < o2order) + return -1; + + return 1; + } + + private int parseOrder(IdentityProvider ip) { + if (ip != null && ip.getGuiOrder() != null) { + try { + return Integer.parseInt(ip.getGuiOrder()); + } catch (NumberFormatException e) { + // ignore it and use defaulr + } + } + return 10000; + } + } } diff --git a/forms/login-freemarker/src/test/java/org/keycloak/login/freemarker/model/IdentityProviderBeanTest.java b/forms/login-freemarker/src/test/java/org/keycloak/login/freemarker/model/IdentityProviderBeanTest.java new file mode 100644 index 0000000000..dda3316a13 --- /dev/null +++ b/forms/login-freemarker/src/test/java/org/keycloak/login/freemarker/model/IdentityProviderBeanTest.java @@ -0,0 +1,55 @@ +/* + * JBoss, Home of Professional Open Source + * Copyright 2015 Red Hat Inc. and/or its affiliates and other contributors + * as indicated by the @authors tag. All rights reserved. + */ +package org.keycloak.login.freemarker.model; + +import org.junit.Assert; +import org.junit.Test; +import org.keycloak.login.freemarker.model.IdentityProviderBean.IdentityProvider; +import org.keycloak.login.freemarker.model.IdentityProviderBean.IdentityProviderComparator; + +/** + * Unit test for {@link IdentityProviderBean} + * + * @author Vlastimil Elias (velias at redhat dot com) + */ +public class IdentityProviderBeanTest { + + + @Test + public void testIdentityProviderComparator() { + + IdentityProvider o1 = new IdentityProvider("alias1", "id1", "ur1", null); + IdentityProvider o2 = new IdentityProvider("alias2", "id2", "ur2", null); + + // guiOrder not defined at any object - first is always lower + Assert.assertEquals(1, IdentityProviderComparator.INSTANCE.compare(o1, o2)); + Assert.assertEquals(1, IdentityProviderComparator.INSTANCE.compare(o2, o1)); + + // guiOrder is not a number so it is same as not defined - first is always lower + o1 = new IdentityProvider("alias1", "id1", "ur1", "not a number"); + Assert.assertEquals(1, IdentityProviderComparator.INSTANCE.compare(o1, o2)); + Assert.assertEquals(1, IdentityProviderComparator.INSTANCE.compare(o2, o1)); + + // guiOrder is defined for one only to it is always first + o1 = new IdentityProvider("alias1", "id1", "ur1", "0"); + Assert.assertEquals(-1, IdentityProviderComparator.INSTANCE.compare(o1, o2)); + Assert.assertEquals(1, IdentityProviderComparator.INSTANCE.compare(o2, o1)); + + // guiOrder is defined for both but is same - first is always lower + o1 = new IdentityProvider("alias1", "id1", "ur1", "0"); + o2 = new IdentityProvider("alias2", "id2", "ur2", "0"); + Assert.assertEquals(1, IdentityProviderComparator.INSTANCE.compare(o1, o2)); + Assert.assertEquals(1, IdentityProviderComparator.INSTANCE.compare(o2, o1)); + + // guiOrder is reflected + o1 = new IdentityProvider("alias1", "id1", "ur1", "0"); + o2 = new IdentityProvider("alias2", "id2", "ur2", "1"); + Assert.assertEquals(-1, IdentityProviderComparator.INSTANCE.compare(o1, o2)); + Assert.assertEquals(1, IdentityProviderComparator.INSTANCE.compare(o2, o1)); + + } + +} From bbef4e2be19b0bd0053afa2f7415df52d298d08e Mon Sep 17 00:00:00 2001 From: Stan Silvert Date: Thu, 9 Apr 2015 10:30:39 -0400 Subject: [PATCH 06/15] KEYCLOAK-1174: Refactor KeycloakAdapterConfigService to be a simple singleton --- .../extension/CredentialAddHandler.java | 2 +- .../CredentialReadWriteAttributeHandler.java | 2 +- .../extension/CredentialRemoveHandler.java | 2 +- ...cloakAdapterConfigDeploymentProcessor.java | 3 +- ...kAdapterConfigDeploymentProcessorEAP6.java | 2 +- .../KeycloakAdapterConfigService.java | 57 ++++--------------- .../extension/KeycloakSubsystemAdd.java | 12 ---- .../subsystem/extension/RealmAddHandler.java | 2 +- .../extension/RealmRemoveHandler.java | 2 +- .../extension/RealmWriteAttributeHandler.java | 2 +- .../extension/SecureDeploymentAddHandler.java | 2 +- .../SecureDeploymentRemoveHandler.java | 2 +- ...SecureDeploymentWriteAttributeHandler.java | 2 +- .../authserver/AuthServerAddHandler.java | 2 +- .../authserver/AuthServerDefinition.java | 4 +- .../authserver/AuthServerRemoveHandler.java | 2 +- .../AuthServerWriteAttributeHandler.java | 4 +- .../KeycloakServerDeploymentProcessor.java | 2 +- 18 files changed, 29 insertions(+), 77 deletions(-) diff --git a/integration/keycloak-subsystem/src/main/java/org/keycloak/subsystem/extension/CredentialAddHandler.java b/integration/keycloak-subsystem/src/main/java/org/keycloak/subsystem/extension/CredentialAddHandler.java index c3c37fa63c..17f7928198 100755 --- a/integration/keycloak-subsystem/src/main/java/org/keycloak/subsystem/extension/CredentialAddHandler.java +++ b/integration/keycloak-subsystem/src/main/java/org/keycloak/subsystem/extension/CredentialAddHandler.java @@ -40,7 +40,7 @@ public class CredentialAddHandler extends AbstractAddStepHandler { @Override protected void performRuntime(OperationContext context, ModelNode operation, ModelNode model, ServiceVerificationHandler verificationHandler, List> newControllers) throws OperationFailedException { - KeycloakAdapterConfigService ckService = KeycloakAdapterConfigService.find(context); + KeycloakAdapterConfigService ckService = KeycloakAdapterConfigService.getInstance(); ckService.addCredential(operation, context.resolveExpressions(model)); } diff --git a/integration/keycloak-subsystem/src/main/java/org/keycloak/subsystem/extension/CredentialReadWriteAttributeHandler.java b/integration/keycloak-subsystem/src/main/java/org/keycloak/subsystem/extension/CredentialReadWriteAttributeHandler.java index 6289ff4539..75b334d3dd 100644 --- a/integration/keycloak-subsystem/src/main/java/org/keycloak/subsystem/extension/CredentialReadWriteAttributeHandler.java +++ b/integration/keycloak-subsystem/src/main/java/org/keycloak/subsystem/extension/CredentialReadWriteAttributeHandler.java @@ -33,7 +33,7 @@ public class CredentialReadWriteAttributeHandler extends AbstractWriteAttributeH protected boolean applyUpdateToRuntime(OperationContext context, ModelNode operation, String attributeName, ModelNode resolvedValue, ModelNode currentValue, AbstractWriteAttributeHandler.HandbackHolder hh) throws OperationFailedException { - KeycloakAdapterConfigService ckService = KeycloakAdapterConfigService.find(context); + KeycloakAdapterConfigService ckService = KeycloakAdapterConfigService.getInstance(); ckService.updateCredential(operation, attributeName, resolvedValue); hh.setHandback(ckService); diff --git a/integration/keycloak-subsystem/src/main/java/org/keycloak/subsystem/extension/CredentialRemoveHandler.java b/integration/keycloak-subsystem/src/main/java/org/keycloak/subsystem/extension/CredentialRemoveHandler.java index 1cad10bfb0..0023d41cc1 100644 --- a/integration/keycloak-subsystem/src/main/java/org/keycloak/subsystem/extension/CredentialRemoveHandler.java +++ b/integration/keycloak-subsystem/src/main/java/org/keycloak/subsystem/extension/CredentialRemoveHandler.java @@ -35,7 +35,7 @@ public final class CredentialRemoveHandler extends AbstractRemoveStepHandler { @Override protected void performRuntime(OperationContext context, ModelNode operation, ModelNode model) throws OperationFailedException { - KeycloakAdapterConfigService ckService = KeycloakAdapterConfigService.find(context); + KeycloakAdapterConfigService ckService = KeycloakAdapterConfigService.getInstance(); ckService.removeCredential(operation); } diff --git a/integration/keycloak-subsystem/src/main/java/org/keycloak/subsystem/extension/KeycloakAdapterConfigDeploymentProcessor.java b/integration/keycloak-subsystem/src/main/java/org/keycloak/subsystem/extension/KeycloakAdapterConfigDeploymentProcessor.java index f96d1c2c99..bebf6dbe54 100755 --- a/integration/keycloak-subsystem/src/main/java/org/keycloak/subsystem/extension/KeycloakAdapterConfigDeploymentProcessor.java +++ b/integration/keycloak-subsystem/src/main/java/org/keycloak/subsystem/extension/KeycloakAdapterConfigDeploymentProcessor.java @@ -68,8 +68,7 @@ public class KeycloakAdapterConfigDeploymentProcessor implements DeploymentUnitP DeploymentUnit deploymentUnit = phaseContext.getDeploymentUnit(); String deploymentName = deploymentUnit.getName(); - KeycloakAdapterConfigService service = KeycloakAdapterConfigService.find(phaseContext.getServiceRegistry()); - //log.info("********* CHECK KEYCLOAK DEPLOYMENT: " + deploymentName); + KeycloakAdapterConfigService service = KeycloakAdapterConfigService.getInstance(); if (service.isSecureDeployment(deploymentName)) { addKeycloakAuthData(phaseContext, deploymentName, service); } diff --git a/integration/keycloak-subsystem/src/main/java/org/keycloak/subsystem/extension/KeycloakAdapterConfigDeploymentProcessorEAP6.java b/integration/keycloak-subsystem/src/main/java/org/keycloak/subsystem/extension/KeycloakAdapterConfigDeploymentProcessorEAP6.java index 77261ba311..dc2d8e76d0 100755 --- a/integration/keycloak-subsystem/src/main/java/org/keycloak/subsystem/extension/KeycloakAdapterConfigDeploymentProcessorEAP6.java +++ b/integration/keycloak-subsystem/src/main/java/org/keycloak/subsystem/extension/KeycloakAdapterConfigDeploymentProcessorEAP6.java @@ -50,7 +50,7 @@ public class KeycloakAdapterConfigDeploymentProcessorEAP6 implements DeploymentU DeploymentUnit deploymentUnit = phaseContext.getDeploymentUnit(); String deploymentName = deploymentUnit.getName(); - KeycloakAdapterConfigService service = KeycloakAdapterConfigService.find(phaseContext.getServiceRegistry()); + KeycloakAdapterConfigService service = KeycloakAdapterConfigService.getInstance(); //log.info("********* CHECK KEYCLOAK DEPLOYMENT: " + deploymentName); if (service.isSecureDeployment(deploymentName)) { addKeycloakAuthData(phaseContext, deploymentName, service); diff --git a/integration/keycloak-subsystem/src/main/java/org/keycloak/subsystem/extension/KeycloakAdapterConfigService.java b/integration/keycloak-subsystem/src/main/java/org/keycloak/subsystem/extension/KeycloakAdapterConfigService.java index d860cb65c4..81bb610138 100755 --- a/integration/keycloak-subsystem/src/main/java/org/keycloak/subsystem/extension/KeycloakAdapterConfigService.java +++ b/integration/keycloak-subsystem/src/main/java/org/keycloak/subsystem/extension/KeycloakAdapterConfigService.java @@ -17,17 +17,9 @@ package org.keycloak.subsystem.extension; -import org.jboss.as.controller.OperationContext; import org.jboss.dmr.ModelNode; import org.jboss.dmr.Property; import org.jboss.logging.Logger; -import org.jboss.msc.service.Service; -import org.jboss.msc.service.ServiceController; -import org.jboss.msc.service.ServiceName; -import org.jboss.msc.service.ServiceRegistry; -import org.jboss.msc.service.StartContext; -import org.jboss.msc.service.StartException; -import org.jboss.msc.service.StopContext; import java.util.HashMap; import java.util.Map; @@ -40,41 +32,27 @@ import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.ADD * * @author Stan Silvert ssilvert@redhat.com (C) 2013 Red Hat Inc. */ -public final class KeycloakAdapterConfigService implements Service { +public final class KeycloakAdapterConfigService { protected Logger log = Logger.getLogger(KeycloakAdapterConfigService.class); private static final String CREDENTIALS_JSON_NAME = "credentials"; - // Right now this is used as a service, but I'm not sure it really needs to be implemented that way. - // It's also a singleton serving the entire subsystem, but the INSTANCE variable is currently only - // used during initialization of the subsystem. - public static final ServiceName SERVICE_NAME = ServiceName.JBOSS.append("KeycloakAdapterConfigService"); - public static final KeycloakAdapterConfigService INSTANCE = new KeycloakAdapterConfigService(); + private static final KeycloakAdapterConfigService INSTANCE = new KeycloakAdapterConfigService(); - private Map realms = new HashMap(); + public static KeycloakAdapterConfigService getInstance() { + return INSTANCE; + } + + private final Map realms = new HashMap(); // keycloak-secured deployments - private Map secureDeployments = new HashMap(); + private final Map secureDeployments = new HashMap(); // key=auth-server deployment name; value=web-context - private Map webContexts = new HashMap(); + private final Map webContexts = new HashMap(); + + private KeycloakAdapterConfigService() { - - } - - @Override - public void start(StartContext sc) throws StartException { - - } - - @Override - public void stop(StopContext sc) { - - } - - @Override - public KeycloakAdapterConfigService getValue() throws IllegalStateException, IllegalArgumentException { - return this; } public void addServerDeployment(String deploymentName, String webContext) { @@ -223,17 +201,4 @@ public final class KeycloakAdapterConfigService implements Service container = registry.getService(KeycloakAdapterConfigService.SERVICE_NAME); - if (container != null) { - KeycloakAdapterConfigService service = (KeycloakAdapterConfigService)container.getValue(); - return service; - } - return null; - } - - public static KeycloakAdapterConfigService find(OperationContext context) { - return find(context.getServiceRegistry(true)); - } } diff --git a/integration/keycloak-subsystem/src/main/java/org/keycloak/subsystem/extension/KeycloakSubsystemAdd.java b/integration/keycloak-subsystem/src/main/java/org/keycloak/subsystem/extension/KeycloakSubsystemAdd.java index 0a490042be..386f8c57bc 100755 --- a/integration/keycloak-subsystem/src/main/java/org/keycloak/subsystem/extension/KeycloakSubsystemAdd.java +++ b/integration/keycloak-subsystem/src/main/java/org/keycloak/subsystem/extension/KeycloakSubsystemAdd.java @@ -82,18 +82,6 @@ class KeycloakSubsystemAdd extends AbstractBoottimeAddStepHandler { } } - @Override - protected void performRuntime(OperationContext context, ModelNode operation, ModelNode model, ServiceVerificationHandler verificationHandler, List> newControllers) throws OperationFailedException { - super.performRuntime(context, operation, model, verificationHandler, newControllers); - - ServiceController controller = context.getServiceTarget() - .addService(KeycloakAdapterConfigService.SERVICE_NAME, KeycloakAdapterConfigService.INSTANCE) - .addListener(verificationHandler) - .setInitialMode(ServiceController.Mode.ACTIVE) - .install(); - newControllers.add(controller); - } - @Override protected boolean requiresRuntimeVerification() { return false; diff --git a/integration/keycloak-subsystem/src/main/java/org/keycloak/subsystem/extension/RealmAddHandler.java b/integration/keycloak-subsystem/src/main/java/org/keycloak/subsystem/extension/RealmAddHandler.java index 0d4a5d86d1..62c76e69b6 100755 --- a/integration/keycloak-subsystem/src/main/java/org/keycloak/subsystem/extension/RealmAddHandler.java +++ b/integration/keycloak-subsystem/src/main/java/org/keycloak/subsystem/extension/RealmAddHandler.java @@ -60,7 +60,7 @@ public final class RealmAddHandler extends AbstractAddStepHandler { @Override protected void performRuntime(OperationContext context, ModelNode operation, ModelNode model, ServiceVerificationHandler verificationHandler, List> newControllers) throws OperationFailedException { - KeycloakAdapterConfigService ckService = KeycloakAdapterConfigService.find(context); + KeycloakAdapterConfigService ckService = KeycloakAdapterConfigService.getInstance(); ckService.addRealm(operation, context.resolveExpressions(model)); } } diff --git a/integration/keycloak-subsystem/src/main/java/org/keycloak/subsystem/extension/RealmRemoveHandler.java b/integration/keycloak-subsystem/src/main/java/org/keycloak/subsystem/extension/RealmRemoveHandler.java index a5c5441554..5cc319c0b2 100644 --- a/integration/keycloak-subsystem/src/main/java/org/keycloak/subsystem/extension/RealmRemoveHandler.java +++ b/integration/keycloak-subsystem/src/main/java/org/keycloak/subsystem/extension/RealmRemoveHandler.java @@ -35,7 +35,7 @@ public final class RealmRemoveHandler extends AbstractRemoveStepHandler { @Override protected void performRuntime(OperationContext context, ModelNode operation, ModelNode model) throws OperationFailedException { - KeycloakAdapterConfigService ckService = KeycloakAdapterConfigService.find(context); + KeycloakAdapterConfigService ckService = KeycloakAdapterConfigService.getInstance(); ckService.removeRealm(operation); } } diff --git a/integration/keycloak-subsystem/src/main/java/org/keycloak/subsystem/extension/RealmWriteAttributeHandler.java b/integration/keycloak-subsystem/src/main/java/org/keycloak/subsystem/extension/RealmWriteAttributeHandler.java index 1902b076bc..13e91c5ce4 100755 --- a/integration/keycloak-subsystem/src/main/java/org/keycloak/subsystem/extension/RealmWriteAttributeHandler.java +++ b/integration/keycloak-subsystem/src/main/java/org/keycloak/subsystem/extension/RealmWriteAttributeHandler.java @@ -43,7 +43,7 @@ public class RealmWriteAttributeHandler extends AbstractWriteAttributeHandler hh) throws OperationFailedException { - KeycloakAdapterConfigService ckService = KeycloakAdapterConfigService.find(context); + KeycloakAdapterConfigService ckService = KeycloakAdapterConfigService.getInstance(); ckService.updateRealm(operation, attributeName, resolvedValue); hh.setHandback(ckService); diff --git a/integration/keycloak-subsystem/src/main/java/org/keycloak/subsystem/extension/SecureDeploymentAddHandler.java b/integration/keycloak-subsystem/src/main/java/org/keycloak/subsystem/extension/SecureDeploymentAddHandler.java index 99267dbe18..0c36146ec6 100755 --- a/integration/keycloak-subsystem/src/main/java/org/keycloak/subsystem/extension/SecureDeploymentAddHandler.java +++ b/integration/keycloak-subsystem/src/main/java/org/keycloak/subsystem/extension/SecureDeploymentAddHandler.java @@ -55,7 +55,7 @@ public final class SecureDeploymentAddHandler extends AbstractAddStepHandler { @Override protected void performRuntime(OperationContext context, ModelNode operation, ModelNode model, ServiceVerificationHandler verificationHandler, List> newControllers) throws OperationFailedException { - KeycloakAdapterConfigService ckService = KeycloakAdapterConfigService.find(context); + KeycloakAdapterConfigService ckService = KeycloakAdapterConfigService.getInstance(); ckService.addSecureDeployment(operation, context.resolveExpressions(model)); } } diff --git a/integration/keycloak-subsystem/src/main/java/org/keycloak/subsystem/extension/SecureDeploymentRemoveHandler.java b/integration/keycloak-subsystem/src/main/java/org/keycloak/subsystem/extension/SecureDeploymentRemoveHandler.java index da0ca7e19d..23196a5fff 100644 --- a/integration/keycloak-subsystem/src/main/java/org/keycloak/subsystem/extension/SecureDeploymentRemoveHandler.java +++ b/integration/keycloak-subsystem/src/main/java/org/keycloak/subsystem/extension/SecureDeploymentRemoveHandler.java @@ -35,7 +35,7 @@ public final class SecureDeploymentRemoveHandler extends AbstractRemoveStepHandl @Override protected void performRuntime(OperationContext context, ModelNode operation, ModelNode model) throws OperationFailedException { - KeycloakAdapterConfigService ckService = KeycloakAdapterConfigService.find(context); + KeycloakAdapterConfigService ckService = KeycloakAdapterConfigService.getInstance(); ckService.removeSecureDeployment(operation); } } diff --git a/integration/keycloak-subsystem/src/main/java/org/keycloak/subsystem/extension/SecureDeploymentWriteAttributeHandler.java b/integration/keycloak-subsystem/src/main/java/org/keycloak/subsystem/extension/SecureDeploymentWriteAttributeHandler.java index 2caca6ae64..6c87ac8601 100755 --- a/integration/keycloak-subsystem/src/main/java/org/keycloak/subsystem/extension/SecureDeploymentWriteAttributeHandler.java +++ b/integration/keycloak-subsystem/src/main/java/org/keycloak/subsystem/extension/SecureDeploymentWriteAttributeHandler.java @@ -44,7 +44,7 @@ public class SecureDeploymentWriteAttributeHandler extends AbstractWriteAttribut @Override protected boolean applyUpdateToRuntime(OperationContext context, ModelNode operation, String attributeName, ModelNode resolvedValue, ModelNode currentValue, HandbackHolder hh) throws OperationFailedException { - KeycloakAdapterConfigService ckService = KeycloakAdapterConfigService.find(context); + KeycloakAdapterConfigService ckService = KeycloakAdapterConfigService.getInstance(); hh.setHandback(ckService); ckService.updateSecureDeployment(operation, attributeName, resolvedValue); return false; diff --git a/integration/keycloak-subsystem/src/main/java/org/keycloak/subsystem/extension/authserver/AuthServerAddHandler.java b/integration/keycloak-subsystem/src/main/java/org/keycloak/subsystem/extension/authserver/AuthServerAddHandler.java index 591718e8b1..43d26ce969 100755 --- a/integration/keycloak-subsystem/src/main/java/org/keycloak/subsystem/extension/authserver/AuthServerAddHandler.java +++ b/integration/keycloak-subsystem/src/main/java/org/keycloak/subsystem/extension/authserver/AuthServerAddHandler.java @@ -69,7 +69,7 @@ public final class AuthServerAddHandler extends AbstractAddStepHandler { AuthServerUtil authServerUtil = new AuthServerUtil(operation); authServerUtil.addStepToUploadAuthServer(context, enabled); - KeycloakAdapterConfigService.INSTANCE.addServerDeployment(authServerUtil.getDeploymentName(), webContext); + KeycloakAdapterConfigService.getInstance().addServerDeployment(authServerUtil.getDeploymentName(), webContext); } @Override diff --git a/integration/keycloak-subsystem/src/main/java/org/keycloak/subsystem/extension/authserver/AuthServerDefinition.java b/integration/keycloak-subsystem/src/main/java/org/keycloak/subsystem/extension/authserver/AuthServerDefinition.java index 653d09ae3b..648e35d118 100755 --- a/integration/keycloak-subsystem/src/main/java/org/keycloak/subsystem/extension/authserver/AuthServerDefinition.java +++ b/integration/keycloak-subsystem/src/main/java/org/keycloak/subsystem/extension/authserver/AuthServerDefinition.java @@ -116,7 +116,7 @@ public class AuthServerDefinition extends SimpleResourceDefinition { @Override public void validateParameter(String paramName, ModelNode value) throws OperationFailedException { String strValue = value.asString(); - if (KeycloakAdapterConfigService.INSTANCE.isWebContextUsed(strValue)) { + if (KeycloakAdapterConfigService.getInstance().isWebContextUsed(strValue)) { throw new OperationFailedException("Can not set web-context to '" + strValue + "'. web-context must be unique among all deployments."); } } @@ -124,7 +124,7 @@ public class AuthServerDefinition extends SimpleResourceDefinition { @Override public void validateResolvedParameter(String paramName, ModelNode value) throws OperationFailedException { String strValue = value.asString(); - if (KeycloakAdapterConfigService.INSTANCE.isWebContextUsed(strValue)) { + if (KeycloakAdapterConfigService.getInstance().isWebContextUsed(strValue)) { throw new OperationFailedException("Can not set web-context to '" + strValue + "'. web-context must be unique among all deployments."); } } diff --git a/integration/keycloak-subsystem/src/main/java/org/keycloak/subsystem/extension/authserver/AuthServerRemoveHandler.java b/integration/keycloak-subsystem/src/main/java/org/keycloak/subsystem/extension/authserver/AuthServerRemoveHandler.java index f84e45ffe1..e80fbc6d75 100644 --- a/integration/keycloak-subsystem/src/main/java/org/keycloak/subsystem/extension/authserver/AuthServerRemoveHandler.java +++ b/integration/keycloak-subsystem/src/main/java/org/keycloak/subsystem/extension/authserver/AuthServerRemoveHandler.java @@ -45,7 +45,7 @@ public final class AuthServerRemoveHandler extends AbstractRemoveStepHandler { @Override protected void performRemove(OperationContext context, ModelNode operation, ModelNode model) throws OperationFailedException { String deploymentName = AuthServerUtil.getDeploymentName(operation); - KeycloakAdapterConfigService.INSTANCE.removeServerDeployment(deploymentName); + KeycloakAdapterConfigService.getInstance().removeServerDeployment(deploymentName); if (requiresRuntime(context)) { // don't do this on a domain controller addStepToRemoveAuthServer(context, deploymentName); diff --git a/integration/keycloak-subsystem/src/main/java/org/keycloak/subsystem/extension/authserver/AuthServerWriteAttributeHandler.java b/integration/keycloak-subsystem/src/main/java/org/keycloak/subsystem/extension/authserver/AuthServerWriteAttributeHandler.java index 48ffc320cf..6c5d6b3235 100755 --- a/integration/keycloak-subsystem/src/main/java/org/keycloak/subsystem/extension/authserver/AuthServerWriteAttributeHandler.java +++ b/integration/keycloak-subsystem/src/main/java/org/keycloak/subsystem/extension/authserver/AuthServerWriteAttributeHandler.java @@ -55,8 +55,8 @@ public class AuthServerWriteAttributeHandler extends ModelOnlyWriteAttributeHand if (attributeName.equals(AuthServerDefinition.WEB_CONTEXT.getName())) { - KeycloakAdapterConfigService.INSTANCE.removeServerDeployment(deploymentName); - KeycloakAdapterConfigService.INSTANCE.addServerDeployment(deploymentName, newValue.asString()); + KeycloakAdapterConfigService.getInstance().removeServerDeployment(deploymentName); + KeycloakAdapterConfigService.getInstance().addServerDeployment(deploymentName, newValue.asString()); if (isEnabled) { AuthServerUtil.addStepToRedeployAuthServer(context, deploymentName); } diff --git a/integration/keycloak-subsystem/src/main/java/org/keycloak/subsystem/extension/authserver/KeycloakServerDeploymentProcessor.java b/integration/keycloak-subsystem/src/main/java/org/keycloak/subsystem/extension/authserver/KeycloakServerDeploymentProcessor.java index dd66a01127..565310d8e2 100644 --- a/integration/keycloak-subsystem/src/main/java/org/keycloak/subsystem/extension/authserver/KeycloakServerDeploymentProcessor.java +++ b/integration/keycloak-subsystem/src/main/java/org/keycloak/subsystem/extension/authserver/KeycloakServerDeploymentProcessor.java @@ -34,7 +34,7 @@ public class KeycloakServerDeploymentProcessor implements DeploymentUnitProcesso public void deploy(DeploymentPhaseContext phaseContext) throws DeploymentUnitProcessingException { DeploymentUnit deploymentUnit = phaseContext.getDeploymentUnit(); String deploymentName = deploymentUnit.getName(); - KeycloakAdapterConfigService service = KeycloakAdapterConfigService.find(phaseContext.getServiceRegistry()); + KeycloakAdapterConfigService service = KeycloakAdapterConfigService.getInstance(); if (!service.isKeycloakServerDeployment(deploymentName)) { return; } From 875aae91fca6227e86902876fa9983a01015a1aa Mon Sep 17 00:00:00 2001 From: Stan Silvert Date: Thu, 9 Apr 2015 14:52:47 -0400 Subject: [PATCH 07/15] Add owner attribute to Keycloak server deployment --- .../subsystem/extension/authserver/AuthServerUtil.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/integration/keycloak-subsystem/src/main/java/org/keycloak/subsystem/extension/authserver/AuthServerUtil.java b/integration/keycloak-subsystem/src/main/java/org/keycloak/subsystem/extension/authserver/AuthServerUtil.java index 9ccef2cd46..bf8074b4e5 100644 --- a/integration/keycloak-subsystem/src/main/java/org/keycloak/subsystem/extension/authserver/AuthServerUtil.java +++ b/integration/keycloak-subsystem/src/main/java/org/keycloak/subsystem/extension/authserver/AuthServerUtil.java @@ -46,6 +46,7 @@ import org.jboss.dmr.ModelNode; import org.jboss.modules.Module; import org.jboss.modules.ModuleIdentifier; import org.jboss.modules.ModuleLoadException; +import org.keycloak.subsystem.extension.KeycloakExtension; /** * Utility methods that help assemble and start an auth server. @@ -105,6 +106,9 @@ public class AuthServerUtil { op.get(ENABLED).set(isEnabled); op.get(PERSISTENT).set(false); // prevents writing this deployment out to standalone.xml + // Owner attribute is valid starting with WidlFly 9. Ignored in WildFly 8 + op.get("owner").set(new ModelNode().add("subsystem", KeycloakExtension.SUBSYSTEM_NAME)); + if (authServerUri == null) { throw new OperationFailedException("Keycloak Auth Server WAR not found in keycloak-subsystem module"); } From 4ae9310f83a333b82bef378d7a27447bcb6ecb41 Mon Sep 17 00:00:00 2001 From: Stian Thorgersen Date: Fri, 10 Apr 2015 09:21:34 +0200 Subject: [PATCH 08/15] KEYCLOAK-1187 DB migration support for oauth/application to client --- .../SetConsentRequiredOnOAuthClients.java | 84 ------------------- .../META-INF/jpa-changelog-1.2.0.RC1.xml | 5 ++ .../impl/DefaultMongoUpdaterProvider.java | 4 +- .../mongo/updater/impl/updates/Update.java | 11 +-- .../impl/updates/Update1_2_0_Beta1.java | 11 +++ .../updater/impl/updates/Update1_2_0_RC1.java | 51 +++++++++++ ...plicationEntity.java => ClientEntity.java} | 12 +-- .../models/file/adapter/ClientAdapter.java | 10 +-- .../models/file/adapter/RealmAdapter.java | 6 +- .../keycloak/models/jpa/ClientAdapter.java | 4 +- .../org/keycloak/models/jpa/RealmAdapter.java | 2 +- .../models/jpa/entities/ClientEntity.java | 14 ++-- .../keycloak/adapters/ClientAdapter.java | 22 ++--- .../keycloak/adapters/MongoRealmProvider.java | 4 +- .../mongo/keycloak/adapters/RealmAdapter.java | 18 ++-- .../mongo/keycloak/adapters/RoleAdapter.java | 6 +- ...tionEntity.java => MongoClientEntity.java} | 8 +- .../keycloak/entities/MongoRealmEntity.java | 2 +- .../keycloak/entities/MongoRoleEntity.java | 6 +- .../models/mongo/utils/MongoModelUtils.java | 4 +- 20 files changed, 131 insertions(+), 153 deletions(-) delete mode 100644 connections/jpa-liquibase/src/main/java/org/keycloak/connections/jpa/updater/liquibase/custom/SetConsentRequiredOnOAuthClients.java create mode 100644 connections/mongo-update/src/main/java/org/keycloak/connections/mongo/updater/impl/updates/Update1_2_0_RC1.java rename model/api/src/main/java/org/keycloak/models/entities/{ApplicationEntity.java => ClientEntity.java} (92%) rename model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/entities/{MongoApplicationEntity.java => MongoClientEntity.java} (71%) diff --git a/connections/jpa-liquibase/src/main/java/org/keycloak/connections/jpa/updater/liquibase/custom/SetConsentRequiredOnOAuthClients.java b/connections/jpa-liquibase/src/main/java/org/keycloak/connections/jpa/updater/liquibase/custom/SetConsentRequiredOnOAuthClients.java deleted file mode 100644 index 6ff8b12e52..0000000000 --- a/connections/jpa-liquibase/src/main/java/org/keycloak/connections/jpa/updater/liquibase/custom/SetConsentRequiredOnOAuthClients.java +++ /dev/null @@ -1,84 +0,0 @@ -package org.keycloak.connections.jpa.updater.liquibase.custom; - -import liquibase.change.custom.CustomSqlChange; -import liquibase.database.Database; -import liquibase.database.jvm.JdbcConnection; -import liquibase.exception.CustomChangeException; -import liquibase.exception.SetupException; -import liquibase.exception.ValidationErrors; -import liquibase.resource.ResourceAccessor; -import liquibase.snapshot.SnapshotGeneratorFactory; -import liquibase.statement.SqlStatement; -import liquibase.statement.core.UpdateStatement; -import liquibase.structure.core.Table; -import org.keycloak.models.utils.KeycloakModelUtils; - -import java.sql.Connection; -import java.sql.ResultSet; -import java.util.ArrayList; - -/** - * @author Stian Thorgersen - */ -public class SetConsentRequiredOnOAuthClients implements CustomSqlChange { - - private String confirmationMessage; - - @Override - public SqlStatement[] generateStatements(Database database) throws CustomChangeException { - try { - StringBuilder sb = new StringBuilder(); - sb.append("Set consent required for: "); - - Connection connection = ((JdbcConnection) (database.getConnection())).getWrappedConnection(); - ArrayList statements = new ArrayList(); - - String correctedTableName = database.correctObjectName("CLIENT", Table.class); - if (SnapshotGeneratorFactory.getInstance().has(new Table().setName(correctedTableName), database)) { - ResultSet resultSet = connection.createStatement().executeQuery("SELECT * FROM CLIENT"); - while (resultSet.next()) { - String id = resultSet.getString(1); - - UpdateStatement statement = new UpdateStatement(null, null, correctedTableName) - .addNewColumnValue("CONSENT_REQUIRED", true) - .setWhereClause("ID='" + id + "'"); - statements.add(statement); - - if (!resultSet.isFirst()) { - sb.append(", "); - } - sb.append(id); - } - - if (!statements.isEmpty()) { - confirmationMessage = sb.toString(); - } - } - - return statements.toArray(new SqlStatement[statements.size()]); - } catch (Exception e) { - throw new CustomChangeException("Failed to add realm code secret", e); - } - } - - @Override - public String getConfirmationMessage() { - return confirmationMessage; - } - - @Override - public void setUp() throws SetupException { - - } - - @Override - public void setFileOpener(ResourceAccessor resourceAccessor) { - - } - - @Override - public ValidationErrors validate(Database database) { - return null; - } - -} diff --git a/connections/jpa-liquibase/src/main/resources/META-INF/jpa-changelog-1.2.0.RC1.xml b/connections/jpa-liquibase/src/main/resources/META-INF/jpa-changelog-1.2.0.RC1.xml index b7349f2231..6fc69db19e 100755 --- a/connections/jpa-liquibase/src/main/resources/META-INF/jpa-changelog-1.2.0.RC1.xml +++ b/connections/jpa-liquibase/src/main/resources/META-INF/jpa-changelog-1.2.0.RC1.xml @@ -42,6 +42,11 @@ + + + DTYPE = 'OAuthClientEntity' + + diff --git a/connections/mongo-update/src/main/java/org/keycloak/connections/mongo/updater/impl/DefaultMongoUpdaterProvider.java b/connections/mongo-update/src/main/java/org/keycloak/connections/mongo/updater/impl/DefaultMongoUpdaterProvider.java index da1d2c02c8..10a13683da 100644 --- a/connections/mongo-update/src/main/java/org/keycloak/connections/mongo/updater/impl/DefaultMongoUpdaterProvider.java +++ b/connections/mongo-update/src/main/java/org/keycloak/connections/mongo/updater/impl/DefaultMongoUpdaterProvider.java @@ -10,6 +10,7 @@ import org.keycloak.connections.mongo.updater.impl.updates.Update; import org.keycloak.connections.mongo.updater.impl.updates.Update1_0_0_Final; import org.keycloak.connections.mongo.updater.impl.updates.Update1_1_0_Beta1; import org.keycloak.connections.mongo.updater.impl.updates.Update1_2_0_Beta1; +import org.keycloak.connections.mongo.updater.impl.updates.Update1_2_0_RC1; import org.keycloak.models.KeycloakSession; import java.util.Date; @@ -28,7 +29,8 @@ public class DefaultMongoUpdaterProvider implements MongoUpdaterProvider { private Class[] updates = new Class[]{ Update1_0_0_Final.class, Update1_1_0_Beta1.class, - Update1_2_0_Beta1.class + Update1_2_0_Beta1.class, + Update1_2_0_RC1.class }; @Override diff --git a/connections/mongo-update/src/main/java/org/keycloak/connections/mongo/updater/impl/updates/Update.java b/connections/mongo-update/src/main/java/org/keycloak/connections/mongo/updater/impl/updates/Update.java index 54e4b706ef..f05e79cc95 100644 --- a/connections/mongo-update/src/main/java/org/keycloak/connections/mongo/updater/impl/updates/Update.java +++ b/connections/mongo-update/src/main/java/org/keycloak/connections/mongo/updater/impl/updates/Update.java @@ -53,15 +53,8 @@ public abstract class Update { log.debugv("Deleted entries from {0}", collection); } - protected String insertApplicationRole(DBCollection roles, String roleName, String applicationId) { - BasicDBObject role = new BasicDBObject(); - String roleId = KeycloakModelUtils.generateId(); - role.append("_id", roleId); - role.append("name", roleName); - role.append("applicationId", applicationId); - role.append("nameIndex", applicationId + "//" + roleName); - roles.insert(role); - return roleId; + protected void renameCollection(String collection, String newName) { + db.getCollection(collection).rename(newName); } public void setLog(Logger log) { diff --git a/connections/mongo-update/src/main/java/org/keycloak/connections/mongo/updater/impl/updates/Update1_2_0_Beta1.java b/connections/mongo-update/src/main/java/org/keycloak/connections/mongo/updater/impl/updates/Update1_2_0_Beta1.java index 349520acb6..abaae4cd42 100644 --- a/connections/mongo-update/src/main/java/org/keycloak/connections/mongo/updater/impl/updates/Update1_2_0_Beta1.java +++ b/connections/mongo-update/src/main/java/org/keycloak/connections/mongo/updater/impl/updates/Update1_2_0_Beta1.java @@ -266,4 +266,15 @@ public class Update1_2_0_Beta1 extends Update { } } + private String insertApplicationRole(DBCollection roles, String roleName, String applicationId) { + BasicDBObject role = new BasicDBObject(); + String roleId = KeycloakModelUtils.generateId(); + role.append("_id", roleId); + role.append("name", roleName); + role.append("applicationId", applicationId); + role.append("nameIndex", applicationId + "//" + roleName); + roles.insert(role); + return roleId; + } + } diff --git a/connections/mongo-update/src/main/java/org/keycloak/connections/mongo/updater/impl/updates/Update1_2_0_RC1.java b/connections/mongo-update/src/main/java/org/keycloak/connections/mongo/updater/impl/updates/Update1_2_0_RC1.java new file mode 100644 index 0000000000..5954199e64 --- /dev/null +++ b/connections/mongo-update/src/main/java/org/keycloak/connections/mongo/updater/impl/updates/Update1_2_0_RC1.java @@ -0,0 +1,51 @@ +package org.keycloak.connections.mongo.updater.impl.updates; + +import com.mongodb.BasicDBObject; +import com.mongodb.DBCollection; +import com.mongodb.DBCursor; +import org.keycloak.models.KeycloakSession; + +/** + * @author Marek Posolda + */ +public class Update1_2_0_RC1 extends Update { + + @Override + public String getId() { + return "1.2.0.RC1"; + } + + @Override + public void update(KeycloakSession session) { + convertApplicationsToClients(); + convertOAuthClientsToClients(); + } + + private void convertApplicationsToClients() { + DBCollection applications = db.getCollection("applications"); + applications.update(new BasicDBObject(), new BasicDBObject("$set", new BasicDBObject("consentRequired", false)), false, true); + applications.update(new BasicDBObject(), new BasicDBObject("$rename", new BasicDBObject("name", "clientId")), false, true); + renameCollection("applications", "clients"); + log.debugv("Converted applications to clients"); + + DBCollection roles = db.getCollection("roles"); + roles.update(new BasicDBObject(), new BasicDBObject("$rename", new BasicDBObject("applicationId", "clientId")), false, true); + log.debugv("Renamed roles.applicationId to roles.clientId"); + } + + private void convertOAuthClientsToClients() { + DBCollection clients = db.getCollection("clients"); + DBCollection oauthClients = db.getCollection("oauthClients"); + oauthClients.update(new BasicDBObject(), new BasicDBObject("$rename", new BasicDBObject("name", "clientId")), false, true); + oauthClients.update(new BasicDBObject(), new BasicDBObject("$set", new BasicDBObject("consentRequired", true)), false, true); + + DBCursor curs = oauthClients.find(); + while (curs.hasNext()) { + clients.insert(curs.next()); + } + + oauthClients.drop(); + log.debugv("Converted oauthClients to clients"); + } + +} diff --git a/model/api/src/main/java/org/keycloak/models/entities/ApplicationEntity.java b/model/api/src/main/java/org/keycloak/models/entities/ClientEntity.java similarity index 92% rename from model/api/src/main/java/org/keycloak/models/entities/ApplicationEntity.java rename to model/api/src/main/java/org/keycloak/models/entities/ClientEntity.java index 4919e5f3c4..699c6d6244 100644 --- a/model/api/src/main/java/org/keycloak/models/entities/ApplicationEntity.java +++ b/model/api/src/main/java/org/keycloak/models/entities/ClientEntity.java @@ -8,9 +8,9 @@ import java.util.Map; /** * @author Marek Posolda */ -public class ApplicationEntity extends AbstractIdentifiableEntity { +public class ClientEntity extends AbstractIdentifiableEntity { - private String name; + private String clientId; private String realmId; private boolean enabled; private String secret; @@ -41,12 +41,12 @@ public class ApplicationEntity extends AbstractIdentifiableEntity { private List identityProviders = new ArrayList(); private List protocolMappers = new ArrayList(); - public String getName() { - return name; + public String getClientId() { + return clientId; } - public void setName(String name) { - this.name = name; + public void setClientId(String clientId) { + this.clientId = clientId; } public boolean isEnabled() { diff --git a/model/file/src/main/java/org/keycloak/models/file/adapter/ClientAdapter.java b/model/file/src/main/java/org/keycloak/models/file/adapter/ClientAdapter.java index ca92129de1..85d9efc9a0 100755 --- a/model/file/src/main/java/org/keycloak/models/file/adapter/ClientAdapter.java +++ b/model/file/src/main/java/org/keycloak/models/file/adapter/ClientAdapter.java @@ -33,7 +33,7 @@ import java.util.Set; import org.keycloak.connections.file.InMemoryModel; import org.keycloak.models.ModelDuplicateException; import org.keycloak.models.UserModel; -import org.keycloak.models.entities.ApplicationEntity; +import org.keycloak.models.entities.ClientEntity; import org.keycloak.models.entities.ClientIdentityProviderMappingEntity; import org.keycloak.models.entities.ProtocolMapperEntity; import org.keycloak.models.entities.RoleEntity; @@ -48,13 +48,13 @@ public class ClientAdapter implements ClientModel { private final RealmModel realm; private KeycloakSession session; - private final ApplicationEntity entity; + private final ClientEntity entity; private final InMemoryModel inMemoryModel; private final Map allRoles = new HashMap(); private final Map allScopeMappings = new HashMap(); - public ClientAdapter(KeycloakSession session, RealmModel realm, ApplicationEntity entity, InMemoryModel inMemoryModel) { + public ClientAdapter(KeycloakSession session, RealmModel realm, ClientEntity entity, InMemoryModel inMemoryModel) { this.realm = realm; this.session = session; this.entity = entity; @@ -406,13 +406,13 @@ public class ClientAdapter implements ClientModel { @Override public String getClientId() { - return entity.getName(); + return entity.getClientId(); } @Override public void setClientId(String clientId) { if (appNameExists(clientId)) throw new ModelDuplicateException("Application named " + clientId + " already exists."); - entity.setName(clientId); + entity.setClientId(clientId); } private boolean appNameExists(String name) { diff --git a/model/file/src/main/java/org/keycloak/models/file/adapter/RealmAdapter.java b/model/file/src/main/java/org/keycloak/models/file/adapter/RealmAdapter.java index 5ae793b48a..57e1620bfc 100755 --- a/model/file/src/main/java/org/keycloak/models/file/adapter/RealmAdapter.java +++ b/model/file/src/main/java/org/keycloak/models/file/adapter/RealmAdapter.java @@ -29,7 +29,7 @@ import org.keycloak.models.RequiredCredentialModel; import org.keycloak.models.RoleModel; import org.keycloak.models.UserFederationProviderModel; import org.keycloak.models.UserModel; -import org.keycloak.models.entities.ApplicationEntity; +import org.keycloak.models.entities.ClientEntity; import org.keycloak.models.entities.IdentityProviderMapperEntity; import org.keycloak.models.entities.RealmEntity; import org.keycloak.models.entities.RequiredCredentialEntity; @@ -626,9 +626,9 @@ public class RealmAdapter implements RealmModel { throw new ModelDuplicateException("Application named '" + clientId + "' already exists."); } - ApplicationEntity appEntity = new ApplicationEntity(); + ClientEntity appEntity = new ClientEntity(); appEntity.setId(id); - appEntity.setName(clientId); + appEntity.setClientId(clientId); appEntity.setRealmId(getId()); appEntity.setEnabled(true); diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/ClientAdapter.java b/model/jpa/src/main/java/org/keycloak/models/jpa/ClientAdapter.java index 4b41921e49..0bf53efaca 100755 --- a/model/jpa/src/main/java/org/keycloak/models/jpa/ClientAdapter.java +++ b/model/jpa/src/main/java/org/keycloak/models/jpa/ClientAdapter.java @@ -475,12 +475,12 @@ public class ClientAdapter implements ClientModel { @Override public String getClientId() { - return entity.getName(); + return entity.getClientId(); } @Override public void setClientId(String clientId) { - entity.setName(clientId); + entity.setClientId(clientId); } @Override diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java b/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java index 251004adcd..2df2bf2b51 100755 --- a/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java +++ b/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java @@ -635,7 +635,7 @@ public class RealmAdapter implements RealmModel { public ClientModel addClient(String id, String clientId) { ClientEntity applicationData = new ClientEntity(); applicationData.setId(id); - applicationData.setName(clientId); + applicationData.setClientId(clientId); applicationData.setEnabled(true); applicationData.setRealm(realm); realm.getApplications().add(applicationData); diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ClientEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ClientEntity.java index a53a0d25aa..f8a25f1832 100755 --- a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ClientEntity.java +++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ClientEntity.java @@ -26,14 +26,14 @@ import java.util.Set; * @version $Revision: 1 $ */ @Entity -@Table(name="CLIENT", uniqueConstraints = {@UniqueConstraint(columnNames = {"REALM_ID", "NAME"})}) +@Table(name="CLIENT", uniqueConstraints = {@UniqueConstraint(columnNames = {"REALM_ID", "CLIENT_ID"})}) public class ClientEntity { @Id @Column(name="ID", length = 36) private String id; - @Column(name = "NAME") - private String name; + @Column(name = "CLIENT_ID") + private String clientId; @Column(name="ENABLED") private boolean enabled; @Column(name="SECRET") @@ -133,12 +133,12 @@ public class ClientEntity { this.enabled = enabled; } - public String getName() { - return name; + public String getClientId() { + return clientId; } - public void setName(String name) { - this.name = name; + public void setClientId(String clientId) { + this.clientId = clientId; } public Set getWebOrigins() { diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/ClientAdapter.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/ClientAdapter.java index adbef6e349..0867ce10b8 100755 --- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/ClientAdapter.java +++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/ClientAdapter.java @@ -11,7 +11,7 @@ import org.keycloak.models.RealmModel; import org.keycloak.models.RoleModel; import org.keycloak.models.entities.ClientIdentityProviderMappingEntity; import org.keycloak.models.entities.ProtocolMapperEntity; -import org.keycloak.models.mongo.keycloak.entities.MongoApplicationEntity; +import org.keycloak.models.mongo.keycloak.entities.MongoClientEntity; import org.keycloak.models.mongo.keycloak.entities.MongoRoleEntity; import org.keycloak.models.mongo.utils.MongoModelUtils; import org.keycloak.models.utils.KeycloakModelUtils; @@ -27,13 +27,13 @@ import java.util.Set; /** * @author Marek Posolda */ -public class ClientAdapter extends AbstractMongoAdapter implements ClientModel { +public class ClientAdapter extends AbstractMongoAdapter implements ClientModel { - protected final MongoApplicationEntity applicationEntity; + protected final MongoClientEntity applicationEntity; private final RealmModel realm; protected KeycloakSession session; - public ClientAdapter(KeycloakSession session, RealmModel realm, MongoApplicationEntity applicationEntity, MongoStoreInvocationContext invContext) { + public ClientAdapter(KeycloakSession session, RealmModel realm, MongoClientEntity applicationEntity, MongoStoreInvocationContext invContext) { super(invContext); this.session = session; this.realm = realm; @@ -41,7 +41,7 @@ public class ClientAdapter extends AbstractMongoAdapter } @Override - public MongoApplicationEntity getMongoEntity() { + public MongoClientEntity getMongoEntity() { return applicationEntity; } @@ -58,12 +58,12 @@ public class ClientAdapter extends AbstractMongoAdapter @Override public String getClientId() { - return getMongoEntity().getName(); + return getMongoEntity().getClientId(); } @Override public void setClientId(String clientId) { - getMongoEntity().setName(clientId); + getMongoEntity().setClientId(clientId); updateMongoEntity(); } @@ -507,7 +507,7 @@ public class ClientAdapter extends AbstractMongoAdapter public RoleAdapter getRole(String name) { DBObject query = new QueryBuilder() .and("name").is(name) - .and("applicationId").is(getId()) + .and("clientId").is(getId()) .get(); MongoRoleEntity role = getMongoStore().loadSingleEntity(MongoRoleEntity.class, query, invocationContext); if (role == null) { @@ -543,7 +543,7 @@ public class ClientAdapter extends AbstractMongoAdapter @Override public Set getRoles() { DBObject query = new QueryBuilder() - .and("applicationId").is(getId()) + .and("clientId").is(getId()) .get(); List roles = getMongoStore().loadEntities(MongoRoleEntity.class, query, invocationContext); @@ -636,7 +636,7 @@ public class ClientAdapter extends AbstractMongoAdapter @Override public void registerNode(String nodeHost, int registrationTime) { - MongoApplicationEntity entity = getMongoEntity(); + MongoClientEntity entity = getMongoEntity(); if (entity.getRegisteredNodes() == null) { entity.setRegisteredNodes(new HashMap()); } @@ -647,7 +647,7 @@ public class ClientAdapter extends AbstractMongoAdapter @Override public void unregisterNode(String nodeHost) { - MongoApplicationEntity entity = getMongoEntity(); + MongoClientEntity entity = getMongoEntity(); if (entity.getRegisteredNodes() == null) return; entity.getRegisteredNodes().remove(nodeHost); diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/MongoRealmProvider.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/MongoRealmProvider.java index 3b5f8a0add..c8bdb389ed 100755 --- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/MongoRealmProvider.java +++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/MongoRealmProvider.java @@ -10,7 +10,7 @@ import org.keycloak.models.KeycloakSession; import org.keycloak.models.RealmModel; import org.keycloak.models.RealmProvider; import org.keycloak.models.RoleModel; -import org.keycloak.models.mongo.keycloak.entities.MongoApplicationEntity; +import org.keycloak.models.mongo.keycloak.entities.MongoClientEntity; import org.keycloak.models.mongo.keycloak.entities.MongoRealmEntity; import org.keycloak.models.mongo.keycloak.entities.MongoRoleEntity; import org.keycloak.models.utils.KeycloakModelUtils; @@ -111,7 +111,7 @@ public class MongoRealmProvider implements RealmProvider { @Override public ClientModel getClientById(String id, RealmModel realm) { - MongoApplicationEntity appData = getMongoStore().loadEntity(MongoApplicationEntity.class, id, invocationContext); + MongoClientEntity appData = getMongoStore().loadEntity(MongoClientEntity.class, id, invocationContext); // Check if application belongs to this realm if (appData == null || !realm.getId().equals(appData.getRealmId())) { diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RealmAdapter.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RealmAdapter.java index dcc73ad182..64b5c41c8c 100755 --- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RealmAdapter.java +++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RealmAdapter.java @@ -18,7 +18,7 @@ import org.keycloak.models.entities.IdentityProviderEntity; import org.keycloak.models.entities.IdentityProviderMapperEntity; import org.keycloak.models.entities.RequiredCredentialEntity; import org.keycloak.models.entities.UserFederationProviderEntity; -import org.keycloak.models.mongo.keycloak.entities.MongoApplicationEntity; +import org.keycloak.models.mongo.keycloak.entities.MongoClientEntity; import org.keycloak.models.mongo.keycloak.entities.MongoRealmEntity; import org.keycloak.models.mongo.keycloak.entities.MongoRoleEntity; import org.keycloak.models.utils.KeycloakModelUtils; @@ -584,9 +584,9 @@ public class RealmAdapter extends AbstractMongoAdapter impleme public ClientModel getClientByClientId(String clientId) { DBObject query = new QueryBuilder() .and("realmId").is(getId()) - .and("name").is(clientId) + .and("clientId").is(clientId) .get(); - MongoApplicationEntity appEntity = getMongoStore().loadSingleEntity(MongoApplicationEntity.class, query, invocationContext); + MongoClientEntity appEntity = getMongoStore().loadSingleEntity(MongoClientEntity.class, query, invocationContext); return appEntity == null ? null : new ClientAdapter(session, this, appEntity, invocationContext); } @@ -604,10 +604,10 @@ public class RealmAdapter extends AbstractMongoAdapter impleme DBObject query = new QueryBuilder() .and("realmId").is(getId()) .get(); - List appDatas = getMongoStore().loadEntities(MongoApplicationEntity.class, query, invocationContext); + List appDatas = getMongoStore().loadEntities(MongoClientEntity.class, query, invocationContext); List result = new ArrayList(); - for (MongoApplicationEntity appData : appDatas) { + for (MongoClientEntity appData : appDatas) { result.add(new ClientAdapter(session, this, appData, invocationContext)); } return result; @@ -620,9 +620,9 @@ public class RealmAdapter extends AbstractMongoAdapter impleme @Override public ClientModel addClient(String id, String clientId) { - MongoApplicationEntity appData = new MongoApplicationEntity(); + MongoClientEntity appData = new MongoClientEntity(); appData.setId(id); - appData.setName(clientId); + appData.setClientId(clientId); appData.setRealmId(getId()); appData.setEnabled(true); getMongoStore().insertEntity(appData, invocationContext); @@ -639,7 +639,7 @@ public class RealmAdapter extends AbstractMongoAdapter impleme @Override public boolean removeClient(String id) { - return getMongoStore().removeEntity(MongoApplicationEntity.class, id, invocationContext); + return getMongoStore().removeEntity(MongoClientEntity.class, id, invocationContext); } @Override @@ -979,7 +979,7 @@ public class RealmAdapter extends AbstractMongoAdapter impleme @Override public ClientModel getMasterAdminApp() { - MongoApplicationEntity appData = getMongoStore().loadEntity(MongoApplicationEntity.class, realm.getAdminAppId(), invocationContext); + MongoClientEntity appData = getMongoStore().loadEntity(MongoClientEntity.class, realm.getAdminAppId(), invocationContext); return appData != null ? new ClientAdapter(session, this, appData, invocationContext) : null; } diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RoleAdapter.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RoleAdapter.java index b38410ee81..91ef361da2 100755 --- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RoleAdapter.java +++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RoleAdapter.java @@ -7,7 +7,7 @@ import org.keycloak.models.KeycloakSession; import org.keycloak.models.RealmModel; import org.keycloak.models.RoleContainerModel; import org.keycloak.models.RoleModel; -import org.keycloak.models.mongo.keycloak.entities.MongoApplicationEntity; +import org.keycloak.models.mongo.keycloak.entities.MongoClientEntity; import org.keycloak.models.mongo.keycloak.entities.MongoRealmEntity; import org.keycloak.models.mongo.keycloak.entities.MongoRoleEntity; import org.keycloak.models.utils.KeycloakModelUtils; @@ -116,13 +116,13 @@ public class RoleAdapter extends AbstractMongoAdapter implement } roleContainer = new RealmAdapter(session, realm, invocationContext); } else if (role.getClientId() != null) { - MongoApplicationEntity appEntity = getMongoStore().loadEntity(MongoApplicationEntity.class, role.getClientId(), invocationContext); + MongoClientEntity appEntity = getMongoStore().loadEntity(MongoClientEntity.class, role.getClientId(), invocationContext); if (appEntity == null) { throw new IllegalStateException("Application with id: " + role.getClientId() + " doesn't exists"); } roleContainer = new ClientAdapter(session, realm, appEntity, invocationContext); } else { - throw new IllegalStateException("Both realmId and applicationId are null for role: " + this); + throw new IllegalStateException("Both realmId and clientId are null for role: " + this); } } return roleContainer; diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/entities/MongoApplicationEntity.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/entities/MongoClientEntity.java similarity index 71% rename from model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/entities/MongoApplicationEntity.java rename to model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/entities/MongoClientEntity.java index 7534e66fb0..cc97d5d992 100755 --- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/entities/MongoApplicationEntity.java +++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/entities/MongoClientEntity.java @@ -5,19 +5,19 @@ import com.mongodb.QueryBuilder; import org.keycloak.connections.mongo.api.MongoCollection; import org.keycloak.connections.mongo.api.MongoIdentifiableEntity; import org.keycloak.connections.mongo.api.context.MongoStoreInvocationContext; -import org.keycloak.models.entities.ApplicationEntity; +import org.keycloak.models.entities.ClientEntity; /** * @author Marek Posolda */ -@MongoCollection(collectionName = "applications") -public class MongoApplicationEntity extends ApplicationEntity implements MongoIdentifiableEntity { +@MongoCollection(collectionName = "clients") +public class MongoClientEntity extends ClientEntity implements MongoIdentifiableEntity { @Override public void afterRemove(MongoStoreInvocationContext context) { // Remove all roles, which belongs to this application DBObject query = new QueryBuilder() - .and("applicationId").is(getId()) + .and("clientId").is(getId()) .get(); context.getMongoStore().removeEntities(MongoRoleEntity.class, query, context); } diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/entities/MongoRealmEntity.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/entities/MongoRealmEntity.java index d873ea20ba..22097514fb 100755 --- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/entities/MongoRealmEntity.java +++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/entities/MongoRealmEntity.java @@ -26,6 +26,6 @@ public class MongoRealmEntity extends RealmEntity implements MongoIdentifiableEn context.getMongoStore().removeEntities(MongoRoleEntity.class, query, context); // Remove all applications of this realm - context.getMongoStore().removeEntities(MongoApplicationEntity.class, query, context); + context.getMongoStore().removeEntities(MongoClientEntity.class, query, context); } } diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/entities/MongoRoleEntity.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/entities/MongoRoleEntity.java index a889670baf..dc820c25f8 100755 --- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/entities/MongoRoleEntity.java +++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/entities/MongoRoleEntity.java @@ -24,13 +24,13 @@ public class MongoRoleEntity extends RoleEntity implements MongoIdentifiableEnti // TODO This is required as Mongo doesn't support sparse indexes with compound keys (see https://jira.mongodb.org/browse/SERVER-2193) public String getNameIndex() { String realmId = getRealmId(); - String applicationId = getClientId(); + String clientId = getClientId(); String name = getName(); if (realmId != null) { return realmId + "//" + name; } else { - return applicationId + "//" + name; + return clientId + "//" + name; } } @@ -75,7 +75,7 @@ public class MongoRoleEntity extends RoleEntity implements MongoIdentifiableEnti // Remove defaultRoles from application if (getClientId() != null) { - MongoApplicationEntity appEntity = mongoStore.loadEntity(MongoApplicationEntity.class, getClientId(), invContext); + MongoClientEntity appEntity = mongoStore.loadEntity(MongoClientEntity.class, getClientId(), invContext); // Application might be already removed at this point if (appEntity != null) { diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/utils/MongoModelUtils.java b/model/mongo/src/main/java/org/keycloak/models/mongo/utils/MongoModelUtils.java index 641d4698bb..48828deecb 100755 --- a/model/mongo/src/main/java/org/keycloak/models/mongo/utils/MongoModelUtils.java +++ b/model/mongo/src/main/java/org/keycloak/models/mongo/utils/MongoModelUtils.java @@ -5,7 +5,7 @@ import com.mongodb.QueryBuilder; import org.keycloak.connections.mongo.api.context.MongoStoreInvocationContext; import org.keycloak.models.ClientModel; import org.keycloak.models.UserModel; -import org.keycloak.models.entities.ApplicationEntity; +import org.keycloak.models.entities.ClientEntity; import org.keycloak.models.mongo.keycloak.adapters.ClientAdapter; import org.keycloak.models.mongo.keycloak.adapters.UserAdapter; import org.keycloak.models.mongo.keycloak.entities.MongoRoleEntity; @@ -36,7 +36,7 @@ public class MongoModelUtils { // Get everything including both application and realm scopes public static List getAllScopesOfClient(ClientModel client, MongoStoreInvocationContext invContext) { - ApplicationEntity scopedEntity = ((ClientAdapter)client).getMongoEntity(); + ClientEntity scopedEntity = ((ClientAdapter)client).getMongoEntity(); List scopeIds = scopedEntity.getScopeIds(); if (scopeIds == null || scopeIds.isEmpty()) { From a18715a7742d4f5712b518ce6d1641304669360d Mon Sep 17 00:00:00 2001 From: Stian Thorgersen Date: Fri, 10 Apr 2015 13:33:29 +0200 Subject: [PATCH 09/15] Deprecate OAuthClientRepresentation and ApplicationRepresentation and added ClientRepresentation --- .../idm/ApplicationRepresentation.java | 204 +-------------- .../idm/ClientRepresentation.java | 218 ++++++++++++++++ .../idm/OAuthClientRepresentation.java | 152 +---------- .../idm/RealmRepresentation.java | 19 +- .../admin-client/src/main/webapp/index.jsp | 4 +- .../exportimport/util/ExportUtils.java | 30 +-- .../exportimport/util/ImportUtils.java | 2 +- ...ationResource.java => ClientResource.java} | 7 +- ...ionsResource.java => ClientsResource.java} | 7 +- .../admin/client/resource/RealmResource.java | 2 +- .../models/utils/KeycloakModelUtils.java | 2 +- .../models/utils/ModelToRepresentation.java | 15 +- .../models/utils/RepresentationToModel.java | 245 +++++++----------- ...icationManager.java => ClientManager.java} | 28 +- .../services/managers/RealmManager.java | 10 +- .../managers/ResourceAdminManager.java | 2 +- .../resources/admin/AdminConsole.java | 6 +- ...ationResource.java => ClientResource.java} | 69 ++--- ...Resource.java => ClientsByIdResource.java} | 8 +- ...ionsResource.java => ClientsResource.java} | 43 ++- .../resources/admin/RealmAdminResource.java | 12 +- .../adapter/AdapterTestStrategy.java | 2 +- .../testsuite/admin/AbstractClientTest.java | 7 +- .../testsuite/admin/AdminAPITest.java | 18 +- .../{ApplicationTest.java => ClientTest.java} | 60 ++--- .../composites/CompositeRoleTest.java | 10 +- .../testsuite/model/ClientModelTest.java | 56 ++-- 27 files changed, 527 insertions(+), 711 deletions(-) create mode 100755 core/src/main/java/org/keycloak/representations/idm/ClientRepresentation.java rename integration/admin-client/src/main/java/org/keycloak/admin/client/resource/{ApplicationResource.java => ClientResource.java} (92%) rename integration/admin-client/src/main/java/org/keycloak/admin/client/resource/{ApplicationsResource.java => ClientsResource.java} (71%) rename services/src/main/java/org/keycloak/services/managers/{ApplicationManager.java => ClientManager.java} (85%) rename services/src/main/java/org/keycloak/services/resources/admin/{ApplicationResource.java => ClientResource.java} (80%) rename services/src/main/java/org/keycloak/services/resources/admin/{ApplicationsByIdResource.java => ClientsByIdResource.java} (56%) rename services/src/main/java/org/keycloak/services/resources/admin/{ApplicationsResource.java => ClientsResource.java} (60%) rename testsuite/integration/src/test/java/org/keycloak/testsuite/admin/{ApplicationTest.java => ClientTest.java} (70%) diff --git a/core/src/main/java/org/keycloak/representations/idm/ApplicationRepresentation.java b/core/src/main/java/org/keycloak/representations/idm/ApplicationRepresentation.java index 8f38e4b37c..cc9b657083 100755 --- a/core/src/main/java/org/keycloak/representations/idm/ApplicationRepresentation.java +++ b/core/src/main/java/org/keycloak/representations/idm/ApplicationRepresentation.java @@ -1,46 +1,14 @@ package org.keycloak.representations.idm; -import java.util.List; -import java.util.Map; - /** * @author Bill Burke * @version $Revision: 1 $ */ -public class ApplicationRepresentation { - protected String id; +@Deprecated +public class ApplicationRepresentation extends ClientRepresentation { protected String name; - protected String adminUrl; - protected String baseUrl; - protected Boolean surrogateAuthRequired; - protected Boolean enabled; - protected String secret; - protected String[] defaultRoles; - protected List redirectUris; - protected List webOrigins; @Deprecated protected ClaimRepresentation claims; - protected Integer notBefore; - protected Boolean bearerOnly; - protected Boolean consentRequired; - protected Boolean directGrantsOnly; - protected Boolean publicClient; - protected Boolean frontchannelLogout; - protected String protocol; - protected Map attributes; - protected Boolean fullScopeAllowed; - protected Integer nodeReRegistrationTimeout; - protected Map registeredNodes; - protected List identityProviders; - protected List protocolMappers; - - public String getId() { - return id; - } - - public void setId(String id) { - this.id = id; - } public String getName() { return name; @@ -50,70 +18,6 @@ public class ApplicationRepresentation { this.name = name; } - public Boolean isEnabled() { - return enabled; - } - - public void setEnabled(Boolean enabled) { - this.enabled = enabled; - } - - public Boolean isSurrogateAuthRequired() { - return surrogateAuthRequired; - } - - public void setSurrogateAuthRequired(Boolean surrogateAuthRequired) { - this.surrogateAuthRequired = surrogateAuthRequired; - } - - public String getAdminUrl() { - return adminUrl; - } - - public void setAdminUrl(String adminUrl) { - this.adminUrl = adminUrl; - } - - public String getBaseUrl() { - return baseUrl; - } - - public void setBaseUrl(String baseUrl) { - this.baseUrl = baseUrl; - } - - public String getSecret() { - return secret; - } - - public void setSecret(String secret) { - this.secret = secret; - } - - public List getRedirectUris() { - return redirectUris; - } - - public void setRedirectUris(List redirectUris) { - this.redirectUris = redirectUris; - } - - public List getWebOrigins() { - return webOrigins; - } - - public void setWebOrigins(List webOrigins) { - this.webOrigins = webOrigins; - } - - public String[] getDefaultRoles() { - return defaultRoles; - } - - public void setDefaultRoles(String[] defaultRoles) { - this.defaultRoles = defaultRoles; - } - public ClaimRepresentation getClaims() { return claims; } @@ -121,108 +25,4 @@ public class ApplicationRepresentation { public void setClaims(ClaimRepresentation claims) { this.claims = claims; } - - public Integer getNotBefore() { - return notBefore; - } - - public void setNotBefore(Integer notBefore) { - this.notBefore = notBefore; - } - - public Boolean isBearerOnly() { - return bearerOnly; - } - - public void setBearerOnly(Boolean bearerOnly) { - this.bearerOnly = bearerOnly; - } - - public Boolean isConsentRequired() { - return consentRequired; - } - - public void setConsentRequired(Boolean consentRequired) { - this.consentRequired = consentRequired; - } - - public Boolean getDirectGrantsOnly() { - return directGrantsOnly; - } - - public void setDirectGrantsOnly(Boolean directGrantsOnly) { - this.directGrantsOnly = directGrantsOnly; - } - - public Boolean isPublicClient() { - return publicClient; - } - - public void setPublicClient(Boolean publicClient) { - this.publicClient = publicClient; - } - - public Boolean isFullScopeAllowed() { - return fullScopeAllowed; - } - - public void setFullScopeAllowed(Boolean fullScopeAllowed) { - this.fullScopeAllowed = fullScopeAllowed; - } - - public String getProtocol() { - return protocol; - } - - public void setProtocol(String protocol) { - this.protocol = protocol; - } - - public Map getAttributes() { - return attributes; - } - - public void setAttributes(Map attributes) { - this.attributes = attributes; - } - - public Integer getNodeReRegistrationTimeout() { - return nodeReRegistrationTimeout; - } - - public void setNodeReRegistrationTimeout(Integer nodeReRegistrationTimeout) { - this.nodeReRegistrationTimeout = nodeReRegistrationTimeout; - } - - public Map getRegisteredNodes() { - return registeredNodes; - } - - public void setRegisteredNodes(Map registeredNodes) { - this.registeredNodes = registeredNodes; - } - - public Boolean isFrontchannelLogout() { - return frontchannelLogout; - } - - public void setFrontchannelLogout(Boolean frontchannelLogout) { - this.frontchannelLogout = frontchannelLogout; - } - - public List getIdentityProviders() { - return this.identityProviders; - } - - public void setIdentityProviders(List identityProviders) { - this.identityProviders = identityProviders; - } - - public List getProtocolMappers() { - return protocolMappers; - } - - public void setProtocolMappers(List protocolMappers) { - this.protocolMappers = protocolMappers; - } } diff --git a/core/src/main/java/org/keycloak/representations/idm/ClientRepresentation.java b/core/src/main/java/org/keycloak/representations/idm/ClientRepresentation.java new file mode 100755 index 0000000000..de40f101ca --- /dev/null +++ b/core/src/main/java/org/keycloak/representations/idm/ClientRepresentation.java @@ -0,0 +1,218 @@ +package org.keycloak.representations.idm; + +import java.util.List; +import java.util.Map; + +/** + * @author Bill Burke + * @version $Revision: 1 $ + */ +public class ClientRepresentation { + protected String id; + protected String clientId; + protected String adminUrl; + protected String baseUrl; + protected Boolean surrogateAuthRequired; + protected Boolean enabled; + protected String secret; + protected String[] defaultRoles; + protected List redirectUris; + protected List webOrigins; + protected Integer notBefore; + protected Boolean bearerOnly; + protected Boolean consentRequired; + protected Boolean directGrantsOnly; + protected Boolean publicClient; + protected Boolean frontchannelLogout; + protected String protocol; + protected Map attributes; + protected Boolean fullScopeAllowed; + protected Integer nodeReRegistrationTimeout; + protected Map registeredNodes; + protected List identityProviders; + protected List protocolMappers; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getClientId() { + return clientId; + } + + public void setClientId(String clientId) { + this.clientId = clientId; + } + + public Boolean isEnabled() { + return enabled; + } + + public void setEnabled(Boolean enabled) { + this.enabled = enabled; + } + + public Boolean isSurrogateAuthRequired() { + return surrogateAuthRequired; + } + + public void setSurrogateAuthRequired(Boolean surrogateAuthRequired) { + this.surrogateAuthRequired = surrogateAuthRequired; + } + + public String getAdminUrl() { + return adminUrl; + } + + public void setAdminUrl(String adminUrl) { + this.adminUrl = adminUrl; + } + + public String getBaseUrl() { + return baseUrl; + } + + public void setBaseUrl(String baseUrl) { + this.baseUrl = baseUrl; + } + + public String getSecret() { + return secret; + } + + public void setSecret(String secret) { + this.secret = secret; + } + + public List getRedirectUris() { + return redirectUris; + } + + public void setRedirectUris(List redirectUris) { + this.redirectUris = redirectUris; + } + + public List getWebOrigins() { + return webOrigins; + } + + public void setWebOrigins(List webOrigins) { + this.webOrigins = webOrigins; + } + + public String[] getDefaultRoles() { + return defaultRoles; + } + + public void setDefaultRoles(String[] defaultRoles) { + this.defaultRoles = defaultRoles; + } + + public Integer getNotBefore() { + return notBefore; + } + + public void setNotBefore(Integer notBefore) { + this.notBefore = notBefore; + } + + public Boolean isBearerOnly() { + return bearerOnly; + } + + public void setBearerOnly(Boolean bearerOnly) { + this.bearerOnly = bearerOnly; + } + + public Boolean isConsentRequired() { + return consentRequired; + } + + public void setConsentRequired(Boolean consentRequired) { + this.consentRequired = consentRequired; + } + + public Boolean getDirectGrantsOnly() { + return directGrantsOnly; + } + + public void setDirectGrantsOnly(Boolean directGrantsOnly) { + this.directGrantsOnly = directGrantsOnly; + } + + public Boolean isPublicClient() { + return publicClient; + } + + public void setPublicClient(Boolean publicClient) { + this.publicClient = publicClient; + } + + public Boolean isFullScopeAllowed() { + return fullScopeAllowed; + } + + public void setFullScopeAllowed(Boolean fullScopeAllowed) { + this.fullScopeAllowed = fullScopeAllowed; + } + + public String getProtocol() { + return protocol; + } + + public void setProtocol(String protocol) { + this.protocol = protocol; + } + + public Map getAttributes() { + return attributes; + } + + public void setAttributes(Map attributes) { + this.attributes = attributes; + } + + public Integer getNodeReRegistrationTimeout() { + return nodeReRegistrationTimeout; + } + + public void setNodeReRegistrationTimeout(Integer nodeReRegistrationTimeout) { + this.nodeReRegistrationTimeout = nodeReRegistrationTimeout; + } + + public Map getRegisteredNodes() { + return registeredNodes; + } + + public void setRegisteredNodes(Map registeredNodes) { + this.registeredNodes = registeredNodes; + } + + public Boolean isFrontchannelLogout() { + return frontchannelLogout; + } + + public void setFrontchannelLogout(Boolean frontchannelLogout) { + this.frontchannelLogout = frontchannelLogout; + } + + public List getIdentityProviders() { + return this.identityProviders; + } + + public void setIdentityProviders(List identityProviders) { + this.identityProviders = identityProviders; + } + + public List getProtocolMappers() { + return protocolMappers; + } + + public void setProtocolMappers(List protocolMappers) { + this.protocolMappers = protocolMappers; + } +} diff --git a/core/src/main/java/org/keycloak/representations/idm/OAuthClientRepresentation.java b/core/src/main/java/org/keycloak/representations/idm/OAuthClientRepresentation.java index 5f0ed4e3b0..9eec3e9d30 100755 --- a/core/src/main/java/org/keycloak/representations/idm/OAuthClientRepresentation.java +++ b/core/src/main/java/org/keycloak/representations/idm/OAuthClientRepresentation.java @@ -1,157 +1,9 @@ package org.keycloak.representations.idm; -import java.util.List; -import java.util.Map; - /** * @author Bill Burke * @version $Revision: 1 $ */ -public class OAuthClientRepresentation { - protected String id; - protected String name; - protected List redirectUris; - protected List webOrigins; - protected Boolean enabled; - protected String secret; - @Deprecated - protected ClaimRepresentation claims; - protected Integer notBefore; - protected Boolean publicClient; - protected String protocol; - protected Map attributes; - protected Boolean directGrantsOnly; - protected Boolean fullScopeAllowed; - protected Boolean frontchannelLogout; - protected List protocolMappers; - private List identityProviders; - - - public String getId() { - return id; - } - - public void setId(String id) { - this.id = id; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public Boolean isEnabled() { - return enabled; - } - - public void setEnabled(Boolean enabled) { - this.enabled = enabled; - } - - public List getRedirectUris() { - return redirectUris; - } - - public void setRedirectUris(List redirectUris) { - this.redirectUris = redirectUris; - } - - public List getWebOrigins() { - return webOrigins; - } - - public void setWebOrigins(List webOrigins) { - this.webOrigins = webOrigins; - } - - public String getSecret() { - return secret; - } - - public void setSecret(String secret) { - this.secret = secret; - } - - public ClaimRepresentation getClaims() { - return claims; - } - - public void setClaims(ClaimRepresentation claims) { - this.claims = claims; - } - - public Integer getNotBefore() { - return notBefore; - } - - public void setNotBefore(Integer notBefore) { - this.notBefore = notBefore; - } - - public Boolean isPublicClient() { - return publicClient; - } - - public void setPublicClient(Boolean publicClient) { - this.publicClient = publicClient; - } - - public Boolean isDirectGrantsOnly() { - return directGrantsOnly; - } - - public void setDirectGrantsOnly(Boolean directGrantsOnly) { - this.directGrantsOnly = directGrantsOnly; - } - - public Boolean isFullScopeAllowed() { - return fullScopeAllowed; - } - - public void setFullScopeAllowed(Boolean fullScopeAllowed) { - this.fullScopeAllowed = fullScopeAllowed; - } - - public String getProtocol() { - return protocol; - } - - public void setProtocol(String protocol) { - this.protocol = protocol; - } - - public Map getAttributes() { - return attributes; - } - - public void setAttributes(Map attributes) { - this.attributes = attributes; - } - - public Boolean isFrontchannelLogout() { - return frontchannelLogout; - } - - public void setFrontchannelLogout(Boolean frontchannelLogout) { - this.frontchannelLogout = frontchannelLogout; - } - - public List getIdentityProviders() { - return this.identityProviders; - } - - public void setIdentityProviders(List identityProviders) { - this.identityProviders = identityProviders; - } - - public List getProtocolMappers() { - return protocolMappers; - } - - public void setProtocolMappers(List protocolMappers) { - this.protocolMappers = protocolMappers; - } +@Deprecated +public class OAuthClientRepresentation extends ApplicationRepresentation { } diff --git a/core/src/main/java/org/keycloak/representations/idm/RealmRepresentation.java b/core/src/main/java/org/keycloak/representations/idm/RealmRepresentation.java index b350e3825a..aad60685ed 100755 --- a/core/src/main/java/org/keycloak/representations/idm/RealmRepresentation.java +++ b/core/src/main/java/org/keycloak/representations/idm/RealmRepresentation.java @@ -56,7 +56,10 @@ public class RealmRepresentation { protected List users; protected List scopeMappings; protected Map> applicationScopeMappings; + protected List clients; + @Deprecated protected List applications; + @Deprecated protected List oauthClients; protected Map browserSecurityHeaders; protected Map smtpServer; @@ -101,14 +104,6 @@ public class RealmRepresentation { return applications; } - public ApplicationRepresentation resource(String name) { - ApplicationRepresentation resource = new ApplicationRepresentation(); - if (applications == null) applications = new ArrayList(); - applications.add(resource); - resource.setName(name); - return resource; - } - public void setUsers(List users) { this.users = users; } @@ -121,6 +116,14 @@ public class RealmRepresentation { return user; } + public List getClients() { + return clients; + } + + public void setClients(List clients) { + this.clients = clients; + } + public void setApplications(List applications) { this.applications = applications; } diff --git a/examples/admin-client/src/main/webapp/index.jsp b/examples/admin-client/src/main/webapp/index.jsp index 13b6eee183..980f1962ec 100644 --- a/examples/admin-client/src/main/webapp/index.jsp +++ b/examples/admin-client/src/main/webapp/index.jsp @@ -1,5 +1,5 @@ <%@ page import="org.keycloak.admin.client.Keycloak" %> -<%@ page import="org.keycloak.admin.client.resource.ApplicationsResource" %> +<%@ page import="org.keycloak.admin.client.resource.ClientsResource" %> <%@ page import="org.keycloak.representations.idm.ApplicationRepresentation" %> <%@ page import="org.keycloak.util.UriUtils" %> <%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1" %> @@ -13,7 +13,7 @@ String authServer = UriUtils.getOrigin(request.getRequestURL().toString()) + "/auth"; Keycloak keycloak = Keycloak.getInstance(authServer, "example", "examples-admin-client", "password", "examples-admin-client", "password"); - ApplicationsResource applications = keycloak.realm("example").applications(); + ClientsResource applications = keycloak.realm("example").applications(); out.println("

    Applications

    "); out.println("
      "); diff --git a/export-import/export-import-api/src/main/java/org/keycloak/exportimport/util/ExportUtils.java b/export-import/export-import-api/src/main/java/org/keycloak/exportimport/util/ExportUtils.java index 787f8ca20e..43d1f6b889 100755 --- a/export-import/export-import-api/src/main/java/org/keycloak/exportimport/util/ExportUtils.java +++ b/export-import/export-import-api/src/main/java/org/keycloak/exportimport/util/ExportUtils.java @@ -16,6 +16,7 @@ import org.keycloak.models.UserCredentialValueModel; import org.keycloak.models.UserModel; import org.keycloak.models.utils.ModelToRepresentation; import org.keycloak.representations.idm.ApplicationRepresentation; +import org.keycloak.representations.idm.ClientRepresentation; import org.keycloak.representations.idm.CredentialRepresentation; import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.representations.idm.RoleRepresentation; @@ -53,14 +54,14 @@ public class ExportUtils { rep.setEventsListeners(new LinkedList(realm.getEventsListeners())); } - // Applications - List applications = realm.getClients(); - List appReps = new ArrayList(); - for (ClientModel app : applications) { - ApplicationRepresentation appRep = exportApplication(app); - appReps.add(appRep); + // Clients + List clients = realm.getClients(); + List clientReps = new ArrayList<>(); + for (ClientModel app : clients) { + ClientRepresentation clientRep = exportClient(app); + clientReps.add(clientRep); } - rep.setApplications(appReps); + rep.setClients(clientReps); // Roles List realmRoleReps = null; @@ -70,7 +71,7 @@ public class ExportUtils { if (realmRoles != null && realmRoles.size() > 0) { realmRoleReps = exportRoles(realmRoles); } - for (ClientModel app : applications) { + for (ClientModel app : clients) { Set currentAppRoles = app.getRoles(); List currentAppRoleReps = exportRoles(currentAppRoles); appRolesReps.put(app.getClientId(), currentAppRoleReps); @@ -86,7 +87,7 @@ public class ExportUtils { rep.setRoles(rolesRep); // Scopes - List allClients = new ArrayList<>(applications); + List allClients = new ArrayList<>(clients); Map> appScopeReps = new HashMap<>(); for (ClientModel client : allClients) { @@ -147,14 +148,13 @@ public class ExportUtils { /** * Full export of application including claims and secret - * @param app + * @param client * @return full ApplicationRepresentation */ - public static ApplicationRepresentation exportApplication(ClientModel app) { - ApplicationRepresentation appRep = ModelToRepresentation.toRepresentation(app); - - appRep.setSecret(app.getSecret()); - return appRep; + public static ClientRepresentation exportClient(ClientModel client) { + ClientRepresentation clientRep = ModelToRepresentation.toRepresentation(client); + clientRep.setSecret(client.getSecret()); + return clientRep; } public static List exportRoles(Collection roles) { diff --git a/export-import/export-import-api/src/main/java/org/keycloak/exportimport/util/ImportUtils.java b/export-import/export-import-api/src/main/java/org/keycloak/exportimport/util/ImportUtils.java index 3bf9d4645c..b109dc3558 100755 --- a/export-import/export-import-api/src/main/java/org/keycloak/exportimport/util/ImportUtils.java +++ b/export-import/export-import-api/src/main/java/org/keycloak/exportimport/util/ImportUtils.java @@ -119,7 +119,7 @@ public class ImportUtils { } adminRole.setDescription("${role_"+AdminRoles.ADMIN+"}"); - ClientModel realmAdminApp = KeycloakModelUtils.createApplication(adminRealm, KeycloakModelUtils.getMasterRealmAdminApplicationName(realm)); + ClientModel realmAdminApp = KeycloakModelUtils.createClient(adminRealm, KeycloakModelUtils.getMasterRealmAdminApplicationName(realm)); realmAdminApp.setBearerOnly(true); realm.setMasterAdminApp(realmAdminApp); diff --git a/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/ApplicationResource.java b/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/ClientResource.java similarity index 92% rename from integration/admin-client/src/main/java/org/keycloak/admin/client/resource/ApplicationResource.java rename to integration/admin-client/src/main/java/org/keycloak/admin/client/resource/ClientResource.java index 2601d5328a..0bc8ad70a6 100755 --- a/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/ApplicationResource.java +++ b/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/ClientResource.java @@ -1,6 +1,7 @@ package org.keycloak.admin.client.resource; import org.keycloak.representations.idm.ApplicationRepresentation; +import org.keycloak.representations.idm.ClientRepresentation; import org.keycloak.representations.idm.CredentialRepresentation; import org.keycloak.representations.idm.UserSessionRepresentation; @@ -21,18 +22,18 @@ import java.util.Set; /** * @author rodrigo.sasaki@icarros.com.br */ -public interface ApplicationResource { +public interface ClientResource { @Path("protocol-mappers") public ProtocolMappersResource getProtocolMappers(); @GET @Produces(MediaType.APPLICATION_JSON) - public ApplicationRepresentation toRepresentation(); + public ClientRepresentation toRepresentation(); @PUT @Consumes(MediaType.APPLICATION_JSON) - public void update(ApplicationRepresentation applicationRepresentation); + public void update(ClientRepresentation clientRepresentation); @DELETE public void remove(); diff --git a/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/ApplicationsResource.java b/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/ClientsResource.java similarity index 71% rename from integration/admin-client/src/main/java/org/keycloak/admin/client/resource/ApplicationsResource.java rename to integration/admin-client/src/main/java/org/keycloak/admin/client/resource/ClientsResource.java index 6ccbdd8643..abc94243a4 100755 --- a/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/ApplicationsResource.java +++ b/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/ClientsResource.java @@ -1,6 +1,7 @@ package org.keycloak.admin.client.resource; import org.keycloak.representations.idm.ApplicationRepresentation; +import org.keycloak.representations.idm.ClientRepresentation; import javax.ws.rs.Consumes; import javax.ws.rs.GET; @@ -14,14 +15,14 @@ import java.util.List; /** * @author rodrigo.sasaki@icarros.com.br */ -public interface ApplicationsResource { +public interface ClientsResource { @Path("{appName}") - public ApplicationResource get(@PathParam("appName") String appName); + public ClientResource get(@PathParam("appName") String appName); @POST @Consumes(MediaType.APPLICATION_JSON) - public void create(ApplicationRepresentation applicationRepresentation); + public void create(ClientRepresentation clientRepresentation); @GET @Produces(MediaType.APPLICATION_JSON) diff --git a/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/RealmResource.java b/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/RealmResource.java index b40cc13806..8cd1d90d5c 100644 --- a/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/RealmResource.java +++ b/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/RealmResource.java @@ -24,7 +24,7 @@ public interface RealmResource { public void update(RealmRepresentation realmRepresentation); @Path("applications") - public ApplicationsResource applications(); + public ClientsResource clients(); @Path("users") public UsersResource users(); diff --git a/model/api/src/main/java/org/keycloak/models/utils/KeycloakModelUtils.java b/model/api/src/main/java/org/keycloak/models/utils/KeycloakModelUtils.java index 71d9ae7008..bd03cac67e 100755 --- a/model/api/src/main/java/org/keycloak/models/utils/KeycloakModelUtils.java +++ b/model/api/src/main/java/org/keycloak/models/utils/KeycloakModelUtils.java @@ -172,7 +172,7 @@ public final class KeycloakModelUtils { return UUID.randomUUID().toString(); } - public static ClientModel createApplication(RealmModel realm, String name) { + public static ClientModel createClient(RealmModel realm, String name) { ClientModel app = realm.addClient(name); generateSecret(app); app.setFullScopeAllowed(true); diff --git a/model/api/src/main/java/org/keycloak/models/utils/ModelToRepresentation.java b/model/api/src/main/java/org/keycloak/models/utils/ModelToRepresentation.java index 09fc0a569e..f9e3556d77 100755 --- a/model/api/src/main/java/org/keycloak/models/utils/ModelToRepresentation.java +++ b/model/api/src/main/java/org/keycloak/models/utils/ModelToRepresentation.java @@ -15,6 +15,7 @@ import org.keycloak.models.UserModel; import org.keycloak.models.UserSessionModel; import org.keycloak.representations.idm.ApplicationRepresentation; import org.keycloak.representations.idm.ClientIdentityProviderMappingRepresentation; +import org.keycloak.representations.idm.ClientRepresentation; import org.keycloak.representations.idm.CredentialRepresentation; import org.keycloak.representations.idm.FederatedIdentityRepresentation; import org.keycloak.representations.idm.IdentityProviderRepresentation; @@ -217,10 +218,10 @@ public class ModelToRepresentation { return rep; } - public static ApplicationRepresentation toRepresentation(ClientModel clientModel) { - ApplicationRepresentation rep = new ApplicationRepresentation(); + public static ClientRepresentation toRepresentation(ClientModel clientModel) { + ClientRepresentation rep = new ClientRepresentation(); rep.setId(clientModel.getId()); - rep.setName(clientModel.getClientId()); + rep.setClientId(clientModel.getClientId()); rep.setEnabled(clientModel.isEnabled()); rep.setAdminUrl(clientModel.getManagementUrl()); rep.setPublicClient(clientModel.isPublicClient()); @@ -237,12 +238,12 @@ public class ModelToRepresentation { Set redirectUris = clientModel.getRedirectUris(); if (redirectUris != null) { - rep.setRedirectUris(new LinkedList(redirectUris)); + rep.setRedirectUris(new LinkedList<>(redirectUris)); } Set webOrigins = clientModel.getWebOrigins(); if (webOrigins != null) { - rep.setWebOrigins(new LinkedList(webOrigins)); + rep.setWebOrigins(new LinkedList<>(webOrigins)); } if (!clientModel.getDefaultRoles().isEmpty()) { @@ -250,7 +251,7 @@ public class ModelToRepresentation { } if (!clientModel.getRegisteredNodes().isEmpty()) { - rep.setRegisteredNodes(new HashMap(clientModel.getRegisteredNodes())); + rep.setRegisteredNodes(new HashMap<>(clientModel.getRegisteredNodes())); } if (!clientModel.getIdentityProviders().isEmpty()) { @@ -258,7 +259,7 @@ public class ModelToRepresentation { } if (!clientModel.getProtocolMappers().isEmpty()) { - List mappings = new LinkedList(); + List mappings = new LinkedList<>(); for (ProtocolMapperModel model : clientModel.getProtocolMappers()) { mappings.add(toRepresentation(model)); } diff --git a/model/api/src/main/java/org/keycloak/models/utils/RepresentationToModel.java b/model/api/src/main/java/org/keycloak/models/utils/RepresentationToModel.java index 66c75b6395..cf8de18d16 100755 --- a/model/api/src/main/java/org/keycloak/models/utils/RepresentationToModel.java +++ b/model/api/src/main/java/org/keycloak/models/utils/RepresentationToModel.java @@ -22,6 +22,7 @@ import org.keycloak.models.UserModel; import org.keycloak.representations.idm.ApplicationRepresentation; import org.keycloak.representations.idm.ClaimRepresentation; import org.keycloak.representations.idm.ClientIdentityProviderMappingRepresentation; +import org.keycloak.representations.idm.ClientRepresentation; import org.keycloak.representations.idm.CredentialRepresentation; import org.keycloak.representations.idm.FederatedIdentityRepresentation; import org.keycloak.representations.idm.IdentityProviderRepresentation; @@ -50,6 +51,7 @@ public class RepresentationToModel { public static void importRealm(KeycloakSession session, RealmRepresentation rep, RealmModel newRealm) { convertDeprecatedSocialProviders(rep); + convertDeprecatedApplications(session, rep); newRealm.setName(rep.getRealm()); if (rep.isEnabled() != null) newRealm.setEnabled(rep.isEnabled()); @@ -127,8 +129,8 @@ public class RepresentationToModel { importIdentityProviders(rep, newRealm); - if (rep.getApplications() != null) { - Map appMap = createApplications(session, rep, newRealm); + if (rep.getClients() != null) { + createClients(session, rep, newRealm); } if (rep.getRoles() != null) { @@ -177,22 +179,17 @@ public class RepresentationToModel { newRealm.addDefaultRole(roleString.trim()); } } - // Setup application default roles - if (rep.getApplications() != null) { - for (ApplicationRepresentation resourceRep : rep.getApplications()) { + // Setup client default roles + if (rep.getClients() != null) { + for (ClientRepresentation resourceRep : rep.getClients()) { if (resourceRep.getDefaultRoles() != null) { - ClientModel appModel = newRealm.getClientByClientId(resourceRep.getName()); - appModel.updateDefaultRoles(resourceRep.getDefaultRoles()); + ClientModel clientModel = newRealm.getClientByClientId(resourceRep.getClientId()); + clientModel.updateDefaultRoles(resourceRep.getDefaultRoles()); } } } - if (rep.getOauthClients() != null) { - createOAuthClients(session, rep, newRealm); - } - - - // Now that all possible roles and applications are created, create scope mappings + // Now that all possible roles and clients are created, create scope mappings Map appMap = newRealm.getClientNameMap(); @@ -201,9 +198,9 @@ public class RepresentationToModel { for (Map.Entry> entry : rep.getApplicationScopeMappings().entrySet()) { ClientModel app = appMap.get(entry.getKey()); if (app == null) { - throw new RuntimeException("Unable to find application role mappings for app: " + entry.getKey()); + throw new RuntimeException("Unable to find client role mappings for client: " + entry.getKey()); } - createApplicationScopeMappings(newRealm, app, entry.getValue()); + createClientScopeMappings(newRealm, app, entry.getValue()); } } @@ -312,15 +309,41 @@ public class RepresentationToModel { user.setSocialLinks(null); } - private static List convertDeprecatedClaimsMask(KeycloakSession session, ClaimRepresentation claimRep) { - if (claimRep == null) { - return null; - } + private static void convertDeprecatedApplications(KeycloakSession session, RealmRepresentation realm) { + if (realm.getApplications() != null || realm.getOauthClients() != null) { + if (realm.getClients() == null) { + realm.setClients(new LinkedList()); + } - logger.warn("Using deprecated 'claims' configuration in JSON representation. It will be removed in future versions"); - long mask = getClaimsMask(claimRep); - MigrationProvider migrationProvider = session.getProvider(MigrationProvider.class); - return migrationProvider.getMappersForClaimMask(mask); + List clients = new LinkedList<>(); + if (realm.getApplications() != null) { + clients.addAll(realm.getApplications()); + } + if (realm.getOauthClients() != null) { + clients.addAll(realm.getOauthClients()); + } + + for (ApplicationRepresentation app : clients) { + app.setClientId(app.getName()); + app.setName(null); + + if (app instanceof OAuthClientRepresentation) { + app.setConsentRequired(true); + app.setFullScopeAllowed(false); + } + + if (app.getProtocolMappers() == null && app.getClaims() != null) { + long mask = getClaimsMask(app.getClaims()); + List convertedProtocolMappers = session.getProvider(MigrationProvider.class).getMappersForClaimMask(mask); + app.setProtocolMappers(convertedProtocolMappers); + app.setClaims(null); + } + + realm.getClients().add(app); + } + + realm.setApplications(null); + } } public static void updateRealm(RealmRepresentation rep, RealmModel realm) { @@ -450,10 +473,10 @@ public class RepresentationToModel { // APPLICATIONS - private static Map createApplications(KeycloakSession session, RealmRepresentation rep, RealmModel realm) { + private static Map createClients(KeycloakSession session, RealmRepresentation rep, RealmModel realm) { Map appMap = new HashMap(); - for (ApplicationRepresentation resourceRep : rep.getApplications()) { - ClientModel app = createApplication(session, realm, resourceRep, false); + for (ClientRepresentation resourceRep : rep.getClients()) { + ClientModel app = createClient(session, realm, resourceRep, false); appMap.put(app.getClientId(), app); } return appMap; @@ -466,63 +489,57 @@ public class RepresentationToModel { * @param resourceRep * @return */ - public static ClientModel createApplication(KeycloakSession session, RealmModel realm, ApplicationRepresentation resourceRep, boolean addDefaultRoles) { - logger.debug("************ CREATE APPLICATION: {0}" + resourceRep.getName()); + public static ClientModel createClient(KeycloakSession session, RealmModel realm, ClientRepresentation resourceRep, boolean addDefaultRoles) { + logger.debug("************ CREATE APPLICATION: {0}" + resourceRep.getClientId()); - if (resourceRep.getProtocolMappers() == null) { - List convertedProtocolMappers = convertDeprecatedClaimsMask(session, resourceRep.getClaims()); - if (convertedProtocolMappers != null) { - resourceRep.setProtocolMappers(convertedProtocolMappers); - } - } - - ClientModel applicationModel = resourceRep.getId()!=null ? realm.addClient(resourceRep.getId(), resourceRep.getName()) : realm.addClient(resourceRep.getName()); - if (resourceRep.isEnabled() != null) applicationModel.setEnabled(resourceRep.isEnabled()); - applicationModel.setManagementUrl(resourceRep.getAdminUrl()); + ClientModel client = resourceRep.getId()!=null ? realm.addClient(resourceRep.getId(), resourceRep.getClientId()) : realm.addClient(resourceRep.getClientId()); + if (resourceRep.isEnabled() != null) client.setEnabled(resourceRep.isEnabled()); + client.setManagementUrl(resourceRep.getAdminUrl()); if (resourceRep.isSurrogateAuthRequired() != null) - applicationModel.setSurrogateAuthRequired(resourceRep.isSurrogateAuthRequired()); - applicationModel.setBaseUrl(resourceRep.getBaseUrl()); - if (resourceRep.isBearerOnly() != null) applicationModel.setBearerOnly(resourceRep.isBearerOnly()); - if (resourceRep.isPublicClient() != null) applicationModel.setPublicClient(resourceRep.isPublicClient()); - if (resourceRep.isFrontchannelLogout() != null) applicationModel.setFrontchannelLogout(resourceRep.isFrontchannelLogout()); - if (resourceRep.getProtocol() != null) applicationModel.setProtocol(resourceRep.getProtocol()); + client.setSurrogateAuthRequired(resourceRep.isSurrogateAuthRequired()); + client.setBaseUrl(resourceRep.getBaseUrl()); + if (resourceRep.isBearerOnly() != null) client.setBearerOnly(resourceRep.isBearerOnly()); + if (resourceRep.isConsentRequired() != null) client.setConsentRequired(resourceRep.isConsentRequired()); + if (resourceRep.isPublicClient() != null) client.setPublicClient(resourceRep.isPublicClient()); + if (resourceRep.isFrontchannelLogout() != null) client.setFrontchannelLogout(resourceRep.isFrontchannelLogout()); + if (resourceRep.getProtocol() != null) client.setProtocol(resourceRep.getProtocol()); if (resourceRep.isFullScopeAllowed() != null) { - applicationModel.setFullScopeAllowed(resourceRep.isFullScopeAllowed()); + client.setFullScopeAllowed(resourceRep.isFullScopeAllowed()); } else { - applicationModel.setFullScopeAllowed(true); + client.setFullScopeAllowed(true); } if (resourceRep.getNodeReRegistrationTimeout() != null) { - applicationModel.setNodeReRegistrationTimeout(resourceRep.getNodeReRegistrationTimeout()); + client.setNodeReRegistrationTimeout(resourceRep.getNodeReRegistrationTimeout()); } else { - applicationModel.setNodeReRegistrationTimeout(-1); + client.setNodeReRegistrationTimeout(-1); } - applicationModel.updateApplication(); + client.updateApplication(); if (resourceRep.getNotBefore() != null) { - applicationModel.setNotBefore(resourceRep.getNotBefore()); + client.setNotBefore(resourceRep.getNotBefore()); } - applicationModel.setSecret(resourceRep.getSecret()); - if (applicationModel.getSecret() == null) { - KeycloakModelUtils.generateSecret(applicationModel); + client.setSecret(resourceRep.getSecret()); + if (client.getSecret() == null) { + KeycloakModelUtils.generateSecret(client); } if (resourceRep.getAttributes() != null) { for (Map.Entry entry : resourceRep.getAttributes().entrySet()) { - applicationModel.setAttribute(entry.getKey(), entry.getValue()); + client.setAttribute(entry.getKey(), entry.getValue()); } } if (resourceRep.getRedirectUris() != null) { for (String redirectUri : resourceRep.getRedirectUris()) { - applicationModel.addRedirectUri(redirectUri); + client.addRedirectUri(redirectUri); } } if (resourceRep.getWebOrigins() != null) { for (String webOrigin : resourceRep.getWebOrigins()) { - logger.debugv("Application: {0} webOrigin: {1}", resourceRep.getName(), webOrigin); - applicationModel.addWebOrigin(webOrigin); + logger.debugv("Application: {0} webOrigin: {1}", resourceRep.getClientId(), webOrigin); + client.addWebOrigin(webOrigin); } } else { // add origins from redirect uris @@ -541,38 +558,38 @@ public class RepresentationToModel { } } if (origins.size() > 0) { - applicationModel.setWebOrigins(origins); + client.setWebOrigins(origins); } } } if (resourceRep.getRegisteredNodes() != null) { for (Map.Entry entry : resourceRep.getRegisteredNodes().entrySet()) { - applicationModel.registerNode(entry.getKey(), entry.getValue()); + client.registerNode(entry.getKey(), entry.getValue()); } } if (addDefaultRoles && resourceRep.getDefaultRoles() != null) { - applicationModel.updateDefaultRoles(resourceRep.getDefaultRoles()); + client.updateDefaultRoles(resourceRep.getDefaultRoles()); } if (resourceRep.getProtocolMappers() != null) { // first, remove all default/built in mappers - Set mappers = applicationModel.getProtocolMappers(); - for (ProtocolMapperModel mapper : mappers) applicationModel.removeProtocolMapper(mapper); + Set mappers = client.getProtocolMappers(); + for (ProtocolMapperModel mapper : mappers) client.removeProtocolMapper(mapper); for (ProtocolMapperRepresentation mapper : resourceRep.getProtocolMappers()) { - applicationModel.addProtocolMapper(toModel(mapper)); + client.addProtocolMapper(toModel(mapper)); } } - applicationModel.updateIdentityProviders(toModel(resourceRep.getIdentityProviders(), realm)); + client.updateIdentityProviders(toModel(resourceRep.getIdentityProviders(), realm)); - return applicationModel; + return client; } - public static void updateApplication(ApplicationRepresentation rep, ClientModel resource) { - if (rep.getName() != null) resource.setClientId(rep.getName()); + public static void updateClient(ClientRepresentation rep, ClientModel resource) { + if (rep.getClientId() != null) resource.setClientId(rep.getClientId()); if (rep.isEnabled() != null) resource.setEnabled(rep.isEnabled()); if (rep.isBearerOnly() != null) resource.setBearerOnly(rep.isBearerOnly()); if (rep.isConsentRequired() != null) resource.setConsentRequired(rep.isConsentRequired()); @@ -675,94 +692,18 @@ public class RepresentationToModel { return mask; } - // OAuth clients - - private static void createOAuthClients(KeycloakSession session, RealmRepresentation realmRep, RealmModel realm) { - for (OAuthClientRepresentation rep : realmRep.getOauthClients()) { - createOAuthClient(session, rep, realm); - } - } - - public static ClientModel createOAuthClient(String id, String name, RealmModel realm) { - ClientModel model = id!=null ? realm.addClient(id, name) : realm.addClient(name); - model.setConsentRequired(true); - KeycloakModelUtils.generateSecret(model); - return model; - } - - public static ClientModel createOAuthClient(KeycloakSession session, OAuthClientRepresentation rep, RealmModel realm) { - ClientModel model = createOAuthClient(rep.getId(), rep.getName(), realm); - - model.updateIdentityProviders(toModel(rep.getIdentityProviders(), realm)); - - updateOAuthClient(session, rep, model); - return model; - } - - public static void updateOAuthClient(KeycloakSession session, OAuthClientRepresentation rep, ClientModel model) { - if (rep.getProtocolMappers() == null) { - List convertedProtocolMappers = convertDeprecatedClaimsMask(session, rep.getClaims()); - if (convertedProtocolMappers != null) { - rep.setProtocolMappers(convertedProtocolMappers); - } - } - - if (rep.getName() != null) model.setClientId(rep.getName()); - if (rep.isEnabled() != null) model.setEnabled(rep.isEnabled()); - if (rep.isPublicClient() != null) model.setPublicClient(rep.isPublicClient()); - if (rep.isFrontchannelLogout() != null) model.setFrontchannelLogout(rep.isFrontchannelLogout()); - if (rep.isFullScopeAllowed() != null) model.setFullScopeAllowed(rep.isFullScopeAllowed()); - if (rep.isDirectGrantsOnly() != null) model.setDirectGrantsOnly(rep.isDirectGrantsOnly()); - if (rep.getNotBefore() != null) { - model.setNotBefore(rep.getNotBefore()); - } - if (rep.getSecret() != null) model.setSecret(rep.getSecret()); - List redirectUris = rep.getRedirectUris(); - if (redirectUris != null) { - model.setRedirectUris(new HashSet(redirectUris)); - } - - List webOrigins = rep.getWebOrigins(); - if (webOrigins != null) { - model.setWebOrigins(new HashSet(webOrigins)); - } - - if (rep.getNotBefore() != null) { - model.setNotBefore(rep.getNotBefore()); - } - if (rep.getProtocol() != null) model.setProtocol(rep.getProtocol()); - if (rep.getAttributes() != null) { - for (Map.Entry entry : rep.getAttributes().entrySet()) { - model.setAttribute(entry.getKey(), entry.getValue()); - } - } - - updateClientIdentityProviders(rep.getIdentityProviders(), model); - - if (rep.getProtocolMappers() != null) { - // first, remove all default/built in mappers - Set mappers = model.getProtocolMappers(); - for (ProtocolMapperModel mapper : mappers) model.removeProtocolMapper(mapper); - - for (ProtocolMapperRepresentation mapper : rep.getProtocolMappers()) { - model.addProtocolMapper(toModel(mapper)); - } - } - - } - // Scope mappings - public static void createApplicationScopeMappings(RealmModel realm, ClientModel applicationModel, List mappings) { + public static void createClientScopeMappings(RealmModel realm, ClientModel clientModel, List mappings) { for (ScopeMappingRepresentation mapping : mappings) { ClientModel client = realm.getClientByClientId(mapping.getClient()); if (client == null) { throw new RuntimeException("Unknown client specified in application scope mappings"); } for (String roleString : mapping.getRoles()) { - RoleModel role = applicationModel.getRole(roleString.trim()); + RoleModel role = clientModel.getRole(roleString.trim()); if (role == null) { - role = applicationModel.addRole(roleString.trim()); + role = clientModel.addRole(roleString.trim()); } client.addScopeMapping(role); } @@ -771,7 +712,7 @@ public class RepresentationToModel { // Users - public static UserModel createUser(KeycloakSession session, RealmModel newRealm, UserRepresentation userRep, Map appMap) { + public static UserModel createUser(KeycloakSession session, RealmModel newRealm, UserRepresentation userRep, Map clientMap) { convertDeprecatedSocialProviders(userRep); // Import users just to user storage. Don't federate @@ -814,11 +755,11 @@ public class RepresentationToModel { } if (userRep.getApplicationRoles() != null) { for (Map.Entry> entry : userRep.getApplicationRoles().entrySet()) { - ClientModel app = appMap.get(entry.getKey()); - if (app == null) { - throw new RuntimeException("Unable to find application role mappings for app: " + entry.getKey()); + ClientModel client = clientMap.get(entry.getKey()); + if (client == null) { + throw new RuntimeException("Unable to find client role mappings for client: " + entry.getKey()); } - createApplicationRoleMappings(app, user, entry.getValue()); + createClientRoleMappings(client, user, entry.getValue()); } } return user; @@ -853,7 +794,7 @@ public class RepresentationToModel { // Role mappings - public static void createApplicationRoleMappings(ClientModel applicationModel, UserModel user, List roleNames) { + public static void createClientRoleMappings(ClientModel applicationModel, UserModel user, List roleNames) { if (user == null) { throw new RuntimeException("User not found"); } diff --git a/services/src/main/java/org/keycloak/services/managers/ApplicationManager.java b/services/src/main/java/org/keycloak/services/managers/ClientManager.java similarity index 85% rename from services/src/main/java/org/keycloak/services/managers/ApplicationManager.java rename to services/src/main/java/org/keycloak/services/managers/ClientManager.java index b7baf9ab5c..18d4d09051 100755 --- a/services/src/main/java/org/keycloak/services/managers/ApplicationManager.java +++ b/services/src/main/java/org/keycloak/services/managers/ClientManager.java @@ -24,27 +24,27 @@ import java.util.TreeSet; * @author Bill Burke * @version $Revision: 1 $ */ -public class ApplicationManager { - protected Logger logger = Logger.getLogger(ApplicationManager.class); +public class ClientManager { + protected Logger logger = Logger.getLogger(ClientManager.class); protected RealmManager realmManager; - public ApplicationManager(RealmManager realmManager) { + public ClientManager(RealmManager realmManager) { this.realmManager = realmManager; } - public ApplicationManager() { + public ClientManager() { } - public ClientModel createApplication(RealmModel realm, String name) { - return KeycloakModelUtils.createApplication(realm, name); + public ClientModel createClient(RealmModel realm, String name) { + return KeycloakModelUtils.createClient(realm, name); } - public boolean removeApplication(RealmModel realm, ClientModel application) { - if (realm.removeClient(application.getId())) { + public boolean removeClient(RealmModel realm, ClientModel client) { + if (realm.removeClient(client.getId())) { UserSessionProvider sessions = realmManager.getSession().sessions(); if (sessions != null) { - sessions.onClientRemoved(realm, application); + sessions.onClientRemoved(realm, client); } return true; } else { @@ -52,8 +52,8 @@ public class ApplicationManager { } } - public Set validateRegisteredNodes(ClientModel application) { - Map registeredNodes = application.getRegisteredNodes(); + public Set validateRegisteredNodes(ClientModel client) { + Map registeredNodes = client.getRegisteredNodes(); if (registeredNodes == null || registeredNodes.isEmpty()) { return Collections.emptySet(); } @@ -61,11 +61,11 @@ public class ApplicationManager { int currentTime = Time.currentTime(); Set validatedNodes = new TreeSet(); - if (application.getNodeReRegistrationTimeout() > 0) { + if (client.getNodeReRegistrationTimeout() > 0) { List toRemove = new LinkedList(); for (Map.Entry entry : registeredNodes.entrySet()) { Integer lastReRegistration = entry.getValue(); - if (lastReRegistration + application.getNodeReRegistrationTimeout() < currentTime) { + if (lastReRegistration + client.getNodeReRegistrationTimeout() < currentTime) { toRemove.add(entry.getKey()); } else { validatedNodes.add(entry.getKey()); @@ -74,7 +74,7 @@ public class ApplicationManager { // Remove time-outed nodes for (String node : toRemove) { - application.unregisterNode(node); + client.unregisterNode(node); } } else { // Periodic node reRegistration is disabled, so allow all nodes 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 f372bbd18b..4a03c26dbd 100755 --- a/services/src/main/java/org/keycloak/services/managers/RealmManager.java +++ b/services/src/main/java/org/keycloak/services/managers/RealmManager.java @@ -91,7 +91,7 @@ public class RealmManager { protected void setupAdminConsole(RealmModel realm) { ClientModel adminConsole = realm.getClientByClientId(Constants.ADMIN_CONSOLE_APPLICATION); - if (adminConsole == null) adminConsole = new ApplicationManager(this).createApplication(realm, Constants.ADMIN_CONSOLE_APPLICATION); + if (adminConsole == null) adminConsole = new ClientManager(this).createClient(realm, Constants.ADMIN_CONSOLE_APPLICATION); String baseUrl = contextPath + "/admin/" + realm.getName() + "/console"; adminConsole.setBaseUrl(baseUrl + "/index.html"); adminConsole.setEnabled(true); @@ -139,7 +139,7 @@ public class RealmManager { boolean removed = model.removeRealm(realm.getId()); if (removed) { - new ApplicationManager(this).removeApplication(getKeycloakAdminstrationRealm(), realm.getMasterAdminApp()); + new ClientManager(this).removeClient(getKeycloakAdminstrationRealm(), realm.getMasterAdminApp()); UserSessionProvider sessions = session.sessions(); if (sessions != null) { @@ -174,12 +174,12 @@ public class RealmManager { private void setupRealmAdminManagement(RealmModel realm) { if (realm.getName().equals(Config.getAdminRealm())) { return; } // don't need to do this for master realm - ApplicationManager applicationManager = new ApplicationManager(new RealmManager(session)); + ClientManager clientManager = new ClientManager(new RealmManager(session)); String realmAdminApplicationName = getRealmAdminApplicationName(realm); ClientModel realmAdminApp = realm.getClientByClientId(realmAdminApplicationName); if (realmAdminApp == null) { - realmAdminApp = applicationManager.createApplication(realm, realmAdminApplicationName); + realmAdminApp = clientManager.createClient(realm, realmAdminApplicationName); } RoleModel adminRole = realmAdminApp.addRole(AdminRoles.REALM_ADMIN); adminRole.setDescription("${role_"+AdminRoles.REALM_ADMIN+"}"); @@ -197,7 +197,7 @@ public class RealmManager { private void setupAccountManagement(RealmModel realm) { ClientModel application = realm.getClientNameMap().get(Constants.ACCOUNT_MANAGEMENT_APP); if (application == null) { - application = new ApplicationManager(this).createApplication(realm, Constants.ACCOUNT_MANAGEMENT_APP); + application = new ClientManager(this).createClient(realm, Constants.ACCOUNT_MANAGEMENT_APP); application.setEnabled(true); application.setFullScopeAllowed(false); String base = contextPath + "/realms/" + realm.getName() + "/account"; diff --git a/services/src/main/java/org/keycloak/services/managers/ResourceAdminManager.java b/services/src/main/java/org/keycloak/services/managers/ResourceAdminManager.java index 5c4e44310b..fa219d6725 100755 --- a/services/src/main/java/org/keycloak/services/managers/ResourceAdminManager.java +++ b/services/src/main/java/org/keycloak/services/managers/ResourceAdminManager.java @@ -78,7 +78,7 @@ public class ResourceAdminManager { return Collections.emptyList(); } - Set registeredNodesHosts = new ApplicationManager().validateRegisteredNodes(application); + Set registeredNodesHosts = new ClientManager().validateRegisteredNodes(application); // No-cluster setup if (registeredNodesHosts.isEmpty()) { diff --git a/services/src/main/java/org/keycloak/services/resources/admin/AdminConsole.java b/services/src/main/java/org/keycloak/services/resources/admin/AdminConsole.java index 3dcffdea18..bfe70da898 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/AdminConsole.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/AdminConsole.java @@ -22,7 +22,7 @@ import org.keycloak.models.RoleModel; import org.keycloak.models.UserModel; import org.keycloak.protocol.oidc.OIDCLoginProtocolService; import org.keycloak.services.managers.AppAuthManager; -import org.keycloak.services.managers.ApplicationManager; +import org.keycloak.services.managers.ClientManager; import org.keycloak.services.managers.AuthenticationManager; import org.keycloak.services.managers.RealmManager; import org.keycloak.services.resources.KeycloakApplication; @@ -153,12 +153,12 @@ public class AdminConsole { @GET @Produces("application/json") @NoCache - public ApplicationManager.InstallationAdapterConfig config() { + public ClientManager.InstallationAdapterConfig config() { ClientModel consoleApp = realm.getClientByClientId(Constants.ADMIN_CONSOLE_APPLICATION); if (consoleApp == null) { throw new NotFoundException("Could not find admin console application"); } - return new ApplicationManager().toInstallationRepresentation(realm, consoleApp, keycloak.getBaseUri(uriInfo)); + return new ClientManager().toInstallationRepresentation(realm, consoleApp, keycloak.getBaseUri(uriInfo)); } diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ApplicationResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ClientResource.java similarity index 80% rename from services/src/main/java/org/keycloak/services/resources/admin/ApplicationResource.java rename to services/src/main/java/org/keycloak/services/resources/admin/ClientResource.java index 7a5e2b5953..8c689757ad 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/ApplicationResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/ClientResource.java @@ -17,9 +17,10 @@ import org.keycloak.models.utils.ModelToRepresentation; import org.keycloak.models.utils.RepresentationToModel; import org.keycloak.representations.adapters.action.GlobalRequestResult; import org.keycloak.representations.idm.ApplicationRepresentation; +import org.keycloak.representations.idm.ClientRepresentation; import org.keycloak.representations.idm.CredentialRepresentation; import org.keycloak.representations.idm.UserSessionRepresentation; -import org.keycloak.services.managers.ApplicationManager; +import org.keycloak.services.managers.ClientManager; import org.keycloak.services.managers.RealmManager; import org.keycloak.services.managers.ResourceAdminManager; import org.keycloak.services.resources.KeycloakApplication; @@ -53,11 +54,11 @@ import java.util.Set; * @author Bill Burke * @version $Revision: 1 $ */ -public class ApplicationResource { - protected static final Logger logger = Logger.getLogger(ApplicationResource.class); +public class ClientResource { + protected static final Logger logger = Logger.getLogger(ClientResource.class); protected RealmModel realm; private RealmAuth auth; - protected ClientModel application; + protected ClientModel client; protected KeycloakSession session; @Context @@ -70,10 +71,10 @@ public class ApplicationResource { return keycloak; } - public ApplicationResource(RealmModel realm, RealmAuth auth, ClientModel clientModel, KeycloakSession session) { + public ClientResource(RealmModel realm, RealmAuth auth, ClientModel clientModel, KeycloakSession session) { this.realm = realm; this.auth = auth; - this.application = clientModel; + this.client = clientModel; this.session = session; auth.init(RealmAuth.Resource.CLIENT); @@ -81,7 +82,7 @@ public class ApplicationResource { @Path("protocol-mappers") public ProtocolMappersResource getProtocolMappers() { - ProtocolMappersResource mappers = new ProtocolMappersResource(application, auth); + ProtocolMappersResource mappers = new ProtocolMappersResource(client, auth); ResteasyProviderFactory.getInstance().injectProperties(mappers); return mappers; } @@ -93,14 +94,14 @@ public class ApplicationResource { */ @PUT @Consumes(MediaType.APPLICATION_JSON) - public Response update(final ApplicationRepresentation rep) { + public Response update(final ClientRepresentation rep) { auth.requireManage(); try { - RepresentationToModel.updateApplication(rep, application); + RepresentationToModel.updateClient(rep, client); return Response.noContent().build(); } catch (ModelDuplicateException e) { - return Flows.errors().exists("Application " + rep.getName() + " already exists"); + return Flows.errors().exists("Client " + rep.getClientId() + " already exists"); } } @@ -113,10 +114,10 @@ public class ApplicationResource { @GET @NoCache @Produces(MediaType.APPLICATION_JSON) - public ApplicationRepresentation getApplication() { + public ClientRepresentation getClient() { auth.requireView(); - return ModelToRepresentation.toRepresentation(application); + return ModelToRepresentation.toRepresentation(client); } /** @@ -126,7 +127,7 @@ public class ApplicationResource { */ @Path("certificates/{attr}") public ClientAttributeCertificateResource getCertficateResource(@PathParam("attr") String attributePrefix) { - return new ClientAttributeCertificateResource(realm, auth, application, session, attributePrefix); + return new ClientAttributeCertificateResource(realm, auth, client, session, attributePrefix); } @@ -143,8 +144,8 @@ public class ApplicationResource { public String getInstallation() throws IOException { auth.requireView(); - ApplicationManager applicationManager = new ApplicationManager(new RealmManager(session)); - Object rep = applicationManager.toInstallationRepresentation(realm, application, getKeycloakApplication().getBaseUri(uriInfo)); + ClientManager clientManager = new ClientManager(new RealmManager(session)); + Object rep = clientManager.toInstallationRepresentation(realm, client, getKeycloakApplication().getBaseUri(uriInfo)); // TODO Temporary solution to pretty-print return JsonSerialization.mapper.writerWithDefaultPrettyPrinter().writeValueAsString(rep); @@ -163,8 +164,8 @@ public class ApplicationResource { public String getJBossInstallation() throws IOException { auth.requireView(); - ApplicationManager applicationManager = new ApplicationManager(new RealmManager(session)); - return applicationManager.toJBossSubsystemConfig(realm, application, getKeycloakApplication().getBaseUri(uriInfo)); + ClientManager clientManager = new ClientManager(new RealmManager(session)); + return clientManager.toJBossSubsystemConfig(realm, client, getKeycloakApplication().getBaseUri(uriInfo)); } /** @@ -175,7 +176,7 @@ public class ApplicationResource { @NoCache public void deleteApplication() { auth.requireManage(); - new ApplicationManager(new RealmManager(session)).removeApplication(realm, application); + new ClientManager(new RealmManager(session)).removeClient(realm, client); } @@ -192,7 +193,7 @@ public class ApplicationResource { auth.requireManage(); logger.debug("regenerateSecret"); - UserCredentialModel cred = KeycloakModelUtils.generateSecret(application); + UserCredentialModel cred = KeycloakModelUtils.generateSecret(client); CredentialRepresentation rep = ModelToRepresentation.toRepresentation(cred); return rep; } @@ -210,7 +211,7 @@ public class ApplicationResource { auth.requireView(); logger.debug("getClientSecret"); - UserCredentialModel model = UserCredentialModel.secret(application.getSecret()); + UserCredentialModel model = UserCredentialModel.secret(client.getSecret()); if (model == null) throw new NotFoundException("Application does not have a secret"); return ModelToRepresentation.toRepresentation(model); } @@ -222,12 +223,12 @@ public class ApplicationResource { */ @Path("scope-mappings") public ScopeMappedResource getScopeMappedResource() { - return new ScopeMappedResource(realm, auth, application, session); + return new ScopeMappedResource(realm, auth, client, session); } @Path("roles") public RoleContainerResource getRoleContainerResource() { - return new RoleContainerResource(realm, auth, application); + return new RoleContainerResource(realm, auth, client); } /** @@ -244,7 +245,7 @@ public class ApplicationResource { { auth.requireView(); - return application.getWebOrigins(); + return client.getWebOrigins(); } /** @@ -260,7 +261,7 @@ public class ApplicationResource { { auth.requireManage(); - application.setWebOrigins(allowedOrigins); + client.setWebOrigins(allowedOrigins); } /** @@ -277,7 +278,7 @@ public class ApplicationResource { auth.requireManage(); for (String origin : allowedOrigins) { - application.removeWebOrigin(origin); + client.removeWebOrigin(origin); } } @@ -289,7 +290,7 @@ public class ApplicationResource { @POST public GlobalRequestResult pushRevocation() { auth.requireManage(); - return new ResourceAdminManager().pushApplicationRevocationPolicy(uriInfo.getRequestUri(), realm, application); + return new ResourceAdminManager().pushApplicationRevocationPolicy(uriInfo.getRequestUri(), realm, client); } /** @@ -308,7 +309,7 @@ public class ApplicationResource { public Map getApplicationSessionCount() { auth.requireView(); Map map = new HashMap(); - map.put("count", session.sessions().getActiveUserSessions(application.getRealm(), application)); + map.put("count", session.sessions().getActiveUserSessions(client.getRealm(), client)); return map; } @@ -326,7 +327,7 @@ public class ApplicationResource { firstResult = firstResult != null ? firstResult : -1; maxResults = maxResults != null ? maxResults : -1; List sessions = new ArrayList(); - for (UserSessionModel userSession : session.sessions().getUserSessions(application.getRealm(), application, firstResult, maxResults)) { + for (UserSessionModel userSession : session.sessions().getUserSessions(client.getRealm(), client, firstResult, maxResults)) { UserSessionRepresentation rep = ModelToRepresentation.toRepresentation(userSession); sessions.add(rep); } @@ -341,7 +342,7 @@ public class ApplicationResource { @POST public GlobalRequestResult logoutAll() { auth.requireManage(); - return new ResourceAdminManager().logoutApplication(uriInfo.getRequestUri(), realm, application); + return new ResourceAdminManager().logoutApplication(uriInfo.getRequestUri(), realm, client); } /** @@ -356,7 +357,7 @@ public class ApplicationResource { if (user == null) { throw new NotFoundException("User not found"); } - new ResourceAdminManager().logoutUserFromApplication(uriInfo.getRequestUri(), realm, application, user, session); + new ResourceAdminManager().logoutUserFromApplication(uriInfo.getRequestUri(), realm, client, user, session); } /** @@ -375,7 +376,7 @@ public class ApplicationResource { throw new BadRequestException("Node not found in params"); } if (logger.isDebugEnabled()) logger.debug("Register node: " + node); - application.registerNode(node, Time.currentTime()); + client.registerNode(node, Time.currentTime()); } /** @@ -390,12 +391,12 @@ public class ApplicationResource { auth.requireManage(); if (logger.isDebugEnabled()) logger.debug("Unregister node: " + node); - Integer time = application.getRegisteredNodes().get(node); + Integer time = client.getRegisteredNodes().get(node); if (time == null) { throw new NotFoundException("Application does not have a node " + node); } - application.unregisterNode(node); + client.unregisterNode(node); } /** @@ -410,7 +411,7 @@ public class ApplicationResource { auth.requireManage(); logger.debug("Test availability of cluster nodes"); - return new ResourceAdminManager().testNodesAvailability(uriInfo.getRequestUri(), realm, application); + return new ResourceAdminManager().testNodesAvailability(uriInfo.getRequestUri(), realm, client); } } diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ApplicationsByIdResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ClientsByIdResource.java similarity index 56% rename from services/src/main/java/org/keycloak/services/resources/admin/ApplicationsByIdResource.java rename to services/src/main/java/org/keycloak/services/resources/admin/ClientsByIdResource.java index d4b8f8fcdb..46f2f8774d 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/ApplicationsByIdResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/ClientsByIdResource.java @@ -7,18 +7,18 @@ import org.keycloak.models.RealmModel; * @author Bill Burke * @version $Revision: 1 $ */ -public class ApplicationsByIdResource extends ApplicationsResource { - public ApplicationsByIdResource(RealmModel realm, RealmAuth auth) { +public class ClientsByIdResource extends ClientsResource { + public ClientsByIdResource(RealmModel realm, RealmAuth auth) { super(realm, auth); } @Override - protected ClientModel getApplicationByPathParam(String id) { + protected ClientModel getClientByPathParam(String id) { return realm.getClientById(id); } @Override - protected String getApplicationPath(ClientModel clientModel) { + protected String getClientPath(ClientModel clientModel) { return clientModel.getId(); } diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ApplicationsResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ClientsResource.java similarity index 60% rename from services/src/main/java/org/keycloak/services/resources/admin/ApplicationsResource.java rename to services/src/main/java/org/keycloak/services/resources/admin/ClientsResource.java index 66ce8a815a..7432efb629 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/ApplicationsResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/ClientsResource.java @@ -10,7 +10,7 @@ import org.keycloak.models.ModelDuplicateException; import org.keycloak.models.RealmModel; import org.keycloak.models.utils.ModelToRepresentation; import org.keycloak.models.utils.RepresentationToModel; -import org.keycloak.representations.idm.ApplicationRepresentation; +import org.keycloak.representations.idm.ClientRepresentation; import org.keycloak.services.resources.flows.Flows; import javax.ws.rs.Consumes; @@ -32,7 +32,7 @@ import java.util.List; * @author Bill Burke * @version $Revision: 1 $ */ -public class ApplicationsResource { +public class ClientsResource { protected static final Logger logger = Logger.getLogger(RealmAdminResource.class); protected RealmModel realm; private RealmAuth auth; @@ -40,7 +40,7 @@ public class ApplicationsResource { @Context protected KeycloakSession session; - public ApplicationsResource(RealmModel realm, RealmAuth auth) { + public ClientsResource(RealmModel realm, RealmAuth auth) { this.realm = realm; this.auth = auth; @@ -55,10 +55,10 @@ public class ApplicationsResource { @GET @Produces(MediaType.APPLICATION_JSON) @NoCache - public List getApplications() { + public List getClients() { auth.requireAny(); - List rep = new ArrayList(); + List rep = new ArrayList<>(); List clientModels = realm.getClients(); boolean view = auth.hasView(); @@ -66,9 +66,9 @@ public class ApplicationsResource { if (view) { rep.add(ModelToRepresentation.toRepresentation(clientModel)); } else { - ApplicationRepresentation app = new ApplicationRepresentation(); - app.setName(clientModel.getClientId()); - rep.add(app); + ClientRepresentation client = new ClientRepresentation(); + client.setClientId(clientModel.getClientId()); + rep.add(client); } } @@ -76,7 +76,7 @@ public class ApplicationsResource { } /** - * Create a new application. Application name must be unique! + * Create a new client. Client client_id must be unique! * * @param uriInfo * @param rep @@ -84,18 +84,18 @@ public class ApplicationsResource { */ @POST @Consumes(MediaType.APPLICATION_JSON) - public Response createApplication(final @Context UriInfo uriInfo, final ApplicationRepresentation rep) { + public Response createClient(final @Context UriInfo uriInfo, final ClientRepresentation rep) { auth.requireManage(); try { - ClientModel clientModel = RepresentationToModel.createApplication(session, realm, rep, true); - return Response.created(uriInfo.getAbsolutePathBuilder().path(getApplicationPath(clientModel)).build()).build(); + ClientModel clientModel = RepresentationToModel.createClient(session, realm, rep, true); + return Response.created(uriInfo.getAbsolutePathBuilder().path(getClientPath(clientModel)).build()).build(); } catch (ModelDuplicateException e) { - return Flows.errors().exists("Application " + rep.getName() + " already exists"); + return Flows.errors().exists("Client " + rep.getClientId() + " already exists"); } } - protected String getApplicationPath(ClientModel clientModel) { + protected String getClientPath(ClientModel clientModel) { return clientModel.getClientId(); } @@ -106,18 +106,17 @@ public class ApplicationsResource { * @return */ @Path("{app-name}") - public ApplicationResource getApplication(final @PathParam("app-name") String name) { - ClientModel clientModel = getApplicationByPathParam(name); + public ClientResource getClient(final @PathParam("app-name") String name) { + ClientModel clientModel = getClientByPathParam(name); if (clientModel == null) { - throw new NotFoundException("Could not find application: " + name); + throw new NotFoundException("Could not find client: " + name); } - ApplicationResource applicationResource = new ApplicationResource(realm, auth, clientModel, session); - ResteasyProviderFactory.getInstance().injectProperties(applicationResource); - //resourceContext.initResource(applicationResource); - return applicationResource; + ClientResource clientResource = new ClientResource(realm, auth, clientModel, session); + ResteasyProviderFactory.getInstance().injectProperties(clientResource); + return clientResource; } - protected ClientModel getApplicationByPathParam(String name) { + protected ClientModel getClientByPathParam(String name) { return realm.getClientByClientId(name); } diff --git a/services/src/main/java/org/keycloak/services/resources/admin/RealmAdminResource.java b/services/src/main/java/org/keycloak/services/resources/admin/RealmAdminResource.java index b178882f44..313d81011c 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/RealmAdminResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/RealmAdminResource.java @@ -101,11 +101,11 @@ public class RealmAdminResource { * @return */ @Path("applications") - public ApplicationsResource getApplications() { - ApplicationsResource applicationsResource = new ApplicationsResource(realm, auth); - ResteasyProviderFactory.getInstance().injectProperties(applicationsResource); + public ClientsResource getApplications() { + ClientsResource clientsResource = new ClientsResource(realm, auth); + ResteasyProviderFactory.getInstance().injectProperties(clientsResource); //resourceContext.initResource(applicationsResource); - return applicationsResource; + return clientsResource; } /** @@ -114,8 +114,8 @@ public class RealmAdminResource { * @return */ @Path("applications-by-id") - public ApplicationsByIdResource getApplicationsById() { - ApplicationsByIdResource applicationsResource = new ApplicationsByIdResource(realm, auth); + public ClientsByIdResource getApplicationsById() { + ClientsByIdResource applicationsResource = new ClientsByIdResource(realm, auth); ResteasyProviderFactory.getInstance().injectProperties(applicationsResource); //resourceContext.initResource(applicationsResource); return applicationsResource; diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/AdapterTestStrategy.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/AdapterTestStrategy.java index 8ec896eee0..39f2731f5e 100755 --- a/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/AdapterTestStrategy.java +++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/AdapterTestStrategy.java @@ -588,7 +588,7 @@ public class AdapterTestStrategy extends ExternalResource { // logout mposolda with admin client Keycloak keycloakAdmin = Keycloak.getInstance(AUTH_SERVER_URL, "master", "admin", "admin", Constants.ADMIN_CONSOLE_APPLICATION); - keycloakAdmin.realm("demo").applications().get("session-portal").logoutUser("mposolda"); + keycloakAdmin.realm("demo").clients().get("session-portal").logoutUser("mposolda"); // bburke should be still logged with original httpSession in our browser window driver.navigate().to(APP_SERVER_BASE_URL + "/session-portal"); diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/admin/AbstractClientTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/admin/AbstractClientTest.java index 4d549095f8..d221df0669 100755 --- a/testsuite/integration/src/test/java/org/keycloak/testsuite/admin/AbstractClientTest.java +++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/admin/AbstractClientTest.java @@ -9,6 +9,7 @@ import org.keycloak.models.Constants; import org.keycloak.models.RealmModel; import org.keycloak.models.utils.KeycloakModelUtils; import org.keycloak.representations.idm.ApplicationRepresentation; +import org.keycloak.representations.idm.ClientRepresentation; import org.keycloak.representations.idm.IdentityProviderRepresentation; import org.keycloak.representations.idm.OAuthClientRepresentation; import org.keycloak.representations.idm.RealmRepresentation; @@ -97,10 +98,8 @@ public abstract class AbstractClientTest { public static String name(Object o1) { if (o1 instanceof RealmRepresentation) { return ((RealmRepresentation) o1).getRealm(); - } else if (o1 instanceof ApplicationRepresentation) { - return ((ApplicationRepresentation) o1).getName(); - } else if (o1 instanceof OAuthClientRepresentation) { - return ((OAuthClientRepresentation) o1).getName(); + } else if (o1 instanceof ClientRepresentation) { + return ((ClientRepresentation) o1).getClientId(); } else if (o1 instanceof IdentityProviderRepresentation) { return ((IdentityProviderRepresentation) o1).getAlias(); } diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/admin/AdminAPITest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/admin/AdminAPITest.java index ff73d79c29..a8a4292049 100755 --- a/testsuite/integration/src/test/java/org/keycloak/testsuite/admin/AdminAPITest.java +++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/admin/AdminAPITest.java @@ -35,7 +35,7 @@ import org.keycloak.models.UserSessionModel; import org.keycloak.protocol.oidc.OIDCLoginProtocol; import org.keycloak.protocol.oidc.TokenManager; import org.keycloak.representations.AccessToken; -import org.keycloak.representations.idm.ApplicationRepresentation; +import org.keycloak.representations.idm.ClientRepresentation; import org.keycloak.representations.idm.CredentialRepresentation; import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.services.managers.RealmManager; @@ -125,19 +125,19 @@ public class AdminAPITest { storedRealm = realmTarget.request().get(RealmRepresentation.class); checkRealmRep(rep, storedRealm); - if (rep.getApplications() != null) { + if (rep.getClients() != null) { WebTarget applicationsTarget = realmTarget.path("applications"); - for (ApplicationRepresentation appRep : rep.getApplications()) { - ApplicationRepresentation newApp = new ApplicationRepresentation(); + for (ClientRepresentation appRep : rep.getClients()) { + ClientRepresentation newApp = new ClientRepresentation(); if (appRep.getId() != null) newApp.setId(appRep.getId()); - newApp.setName(appRep.getName()); + newApp.setClientId(appRep.getClientId()); if (appRep.getSecret() != null) { newApp.setSecret(appRep.getSecret()); } Response appCreateResponse = applicationsTarget.request().post(Entity.json(newApp)); Assert.assertEquals(201, appCreateResponse.getStatus()); appCreateResponse.close(); - WebTarget appTarget = applicationsTarget.path(appRep.getName()); + WebTarget appTarget = applicationsTarget.path(appRep.getClientId()); CredentialRepresentation cred = appTarget.path("client-secret").request().get(CredentialRepresentation.class); if (appRep.getSecret() != null) Assert.assertEquals(appRep.getSecret(), cred.getValue()); CredentialRepresentation newCred = appTarget.path("client-secret").request().post(null, CredentialRepresentation.class); @@ -148,7 +148,7 @@ public class AdminAPITest { appUpdateResponse.close(); - ApplicationRepresentation storedApp = appTarget.request().get(ApplicationRepresentation.class); + ClientRepresentation storedApp = appTarget.request().get(ClientRepresentation.class); checkAppUpdate(appRep, storedApp); @@ -165,8 +165,8 @@ public class AdminAPITest { client.close(); } - protected void checkAppUpdate(ApplicationRepresentation appRep, ApplicationRepresentation storedApp) { - if (appRep.getName() != null) Assert.assertEquals(appRep.getName(), storedApp.getName()); + protected void checkAppUpdate(ClientRepresentation appRep, ClientRepresentation storedApp) { + if (appRep.getClientId() != null) Assert.assertEquals(appRep.getClientId(), storedApp.getClientId()); if (appRep.isEnabled() != null) Assert.assertEquals(appRep.isEnabled(), storedApp.isEnabled()); if (appRep.isBearerOnly() != null) Assert.assertEquals(appRep.isBearerOnly(), storedApp.isBearerOnly()); if (appRep.isPublicClient() != null) Assert.assertEquals(appRep.isPublicClient(), storedApp.isPublicClient()); diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/admin/ApplicationTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/admin/ClientTest.java similarity index 70% rename from testsuite/integration/src/test/java/org/keycloak/testsuite/admin/ApplicationTest.java rename to testsuite/integration/src/test/java/org/keycloak/testsuite/admin/ClientTest.java index 55e17e68c8..7dc995223b 100644 --- a/testsuite/integration/src/test/java/org/keycloak/testsuite/admin/ApplicationTest.java +++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/admin/ClientTest.java @@ -2,10 +2,10 @@ package org.keycloak.testsuite.admin; import org.junit.Rule; import org.junit.Test; -import org.keycloak.admin.client.resource.ApplicationResource; +import org.keycloak.admin.client.resource.ClientResource; import org.keycloak.admin.client.resource.ProtocolMappersResource; import org.keycloak.protocol.oidc.OIDCLoginProtocolFactory; -import org.keycloak.representations.idm.ApplicationRepresentation; +import org.keycloak.representations.idm.ClientRepresentation; import org.keycloak.representations.idm.ProtocolMapperRepresentation; import org.keycloak.representations.idm.RoleRepresentation; import org.keycloak.representations.idm.UserSessionRepresentation; @@ -29,7 +29,7 @@ import static org.junit.Assert.fail; /** * @author Stian Thorgersen */ -public class ApplicationTest extends AbstractClientTest { +public class ClientTest extends AbstractClientTest { @Rule public WebRule webRule = new WebRule(this); @@ -41,38 +41,38 @@ public class ApplicationTest extends AbstractClientTest { protected OAuthClient oauth; @Test - public void getApplications() { - assertNames(realm.applications().findAll(), "account", "realm-management", "security-admin-console"); + public void getClients() { + assertNames(realm.clients().findAll(), "account", "realm-management", "security-admin-console"); } @Test - public void createApplication() { - ApplicationRepresentation rep = new ApplicationRepresentation(); - rep.setName("my-app"); + public void createClient() { + ClientRepresentation rep = new ClientRepresentation(); + rep.setClientId("my-app"); rep.setEnabled(true); - realm.applications().create(rep); + realm.clients().create(rep); - assertNames(realm.applications().findAll(), "account", "realm-management", "security-admin-console", "my-app"); + assertNames(realm.clients().findAll(), "account", "realm-management", "security-admin-console", "my-app"); } @Test - public void removeApplication() { - createApplication(); + public void removeClient() { + createClient(); - realm.applications().get("my-app").remove(); + realm.clients().get("my-app").remove(); } @Test - public void getApplicationRepresentation() { - createApplication(); + public void getClientRepresentation() { + createClient(); - ApplicationRepresentation rep = realm.applications().get("my-app").toRepresentation(); - assertEquals("my-app", rep.getName()); + ClientRepresentation rep = realm.clients().get("my-app").toRepresentation(); + assertEquals("my-app", rep.getClientId()); assertTrue(rep.isEnabled()); } @Test - public void getApplicationSessions() throws Exception { + public void getClientSessions() throws Exception { OAuthClient.AccessTokenResponse response = oauth.doGrantAccessTokenRequest("password", "test-user@localhost", "password"); assertEquals(200, response.getStatusCode()); @@ -81,7 +81,7 @@ public class ApplicationTest extends AbstractClientTest { OAuthClient.AccessTokenResponse response2 = oauth.doAccessTokenRequest(codeResponse.getCode(), "password"); assertEquals(200, response2.getStatusCode()); - ApplicationResource app = keycloak.realm("test").applications().get("test-app"); + ClientResource app = keycloak.realm("test").clients().get("test-app"); assertEquals(2, (long) app.getApplicationSessionCount().get("count")); @@ -93,29 +93,29 @@ public class ApplicationTest extends AbstractClientTest { @Test // KEYCLOAK-1110 public void deleteDefaultRole() { - ApplicationRepresentation rep = new ApplicationRepresentation(); - rep.setName("my-app"); + ClientRepresentation rep = new ClientRepresentation(); + rep.setClientId("my-app"); rep.setEnabled(true); - realm.applications().create(rep); + realm.clients().create(rep); RoleRepresentation role = new RoleRepresentation("test", "test"); - realm.applications().get("my-app").roles().create(role); + realm.clients().get("my-app").roles().create(role); - rep = realm.applications().get("my-app").toRepresentation(); + rep = realm.clients().get("my-app").toRepresentation(); rep.setDefaultRoles(new String[] { "test" }); - realm.applications().get("my-app").update(rep); + realm.clients().get("my-app").update(rep); - assertArrayEquals(new String[] { "test" }, realm.applications().get("my-app").toRepresentation().getDefaultRoles()); + assertArrayEquals(new String[] { "test" }, realm.clients().get("my-app").toRepresentation().getDefaultRoles()); - realm.applications().get("my-app").roles().deleteRole("test"); + realm.clients().get("my-app").roles().deleteRole("test"); - assertNull(realm.applications().get("my-app").toRepresentation().getDefaultRoles()); + assertNull(realm.clients().get("my-app").toRepresentation().getDefaultRoles()); } @Test public void testProtocolMappers() { - createApplication(); - ProtocolMappersResource mappersResource = realm.applications().get("my-app").getProtocolMappers(); + createClient(); + ProtocolMappersResource mappersResource = realm.clients().get("my-app").getProtocolMappers(); protocolMappersTest(mappersResource); } diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/composites/CompositeRoleTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/composites/CompositeRoleTest.java index fc8bf15dd7..7178f1de10 100755 --- a/testsuite/integration/src/test/java/org/keycloak/testsuite/composites/CompositeRoleTest.java +++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/composites/CompositeRoleTest.java @@ -35,7 +35,7 @@ import org.keycloak.models.UserCredentialModel; import org.keycloak.models.UserModel; import org.keycloak.models.utils.KeycloakModelUtils; import org.keycloak.representations.AccessToken; -import org.keycloak.services.managers.ApplicationManager; +import org.keycloak.services.managers.ClientManager; import org.keycloak.services.managers.RealmManager; import org.keycloak.testsuite.ApplicationServlet; import org.keycloak.testsuite.OAuthClient; @@ -85,7 +85,7 @@ public class CompositeRoleTest { realmRole1User.updateCredential(UserCredentialModel.password("password")); realmRole1User.grantRole(realmRole1); - final ClientModel realmComposite1Application = new ApplicationManager(manager).createApplication(realm, "REALM_COMPOSITE_1_APPLICATION"); + final ClientModel realmComposite1Application = new ClientManager(manager).createClient(realm, "REALM_COMPOSITE_1_APPLICATION"); realmComposite1Application.setFullScopeAllowed(false); realmComposite1Application.setEnabled(true); realmComposite1Application.addScopeMapping(realmComposite1); @@ -94,7 +94,7 @@ public class CompositeRoleTest { realmComposite1Application.setManagementUrl("http://localhost:8081/app/logout"); realmComposite1Application.setSecret("password"); - final ClientModel realmRole1Application = new ApplicationManager(manager).createApplication(realm, "REALM_ROLE_1_APPLICATION"); + final ClientModel realmRole1Application = new ClientManager(manager).createClient(realm, "REALM_ROLE_1_APPLICATION"); realmRole1Application.setFullScopeAllowed(false); realmRole1Application.setEnabled(true); realmRole1Application.addScopeMapping(realmRole1); @@ -104,7 +104,7 @@ public class CompositeRoleTest { realmRole1Application.setSecret("password"); - final ClientModel appRoleApplication = new ApplicationManager(manager).createApplication(realm, "APP_ROLE_APPLICATION"); + final ClientModel appRoleApplication = new ClientManager(manager).createClient(realm, "APP_ROLE_APPLICATION"); appRoleApplication.setFullScopeAllowed(false); appRoleApplication.setEnabled(true); appRoleApplication.addRedirectUri("http://localhost:8081/app/*"); @@ -127,7 +127,7 @@ public class CompositeRoleTest { realmAppRoleUser.updateCredential(UserCredentialModel.password("password")); realmAppRoleUser.grantRole(appRole2); - final ClientModel appCompositeApplication = new ApplicationManager(manager).createApplication(realm, "APP_COMPOSITE_APPLICATION"); + final ClientModel appCompositeApplication = new ClientManager(manager).createClient(realm, "APP_COMPOSITE_APPLICATION"); appCompositeApplication.setFullScopeAllowed(false); appCompositeApplication.setEnabled(true); appCompositeApplication.addRedirectUri("http://localhost:8081/app/*"); diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/model/ClientModelTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/model/ClientModelTest.java index f80b040173..a9b1344f2c 100755 --- a/testsuite/integration/src/test/java/org/keycloak/testsuite/model/ClientModelTest.java +++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/model/ClientModelTest.java @@ -8,8 +8,8 @@ import org.keycloak.models.RealmModel; import org.keycloak.models.RoleModel; import org.keycloak.models.utils.ModelToRepresentation; import org.keycloak.models.utils.RepresentationToModel; -import org.keycloak.representations.idm.ApplicationRepresentation; -import org.keycloak.services.managers.ApplicationManager; +import org.keycloak.representations.idm.ClientRepresentation; +import org.keycloak.services.managers.ClientManager; import java.util.Iterator; import java.util.List; @@ -18,37 +18,37 @@ import java.util.List; * @author Stian Thorgersen */ public class ClientModelTest extends AbstractModelTest { - private ClientModel application; + private ClientModel client; private RealmModel realm; - private ApplicationManager appManager; + private ClientManager appManager; @Before @Override public void before() throws Exception { super.before(); - appManager = new ApplicationManager(realmManager); + appManager = new ClientManager(realmManager); realm = realmManager.createRealm("original"); - application = realm.addClient("application"); - application.setBaseUrl("http://base"); - application.setManagementUrl("http://management"); - application.setClientId("app-name"); - application.addRole("role-1"); - application.addRole("role-2"); - application.addRole("role-3"); - application.addDefaultRole("role-1"); - application.addDefaultRole("role-2"); + client = realm.addClient("application"); + client.setBaseUrl("http://base"); + client.setManagementUrl("http://management"); + client.setClientId("app-name"); + client.addRole("role-1"); + client.addRole("role-2"); + client.addRole("role-3"); + client.addDefaultRole("role-1"); + client.addDefaultRole("role-2"); - application.addRedirectUri("redirect-1"); - application.addRedirectUri("redirect-2"); + client.addRedirectUri("redirect-1"); + client.addRedirectUri("redirect-2"); - application.addWebOrigin("origin-1"); - application.addWebOrigin("origin-2"); + client.addWebOrigin("origin-1"); + client.addWebOrigin("origin-2"); - application.registerNode("node1", 10); - application.registerNode("10.20.30.40", 50); + client.registerNode("node1", 10); + client.registerNode("10.20.30.40", 50); - application.updateApplication(); + client.updateApplication(); } @Test @@ -56,26 +56,26 @@ public class ClientModelTest extends AbstractModelTest { RealmModel persisted = realmManager.getRealm(realm.getId()); ClientModel actual = persisted.getClientNameMap().get("app-name"); - assertEquals(application, actual); + assertEquals(client, actual); } @Test public void json() { - ApplicationRepresentation representation = ModelToRepresentation.toRepresentation(application); + ClientRepresentation representation = ModelToRepresentation.toRepresentation(client); representation.setId(null); RealmModel realm = realmManager.createRealm("copy"); - ClientModel copy = RepresentationToModel.createApplication(session, realm, representation, true); + ClientModel copy = RepresentationToModel.createClient(session, realm, representation, true); - assertEquals(application, copy); + assertEquals(client, copy); } @Test public void testAddApplicationWithId() { - application = realm.addClient("app-123", "application2"); + client = realm.addClient("app-123", "application2"); commit(); - application = realmManager.getRealm(realm.getId()).getClientById("app-123"); - Assert.assertNotNull(application); + client = realmManager.getRealm(realm.getId()).getClientById("app-123"); + Assert.assertNotNull(client); } From f435a8c6df0d5b99574f456bfc1b5694b3319b22 Mon Sep 17 00:00:00 2001 From: Stian Thorgersen Date: Fri, 10 Apr 2015 13:35:27 +0200 Subject: [PATCH 10/15] Remove @Test on methods in AdapterTestStrategy. These are not executed from other test classes. Having the @Test on methods in a non-empty constructor causes IntelliJ to complain --- .../testsuite/adapter/AdapterTestStrategy.java | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/AdapterTestStrategy.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/AdapterTestStrategy.java index 39f2731f5e..dcbdcbf6c3 100755 --- a/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/AdapterTestStrategy.java +++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/AdapterTestStrategy.java @@ -150,7 +150,6 @@ public class AdapterTestStrategy extends ExternalResource { } } - @Test public void testSavedPostRequest() throws Exception { // test login to customer-portal which does a bearer request to customer-db driver.navigate().to(APP_SERVER_BASE_URL + "/input-portal"); @@ -189,7 +188,6 @@ public class AdapterTestStrategy extends ExternalResource { } - @Test public void testLoginSSOAndLogout() throws Exception { // test login to customer-portal which does a bearer request to customer-db driver.navigate().to(APP_SERVER_BASE_URL + "/customer-portal"); @@ -246,7 +244,6 @@ public class AdapterTestStrategy extends ExternalResource { } - @Test public void testServletRequestLogout() throws Exception { // test login to customer-portal which does a bearer request to customer-db driver.navigate().to(APP_SERVER_BASE_URL + "/customer-portal"); @@ -288,7 +285,6 @@ public class AdapterTestStrategy extends ExternalResource { } - @Test public void testLoginSSOIdle() throws Exception { // test login to customer-portal which does a bearer request to customer-db driver.navigate().to(APP_SERVER_BASE_URL + "/customer-portal"); @@ -322,7 +318,6 @@ public class AdapterTestStrategy extends ExternalResource { session.close(); } - @Test public void testLoginSSOIdleRemoveExpiredUserSessions() throws Exception { // test login to customer-portal which does a bearer request to customer-db driver.navigate().to(APP_SERVER_BASE_URL + "/customer-portal"); @@ -364,7 +359,6 @@ public class AdapterTestStrategy extends ExternalResource { session.close(); } - @Test public void testLoginSSOMax() throws Exception { // test login to customer-portal which does a bearer request to customer-db driver.navigate().to(APP_SERVER_BASE_URL + "/customer-portal"); @@ -402,7 +396,6 @@ public class AdapterTestStrategy extends ExternalResource { * KEYCLOAK-518 * @throws Exception */ - @Test public void testNullBearerToken() throws Exception { Client client = ClientBuilder.newClient(); WebTarget target = client.target(APP_SERVER_BASE_URL + "/customer-db/"); @@ -420,7 +413,6 @@ public class AdapterTestStrategy extends ExternalResource { * KEYCLOAK-518 * @throws Exception */ - @Test public void testBadUser() throws Exception { Client client = ClientBuilder.newClient(); UriBuilder builder = UriBuilder.fromUri(AUTH_SERVER_URL); @@ -440,7 +432,6 @@ public class AdapterTestStrategy extends ExternalResource { } - @Test public void testVersion() throws Exception { Client client = ClientBuilder.newClient(); WebTarget target = client.target(AUTH_SERVER_URL).path("version"); @@ -463,7 +454,6 @@ public class AdapterTestStrategy extends ExternalResource { - @Test public void testAuthenticated() throws Exception { // test login to customer-portal which does a bearer request to customer-db driver.navigate().to(APP_SERVER_BASE_URL + "/secure-portal"); @@ -491,7 +481,6 @@ public class AdapterTestStrategy extends ExternalResource { * * @throws Throwable */ - @Test public void testSingleSessionInvalidated() throws Throwable { AdapterTestStrategy browser1 = this; AdapterTestStrategy browser2 = new AdapterTestStrategy(AUTH_SERVER_URL, APP_SERVER_BASE_URL, keycloakRule); @@ -529,7 +518,6 @@ public class AdapterTestStrategy extends ExternalResource { /** * KEYCLOAK-741 */ - @Test public void testSessionInvalidatedAfterFailedRefresh() throws Throwable { final AtomicInteger origTokenLifespan = new AtomicInteger(); @@ -581,7 +569,6 @@ public class AdapterTestStrategy extends ExternalResource { /** * KEYCLOAK-942 */ - @Test public void testAdminApplicationLogout() throws Throwable { // login as bburke loginAndCheckSession(driver, loginPage); From 9a047eda36935eb81ebfb00301079597cef62a23 Mon Sep 17 00:00:00 2001 From: Stian Thorgersen Date: Mon, 13 Apr 2015 10:13:32 +0200 Subject: [PATCH 11/15] KEYCLOAK-1187 Updated representations --- .../ApplicationMappingsRepresentation.java | 38 --------- .../idm/ClientMappingsRepresentation.java | 38 +++++++++ .../idm/MappingsRepresentation.java | 10 +-- .../idm/RealmRepresentation.java | 58 ++++++------- .../idm/RoleRepresentation.java | 16 ++-- .../idm/RolesRepresentation.java | 15 +++- .../idm/UserRepresentation.java | 20 +++-- .../idm/UserSessionRepresentation.java | 9 -- .../src/main/java/org/keycloak/util/Time.java | 4 + .../exportimport/util/ExportUtils.java | 62 +++++++------- .../models/utils/ModelToRepresentation.java | 7 +- .../models/utils/RepresentationToModel.java | 83 ++++++++++++------- .../resources/admin/ScopeMappedResource.java | 22 ++--- .../resources/admin/UsersResource.java | 12 +-- .../keycloak/testsuite/admin/ClientTest.java | 2 +- .../src/test/resources/testrealm.json | 10 +-- 16 files changed, 220 insertions(+), 186 deletions(-) delete mode 100755 core/src/main/java/org/keycloak/representations/idm/ApplicationMappingsRepresentation.java create mode 100755 core/src/main/java/org/keycloak/representations/idm/ClientMappingsRepresentation.java diff --git a/core/src/main/java/org/keycloak/representations/idm/ApplicationMappingsRepresentation.java b/core/src/main/java/org/keycloak/representations/idm/ApplicationMappingsRepresentation.java deleted file mode 100755 index 30b94d2905..0000000000 --- a/core/src/main/java/org/keycloak/representations/idm/ApplicationMappingsRepresentation.java +++ /dev/null @@ -1,38 +0,0 @@ -package org.keycloak.representations.idm; - -import java.util.List; - -/** - * @author Bill Burke - * @version $Revision: 1 $ - */ -public class ApplicationMappingsRepresentation { - protected String applicationId; - protected String application; - - protected List mappings; - - public String getApplicationId() { - return applicationId; - } - - public void setApplicationId(String applicationId) { - this.applicationId = applicationId; - } - - public String getApplication() { - return application; - } - - public void setApplication(String application) { - this.application = application; - } - - public List getMappings() { - return mappings; - } - - public void setMappings(List mappings) { - this.mappings = mappings; - } -} diff --git a/core/src/main/java/org/keycloak/representations/idm/ClientMappingsRepresentation.java b/core/src/main/java/org/keycloak/representations/idm/ClientMappingsRepresentation.java new file mode 100755 index 0000000000..8f87c8ab68 --- /dev/null +++ b/core/src/main/java/org/keycloak/representations/idm/ClientMappingsRepresentation.java @@ -0,0 +1,38 @@ +package org.keycloak.representations.idm; + +import java.util.List; + +/** + * @author Bill Burke + * @version $Revision: 1 $ + */ +public class ClientMappingsRepresentation { + protected String id; + protected String client; + + protected List mappings; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getClient() { + return client; + } + + public void setClient(String client) { + this.client = client; + } + + public List getMappings() { + return mappings; + } + + public void setMappings(List mappings) { + this.mappings = mappings; + } +} diff --git a/core/src/main/java/org/keycloak/representations/idm/MappingsRepresentation.java b/core/src/main/java/org/keycloak/representations/idm/MappingsRepresentation.java index 8172a2a2db..b7e90b8c75 100755 --- a/core/src/main/java/org/keycloak/representations/idm/MappingsRepresentation.java +++ b/core/src/main/java/org/keycloak/representations/idm/MappingsRepresentation.java @@ -9,7 +9,7 @@ import java.util.Map; */ public class MappingsRepresentation { protected List realmMappings; - protected Map applicationMappings; + protected Map clientMappings; public List getRealmMappings() { return realmMappings; @@ -19,11 +19,11 @@ public class MappingsRepresentation { this.realmMappings = realmMappings; } - public Map getApplicationMappings() { - return applicationMappings; + public Map getClientMappings() { + return clientMappings; } - public void setApplicationMappings(Map applicationMappings) { - this.applicationMappings = applicationMappings; + public void setClientMappings(Map clientMappings) { + this.clientMappings = clientMappings; } } diff --git a/core/src/main/java/org/keycloak/representations/idm/RealmRepresentation.java b/core/src/main/java/org/keycloak/representations/idm/RealmRepresentation.java index aad60685ed..cbd5a777ce 100755 --- a/core/src/main/java/org/keycloak/representations/idm/RealmRepresentation.java +++ b/core/src/main/java/org/keycloak/representations/idm/RealmRepresentation.java @@ -25,13 +25,6 @@ public class RealmRepresentation { protected Boolean verifyEmail; protected Boolean resetPasswordAllowed; - @Deprecated - protected Boolean social; - @Deprecated - protected Boolean updateProfileOnInitialSocialLogin; - @Deprecated - protected Map socialProviders; - protected Boolean userCacheEnabled; protected Boolean realmCacheEnabled; @@ -55,12 +48,8 @@ public class RealmRepresentation { protected String passwordPolicy; protected List users; protected List scopeMappings; - protected Map> applicationScopeMappings; + protected Map> clientScopeMappings; protected List clients; - @Deprecated - protected List applications; - @Deprecated - protected List oauthClients; protected Map browserSecurityHeaders; protected Map smtpServer; protected List userFederationProviders; @@ -79,6 +68,18 @@ public class RealmRepresentation { protected Set supportedLocales; protected String defaultLocale; + @Deprecated + protected Boolean social; + @Deprecated + protected Boolean updateProfileOnInitialSocialLogin; + @Deprecated + protected Map socialProviders; + @Deprecated + protected Map> applicationScopeMappings; + @Deprecated + protected List applications; + @Deprecated + protected List oauthClients; public String getId() { return id; @@ -124,10 +125,6 @@ public class RealmRepresentation { this.clients = clients; } - public void setApplications(List applications) { - this.applications = applications; - } - public Boolean isEnabled() { return enabled; } @@ -324,22 +321,16 @@ public class RealmRepresentation { this.resetPasswordAllowed = resetPassword; } + @Deprecated public Boolean isSocial() { return social; } - public void setSocial(Boolean social) { - this.social = social; - } - + @Deprecated public Boolean isUpdateProfileOnInitialSocialLogin() { return updateProfileOnInitialSocialLogin; } - public void setUpdateProfileOnInitialSocialLogin(Boolean updateProfileOnInitialSocialLogin) { - this.updateProfileOnInitialSocialLogin = updateProfileOnInitialSocialLogin; - } - public Map getBrowserSecurityHeaders() { return browserSecurityHeaders; } @@ -348,14 +339,11 @@ public class RealmRepresentation { this.browserSecurityHeaders = browserSecurityHeaders; } + @Deprecated public Map getSocialProviders() { return socialProviders; } - public void setSocialProviders(Map socialProviders) { - this.socialProviders = socialProviders; - } - public Map getSmtpServer() { return smtpServer; } @@ -364,22 +352,24 @@ public class RealmRepresentation { this.smtpServer = smtpServer; } + @Deprecated public List getOauthClients() { return oauthClients; } - public void setOauthClients(List oauthClients) { - this.oauthClients = oauthClients; + public Map> getClientScopeMappings() { + return clientScopeMappings; } + public void setClientScopeMappings(Map> clientScopeMappings) { + this.clientScopeMappings = clientScopeMappings; + } + + @Deprecated public Map> getApplicationScopeMappings() { return applicationScopeMappings; } - public void setApplicationScopeMappings(Map> applicationScopeMappings) { - this.applicationScopeMappings = applicationScopeMappings; - } - public RolesRepresentation getRoles() { return roles; } diff --git a/core/src/main/java/org/keycloak/representations/idm/RoleRepresentation.java b/core/src/main/java/org/keycloak/representations/idm/RoleRepresentation.java index 34ea91f841..9d0909d770 100755 --- a/core/src/main/java/org/keycloak/representations/idm/RoleRepresentation.java +++ b/core/src/main/java/org/keycloak/representations/idm/RoleRepresentation.java @@ -17,9 +17,10 @@ public class RoleRepresentation { public static class Composites { protected Set realm; + protected Map> client; + @Deprecated protected Map> application; - public Set getRealm() { return realm; } @@ -28,12 +29,17 @@ public class RoleRepresentation { this.realm = realm; } - public Map> getApplication() { - return application; + public Map> getClient() { + return client; } - public void setApplication(Map> application) { - this.application = application; + public void setClient(Map> client) { + this.client = client; + } + + @Deprecated + public Map> getApplication() { + return application; } } diff --git a/core/src/main/java/org/keycloak/representations/idm/RolesRepresentation.java b/core/src/main/java/org/keycloak/representations/idm/RolesRepresentation.java index 496f7385bb..afeb96afd5 100755 --- a/core/src/main/java/org/keycloak/representations/idm/RolesRepresentation.java +++ b/core/src/main/java/org/keycloak/representations/idm/RolesRepresentation.java @@ -9,6 +9,8 @@ import java.util.Map; */ public class RolesRepresentation { protected List realm; + protected Map> client; + @Deprecated protected Map> application; public List getRealm() { @@ -19,11 +21,16 @@ public class RolesRepresentation { this.realm = realm; } + public Map> getClient() { + return client; + } + + public void setClient(Map> client) { + this.client = client; + } + + @Deprecated public Map> getApplication() { return application; } - - public void setApplication(Map> application) { - this.application = application; - } } diff --git a/core/src/main/java/org/keycloak/representations/idm/UserRepresentation.java b/core/src/main/java/org/keycloak/representations/idm/UserRepresentation.java index d2907d54a6..94a90d9e45 100755 --- a/core/src/main/java/org/keycloak/representations/idm/UserRepresentation.java +++ b/core/src/main/java/org/keycloak/representations/idm/UserRepresentation.java @@ -25,10 +25,13 @@ public class UserRepresentation { protected List credentials; protected List requiredActions; protected List federatedIdentities; + protected List realmRoles; + protected Map> clientRoles; + + @Deprecated + protected Map> applicationRoles; @Deprecated protected List socialLinks; - protected List realmRoles; - protected Map> applicationRoles; public String getSelf() { return self; @@ -165,12 +168,17 @@ public class UserRepresentation { this.realmRoles = realmRoles; } - public Map> getApplicationRoles() { - return applicationRoles; + public Map> getClientRoles() { + return clientRoles; } - public void setApplicationRoles(Map> applicationRoles) { - this.applicationRoles = applicationRoles; + public void setClientRoles(Map> clientRoles) { + this.clientRoles = clientRoles; + } + + @Deprecated + public Map> getApplicationRoles() { + return applicationRoles; } public String getFederationLink() { diff --git a/core/src/main/java/org/keycloak/representations/idm/UserSessionRepresentation.java b/core/src/main/java/org/keycloak/representations/idm/UserSessionRepresentation.java index 3035d2dfe8..6701f6acfa 100755 --- a/core/src/main/java/org/keycloak/representations/idm/UserSessionRepresentation.java +++ b/core/src/main/java/org/keycloak/representations/idm/UserSessionRepresentation.java @@ -15,7 +15,6 @@ public class UserSessionRepresentation { private String ipAddress; private long start; private long lastAccess; - private Map applications = new HashMap(); private Map clients = new HashMap(); public String getId() { @@ -58,14 +57,6 @@ public class UserSessionRepresentation { this.lastAccess = lastAccess; } - public Map getApplications() { - return applications; - } - - public void setApplications(Map applications) { - this.applications = applications; - } - public Map getClients() { return clients; } diff --git a/core/src/main/java/org/keycloak/util/Time.java b/core/src/main/java/org/keycloak/util/Time.java index 7da54f1f27..a5334ddb03 100644 --- a/core/src/main/java/org/keycloak/util/Time.java +++ b/core/src/main/java/org/keycloak/util/Time.java @@ -17,6 +17,10 @@ public class Time { return new Date(((long) time ) * 1000); } + public static long toMillis(int time) { + return ((long) time) * 1000; + } + public static void setOffset(int offset) { Time.offset = offset; } diff --git a/export-import/export-import-api/src/main/java/org/keycloak/exportimport/util/ExportUtils.java b/export-import/export-import-api/src/main/java/org/keycloak/exportimport/util/ExportUtils.java index 43d1f6b889..c404c3d3ad 100755 --- a/export-import/export-import-api/src/main/java/org/keycloak/exportimport/util/ExportUtils.java +++ b/export-import/export-import-api/src/main/java/org/keycloak/exportimport/util/ExportUtils.java @@ -65,30 +65,30 @@ public class ExportUtils { // Roles List realmRoleReps = null; - Map> appRolesReps = new HashMap>(); + Map> clientRolesReps = new HashMap<>(); Set realmRoles = realm.getRoles(); if (realmRoles != null && realmRoles.size() > 0) { realmRoleReps = exportRoles(realmRoles); } - for (ClientModel app : clients) { - Set currentAppRoles = app.getRoles(); + for (ClientModel client : clients) { + Set currentAppRoles = client.getRoles(); List currentAppRoleReps = exportRoles(currentAppRoles); - appRolesReps.put(app.getClientId(), currentAppRoleReps); + clientRolesReps.put(client.getClientId(), currentAppRoleReps); } RolesRepresentation rolesRep = new RolesRepresentation(); if (realmRoleReps != null) { rolesRep.setRealm(realmRoleReps); } - if (appRolesReps.size() > 0) { - rolesRep.setApplication(appRolesReps); + if (clientRolesReps.size() > 0) { + rolesRep.setClient(clientRolesReps); } rep.setRoles(rolesRep); // Scopes List allClients = new ArrayList<>(clients); - Map> appScopeReps = new HashMap<>(); + Map> clientScopeReps = new HashMap<>(); for (ClientModel client : allClients) { Set clientScopes = client.getScopeMappings(); @@ -102,10 +102,10 @@ public class ExportUtils { } else { ClientModel app = (ClientModel)scope.getContainer(); String appName = app.getClientId(); - List currentAppScopes = appScopeReps.get(appName); + List currentAppScopes = clientScopeReps.get(appName); if (currentAppScopes == null) { currentAppScopes = new ArrayList<>(); - appScopeReps.put(appName, currentAppScopes); + clientScopeReps.put(appName, currentAppScopes); } ScopeMappingRepresentation currentClientScope = null; @@ -125,8 +125,8 @@ public class ExportUtils { } } - if (appScopeReps.size() > 0) { - rep.setApplicationScopeMappings(appScopeReps); + if (clientScopeReps.size() > 0) { + rep.setClientScopeMappings(clientScopeReps); } // Finally users if needed @@ -186,27 +186,27 @@ public class ExportUtils { Set composites = role.getComposites(); if (composites != null && composites.size() > 0) { Set compositeRealmRoles = null; - Map> compositeAppRoles = null; + Map> compositeClientRoles = null; for (RoleModel composite : composites) { RoleContainerModel crContainer = composite.getContainer(); if (crContainer instanceof RealmModel) { if (compositeRealmRoles == null) { - compositeRealmRoles = new HashSet(); + compositeRealmRoles = new HashSet<>(); } compositeRealmRoles.add(composite.getName()); } else { - if (compositeAppRoles == null) { - compositeAppRoles = new HashMap>(); + if (compositeClientRoles == null) { + compositeClientRoles = new HashMap<>(); } ClientModel app = (ClientModel)crContainer; String appName = app.getClientId(); - List currentAppComposites = compositeAppRoles.get(appName); + List currentAppComposites = compositeClientRoles.get(appName); if (currentAppComposites == null) { - currentAppComposites = new ArrayList(); - compositeAppRoles.put(appName, currentAppComposites); + currentAppComposites = new ArrayList<>(); + compositeClientRoles.put(appName, currentAppComposites); } currentAppComposites.add(composite.getName()); } @@ -216,8 +216,8 @@ public class ExportUtils { if (compositeRealmRoles != null) { compRep.setRealm(compositeRealmRoles); } - if (compositeAppRoles != null) { - compRep.setApplication(compositeAppRoles); + if (compositeClientRoles != null) { + compRep.setClient(compositeClientRoles); } roleRep.setComposites(compRep); @@ -248,29 +248,29 @@ public class ExportUtils { // Role mappings Set roles = user.getRoleMappings(); - List realmRoleNames = new ArrayList(); - Map> appRoleNames = new HashMap>(); + List realmRoleNames = new ArrayList<>(); + Map> clientRoleNames = new HashMap<>(); for (RoleModel role : roles) { if (role.getContainer() instanceof RealmModel) { realmRoleNames.add(role.getName()); } else { - ClientModel app = (ClientModel)role.getContainer(); - String appName = app.getClientId(); - List currentAppRoles = appRoleNames.get(appName); - if (currentAppRoles == null) { - currentAppRoles = new ArrayList(); - appRoleNames.put(appName, currentAppRoles); + ClientModel client = (ClientModel)role.getContainer(); + String clientId = client.getClientId(); + List currentClientRoles = clientRoleNames.get(clientId); + if (currentClientRoles == null) { + currentClientRoles = new ArrayList<>(); + clientRoleNames.put(clientId, currentClientRoles); } - currentAppRoles.add(role.getName()); + currentClientRoles.add(role.getName()); } } if (realmRoleNames.size() > 0) { userRep.setRealmRoles(realmRoleNames); } - if (appRoleNames.size() > 0) { - userRep.setApplicationRoles(appRoleNames); + if (clientRoleNames.size() > 0) { + userRep.setClientRoles(clientRoleNames); } // Credentials diff --git a/model/api/src/main/java/org/keycloak/models/utils/ModelToRepresentation.java b/model/api/src/main/java/org/keycloak/models/utils/ModelToRepresentation.java index f9e3556d77..dc1124ae54 100755 --- a/model/api/src/main/java/org/keycloak/models/utils/ModelToRepresentation.java +++ b/model/api/src/main/java/org/keycloak/models/utils/ModelToRepresentation.java @@ -26,6 +26,7 @@ import org.keycloak.representations.idm.RoleRepresentation; import org.keycloak.representations.idm.UserFederationProviderRepresentation; import org.keycloak.representations.idm.UserRepresentation; import org.keycloak.representations.idm.UserSessionRepresentation; +import org.keycloak.util.Time; import java.util.ArrayList; import java.util.HashMap; @@ -207,13 +208,13 @@ public class ModelToRepresentation { public static UserSessionRepresentation toRepresentation(UserSessionModel session) { UserSessionRepresentation rep = new UserSessionRepresentation(); rep.setId(session.getId()); - rep.setStart(((long)session.getStarted()) * 1000L); - rep.setLastAccess(((long)session.getLastSessionRefresh())* 1000L); + rep.setStart(Time.toMillis(session.getStarted())); + rep.setLastAccess(Time.toMillis(session.getLastSessionRefresh())); rep.setUser(session.getUser().getUsername()); rep.setIpAddress(session.getIpAddress()); for (ClientSessionModel clientSession : session.getClientSessions()) { ClientModel client = clientSession.getClient(); - rep.getApplications().put(client.getId(), client.getClientId()); + rep.getClients().put(client.getId(), client.getClientId()); } return rep; } diff --git a/model/api/src/main/java/org/keycloak/models/utils/RepresentationToModel.java b/model/api/src/main/java/org/keycloak/models/utils/RepresentationToModel.java index cf8de18d16..c8a976100a 100755 --- a/model/api/src/main/java/org/keycloak/models/utils/RepresentationToModel.java +++ b/model/api/src/main/java/org/keycloak/models/utils/RepresentationToModel.java @@ -139,15 +139,15 @@ public class RepresentationToModel { createRole(newRealm, roleRep); } } - if (rep.getRoles().getApplication() != null) { - for (Map.Entry> entry : rep.getRoles().getApplication().entrySet()) { - ClientModel app = newRealm.getClientByClientId(entry.getKey()); - if (app == null) { + if (rep.getRoles().getClient() != null) { + for (Map.Entry> entry : rep.getRoles().getClient().entrySet()) { + ClientModel client = newRealm.getClientByClientId(entry.getKey()); + if (client == null) { throw new RuntimeException("App doesn't exist in role definitions: " + entry.getKey()); } for (RoleRepresentation roleRep : entry.getValue()) { // Application role may already exists (for example if it is defaultRole) - RoleModel role = roleRep.getId()!=null ? app.addRole(roleRep.getId(), roleRep.getName()) : app.addRole(roleRep.getName()); + RoleModel role = roleRep.getId()!=null ? client.addRole(roleRep.getId(), roleRep.getName()) : client.addRole(roleRep.getName()); role.setDescription(roleRep.getDescription()); } } @@ -159,14 +159,14 @@ public class RepresentationToModel { addComposites(role, roleRep, newRealm); } } - if (rep.getRoles().getApplication() != null) { - for (Map.Entry> entry : rep.getRoles().getApplication().entrySet()) { - ClientModel app = newRealm.getClientByClientId(entry.getKey()); - if (app == null) { + if (rep.getRoles().getClient() != null) { + for (Map.Entry> entry : rep.getRoles().getClient().entrySet()) { + ClientModel client = newRealm.getClientByClientId(entry.getKey()); + if (client == null) { throw new RuntimeException("App doesn't exist in role definitions: " + entry.getKey()); } for (RoleRepresentation roleRep : entry.getValue()) { - RoleModel role = app.getRole(roleRep.getName()); + RoleModel role = client.getRole(roleRep.getName()); addComposites(role, roleRep, newRealm); } } @@ -193,9 +193,9 @@ public class RepresentationToModel { Map appMap = newRealm.getClientNameMap(); - if (rep.getApplicationScopeMappings() != null) { + if (rep.getClientScopeMappings() != null) { - for (Map.Entry> entry : rep.getApplicationScopeMappings().entrySet()) { + for (Map.Entry> entry : rep.getClientScopeMappings().entrySet()) { ClientModel app = appMap.get(entry.getKey()); if (app == null) { throw new RuntimeException("Unable to find client role mappings for client: " + entry.getKey()); @@ -285,10 +285,6 @@ public class RepresentationToModel { rep.setIdentityProviders(identityProviders); } } - - rep.setSocial(null); - rep.setSocialProviders(null); - rep.setUpdateProfileOnInitialSocialLogin(false); } private static void convertDeprecatedSocialProviders(UserRepresentation user) { @@ -341,8 +337,40 @@ public class RepresentationToModel { realm.getClients().add(app); } + } - realm.setApplications(null); + if (realm.getApplicationScopeMappings() != null && realm.getClientScopeMappings() == null) { + realm.setClientScopeMappings(realm.getApplicationScopeMappings()); + } + + if (realm.getRoles() != null && realm.getRoles().getApplication() != null && realm.getRoles().getClient() == null) { + realm.getRoles().setClient(realm.getRoles().getApplication()); + } + + if (realm.getUsers() != null) { + for (UserRepresentation user : realm.getUsers()) { + if (user.getApplicationRoles() != null && user.getClientRoles() == null) { + user.setClientRoles(user.getApplicationRoles()); + } + } + } + + if (realm.getRoles() != null && realm.getRoles().getRealm() != null) { + for (RoleRepresentation role : realm.getRoles().getRealm()) { + if (role.getComposites() != null && role.getComposites().getApplication() != null && role.getComposites().getClient() == null) { + role.getComposites().setClient(role.getComposites().getApplication()); + } + } + } + + if (realm.getRoles() != null && realm.getRoles().getClient() != null) { + for (Map.Entry> clientRoles : realm.getRoles().getClient().entrySet()) { + for (RoleRepresentation role : clientRoles.getValue()) { + if (role.getComposites() != null && role.getComposites().getApplication() != null && role.getComposites().getClient() == null) { + role.getComposites().setClient(role.getComposites().getApplication()); + } + } + } } } @@ -453,25 +481,24 @@ public class RepresentationToModel { role.addCompositeRole(realmRole); } } - if (roleRep.getComposites().getApplication() != null) { - for (Map.Entry> entry : roleRep.getComposites().getApplication().entrySet()) { - ClientModel app = realm.getClientByClientId(entry.getKey()); - if (app == null) { + if (roleRep.getComposites().getClient() != null) { + for (Map.Entry> entry : roleRep.getComposites().getClient().entrySet()) { + ClientModel client = realm.getClientByClientId(entry.getKey()); + if (client == null) { throw new RuntimeException("App doesn't exist in role definitions: " + roleRep.getName()); } for (String roleStr : entry.getValue()) { - RoleModel appRole = app.getRole(roleStr); - if (appRole == null) throw new RuntimeException("Unable to find composite app role: " + roleStr); - role.addCompositeRole(appRole); + RoleModel clientRole = client.getRole(roleStr); + if (clientRole == null) throw new RuntimeException("Unable to find composite client role: " + roleStr); + role.addCompositeRole(clientRole); } - } } } - // APPLICATIONS + // CLIENTS private static Map createClients(KeycloakSession session, RealmRepresentation rep, RealmModel realm) { Map appMap = new HashMap(); @@ -753,8 +780,8 @@ public class RepresentationToModel { user.grantRole(role); } } - if (userRep.getApplicationRoles() != null) { - for (Map.Entry> entry : userRep.getApplicationRoles().entrySet()) { + if (userRep.getClientRoles() != null) { + for (Map.Entry> entry : userRep.getClientRoles().entrySet()) { ClientModel client = clientMap.get(entry.getKey()); if (client == null) { throw new RuntimeException("Unable to find client role mappings for client: " + entry.getKey()); diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ScopeMappedResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ScopeMappedResource.java index 2dda52bab3..28b63ced08 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/ScopeMappedResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/ScopeMappedResource.java @@ -7,7 +7,7 @@ import org.keycloak.models.KeycloakSession; import org.keycloak.models.RealmModel; import org.keycloak.models.RoleModel; import org.keycloak.models.utils.ModelToRepresentation; -import org.keycloak.representations.idm.ApplicationMappingsRepresentation; +import org.keycloak.representations.idm.ClientMappingsRepresentation; import org.keycloak.representations.idm.MappingsRepresentation; import org.keycloak.representations.idm.RoleRepresentation; @@ -64,22 +64,22 @@ public class ScopeMappedResource { all.setRealmMappings(realmRep); } - List applications = realm.getClients(); - if (applications.size() > 0) { - Map appMappings = new HashMap(); - for (ClientModel app : applications) { - Set roleMappings = app.getApplicationScopeMappings(client); + List clients = realm.getClients(); + if (clients.size() > 0) { + Map clientMappings = new HashMap(); + for (ClientModel client : clients) { + Set roleMappings = client.getApplicationScopeMappings(this.client); if (roleMappings.size() > 0) { - ApplicationMappingsRepresentation mappings = new ApplicationMappingsRepresentation(); - mappings.setApplicationId(app.getId()); - mappings.setApplication(app.getClientId()); + ClientMappingsRepresentation mappings = new ClientMappingsRepresentation(); + mappings.setId(client.getId()); + mappings.setClient(client.getClientId()); List roles = new ArrayList(); mappings.setMappings(roles); for (RoleModel role : roleMappings) { roles.add(ModelToRepresentation.toRepresentation(role)); } - appMappings.put(app.getClientId(), mappings); - all.setApplicationMappings(appMappings); + clientMappings.put(client.getClientId(), mappings); + all.setClientMappings(clientMappings); } } } diff --git a/services/src/main/java/org/keycloak/services/resources/admin/UsersResource.java b/services/src/main/java/org/keycloak/services/resources/admin/UsersResource.java index e42417539e..eec34c8d65 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/UsersResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/UsersResource.java @@ -25,7 +25,7 @@ import org.keycloak.models.utils.RepresentationToModel; import org.keycloak.protocol.oidc.OIDCLoginProtocol; import org.keycloak.protocol.oidc.TokenManager; import org.keycloak.protocol.oidc.utils.RedirectUtils; -import org.keycloak.representations.idm.ApplicationMappingsRepresentation; +import org.keycloak.representations.idm.ClientMappingsRepresentation; import org.keycloak.representations.idm.CredentialRepresentation; import org.keycloak.representations.idm.FederatedIdentityRepresentation; import org.keycloak.representations.idm.MappingsRepresentation; @@ -441,20 +441,20 @@ public class UsersResource { List applications = realm.getClients(); if (applications.size() > 0) { - Map appMappings = new HashMap(); + Map appMappings = new HashMap(); for (ClientModel application : applications) { Set roleMappings = user.getApplicationRoleMappings(application); if (roleMappings.size() > 0) { - ApplicationMappingsRepresentation mappings = new ApplicationMappingsRepresentation(); - mappings.setApplicationId(application.getId()); - mappings.setApplication(application.getClientId()); + ClientMappingsRepresentation mappings = new ClientMappingsRepresentation(); + mappings.setId(application.getId()); + mappings.setClient(application.getClientId()); List roles = new ArrayList(); mappings.setMappings(roles); for (RoleModel role : roleMappings) { roles.add(ModelToRepresentation.toRepresentation(role)); } appMappings.put(application.getClientId(), mappings); - all.setApplicationMappings(appMappings); + all.setClientMappings(appMappings); } } } diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/admin/ClientTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/admin/ClientTest.java index 7dc995223b..8151ca5194 100644 --- a/testsuite/integration/src/test/java/org/keycloak/testsuite/admin/ClientTest.java +++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/admin/ClientTest.java @@ -87,7 +87,7 @@ public class ClientTest extends AbstractClientTest { List userSessions = app.getUserSessions(0, 100); assertEquals(2, userSessions.size()); - assertEquals(1, userSessions.get(0).getApplications().size()); + assertEquals(1, userSessions.get(0).getClients().size()); } @Test diff --git a/testsuite/integration/src/test/resources/testrealm.json b/testsuite/integration/src/test/resources/testrealm.json index cedc22dbae..b33febcd54 100755 --- a/testsuite/integration/src/test/resources/testrealm.json +++ b/testsuite/integration/src/test/resources/testrealm.json @@ -27,7 +27,7 @@ "value" : "password" } ], "realmRoles": ["user"], - "applicationRoles": { + "clientRoles": { "test-app": [ "customer-user" ], "account": [ "view-profile", "manage-account" ] } @@ -41,7 +41,7 @@ "value" : "password" } ], "realmRoles": ["user"], - "applicationRoles": { + "clientRoles": { "test-app": [ "customer-user" ], "account": [ "view-profile", "manage-account" ] } @@ -67,7 +67,7 @@ "roles": ["user"] } ], - "applications": [ + "clients": [ { "name": "test-app", "enabled": true, @@ -90,7 +90,7 @@ "description": "Have Administrator privileges" } ], - "application" : { + "client" : { "test-app" : [ { "name": "customer-user", @@ -105,7 +105,7 @@ }, - "applicationScopeMappings": { + "clientScopeMappings": { "test-app": [ { "client": "third-party", From 4fbbf39c51387e0090360c8435bbadef4bb50181 Mon Sep 17 00:00:00 2001 From: Stian Thorgersen Date: Mon, 13 Apr 2015 13:29:31 +0200 Subject: [PATCH 12/15] KEYCLOAK-1187 Admin console and endpoints --- .../oidc/KeycloakOIDCIdentityProvider.java | 4 +- .../keycloak/constants/AdapterConstants.java | 6 +- .../exportimport/util/ImportUtils.java | 8 +- .../main/resources/theme/base/admin/index.ftl | 3 +- .../theme/base/admin/resources/js/app.js | 278 ++++---- .../{applications.js => clients.js} | 622 +++++++++--------- .../admin/resources/js/controllers/realm.js | 102 +-- .../admin/resources/js/controllers/users.js | 98 +-- .../theme/base/admin/resources/js/loaders.js | 56 +- .../theme/base/admin/resources/js/services.js | 274 ++++---- .../resources/partials/application-list.html | 59 -- ...-node.html => client-clustering-node.html} | 10 +- ...clustering.html => client-clustering.html} | 20 +- ...edentials.html => client-credentials.html} | 12 +- ...ication-detail.html => client-detail.html} | 76 +-- ...der.html => client-identity-provider.html} | 14 +- ...ication-import.html => client-import.html} | 4 +- ...allation.html => client-installation.html} | 8 +- ...application-keys.html => client-keys.html} | 10 +- .../admin/resources/partials/client-list.html | 47 ++ ...ppers-add.html => client-mappers-add.html} | 10 +- ...ation-mappers.html => client-mappers.html} | 14 +- ...revocation.html => client-revocation.html} | 12 +- ...le-detail.html => client-role-detail.html} | 52 +- ...n-role-list.html => client-role-list.html} | 14 +- ...xport.html => client-saml-key-export.html} | 10 +- ...mport.html => client-saml-key-import.html} | 10 +- ...n-saml-keys.html => client-saml-keys.html} | 12 +- ...ppings.html => client-scope-mappings.html} | 50 +- ...ion-sessions.html => client-sessions.html} | 12 +- .../partials/protocol-mapper-detail.html | 14 +- .../partials/realm-cache-settings.html | 2 +- .../partials/realm-default-roles.html | 32 +- .../resources/partials/realm-detail.html | 2 +- .../realm-identity-provider-oidc.html | 4 +- .../realm-identity-provider-social.html | 4 +- ...m-identity-provider-stackoverflow-ext.html | 2 +- .../admin/resources/partials/realm-menu.html | 6 +- .../resources/partials/realm-tokens.html | 3 +- .../admin/resources/partials/role-detail.html | 32 +- .../resources/partials/role-mappings.html | 38 +- .../resources/partials/session-realm.html | 4 +- .../partials/session-revocation.html | 2 +- .../resources/partials/user-sessions.html | 12 +- .../templates/kc-navigation-application.html | 13 - .../templates/kc-navigation-client.html | 13 + .../org/keycloak/adapters/ServerRequest.java | 6 +- .../java/org/keycloak/models/ClientModel.java | 2 +- .../java/org/keycloak/models/Constants.java | 4 +- .../java/org/keycloak/models/RealmModel.java | 4 +- .../java/org/keycloak/models/UserModel.java | 2 +- .../models/utils/RepresentationToModel.java | 2 +- .../models/utils/UserModelDelegate.java | 4 +- .../models/file/adapter/ClientAdapter.java | 2 +- .../models/file/adapter/RealmAdapter.java | 10 +- .../models/file/adapter/UserAdapter.java | 2 +- .../keycloak/models/cache/ClientAdapter.java | 2 +- .../keycloak/models/cache/RealmAdapter.java | 7 +- .../keycloak/models/cache/UserAdapter.java | 4 +- .../models/cache/entities/CachedRealm.java | 2 +- .../keycloak/models/jpa/ClientAdapter.java | 2 +- .../org/keycloak/models/jpa/RealmAdapter.java | 6 +- .../org/keycloak/models/jpa/UserAdapter.java | 2 +- .../keycloak/adapters/ClientAdapter.java | 2 +- .../mongo/keycloak/adapters/RealmAdapter.java | 6 +- .../mongo/keycloak/adapters/UserAdapter.java | 2 +- .../saml/EntityDescriptorImporter.java | 4 +- .../saml/EntityDescriptorImporterFactory.java | 8 +- ...ycloak.exportimport.ClientImporterFactory} | 0 ...ionImportSpi.java => ClientImportSpi.java} | 8 +- ...ationImporter.java => ClientImporter.java} | 4 +- ...actory.java => ClientImporterFactory.java} | 4 +- .../keycloak/protocol/oidc/TokenManager.java | 4 +- .../oidc/endpoints/LogoutEndpoint.java | 4 +- .../oidc/endpoints/TokenEndpoint.java | 12 +- .../oidc/endpoints/ValidateTokenEndpoint.java | 2 +- .../protocol/oidc/mappers/HardcodedRole.java | 2 +- .../protocol/oidc/mappers/RoleNameMapper.java | 2 +- .../oidc/utils/AuthorizeClientUtil.java | 9 +- .../services/ErrorResponseException.java | 3 +- .../services/managers/ApplianceBootstrap.java | 2 +- .../org/keycloak/services/managers/Auth.java | 4 +- .../services/managers/RealmManager.java | 82 +-- .../managers/ResourceAdminManager.java | 64 +- .../services/resources/AccountService.java | 34 +- .../resources/ClientsManagementService.java | 55 +- .../resources/IdentityBrokerService.java | 6 +- .../resources/PublicRealmResource.java | 3 +- .../services/resources/RealmsResource.java | 9 +- .../resources/admin/AdminConsole.java | 12 +- .../resources/admin/ClientResource.java | 65 +- .../resources/admin/ClientsResource.java | 6 +- .../admin/IdentityProviderResource.java | 5 +- .../admin/IdentityProvidersResource.java | 4 +- .../admin/ProtocolMappersResource.java | 13 +- .../resources/admin/RealmAdminResource.java | 81 ++- .../resources/admin/RealmsAdminResource.java | 20 +- .../resources/admin/RoleByIdResource.java | 37 +- .../admin/RoleContainerResource.java | 57 +- .../resources/admin/RoleResource.java | 2 +- ...ce.java => ScopeMappedClientResource.java} | 51 +- .../resources/admin/ScopeMappedResource.java | 37 +- .../admin/ServerInfoAdminResource.java | 22 +- ...va => UserClientRoleMappingsResource.java} | 64 +- .../admin/UserFederationResource.java | 13 +- .../resources/admin/UsersResource.java | 72 +- .../services/org.keycloak.provider.Spi | 2 +- .../testsuite/account/AccountTest.java | 3 +- .../testsuite/account/ProfileTest.java | 2 +- .../adapter/AdapterTestStrategy.java | 5 +- .../adapter/RelativeUriAdapterTest.java | 2 +- .../testsuite/admin/AbstractClientTest.java | 4 +- .../testsuite/admin/AdminAPITest.java | 2 +- .../keycloak/testsuite/model/AdapterTest.java | 2 +- .../keycloak/testsuite/model/ImportTest.java | 6 +- .../testsuite/saml/SamlBindingTest.java | 2 +- .../src/test/resources/testrealm.json | 24 +- 117 files changed, 1523 insertions(+), 1580 deletions(-) rename forms/common-themes/src/main/resources/theme/base/admin/resources/js/controllers/{applications.js => clients.js} (51%) delete mode 100755 forms/common-themes/src/main/resources/theme/base/admin/resources/partials/application-list.html rename forms/common-themes/src/main/resources/theme/base/admin/resources/partials/{application-clustering-node.html => client-clustering-node.html} (79%) rename forms/common-themes/src/main/resources/theme/base/admin/resources/partials/{application-clustering.html => client-clustering.html} (78%) rename forms/common-themes/src/main/resources/theme/base/admin/resources/partials/{application-credentials.html => client-credentials.html} (71%) rename forms/common-themes/src/main/resources/theme/base/admin/resources/partials/{application-detail.html => client-detail.html} (79%) rename forms/common-themes/src/main/resources/theme/base/admin/resources/partials/{application-identity-provider.html => client-identity-provider.html} (57%) rename forms/common-themes/src/main/resources/theme/base/admin/resources/partials/{application-import.html => client-import.html} (87%) rename forms/common-themes/src/main/resources/theme/base/admin/resources/partials/{application-installation.html => client-installation.html} (73%) rename forms/common-themes/src/main/resources/theme/base/admin/resources/partials/{application-keys.html => client-keys.html} (92%) create mode 100755 forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-list.html rename forms/common-themes/src/main/resources/theme/base/admin/resources/partials/{application-mappers-add.html => client-mappers-add.html} (80%) rename forms/common-themes/src/main/resources/theme/base/admin/resources/partials/{application-mappers.html => client-mappers.html} (65%) rename forms/common-themes/src/main/resources/theme/base/admin/resources/partials/{application-revocation.html => client-revocation.html} (71%) rename forms/common-themes/src/main/resources/theme/base/admin/resources/partials/{application-role-detail.html => client-role-detail.html} (72%) rename forms/common-themes/src/main/resources/theme/base/admin/resources/partials/{application-role-list.html => client-role-list.html} (79%) rename forms/common-themes/src/main/resources/theme/base/admin/resources/partials/{application-saml-key-export.html => client-saml-key-export.html} (85%) rename forms/common-themes/src/main/resources/theme/base/admin/resources/partials/{application-saml-key-import.html => client-saml-key-import.html} (85%) rename forms/common-themes/src/main/resources/theme/base/admin/resources/partials/{application-saml-keys.html => client-saml-keys.html} (86%) rename forms/common-themes/src/main/resources/theme/base/admin/resources/partials/{application-scope-mappings.html => client-scope-mappings.html} (66%) rename forms/common-themes/src/main/resources/theme/base/admin/resources/partials/{application-sessions.html => client-sessions.html} (78%) delete mode 100755 forms/common-themes/src/main/resources/theme/base/admin/resources/templates/kc-navigation-application.html create mode 100755 forms/common-themes/src/main/resources/theme/base/admin/resources/templates/kc-navigation-client.html rename saml/saml-protocol/src/main/resources/META-INF/services/{org.keycloak.exportimport.ApplicationImporterFactory => org.keycloak.exportimport.ClientImporterFactory} (100%) rename services/src/main/java/org/keycloak/exportimport/{ApplicationImportSpi.java => ClientImportSpi.java} (71%) rename services/src/main/java/org/keycloak/exportimport/{ApplicationImporter.java => ClientImporter.java} (67%) rename services/src/main/java/org/keycloak/exportimport/{ApplicationImporterFactory.java => ClientImporterFactory.java} (52%) rename services/src/main/java/org/keycloak/services/resources/admin/{ScopeMappedApplicationResource.java => ScopeMappedClientResource.java} (59%) rename services/src/main/java/org/keycloak/services/resources/admin/{UserApplicationRoleMappingsResource.java => UserClientRoleMappingsResource.java} (60%) diff --git a/broker/oidc/src/main/java/org/keycloak/broker/oidc/KeycloakOIDCIdentityProvider.java b/broker/oidc/src/main/java/org/keycloak/broker/oidc/KeycloakOIDCIdentityProvider.java index 47847dc68d..ff89a89edc 100755 --- a/broker/oidc/src/main/java/org/keycloak/broker/oidc/KeycloakOIDCIdentityProvider.java +++ b/broker/oidc/src/main/java/org/keycloak/broker/oidc/KeycloakOIDCIdentityProvider.java @@ -4,14 +4,12 @@ import org.keycloak.broker.oidc.util.SimpleHttp; import org.keycloak.constants.AdapterConstants; import org.keycloak.events.EventBuilder; import org.keycloak.jose.jws.JWSInput; -import org.keycloak.jose.jws.crypto.RSAProvider; import org.keycloak.models.RealmModel; import org.keycloak.models.UserSessionModel; import org.keycloak.representations.adapters.action.AdminAction; import org.keycloak.representations.adapters.action.LogoutAction; import org.keycloak.services.managers.AuthenticationManager; import org.keycloak.util.JsonSerialization; -import org.keycloak.util.PemUtils; import javax.ws.rs.POST; import javax.ws.rs.Path; @@ -90,7 +88,7 @@ public class KeycloakOIDCIdentityProvider extends OIDCIdentityProvider { @Override public SimpleHttp generateTokenRequest(String authorizationCode) { return super.generateTokenRequest(authorizationCode) - .param(AdapterConstants.APPLICATION_SESSION_STATE, "n/a"); // hack to get backchannel logout to work + .param(AdapterConstants.CLIENT_SESSION_STATE, "n/a"); // hack to get backchannel logout to work } diff --git a/core/src/main/java/org/keycloak/constants/AdapterConstants.java b/core/src/main/java/org/keycloak/constants/AdapterConstants.java index df302b2f1e..aa223955d3 100755 --- a/core/src/main/java/org/keycloak/constants/AdapterConstants.java +++ b/core/src/main/java/org/keycloak/constants/AdapterConstants.java @@ -19,13 +19,13 @@ public interface AdapterConstants { String AUTH_DATA_PARAM_NAME = "org.keycloak.json.adapterConfig"; // Attribute passed in codeToToken request from adapter to Keycloak and saved in ClientSession. Contains ID of HttpSession on adapter - public static final String APPLICATION_SESSION_STATE = "application_session_state"; + public static final String CLIENT_SESSION_STATE = "client_session_state"; // Attribute passed in codeToToken request from adapter to Keycloak and saved in ClientSession. Contains hostname of adapter where HttpSession is served - public static final String APPLICATION_SESSION_HOST = "application_session_host"; + public static final String CLIENT_SESSION_HOST = "client_session_host"; // Attribute passed in registerNode request for register new application cluster node once he joined cluster - public static final String APPLICATION_CLUSTER_HOST = "application_cluster_host"; + public static final String CLIENT_CLUSTER_HOST = "client_cluster_host"; // Cookie used on adapter side to store token info. Used only when tokenStore is 'COOKIE' public static final String KEYCLOAK_ADAPTER_STATE_COOKIE = "KEYCLOAK_ADAPTER_STATE"; diff --git a/export-import/export-import-api/src/main/java/org/keycloak/exportimport/util/ImportUtils.java b/export-import/export-import-api/src/main/java/org/keycloak/exportimport/util/ImportUtils.java index b109dc3558..21285c9572 100755 --- a/export-import/export-import-api/src/main/java/org/keycloak/exportimport/util/ImportUtils.java +++ b/export-import/export-import-api/src/main/java/org/keycloak/exportimport/util/ImportUtils.java @@ -54,7 +54,7 @@ public class ImportUtils { if (Config.getAdminRealm().equals(realm.getId())) { // Delete all masterAdmin apps due to foreign key constraints for (RealmModel currRealm : model.getRealms()) { - currRealm.setMasterAdminApp(null); + currRealm.setMasterAdminClient(null); } } // TODO: For migration between versions, it should be possible to delete just realm but keep it's users @@ -83,7 +83,7 @@ public class ImportUtils { for (RealmModel currentRealm : model.getRealms()) { ClientModel masterApp = adminRealm.getClientByClientId(KeycloakModelUtils.getMasterRealmAdminApplicationName(currentRealm)); if (masterApp != null) { - currentRealm.setMasterAdminApp(masterApp); + currentRealm.setMasterAdminClient(masterApp); } else { setupMasterAdminManagement(model, currentRealm); } @@ -93,7 +93,7 @@ public class ImportUtils { RealmModel adminRealm = model.getRealm(adminRealmId); ClientModel masterApp = adminRealm.getClientByClientId(KeycloakModelUtils.getMasterRealmAdminApplicationName(realm)); if (masterApp != null) { - realm.setMasterAdminApp(masterApp); + realm.setMasterAdminClient(masterApp); } else { setupMasterAdminManagement(model, realm); } @@ -121,7 +121,7 @@ public class ImportUtils { ClientModel realmAdminApp = KeycloakModelUtils.createClient(adminRealm, KeycloakModelUtils.getMasterRealmAdminApplicationName(realm)); realmAdminApp.setBearerOnly(true); - realm.setMasterAdminApp(realmAdminApp); + realm.setMasterAdminClient(realmAdminApp); for (String r : AdminRoles.ALL_REALM_ROLES) { RoleModel role = realmAdminApp.addRole(r); diff --git a/forms/common-themes/src/main/resources/theme/base/admin/index.ftl b/forms/common-themes/src/main/resources/theme/base/admin/index.ftl index 161acdad73..20e21b744f 100755 --- a/forms/common-themes/src/main/resources/theme/base/admin/index.ftl +++ b/forms/common-themes/src/main/resources/theme/base/admin/index.ftl @@ -30,8 +30,7 @@ - - + diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/js/app.js b/forms/common-themes/src/main/resources/theme/base/admin/resources/js/app.js index f7ea60dddf..f45453c744 100755 --- a/forms/common-themes/src/main/resources/theme/base/admin/resources/js/app.js +++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/js/app.js @@ -212,8 +212,8 @@ module.config([ '$routeProvider', function($routeProvider) { realm : function(RealmLoader) { return RealmLoader(); }, - applications : function(ApplicationListLoader) { - return ApplicationListLoader(); + clients : function(ClientListLoader) { + return ClientListLoader(); }, roles : function(RoleListLoader) { return RoleListLoader(); @@ -311,8 +311,8 @@ module.config([ '$routeProvider', function($routeProvider) { user : function(UserLoader) { return UserLoader(); }, - applications : function(ApplicationListLoader) { - return ApplicationListLoader(); + clients : function(ClientListLoader) { + return ClientListLoader(); } }, controller : 'UserRoleMappingCtrl' @@ -369,8 +369,8 @@ module.config([ '$routeProvider', function($routeProvider) { roles : function(RoleListLoader) { return RoleListLoader(); }, - applications : function(ApplicationListLoader) { - return ApplicationListLoader(); + clients : function(ClientListLoader) { + return ClientListLoader(); } }, controller : 'RoleDetailCtrl' @@ -387,8 +387,8 @@ module.config([ '$routeProvider', function($routeProvider) { roles : function(RoleListLoader) { return RoleListLoader(); }, - applications : function(ApplicationListLoader) { - return ApplicationListLoader(); + clients : function(ClientListLoader) { + return ClientListLoader(); } }, controller : 'RoleDetailCtrl' @@ -406,14 +406,14 @@ module.config([ '$routeProvider', function($routeProvider) { controller : 'RoleListCtrl' }) - .when('/create/role/:realm/applications/:application', { - templateUrl : resourceUrl + '/partials/application-role-detail.html', + .when('/create/role/:realm/clients/:client', { + templateUrl : resourceUrl + '/partials/client-role-detail.html', resolve : { realm : function(RealmLoader) { return RealmLoader(); }, - application : function(ApplicationLoader) { - return ApplicationLoader(); + client : function(ClientLoader) { + return ClientLoader(); }, role : function() { return {}; @@ -421,56 +421,56 @@ module.config([ '$routeProvider', function($routeProvider) { roles : function(RoleListLoader) { return RoleListLoader(); }, - applications : function(ApplicationListLoader) { - return ApplicationListLoader(); + clients : function(ClientListLoader) { + return ClientListLoader(); } }, - controller : 'ApplicationRoleDetailCtrl' + controller : 'ClientRoleDetailCtrl' }) - .when('/realms/:realm/applications/:application/roles/:role', { - templateUrl : resourceUrl + '/partials/application-role-detail.html', + .when('/realms/:realm/clients/:client/roles/:role', { + templateUrl : resourceUrl + '/partials/client-role-detail.html', resolve : { realm : function(RealmLoader) { return RealmLoader(); }, - application : function(ApplicationLoader) { - return ApplicationLoader(); + client : function(ClientLoader) { + return ClientLoader(); }, - role : function(ApplicationRoleLoader) { - return ApplicationRoleLoader(); + role : function(ClientRoleLoader) { + return ClientRoleLoader(); }, roles : function(RoleListLoader) { return RoleListLoader(); }, - applications : function(ApplicationListLoader) { - return ApplicationListLoader(); + clients : function(ClientListLoader) { + return ClientListLoader(); } }, - controller : 'ApplicationRoleDetailCtrl' + controller : 'ClientRoleDetailCtrl' }) - .when('/realms/:realm/applications/:application/mappers', { - templateUrl : resourceUrl + '/partials/application-mappers.html', + .when('/realms/:realm/clients/:client/mappers', { + templateUrl : resourceUrl + '/partials/client-mappers.html', resolve : { realm : function(RealmLoader) { return RealmLoader(); }, - application : function(ApplicationLoader) { - return ApplicationLoader(); + client : function(ClientLoader) { + return ClientLoader(); }, serverInfo : function(ServerInfoLoader) { return ServerInfoLoader(); } }, - controller : 'ApplicationProtocolMapperListCtrl' + controller : 'ClientProtocolMapperListCtrl' }) - .when('/realms/:realm/applications/:application/add-mappers', { - templateUrl : resourceUrl + '/partials/application-mappers-add.html', + .when('/realms/:realm/clients/:client/add-mappers', { + templateUrl : resourceUrl + '/partials/client-mappers-add.html', resolve : { realm : function(RealmLoader) { return RealmLoader(); }, - application : function(ApplicationLoader) { - return ApplicationLoader(); + client : function(ClientLoader) { + return ClientLoader(); }, serverInfo : function(ServerInfoLoader) { return ServerInfoLoader(); @@ -478,26 +478,26 @@ module.config([ '$routeProvider', function($routeProvider) { }, controller : 'AddBuiltinProtocolMapperCtrl' }) - .when('/realms/:realm/applications/:application/mappers/:id', { + .when('/realms/:realm/clients/:client/mappers/:id', { templateUrl : resourceUrl + '/partials/protocol-mapper-detail.html', resolve : { realm : function(RealmLoader) { return RealmLoader(); }, - application : function(ApplicationLoader) { - return ApplicationLoader(); + client : function(ClientLoader) { + return ClientLoader(); }, serverInfo : function(ServerInfoLoader) { return ServerInfoLoader(); }, - mapper : function(ApplicationProtocolMapperLoader) { - return ApplicationProtocolMapperLoader(); + mapper : function(ClientProtocolMapperLoader) { + return ClientProtocolMapperLoader(); } }, - controller : 'ApplicationProtocolMapperCtrl' + controller : 'ClientProtocolMapperCtrl' }) - .when('/create/application/:realm/:application/mappers', { + .when('/create/client/:realm/:client/mappers', { templateUrl : resourceUrl + '/partials/protocol-mapper-detail.html', resolve : { realm : function(RealmLoader) { @@ -506,231 +506,231 @@ module.config([ '$routeProvider', function($routeProvider) { serverInfo : function(ServerInfoLoader) { return ServerInfoLoader(); }, - application : function(ApplicationLoader) { - return ApplicationLoader(); + client : function(ClientLoader) { + return ClientLoader(); } }, - controller : 'ApplicationProtocolMapperCreateCtrl' + controller : 'ClientProtocolMapperCreateCtrl' }) - .when('/realms/:realm/applications/:application/sessions', { - templateUrl : resourceUrl + '/partials/application-sessions.html', + .when('/realms/:realm/clients/:client/sessions', { + templateUrl : resourceUrl + '/partials/client-sessions.html', resolve : { realm : function(RealmLoader) { return RealmLoader(); }, - application : function(ApplicationLoader) { - return ApplicationLoader(); + client : function(ClientLoader) { + return ClientLoader(); }, - sessionCount : function(ApplicationSessionCountLoader) { - return ApplicationSessionCountLoader(); + sessionCount : function(ClientSessionCountLoader) { + return ClientSessionCountLoader(); } }, - controller : 'ApplicationSessionsCtrl' + controller : 'ClientSessionsCtrl' }) - .when('/realms/:realm/applications/:application/credentials', { - templateUrl : resourceUrl + '/partials/application-credentials.html', + .when('/realms/:realm/clients/:client/credentials', { + templateUrl : resourceUrl + '/partials/client-credentials.html', resolve : { realm : function(RealmLoader) { return RealmLoader(); }, - application : function(ApplicationLoader) { - return ApplicationLoader(); + client : function(ClientLoader) { + return ClientLoader(); } }, - controller : 'ApplicationCredentialsCtrl' + controller : 'ClientCredentialsCtrl' }) - .when('/realms/:realm/applications/:application/identity-provider', { - templateUrl : resourceUrl + '/partials/application-identity-provider.html', + .when('/realms/:realm/clients/:client/identity-provider', { + templateUrl : resourceUrl + '/partials/client-identity-provider.html', resolve : { realm : function(RealmLoader) { return RealmLoader(); }, - application : function(ApplicationLoader) { - return ApplicationLoader(); + client : function(ClientLoader) { + return ClientLoader(); } }, - controller : 'ApplicationIdentityProviderCtrl' + controller : 'ClientIdentityProviderCtrl' }) - .when('/realms/:realm/applications/:application/clustering', { - templateUrl : resourceUrl + '/partials/application-clustering.html', + .when('/realms/:realm/clients/:client/clustering', { + templateUrl : resourceUrl + '/partials/client-clustering.html', resolve : { realm : function(RealmLoader) { return RealmLoader(); }, - application : function(ApplicationLoader) { - return ApplicationLoader(); + client : function(ClientLoader) { + return ClientLoader(); } }, - controller : 'ApplicationClusteringCtrl' + controller : 'ClientClusteringCtrl' }) - .when('/register-node/realms/:realm/applications/:application/clustering', { - templateUrl : resourceUrl + '/partials/application-clustering-node.html', + .when('/register-node/realms/:realm/clients/:client/clustering', { + templateUrl : resourceUrl + '/partials/client-clustering-node.html', resolve : { realm : function(RealmLoader) { return RealmLoader(); }, - application : function(ApplicationLoader) { - return ApplicationLoader(); + client : function(ClientLoader) { + return ClientLoader(); } }, - controller : 'ApplicationClusteringNodeCtrl' + controller : 'ClientClusteringNodeCtrl' }) - .when('/realms/:realm/applications/:application/clustering/:node', { - templateUrl : resourceUrl + '/partials/application-clustering-node.html', + .when('/realms/:realm/clients/:client/clustering/:node', { + templateUrl : resourceUrl + '/partials/client-clustering-node.html', resolve : { realm : function(RealmLoader) { return RealmLoader(); }, - application : function(ApplicationLoader) { - return ApplicationLoader(); + client : function(ClientLoader) { + return ClientLoader(); } }, - controller : 'ApplicationClusteringNodeCtrl' + controller : 'ClientClusteringNodeCtrl' }) - .when('/realms/:realm/applications/:application/saml/keys', { - templateUrl : resourceUrl + '/partials/application-saml-keys.html', + .when('/realms/:realm/clients/:client/saml/keys', { + templateUrl : resourceUrl + '/partials/client-saml-keys.html', resolve : { realm : function(RealmLoader) { return RealmLoader(); }, - application : function(ApplicationLoader) { - return ApplicationLoader(); + client : function(ClientLoader) { + return ClientLoader(); } }, - controller : 'ApplicationSamlKeyCtrl' + controller : 'ClientSamlKeyCtrl' }) - .when('/realms/:realm/applications/:application/saml/:keyType/import/:attribute', { - templateUrl : resourceUrl + '/partials/application-saml-key-import.html', + .when('/realms/:realm/clients/:client/saml/:keyType/import/:attribute', { + templateUrl : resourceUrl + '/partials/client-saml-key-import.html', resolve : { realm : function(RealmLoader) { return RealmLoader(); }, - application : function(ApplicationLoader) { - return ApplicationLoader(); + client : function(ClientLoader) { + return ClientLoader(); } }, - controller : 'ApplicationCertificateImportCtrl' + controller : 'ClientCertificateImportCtrl' }) - .when('/realms/:realm/applications/:application/saml/:keyType/export/:attribute', { - templateUrl : resourceUrl + '/partials/application-saml-key-export.html', + .when('/realms/:realm/clients/:client/saml/:keyType/export/:attribute', { + templateUrl : resourceUrl + '/partials/client-saml-key-export.html', resolve : { realm : function(RealmLoader) { return RealmLoader(); }, - application : function(ApplicationLoader) { - return ApplicationLoader(); + client : function(ClientLoader) { + return ClientLoader(); } }, - controller : 'ApplicationCertificateExportCtrl' + controller : 'ClientCertificateExportCtrl' }) - .when('/realms/:realm/applications/:application/roles', { - templateUrl : resourceUrl + '/partials/application-role-list.html', + .when('/realms/:realm/clients/:client/roles', { + templateUrl : resourceUrl + '/partials/client-role-list.html', resolve : { realm : function(RealmLoader) { return RealmLoader(); }, - application : function(ApplicationLoader) { - return ApplicationLoader(); + client : function(ClientLoader) { + return ClientLoader(); }, - roles : function(ApplicationRoleListLoader) { - return ApplicationRoleListLoader(); + roles : function(ClientRoleListLoader) { + return ClientRoleListLoader(); } }, - controller : 'ApplicationRoleListCtrl' + controller : 'ClientRoleListCtrl' }) - .when('/realms/:realm/applications/:application/revocation', { - templateUrl : resourceUrl + '/partials/application-revocation.html', + .when('/realms/:realm/clients/:client/revocation', { + templateUrl : resourceUrl + '/partials/client-revocation.html', resolve : { realm : function(RealmLoader) { return RealmLoader(); }, - application : function(ApplicationLoader) { - return ApplicationLoader(); + client : function(ClientLoader) { + return ClientLoader(); } }, - controller : 'ApplicationRevocationCtrl' + controller : 'ClientRevocationCtrl' }) - .when('/realms/:realm/applications/:application/scope-mappings', { - templateUrl : resourceUrl + '/partials/application-scope-mappings.html', + .when('/realms/:realm/clients/:client/scope-mappings', { + templateUrl : resourceUrl + '/partials/client-scope-mappings.html', resolve : { realm : function(RealmLoader) { return RealmLoader(); }, - application : function(ApplicationLoader) { - return ApplicationLoader(); + client : function(ClientLoader) { + return ClientLoader(); }, - applications : function(ApplicationListLoader) { - return ApplicationListLoader(); + clients : function(ClientListLoader) { + return ClientListLoader(); } }, - controller : 'ApplicationScopeMappingCtrl' + controller : 'ClientScopeMappingCtrl' }) - .when('/realms/:realm/applications/:application/installation', { - templateUrl : resourceUrl + '/partials/application-installation.html', + .when('/realms/:realm/clients/:client/installation', { + templateUrl : resourceUrl + '/partials/client-installation.html', resolve : { realm : function(RealmLoader) { return RealmLoader(); }, - application : function(ApplicationLoader) { - return ApplicationLoader(); + client : function(ClientLoader) { + return ClientLoader(); } }, - controller : 'ApplicationInstallationCtrl' + controller : 'ClientInstallationCtrl' }) - .when('/create/application/:realm', { - templateUrl : resourceUrl + '/partials/application-detail.html', + .when('/create/client/:realm', { + templateUrl : resourceUrl + '/partials/client-detail.html', resolve : { realm : function(RealmLoader) { return RealmLoader(); }, - applications : function(ApplicationListLoader) { - return ApplicationListLoader(); + clients : function(ClientListLoader) { + return ClientListLoader(); }, - application : function() { + client : function() { return {}; }, serverInfo : function(ServerInfoLoader) { return ServerInfoLoader(); } }, - controller : 'ApplicationDetailCtrl' + controller : 'ClientDetailCtrl' }) - .when('/realms/:realm/applications/:application', { - templateUrl : resourceUrl + '/partials/application-detail.html', + .when('/realms/:realm/clients/:client', { + templateUrl : resourceUrl + '/partials/client-detail.html', resolve : { realm : function(RealmLoader) { return RealmLoader(); }, - applications : function(ApplicationListLoader) { - return ApplicationListLoader(); + clients : function(ClientListLoader) { + return ClientListLoader(); }, - application : function(ApplicationLoader) { - return ApplicationLoader(); + client : function(ClientLoader) { + return ClientLoader(); }, serverInfo : function(ServerInfoLoader) { return ServerInfoLoader(); } }, - controller : 'ApplicationDetailCtrl' + controller : 'ClientDetailCtrl' }) - .when('/realms/:realm/applications', { - templateUrl : resourceUrl + '/partials/application-list.html', + .when('/realms/:realm/clients', { + templateUrl : resourceUrl + '/partials/client-list.html', resolve : { realm : function(RealmLoader) { return RealmLoader(); }, - applications : function(ApplicationListLoader) { - return ApplicationListLoader(); + clients : function(ClientListLoader) { + return ClientListLoader(); }, serverInfo : function(ServerInfoLoader) { return ServerInfoLoader(); } }, - controller : 'ApplicationListCtrl' + controller : 'ClientListCtrl' }) - .when('/import/application/:realm', { - templateUrl : resourceUrl + '/partials/application-import.html', + .when('/import/client/:realm', { + templateUrl : resourceUrl + '/partials/client-import.html', resolve : { realm : function(RealmLoader) { return RealmLoader(); @@ -739,7 +739,7 @@ module.config([ '$routeProvider', function($routeProvider) { return ServerInfoLoader(); } }, - controller : 'ApplicationImportCtrl' + controller : 'ClientImportCtrl' }) .when('/', { templateUrl : resourceUrl + '/partials/home.html', @@ -772,8 +772,8 @@ module.config([ '$routeProvider', function($routeProvider) { realm : function(RealmLoader) { return RealmLoader(); }, - stats : function(RealmApplicationSessionStatsLoader) { - return RealmApplicationSessionStatsLoader(); + stats : function(RealmClientSessionStatsLoader) { + return RealmClientSessionStatsLoader(); } }, controller : 'RealmSessionStatsCtrl' @@ -1353,12 +1353,12 @@ module.directive('kcNavigation', function ($compile, Notifications) { } }); -module.directive('kcNavigationApplication', function () { +module.directive('kcNavigationClient', function () { return { scope: true, restrict: 'E', replace: true, - templateUrl: resourceUrl + '/templates/kc-navigation-application.html' + templateUrl: resourceUrl + '/templates/kc-navigation-client.html' } }); diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/js/controllers/applications.js b/forms/common-themes/src/main/resources/theme/base/admin/resources/js/controllers/clients.js similarity index 51% rename from forms/common-themes/src/main/resources/theme/base/admin/resources/js/controllers/applications.js rename to forms/common-themes/src/main/resources/theme/base/admin/resources/js/controllers/clients.js index 307f805dea..2324d4876b 100755 --- a/forms/common-themes/src/main/resources/theme/base/admin/resources/js/controllers/applications.js +++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/js/controllers/clients.js @@ -4,14 +4,10 @@ Array.prototype.remove = function(from, to) { return this.push.apply(this, rest); }; -module.controller('ApplicationRoleListCtrl', function($scope, $location, realm, application, roles) { +module.controller('ClientRoleListCtrl', function($scope, $location, realm, client, roles) { $scope.realm = realm; $scope.roles = roles; - $scope.application = application; - - for (var i = 0; i < roles.length; i++) { - console.log("role.id: " + roles[i].id + " role.name: " + roles[i].name); - } + $scope.client = client; $scope.$watch(function() { return $location.path(); @@ -20,17 +16,17 @@ module.controller('ApplicationRoleListCtrl', function($scope, $location, realm, }); }); -module.controller('ApplicationCredentialsCtrl', function($scope, $location, realm, application, ApplicationCredentials, Notifications) { +module.controller('ClientCredentialsCtrl', function($scope, $location, realm, client, ClientCredentials, Notifications) { $scope.realm = realm; - $scope.application = application; - var secret = ApplicationCredentials.get({ realm : realm.realm, application : application.id }, + $scope.client = client; + var secret = ClientCredentials.get({ realm : realm.realm, client : client.id }, function() { $scope.secret = secret.value; } ); $scope.changePassword = function() { - var secret = ApplicationCredentials.update({ realm : realm.realm, application : application.id }, + var secret = ClientCredentials.update({ realm : realm.realm, client : client.id }, function() { Notifications.success('The secret has been changed.'); $scope.secret = secret.value; @@ -49,107 +45,107 @@ module.controller('ApplicationCredentialsCtrl', function($scope, $location, real }); }); -module.controller('ApplicationIdentityProviderCtrl', function($scope, $location, $route, realm, application, Application, $location, Notifications) { +module.controller('ClientIdentityProviderCtrl', function($scope, $location, $route, realm, client, Client, $location, Notifications) { $scope.realm = realm; - $scope.application = angular.copy(application); + $scope.client = angular.copy(client); var length = 0; - if ($scope.application.identityProviders) { - length = $scope.application.identityProviders.length; + if ($scope.client.identityProviders) { + length = $scope.client.identityProviders.length; - for (i = 0; i < $scope.application.identityProviders.length; i++) { - var applicationProvider = $scope.application.identityProviders[i]; - if (applicationProvider.retrieveToken) { - applicationProvider.retrieveToken = applicationProvider.retrieveToken.toString(); + for (i = 0; i < $scope.client.identityProviders.length; i++) { + var clientProvider = $scope.client.identityProviders[i]; + if (clientProvider.retrieveToken) { + clientProvider.retrieveToken = clientProvider.retrieveToken.toString(); } } } else { - $scope.application.identityProviders = []; + $scope.client.identityProviders = []; } $scope.identityProviders = []; - var providersMissingInApp = []; + var providersMissingInClient = []; for (j = 0; j < realm.identityProviders.length; j++) { var identityProvider = realm.identityProviders[j]; - var applicationProvider = null; + var clientProvider = null; - for (i = 0; i < $scope.application.identityProviders.length; i++) { - applicationProvider = $scope.application.identityProviders[i]; + for (i = 0; i < $scope.client.identityProviders.length; i++) { + clientProvider = $scope.client.identityProviders[i]; - if (applicationProvider) { + if (clientProvider) { - if (applicationProvider.id == identityProvider.id) { + if (clientProvider.id == identityProvider.id) { $scope.identityProviders[i] = {}; $scope.identityProviders[i].identityProvider = identityProvider; - $scope.identityProviders[i].retrieveToken = applicationProvider.retrieveToken; + $scope.identityProviders[i].retrieveToken = clientProvider.retrieveToken; break; } - applicationProvider = null; + clientProvider = null; } } - if (applicationProvider == null) { - providersMissingInApp.push(identityProvider); + if (clientProvider == null) { + providersMissingInClient.push(identityProvider); } } - for (j = 0; j < providersMissingInApp.length; j++) { - var identityProvider = providersMissingInApp[j]; + for (j = 0; j < providersMissingInClient.length; j++) { + var identityProvider = providersMissingInClient[j]; var currentProvider = {}; currentProvider.identityProvider = identityProvider; currentProvider.retrieveToken = "false"; $scope.identityProviders.push(currentProvider); - var currentAppProvider = {}; - currentAppProvider.id = identityProvider.id; - currentAppProvider.retrieveToken = "false"; - $scope.application.identityProviders.push(currentAppProvider); + var currentClientProvider = {}; + currentClientProvider.id = identityProvider.id; + currentClientProvider.retrieveToken = "false"; + $scope.client.identityProviders.push(currentClientProvider); } - var oldCopy = angular.copy($scope.application); + var oldCopy = angular.copy($scope.client); $scope.save = function() { - Application.update({ + Client.update({ realm : realm.realm, - application : application.id - }, $scope.application, function() { + client : client.id + }, $scope.client, function() { $scope.changed = false; $route.reload(); - Notifications.success("Your changes have been saved to the application."); + Notifications.success("Your changes have been saved to the client."); }); }; $scope.reset = function() { - $scope.application = angular.copy(oldCopy); + $scope.client = angular.copy(oldCopy); $scope.changed = false; }; - $scope.$watch('application', function() { - if (!angular.equals($scope.application, oldCopy)) { + $scope.$watch('client', function() { + if (!angular.equals($scope.client, oldCopy)) { $scope.changed = true; } }, true); }); -module.controller('ApplicationSamlKeyCtrl', function($scope, $location, $http, $upload, realm, application, - ApplicationCertificate, ApplicationCertificateGenerate, - ApplicationCertificateDownload, Notifications) { +module.controller('ClientSamlKeyCtrl', function($scope, $location, $http, $upload, realm, client, + ClientCertificate, ClientCertificateGenerate, + ClientCertificateDownload, Notifications) { $scope.realm = realm; - $scope.application = application; + $scope.client = client; - var signingKeyInfo = ApplicationCertificate.get({ realm : realm.realm, application : application.id, attribute: 'saml.signing' }, + var signingKeyInfo = ClientCertificate.get({ realm : realm.realm, client : client.id, attribute: 'saml.signing' }, function() { $scope.signingKeyInfo = signingKeyInfo; } ); $scope.generateSigningKey = function() { - var keyInfo = ApplicationCertificateGenerate.generate({ realm : realm.realm, application : application.id, attribute: 'saml.signing' }, + var keyInfo = ClientCertificateGenerate.generate({ realm : realm.realm, client : client.id, attribute: 'saml.signing' }, function() { Notifications.success('Signing key has been regenerated.'); $scope.signingKeyInfo = keyInfo; @@ -161,21 +157,21 @@ module.controller('ApplicationSamlKeyCtrl', function($scope, $location, $http, $ }; $scope.importSigningKey = function() { - $location.url("/realms/" + realm.realm + "/applications/" + application.id + "/saml/Signing/import/saml.signing"); + $location.url("/realms/" + realm.realm + "/clients/" + client.id + "/saml/Signing/import/saml.signing"); }; $scope.exportSigningKey = function() { - $location.url("/realms/" + realm.realm + "/applications/" + application.id + "/saml/Signing/export/saml.signing"); + $location.url("/realms/" + realm.realm + "/clients/" + client.id + "/saml/Signing/export/saml.signing"); }; - var encryptionKeyInfo = ApplicationCertificate.get({ realm : realm.realm, application : application.id, attribute: 'saml.encryption' }, + var encryptionKeyInfo = ClientCertificate.get({ realm : realm.realm, client : client.id, attribute: 'saml.encryption' }, function() { $scope.encryptionKeyInfo = encryptionKeyInfo; } ); $scope.generateEncryptionKey = function() { - var keyInfo = ApplicationCertificateGenerate.generate({ realm : realm.realm, application : application.id, attribute: 'saml.encryption' }, + var keyInfo = ClientCertificateGenerate.generate({ realm : realm.realm, client : client.id, attribute: 'saml.encryption' }, function() { Notifications.success('Encryption key has been regenerated.'); $scope.encryptionKeyInfo = keyInfo; @@ -187,11 +183,11 @@ module.controller('ApplicationSamlKeyCtrl', function($scope, $location, $http, $ }; $scope.importEncryptionKey = function() { - $location.url("/realms/" + realm.realm + "/applications/" + application.id + "/saml/Encryption/import/saml.encryption"); + $location.url("/realms/" + realm.realm + "/clients/" + client.id + "/saml/Encryption/import/saml.encryption"); }; $scope.exportEncryptionKey = function() { - $location.url("/realms/" + realm.realm + "/applications/" + application.id + "/saml/Encryption/export/saml.encryption"); + $location.url("/realms/" + realm.realm + "/clients/" + client.id + "/saml/Encryption/export/saml.encryption"); }; @@ -202,14 +198,14 @@ module.controller('ApplicationSamlKeyCtrl', function($scope, $location, $http, $ }); }); -module.controller('ApplicationCertificateImportCtrl', function($scope, $location, $http, $upload, realm, application, $routeParams, - ApplicationCertificate, ApplicationCertificateGenerate, - ApplicationCertificateDownload, Notifications) { +module.controller('ClientCertificateImportCtrl', function($scope, $location, $http, $upload, realm, client, $routeParams, + ClientCertificate, ClientCertificateGenerate, + ClientCertificateDownload, Notifications) { var keyType = $routeParams.keyType; var attribute = $routeParams.attribute; $scope.realm = realm; - $scope.application = application; + $scope.client = client; $scope.keyType = keyType; $scope.files = []; @@ -234,7 +230,7 @@ module.controller('ApplicationCertificateImportCtrl', function($scope, $location for (var i = 0; i < $scope.files.length; i++) { var $file = $scope.files[i]; $scope.upload = $upload.upload({ - url: authUrl + '/admin/realms/' + realm.realm + '/applications-by-id/' + application.id + '/certificates/' + attribute + '/upload', + url: authUrl + '/admin/realms/' + realm.realm + '/clients-by-id/' + client.id + '/certificates/' + attribute + '/upload', // method: POST or PUT, // headers: {'headerKey': 'headerValue'}, withCredential: true, data: {keystoreFormat: $scope.uploadKeyFormat, @@ -247,11 +243,9 @@ module.controller('ApplicationCertificateImportCtrl', function($scope, $location //fileFormDataName: myFile, /* customize how data is added to formData. See #40#issuecomment-28612000 for example */ //formDataAppender: function(formData, key, val){} - }).progress(function(evt) { - console.log('percent: ' + parseInt(100.0 * evt.loaded / evt.total)); }).success(function(data, status, headers) { Notifications.success("Keystore uploaded successfully."); - $location.url("/realms/" + realm.realm + "/applications/" + application.id + "/saml/keys"); + $location.url("/realms/" + realm.realm + "/clients/" + client.id + "/saml/keys"); }) .error(function() { Notifications.error("The key store can not be uploaded. Please verify the file."); @@ -268,16 +262,16 @@ module.controller('ApplicationCertificateImportCtrl', function($scope, $location }); }); -module.controller('ApplicationCertificateExportCtrl', function($scope, $location, $http, $upload, realm, application, $routeParams, - ApplicationCertificate, ApplicationCertificateGenerate, - ApplicationCertificateDownload, Notifications) { +module.controller('ClientCertificateExportCtrl', function($scope, $location, $http, $upload, realm, client, $routeParams, + ClientCertificate, ClientCertificateGenerate, + ClientCertificateDownload, Notifications) { var keyType = $routeParams.keyType; var attribute = $routeParams.attribute; $scope.realm = realm; - $scope.application = application; + $scope.client = client; $scope.keyType = keyType; var jks = { - keyAlias: application.name, + keyAlias: client.clientId, realmAlias: realm.realm }; @@ -286,7 +280,7 @@ module.controller('ApplicationCertificateExportCtrl', function($scope, $location "PKCS12" ]; - var keyInfo = ApplicationCertificate.get({ realm : realm.realm, application : application.id, attribute: attribute }, + var keyInfo = ClientCertificate.get({ realm : realm.realm, client : client.id, attribute: attribute }, function() { $scope.keyInfo = keyInfo; } @@ -296,17 +290,17 @@ module.controller('ApplicationCertificateExportCtrl', function($scope, $location $scope.download = function() { $http({ - url: authUrl + '/admin/realms/' + realm.realm + '/applications-by-id/' + application.id + '/certificates/' + attribute + '/download', + url: authUrl + '/admin/realms/' + realm.realm + '/clients-by-id/' + client.id + '/certificates/' + attribute + '/download', method: 'POST', responseType: 'arraybuffer', data: $scope.jks, headers: { 'Content-Type': 'application/json', - 'Accept': 'application/octet-stream' + 'Accept': 'client/octet-stream' } }).success(function(data){ var blob = new Blob([data], { - type: 'application/octet-stream' + type: 'client/octet-stream' }); var ext = ".jks"; if ($scope.jks.format == 'PKCS12') ext = ".p12"; @@ -323,18 +317,18 @@ module.controller('ApplicationCertificateExportCtrl', function($scope, $location }); }); -module.controller('ApplicationSessionsCtrl', function($scope, realm, sessionCount, application, - ApplicationUserSessions) { +module.controller('ClientSessionsCtrl', function($scope, realm, sessionCount, client, + ClientUserSessions) { $scope.realm = realm; $scope.count = sessionCount.count; $scope.sessions = []; - $scope.application = application; + $scope.client = client; $scope.page = 0; $scope.query = { realm : realm.realm, - application: $scope.application.id, + client: $scope.client.id, max : 5, first : 0 } @@ -365,17 +359,17 @@ module.controller('ApplicationSessionsCtrl', function($scope, realm, sessionCoun }; $scope.loadUsers = function() { - ApplicationUserSessions.query($scope.query, function(updated) { + ClientUserSessions.query($scope.query, function(updated) { $scope.sessions = updated; }) }; }); -module.controller('ApplicationRoleDetailCtrl', function($scope, realm, application, role, roles, applications, - Role, ApplicationRole, RoleById, RoleRealmComposites, RoleApplicationComposites, +module.controller('ClientRoleDetailCtrl', function($scope, realm, client, role, roles, clients, + Role, ClientRole, RoleById, RoleRealmComposites, RoleClientComposites, $http, $location, Dialog, Notifications) { $scope.realm = realm; - $scope.application = application; + $scope.client = client; $scope.role = angular.copy(role); $scope.create = !role.name; @@ -383,16 +377,16 @@ module.controller('ApplicationRoleDetailCtrl', function($scope, realm, applicati $scope.save = function() { if ($scope.create) { - ApplicationRole.save({ + ClientRole.save({ realm: realm.realm, - application : application.id + client : client.id }, $scope.role, function (data, headers) { $scope.changed = false; role = angular.copy($scope.role); - ApplicationRole.get({ realm: realm.realm, application : application.id, role: role.name }, function(role) { + ClientRole.get({ realm: realm.realm, client : client.id, role: role.name }, function(role) { var id = role.id; - $location.url("/realms/" + realm.realm + "/applications/" + application.id + "/roles/" + id); + $location.url("/realms/" + realm.realm + "/clients/" + client.id + "/roles/" + id); Notifications.success("The role has been created."); }); }); @@ -405,30 +399,30 @@ module.controller('ApplicationRoleDetailCtrl', function($scope, realm, applicati Dialog.confirmDelete($scope.role.name, 'role', function() { $scope.role.$remove({ realm : realm.realm, - application : application.id, + client : client.id, role : $scope.role.id }, function() { - $location.url("/realms/" + realm.realm + "/applications/" + application.id + "/roles"); + $location.url("/realms/" + realm.realm + "/clients/" + client.id + "/roles"); Notifications.success("The role has been deleted."); }); }); }; $scope.cancel = function () { - $location.url("/realms/" + realm.realm + "/applications/" + application.id + "/roles"); + $location.url("/realms/" + realm.realm + "/clients/" + client.id + "/roles"); }; - roleControl($scope, realm, role, roles, applications, - ApplicationRole, RoleById, RoleRealmComposites, RoleApplicationComposites, + roleControl($scope, realm, role, roles, clients, + ClientRole, RoleById, RoleRealmComposites, RoleClientComposites, $http, $location, Notifications, Dialog); }); -module.controller('ApplicationImportCtrl', function($scope, $location, $upload, realm, serverInfo, Notifications) { +module.controller('ClientImportCtrl', function($scope, $location, $upload, realm, serverInfo, Notifications) { $scope.realm = realm; - $scope.configFormats = serverInfo.applicationImporters; + $scope.configFormats = serverInfo.clientImporters; $scope.configFormat = null; $scope.files = []; @@ -446,7 +440,7 @@ module.controller('ApplicationImportCtrl', function($scope, $location, $upload, for (var i = 0; i < $scope.files.length; i++) { var $file = $scope.files[i]; $scope.upload = $upload.upload({ - url: authUrl + '/admin/realms/' + realm.realm + '/application-importers/' + $scope.configFormat.id + '/upload', + url: authUrl + '/admin/realms/' + realm.realm + '/client-importers/' + $scope.configFormat.id + '/upload', // method: POST or PUT, // headers: {'headerKey': 'headerValue'}, withCredential: true, data: {myObj: ""}, @@ -455,11 +449,9 @@ module.controller('ApplicationImportCtrl', function($scope, $location, $upload, //fileFormDataName: myFile, /* customize how data is added to formData. See #40#issuecomment-28612000 for example */ //formDataAppender: function(formData, key, val){} - }).progress(function(evt) { - console.log('percent: ' + parseInt(100.0 * evt.loaded / evt.total)); }).success(function(data, status, headers) { Notifications.success("Uploaded successfully."); - $location.url("/realms/" + realm.realm + "/applications"); + $location.url("/realms/" + realm.realm + "/clients"); }) .error(function() { Notifications.error("The file can not be uploaded. Please verify the file."); @@ -477,10 +469,10 @@ module.controller('ApplicationImportCtrl', function($scope, $location, $upload, }); -module.controller('ApplicationListCtrl', function($scope, realm, applications, Application, serverInfo, $location) { +module.controller('ClientListCtrl', function($scope, realm, clients, Client, serverInfo, $location) { $scope.realm = realm; - $scope.applications = applications; - $scope.importButton = serverInfo.applicationImporters.length > 0; + $scope.clients = clients; + $scope.importButton = serverInfo.clientImporters.length > 0; $scope.$watch(function() { return $location.path(); }, function() { @@ -488,10 +480,9 @@ module.controller('ApplicationListCtrl', function($scope, realm, applications, A }); }); -module.controller('ApplicationInstallationCtrl', function($scope, realm, application, ApplicationInstallation,ApplicationInstallationJBoss, $http, $routeParams) { - console.log('ApplicationInstallationCtrl'); +module.controller('ClientInstallationCtrl', function($scope, realm, client, ClientInstallation,ClientInstallationJBoss, $http, $routeParams) { $scope.realm = realm; - $scope.application = application; + $scope.client = client; $scope.installation = null; $scope.download = null; $scope.configFormat = null; @@ -503,14 +494,14 @@ module.controller('ApplicationInstallationCtrl', function($scope, realm, applica $scope.changeFormat = function() { if ($scope.configFormat == "keycloak.json") { - var url = ApplicationInstallation.url({ realm: $routeParams.realm, application: $routeParams.application }); + var url = ClientInstallation.url({ realm: $routeParams.realm, client: $routeParams.client }); $http.get(url).success(function(data) { var tmp = angular.fromJson(data); $scope.installation = angular.toJson(tmp, true); $scope.type = 'application/json'; }) } else if ($scope.configFormat == "Wildfly/JBoss Subsystem XML") { - var url = ApplicationInstallationJBoss.url({ realm: $routeParams.realm, application: $routeParams.application }); + var url = ClientInstallationJBoss.url({ realm: $routeParams.realm, client: $routeParams.client }); $http.get(url).success(function(data) { $scope.installation = data; $scope.type = 'text/xml'; @@ -523,9 +514,7 @@ module.controller('ApplicationInstallationCtrl', function($scope, realm, applica } }); -module.controller('ApplicationDetailCtrl', function($scope, realm, application, serverInfo, Application, $location, Dialog, Notifications) { - console.log('ApplicationDetailCtrl'); - +module.controller('ClientDetailCtrl', function($scope, realm, client, serverInfo, Client, $location, Dialog, Notifications) { $scope.accessTypes = [ "confidential", "public", @@ -548,7 +537,7 @@ module.controller('ApplicationDetailCtrl', function($scope, realm, application, ]; $scope.realm = realm; - $scope.create = !application.name; + $scope.create = !client.clientId; $scope.samlAuthnStatement = false; $scope.samlMultiValuedRoles = false; $scope.samlServerSignature = false; @@ -558,43 +547,43 @@ module.controller('ApplicationDetailCtrl', function($scope, realm, application, $scope.samlForcePostBinding = false; $scope.samlForceNameIdFormat = false; if (!$scope.create) { - if (!application.attributes) { - application.attributes = {}; + if (!client.attributes) { + client.attributes = {}; } - $scope.application= angular.copy(application); + $scope.client= angular.copy(client); $scope.accessType = $scope.accessTypes[0]; - if (application.bearerOnly) { + if (client.bearerOnly) { $scope.accessType = $scope.accessTypes[2]; - } else if (application.publicClient) { + } else if (client.publicClient) { $scope.accessType = $scope.accessTypes[1]; } - if (application.protocol) { - $scope.protocol = $scope.protocols[$scope.protocols.indexOf(application.protocol)]; + if (client.protocol) { + $scope.protocol = $scope.protocols[$scope.protocols.indexOf(client.protocol)]; } else { $scope.protocol = $scope.protocols[0]; } - if (application.attributes['saml.signature.algorithm'] == 'RSA_SHA1') { + if (client.attributes['saml.signature.algorithm'] == 'RSA_SHA1') { $scope.signatureAlgorithm = $scope.signatureAlgorithms[0]; - } else if (application.attributes['saml.signature.algorithm'] == 'RSA_SHA256') { + } else if (client.attributes['saml.signature.algorithm'] == 'RSA_SHA256') { $scope.signatureAlgorithm = $scope.signatureAlgorithms[1]; - } else if (application.attributes['saml.signature.algorithm'] == 'RSA_SHA512') { + } else if (client.attributes['saml.signature.algorithm'] == 'RSA_SHA512') { $scope.signatureAlgorithm = $scope.signatureAlgorithms[2]; - } else if (application.attributes['saml.signature.algorithm'] == 'DSA_SHA1') { + } else if (client.attributes['saml.signature.algorithm'] == 'DSA_SHA1') { $scope.signatureAlgorithm = $scope.signatureAlgorithms[3]; } - if (application.attributes['saml_name_id_format'] == 'unspecified') { + if (client.attributes['saml_name_id_format'] == 'unspecified') { $scope.nameIdFormat = $scope.nameIdFormats[0]; - } else if (application.attributes['saml_name_id_format'] == 'email') { + } else if (client.attributes['saml_name_id_format'] == 'email') { $scope.nameIdFormat = $scope.nameIdFormats[1]; - } else if (application.attributes['saml_name_id_format'] == 'transient') { + } else if (client.attributes['saml_name_id_format'] == 'transient') { $scope.nameIdFormat = $scope.nameIdFormats[2]; - } else if (application.attributes['saml_name_id_format'] == 'persistent') { + } else if (client.attributes['saml_name_id_format'] == 'persistent') { $scope.nameIdFormat = $scope.nameIdFormats[3]; } } else { - $scope.application = { enabled: true, attributes: {}}; - $scope.application.redirectUris = []; + $scope.client = { enabled: true, attributes: {}}; + $scope.client.redirectUris = []; $scope.accessType = $scope.accessTypes[0]; $scope.protocol = $scope.protocols[0]; $scope.signatureAlgorithm = $scope.signatureAlgorithms[1]; @@ -603,58 +592,58 @@ module.controller('ApplicationDetailCtrl', function($scope, realm, application, $scope.samlForceNameIdFormat = false; } - if ($scope.application.attributes["saml.server.signature"]) { - if ($scope.application.attributes["saml.server.signature"] == "true") { + if ($scope.client.attributes["saml.server.signature"]) { + if ($scope.client.attributes["saml.server.signature"] == "true") { $scope.samlServerSignature = true; } else { $scope.samlServerSignature = false; } } - if ($scope.application.attributes["saml.assertion.signature"]) { - if ($scope.application.attributes["saml.assertion.signature"] == "true") { + if ($scope.client.attributes["saml.assertion.signature"]) { + if ($scope.client.attributes["saml.assertion.signature"] == "true") { $scope.samlAssertionSignature = true; } else { $scope.samlAssertionSignature = false; } } - if ($scope.application.attributes["saml.client.signature"]) { - if ($scope.application.attributes["saml.client.signature"] == "true") { + if ($scope.client.attributes["saml.client.signature"]) { + if ($scope.client.attributes["saml.client.signature"] == "true") { $scope.samlClientSignature = true; } else { $scope.samlClientSignature = false; } } - if ($scope.application.attributes["saml.encrypt"]) { - if ($scope.application.attributes["saml.encrypt"] == "true") { + if ($scope.client.attributes["saml.encrypt"]) { + if ($scope.client.attributes["saml.encrypt"] == "true") { $scope.samlEncrypt = true; } else { $scope.samlEncrypt = false; } } - if ($scope.application.attributes["saml.authnstatement"]) { - if ($scope.application.attributes["saml.authnstatement"] == "true") { + if ($scope.client.attributes["saml.authnstatement"]) { + if ($scope.client.attributes["saml.authnstatement"] == "true") { $scope.samlAuthnStatement = true; } else { $scope.samlAuthnStatement = false; } } - if ($scope.application.attributes["saml_force_name_id_format"]) { - if ($scope.application.attributes["saml_force_name_id_format"] == "true") { + if ($scope.client.attributes["saml_force_name_id_format"]) { + if ($scope.client.attributes["saml_force_name_id_format"] == "true") { $scope.samlForceNameIdFormat = true; } else { $scope.samlForceNameIdFormat = false; } } - if ($scope.application.attributes["saml.multivalued.roles"]) { - if ($scope.application.attributes["saml.multivalued.roles"] == "true") { + if ($scope.client.attributes["saml.multivalued.roles"]) { + if ($scope.client.attributes["saml.multivalued.roles"] == "true") { $scope.samlMultiValuedRoles = true; } else { $scope.samlMultiValuedRoles = false; } } - if ($scope.application.attributes["saml.force.post.binding"]) { - if ($scope.application.attributes["saml.force.post.binding"] == "true") { + if ($scope.client.attributes["saml.force.post.binding"]) { + if ($scope.client.attributes["saml.force.post.binding"] == "true") { $scope.samlForcePostBinding = true; } else { $scope.samlForcePostBinding = false; @@ -667,31 +656,31 @@ module.controller('ApplicationDetailCtrl', function($scope, realm, application, $scope.changeAccessType = function() { if ($scope.accessType == "confidential") { - $scope.application.bearerOnly = false; - $scope.application.publicClient = false; + $scope.client.bearerOnly = false; + $scope.client.publicClient = false; } else if ($scope.accessType == "public") { - $scope.application.bearerOnly = false; - $scope.application.publicClient = true; + $scope.client.bearerOnly = false; + $scope.client.publicClient = true; } else if ($scope.accessType == "bearer-only") { - $scope.application.bearerOnly = true; - $scope.application.publicClient = false; + $scope.client.bearerOnly = true; + $scope.client.publicClient = false; } }; $scope.changeProtocol = function() { if ($scope.protocol == "openid-connect") { - $scope.application.protocol = "openid-connect"; + $scope.client.protocol = "openid-connect"; } else if ($scope.accessType == "saml") { - $scope.application.protocol = "saml"; + $scope.client.protocol = "saml"; } }; $scope.changeAlgorithm = function() { - $scope.application.attributes['saml.signature.algorithm'] = $scope.signatureAlgorithm; + $scope.client.attributes['saml.signature.algorithm'] = $scope.signatureAlgorithm; }; $scope.changeNameIdFormat = function() { - $scope.application.attributes['saml_name_id_format'] = $scope.nameIdFormat; + $scope.client.attributes['saml_name_id_format'] = $scope.nameIdFormat; }; $scope.$watch(function() { @@ -700,125 +689,125 @@ module.controller('ApplicationDetailCtrl', function($scope, realm, application, $scope.path = $location.path().substring(1).split("/"); }); - $scope.$watch('application', function() { - if (!angular.equals($scope.application, application)) { + $scope.$watch('client', function() { + if (!angular.equals($scope.client, client)) { $scope.changed = true; } }, true); $scope.deleteWebOrigin = function(index) { - $scope.application.webOrigins.splice(index, 1); + $scope.client.webOrigins.splice(index, 1); } $scope.addWebOrigin = function() { - $scope.application.webOrigins.push($scope.newWebOrigin); + $scope.client.webOrigins.push($scope.newWebOrigin); $scope.newWebOrigin = ""; } $scope.deleteRedirectUri = function(index) { - $scope.application.redirectUris.splice(index, 1); + $scope.client.redirectUris.splice(index, 1); } $scope.addRedirectUri = function() { - $scope.application.redirectUris.push($scope.newRedirectUri); + $scope.client.redirectUris.push($scope.newRedirectUri); $scope.newRedirectUri = ""; } $scope.save = function() { if ($scope.samlServerSignature == true) { - $scope.application.attributes["saml.server.signature"] = "true"; + $scope.client.attributes["saml.server.signature"] = "true"; } else { - $scope.application.attributes["saml.server.signature"] = "false"; + $scope.client.attributes["saml.server.signature"] = "false"; } if ($scope.samlAssertionSignature == true) { - $scope.application.attributes["saml.assertion.signature"] = "true"; + $scope.client.attributes["saml.assertion.signature"] = "true"; } else { - $scope.application.attributes["saml.assertion.signature"] = "false"; + $scope.client.attributes["saml.assertion.signature"] = "false"; } if ($scope.samlClientSignature == true) { - $scope.application.attributes["saml.client.signature"] = "true"; + $scope.client.attributes["saml.client.signature"] = "true"; } else { - $scope.application.attributes["saml.client.signature"] = "false"; + $scope.client.attributes["saml.client.signature"] = "false"; } if ($scope.samlEncrypt == true) { - $scope.application.attributes["saml.encrypt"] = "true"; + $scope.client.attributes["saml.encrypt"] = "true"; } else { - $scope.application.attributes["saml.encrypt"] = "false"; + $scope.client.attributes["saml.encrypt"] = "false"; } if ($scope.samlAuthnStatement == true) { - $scope.application.attributes["saml.authnstatement"] = "true"; + $scope.client.attributes["saml.authnstatement"] = "true"; } else { - $scope.application.attributes["saml.authnstatement"] = "false"; + $scope.client.attributes["saml.authnstatement"] = "false"; } if ($scope.samlForceNameIdFormat == true) { - $scope.application.attributes["saml_force_name_id_format"] = "true"; + $scope.client.attributes["saml_force_name_id_format"] = "true"; } else { - $scope.application.attributes["saml_force_name_id_format"] = "false"; + $scope.client.attributes["saml_force_name_id_format"] = "false"; } if ($scope.samlMultiValuedRoles == true) { - $scope.application.attributes["saml.multivalued.roles"] = "true"; + $scope.client.attributes["saml.multivalued.roles"] = "true"; } else { - $scope.application.attributes["saml.multivalued.roles"] = "false"; + $scope.client.attributes["saml.multivalued.roles"] = "false"; } if ($scope.samlForcePostBinding == true) { - $scope.application.attributes["saml.force.post.binding"] = "true"; + $scope.client.attributes["saml.force.post.binding"] = "true"; } else { - $scope.application.attributes["saml.force.post.binding"] = "false"; + $scope.client.attributes["saml.force.post.binding"] = "false"; } - $scope.application.protocol = $scope.protocol; - $scope.application.attributes['saml.signature.algorithm'] = $scope.signatureAlgorithm; - $scope.application.attributes['saml_name_id_format'] = $scope.nameIdFormat; + $scope.client.protocol = $scope.protocol; + $scope.client.attributes['saml.signature.algorithm'] = $scope.signatureAlgorithm; + $scope.client.attributes['saml_name_id_format'] = $scope.nameIdFormat; - if ($scope.application.protocol != 'saml' && !$scope.application.bearerOnly && (!$scope.application.redirectUris || $scope.application.redirectUris.length == 0)) { + if ($scope.client.protocol != 'saml' && !$scope.client.bearerOnly && (!$scope.client.redirectUris || $scope.client.redirectUris.length == 0)) { Notifications.error("You must specify at least one redirect uri"); } else { if ($scope.create) { - Application.save({ + Client.save({ realm: realm.realm, - application: '' - }, $scope.application, function (data, headers) { + client: '' + }, $scope.client, function (data, headers) { $scope.changed = false; var l = headers().location; var id = l.substring(l.lastIndexOf("/") + 1); - $location.url("/realms/" + realm.realm + "/applications/" + id); - Notifications.success("The application has been created."); + $location.url("/realms/" + realm.realm + "/clients/" + id); + Notifications.success("The client has been created."); }); } else { - Application.update({ + Client.update({ realm : realm.realm, - application : application.id - }, $scope.application, function() { + client : client.id + }, $scope.client, function() { $scope.changed = false; - application = angular.copy($scope.application); - $location.url("/realms/" + realm.realm + "/applications/" + application.id); - Notifications.success("Your changes have been saved to the application."); + client = angular.copy($scope.client); + $location.url("/realms/" + realm.realm + "/clients/" + client.id); + Notifications.success("Your changes have been saved to the client."); }); } } }; $scope.reset = function() { - $scope.application = angular.copy(application); + $scope.client = angular.copy(client); $scope.changed = false; }; $scope.cancel = function() { - $location.url("/realms/" + realm.realm + "/applications"); + $location.url("/realms/" + realm.realm + "/clients"); }; $scope.remove = function() { - Dialog.confirmDelete($scope.application.name, 'application', function() { - $scope.application.$remove({ + Dialog.confirmDelete($scope.client.clientId, 'client', function() { + $scope.client.$remove({ realm : realm.realm, - application : $scope.application.id + client : $scope.client.id }, function() { - $location.url("/realms/" + realm.realm + "/applications"); - Notifications.success("The application has been deleted."); + $location.url("/realms/" + realm.realm + "/clients"); + Notifications.success("The client has been deleted."); }); }); }; @@ -826,33 +815,32 @@ module.controller('ApplicationDetailCtrl', function($scope, realm, application, }); -module.controller('ApplicationScopeMappingCtrl', function($scope, $http, realm, application, applications, Notifications, - Application, - ApplicationRealmScopeMapping, ApplicationApplicationScopeMapping, ApplicationRole, - ApplicationAvailableRealmScopeMapping, ApplicationAvailableApplicationScopeMapping, - ApplicationCompositeRealmScopeMapping, ApplicationCompositeApplicationScopeMapping) { +module.controller('ClientScopeMappingCtrl', function($scope, $http, realm, client, clients, Notifications, + Client, + ClientRealmScopeMapping, ClientClientScopeMapping, ClientRole, + ClientAvailableRealmScopeMapping, ClientAvailableClientScopeMapping, + ClientCompositeRealmScopeMapping, ClientCompositeClientScopeMapping) { $scope.realm = realm; - $scope.application = angular.copy(application); + $scope.client = angular.copy(client); $scope.selectedRealmRoles = []; $scope.selectedRealmMappings = []; $scope.realmMappings = []; - $scope.applications = applications; - $scope.applicationRoles = []; - $scope.applicationComposite = []; - $scope.selectedApplicationRoles = []; - $scope.selectedApplicationMappings = []; - $scope.applicationMappings = []; + $scope.clients = clients; + $scope.clientRoles = []; + $scope.clientComposite = []; + $scope.selectedClientRoles = []; + $scope.selectedClientMappings = []; + $scope.clientMappings = []; $scope.dummymodel = []; $scope.changeFullScopeAllowed = function() { - console.log('change full scope'); - Application.update({ + Client.update({ realm : realm.realm, - application : application.id - }, $scope.application, function() { + client : client.id + }, $scope.client, function() { $scope.changed = false; - application = angular.copy($scope.application); + client = angular.copy($scope.client); updateRealmRoles(); Notifications.success("Scope mappings updated."); }); @@ -861,30 +849,29 @@ module.controller('ApplicationScopeMappingCtrl', function($scope, $http, realm, function updateRealmRoles() { - $scope.realmRoles = ApplicationAvailableRealmScopeMapping.query({realm : realm.realm, application : application.id}); - $scope.realmMappings = ApplicationRealmScopeMapping.query({realm : realm.realm, application : application.id}); - $scope.realmComposite = ApplicationCompositeRealmScopeMapping.query({realm : realm.realm, application : application.id}); + $scope.realmRoles = ClientAvailableRealmScopeMapping.query({realm : realm.realm, client : client.id}); + $scope.realmMappings = ClientRealmScopeMapping.query({realm : realm.realm, client : client.id}); + $scope.realmComposite = ClientCompositeRealmScopeMapping.query({realm : realm.realm, client : client.id}); } - function updateAppRoles() { - if ($scope.targetApp) { - console.debug($scope.targetApp.name); - $scope.applicationRoles = ApplicationAvailableApplicationScopeMapping.query({realm : realm.realm, application : application.id, targetApp : $scope.targetApp.id}); - $scope.applicationMappings = ApplicationApplicationScopeMapping.query({realm : realm.realm, application : application.id, targetApp : $scope.targetApp.id}); - $scope.applicationComposite = ApplicationCompositeApplicationScopeMapping.query({realm : realm.realm, application : application.id, targetApp : $scope.targetApp.id}); + function updateClientRoles() { + if ($scope.targetClient) { + $scope.clientRoles = ClientAvailableClientScopeMapping.query({realm : realm.realm, client : client.id, targetClient : $scope.targetClient.id}); + $scope.clientMappings = ClientClientScopeMapping.query({realm : realm.realm, client : client.id, targetClient : $scope.targetClient.id}); + $scope.clientComposite = ClientCompositeClientScopeMapping.query({realm : realm.realm, client : client.id, targetClient : $scope.targetClient.id}); } else { - $scope.applicationRoles = null; - $scope.applicationMappings = null; - $scope.applicationComposite = null; + $scope.clientRoles = null; + $scope.clientMappings = null; + $scope.clientComposite = null; } } - $scope.changeApplication = function() { - updateAppRoles(); + $scope.changeClient = function() { + updateClientRoles(); }; $scope.addRealmRole = function() { - $http.post(authUrl + '/admin/realms/' + realm.realm + '/applications-by-id/' + application.id + '/scope-mappings/realm', + $http.post(authUrl + '/admin/realms/' + realm.realm + '/clients-by-id/' + client.id + '/scope-mappings/realm', $scope.selectedRealmRoles).success(function() { updateRealmRoles(); Notifications.success("Scope mappings updated."); @@ -892,25 +879,25 @@ module.controller('ApplicationScopeMappingCtrl', function($scope, $http, realm, }; $scope.deleteRealmRole = function() { - $http.delete(authUrl + '/admin/realms/' + realm.realm + '/applications-by-id/' + application.id + '/scope-mappings/realm', + $http.delete(authUrl + '/admin/realms/' + realm.realm + '/clients-by-id/' + client.id + '/scope-mappings/realm', {data : $scope.selectedRealmMappings, headers : {"content-type" : "application/json"}}).success(function () { updateRealmRoles(); Notifications.success("Scope mappings updated."); }); }; - $scope.addApplicationRole = function() { - $http.post(authUrl + '/admin/realms/' + realm.realm + '/applications-by-id/' + application.id + '/scope-mappings/applications-by-id/' + $scope.targetApp.id, - $scope.selectedApplicationRoles).success(function () { - updateAppRoles(); + $scope.addClientRole = function() { + $http.post(authUrl + '/admin/realms/' + realm.realm + '/clients-by-id/' + client.id + '/scope-mappings/clients-by-id/' + $scope.targetClient.id, + $scope.selectedClientRoles).success(function () { + updateClientRoles(); Notifications.success("Scope mappings updated."); }); }; - $scope.deleteApplicationRole = function() { - $http.delete(authUrl + '/admin/realms/' + realm.realm + '/applications-by-id/' + application.id + '/scope-mappings/applications-by-id/' + $scope.targetApp.id, - {data : $scope.selectedApplicationMappings, headers : {"content-type" : "application/json"}}).success(function () { - updateAppRoles(); + $scope.deleteClientRole = function() { + $http.delete(authUrl + '/admin/realms/' + realm.realm + '/clients-by-id/' + client.id + '/scope-mappings/clients-by-id/' + $scope.targetClient.id, + {data : $scope.selectedClientMappings, headers : {"content-type" : "application/json"}}).success(function () { + updateClientRoles(); Notifications.success("Scope mappings updated."); }); }; @@ -918,45 +905,45 @@ module.controller('ApplicationScopeMappingCtrl', function($scope, $http, realm, updateRealmRoles(); }); -module.controller('ApplicationRevocationCtrl', function($scope, realm, application, Application, ApplicationPushRevocation, $location, Dialog, Notifications) { +module.controller('ClientRevocationCtrl', function($scope, realm, client, Client, ClientPushRevocation, $location, Dialog, Notifications) { $scope.realm = realm; - $scope.application = application; + $scope.client = client; var setNotBefore = function() { - if ($scope.application.notBefore == 0) { + if ($scope.client.notBefore == 0) { $scope.notBefore = "None"; } else { - $scope.notBefore = new Date($scope.application.notBefore * 1000); + $scope.notBefore = new Date($scope.client.notBefore * 1000); } }; setNotBefore(); var refresh = function() { - Application.get({ realm : realm.realm, application: $scope.application.id }, function(updated) { - $scope.application = updated; + Client.get({ realm : realm.realm, client: $scope.client.id }, function(updated) { + $scope.client = updated; setNotBefore(); }) }; $scope.clear = function() { - $scope.application.notBefore = 0; - Application.update({ realm : realm.realm, application: application.id}, $scope.application, function () { + $scope.client.notBefore = 0; + Client.update({ realm : realm.realm, client: client.id}, $scope.client, function () { $scope.notBefore = "None"; - Notifications.success('Not Before cleared for application.'); + Notifications.success('Not Before cleared for client.'); refresh(); }); } $scope.setNotBeforeNow = function() { - $scope.application.notBefore = new Date().getTime()/1000; - Application.update({ realm : realm.realm, application: $scope.application.id}, $scope.application, function () { - Notifications.success('Not Before set for application.'); + $scope.client.notBefore = new Date().getTime()/1000; + Client.update({ realm : realm.realm, client: $scope.client.id}, $scope.client, function () { + Notifications.success('Not Before set for client.'); refresh(); }); } $scope.pushRevocation = function() { - ApplicationPushRevocation.save({realm : realm.realm, application: $scope.application.id}, function (globalReqResult) { + ClientPushRevocation.save({realm : realm.realm, client: $scope.client.id}, function (globalReqResult) { var successCount = globalReqResult.successRequests ? globalReqResult.successRequests.length : 0; var failedCount = globalReqResult.failedRequests ? globalReqResult.failedRequests.length : 0; @@ -973,32 +960,32 @@ module.controller('ApplicationRevocationCtrl', function($scope, realm, applicati }); -module.controller('ApplicationClusteringCtrl', function($scope, application, Application, ApplicationTestNodesAvailable, realm, $location, $route, Notifications, TimeUnit) { - $scope.application = application; +module.controller('ClientClusteringCtrl', function($scope, client, Client, ClientTestNodesAvailable, realm, $location, $route, Notifications, TimeUnit) { + $scope.client = client; $scope.realm = realm; - var oldCopy = angular.copy($scope.application); + var oldCopy = angular.copy($scope.client); $scope.changed = false; - $scope.$watch('application', function() { - if (!angular.equals($scope.application, oldCopy)) { + $scope.$watch('client', function() { + if (!angular.equals($scope.client, oldCopy)) { $scope.changed = true; } }, true); - $scope.application.nodeReRegistrationTimeoutUnit = TimeUnit.autoUnit(application.nodeReRegistrationTimeout); - $scope.application.nodeReRegistrationTimeout = TimeUnit.toUnit(application.nodeReRegistrationTimeout, $scope.application.nodeReRegistrationTimeoutUnit); - $scope.$watch('application.nodeReRegistrationTimeoutUnit', function(to, from) { - $scope.application.nodeReRegistrationTimeout = TimeUnit.convert($scope.application.nodeReRegistrationTimeout, from, to); + $scope.client.nodeReRegistrationTimeoutUnit = TimeUnit.autoUnit(client.nodeReRegistrationTimeout); + $scope.client.nodeReRegistrationTimeout = TimeUnit.toUnit(client.nodeReRegistrationTimeout, $scope.client.nodeReRegistrationTimeoutUnit); + $scope.$watch('client.nodeReRegistrationTimeoutUnit', function(to, from) { + $scope.client.nodeReRegistrationTimeout = TimeUnit.convert($scope.client.nodeReRegistrationTimeout, from, to); }); $scope.save = function() { - var appCopy = angular.copy($scope.application); - delete appCopy['nodeReRegistrationTimeoutUnit']; - appCopy.nodeReRegistrationTimeout = TimeUnit.toSeconds($scope.application.nodeReRegistrationTimeout, $scope.application.nodeReRegistrationTimeoutUnit) - Application.update({ realm : realm.realm, application : application.id }, appCopy, function () { + var clientCopy = angular.copy($scope.client); + delete clientCopy['nodeReRegistrationTimeoutUnit']; + clientCopy.nodeReRegistrationTimeout = TimeUnit.toSeconds($scope.client.nodeReRegistrationTimeout, $scope.client.nodeReRegistrationTimeoutUnit) + Client.update({ realm : realm.realm, client : client.id }, clientCopy, function () { $route.reload(); - Notifications.success('Your changes have been saved to the application.'); + Notifications.success('Your changes have been saved to the client.'); }); }; @@ -1007,8 +994,7 @@ module.controller('ApplicationClusteringCtrl', function($scope, application, App }; $scope.testNodesAvailable = function() { - console.log('testNodesAvailable'); - ApplicationTestNodesAvailable.get({ realm : realm.realm, application : application.id }, function(globalReqResult) { + ClientTestNodesAvailable.get({ realm : realm.realm, client : client.id }, function(globalReqResult) { $route.reload(); var successCount = globalReqResult.successRequests ? globalReqResult.successRequests.length : 0; @@ -1025,12 +1011,12 @@ module.controller('ApplicationClusteringCtrl', function($scope, application, App }); }; - if (application.registeredNodes) { + if (client.registeredNodes) { var nodeRegistrations = []; - for (node in application.registeredNodes) { + for (node in client.registeredNodes) { reg = { host: node, - lastRegistration: new Date(application.registeredNodes[node] * 1000) + lastRegistration: new Date(client.registeredNodes[node] * 1000) } nodeRegistrations.push(reg); } @@ -1039,24 +1025,22 @@ module.controller('ApplicationClusteringCtrl', function($scope, application, App }; }); -module.controller('ApplicationClusteringNodeCtrl', function($scope, application, Application, ApplicationClusterNode, realm, $location, $routeParams, Notifications) { - $scope.application = application; +module.controller('ClientClusteringNodeCtrl', function($scope, client, Client, ClientClusterNode, realm, $location, $routeParams, Notifications) { + $scope.client = client; $scope.realm = realm; $scope.create = !$routeParams.node; $scope.save = function() { - console.log('registerNode: ' + $scope.node.host); - ApplicationClusterNode.save({ realm : realm.realm, application : application.id , node: $scope.node.host }, function() { + ClientClusterNode.save({ realm : realm.realm, client : client.id , node: $scope.node.host }, function() { Notifications.success('Node ' + $scope.node.host + ' registered successfully.'); - $location.url('/realms/' + realm.realm + '/applications/' + application.id + '/clustering'); + $location.url('/realms/' + realm.realm + '/clients/' + client.id + '/clustering'); }); } $scope.unregisterNode = function() { - console.log('unregisterNode: ' + $scope.node.host); - ApplicationClusterNode.remove({ realm : realm.realm, application : application.id , node: $scope.node.host }, function() { + ClientClusterNode.remove({ realm : realm.realm, client : client.id , node: $scope.node.host }, function() { Notifications.success('Node ' + $scope.node.host + ' unregistered successfully.'); - $location.url('/realms/' + realm.realm + '/applications/' + application.id + '/clustering'); + $location.url('/realms/' + realm.realm + '/clients/' + client.id + '/clustering'); }); } @@ -1064,7 +1048,7 @@ module.controller('ApplicationClusteringNodeCtrl', function($scope, application, $scope.node = {} $scope.registered = false; } else { - var lastRegTime = application.registeredNodes[$routeParams.node]; + var lastRegTime = client.registeredNodes[$routeParams.node]; if (lastRegTime) { $scope.registered = true; @@ -1082,16 +1066,16 @@ module.controller('ApplicationClusteringNodeCtrl', function($scope, application, } }); -module.controller('ApplicationProtocolMapperListCtrl', function($scope, realm, application, serverInfo, - ApplicationProtocolMappersByProtocol, +module.controller('ClientProtocolMapperListCtrl', function($scope, realm, client, serverInfo, + ClientProtocolMappersByProtocol, $http, $location, Dialog, Notifications) { $scope.realm = realm; - $scope.application = application; - if (application.protocol == null) { - application.protocol = 'openid-connect'; + $scope.client = client; + if (client.protocol == null) { + client.protocol = 'openid-connect'; } - var protocolMappers = serverInfo.protocolMapperTypes[application.protocol]; + var protocolMappers = serverInfo.protocolMapperTypes[client.protocol]; var mapperTypes = {}; for (var i = 0; i < protocolMappers.length; i++) { mapperTypes[protocolMappers[i].id] = protocolMappers[i]; @@ -1100,22 +1084,22 @@ module.controller('ApplicationProtocolMapperListCtrl', function($scope, realm, a var updateMappers = function() { - $scope.mappers = ApplicationProtocolMappersByProtocol.query({realm : realm.realm, application : application.id, protocol : application.protocol}); + $scope.mappers = ClientProtocolMappersByProtocol.query({realm : realm.realm, client : client.id, protocol : client.protocol}); }; updateMappers(); }); -module.controller('AddBuiltinProtocolMapperCtrl', function($scope, realm, application, serverInfo, - ApplicationProtocolMappersByProtocol, +module.controller('AddBuiltinProtocolMapperCtrl', function($scope, realm, client, serverInfo, + ClientProtocolMappersByProtocol, $http, $location, Dialog, Notifications) { $scope.realm = realm; - $scope.application = application; - if (application.protocol == null) { - application.protocol = 'openid-connect'; + $scope.client = client; + if (client.protocol == null) { + client.protocol = 'openid-connect'; } - var protocolMappers = serverInfo.protocolMapperTypes[application.protocol]; + var protocolMappers = serverInfo.protocolMapperTypes[client.protocol]; var mapperTypes = {}; for (var i = 0; i < protocolMappers.length; i++) { mapperTypes[protocolMappers[i].id] = protocolMappers[i]; @@ -1126,21 +1110,17 @@ module.controller('AddBuiltinProtocolMapperCtrl', function($scope, realm, applic var updateMappers = function() { - var appMappers = ApplicationProtocolMappersByProtocol.query({realm : realm.realm, application : application.id, protocol : application.protocol}, function() { - var builtinMappers = serverInfo.builtinProtocolMappers[application.protocol]; - for (var i = 0; i < appMappers.length; i++) { + var clientMappers = ClientProtocolMappersByProtocol.query({realm : realm.realm, client : client.id, protocol : client.protocol}, function() { + var builtinMappers = serverInfo.builtinProtocolMappers[client.protocol]; + for (var i = 0; i < clientMappers.length; i++) { for (var j = 0; j < builtinMappers.length; j++) { - if (builtinMappers[j].name == appMappers[i].name - && builtinMappers[j].protocolMapper == appMappers[i].protocolMapper) { - console.log('removing: ' + builtinMappers[j].name); + if (builtinMappers[j].name == clientMappers[i].name + && builtinMappers[j].protocolMapper == clientMappers[i].protocolMapper) { builtinMappers.splice(j, 1); break; } } } - for (var j = 0; j < builtinMappers.length; j++) { - console.log('builtin left: ' + builtinMappers[j].name); - } $scope.mappers = builtinMappers; for (var i = 0; i < $scope.mappers.length; i++) { $scope.mappers[i].isChecked = false; @@ -1160,32 +1140,32 @@ module.controller('AddBuiltinProtocolMapperCtrl', function($scope, realm, applic toAdd.push($scope.mappers[i]); } } - $http.post(authUrl + '/admin/realms/' + realm.realm + '/applications-by-id/' + application.id + '/protocol-mappers/add-models', + $http.post(authUrl + '/admin/realms/' + realm.realm + '/clients-by-id/' + client.id + '/protocol-mappers/add-models', toAdd).success(function() { Notifications.success("Mappers added"); - $location.url('/realms/' + realm.realm + '/applications/' + application.id + '/mappers'); + $location.url('/realms/' + realm.realm + '/clients/' + client.id + '/mappers'); }).error(function() { Notifications.error("Error adding mappers"); - $location.url('/realms/' + realm.realm + '/applications/' + application.id + '/mappers'); + $location.url('/realms/' + realm.realm + '/clients/' + client.id + '/mappers'); }); }; }); -module.controller('ApplicationProtocolMapperCtrl', function($scope, realm, serverInfo, application, mapper, ApplicationProtocolMapper, Notifications, Dialog, $location) { +module.controller('ClientProtocolMapperCtrl', function($scope, realm, serverInfo, client, mapper, ClientProtocolMapper, Notifications, Dialog, $location) { $scope.realm = realm; - $scope.application = application; + $scope.client = client; $scope.create = false; - if (application.protocol == null) { - application.protocol = 'openid-connect'; + if (client.protocol == null) { + client.protocol = 'openid-connect'; } - $scope.protocol = application.protocol; + $scope.protocol = client.protocol; $scope.mapper = angular.copy(mapper); $scope.changed = false; $scope.boolval = true; $scope.boolvalId = 'boolval'; - var protocolMappers = serverInfo.protocolMapperTypes[application.protocol]; + var protocolMappers = serverInfo.protocolMapperTypes[client.protocol]; for (var i = 0; i < protocolMappers.length; i++) { if (protocolMappers[i].id == mapper.protocolMapper) { $scope.mapperType = protocolMappers[i]; @@ -1204,14 +1184,14 @@ module.controller('ApplicationProtocolMapperCtrl', function($scope, realm, serve }, true); $scope.save = function() { - ApplicationProtocolMapper.update({ + ClientProtocolMapper.update({ realm : realm.realm, - application: application.id, + client: client.id, id : mapper.id }, $scope.mapper, function() { $scope.changed = false; mapper = angular.copy($scope.mapper); - $location.url("/realms/" + realm.realm + '/applications/' + application.id + "/mappers/" + mapper.id); + $location.url("/realms/" + realm.realm + '/clients/' + client.id + "/mappers/" + mapper.id); Notifications.success("Your changes have been saved."); }); }; @@ -1228,25 +1208,25 @@ module.controller('ApplicationProtocolMapperCtrl', function($scope, realm, serve $scope.remove = function() { Dialog.confirmDelete($scope.mapper.name, 'mapper', function() { - ApplicationProtocolMapper.remove({ realm: realm.realm, application: application.id, id : $scope.mapper.id }, function() { + ClientProtocolMapper.remove({ realm: realm.realm, client: client.id, id : $scope.mapper.id }, function() { Notifications.success("The mapper has been deleted."); - $location.url("/realms/" + realm.realm + '/applications/' + application.id + "/mappers"); + $location.url("/realms/" + realm.realm + '/clients/' + client.id + "/mappers"); }); }); }; }); -module.controller('ApplicationProtocolMapperCreateCtrl', function($scope, realm, serverInfo, application, ApplicationProtocolMapper, Notifications, Dialog, $location) { +module.controller('ClientProtocolMapperCreateCtrl', function($scope, realm, serverInfo, client, ClientProtocolMapper, Notifications, Dialog, $location) { $scope.realm = realm; - $scope.application = application; + $scope.client = client; $scope.create = true; - if (application.protocol == null) { - application.protocol = 'openid-connect'; + if (client.protocol == null) { + client.protocol = 'openid-connect'; } - var protocol = application.protocol; + var protocol = client.protocol; $scope.protocol = protocol; - $scope.mapper = { protocol : application.protocol, config: {}}; + $scope.mapper = { protocol : client.protocol, config: {}}; $scope.mapperTypes = serverInfo.protocolMapperTypes[protocol]; $scope.$watch(function() { @@ -1257,12 +1237,12 @@ module.controller('ApplicationProtocolMapperCreateCtrl', function($scope, realm, $scope.save = function() { $scope.mapper.protocolMapper = $scope.mapperType.id; - ApplicationProtocolMapper.save({ - realm : realm.realm, application: application.id + ClientProtocolMapper.save({ + realm : realm.realm, client: client.id }, $scope.mapper, function(data, headers) { var l = headers().location; var id = l.substring(l.lastIndexOf("/") + 1); - $location.url("/realms/" + realm.realm + '/applications/' + application.id + "/mappers/" + id); + $location.url("/realms/" + realm.realm + '/clients/' + client.id + "/mappers/" + id); Notifications.success("Mapper has been created."); }); }; diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/js/controllers/realm.js b/forms/common-themes/src/main/resources/theme/base/admin/resources/js/controllers/realm.js index 750d482547..97c1bdaa7a 100755 --- a/forms/common-themes/src/main/resources/theme/base/admin/resources/js/controllers/realm.js +++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/js/controllers/realm.js @@ -476,7 +476,7 @@ module.controller('RealmRequiredCredentialsCtrl', function($scope, Realm, realm, }; }); -module.controller('RealmDefaultRolesCtrl', function ($scope, Realm, realm, applications, roles, Notifications, ApplicationRole, Application) { +module.controller('RealmDefaultRolesCtrl', function ($scope, Realm, realm, clients, roles, Notifications, ClientRole, Client) { console.log('RealmDefaultRolesCtrl'); @@ -486,17 +486,17 @@ module.controller('RealmDefaultRolesCtrl', function ($scope, Realm, realm, appli $scope.selectedRealmRoles = []; $scope.selectedRealmDefRoles = []; - $scope.applications = angular.copy(applications); - for (var i = 0; i < applications.length; i++) { - if (applications[i].name == 'account') { - $scope.application = $scope.applications[i]; + $scope.clients = angular.copy(clients); + for (var i = 0; i < clients.length; i++) { + if (clients[i].name == 'account') { + $scope.client = $scope.clients[i]; break; } } - $scope.availableAppRoles = []; - $scope.selectedAppRoles = []; - $scope.selectedAppDefRoles = []; + $scope.availableClientRoles = []; + $scope.selectedClientRoles = []; + $scope.selectedClientDefRoles = []; if (!$scope.realm.hasOwnProperty('defaultRoles') || $scope.realm.defaultRoles === null) { $scope.realm.defaultRoles = []; @@ -550,81 +550,81 @@ module.controller('RealmDefaultRolesCtrl', function ($scope, Realm, realm, appli }); }; - $scope.changeApplication = function () { + $scope.changeClient = function () { - $scope.selectedAppRoles = []; - $scope.selectedAppDefRoles = []; + $scope.selectedClientRoles = []; + $scope.selectedClientDefRoles = []; - // Populate available roles for selected application - if ($scope.application) { - var appDefaultRoles = ApplicationRole.query({realm: $scope.realm.realm, application: $scope.application.id}, function () { + // Populate available roles for selected client + if ($scope.client) { + var appDefaultRoles = ClientRole.query({realm: $scope.realm.realm, client: $scope.client.id}, function () { - if (!$scope.application.hasOwnProperty('defaultRoles') || $scope.application.defaultRoles === null) { - $scope.application.defaultRoles = []; + if (!$scope.client.hasOwnProperty('defaultRoles') || $scope.client.defaultRoles === null) { + $scope.client.defaultRoles = []; } - $scope.availableAppRoles = []; + $scope.availableClientRoles = []; for (var i = 0; i < appDefaultRoles.length; i++) { var roleName = appDefaultRoles[i].name; - if ($scope.application.defaultRoles.indexOf(roleName) < 0) { - $scope.availableAppRoles.push(roleName); + if ($scope.client.defaultRoles.indexOf(roleName) < 0) { + $scope.availableClientRoles.push(roleName); } } }); } else { - $scope.availableAppRoles = null; + $scope.availableClientRoles = null; } }; - $scope.addAppDefaultRole = function () { + $scope.addClientDefaultRole = function () { // Remove selected roles from the app available roles and add them to app default roles (move from left to right). - for (var i = 0; i < $scope.selectedAppRoles.length; i++) { - var role = $scope.selectedAppRoles[i]; + for (var i = 0; i < $scope.selectedClientRoles.length; i++) { + var role = $scope.selectedClientRoles[i]; - var idx = $scope.application.defaultRoles.indexOf(role); + var idx = $scope.client.defaultRoles.indexOf(role); if (idx < 0) { - $scope.application.defaultRoles.push(role); + $scope.client.defaultRoles.push(role); } - idx = $scope.availableAppRoles.indexOf(role); + idx = $scope.availableClientRoles.indexOf(role); if (idx != -1) { - $scope.availableAppRoles.splice(idx, 1); + $scope.availableClientRoles.splice(idx, 1); } } - // Update/save the selected application with new default roles. - Application.update({ + // Update/save the selected client with new default roles. + Client.update({ realm: $scope.realm.realm, - application: $scope.application.id - }, $scope.application, function () { - Notifications.success("Your changes have been saved to the application."); + client: $scope.client.id + }, $scope.client, function () { + Notifications.success("Your changes have been saved to the client."); }); }; - $scope.rmAppDefaultRole = function () { + $scope.rmClientDefaultRole = function () { // Remove selected roles from the app default roles and add them to app available roles (move from right to left). - for (var i = 0; i < $scope.selectedAppDefRoles.length; i++) { - var role = $scope.selectedAppDefRoles[i]; - var idx = $scope.application.defaultRoles.indexOf(role); + for (var i = 0; i < $scope.selectedClientDefRoles.length; i++) { + var role = $scope.selectedClientDefRoles[i]; + var idx = $scope.client.defaultRoles.indexOf(role); if (idx != -1) { - $scope.application.defaultRoles.splice(idx, 1); + $scope.client.defaultRoles.splice(idx, 1); } - idx = $scope.availableAppRoles.indexOf(role); + idx = $scope.availableClientRoles.indexOf(role); if (idx < 0) { - $scope.availableAppRoles.push(role); + $scope.availableClientRoles.push(role); } } - // Update/save the selected application with new default roles. - Application.update({ + // Update/save the selected client with new default roles. + Client.update({ realm: $scope.realm.realm, - application: $scope.application.id - }, $scope.application, function () { - Notifications.success("Your changes have been saved to the application."); + client: $scope.client.id + }, $scope.client, function () { + Notifications.success("Your changes have been saved to the client."); }); }; @@ -848,7 +848,7 @@ module.controller('RealmIdentityProviderCtrl', function($scope, $filter, $upload alias : $scope.identityProvider.alias }, function() { $location.url("/realms/" + realm.realm + "/identity-provider-settings"); - Notifications.success("The application has been deleted."); + Notifications.success("The client has been deleted."); }); }); }; @@ -1008,7 +1008,7 @@ module.controller('RealmKeysDetailCtrl', function($scope, Realm, realm, $http, $ }; }); -module.controller('RealmSessionStatsCtrl', function($scope, realm, stats, RealmApplicationSessionStats, RealmLogoutAll, Notifications) { +module.controller('RealmSessionStatsCtrl', function($scope, realm, stats, RealmClientSessionStats, RealmLogoutAll, Notifications) { $scope.realm = realm; $scope.stats = stats; @@ -1073,7 +1073,7 @@ module.controller('RealmRevocationCtrl', function($scope, Realm, RealmPushRevoca var msgStart = successCount>0 ? 'Successfully push notBefore to: ' + globalReqResult.successRequests + ' . ' : ''; Notifications.error(msgStart + 'Failed to push notBefore to: ' + globalReqResult.failedRequests + '. Verify availability of failed hosts and try again'); } else { - Notifications.success('Successfully push notBefore to all configured applications'); + Notifications.success('Successfully push notBefore to all configured clients'); } }); } @@ -1094,8 +1094,8 @@ module.controller('RoleListCtrl', function($scope, $location, realm, roles) { }); -module.controller('RoleDetailCtrl', function($scope, realm, role, roles, applications, - Role, ApplicationRole, RoleById, RoleRealmComposites, RoleApplicationComposites, +module.controller('RoleDetailCtrl', function($scope, realm, role, roles, clients, + Role, ClientRole, RoleById, RoleRealmComposites, RoleClientComposites, $http, $location, Dialog, Notifications) { $scope.realm = realm; $scope.role = angular.copy(role); @@ -1141,8 +1141,8 @@ module.controller('RoleDetailCtrl', function($scope, realm, role, roles, applica - roleControl($scope, realm, role, roles, applications, - ApplicationRole, RoleById, RoleRealmComposites, RoleApplicationComposites, + roleControl($scope, realm, role, roles, clients, + ClientRole, RoleById, RoleRealmComposites, RoleClientComposites, $http, $location, Notifications, Dialog); }); diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/js/controllers/users.js b/forms/common-themes/src/main/resources/theme/base/admin/resources/js/controllers/users.js index 3d50839a9c..30003bd05a 100755 --- a/forms/common-themes/src/main/resources/theme/base/admin/resources/js/controllers/users.js +++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/js/controllers/users.js @@ -1,17 +1,17 @@ -module.controller('UserRoleMappingCtrl', function($scope, $http, realm, user, applications, Notifications, RealmRoleMapping, - ApplicationRoleMapping, AvailableRealmRoleMapping, AvailableApplicationRoleMapping, - CompositeRealmRoleMapping, CompositeApplicationRoleMapping) { +module.controller('UserRoleMappingCtrl', function($scope, $http, realm, user, clients, Notifications, RealmRoleMapping, + ClientRoleMapping, AvailableRealmRoleMapping, AvailableClientRoleMapping, + CompositeRealmRoleMapping, CompositeClientRoleMapping) { $scope.realm = realm; $scope.user = user; $scope.selectedRealmRoles = []; $scope.selectedRealmMappings = []; $scope.realmMappings = []; - $scope.applications = applications; - $scope.applicationRoles = []; - $scope.applicationComposite = []; - $scope.selectedApplicationRoles = []; - $scope.selectedApplicationMappings = []; - $scope.applicationMappings = []; + $scope.clients = clients; + $scope.clientRoles = []; + $scope.clientComposite = []; + $scope.selectedClientRoles = []; + $scope.selectedClientMappings = []; + $scope.clientMappings = []; $scope.dummymodel = []; $scope.realmMappings = RealmRoleMapping.query({realm : realm.realm, userId : user.username}); @@ -26,13 +26,13 @@ module.controller('UserRoleMappingCtrl', function($scope, $http, realm, user, ap $scope.realmComposite = CompositeRealmRoleMapping.query({realm : realm.realm, userId : user.username}); $scope.selectedRealmMappings = []; $scope.selectRealmRoles = []; - if ($scope.application) { + if ($scope.client) { console.log('load available'); - $scope.applicationComposite = CompositeApplicationRoleMapping.query({realm : realm.realm, userId : user.username, application : $scope.application.id}); - $scope.applicationRoles = AvailableApplicationRoleMapping.query({realm : realm.realm, userId : user.username, application : $scope.application.id}); - $scope.applicationMappings = ApplicationRoleMapping.query({realm : realm.realm, userId : user.username, application : $scope.application.id}); - $scope.selectedApplicationRoles = []; - $scope.selectedApplicationMappings = []; + $scope.clientComposite = CompositeClientRoleMapping.query({realm : realm.realm, userId : user.username, client : $scope.client.id}); + $scope.clientRoles = AvailableClientRoleMapping.query({realm : realm.realm, userId : user.username, client : $scope.client.id}); + $scope.clientMappings = ClientRoleMapping.query({realm : realm.realm, userId : user.username, client : $scope.client.id}); + $scope.selectedClientRoles = []; + $scope.selectedClientMappings = []; } Notifications.success("Role mappings updated."); @@ -47,57 +47,57 @@ module.controller('UserRoleMappingCtrl', function($scope, $http, realm, user, ap $scope.realmComposite = CompositeRealmRoleMapping.query({realm : realm.realm, userId : user.username}); $scope.selectedRealmMappings = []; $scope.selectRealmRoles = []; - if ($scope.application) { + if ($scope.client) { console.log('load available'); - $scope.applicationComposite = CompositeApplicationRoleMapping.query({realm : realm.realm, userId : user.username, application : $scope.application.id}); - $scope.applicationRoles = AvailableApplicationRoleMapping.query({realm : realm.realm, userId : user.username, application : $scope.application.id}); - $scope.applicationMappings = ApplicationRoleMapping.query({realm : realm.realm, userId : user.username, application : $scope.application.id}); - $scope.selectedApplicationRoles = []; - $scope.selectedApplicationMappings = []; + $scope.clientComposite = CompositeClientRoleMapping.query({realm : realm.realm, userId : user.username, client : $scope.client.id}); + $scope.clientRoles = AvailableClientRoleMapping.query({realm : realm.realm, userId : user.username, client : $scope.client.id}); + $scope.clientMappings = ClientRoleMapping.query({realm : realm.realm, userId : user.username, client : $scope.client.id}); + $scope.selectedClientRoles = []; + $scope.selectedClientMappings = []; } Notifications.success("Role mappings updated."); }); }; - $scope.addApplicationRole = function() { - $http.post(authUrl + '/admin/realms/' + realm.realm + '/users/' + user.username + '/role-mappings/applications-by-id/' + $scope.application.id, - $scope.selectedApplicationRoles).success(function() { - $scope.applicationMappings = ApplicationRoleMapping.query({realm : realm.realm, userId : user.username, application : $scope.application.id}); - $scope.applicationRoles = AvailableApplicationRoleMapping.query({realm : realm.realm, userId : user.username, application : $scope.application.id}); - $scope.applicationComposite = CompositeApplicationRoleMapping.query({realm : realm.realm, userId : user.username, application : $scope.application.id}); - $scope.selectedApplicationRoles = []; - $scope.selectedApplicationMappings = []; + $scope.addClientRole = function() { + $http.post(authUrl + '/admin/realms/' + realm.realm + '/users/' + user.username + '/role-mappings/clients-by-id/' + $scope.client.id, + $scope.selectedClientRoles).success(function() { + $scope.clientMappings = ClientRoleMapping.query({realm : realm.realm, userId : user.username, client : $scope.client.id}); + $scope.clientRoles = AvailableClientRoleMapping.query({realm : realm.realm, userId : user.username, client : $scope.client.id}); + $scope.clientComposite = CompositeClientRoleMapping.query({realm : realm.realm, userId : user.username, client : $scope.client.id}); + $scope.selectedClientRoles = []; + $scope.selectedClientMappings = []; Notifications.success("Role mappings updated."); }); }; - $scope.deleteApplicationRole = function() { - $http.delete(authUrl + '/admin/realms/' + realm.realm + '/users/' + user.username + '/role-mappings/applications-by-id/' + $scope.application.id, - {data : $scope.selectedApplicationMappings, headers : {"content-type" : "application/json"}}).success(function() { - $scope.applicationMappings = ApplicationRoleMapping.query({realm : realm.realm, userId : user.username, application : $scope.application.id}); - $scope.applicationRoles = AvailableApplicationRoleMapping.query({realm : realm.realm, userId : user.username, application : $scope.application.id}); - $scope.applicationComposite = CompositeApplicationRoleMapping.query({realm : realm.realm, userId : user.username, application : $scope.application.id}); - $scope.selectedApplicationRoles = []; - $scope.selectedApplicationMappings = []; + $scope.deleteClientRole = function() { + $http.delete(authUrl + '/admin/realms/' + realm.realm + '/users/' + user.username + '/role-mappings/clients-by-id/' + $scope.client.id, + {data : $scope.selectedClientMappings, headers : {"content-type" : "application/json"}}).success(function() { + $scope.clientMappings = ClientRoleMapping.query({realm : realm.realm, userId : user.username, client : $scope.client.id}); + $scope.clientRoles = AvailableClientRoleMapping.query({realm : realm.realm, userId : user.username, client : $scope.client.id}); + $scope.clientComposite = CompositeClientRoleMapping.query({realm : realm.realm, userId : user.username, client : $scope.client.id}); + $scope.selectedClientRoles = []; + $scope.selectedClientMappings = []; Notifications.success("Role mappings updated."); }); }; - $scope.changeApplication = function() { - console.log('changeApplication'); - if ($scope.application) { + $scope.changeClient = function() { + console.log('changeClient'); + if ($scope.client) { console.log('load available'); - $scope.applicationComposite = CompositeApplicationRoleMapping.query({realm : realm.realm, userId : user.username, application : $scope.application.id}); - $scope.applicationRoles = AvailableApplicationRoleMapping.query({realm : realm.realm, userId : user.username, application : $scope.application.id}); - $scope.applicationMappings = ApplicationRoleMapping.query({realm : realm.realm, userId : user.username, application : $scope.application.id}); + $scope.clientComposite = CompositeClientRoleMapping.query({realm : realm.realm, userId : user.username, client : $scope.client.id}); + $scope.clientRoles = AvailableClientRoleMapping.query({realm : realm.realm, userId : user.username, client : $scope.client.id}); + $scope.clientMappings = ClientRoleMapping.query({realm : realm.realm, userId : user.username, client : $scope.client.id}); } else { - $scope.applicationRoles = null; - $scope.applicationMappings = null; - $scope.applicationComposite = null; + $scope.clientRoles = null; + $scope.clientMappings = null; + $scope.clientComposite = null; } - $scope.selectedApplicationRoles = []; - $scope.selectedApplicationMappings = []; + $scope.selectedClientRoles = []; + $scope.selectedClientMappings = []; }; @@ -111,7 +111,7 @@ module.controller('UserSessionsCtrl', function($scope, realm, user, sessions, Us $scope.logoutAll = function() { UserLogout.save({realm : realm.realm, user: user.username}, function () { - Notifications.success('Logged out user in all applications'); + Notifications.success('Logged out user in all clients'); UserSessions.query({realm: realm.realm, user: user.username}, function(updated) { $scope.sessions = updated; }) diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/js/loaders.js b/forms/common-themes/src/main/resources/theme/base/admin/resources/js/loaders.js index 7223ae5592..b6e0541999 100755 --- a/forms/common-themes/src/main/resources/theme/base/admin/resources/js/loaders.js +++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/js/loaders.js @@ -71,19 +71,19 @@ module.factory('RealmSessionStatsLoader', function(Loader, RealmSessionStats, $r }); }); -module.factory('RealmApplicationSessionStatsLoader', function(Loader, RealmApplicationSessionStats, $route, $q) { - return Loader.query(RealmApplicationSessionStats, function() { +module.factory('RealmClientSessionStatsLoader', function(Loader, RealmClientSessionStats, $route, $q) { + return Loader.query(RealmClientSessionStats, function() { return { realm : $route.current.params.realm } }); }); -module.factory('ApplicationProtocolMapperLoader', function(Loader, ApplicationProtocolMapper, $route, $q) { - return Loader.get(ApplicationProtocolMapper, function() { +module.factory('ClientProtocolMapperLoader', function(Loader, ClientProtocolMapper, $route, $q) { + return Loader.get(ClientProtocolMapper, function() { return { realm : $route.current.params.realm, - application : $route.current.params.application, + client : $route.current.params.client, id: $route.current.params.id } }); @@ -164,74 +164,74 @@ module.factory('RoleListLoader', function(Loader, Role, $route, $q) { }); }); -module.factory('ApplicationRoleLoader', function(Loader, RoleById, $route, $q) { +module.factory('ClientRoleLoader', function(Loader, RoleById, $route, $q) { return Loader.get(RoleById, function() { return { realm : $route.current.params.realm, - application : $route.current.params.application, + client : $route.current.params.client, role : $route.current.params.role } }); }); -module.factory('ApplicationSessionStatsLoader', function(Loader, ApplicationSessionStats, $route, $q) { - return Loader.get(ApplicationSessionStats, function() { +module.factory('ClientSessionStatsLoader', function(Loader, ClientSessionStats, $route, $q) { + return Loader.get(ClientSessionStats, function() { return { realm : $route.current.params.realm, - application : $route.current.params.application + client : $route.current.params.client } }); }); -module.factory('ApplicationSessionCountLoader', function(Loader, ApplicationSessionCount, $route, $q) { - return Loader.get(ApplicationSessionCount, function() { +module.factory('ClientSessionCountLoader', function(Loader, ClientSessionCount, $route, $q) { + return Loader.get(ClientSessionCount, function() { return { realm : $route.current.params.realm, - application : $route.current.params.application + client : $route.current.params.client } }); }); -module.factory('ApplicationClaimsLoader', function(Loader, ApplicationClaims, $route, $q) { - return Loader.get(ApplicationClaims, function() { +module.factory('ClientClaimsLoader', function(Loader, ClientClaims, $route, $q) { + return Loader.get(ClientClaims, function() { return { realm : $route.current.params.realm, - application : $route.current.params.application + client : $route.current.params.client } }); }); -module.factory('ApplicationInstallationLoader', function(Loader, ApplicationInstallation, $route, $q) { - return Loader.get(ApplicationInstallation, function() { +module.factory('ClientInstallationLoader', function(Loader, ClientInstallation, $route, $q) { + return Loader.get(ClientInstallation, function() { return { realm : $route.current.params.realm, - application : $route.current.params.application + client : $route.current.params.client } }); }); -module.factory('ApplicationRoleListLoader', function(Loader, ApplicationRole, $route, $q) { - return Loader.query(ApplicationRole, function() { +module.factory('ClientRoleListLoader', function(Loader, ClientRole, $route, $q) { + return Loader.query(ClientRole, function() { return { realm : $route.current.params.realm, - application : $route.current.params.application + client : $route.current.params.client } }); }); -module.factory('ApplicationLoader', function(Loader, Application, $route, $q) { - return Loader.get(Application, function() { +module.factory('ClientLoader', function(Loader, Client, $route, $q) { + return Loader.get(Client, function() { return { realm : $route.current.params.realm, - application : $route.current.params.application + client : $route.current.params.client } }); }); -module.factory('ApplicationListLoader', function(Loader, Application, $route, $q) { - return Loader.query(Application, function() { +module.factory('ClientListLoader', function(Loader, Client, $route, $q) { + return Loader.query(Client, function() { return { realm : $route.current.params.realm } @@ -240,7 +240,7 @@ module.factory('ApplicationListLoader', function(Loader, Application, $route, $q module.factory('RoleMappingLoader', function(Loader, RoleMapping, $route, $q) { - var realm = $route.current.params.realm || $route.current.params.application; + var realm = $route.current.params.realm || $route.current.params.client; return Loader.query(RoleMapping, function() { return { diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/js/services.js b/forms/common-themes/src/main/resources/theme/base/admin/resources/js/services.js index 805bc01319..da0b2eb1a7 100755 --- a/forms/common-themes/src/main/resources/theme/base/admin/resources/js/services.js +++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/js/services.js @@ -190,10 +190,10 @@ module.factory('ServerInfo', function($resource) { -module.factory('ApplicationProtocolMapper', function($resource) { - return $resource(authUrl + '/admin/realms/:realm/applications-by-id/:application/protocol-mappers/models/:id', { +module.factory('ClientProtocolMapper', function($resource) { + return $resource(authUrl + '/admin/realms/:realm/clients-by-id/:client/protocol-mappers/models/:id', { realm : '@realm', - application: '@application', + client: '@client', id : "@id" }, { update : { @@ -324,72 +324,72 @@ module.factory('AvailableRealmRoleMapping', function($resource) { }); -module.factory('ApplicationRoleMapping', function($resource) { - return $resource(authUrl + '/admin/realms/:realm/users/:userId/role-mappings/applications-by-id/:application', { +module.factory('ClientRoleMapping', function($resource) { + return $resource(authUrl + '/admin/realms/:realm/users/:userId/role-mappings/clients-by-id/:client', { realm : '@realm', userId : '@userId', - application : "@application" + client : "@client" }); }); -module.factory('AvailableApplicationRoleMapping', function($resource) { - return $resource(authUrl + '/admin/realms/:realm/users/:userId/role-mappings/applications-by-id/:application/available', { +module.factory('AvailableClientRoleMapping', function($resource) { + return $resource(authUrl + '/admin/realms/:realm/users/:userId/role-mappings/clients-by-id/:client/available', { realm : '@realm', userId : '@userId', - application : "@application" + client : "@client" }); }); -module.factory('CompositeApplicationRoleMapping', function($resource) { - return $resource(authUrl + '/admin/realms/:realm/users/:userId/role-mappings/applications-by-id/:application/composite', { +module.factory('CompositeClientRoleMapping', function($resource) { + return $resource(authUrl + '/admin/realms/:realm/users/:userId/role-mappings/clients-by-id/:client/composite', { realm : '@realm', userId : '@userId', - application : "@application" + client : "@client" }); }); -module.factory('ApplicationRealmScopeMapping', function($resource) { - return $resource(authUrl + '/admin/realms/:realm/applications-by-id/:application/scope-mappings/realm', { +module.factory('ClientRealmScopeMapping', function($resource) { + return $resource(authUrl + '/admin/realms/:realm/clients-by-id/:client/scope-mappings/realm', { realm : '@realm', - application : '@application' + client : '@client' }); }); -module.factory('ApplicationAvailableRealmScopeMapping', function($resource) { - return $resource(authUrl + '/admin/realms/:realm/applications-by-id/:application/scope-mappings/realm/available', { +module.factory('ClientAvailableRealmScopeMapping', function($resource) { + return $resource(authUrl + '/admin/realms/:realm/clients-by-id/:client/scope-mappings/realm/available', { realm : '@realm', - application : '@application' + client : '@client' }); }); -module.factory('ApplicationCompositeRealmScopeMapping', function($resource) { - return $resource(authUrl + '/admin/realms/:realm/applications-by-id/:application/scope-mappings/realm/composite', { +module.factory('ClientCompositeRealmScopeMapping', function($resource) { + return $resource(authUrl + '/admin/realms/:realm/clients-by-id/:client/scope-mappings/realm/composite', { realm : '@realm', - application : '@application' + client : '@client' }); }); -module.factory('ApplicationApplicationScopeMapping', function($resource) { - return $resource(authUrl + '/admin/realms/:realm/applications-by-id/:application/scope-mappings/applications-by-id/:targetApp', { +module.factory('ClientClientScopeMapping', function($resource) { + return $resource(authUrl + '/admin/realms/:realm/clients-by-id/:client/scope-mappings/clients-by-id/:targetClient', { realm : '@realm', - application : '@application', - targetApp : '@targetApp' + client : '@client', + targetClient : '@targetClient' }); }); -module.factory('ApplicationAvailableApplicationScopeMapping', function($resource) { - return $resource(authUrl + '/admin/realms/:realm/applications-by-id/:application/scope-mappings/applications-by-id/:targetApp/available', { +module.factory('ClientAvailableClientScopeMapping', function($resource) { + return $resource(authUrl + '/admin/realms/:realm/clients-by-id/:client/scope-mappings/clients-by-id/:targetClient/available', { realm : '@realm', - application : '@application', - targetApp : '@targetApp' + client : '@client', + targetClient : '@targetClient' }); }); -module.factory('ApplicationCompositeApplicationScopeMapping', function($resource) { - return $resource(authUrl + '/admin/realms/:realm/applications-by-id/:application/scope-mappings/applications-by-id/:targetApp/composite', { +module.factory('ClientCompositeClientScopeMapping', function($resource) { + return $resource(authUrl + '/admin/realms/:realm/clients-by-id/:client/scope-mappings/clients-by-id/:targetClient/composite', { realm : '@realm', - application : '@application', - targetApp : '@targetApp' + client : '@client', + targetClient : '@targetClient' }); }); @@ -420,24 +420,24 @@ module.factory('RealmSessionStats', function($resource) { }); }); -module.factory('RealmApplicationSessionStats', function($resource) { - return $resource(authUrl + '/admin/realms/:realm/application-by-id-session-stats', { +module.factory('RealmClientSessionStats', function($resource) { + return $resource(authUrl + '/admin/realms/:realm/client-by-id-session-stats', { realm : '@realm' }); }); -module.factory('RoleApplicationComposites', function($resource) { - return $resource(authUrl + '/admin/realms/:realm/roles-by-id/:role/composites/applications-by-id/:application', { +module.factory('RoleClientComposites', function($resource) { + return $resource(authUrl + '/admin/realms/:realm/roles-by-id/:role/composites/clients-by-id/:client', { realm : '@realm', role : '@role', - application : "@application" + client : "@client" }); }); -function roleControl($scope, realm, role, roles, applications, - ApplicationRole, RoleById, RoleRealmComposites, RoleApplicationComposites, +function roleControl($scope, realm, role, roles, clients, + ClientRole, RoleById, RoleRealmComposites, RoleClientComposites, $http, $location, Notifications, Dialog) { $scope.$watch(function () { @@ -476,11 +476,11 @@ function roleControl($scope, realm, role, roles, applications, $scope.selectedRealmRoles = []; $scope.selectedRealmMappings = []; $scope.realmMappings = []; - $scope.applications = applications; - $scope.applicationRoles = []; - $scope.selectedApplicationRoles = []; - $scope.selectedApplicationMappings = []; - $scope.applicationMappings = []; + $scope.clients = clients; + $scope.clientRoles = []; + $scope.selectedClientRoles = []; + $scope.selectedClientMappings = []; + $scope.clientMappings = []; for (var j = 0; j < $scope.realmRoles.length; j++) { if ($scope.realmRoles[j].id == role.id) { @@ -540,61 +540,61 @@ function roleControl($scope, realm, role, roles, applications, }); }; - $scope.addApplicationRole = function() { + $scope.addClientRole = function() { $scope.compositeSwitchDisabled=true; $http.post(authUrl + '/admin/realms/' + realm.realm + '/roles-by-id/' + role.id + '/composites', - $scope.selectedApplicationRoles).success(function() { - for (var i = 0; i < $scope.selectedApplicationRoles.length; i++) { - var role = $scope.selectedApplicationRoles[i]; - var idx = $scope.applicationRoles.indexOf($scope.selectedApplicationRoles[i]); + $scope.selectedClientRoles).success(function() { + for (var i = 0; i < $scope.selectedClientRoles.length; i++) { + var role = $scope.selectedClientRoles[i]; + var idx = $scope.clientRoles.indexOf($scope.selectedClientRoles[i]); if (idx != -1) { - $scope.applicationRoles.splice(idx, 1); - $scope.applicationMappings.push(role); + $scope.clientRoles.splice(idx, 1); + $scope.clientMappings.push(role); } } - $scope.selectedApplicationRoles = []; + $scope.selectedClientRoles = []; }); }; - $scope.deleteApplicationRole = function() { + $scope.deleteClientRole = function() { $scope.compositeSwitchDisabled=true; $http.delete(authUrl + '/admin/realms/' + realm.realm + '/roles-by-id/' + role.id + '/composites', - {data : $scope.selectedApplicationMappings, headers : {"content-type" : "application/json"}}).success(function() { - for (var i = 0; i < $scope.selectedApplicationMappings.length; i++) { - var role = $scope.selectedApplicationMappings[i]; - var idx = $scope.applicationMappings.indexOf($scope.selectedApplicationMappings[i]); + {data : $scope.selectedClientMappings, headers : {"content-type" : "application/json"}}).success(function() { + for (var i = 0; i < $scope.selectedClientMappings.length; i++) { + var role = $scope.selectedClientMappings[i]; + var idx = $scope.clientMappings.indexOf($scope.selectedClientMappings[i]); if (idx != -1) { - $scope.applicationMappings.splice(idx, 1); - $scope.applicationRoles.push(role); + $scope.clientMappings.splice(idx, 1); + $scope.clientRoles.push(role); } } - $scope.selectedApplicationMappings = []; + $scope.selectedClientMappings = []; }); }; - $scope.changeApplication = function() { - $scope.applicationRoles = ApplicationRole.query({realm : realm.realm, application : $scope.compositeApp.id}, function() { - $scope.applicationMappings = RoleApplicationComposites.query({realm : realm.realm, role : role.id, application : $scope.compositeApp.id}, function(){ - for (var i = 0; i < $scope.applicationMappings.length; i++) { - var role = $scope.applicationMappings[i]; - for (var j = 0; j < $scope.applicationRoles.length; j++) { - var realmRole = $scope.applicationRoles[j]; + $scope.changeClient = function() { + $scope.clientRoles = ClientRole.query({realm : realm.realm, client : $scope.compositeClient.id}, function() { + $scope.clientMappings = RoleClientComposites.query({realm : realm.realm, role : role.id, client : $scope.compositeClient.id}, function(){ + for (var i = 0; i < $scope.clientMappings.length; i++) { + var role = $scope.clientMappings[i]; + for (var j = 0; j < $scope.clientRoles.length; j++) { + var realmRole = $scope.clientRoles[j]; if (realmRole.id == role.id) { - var idx = $scope.applicationRoles.indexOf(realmRole); + var idx = $scope.clientRoles.indexOf(realmRole); if (idx != -1) { - $scope.applicationRoles.splice(idx, 1); + $scope.clientRoles.splice(idx, 1); break; } } } } }); - for (var j = 0; j < $scope.applicationRoles.length; j++) { - if ($scope.applicationRoles[j] == role.id) { - var appRole = $scope.applicationRoles[j]; - var idx = $scope.applicationRoles.indexof(appRole); - $scope.applicationRoles.splice(idx, 1); + for (var j = 0; j < $scope.clientRoles.length; j++) { + if ($scope.clientRoles[j] == role.id) { + var appRole = $scope.clientRoles[j]; + var idx = $scope.clientRoles.indexof(appRole); + $scope.clientRoles.splice(idx, 1); break; } } @@ -630,10 +630,10 @@ module.factory('RoleById', function($resource) { }); }); -module.factory('ApplicationRole', function($resource) { - return $resource(authUrl + '/admin/realms/:realm/applications-by-id/:application/roles/:role', { +module.factory('ClientRole', function($resource) { + return $resource(authUrl + '/admin/realms/:realm/clients-by-id/:client/roles/:role', { realm : '@realm', - application : "@application", + client : "@client", role : '@role' }, { update : { @@ -642,10 +642,10 @@ module.factory('ApplicationRole', function($resource) { }); }); -module.factory('ApplicationClaims', function($resource) { - return $resource(authUrl + '/admin/realms/:realm/applications-by-id/:application/claims', { +module.factory('ClientClaims', function($resource) { + return $resource(authUrl + '/admin/realms/:realm/clients-by-id/:client/claims', { realm : '@realm', - application : "@application" + client : "@client" }, { update : { method : 'PUT' @@ -653,52 +653,52 @@ module.factory('ApplicationClaims', function($resource) { }); }); -module.factory('ApplicationProtocolMappersByProtocol', function($resource) { - return $resource(authUrl + '/admin/realms/:realm/applications-by-id/:application/protocol-mappers/protocol/:protocol', { +module.factory('ClientProtocolMappersByProtocol', function($resource) { + return $resource(authUrl + '/admin/realms/:realm/clients-by-id/:client/protocol-mappers/protocol/:protocol', { realm : '@realm', - application : "@application", + client : "@client", protocol : "@protocol" }); }); -module.factory('ApplicationSessionStats', function($resource) { - return $resource(authUrl + '/admin/realms/:realm/applications-by-id/:application/session-stats', { +module.factory('ClientSessionStats', function($resource) { + return $resource(authUrl + '/admin/realms/:realm/clients-by-id/:client/session-stats', { realm : '@realm', - application : "@application" + client : "@client" }); }); -module.factory('ApplicationSessionStatsWithUsers', function($resource) { - return $resource(authUrl + '/admin/realms/:realm/applications-by-id/:application/session-stats?users=true', { +module.factory('ClientSessionStatsWithUsers', function($resource) { + return $resource(authUrl + '/admin/realms/:realm/clients-by-id/:client/session-stats?users=true', { realm : '@realm', - application : "@application" + client : "@client" }); }); -module.factory('ApplicationSessionCount', function($resource) { - return $resource(authUrl + '/admin/realms/:realm/applications-by-id/:application/session-count', { +module.factory('ClientSessionCount', function($resource) { + return $resource(authUrl + '/admin/realms/:realm/clients-by-id/:client/session-count', { realm : '@realm', - application : "@application" + client : "@client" }); }); -module.factory('ApplicationUserSessions', function($resource) { - return $resource(authUrl + '/admin/realms/:realm/applications-by-id/:application/user-sessions', { +module.factory('ClientUserSessions', function($resource) { + return $resource(authUrl + '/admin/realms/:realm/clients-by-id/:client/user-sessions', { realm : '@realm', - application : "@application" + client : "@client" }); }); -module.factory('ApplicationLogoutAll', function($resource) { - return $resource(authUrl + '/admin/realms/:realm/applications-by-id/:application/logout-all', { +module.factory('ClientLogoutAll', function($resource) { + return $resource(authUrl + '/admin/realms/:realm/clients-by-id/:client/logout-all', { realm : '@realm', - application : "@application" + client : "@client" }); }); -module.factory('ApplicationLogoutUser', function($resource) { - return $resource(authUrl + '/admin/realms/:realm/applications-by-id/:application/logout-user/:user', { +module.factory('ClientLogoutUser', function($resource) { + return $resource(authUrl + '/admin/realms/:realm/clients-by-id/:client/logout-user/:user', { realm : '@realm', - application : "@application", + client : "@client", user : "@user" }); }); @@ -708,39 +708,39 @@ module.factory('RealmLogoutAll', function($resource) { }); }); -module.factory('ApplicationPushRevocation', function($resource) { - return $resource(authUrl + '/admin/realms/:realm/applications-by-id/:application/push-revocation', { +module.factory('ClientPushRevocation', function($resource) { + return $resource(authUrl + '/admin/realms/:realm/clients-by-id/:client/push-revocation', { realm : '@realm', - application : "@application" + client : "@client" }); }); -module.factory('ApplicationClusterNode', function($resource) { - return $resource(authUrl + '/admin/realms/:realm/applications-by-id/:application/nodes/:node', { +module.factory('ClientClusterNode', function($resource) { + return $resource(authUrl + '/admin/realms/:realm/clients-by-id/:client/nodes/:node', { realm : '@realm', - application : "@application" + client : "@client" }); }); -module.factory('ApplicationTestNodesAvailable', function($resource) { - return $resource(authUrl + '/admin/realms/:realm/applications-by-id/:application/test-nodes-available', { +module.factory('ClientTestNodesAvailable', function($resource) { + return $resource(authUrl + '/admin/realms/:realm/clients-by-id/:client/test-nodes-available', { realm : '@realm', - application : "@application" + client : "@client" }); }); -module.factory('ApplicationCertificate', function($resource) { - return $resource(authUrl + '/admin/realms/:realm/applications-by-id/:application/certificates/:attribute', { +module.factory('ClientCertificate', function($resource) { + return $resource(authUrl + '/admin/realms/:realm/clients-by-id/:client/certificates/:attribute', { realm : '@realm', - application : "@application", + client : "@client", attribute: "@attribute" }); }); -module.factory('ApplicationCertificateGenerate', function($resource) { - return $resource(authUrl + '/admin/realms/:realm/applications-by-id/:application/certificates/:attribute/generate', { +module.factory('ClientCertificateGenerate', function($resource) { + return $resource(authUrl + '/admin/realms/:realm/clients-by-id/:client/certificates/:attribute/generate', { realm : '@realm', - application : "@application", + client : "@client", attribute: "@attribute" }, { @@ -750,10 +750,10 @@ module.factory('ApplicationCertificateGenerate', function($resource) { }); }); -module.factory('ApplicationCertificateDownload', function($resource) { - return $resource(authUrl + '/admin/realms/:realm/applications-by-id/:application/certificates/:attribute/download', { +module.factory('ClientCertificateDownload', function($resource) { + return $resource(authUrl + '/admin/realms/:realm/clients-by-id/:client/certificates/:attribute/download', { realm : '@realm', - application : "@application", + client : "@client", attribute: "@attribute" }, { @@ -764,10 +764,10 @@ module.factory('ApplicationCertificateDownload', function($resource) { }); }); -module.factory('Application', function($resource) { - return $resource(authUrl + '/admin/realms/:realm/applications-by-id/:application', { +module.factory('Client', function($resource) { + return $resource(authUrl + '/admin/realms/:realm/clients-by-id/:client', { realm : '@realm', - application : '@application' + client : '@client' }, { update : { method : 'PUT' @@ -775,29 +775,29 @@ module.factory('Application', function($resource) { }); }); -module.factory('ApplicationInstallation', function($resource) { - var url = authUrl + '/admin/realms/:realm/applications-by-id/:application/installation/json'; +module.factory('ClientInstallation', function($resource) { + var url = authUrl + '/admin/realms/:realm/clients-by-id/:client/installation/json'; return { url : function(parameters) { - return url.replace(':realm', parameters.realm).replace(':application', parameters.application); + return url.replace(':realm', parameters.realm).replace(':client', parameters.client); } } }); -module.factory('ApplicationInstallationJBoss', function($resource) { - var url = authUrl + '/admin/realms/:realm/applications-by-id/:application/installation/jboss'; +module.factory('ClientInstallationJBoss', function($resource) { + var url = authUrl + '/admin/realms/:realm/clients-by-id/:client/installation/jboss'; return { url : function(parameters) { - return url.replace(':realm', parameters.realm).replace(':application', parameters.application); + return url.replace(':realm', parameters.realm).replace(':client', parameters.client); } } }); -module.factory('ApplicationCredentials', function($resource) { - return $resource(authUrl + '/admin/realms/:realm/applications-by-id/:application/client-secret', { +module.factory('ClientCredentials', function($resource) { + return $resource(authUrl + '/admin/realms/:realm/clients-by-id/:client/client-secret', { realm : '@realm', - application : '@application' + client : '@client' }, { update : { method : 'POST' @@ -805,10 +805,10 @@ module.factory('ApplicationCredentials', function($resource) { }); }); -module.factory('ApplicationOrigins', function($resource) { - return $resource(authUrl + '/admin/realms/:realm/applications-by-id/:application/allowed-origins', { +module.factory('ClientOrigins', function($resource) { + return $resource(authUrl + '/admin/realms/:realm/clients-by-id/:client/allowed-origins', { realm : '@realm', - application : '@application' + client : '@client' }, { update : { method : 'PUT', @@ -822,8 +822,8 @@ module.factory('Current', function(Realm, $route) { current.realms = {}; current.realm = null; - current.applications = {}; - current.application = null; + current.clients = {}; + current.client = null; current.refresh = function() { current.realm = null; diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/application-list.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/application-list.html deleted file mode 100755 index 92bb4af983..0000000000 --- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/application-list.html +++ /dev/null @@ -1,59 +0,0 @@ -
      -
      -

      -
      -

      {{realm.realm}} Applications

      - - - - - - - - - - - - - - - - - - - - - -
      -
      - - -
      -
      - Import - Create -
      -
      Application NameEnabledBase URL
      {{app.name}}{{app.enabled}} - {{app.baseUrl}} - Not defined -
      No applications available
      - -
      -
      \ No newline at end of file diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/application-clustering-node.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-clustering-node.html similarity index 79% rename from forms/common-themes/src/main/resources/theme/base/admin/resources/partials/application-clustering-node.html rename to forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-clustering-node.html index 3c4f6145e1..d959154e16 100644 --- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/application-clustering-node.html +++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-clustering-node.html @@ -1,14 +1,14 @@
      - +
      -

      {{application.name}} Clustering

      +

      {{client.clientId}} Clustering

      Cluster node on host {{node.host}} not registered!

      diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/application-clustering.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-clustering.html similarity index 78% rename from forms/common-themes/src/main/resources/theme/base/admin/resources/partials/application-clustering.html rename to forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-clustering.html index dd5316e0a4..cedd87d551 100644 --- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/application-clustering.html +++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-clustering.html @@ -1,13 +1,13 @@
      - +
      -

      {{application.name}} Clustering

      +

      {{client.clientId}} Clustering

      Basic configuration
      @@ -17,12 +17,12 @@
      - + @@ -30,7 +30,7 @@
      - +
      @@ -46,7 +46,7 @@
    Register node manually + tooltip-placement="bottom" href="#/register-node/realms/{{realm.realm}}/clients/{{client.id}}/clustering">Register node manually
    {{node.host}}{{node.host}} {{node.lastRegistration}}
    + + + + + + + + + + + + + + + + + + + +
    +
    + + +
    +
    + Import + Create +
    +
    Client IDEnabledBase URL
    {{client.clientId}}{{client.enabled}} + {{client.baseUrl}} + Not defined +
    No clients available
    + +
    +
    \ No newline at end of file diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/application-mappers-add.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-mappers-add.html similarity index 80% rename from forms/common-themes/src/main/resources/theme/base/admin/resources/partials/application-mappers-add.html rename to forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-mappers-add.html index 07ec62c626..c111c3be26 100755 --- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/application-mappers-add.html +++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-mappers-add.html @@ -1,14 +1,14 @@
    - +
    -

    {{realm.realm}} Add Builtin Protocol Mappers

    +

    {{realm.realm}} Add Builtin Protocol Mappers

    diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/application-mappers.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-mappers.html similarity index 65% rename from forms/common-themes/src/main/resources/theme/base/admin/resources/partials/application-mappers.html rename to forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-mappers.html index c9c14fede4..343a622525 100755 --- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/application-mappers.html +++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-mappers.html @@ -1,13 +1,13 @@
    - +
    -

    {{realm.realm}} {{application.name}} {{application.protocol}} Protocol Mappers

    +

    {{realm.realm}} {{client.clientId}} {{client.protocol}} Protocol Mappers

    @@ -21,8 +21,8 @@ @@ -34,7 +34,7 @@ - + diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/application-revocation.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-revocation.html similarity index 71% rename from forms/common-themes/src/main/resources/theme/base/admin/resources/partials/application-revocation.html rename to forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-revocation.html index cfd17cd741..22087c23ba 100755 --- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/application-revocation.html +++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-revocation.html @@ -1,13 +1,13 @@
    - +
    -

    {{application.name}} Revocation Policies

    +

    {{client.clientId}} Revocation Policies

    @@ -15,7 +15,7 @@
    - +
    @@ -23,7 +23,7 @@ -
    diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/application-role-detail.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-role-detail.html similarity index 72% rename from forms/common-themes/src/main/resources/theme/base/admin/resources/partials/application-role-detail.html rename to forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-role-detail.html index 9729b945a0..d57ab3f99b 100755 --- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/application-role-detail.html +++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-role-detail.html @@ -1,23 +1,23 @@
    - +
    -

    {{application.name}} {{role.name}} Application Role

    -

    {{application.name}} Add Application Role

    +

    {{client.clientId}} {{role.name}} Client Role

    +

    {{client.clientId}} Add Client Role

    * Required fields

    @@ -81,45 +81,45 @@
    -
    - Composite Application Roles +
    + Composite Client Roles
    - +
    - +
    -
    -
    +
    +
    - - + ng-model="selectedClientRoles" + ng-options="r.name for r in clientRoles">
    - -
    - - + ng-model="selectedClientMappings" + ng-options="r.name for r in clientMappings">
    diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/application-role-list.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-role-list.html similarity index 79% rename from forms/common-themes/src/main/resources/theme/base/admin/resources/partials/application-role-list.html rename to forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-role-list.html index b2dc850858..f996169d89 100755 --- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/application-role-list.html +++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-role-list.html @@ -1,20 +1,20 @@
    - +
    -

    {{application.name}} Application Roles

    +

    {{client.clientId}} Client Roles

    {{mapper.name}}{{mapper.name}} {{mapperTypes[mapper.protocolMapper].category}} {{mapperTypes[mapper.protocolMapper].name}}
    @@ -52,12 +52,12 @@ --> - + - +
    {{role.name}}{{role.name}} {{role.composite}} {{role.description}}
    No application roles availableNo client roles available
    diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/application-saml-key-export.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-saml-key-export.html similarity index 85% rename from forms/common-themes/src/main/resources/theme/base/admin/resources/partials/application-saml-key-export.html rename to forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-saml-key-export.html index 2431612060..1f29c0543e 100755 --- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/application-saml-key-export.html +++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-saml-key-export.html @@ -1,14 +1,14 @@
    - +
    -

    {{application.name}} SAML {{keyType}} Key Export

    +

    {{client.clientId}} SAML {{keyType}} Key Export

    diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/application-saml-key-import.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-saml-key-import.html similarity index 85% rename from forms/common-themes/src/main/resources/theme/base/admin/resources/partials/application-saml-key-import.html rename to forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-saml-key-import.html index 63e5a968d7..3a26937fd7 100755 --- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/application-saml-key-import.html +++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-saml-key-import.html @@ -1,14 +1,14 @@
    - +
    -

    {{application.name}} SAML {{keyType}} Key Import

    +

    {{client.clientId}} SAML {{keyType}} Key Import

    diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/application-saml-keys.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-saml-keys.html similarity index 86% rename from forms/common-themes/src/main/resources/theme/base/admin/resources/partials/application-saml-keys.html rename to forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-saml-keys.html index 5d9ba63782..206ce66366 100755 --- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/application-saml-keys.html +++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-saml-keys.html @@ -1,15 +1,15 @@
    - +
    -

    {{application.name}} SAML Keys

    +

    {{client.clientId}} SAML Keys

    -
    +
    Signing Key
    @@ -35,7 +35,7 @@
    -
    +
    Encryption Key
    diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/application-scope-mappings.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-scope-mappings.html similarity index 66% rename from forms/common-themes/src/main/resources/theme/base/admin/resources/partials/application-scope-mappings.html rename to forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-scope-mappings.html index ce693c1e3b..6339f4efc7 100755 --- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/application-scope-mappings.html +++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-scope-mappings.html @@ -1,28 +1,28 @@
    - +
    -

    {{application.name}} Scope Mappings

    +

    {{client.clientId}} Scope Mappings

    - +
    -
    +
    Realm Roles
    @@ -66,56 +66,56 @@
    -
    - Application Roles +
    + Client Roles
    - +
    - +
    -
    +
    - - + ng-model="selectedClientRoles" + ng-options="r.name for r in clientRoles">
    - -
    - - + ng-model="selectedClientMappings" + ng-options="r.name for r in clientMappings">
    -
    - - + ng-options="r.name for r in clientComposite">
    diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/application-sessions.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-sessions.html similarity index 78% rename from forms/common-themes/src/main/resources/theme/base/admin/resources/partials/application-sessions.html rename to forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-sessions.html index 3284c3ac5f..2df97f6108 100755 --- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/application-sessions.html +++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-sessions.html @@ -1,13 +1,13 @@
    - +
    -

    {{application.name}} Active Sessions

    +

    {{client.clientId}} Active Sessions

    @@ -15,7 +15,7 @@
    - +
    diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/protocol-mapper-detail.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/protocol-mapper-detail.html index aed7f506c6..03a52bb85e 100755 --- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/protocol-mapper-detail.html +++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/protocol-mapper-detail.html @@ -1,18 +1,18 @@
    - +

    {{mapper.name}} Protocol Mapper

    diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-cache-settings.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-cache-settings.html index 2567173017..e4a134c17d 100755 --- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-cache-settings.html +++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-cache-settings.html @@ -12,7 +12,7 @@
    - +
    diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-default-roles.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-default-roles.html index d2207f732d..f03349ea82 100755 --- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-default-roles.html +++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-default-roles.html @@ -40,45 +40,45 @@
    -
    - Application Default Roles +
    + Client Default Roles
    - +
    - +
    -
    +
    - - + ng-model="selectedClientRoles" + ng-options="r for r in availableClientRoles">
    - -
    - - + ng-model="selectedClientDefRoles" + ng-options="r for r in client.defaultRoles">
    diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-detail.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-detail.html index 80f8e13a7d..ae5b53a0a5 100755 --- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-detail.html +++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-detail.html @@ -17,7 +17,7 @@
    - +
    diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-identity-provider-oidc.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-identity-provider-oidc.html index d093744fe1..67b0a68fe1 100755 --- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-identity-provider-oidc.html +++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-identity-provider-oidc.html @@ -98,7 +98,7 @@
    - +
    @@ -108,7 +108,7 @@ Show Secret Hide Secret
    - +
    diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-identity-provider-social.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-identity-provider-social.html index 809984bcfe..dd0709392a 100755 --- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-identity-provider-social.html +++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-identity-provider-social.html @@ -25,7 +25,7 @@
    - +
    @@ -35,7 +35,7 @@ Show Secret Hide Secret
    - +
    diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-identity-provider-stackoverflow-ext.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-identity-provider-stackoverflow-ext.html index 86516dfaaa..07a0e604e1 100755 --- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-identity-provider-stackoverflow-ext.html +++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-identity-provider-stackoverflow-ext.html @@ -3,5 +3,5 @@
    - +
    diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-menu.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-menu.html index 00d2e31b3b..4c60b0271b 100755 --- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-menu.html +++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-menu.html @@ -4,12 +4,12 @@ || path[2] == 'login-settings' || path[2] == 'theme-settings' || path[2] == 'cache-settings' - || path[2] == 'keys-settings' || path[2] == 'smtp-settings' || path[2] == 'ldap-settings' || path[2] == 'auth-settings') && path[3] != 'applications') && 'active'"> + || path[2] == 'keys-settings' || path[2] == 'smtp-settings' || path[2] == 'ldap-settings' || path[2] == 'auth-settings') && path[3] != 'clients') && 'active'"> Settings
  • Users
  • -
  • Clients
  • -
  • Roles
  • +
  • Clients
  • +
  • Roles
  • Sessions and Tokens
  • Security Defenses
  • Events
  • diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-tokens.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-tokens.html index 2f30127aef..eb519ee9b3 100755 --- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-tokens.html +++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-tokens.html @@ -90,8 +90,7 @@
    - -
    +
    diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/role-detail.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/role-detail.html index d5be190d09..412c8a09ba 100755 --- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/role-detail.html +++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/role-detail.html @@ -74,45 +74,45 @@
    -
    - Composite Application Roles +
    + Composite Client Roles
    -
    -
    +
    - - + ng-model="selectedClientRoles" + ng-options="r.name for r in clientRoles">
    - -
    - - + ng-model="selectedClientMappings" + ng-options="r.name for r in clientMappings">
    diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/role-mappings.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/role-mappings.html index 0ae08be374..314212bd29 100755 --- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/role-mappings.html +++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/role-mappings.html @@ -63,56 +63,56 @@
    -
    - Application Roles +
    + Client Roles
    - +
    - +
    -
    +
    - - + ng-model="selectedClientRoles" + ng-options="r.name for r in clientRoles">
    - -
    - - + ng-model="selectedClientMappings" + ng-options="r.name for r in clientMappings">
    -
    - - + ng-options="r.name for r in clientComposite">
    diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/session-realm.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/session-realm.html index 1394703e15..2535b46f26 100755 --- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/session-realm.html +++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/session-realm.html @@ -18,13 +18,13 @@ - Application + Client Active Sessions - {{data.name}} + {{data.clientId}} {{data.active}} diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/session-revocation.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/session-revocation.html index 79007bc1dc..f84c5ae914 100755 --- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/session-revocation.html +++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/session-revocation.html @@ -23,7 +23,7 @@ -
    diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/user-sessions.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/user-sessions.html index f3de7e404d..9db3f7de09 100755 --- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/user-sessions.html +++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/user-sessions.html @@ -27,8 +27,7 @@ IP Address Started Last Access - Applications - OAuth Clients + Clients Action @@ -38,16 +37,11 @@ {{session.start | date:'medium'}} {{session.lastAccess | date:'medium'}} -
    - {{name}} + - - - logout diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/templates/kc-navigation-application.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/templates/kc-navigation-application.html deleted file mode 100755 index 49949d9c60..0000000000 --- a/forms/common-themes/src/main/resources/theme/base/admin/resources/templates/kc-navigation-application.html +++ /dev/null @@ -1,13 +0,0 @@ - \ No newline at end of file diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/templates/kc-navigation-client.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/templates/kc-navigation-client.html new file mode 100755 index 0000000000..9794e388f3 --- /dev/null +++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/templates/kc-navigation-client.html @@ -0,0 +1,13 @@ + \ No newline at end of file diff --git a/integration/adapter-core/src/main/java/org/keycloak/adapters/ServerRequest.java b/integration/adapter-core/src/main/java/org/keycloak/adapters/ServerRequest.java index 27a2949520..701dc097f4 100755 --- a/integration/adapter-core/src/main/java/org/keycloak/adapters/ServerRequest.java +++ b/integration/adapter-core/src/main/java/org/keycloak/adapters/ServerRequest.java @@ -102,8 +102,8 @@ public class ServerRequest { formparams.add(new BasicNameValuePair(OAuth2Constants.CODE, code)); formparams.add(new BasicNameValuePair(OAuth2Constants.REDIRECT_URI, redirectUri)); if (sessionId != null) { - formparams.add(new BasicNameValuePair(AdapterConstants.APPLICATION_SESSION_STATE, sessionId)); - formparams.add(new BasicNameValuePair(AdapterConstants.APPLICATION_SESSION_HOST, HostUtils.getHostName())); + formparams.add(new BasicNameValuePair(AdapterConstants.CLIENT_SESSION_STATE, sessionId)); + formparams.add(new BasicNameValuePair(AdapterConstants.CLIENT_SESSION_HOST, HostUtils.getHostName())); } HttpResponse response = null; HttpPost post = new HttpPost(tokenUrl); @@ -237,7 +237,7 @@ public class ServerRequest { } List formparams = new ArrayList(); - formparams.add(new BasicNameValuePair(AdapterConstants.APPLICATION_CLUSTER_HOST, host)); + formparams.add(new BasicNameValuePair(AdapterConstants.CLIENT_CLUSTER_HOST, host)); HttpPost post = new HttpPost(endpointUrl); diff --git a/model/api/src/main/java/org/keycloak/models/ClientModel.java b/model/api/src/main/java/org/keycloak/models/ClientModel.java index ad0c51e14c..9cc51f375c 100755 --- a/model/api/src/main/java/org/keycloak/models/ClientModel.java +++ b/model/api/src/main/java/org/keycloak/models/ClientModel.java @@ -62,7 +62,7 @@ public interface ClientModel extends RoleContainerModel { void updateDefaultRoles(String[] defaultRoles); - Set getApplicationScopeMappings(ClientModel client); + Set getClientScopeMappings(ClientModel client); boolean isBearerOnly(); void setBearerOnly(boolean only); diff --git a/model/api/src/main/java/org/keycloak/models/Constants.java b/model/api/src/main/java/org/keycloak/models/Constants.java index 7374d7bc5b..edba3e3284 100755 --- a/model/api/src/main/java/org/keycloak/models/Constants.java +++ b/model/api/src/main/java/org/keycloak/models/Constants.java @@ -5,9 +5,9 @@ package org.keycloak.models; * @version $Revision: 1 $ */ public interface Constants { - String ADMIN_CONSOLE_APPLICATION = "security-admin-console"; + String ADMIN_CONSOLE_CLIENT_ID = "security-admin-console"; - String ACCOUNT_MANAGEMENT_APP = "account"; + String ACCOUNT_MANAGEMENT_CLIENT_ID = "account"; String INSTALLED_APP_URN = "urn:ietf:wg:oauth:2.0:oob"; String INSTALLED_APP_URL = "http://localhost"; diff --git a/model/api/src/main/java/org/keycloak/models/RealmModel.java b/model/api/src/main/java/org/keycloak/models/RealmModel.java index 0272500d2c..17c88ea76e 100755 --- a/model/api/src/main/java/org/keycloak/models/RealmModel.java +++ b/model/api/src/main/java/org/keycloak/models/RealmModel.java @@ -232,9 +232,9 @@ public interface RealmModel extends RoleContainerModel { void setEnabledEventTypes(Set enabledEventTypes); - ClientModel getMasterAdminApp(); + ClientModel getMasterAdminClient(); - void setMasterAdminApp(ClientModel app); + void setMasterAdminClient(ClientModel client); boolean isIdentityFederationEnabled(); diff --git a/model/api/src/main/java/org/keycloak/models/UserModel.java b/model/api/src/main/java/org/keycloak/models/UserModel.java index 9055e7c4c1..770cf03a8a 100755 --- a/model/api/src/main/java/org/keycloak/models/UserModel.java +++ b/model/api/src/main/java/org/keycloak/models/UserModel.java @@ -66,7 +66,7 @@ public interface UserModel { void updateCredentialDirectly(UserCredentialValueModel cred); Set getRealmRoleMappings(); - Set getApplicationRoleMappings(ClientModel app); + Set getClientRoleMappings(ClientModel app); boolean hasRole(RoleModel role); void grantRole(RoleModel role); Set getRoleMappings(); diff --git a/model/api/src/main/java/org/keycloak/models/utils/RepresentationToModel.java b/model/api/src/main/java/org/keycloak/models/utils/RepresentationToModel.java index c8a976100a..ae26387bab 100755 --- a/model/api/src/main/java/org/keycloak/models/utils/RepresentationToModel.java +++ b/model/api/src/main/java/org/keycloak/models/utils/RepresentationToModel.java @@ -533,7 +533,7 @@ public class RepresentationToModel { if (resourceRep.isFullScopeAllowed() != null) { client.setFullScopeAllowed(resourceRep.isFullScopeAllowed()); } else { - client.setFullScopeAllowed(true); + client.setFullScopeAllowed(!client.isConsentRequired()); } if (resourceRep.getNodeReRegistrationTimeout() != null) { client.setNodeReRegistrationTimeout(resourceRep.getNodeReRegistrationTimeout()); diff --git a/model/api/src/main/java/org/keycloak/models/utils/UserModelDelegate.java b/model/api/src/main/java/org/keycloak/models/utils/UserModelDelegate.java index 40665e36cc..0e84ca9ca4 100755 --- a/model/api/src/main/java/org/keycloak/models/utils/UserModelDelegate.java +++ b/model/api/src/main/java/org/keycloak/models/utils/UserModelDelegate.java @@ -152,8 +152,8 @@ public class UserModelDelegate implements UserModel { } @Override - public Set getApplicationRoleMappings(ClientModel app) { - return delegate.getApplicationRoleMappings(app); + public Set getClientRoleMappings(ClientModel app) { + return delegate.getClientRoleMappings(app); } @Override diff --git a/model/file/src/main/java/org/keycloak/models/file/adapter/ClientAdapter.java b/model/file/src/main/java/org/keycloak/models/file/adapter/ClientAdapter.java index 85d9efc9a0..e40d25182c 100755 --- a/model/file/src/main/java/org/keycloak/models/file/adapter/ClientAdapter.java +++ b/model/file/src/main/java/org/keycloak/models/file/adapter/ClientAdapter.java @@ -565,7 +565,7 @@ public class ClientAdapter implements ClientModel { } @Override - public Set getApplicationScopeMappings(ClientModel client) { + public Set getClientScopeMappings(ClientModel client) { Set allScopes = client.getScopeMappings(); Set appRoles = new HashSet(); diff --git a/model/file/src/main/java/org/keycloak/models/file/adapter/RealmAdapter.java b/model/file/src/main/java/org/keycloak/models/file/adapter/RealmAdapter.java index 57e1620bfc..31b4bfc869 100755 --- a/model/file/src/main/java/org/keycloak/models/file/adapter/RealmAdapter.java +++ b/model/file/src/main/java/org/keycloak/models/file/adapter/RealmAdapter.java @@ -959,22 +959,22 @@ public class RealmAdapter implements RealmModel { } @Override - public ClientModel getMasterAdminApp() { + public ClientModel getMasterAdminClient() { return this.masterAdminApp; } @Override - public void setMasterAdminApp(ClientModel app) { - if (app == null) { + public void setMasterAdminClient(ClientModel client) { + if (client == null) { realm.setAdminAppId(null); this.masterAdminApp = null; } else { - String appId = app.getId(); + String appId = client.getId(); if (appId == null) { throw new IllegalStateException("Master Admin app not initialized."); } realm.setAdminAppId(appId); - this.masterAdminApp = app; + this.masterAdminApp = client; } } diff --git a/model/file/src/main/java/org/keycloak/models/file/adapter/UserAdapter.java b/model/file/src/main/java/org/keycloak/models/file/adapter/UserAdapter.java index 00b6af8403..e9ba84ab01 100755 --- a/model/file/src/main/java/org/keycloak/models/file/adapter/UserAdapter.java +++ b/model/file/src/main/java/org/keycloak/models/file/adapter/UserAdapter.java @@ -325,7 +325,7 @@ public class UserAdapter implements UserModel, Comparable { } @Override - public Set getApplicationRoleMappings(ClientModel app) { + public Set getClientRoleMappings(ClientModel app) { Set result = new HashSet(); for (RoleModel role : allRoles) { diff --git a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/ClientAdapter.java b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/ClientAdapter.java index 0dc490d12c..42d41538db 100755 --- a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/ClientAdapter.java +++ b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/ClientAdapter.java @@ -377,7 +377,7 @@ public class ClientAdapter implements ClientModel { } @Override - public Set getApplicationScopeMappings(ClientModel client) { + public Set getClientScopeMappings(ClientModel client) { Set roleMappings = client.getScopeMappings(); Set appRoles = new HashSet(); diff --git a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/RealmAdapter.java b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/RealmAdapter.java index 1e51a0cee1..f2532af4b3 100755 --- a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/RealmAdapter.java +++ b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/RealmAdapter.java @@ -11,7 +11,6 @@ import org.keycloak.models.RequiredCredentialModel; import org.keycloak.models.RoleModel; import org.keycloak.models.UserFederationProviderModel; import org.keycloak.models.cache.entities.CachedRealm; -import org.keycloak.models.entities.IdentityProviderMapperEntity; import org.keycloak.models.utils.KeycloakModelUtils; import java.security.Key; @@ -752,14 +751,14 @@ public class RealmAdapter implements RealmModel { } @Override - public ClientModel getMasterAdminApp() { + public ClientModel getMasterAdminClient() { return cacheSession.getRealm(Config.getAdminRealm()).getClientById(cached.getMasterAdminApp()); } @Override - public void setMasterAdminApp(ClientModel app) { + public void setMasterAdminClient(ClientModel client) { getDelegateForUpdate(); - updated.setMasterAdminApp(app); + updated.setMasterAdminClient(client); } @Override diff --git a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/UserAdapter.java b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/UserAdapter.java index e65983769d..2087fc20ea 100755 --- a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/UserAdapter.java +++ b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/UserAdapter.java @@ -219,8 +219,8 @@ public class UserAdapter implements UserModel { } @Override - public Set getApplicationRoleMappings(ClientModel app) { - if (updated != null) return updated.getApplicationRoleMappings(app); + public Set getClientRoleMappings(ClientModel app) { + if (updated != null) return updated.getClientRoleMappings(app); Set roleMappings = getRoleMappings(); Set appMappings = new HashSet(); for (RoleModel role : roleMappings) { diff --git a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/entities/CachedRealm.java b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/entities/CachedRealm.java index baafe4346e..d302c48979 100755 --- a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/entities/CachedRealm.java +++ b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/entities/CachedRealm.java @@ -155,7 +155,7 @@ public class CachedRealm { eventsListeners.addAll(model.getEventsListeners()); enabledEventTypes.addAll(model.getEnabledEventTypes()); defaultRoles.addAll(model.getDefaultRoles()); - masterAdminApp = model.getMasterAdminApp().getId(); + masterAdminApp = model.getMasterAdminClient().getId(); for (RoleModel role : model.getRoles()) { realmRoles.put(role.getName(), role.getId()); diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/ClientAdapter.java b/model/jpa/src/main/java/org/keycloak/models/jpa/ClientAdapter.java index 0bf53efaca..90e83f4c89 100755 --- a/model/jpa/src/main/java/org/keycloak/models/jpa/ClientAdapter.java +++ b/model/jpa/src/main/java/org/keycloak/models/jpa/ClientAdapter.java @@ -625,7 +625,7 @@ public class ClientAdapter implements ClientModel { } @Override - public Set getApplicationScopeMappings(ClientModel client) { + public Set getClientScopeMappings(ClientModel client) { Set roleMappings = client.getScopeMappings(); Set appRoles = new HashSet(); diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java b/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java index 2df2bf2b51..4370165ff5 100755 --- a/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java +++ b/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java @@ -1065,13 +1065,13 @@ public class RealmAdapter implements RealmModel { } @Override - public ClientModel getMasterAdminApp() { + public ClientModel getMasterAdminClient() { return new ClientAdapter(this, em, session, realm.getMasterAdminApp()); } @Override - public void setMasterAdminApp(ClientModel app) { - ClientEntity appEntity = app!=null ? em.getReference(ClientEntity.class, app.getId()) : null; + public void setMasterAdminClient(ClientModel client) { + ClientEntity appEntity = client !=null ? em.getReference(ClientEntity.class, client.getId()) : null; realm.setMasterAdminApp(appEntity); em.flush(); } diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/UserAdapter.java b/model/jpa/src/main/java/org/keycloak/models/jpa/UserAdapter.java index c0263ed700..a51d0de21b 100755 --- a/model/jpa/src/main/java/org/keycloak/models/jpa/UserAdapter.java +++ b/model/jpa/src/main/java/org/keycloak/models/jpa/UserAdapter.java @@ -363,7 +363,7 @@ public class UserAdapter implements UserModel { } @Override - public Set getApplicationRoleMappings(ClientModel app) { + public Set getClientRoleMappings(ClientModel app) { Set roleMappings = getRoleMappings(); Set roles = new HashSet(); diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/ClientAdapter.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/ClientAdapter.java index 0867ce10b8..a2e1fa04d2 100755 --- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/ClientAdapter.java +++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/ClientAdapter.java @@ -575,7 +575,7 @@ public class ClientAdapter extends AbstractMongoAdapter imple } @Override - public Set getApplicationScopeMappings(ClientModel client) { + public Set getClientScopeMappings(ClientModel client) { Set result = new HashSet(); List roles = MongoModelUtils.getAllScopesOfClient(client, invocationContext); diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RealmAdapter.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RealmAdapter.java index 64b5c41c8c..d7a534a9a5 100755 --- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RealmAdapter.java +++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RealmAdapter.java @@ -978,14 +978,14 @@ public class RealmAdapter extends AbstractMongoAdapter impleme } @Override - public ClientModel getMasterAdminApp() { + public ClientModel getMasterAdminClient() { MongoClientEntity appData = getMongoStore().loadEntity(MongoClientEntity.class, realm.getAdminAppId(), invocationContext); return appData != null ? new ClientAdapter(session, this, appData, invocationContext) : null; } @Override - public void setMasterAdminApp(ClientModel app) { - String adminAppId = app != null ? app.getId() : null; + public void setMasterAdminClient(ClientModel client) { + String adminAppId = client != null ? client.getId() : null; realm.setAdminAppId(adminAppId); updateRealm(); } diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/UserAdapter.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/UserAdapter.java index 6e7994abaa..874f7d8159 100755 --- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/UserAdapter.java +++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/UserAdapter.java @@ -316,7 +316,7 @@ public class UserAdapter extends AbstractMongoAdapter implement } @Override - public Set getApplicationRoleMappings(ClientModel app) { + public Set getClientRoleMappings(ClientModel app) { Set result = new HashSet(); List roles = MongoModelUtils.getAllRolesOfUser(this, invocationContext); diff --git a/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/EntityDescriptorImporter.java b/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/EntityDescriptorImporter.java index 32f0990d6c..1ad72bfd39 100755 --- a/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/EntityDescriptorImporter.java +++ b/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/EntityDescriptorImporter.java @@ -1,6 +1,6 @@ package org.keycloak.protocol.saml; -import org.keycloak.exportimport.ApplicationImporter; +import org.keycloak.exportimport.ClientImporter; import org.keycloak.models.RealmModel; import org.keycloak.services.resources.admin.RealmAuth; @@ -8,7 +8,7 @@ import org.keycloak.services.resources.admin.RealmAuth; * @author Bill Burke * @version $Revision: 1 $ */ -public class EntityDescriptorImporter implements ApplicationImporter { +public class EntityDescriptorImporter implements ClientImporter { @Override public Object createJaxrsService(RealmModel realm, RealmAuth auth) { return new EntityDescriptorImporterService(realm, auth); diff --git a/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/EntityDescriptorImporterFactory.java b/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/EntityDescriptorImporterFactory.java index 51644d904a..14af68569d 100755 --- a/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/EntityDescriptorImporterFactory.java +++ b/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/EntityDescriptorImporterFactory.java @@ -1,8 +1,8 @@ package org.keycloak.protocol.saml; import org.keycloak.Config; -import org.keycloak.exportimport.ApplicationImporter; -import org.keycloak.exportimport.ApplicationImporterFactory; +import org.keycloak.exportimport.ClientImporter; +import org.keycloak.exportimport.ClientImporterFactory; import org.keycloak.models.KeycloakSession; import org.keycloak.models.KeycloakSessionFactory; @@ -10,14 +10,14 @@ import org.keycloak.models.KeycloakSessionFactory; * @author Bill Burke * @version $Revision: 1 $ */ -public class EntityDescriptorImporterFactory implements ApplicationImporterFactory { +public class EntityDescriptorImporterFactory implements ClientImporterFactory { @Override public String getDisplayName() { return "SAML 2.0 Entity Descriptor"; } @Override - public ApplicationImporter create(KeycloakSession session) { + public ClientImporter create(KeycloakSession session) { return new EntityDescriptorImporter(); } diff --git a/saml/saml-protocol/src/main/resources/META-INF/services/org.keycloak.exportimport.ApplicationImporterFactory b/saml/saml-protocol/src/main/resources/META-INF/services/org.keycloak.exportimport.ClientImporterFactory similarity index 100% rename from saml/saml-protocol/src/main/resources/META-INF/services/org.keycloak.exportimport.ApplicationImporterFactory rename to saml/saml-protocol/src/main/resources/META-INF/services/org.keycloak.exportimport.ClientImporterFactory diff --git a/services/src/main/java/org/keycloak/exportimport/ApplicationImportSpi.java b/services/src/main/java/org/keycloak/exportimport/ClientImportSpi.java similarity index 71% rename from services/src/main/java/org/keycloak/exportimport/ApplicationImportSpi.java rename to services/src/main/java/org/keycloak/exportimport/ClientImportSpi.java index 4493b19e22..6fe071e536 100755 --- a/services/src/main/java/org/keycloak/exportimport/ApplicationImportSpi.java +++ b/services/src/main/java/org/keycloak/exportimport/ClientImportSpi.java @@ -7,20 +7,20 @@ import org.keycloak.provider.Spi; /** * @author Marek Posolda */ -public class ApplicationImportSpi implements Spi { +public class ClientImportSpi implements Spi { @Override public String getName() { - return "application-import"; + return "client-import"; } @Override public Class getProviderClass() { - return ApplicationImporter.class; + return ClientImporter.class; } @Override public Class getProviderFactoryClass() { - return ApplicationImporterFactory.class; + return ClientImporterFactory.class; } } diff --git a/services/src/main/java/org/keycloak/exportimport/ApplicationImporter.java b/services/src/main/java/org/keycloak/exportimport/ClientImporter.java similarity index 67% rename from services/src/main/java/org/keycloak/exportimport/ApplicationImporter.java rename to services/src/main/java/org/keycloak/exportimport/ClientImporter.java index f4c526ef40..3d236fb16e 100755 --- a/services/src/main/java/org/keycloak/exportimport/ApplicationImporter.java +++ b/services/src/main/java/org/keycloak/exportimport/ClientImporter.java @@ -5,11 +5,11 @@ import org.keycloak.provider.Provider; import org.keycloak.services.resources.admin.RealmAuth; /** - * Provider plugin interface for importing applications from an arbitrary configuration format + * Provider plugin interface for importing clients from an arbitrary configuration format * * @author Bill Burke * @version $Revision: 1 $ */ -public interface ApplicationImporter extends Provider { +public interface ClientImporter extends Provider { public Object createJaxrsService(RealmModel realm, RealmAuth auth); } diff --git a/services/src/main/java/org/keycloak/exportimport/ApplicationImporterFactory.java b/services/src/main/java/org/keycloak/exportimport/ClientImporterFactory.java similarity index 52% rename from services/src/main/java/org/keycloak/exportimport/ApplicationImporterFactory.java rename to services/src/main/java/org/keycloak/exportimport/ClientImporterFactory.java index b73e2e68c3..e70bbfaea4 100755 --- a/services/src/main/java/org/keycloak/exportimport/ApplicationImporterFactory.java +++ b/services/src/main/java/org/keycloak/exportimport/ClientImporterFactory.java @@ -3,11 +3,11 @@ package org.keycloak.exportimport; import org.keycloak.provider.ProviderFactory; /** - * Provider plugin interface for importing applications from an arbitrary configuration format + * Provider plugin interface for importing clients from an arbitrary configuration format * * @author Bill Burke * @version $Revision: 1 $ */ -public interface ApplicationImporterFactory extends ProviderFactory { +public interface ClientImporterFactory extends ProviderFactory { public String getDisplayName(); } diff --git a/services/src/main/java/org/keycloak/protocol/oidc/TokenManager.java b/services/src/main/java/org/keycloak/protocol/oidc/TokenManager.java index 6a27c5580b..8d9ab8c7ea 100755 --- a/services/src/main/java/org/keycloak/protocol/oidc/TokenManager.java +++ b/services/src/main/java/org/keycloak/protocol/oidc/TokenManager.java @@ -260,12 +260,12 @@ public class TokenManager { for (Map.Entry entry : token.getResourceAccess().entrySet()) { AccessToken.Access appAccess = newToken.getResourceAccess(entry.getKey()); if (appAccess == null && !entry.getValue().getRoles().isEmpty()) { - throw new OAuthErrorException(OAuthErrorException.INVALID_SCOPE, "User or application no longer has role permissions for application key: " + entry.getKey()); + throw new OAuthErrorException(OAuthErrorException.INVALID_SCOPE, "User or client no longer has role permissions for client key: " + entry.getKey()); } for (String roleName : entry.getValue().getRoles()) { if (!appAccess.getRoles().contains(roleName)) { - throw new OAuthErrorException(OAuthErrorException.INVALID_SCOPE, "User no long has permission for application role " + roleName); + throw new OAuthErrorException(OAuthErrorException.INVALID_SCOPE, "User no long has permission for client role " + roleName); } } } diff --git a/services/src/main/java/org/keycloak/protocol/oidc/endpoints/LogoutEndpoint.java b/services/src/main/java/org/keycloak/protocol/oidc/endpoints/LogoutEndpoint.java index 582de3825f..5bab0e0d11 100755 --- a/services/src/main/java/org/keycloak/protocol/oidc/endpoints/LogoutEndpoint.java +++ b/services/src/main/java/org/keycloak/protocol/oidc/endpoints/LogoutEndpoint.java @@ -145,9 +145,9 @@ public class LogoutEndpoint { * authenticate the client if it is not public. * * If the client is a confidential client - * you must include the client-id (application name or oauth client name) and secret in an Basic Auth Authorization header. + * you must include the client-id and secret in an Basic Auth Authorization header. * - * If the client is a public client, then you must include a "client_id" form parameter with the app's or oauth client's name. + * If the client is a public client, then you must include a "client_id" form parameter. * * returns 204 if successful, 400 if not with a json error response. * diff --git a/services/src/main/java/org/keycloak/protocol/oidc/endpoints/TokenEndpoint.java b/services/src/main/java/org/keycloak/protocol/oidc/endpoints/TokenEndpoint.java index 331dbec7a7..60b1b98db6 100755 --- a/services/src/main/java/org/keycloak/protocol/oidc/endpoints/TokenEndpoint.java +++ b/services/src/main/java/org/keycloak/protocol/oidc/endpoints/TokenEndpoint.java @@ -231,15 +231,15 @@ public class TokenEndpoint { throw new ErrorResponseException("invalid_grant", "Session not active", Response.Status.BAD_REQUEST); } - String adapterSessionId = formParams.getFirst(AdapterConstants.APPLICATION_SESSION_STATE); + String adapterSessionId = formParams.getFirst(AdapterConstants.CLIENT_SESSION_STATE); if (adapterSessionId != null) { - String adapterSessionHost = formParams.getFirst(AdapterConstants.APPLICATION_SESSION_HOST); + String adapterSessionHost = formParams.getFirst(AdapterConstants.CLIENT_SESSION_HOST); logger.debugf("Adapter Session '%s' saved in ClientSession for client '%s'. Host is '%s'", adapterSessionId, client.getClientId(), adapterSessionHost); - event.detail(AdapterConstants.APPLICATION_SESSION_STATE, adapterSessionId); - clientSession.setNote(AdapterConstants.APPLICATION_SESSION_STATE, adapterSessionId); - event.detail(AdapterConstants.APPLICATION_SESSION_HOST, adapterSessionHost); - clientSession.setNote(AdapterConstants.APPLICATION_SESSION_HOST, adapterSessionHost); + event.detail(AdapterConstants.CLIENT_SESSION_STATE, adapterSessionId); + clientSession.setNote(AdapterConstants.CLIENT_SESSION_STATE, adapterSessionId); + event.detail(AdapterConstants.CLIENT_SESSION_HOST, adapterSessionHost); + clientSession.setNote(AdapterConstants.CLIENT_SESSION_HOST, adapterSessionHost); } AccessToken token = tokenManager.createClientAccessToken(session, accessCode.getRequestedRoles(), realm, client, user, userSession, clientSession); diff --git a/services/src/main/java/org/keycloak/protocol/oidc/endpoints/ValidateTokenEndpoint.java b/services/src/main/java/org/keycloak/protocol/oidc/endpoints/ValidateTokenEndpoint.java index 31499d1bd1..249aa30ddb 100644 --- a/services/src/main/java/org/keycloak/protocol/oidc/endpoints/ValidateTokenEndpoint.java +++ b/services/src/main/java/org/keycloak/protocol/oidc/endpoints/ValidateTokenEndpoint.java @@ -88,7 +88,7 @@ public class ValidateTokenEndpoint { error.put(OAuth2Constants.ERROR, e.getError()); if (e.getDescription() != null) error.put(OAuth2Constants.ERROR_DESCRIPTION, e.getDescription()); event.error(Errors.INVALID_TOKEN); - return Response.status(Response.Status.BAD_REQUEST).entity(error).type("application/json").build(); + return Response.status(Response.Status.BAD_REQUEST).entity(error).type(MediaType.APPLICATION_JSON_TYPE).build(); } event.success(); diff --git a/services/src/main/java/org/keycloak/protocol/oidc/mappers/HardcodedRole.java b/services/src/main/java/org/keycloak/protocol/oidc/mappers/HardcodedRole.java index 088389fbec..4bed115f05 100755 --- a/services/src/main/java/org/keycloak/protocol/oidc/mappers/HardcodedRole.java +++ b/services/src/main/java/org/keycloak/protocol/oidc/mappers/HardcodedRole.java @@ -30,7 +30,7 @@ public class HardcodedRole extends AbstractOIDCProtocolMapper implements OIDCAcc property = new ConfigProperty(); property.setName(ROLE_CONFIG); property.setLabel("Role"); - property.setHelpText("Role you want added to the token. To specify an application role the syntax is appname.approle, i.e. myapp.myrole"); + property.setHelpText("Role you want added to the token. To specify a client role the syntax is clientId.clientRole, i.e. myapp.myrole"); property.setType(ConfigProperty.STRING_TYPE); configProperties.add(property); } diff --git a/services/src/main/java/org/keycloak/protocol/oidc/mappers/RoleNameMapper.java b/services/src/main/java/org/keycloak/protocol/oidc/mappers/RoleNameMapper.java index 1e5784cce7..14c68d67cc 100755 --- a/services/src/main/java/org/keycloak/protocol/oidc/mappers/RoleNameMapper.java +++ b/services/src/main/java/org/keycloak/protocol/oidc/mappers/RoleNameMapper.java @@ -33,7 +33,7 @@ public class RoleNameMapper extends AbstractOIDCProtocolMapper implements OIDCAc property = new ConfigProperty(); property.setName(ROLE_CONFIG); property.setLabel("Role"); - property.setHelpText("Role name you want changed. To reference an application role the syntax is appname.approle, i.e. myapp.myrole"); + property.setHelpText("Role name you want changed. To reference an client role the syntax is clientId.clientRole, i.e. myapp.myrole"); property.setType(ConfigProperty.STRING_TYPE); configProperties.add(property); property = new ConfigProperty(); diff --git a/services/src/main/java/org/keycloak/protocol/oidc/utils/AuthorizeClientUtil.java b/services/src/main/java/org/keycloak/protocol/oidc/utils/AuthorizeClientUtil.java index 4b97c97299..a8a9e2a495 100644 --- a/services/src/main/java/org/keycloak/protocol/oidc/utils/AuthorizeClientUtil.java +++ b/services/src/main/java/org/keycloak/protocol/oidc/utils/AuthorizeClientUtil.java @@ -10,6 +10,7 @@ import org.keycloak.models.RealmModel; import org.keycloak.util.BasicAuthHelper; import javax.ws.rs.core.HttpHeaders; +import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.core.Response; import java.util.HashMap; @@ -39,7 +40,7 @@ public class AuthorizeClientUtil { Map error = new HashMap(); error.put(OAuth2Constants.ERROR, "invalid_client"); error.put(OAuth2Constants.ERROR_DESCRIPTION, "Could not find client"); - throw new BadRequestException("Could not find client", Response.status(Response.Status.BAD_REQUEST).entity(error).type("application/json").build()); + throw new BadRequestException("Could not find client", Response.status(Response.Status.BAD_REQUEST).entity(error).type(MediaType.APPLICATION_JSON_TYPE).build()); } event.client(client_id); @@ -50,7 +51,7 @@ public class AuthorizeClientUtil { error.put(OAuth2Constants.ERROR, "invalid_client"); error.put(OAuth2Constants.ERROR_DESCRIPTION, "Could not find client"); event.error(Errors.CLIENT_NOT_FOUND); - throw new BadRequestException("Could not find client", Response.status(Response.Status.BAD_REQUEST).entity(error).type("application/json").build()); + throw new BadRequestException("Could not find client", Response.status(Response.Status.BAD_REQUEST).entity(error).type(MediaType.APPLICATION_JSON_TYPE).build()); } if (!client.isEnabled()) { @@ -58,7 +59,7 @@ public class AuthorizeClientUtil { error.put(OAuth2Constants.ERROR, "invalid_client"); error.put(OAuth2Constants.ERROR_DESCRIPTION, "Client is not enabled"); event.error(Errors.CLIENT_DISABLED); - throw new BadRequestException("Client is not enabled", Response.status(Response.Status.BAD_REQUEST).entity(error).type("application/json").build()); + throw new BadRequestException("Client is not enabled", Response.status(Response.Status.BAD_REQUEST).entity(error).type(MediaType.APPLICATION_JSON_TYPE).build()); } if (!client.isPublicClient()) { @@ -66,7 +67,7 @@ public class AuthorizeClientUtil { Map error = new HashMap(); error.put(OAuth2Constants.ERROR, "unauthorized_client"); event.error(Errors.INVALID_CLIENT_CREDENTIALS); - throw new BadRequestException("Unauthorized Client", Response.status(Response.Status.BAD_REQUEST).entity(error).type("application/json").build()); + throw new BadRequestException("Unauthorized Client", Response.status(Response.Status.BAD_REQUEST).entity(error).type(MediaType.APPLICATION_JSON_TYPE).build()); } } diff --git a/services/src/main/java/org/keycloak/services/ErrorResponseException.java b/services/src/main/java/org/keycloak/services/ErrorResponseException.java index bf9f278429..0dd3e13b8d 100644 --- a/services/src/main/java/org/keycloak/services/ErrorResponseException.java +++ b/services/src/main/java/org/keycloak/services/ErrorResponseException.java @@ -6,6 +6,7 @@ import org.keycloak.models.RealmModel; import org.keycloak.services.resources.flows.Flows; import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import javax.ws.rs.core.UriInfo; import java.util.HashMap; @@ -33,7 +34,7 @@ public class ErrorResponseException extends WebApplicationException { if (errorDescription != null) { e.put(OAuth2Constants.ERROR_DESCRIPTION, errorDescription); } - return Response.status(status).entity(e).type("application/json").build(); + return Response.status(status).entity(e).type(MediaType.APPLICATION_JSON_TYPE).build(); } } diff --git a/services/src/main/java/org/keycloak/services/managers/ApplianceBootstrap.java b/services/src/main/java/org/keycloak/services/managers/ApplianceBootstrap.java index 3caa7139ae..8760ff01b3 100755 --- a/services/src/main/java/org/keycloak/services/managers/ApplianceBootstrap.java +++ b/services/src/main/java/org/keycloak/services/managers/ApplianceBootstrap.java @@ -71,7 +71,7 @@ public class ApplianceBootstrap { RoleModel adminRole = realm.getRole(AdminRoles.ADMIN); adminUser.grantRole(adminRole); - ClientModel accountApp = realm.getClientNameMap().get(Constants.ACCOUNT_MANAGEMENT_APP); + ClientModel accountApp = realm.getClientNameMap().get(Constants.ACCOUNT_MANAGEMENT_CLIENT_ID); for (String r : accountApp.getDefaultRoles()) { adminUser.grantRole(accountApp.getRole(r)); } diff --git a/services/src/main/java/org/keycloak/services/managers/Auth.java b/services/src/main/java/org/keycloak/services/managers/Auth.java index ecaf0d9548..8d76e56cb6 100755 --- a/services/src/main/java/org/keycloak/services/managers/Auth.java +++ b/services/src/main/java/org/keycloak/services/managers/Auth.java @@ -80,7 +80,7 @@ public class Auth { return false; } - public boolean hasAppRole(ClientModel app, String role) { + public boolean hasClientRole(ClientModel app, String role) { if (cookie) { return user.hasRole(app.getRole(role)); } else { @@ -91,7 +91,7 @@ public class Auth { public boolean hasOneOfAppRole(ClientModel app, String... roles) { for (String r : roles) { - if (hasAppRole(app, r)) { + if (hasClientRole(app, r)) { return true; } } 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 4a03c26dbd..53b460a04c 100755 --- a/services/src/main/java/org/keycloak/services/managers/RealmManager.java +++ b/services/src/main/java/org/keycloak/services/managers/RealmManager.java @@ -18,7 +18,7 @@ import org.keycloak.models.UserModel; import org.keycloak.models.UserSessionProvider; import org.keycloak.models.utils.KeycloakModelUtils; import org.keycloak.models.utils.RepresentationToModel; -import org.keycloak.representations.idm.ApplicationRepresentation; +import org.keycloak.representations.idm.ClientRepresentation; import org.keycloak.representations.idm.RealmEventsConfigRepresentation; import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.timer.TimerProvider; @@ -90,8 +90,8 @@ public class RealmManager { } protected void setupAdminConsole(RealmModel realm) { - ClientModel adminConsole = realm.getClientByClientId(Constants.ADMIN_CONSOLE_APPLICATION); - if (adminConsole == null) adminConsole = new ClientManager(this).createClient(realm, Constants.ADMIN_CONSOLE_APPLICATION); + ClientModel adminConsole = realm.getClientByClientId(Constants.ADMIN_CONSOLE_CLIENT_ID); + if (adminConsole == null) adminConsole = new ClientManager(this).createClient(realm, Constants.ADMIN_CONSOLE_CLIENT_ID); String baseUrl = contextPath + "/admin/" + realm.getName() + "/console"; adminConsole.setBaseUrl(baseUrl + "/index.html"); adminConsole.setEnabled(true); @@ -103,18 +103,18 @@ public class RealmManager { if (realm.getName().equals(Config.getAdminRealm())) { adminRole = realm.getRole(AdminRoles.ADMIN); } else { - String realmAdminApplicationName = getRealmAdminApplicationName(realm); - ClientModel realmAdminApp = realm.getClientByClientId(realmAdminApplicationName); + String realmAdminApplicationClientId = getRealmAdminClientId(realm); + ClientModel realmAdminApp = realm.getClientByClientId(realmAdminApplicationClientId); adminRole = realmAdminApp.getRole(AdminRoles.REALM_ADMIN); } adminConsole.addScopeMapping(adminRole); } - public String getRealmAdminApplicationName(RealmModel realm) { + public String getRealmAdminClientId(RealmModel realm) { return "realm-management"; } - public String getRealmAdminApplicationName(RealmRepresentation realm) { + public String getRealmAdminClientId(RealmRepresentation realm) { return "realm-management"; } @@ -139,7 +139,7 @@ public class RealmManager { boolean removed = model.removeRealm(realm.getId()); if (removed) { - new ClientManager(this).removeClient(getKeycloakAdminstrationRealm(), realm.getMasterAdminApp()); + new ClientManager(this).removeClient(getKeycloakAdminstrationRealm(), realm.getMasterAdminClient()); UserSessionProvider sessions = session.sessions(); if (sessions != null) { @@ -176,18 +176,18 @@ public class RealmManager { ClientManager clientManager = new ClientManager(new RealmManager(session)); - String realmAdminApplicationName = getRealmAdminApplicationName(realm); - ClientModel realmAdminApp = realm.getClientByClientId(realmAdminApplicationName); - if (realmAdminApp == null) { - realmAdminApp = clientManager.createClient(realm, realmAdminApplicationName); + String realmAdminClientId = getRealmAdminClientId(realm); + ClientModel realmAdminClient = realm.getClientByClientId(realmAdminClientId); + if (realmAdminClient == null) { + realmAdminClient = clientManager.createClient(realm, realmAdminClientId); } - RoleModel adminRole = realmAdminApp.addRole(AdminRoles.REALM_ADMIN); - adminRole.setDescription("${role_"+AdminRoles.REALM_ADMIN+"}"); - realmAdminApp.setBearerOnly(true); - realmAdminApp.setFullScopeAllowed(false); + RoleModel adminRole = realmAdminClient.addRole(AdminRoles.REALM_ADMIN); + adminRole.setDescription("${role_" + AdminRoles.REALM_ADMIN + "}"); + realmAdminClient.setBearerOnly(true); + realmAdminClient.setFullScopeAllowed(false); for (String r : AdminRoles.ALL_REALM_ROLES) { - RoleModel role = realmAdminApp.addRole(r); + RoleModel role = realmAdminClient.addRole(r); role.setDescription("${role_"+r+"}"); adminRole.addCompositeRole(role); } @@ -195,19 +195,19 @@ public class RealmManager { private void setupAccountManagement(RealmModel realm) { - ClientModel application = realm.getClientNameMap().get(Constants.ACCOUNT_MANAGEMENT_APP); - if (application == null) { - application = new ClientManager(this).createClient(realm, Constants.ACCOUNT_MANAGEMENT_APP); - application.setEnabled(true); - application.setFullScopeAllowed(false); + ClientModel client = realm.getClientNameMap().get(Constants.ACCOUNT_MANAGEMENT_CLIENT_ID); + if (client == null) { + client = new ClientManager(this).createClient(realm, Constants.ACCOUNT_MANAGEMENT_CLIENT_ID); + client.setEnabled(true); + client.setFullScopeAllowed(false); String base = contextPath + "/realms/" + realm.getName() + "/account"; String redirectUri = base + "/*"; - application.addRedirectUri(redirectUri); - application.setBaseUrl(base); + client.addRedirectUri(redirectUri); + client.setBaseUrl(base); for (String role : AccountRoles.ALL) { - application.addDefaultRole(role); - application.getRole(role).setDescription("${role_"+role+"}"); + client.addDefaultRole(role); + client.getRole(role).setDescription("${role_"+role+"}"); } } } @@ -224,9 +224,9 @@ public class RealmManager { setupRealmDefaults(realm); setupMasterAdminManagement(realm); - if (!hasRealmAdminManagementApp(rep)) setupRealmAdminManagement(realm); - if (!hasAccountManagementApp(rep)) setupAccountManagement(realm); - if (!hasAdminConsoleApp(rep)) setupAdminConsole(realm); + if (!hasRealmAdminManagementClient(rep)) setupRealmAdminManagement(realm); + if (!hasAccountManagementClient(rep)) setupAccountManagement(realm); + if (!hasAdminConsoleClient(rep)) setupAdminConsole(realm); RepresentationToModel.importRealm(session, rep, realm); @@ -239,30 +239,30 @@ public class RealmManager { return realm; } - private boolean hasRealmAdminManagementApp(RealmRepresentation rep) { - if (rep.getApplications() == null) return false; - for (ApplicationRepresentation app : rep.getApplications()) { - if (app.getName().equals(getRealmAdminApplicationName(rep))) { + private boolean hasRealmAdminManagementClient(RealmRepresentation rep) { + if (rep.getClients() == null) return false; + for (ClientRepresentation clientRep : rep.getClients()) { + if (clientRep.getClientId().equals(getRealmAdminClientId(rep))) { return true; } } return false; } - private boolean hasAccountManagementApp(RealmRepresentation rep) { - if (rep.getApplications() == null) return false; - for (ApplicationRepresentation app : rep.getApplications()) { - if (app.getName().equals(Constants.ACCOUNT_MANAGEMENT_APP)) { + private boolean hasAccountManagementClient(RealmRepresentation rep) { + if (rep.getClients() == null) return false; + for (ClientRepresentation clientRep : rep.getClients()) { + if (clientRep.getClientId().equals(Constants.ACCOUNT_MANAGEMENT_CLIENT_ID)) { return true; } } return false; } - private boolean hasAdminConsoleApp(RealmRepresentation rep) { - if (rep.getApplications() == null) return false; - for (ApplicationRepresentation app : rep.getApplications()) { - if (app.getName().equals(Constants.ADMIN_CONSOLE_APPLICATION)) { + private boolean hasAdminConsoleClient(RealmRepresentation rep) { + if (rep.getClients() == null) return false; + for (ClientRepresentation clientRep : rep.getClients()) { + if (clientRep.getClientId().equals(Constants.ADMIN_CONSOLE_CLIENT_ID)) { return true; } } diff --git a/services/src/main/java/org/keycloak/services/managers/ResourceAdminManager.java b/services/src/main/java/org/keycloak/services/managers/ResourceAdminManager.java index fa219d6725..ac64cbc5b0 100755 --- a/services/src/main/java/org/keycloak/services/managers/ResourceAdminManager.java +++ b/services/src/main/java/org/keycloak/services/managers/ResourceAdminManager.java @@ -42,7 +42,7 @@ import java.util.Set; */ public class ResourceAdminManager { protected static Logger logger = Logger.getLogger(ResourceAdminManager.class); - private static final String APPLICATION_SESSION_HOST_PROPERTY = "${application.session.host}"; + private static final String CLIENT_SESSION_HOST_PROPERTY = "${application.session.host}"; public static ApacheHttpClient4Executor createExecutor() { HttpClient client = new HttpClientBuilder() @@ -57,13 +57,13 @@ public class ResourceAdminManager { } - public static String getManagementUrl(URI requestUri, ClientModel application) { - String mgmtUrl = application.getManagementUrl(); + public static String getManagementUrl(URI requestUri, ClientModel client) { + String mgmtUrl = client.getManagementUrl(); if (mgmtUrl == null || mgmtUrl.equals("")) { return null; } - // this is to support relative admin urls when keycloak and applications are deployed on the same machine + // this is to support relative admin urls when keycloak and clients are deployed on the same machine String absoluteURI = ResolveRelative.resolveRelativeUri(requestUri, mgmtUrl); // this is for resolving URI like "http://${jboss.host.name}:8080/..." in order to send request to same machine and avoid request to LB in cluster environment @@ -72,13 +72,13 @@ public class ResourceAdminManager { // For non-cluster setup, return just single configured managementUrls // For cluster setup, return the management Urls corresponding to all registered cluster nodes - private List getAllManagementUrls(URI requestUri, ClientModel application) { - String baseMgmtUrl = getManagementUrl(requestUri, application); + private List getAllManagementUrls(URI requestUri, ClientModel client) { + String baseMgmtUrl = getManagementUrl(requestUri, client); if (baseMgmtUrl == null) { return Collections.emptyList(); } - Set registeredNodesHosts = new ClientManager().validateRegisteredNodes(application); + Set registeredNodesHosts = new ClientManager().validateRegisteredNodes(client); // No-cluster setup if (registeredNodesHosts.isEmpty()) { @@ -128,7 +128,7 @@ public class ResourceAdminManager { } } - public void logoutUserFromApplication(URI requestUri, RealmModel realm, ClientModel resource, UserModel user, KeycloakSession session) { + public void logoutUserFromClient(URI requestUri, RealmModel realm, ClientModel resource, UserModel user, KeycloakSession session) { ApacheHttpClient4Executor executor = createExecutor(); try { @@ -163,9 +163,9 @@ public class ResourceAdminManager { if (clientSessions != null && clientSessions.size() > 0) { adapterSessionIds = new MultivaluedHashMap(); for (ClientSessionModel clientSession : clientSessions) { - String adapterSessionId = clientSession.getNote(AdapterConstants.APPLICATION_SESSION_STATE); + String adapterSessionId = clientSession.getNote(AdapterConstants.CLIENT_SESSION_STATE); if (adapterSessionId != null) { - String host = clientSession.getNote(AdapterConstants.APPLICATION_SESSION_HOST); + String host = clientSession.getNote(AdapterConstants.CLIENT_SESSION_HOST); adapterSessionIds.add(host, adapterSessionId); } if (clientSession.getUserSession() != null) userSessions.add(clientSession.getUserSession().getId()); @@ -177,13 +177,13 @@ public class ResourceAdminManager { return false; } - if (managementUrl.contains(APPLICATION_SESSION_HOST_PROPERTY)) { + if (managementUrl.contains(CLIENT_SESSION_HOST_PROPERTY)) { boolean allPassed = true; // Send logout separately to each host (needed for single-sign-out in cluster for non-distributable apps - KEYCLOAK-748) for (Map.Entry> entry : adapterSessionIds.entrySet()) { String host = entry.getKey(); List sessionIds = entry.getValue(); - String currentHostMgmtUrl = managementUrl.replace(APPLICATION_SESSION_HOST_PROPERTY, host); + String currentHostMgmtUrl = managementUrl.replace(CLIENT_SESSION_HOST_PROPERTY, host); allPassed = sendLogoutRequest(realm, resource, sessionIds, userSessions, client, 0, currentHostMgmtUrl) && allPassed; } @@ -215,7 +215,7 @@ public class ResourceAdminManager { GlobalRequestResult finalResult = new GlobalRequestResult(); for (ClientModel resource : resources) { - GlobalRequestResult currentResult = logoutApplication(requestUri, realm, resource, executor, realm.getNotBefore()); + GlobalRequestResult currentResult = logoutClient(requestUri, realm, resource, executor, realm.getNotBefore()); finalResult.addAll(currentResult); } return finalResult; @@ -224,25 +224,25 @@ public class ResourceAdminManager { } } - public GlobalRequestResult logoutApplication(URI requestUri, RealmModel realm, ClientModel resource) { + public GlobalRequestResult logoutClient(URI requestUri, RealmModel realm, ClientModel resource) { ApacheHttpClient4Executor executor = createExecutor(); try { resource.setNotBefore(Time.currentTime()); - return logoutApplication(requestUri, realm, resource, executor, resource.getNotBefore()); + return logoutClient(requestUri, realm, resource, executor, resource.getNotBefore()); } finally { executor.getHttpClient().getConnectionManager().shutdown(); } } - protected GlobalRequestResult logoutApplication(URI requestUri, RealmModel realm, ClientModel resource, ApacheHttpClient4Executor executor, int notBefore) { + protected GlobalRequestResult logoutClient(URI requestUri, RealmModel realm, ClientModel resource, ApacheHttpClient4Executor executor, int notBefore) { List mgmtUrls = getAllManagementUrls(requestUri, resource); if (mgmtUrls.isEmpty()) { - logger.debug("No management URL or no registered cluster nodes for the application " + resource.getClientId()); + logger.debug("No management URL or no registered cluster nodes for the client " + resource.getClientId()); return new GlobalRequestResult(); } - if (logger.isDebugEnabled()) logger.debug("Send logoutApplication for URLs: " + mgmtUrls); + if (logger.isDebugEnabled()) logger.debug("Send logoutClient for URLs: " + mgmtUrls); // Propagate this to all hosts GlobalRequestResult result = new GlobalRequestResult(); @@ -265,7 +265,7 @@ public class ResourceAdminManager { try { response = request.body(MediaType.TEXT_PLAIN_TYPE, token).post(); } catch (Exception e) { - logger.warn("Logout for application '" + resource.getClientId() + "' failed", e); + logger.warn("Logout for client '" + resource.getClientId() + "' failed", e); return false; } try { @@ -282,8 +282,8 @@ public class ResourceAdminManager { try { GlobalRequestResult finalResult = new GlobalRequestResult(); - for (ClientModel application : realm.getClients()) { - GlobalRequestResult currentResult = pushRevocationPolicy(requestUri, realm, application, realm.getNotBefore(), executor); + for (ClientModel client : realm.getClients()) { + GlobalRequestResult currentResult = pushRevocationPolicy(requestUri, realm, client, realm.getNotBefore(), executor); finalResult.addAll(currentResult); } return finalResult; @@ -292,11 +292,11 @@ public class ResourceAdminManager { } } - public GlobalRequestResult pushApplicationRevocationPolicy(URI requestUri, RealmModel realm, ClientModel application) { + public GlobalRequestResult pushClientRevocationPolicy(URI requestUri, RealmModel realm, ClientModel client) { ApacheHttpClient4Executor executor = createExecutor(); try { - return pushRevocationPolicy(requestUri, realm, application, application.getNotBefore(), executor); + return pushRevocationPolicy(requestUri, realm, client, client.getNotBefore(), executor); } finally { executor.getHttpClient().getConnectionManager().shutdown(); } @@ -306,7 +306,7 @@ public class ResourceAdminManager { protected GlobalRequestResult pushRevocationPolicy(URI requestUri, RealmModel realm, ClientModel resource, int notBefore, ApacheHttpClient4Executor executor) { List mgmtUrls = getAllManagementUrls(requestUri, resource); if (mgmtUrls.isEmpty()) { - logger.debugf("No management URL or no registered cluster nodes for the application %s", resource.getClientId()); + logger.debugf("No management URL or no registered cluster nodes for the client %s", resource.getClientId()); return new GlobalRequestResult(); } @@ -345,10 +345,10 @@ public class ResourceAdminManager { } } - public GlobalRequestResult testNodesAvailability(URI requestUri, RealmModel realm, ClientModel application) { - List mgmtUrls = getAllManagementUrls(requestUri, application); + public GlobalRequestResult testNodesAvailability(URI requestUri, RealmModel realm, ClientModel client) { + List mgmtUrls = getAllManagementUrls(requestUri, client); if (mgmtUrls.isEmpty()) { - logger.debug("No management URL or no registered cluster nodes for the application " + application.getClientId()); + logger.debug("No management URL or no registered cluster nodes for the application " + client.getClientId()); return new GlobalRequestResult(); } @@ -360,7 +360,7 @@ public class ResourceAdminManager { // Propagate this to all hosts GlobalRequestResult result = new GlobalRequestResult(); for (String mgmtUrl : mgmtUrls) { - if (sendTestNodeAvailabilityRequest(realm, application, executor, mgmtUrl)) { + if (sendTestNodeAvailabilityRequest(realm, client, executor, mgmtUrl)) { result.addSuccessRequest(mgmtUrl); } else { result.addFailedRequest(mgmtUrl); @@ -372,11 +372,11 @@ public class ResourceAdminManager { } } - protected boolean sendTestNodeAvailabilityRequest(RealmModel realm, ClientModel application, ApacheHttpClient4Executor client, String managementUrl) { - TestAvailabilityAction adminAction = new TestAvailabilityAction(TokenIdGenerator.generateId(), Time.currentTime() + 30, application.getClientId()); + protected boolean sendTestNodeAvailabilityRequest(RealmModel realm, ClientModel client, ApacheHttpClient4Executor httpClient, String managementUrl) { + TestAvailabilityAction adminAction = new TestAvailabilityAction(TokenIdGenerator.generateId(), Time.currentTime() + 30, client.getClientId()); String token = new TokenManager().encodeToken(realm, adminAction); - logger.debugv("testNodes availability resource: {0} url: {1}", application.getClientId(), managementUrl); - ClientRequest request = client.createRequest(UriBuilder.fromUri(managementUrl).path(AdapterConstants.K_TEST_AVAILABLE).build().toString()); + logger.debugv("testNodes availability resource: {0} url: {1}", client.getClientId(), managementUrl); + ClientRequest request = httpClient.createRequest(UriBuilder.fromUri(managementUrl).path(AdapterConstants.K_TEST_AVAILABLE).build().toString()); ClientResponse response; try { response = request.body(MediaType.TEXT_PLAIN_TYPE, token).post(); diff --git a/services/src/main/java/org/keycloak/services/resources/AccountService.java b/services/src/main/java/org/keycloak/services/resources/AccountService.java index d3e979ba20..71fb570adb 100755 --- a/services/src/main/java/org/keycloak/services/resources/AccountService.java +++ b/services/src/main/java/org/keycloak/services/resources/AccountService.java @@ -131,16 +131,16 @@ public class AccountService { private KeycloakSession session; private final AppAuthManager authManager; - private final ClientModel application; + private final ClientModel client; private EventBuilder event; private AccountProvider account; private Auth auth; private EventStoreProvider eventStore; private String stateChecker; - public AccountService(RealmModel realm, ClientModel application, EventBuilder event) { + public AccountService(RealmModel realm, ClientModel client, EventBuilder event) { this.realm = realm; - this.application = application; + this.client = client; this.event = event; this.authManager = new AppAuthManager(); } @@ -152,11 +152,11 @@ public class AccountService { AuthenticationManager.AuthResult authResult = authManager.authenticateBearerToken(session, realm, uriInfo, clientConnection, headers); if (authResult != null) { - auth = new Auth(realm, authResult.getToken(), authResult.getUser(), application, authResult.getSession(), false); + auth = new Auth(realm, authResult.getToken(), authResult.getUser(), client, authResult.getSession(), false); } else { authResult = authManager.authenticateIdentityCookie(session, realm, uriInfo, clientConnection, headers); if (authResult != null) { - auth = new Auth(realm, authResult.getToken(), authResult.getUser(), application, authResult.getSession(), true); + auth = new Auth(realm, authResult.getToken(), authResult.getUser(), client, authResult.getSession(), true); Cookie cookie = headers.getCookies().get(KEYCLOAK_STATE_CHECKER); if (cookie != null) { stateChecker = cookie.getValue(); @@ -193,14 +193,14 @@ public class AccountService { if (userSession != null) { boolean associated = false; for (ClientSessionModel c : userSession.getClientSessions()) { - if (c.getClient().equals(application)) { + if (c.getClient().equals(client)) { auth.setClientSession(c); associated = true; break; } } if (!associated) { - ClientSessionModel clientSession = session.sessions().createClientSession(realm, application); + ClientSessionModel clientSession = session.sessions().createClientSession(realm, client); clientSession.setUserSession(userSession); auth.setClientSession(clientSession); } @@ -737,7 +737,7 @@ public class AccountService { logger.debug("realm not enabled"); throw new ForbiddenException(); } - if (!application.isEnabled()) { + if (!client.isEnabled()) { logger.debug("account management app not enabled"); throw new ForbiddenException(); } @@ -766,7 +766,7 @@ public class AccountService { String authUrl = OIDCLoginProtocolService.authUrl(uriInfo).build(realm.getName()).toString(); oauth.setAuthUrl(authUrl); - oauth.setClientId(Constants.ACCOUNT_MANAGEMENT_APP); + oauth.setClientId(Constants.ACCOUNT_MANAGEMENT_CLIENT_ID); UriBuilder uriBuilder = Urls.accountPageBuilder(uriInfo.getBaseUri()).path(AccountService.class, "loginRedirect"); @@ -813,21 +813,21 @@ public class AccountService { String referrerUri = uriInfo.getQueryParameters().getFirst("referrer_uri"); - ClientModel application = realm.getClientByClientId(referrer); - if (application != null) { + ClientModel referrerClient = realm.getClientByClientId(referrer); + if (referrerClient != null) { if (referrerUri != null) { - referrerUri = RedirectUtils.verifyRedirectUri(uriInfo, referrerUri, realm, application); + referrerUri = RedirectUtils.verifyRedirectUri(uriInfo, referrerUri, realm, referrerClient); } else { - referrerUri = ResolveRelative.resolveRelativeUri(uriInfo.getRequestUri(), application.getBaseUrl()); + referrerUri = ResolveRelative.resolveRelativeUri(uriInfo.getRequestUri(), referrerClient.getBaseUrl()); } if (referrerUri != null) { return new String[]{referrer, referrerUri}; } } else if (referrerUri != null) { - ClientModel client = realm.getClientByClientId(referrer); + referrerClient = realm.getClientByClientId(referrer); if (client != null) { - referrerUri = RedirectUtils.verifyRedirectUri(uriInfo, referrerUri, realm, application); + referrerUri = RedirectUtils.verifyRedirectUri(uriInfo, referrerUri, realm, referrerClient); if (referrerUri != null) { return new String[]{referrer, referrerUri}; @@ -843,7 +843,7 @@ public class AccountService { throw new ForbiddenException(); } - if (!auth.hasAppRole(application, role)) { + if (!auth.hasClientRole(client, role)) { throw new ForbiddenException(); } } @@ -853,7 +853,7 @@ public class AccountService { throw new ForbiddenException(); } - if (!auth.hasOneOfAppRole(application, roles)) { + if (!auth.hasOneOfAppRole(client, roles)) { throw new ForbiddenException(); } } diff --git a/services/src/main/java/org/keycloak/services/resources/ClientsManagementService.java b/services/src/main/java/org/keycloak/services/resources/ClientsManagementService.java index beca17de43..1eb54800a4 100755 --- a/services/src/main/java/org/keycloak/services/resources/ClientsManagementService.java +++ b/services/src/main/java/org/keycloak/services/resources/ClientsManagementService.java @@ -24,6 +24,7 @@ import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.core.Context; import javax.ws.rs.core.HttpHeaders; +import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.core.Response; import javax.ws.rs.core.UriBuilder; @@ -81,7 +82,7 @@ public class ClientsManagementService { } /** - * URL invoked by adapter to register new application cluster node. Each application cluster node will invoke this URL once it joins cluster + * URL invoked by adapter to register new client cluster node. Each application cluster node will invoke this URL once it joins cluster * * @param authorizationHeader * @param formData @@ -89,7 +90,7 @@ public class ClientsManagementService { */ @Path("register-node") @POST - @Produces("application/json") + @Produces(MediaType.APPLICATION_JSON) public Response registerNode(@HeaderParam(HttpHeaders.AUTHORIZATION) String authorizationHeader, final MultivaluedMap formData) { if (!checkSsl()) { throw new ForbiddenException("HTTPS required"); @@ -102,13 +103,13 @@ public class ClientsManagementService { throw new UnauthorizedException("Realm not enabled"); } - ClientModel application = authorizeApplication(authorizationHeader, formData); - String nodeHost = getApplicationClusterHost(formData); + ClientModel client = authorizeClient(authorizationHeader, formData); + String nodeHost = getClientClusterHost(formData); - event.client(application).detail(Details.NODE_HOST, nodeHost); - logger.debugf("Registering cluster host '%s' for client '%s'", nodeHost, application.getClientId()); + event.client(client).detail(Details.NODE_HOST, nodeHost); + logger.debugf("Registering cluster host '%s' for client '%s'", nodeHost, client.getClientId()); - application.registerNode(nodeHost, Time.currentTime()); + client.registerNode(nodeHost, Time.currentTime()); event.success(); @@ -117,7 +118,7 @@ public class ClientsManagementService { /** - * URL invoked by adapter to register new application cluster node. Each application cluster node will invoke this URL once it joins cluster + * URL invoked by adapter to register new client cluster node. Each application cluster node will invoke this URL once it joins cluster * * @param authorizationHeader * @param formData @@ -125,7 +126,7 @@ public class ClientsManagementService { */ @Path("unregister-node") @POST - @Produces("application/json") + @Produces(MediaType.APPLICATION_JSON) public Response unregisterNode(@HeaderParam(HttpHeaders.AUTHORIZATION) String authorizationHeader, final MultivaluedMap formData) { if (!checkSsl()) { throw new ForbiddenException("HTTPS required"); @@ -138,20 +139,20 @@ public class ClientsManagementService { throw new UnauthorizedException("Realm not enabled"); } - ClientModel application = authorizeApplication(authorizationHeader, formData); - String nodeHost = getApplicationClusterHost(formData); + ClientModel client = authorizeClient(authorizationHeader, formData); + String nodeHost = getClientClusterHost(formData); - event.client(application).detail(Details.NODE_HOST, nodeHost); - logger.debugf("Unregistering cluster host '%s' for client '%s'", nodeHost, application.getClientId()); + event.client(client).detail(Details.NODE_HOST, nodeHost); + logger.debugf("Unregistering cluster host '%s' for client '%s'", nodeHost, client.getClientId()); - application.unregisterNode(nodeHost); + client.unregisterNode(nodeHost); event.success(); return Response.noContent().build(); } - protected ClientModel authorizeApplication(String authorizationHeader, MultivaluedMap formData) { + protected ClientModel authorizeClient(String authorizationHeader, MultivaluedMap formData) { ClientModel client = AuthorizeClientUtil.authorizeClient(authorizationHeader, formData, event, realm); if (client.isPublicClient()) { @@ -159,31 +160,23 @@ public class ClientsManagementService { error.put(OAuth2Constants.ERROR, "invalid_client"); error.put(OAuth2Constants.ERROR_DESCRIPTION, "Public clients not allowed"); event.error(Errors.INVALID_CLIENT); - throw new BadRequestException("Public clients not allowed", javax.ws.rs.core.Response.status(javax.ws.rs.core.Response.Status.BAD_REQUEST).entity(error).type("application/json").build()); + throw new BadRequestException("Public clients not allowed", javax.ws.rs.core.Response.status(javax.ws.rs.core.Response.Status.BAD_REQUEST).entity(error).type(MediaType.APPLICATION_JSON_TYPE).build()); } - if (!(client instanceof ClientModel)) { - Map error = new HashMap(); - error.put(OAuth2Constants.ERROR, "invalid_client"); - error.put(OAuth2Constants.ERROR_DESCRIPTION, "Just applications are allowed"); - event.error(Errors.INVALID_CLIENT); - throw new BadRequestException("ust applications are allowed", javax.ws.rs.core.Response.status(javax.ws.rs.core.Response.Status.BAD_REQUEST).entity(error).type("application/json").build()); - } - - return (ClientModel)client; + return client; } - protected String getApplicationClusterHost(MultivaluedMap formData) { - String applicationClusterHost = formData.getFirst(AdapterConstants.APPLICATION_CLUSTER_HOST); - if (applicationClusterHost == null || applicationClusterHost.length() == 0) { + protected String getClientClusterHost(MultivaluedMap formData) { + String clientClusterHost = formData.getFirst(AdapterConstants.CLIENT_CLUSTER_HOST); + if (clientClusterHost == null || clientClusterHost.length() == 0) { Map error = new HashMap(); error.put(OAuth2Constants.ERROR, "invalid_request"); - error.put(OAuth2Constants.ERROR_DESCRIPTION, "application cluster host not specified"); + error.put(OAuth2Constants.ERROR_DESCRIPTION, "Client cluster host not specified"); event.error(Errors.INVALID_CODE); - throw new BadRequestException("Cluster host not specified", javax.ws.rs.core.Response.status(javax.ws.rs.core.Response.Status.BAD_REQUEST).entity(error).type("application/json").build()); + throw new BadRequestException("Cluster host not specified", javax.ws.rs.core.Response.status(javax.ws.rs.core.Response.Status.BAD_REQUEST).entity(error).type(MediaType.APPLICATION_JSON_TYPE).build()); } - return applicationClusterHost; + return clientClusterHost; } diff --git a/services/src/main/java/org/keycloak/services/resources/IdentityBrokerService.java b/services/src/main/java/org/keycloak/services/resources/IdentityBrokerService.java index a26b2794dc..f8e5e8febc 100755 --- a/services/src/main/java/org/keycloak/services/resources/IdentityBrokerService.java +++ b/services/src/main/java/org/keycloak/services/resources/IdentityBrokerService.java @@ -73,7 +73,7 @@ import java.util.Map; import static org.keycloak.models.AccountRoles.MANAGE_ACCOUNT; import static org.keycloak.models.ClientSessionModel.Action.AUTHENTICATE; -import static org.keycloak.models.Constants.ACCOUNT_MANAGEMENT_APP; +import static org.keycloak.models.Constants.ACCOUNT_MANAGEMENT_CLIENT_ID; import static org.keycloak.models.UserModel.RequiredAction.UPDATE_PROFILE; /** @@ -327,7 +327,7 @@ public class IdentityBrokerService implements IdentityProvider.AuthenticationCal return redirectToErrorPage(Messages.ACCOUNT_DISABLED); } - if (!authenticatedUser.hasRole(this.realmModel.getClientByClientId(ACCOUNT_MANAGEMENT_APP).getRole(MANAGE_ACCOUNT))) { + if (!authenticatedUser.hasRole(this.realmModel.getClientByClientId(ACCOUNT_MANAGEMENT_CLIENT_ID).getRole(MANAGE_ACCOUNT))) { fireErrorEvent(Errors.NOT_ALLOWED); return redirectToErrorPage(Messages.INSUFFICIENT_PERMISSION); } @@ -382,7 +382,7 @@ public class IdentityBrokerService implements IdentityProvider.AuthenticationCal return clientCode; } - throw new IdentityBrokerException("Invalid code, please login again through your application."); + throw new IdentityBrokerException("Invalid code, please login again through your client."); } private AuthenticationRequest createAuthenticationRequest(String providerId, ClientSessionCode clientSessionCode) { diff --git a/services/src/main/java/org/keycloak/services/resources/PublicRealmResource.java b/services/src/main/java/org/keycloak/services/resources/PublicRealmResource.java index b4c3284225..25beaa5f14 100755 --- a/services/src/main/java/org/keycloak/services/resources/PublicRealmResource.java +++ b/services/src/main/java/org/keycloak/services/resources/PublicRealmResource.java @@ -14,6 +14,7 @@ import javax.ws.rs.OPTIONS; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import javax.ws.rs.core.UriInfo; @@ -59,7 +60,7 @@ public class PublicRealmResource { */ @GET @NoCache - @Produces("application/json") + @Produces(MediaType.APPLICATION_JSON) public PublishedRealmRepresentation getRealm() { Cors.add(request).allowedOrigins(Cors.ACCESS_CONTROL_ALLOW_ORIGIN_WILDCARD).auth().build(response); return realmRep(realm, uriInfo); diff --git a/services/src/main/java/org/keycloak/services/resources/RealmsResource.java b/services/src/main/java/org/keycloak/services/resources/RealmsResource.java index 4989fbcdc4..571f111a8f 100755 --- a/services/src/main/java/org/keycloak/services/resources/RealmsResource.java +++ b/services/src/main/java/org/keycloak/services/resources/RealmsResource.java @@ -157,16 +157,15 @@ public class RealmsResource { RealmManager realmManager = new RealmManager(session); RealmModel realm = locateRealm(name, realmManager); - ClientModel application = realm.getClientNameMap().get(Constants.ACCOUNT_MANAGEMENT_APP); - if (application == null || !application.isEnabled()) { + ClientModel client = realm.getClientNameMap().get(Constants.ACCOUNT_MANAGEMENT_CLIENT_ID); + if (client == null || !client.isEnabled()) { logger.debug("account management not enabled"); throw new NotFoundException("account management not enabled"); } EventBuilder event = new EventBuilder(realm, session, clientConnection); - AccountService accountService = new AccountService(realm, application, event); + AccountService accountService = new AccountService(realm, client, event); ResteasyProviderFactory.getInstance().injectProperties(accountService); - //resourceContext.initResource(accountService); accountService.init(); return accountService; } @@ -177,7 +176,6 @@ public class RealmsResource { RealmModel realm = locateRealm(name, realmManager); PublicRealmResource realmResource = new PublicRealmResource(realm); ResteasyProviderFactory.getInstance().injectProperties(realmResource); - //resourceContext.initResource(realmResource); return realmResource; } @@ -188,7 +186,6 @@ public class RealmsResource { IdentityBrokerService brokerService = new IdentityBrokerService(realm); ResteasyProviderFactory.getInstance().injectProperties(brokerService); - //resourceContext.initResource(brokerService); brokerService.init(); diff --git a/services/src/main/java/org/keycloak/services/resources/admin/AdminConsole.java b/services/src/main/java/org/keycloak/services/resources/admin/AdminConsole.java index bfe70da898..24d76b2873 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/AdminConsole.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/AdminConsole.java @@ -151,12 +151,12 @@ public class AdminConsole { */ @Path("config") @GET - @Produces("application/json") + @Produces(MediaType.APPLICATION_JSON) @NoCache public ClientManager.InstallationAdapterConfig config() { - ClientModel consoleApp = realm.getClientByClientId(Constants.ADMIN_CONSOLE_APPLICATION); + ClientModel consoleApp = realm.getClientByClientId(Constants.ADMIN_CONSOLE_CLIENT_ID); if (consoleApp == null) { - throw new NotFoundException("Could not find admin console application"); + throw new NotFoundException("Could not find admin console client"); } return new ClientManager().toInstallationRepresentation(realm, consoleApp, keycloak.getBaseUri(uriInfo)); @@ -170,7 +170,7 @@ public class AdminConsole { */ @Path("whoami") @GET - @Produces("application/json") + @Produces(MediaType.APPLICATION_JSON) @NoCache public Response whoAmI(final @Context HttpHeaders headers) { RealmManager realmManager = new RealmManager(session); @@ -208,7 +208,7 @@ public class AdminConsole { private void addRealmAccess(RealmModel realm, UserModel user, Map> realmAdminAccess) { RealmManager realmManager = new RealmManager(session); - ClientModel realmAdminApp = realm.getClientByClientId(realmManager.getRealmAdminApplicationName(realm)); + ClientModel realmAdminApp = realm.getClientByClientId(realmManager.getRealmAdminClientId(realm)); Set roles = realmAdminApp.getRoles(); for (RoleModel role : roles) { if (!user.hasRole(role)) continue; @@ -223,7 +223,7 @@ public class AdminConsole { private void addMasterRealmAccess(RealmModel masterRealm, UserModel user, Map> realmAdminAccess) { List realms = session.realms().getRealms(); for (RealmModel realm : realms) { - ClientModel realmAdminApp = realm.getMasterAdminApp(); + ClientModel realmAdminApp = realm.getMasterAdminClient(); Set roles = realmAdminApp.getRoles(); for (RoleModel role : roles) { if (!user.hasRole(role)) continue; 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 8c689757ad..f0decf37fe 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 @@ -16,7 +16,6 @@ import org.keycloak.models.utils.KeycloakModelUtils; import org.keycloak.models.utils.ModelToRepresentation; import org.keycloak.models.utils.RepresentationToModel; import org.keycloak.representations.adapters.action.GlobalRequestResult; -import org.keycloak.representations.idm.ApplicationRepresentation; import org.keycloak.representations.idm.ClientRepresentation; import org.keycloak.representations.idm.CredentialRepresentation; import org.keycloak.representations.idm.UserSessionRepresentation; @@ -49,7 +48,7 @@ import java.util.Map; import java.util.Set; /** - * Base resource class for managing one particular application of a realm. + * Base resource class for managing one particular client of a realm. * * @author Bill Burke * @version $Revision: 1 $ @@ -88,7 +87,7 @@ public class ClientResource { } /** - * Update the application. + * Update the client. * @param rep * @return */ @@ -107,7 +106,7 @@ public class ClientResource { /** - * Get representation of the application. + * Get representation of the client. * * @return */ @@ -132,7 +131,7 @@ public class ClientResource { /** - * Return keycloak.json file for this application to be used to configure the adapter of that application. + * Return keycloak.json file for this client to be used to configure the adapter of that client. * * @return * @throws IOException @@ -152,7 +151,7 @@ public class ClientResource { } /** - * Return XML that can be included in the JBoss/Wildfly Keycloak subsystem to configure the adapter of that application. + * Return XML that can be included in the JBoss/Wildfly Keycloak subsystem to configure the adapter of that client. * * @return * @throws IOException @@ -169,26 +168,26 @@ public class ClientResource { } /** - * Delete this application. + * Delete this client. * */ @DELETE @NoCache - public void deleteApplication() { + public void deleteClient() { auth.requireManage(); new ClientManager(new RealmManager(session)).removeClient(realm, client); } /** - * Generates a new secret for this application + * Generates a new secret for this client * * @return */ @Path("client-secret") @POST - @Produces("application/json") - @Consumes("application/json") + @Produces(MediaType.APPLICATION_JSON) + @Consumes(MediaType.APPLICATION_JSON) public CredentialRepresentation regenerateSecret() { auth.requireManage(); @@ -199,25 +198,25 @@ public class ClientResource { } /** - * Get the secret of this application + * Get the secret of this client * * @return */ @Path("client-secret") @GET @NoCache - @Produces("application/json") + @Produces(MediaType.APPLICATION_JSON) public CredentialRepresentation getClientSecret() { auth.requireView(); logger.debug("getClientSecret"); UserCredentialModel model = UserCredentialModel.secret(client.getSecret()); - if (model == null) throw new NotFoundException("Application does not have a secret"); + if (model == null) throw new NotFoundException("Client does not have a secret"); return ModelToRepresentation.toRepresentation(model); } /** - * Base path for managing the scope mappings for this application + * Base path for managing the scope mappings for this client * * @return */ @@ -233,14 +232,14 @@ public class ClientResource { /** * Returns set of allowed origin. This is used for CORS requests. Access tokens will have - * their allowedOrigins claim set to this value for tokens created for this application. + * their allowedOrigins claim set to this value for tokens created for this client. * * @return */ @Path("allowed-origins") @GET @NoCache - @Produces("application/json") + @Produces(MediaType.APPLICATION_JSON) public Set getAllowedOrigins() { auth.requireView(); @@ -250,13 +249,13 @@ public class ClientResource { /** * Change the set of allowed origins. This is used for CORS requests. Access tokens will have - * their allowedOrigins claim set to this value for tokens created for this application. + * their allowedOrigins claim set to this value for tokens created for this client. * * @param allowedOrigins */ @Path("allowed-origins") @PUT - @Consumes("application/json") + @Consumes(MediaType.APPLICATION_JSON) public void updateAllowedOrigins(Set allowedOrigins) { auth.requireManage(); @@ -266,13 +265,13 @@ public class ClientResource { /** * Remove set of allowed origins from current allowed origins list. This is used for CORS requests. Access tokens will have - * their allowedOrigins claim set to this value for tokens created for this application. + * their allowedOrigins claim set to this value for tokens created for this client. * * @param allowedOrigins */ @Path("allowed-origins") @DELETE - @Consumes("application/json") + @Consumes(MediaType.APPLICATION_JSON) public void deleteAllowedOrigins(Set allowedOrigins) { auth.requireManage(); @@ -283,18 +282,18 @@ public class ClientResource { } /** - * If the application has an admin URL, push the application's revocation policy to it. + * If the client has an admin URL, push the client's revocation policy to it. * */ @Path("push-revocation") @POST public GlobalRequestResult pushRevocation() { auth.requireManage(); - return new ResourceAdminManager().pushApplicationRevocationPolicy(uriInfo.getRequestUri(), realm, client); + return new ResourceAdminManager().pushClientRevocationPolicy(uriInfo.getRequestUri(), realm, client); } /** - * Number of user sessions associated with this application + * Number of user sessions associated with this client * * { * "count": number @@ -314,7 +313,7 @@ public class ClientResource { } /** - * Return a list of user sessions associated with this application + * Return a list of user sessions associated with this client * * @return */ @@ -335,18 +334,18 @@ public class ClientResource { } /** - * If the application has an admin URL, invalidate all sessions associated with that application directly. + * If the client has an admin URL, invalidate all sessions associated with that client directly. * */ @Path("logout-all") @POST public GlobalRequestResult logoutAll() { auth.requireManage(); - return new ResourceAdminManager().logoutApplication(uriInfo.getRequestUri(), realm, client); + return new ResourceAdminManager().logoutClient(uriInfo.getRequestUri(), realm, client); } /** - * If the application has an admin URL, invalidate the sessions for a particular user directly. + * If the client has an admin URL, invalidate the sessions for a particular user directly. * */ @Path("logout-user/{username}") @@ -357,18 +356,18 @@ public class ClientResource { if (user == null) { throw new NotFoundException("User not found"); } - new ResourceAdminManager().logoutUserFromApplication(uriInfo.getRequestUri(), realm, client, user, session); + new ResourceAdminManager().logoutUserFromClient(uriInfo.getRequestUri(), realm, client, user, session); } /** - * Manually register cluster node to this application - usually it's not needed to call this directly as adapter should handle + * Manually register cluster node to this client - usually it's not needed to call this directly as adapter should handle * by sending registration request to Keycloak * * @param formParams */ @Path("nodes") @POST - @Consumes("application/json") + @Consumes(MediaType.APPLICATION_JSON) public void registerNode(Map formParams) { auth.requireManage(); String node = formParams.get("node"); @@ -380,7 +379,7 @@ public class ClientResource { } /** - * Unregister cluster node from this application + * Unregister cluster node from this client * * @param node */ @@ -393,7 +392,7 @@ public class ClientResource { Integer time = client.getRegisteredNodes().get(node); if (time == null) { - throw new NotFoundException("Application does not have a node " + node); + throw new NotFoundException("Client does not have a node " + node); } client.unregisterNode(node); 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 7432efb629..270b7ac4e4 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 @@ -27,7 +27,7 @@ import java.util.ArrayList; import java.util.List; /** - * Base resource class for managing a realm's applications. + * Base resource class for managing a realm's clients. * * @author Bill Burke * @version $Revision: 1 $ @@ -48,7 +48,7 @@ public class ClientsResource { } /** - * List of applications belonging to this realm. + * List of clients belonging to this realm. * * @return */ @@ -100,7 +100,7 @@ public class ClientsResource { } /** - * Base path for managing a specific application. + * Base path for managing a specific client. * * @param name * @return diff --git a/services/src/main/java/org/keycloak/services/resources/admin/IdentityProviderResource.java b/services/src/main/java/org/keycloak/services/resources/admin/IdentityProviderResource.java index 97c56f119d..bbb32b441b 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/IdentityProviderResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/IdentityProviderResource.java @@ -27,6 +27,7 @@ import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import javax.ws.rs.core.UriInfo; import java.util.ArrayList; @@ -53,7 +54,7 @@ public class IdentityProviderResource { @GET @NoCache - @Produces("application/json") + @Produces(MediaType.APPLICATION_JSON) public IdentityProviderRepresentation getIdentityProvider() { IdentityProviderRepresentation rep = ModelToRepresentation.toRepresentation(this.identityProviderModel); @@ -73,7 +74,7 @@ public class IdentityProviderResource { } @PUT - @Consumes("application/json") + @Consumes(MediaType.APPLICATION_JSON) public Response update(IdentityProviderRepresentation providerRep) { try { this.auth.requireManage(); diff --git a/services/src/main/java/org/keycloak/services/resources/admin/IdentityProvidersResource.java b/services/src/main/java/org/keycloak/services/resources/admin/IdentityProvidersResource.java index e59ee6e52e..ef0e94bd25 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/IdentityProvidersResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/IdentityProvidersResource.java @@ -57,7 +57,7 @@ public class IdentityProvidersResource { @Path("/providers/{provider_id}") @GET @NoCache - @Produces("application/json") + @Produces(MediaType.APPLICATION_JSON) public Response getIdentityProviders(@PathParam("provider_id") String providerId) { this.auth.requireView(); IdentityProviderFactory providerFactory = getProviderFactorytById(providerId); @@ -108,7 +108,7 @@ public class IdentityProvidersResource { @GET @Path("instances") @NoCache - @Produces("application/json") + @Produces(MediaType.APPLICATION_JSON) public List getIdentityProviders() { this.auth.requireView(); diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ProtocolMappersResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ProtocolMappersResource.java index d4ceddab04..36428b89fb 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/ProtocolMappersResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/ProtocolMappersResource.java @@ -19,6 +19,7 @@ import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import javax.ws.rs.core.UriInfo; import java.util.LinkedList; @@ -59,7 +60,7 @@ public class ProtocolMappersResource { @GET @NoCache @Path("protocol/{protocol}") - @Produces("application/json") + @Produces(MediaType.APPLICATION_JSON) public List getMappersPerProtocol(@PathParam("protocol") String protocol) { auth.requireView(); List mappers = new LinkedList(); @@ -77,7 +78,7 @@ public class ProtocolMappersResource { @Path("models") @POST @NoCache - @Consumes("application/json") + @Consumes(MediaType.APPLICATION_JSON) public Response createMapper(ProtocolMapperRepresentation rep) { auth.requireManage(); ProtocolMapperModel model = RepresentationToModel.toModel(rep); @@ -91,7 +92,7 @@ public class ProtocolMappersResource { @Path("add-models") @POST @NoCache - @Consumes("application/json") + @Consumes(MediaType.APPLICATION_JSON) public void createMapper(List reps) { auth.requireManage(); for (ProtocolMapperRepresentation rep : reps) { @@ -103,7 +104,7 @@ public class ProtocolMappersResource { @GET @NoCache @Path("models") - @Produces("application/json") + @Produces(MediaType.APPLICATION_JSON) public List getMappers() { auth.requireView(); List mappers = new LinkedList(); @@ -116,7 +117,7 @@ public class ProtocolMappersResource { @GET @NoCache @Path("models/{id}") - @Produces("application/json") + @Produces(MediaType.APPLICATION_JSON) public ProtocolMapperRepresentation getMapperById(@PathParam("id") String id) { auth.requireView(); ProtocolMapperModel model = client.getProtocolMapperById(id); @@ -127,7 +128,7 @@ public class ProtocolMappersResource { @PUT @NoCache @Path("models/{id}") - @Consumes("application/json") + @Consumes(MediaType.APPLICATION_JSON) public void update(@PathParam("id") String id, ProtocolMapperRepresentation rep) { auth.requireManage(); ProtocolMapperModel model = client.getProtocolMapperById(id); diff --git a/services/src/main/java/org/keycloak/services/resources/admin/RealmAdminResource.java b/services/src/main/java/org/keycloak/services/resources/admin/RealmAdminResource.java index 313d81011c..5fea57dfbf 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/RealmAdminResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/RealmAdminResource.java @@ -9,7 +9,7 @@ import org.keycloak.events.Event; import org.keycloak.events.EventQuery; import org.keycloak.events.EventStoreProvider; import org.keycloak.events.EventType; -import org.keycloak.exportimport.ApplicationImporter; +import org.keycloak.exportimport.ClientImporter; import org.keycloak.models.ClientModel; import org.keycloak.models.KeycloakSession; import org.keycloak.models.ModelDuplicateException; @@ -85,40 +85,38 @@ public class RealmAdminResource { } /** - * Base path for importing applications under this realm. + * Base path for importing clients under this realm. * * @return */ - @Path("application-importers/{formatId}") - public Object getApplicationImporter(@PathParam("formatId") String formatId) { - ApplicationImporter importer = session.getProvider(ApplicationImporter.class, formatId); + @Path("client-importers/{formatId}") + public Object getClientImporter(@PathParam("formatId") String formatId) { + ClientImporter importer = session.getProvider(ClientImporter.class, formatId); return importer.createJaxrsService(realm, auth); } /** - * Base path for managing applications under this realm. + * Base path for managing clients under this realm. * * @return */ - @Path("applications") - public ClientsResource getApplications() { + @Path("clients") + public ClientsResource getClients() { ClientsResource clientsResource = new ClientsResource(realm, auth); ResteasyProviderFactory.getInstance().injectProperties(clientsResource); - //resourceContext.initResource(applicationsResource); return clientsResource; } /** - * Base path for managing applications under this realm. + * Base path for managing clients under this realm. * * @return */ - @Path("applications-by-id") - public ClientsByIdResource getApplicationsById() { - ClientsByIdResource applicationsResource = new ClientsByIdResource(realm, auth); - ResteasyProviderFactory.getInstance().injectProperties(applicationsResource); - //resourceContext.initResource(applicationsResource); - return applicationsResource; + @Path("clients-by-id") + public ClientsByIdResource getClientsById() { + ClientsByIdResource clientsResource = new ClientsByIdResource(realm, auth); + ResteasyProviderFactory.getInstance().injectProperties(clientsResource); + return clientsResource; } /** @@ -132,14 +130,13 @@ public class RealmAdminResource { } /** - * Get the top-level representation of the realm. It will not include nested information like User, Application, or OAuth - * Client representations. + * Get the top-level representation of the realm. It will not include nested information like User and Client representations. * * @return */ @GET @NoCache - @Produces("application/json") + @Produces(MediaType.APPLICATION_JSON) public RealmRepresentation getRealm() { if (auth.hasView()) { RealmRepresentation rep = ModelToRepresentation.toRepresentation(realm, false); @@ -162,14 +159,14 @@ public class RealmAdminResource { } /** - * Update the top-level information of this realm. Any user, roles, application, or oauth client information in the representation + * Update the top-level information of this realm. Any user, roles or client information in the representation * will be ignored. This will only update top-level attributes of the realm. * * @param rep * @return */ @PUT - @Consumes("application/json") + @Consumes(MediaType.APPLICATION_JSON) public Response updateRealm(final RealmRepresentation rep) { auth.requireManage(); @@ -237,7 +234,7 @@ public class RealmAdminResource { } /** - * Path for managing all realm-level or application-level roles defined in this realm by it's id. + * Path for managing all realm-level or client-level roles defined in this realm by it's id. * * @return */ @@ -250,7 +247,7 @@ public class RealmAdminResource { } /** - * Push the realm's revocation policy to any application that has an admin url associated with it. + * Push the realm's revocation policy to any client that has an admin url associated with it. * */ @Path("push-revocation") @@ -261,7 +258,7 @@ public class RealmAdminResource { } /** - * Removes all user sessions. Any application that has an admin url will also be told to invalidate any sessions + * Removes all user sessions. Any client that has an admin url will also be told to invalidate any sessions * they have. * */ @@ -273,7 +270,7 @@ public class RealmAdminResource { } /** - * Remove a specific user session. Any application that has an admin url will also be told to invalidate this + * Remove a specific user session. Any client that has an admin url will also be told to invalidate this * particular session. * * @param sessionId @@ -287,46 +284,46 @@ public class RealmAdminResource { } /** - * Returns a JSON map. The key is the application name, the value is the number of sessions that currently are active - * with that application. Only application's that actually have a session associated with them will be in this map. + * Returns a JSON map. The key is the client name, the value is the number of sessions that currently are active + * with that client. Only client's that actually have a session associated with them will be in this map. * * @return */ - @Path("application-session-stats") + @Path("client-session-stats") @GET @NoCache @Produces(MediaType.APPLICATION_JSON) @Deprecated - public Map getApplicationSessionStats() { + public Map getClientSessionStats() { auth.requireView(); Map stats = new HashMap(); - for (ClientModel application : realm.getClients()) { - int size = session.sessions().getActiveUserSessions(application.getRealm(), application); + for (ClientModel client : realm.getClients()) { + int size = session.sessions().getActiveUserSessions(client.getRealm(), client); if (size == 0) continue; - stats.put(application.getClientId(), size); + stats.put(client.getClientId(), size); } return stats; } /** - * Returns a JSON map. The key is the application id, the value is the number of sessions that currently are active - * with that application. Only application's that actually have a session associated with them will be in this map. + * Returns a JSON map. The key is the client id, the value is the number of sessions that currently are active + * with that client. Only client's that actually have a session associated with them will be in this map. * * @return */ - @Path("application-by-id-session-stats") + @Path("client-by-id-session-stats") @GET @NoCache @Produces(MediaType.APPLICATION_JSON) - public List> getApplicationByIdSessionStats() { + public List> getClientByIdSessionStats() { auth.requireView(); List> data = new LinkedList>(); - for (ClientModel application : realm.getClients()) { - int size = session.sessions().getActiveUserSessions(application.getRealm(), application); + for (ClientModel client : realm.getClients()) { + int size = session.sessions().getActiveUserSessions(client.getRealm(), client); if (size == 0) continue; Map map = new HashMap(); - map.put("id", application.getId()); - map.put("name", application.getClientId()); + map.put("id", client.getId()); + map.put("clientId", client.getClientId()); map.put("active", size + ""); data.add(map); } @@ -341,7 +338,7 @@ public class RealmAdminResource { @GET @NoCache @Path("events/config") - @Produces("application/json") + @Produces(MediaType.APPLICATION_JSON) public RealmEventsConfigRepresentation getRealmEventsConfig() { auth.init(RealmAuth.Resource.EVENTS).requireView(); @@ -355,7 +352,7 @@ public class RealmAdminResource { */ @PUT @Path("events/config") - @Consumes("application/json") + @Consumes(MediaType.APPLICATION_JSON) public void updateRealmEventsConfig(final RealmEventsConfigRepresentation rep) { auth.init(RealmAuth.Resource.EVENTS).requireManage(); diff --git a/services/src/main/java/org/keycloak/services/resources/admin/RealmsAdminResource.java b/services/src/main/java/org/keycloak/services/resources/admin/RealmsAdminResource.java index 963bd6a686..21fc79e952 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/RealmsAdminResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/RealmsAdminResource.java @@ -74,27 +74,27 @@ public class RealmsAdminResource { */ @GET @NoCache - @Produces("application/json") + @Produces(MediaType.APPLICATION_JSON) public List getRealms() { RealmManager realmManager = new RealmManager(session); List reps = new ArrayList(); if (auth.getRealm().equals(realmManager.getKeycloakAdminstrationRealm())) { List realms = session.realms().getRealms(); for (RealmModel realm : realms) { - addRealmRep(reps, realm, realm.getMasterAdminApp()); + addRealmRep(reps, realm, realm.getMasterAdminClient()); } } else { - ClientModel adminApp = auth.getRealm().getClientByClientId(realmManager.getRealmAdminApplicationName(auth.getRealm())); + ClientModel adminApp = auth.getRealm().getClientByClientId(realmManager.getRealmAdminClientId(auth.getRealm())); addRealmRep(reps, auth.getRealm(), adminApp); } logger.debug(("getRealms()")); return reps; } - protected void addRealmRep(List reps, RealmModel realm, ClientModel realmManagementApplication) { - if (auth.hasAppRole(realmManagementApplication, AdminRoles.MANAGE_REALM)) { + protected void addRealmRep(List reps, RealmModel realm, ClientModel realmManagementClient) { + if (auth.hasAppRole(realmManagementClient, AdminRoles.MANAGE_REALM)) { reps.add(ModelToRepresentation.toRepresentation(realm, false)); - } else if (auth.hasOneOfAppRole(realmManagementApplication, AdminRoles.ALL_REALM_ROLES)) { + } else if (auth.hasOneOfAppRole(realmManagementClient, AdminRoles.ALL_REALM_ROLES)) { RealmRepresentation rep = new RealmRepresentation(); rep.setRealm(realm.getName()); reps.add(rep); @@ -109,7 +109,7 @@ public class RealmsAdminResource { * @return */ @POST - @Consumes("application/json") + @Consumes(MediaType.APPLICATION_JSON) public Response importRealm(@Context final UriInfo uriInfo, final RealmRepresentation rep) { RealmManager realmManager = new RealmManager(session); realmManager.setContextPath(keycloak.getContextPath()); @@ -186,7 +186,7 @@ public class RealmsAdminResource { } RealmModel adminRealm = new RealmManager(session).getKeycloakAdminstrationRealm(); - ClientModel realmAdminApp = realm.getMasterAdminApp(); + ClientModel realmAdminApp = realm.getMasterAdminClient(); for (String r : AdminRoles.ALL_REALM_ROLES) { RoleModel role = realmAdminApp.getRole(r); auth.getUser().grantRole(role); @@ -214,9 +214,9 @@ public class RealmsAdminResource { RealmAuth realmAuth; if (auth.getRealm().equals(realmManager.getKeycloakAdminstrationRealm())) { - realmAuth = new RealmAuth(auth, realm.getMasterAdminApp()); + realmAuth = new RealmAuth(auth, realm.getMasterAdminClient()); } else { - realmAuth = new RealmAuth(auth, realm.getClientByClientId(realmManager.getRealmAdminApplicationName(auth.getRealm()))); + realmAuth = new RealmAuth(auth, realm.getClientByClientId(realmManager.getRealmAdminClientId(auth.getRealm()))); } RealmAdminResource adminResource = new RealmAdminResource(realmAuth, realm, tokenManager); diff --git a/services/src/main/java/org/keycloak/services/resources/admin/RoleByIdResource.java b/services/src/main/java/org/keycloak/services/resources/admin/RoleByIdResource.java index 710f065d37..67d8c12e26 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/RoleByIdResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/RoleByIdResource.java @@ -19,6 +19,7 @@ import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; import java.util.List; import java.util.Set; @@ -52,7 +53,7 @@ public class RoleByIdResource extends RoleResource { @Path("{role-id}") @GET @NoCache - @Produces("application/json") + @Produces(MediaType.APPLICATION_JSON) public RoleRepresentation getRole(final @PathParam("role-id") String id) { RoleModel roleModel = getRoleModel(id); auth.requireView(); @@ -101,7 +102,7 @@ public class RoleByIdResource extends RoleResource { */ @Path("{role-id}") @PUT - @Consumes("application/json") + @Consumes(MediaType.APPLICATION_JSON) public void updateRole(final @PathParam("role-id") String id, final RoleRepresentation rep) { RoleModel role = getRoleModel(id); auth.requireManage(); @@ -116,7 +117,7 @@ public class RoleByIdResource extends RoleResource { */ @Path("{role-id}/composites") @POST - @Consumes("application/json") + @Consumes(MediaType.APPLICATION_JSON) public void addComposites(final @PathParam("role-id") String id, List roles) { RoleModel role = getRoleModel(id); auth.requireManage(); @@ -132,7 +133,7 @@ public class RoleByIdResource extends RoleResource { @Path("{role-id}/composites") @GET @NoCache - @Produces("application/json") + @Produces(MediaType.APPLICATION_JSON) public Set getRoleComposites(final @PathParam("role-id") String id) { if (logger.isDebugEnabled()) logger.debug("*** getRoleComposites: '" + id + "'"); @@ -150,7 +151,7 @@ public class RoleByIdResource extends RoleResource { @Path("{role-id}/composites/realm") @GET @NoCache - @Produces("application/json") + @Produces(MediaType.APPLICATION_JSON) public Set getRealmRoleComposites(final @PathParam("role-id") String id) { RoleModel role = getRoleModel(id); auth.requireView(); @@ -158,49 +159,49 @@ public class RoleByIdResource extends RoleResource { } /** - * Return a set of application-level roles for a specific app that are in the role's composite + * Return a set of client-level roles for a specific client that are in the role's composite * * @param id * @param appName * @return */ - @Path("{role-id}/composites/applications/{app}") + @Path("{role-id}/composites/clients/{app}") @GET @NoCache - @Produces("application/json") - public Set getApplicationRoleComposites(final @PathParam("role-id") String id, + @Produces(MediaType.APPLICATION_JSON) + public Set getClientRoleComposites(final @PathParam("role-id") String id, final @PathParam("app") String appName) { RoleModel role = getRoleModel(id); auth.requireView(); ClientModel app = realm.getClientByClientId(appName); if (app == null) { - throw new NotFoundException("Could not find application: " + appName); + throw new NotFoundException("Could not find client: " + appName); } - return getApplicationRoleComposites(app, role); + return getClientRoleComposites(app, role); } /** - * Return a set of application-level roles for a specific app that are in the role's composite + * Return a set of client-level roles for a specific client that are in the role's composite * * @param id * @param appId * @return */ - @Path("{role-id}/composites/applications-by-id/{appId}") + @Path("{role-id}/composites/clients-by-id/{appId}") @GET @NoCache - @Produces("application/json") - public Set getApplicationByIdRoleComposites(final @PathParam("role-id") String id, + @Produces(MediaType.APPLICATION_JSON) + public Set getClientByIdRoleComposites(final @PathParam("role-id") String id, final @PathParam("appId") String appId) { RoleModel role = getRoleModel(id); auth.requireView(); ClientModel app = realm.getClientById(appId); if (app == null) { - throw new NotFoundException("Could not find application: " + appId); + throw new NotFoundException("Could not find client: " + appId); } - return getApplicationRoleComposites(app, role); + return getClientRoleComposites(app, role); } /** @@ -211,7 +212,7 @@ public class RoleByIdResource extends RoleResource { */ @Path("{role-id}/composites") @DELETE - @Consumes("application/json") + @Consumes(MediaType.APPLICATION_JSON) public void deleteComposites(final @PathParam("role-id") String id, List roles) { RoleModel role = getRoleModel(id); auth.requireManage(); diff --git a/services/src/main/java/org/keycloak/services/resources/admin/RoleContainerResource.java b/services/src/main/java/org/keycloak/services/resources/admin/RoleContainerResource.java index e1d5c28dda..66d37a9492 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/RoleContainerResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/RoleContainerResource.java @@ -20,6 +20,7 @@ import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import javax.ws.rs.core.UriInfo; import java.util.ArrayList; @@ -43,13 +44,13 @@ public class RoleContainerResource extends RoleResource { } /** - * List all roles for this realm or application + * List all roles for this realm or client * * @return */ @GET @NoCache - @Produces("application/json") + @Produces(MediaType.APPLICATION_JSON) public List getRoles() { auth.requireAny(); @@ -62,14 +63,14 @@ public class RoleContainerResource extends RoleResource { } /** - * Create a new role for this realm or application + * Create a new role for this realm or client * * @param uriInfo * @param rep * @return */ @POST - @Consumes("application/json") + @Consumes(MediaType.APPLICATION_JSON) public Response createRole(final @Context UriInfo uriInfo, final RoleRepresentation rep) { auth.requireManage(); @@ -91,7 +92,7 @@ public class RoleContainerResource extends RoleResource { @Path("{role-name}") @GET @NoCache - @Produces("application/json") + @Produces(MediaType.APPLICATION_JSON) public RoleRepresentation getRole(final @PathParam("role-name") String roleName) { auth.requireView(); @@ -131,7 +132,7 @@ public class RoleContainerResource extends RoleResource { */ @Path("{role-name}") @PUT - @Consumes("application/json") + @Consumes(MediaType.APPLICATION_JSON) public Response updateRole(final @PathParam("role-name") String roleName, final RoleRepresentation rep) { auth.requireManage(); @@ -155,7 +156,7 @@ public class RoleContainerResource extends RoleResource { */ @Path("{role-name}/composites") @POST - @Consumes("application/json") + @Consumes(MediaType.APPLICATION_JSON) public void addComposites(final @PathParam("role-name") String roleName, List roles) { auth.requireManage(); @@ -175,7 +176,7 @@ public class RoleContainerResource extends RoleResource { @Path("{role-name}/composites") @GET @NoCache - @Produces("application/json") + @Produces(MediaType.APPLICATION_JSON) public Set getRoleComposites(final @PathParam("role-name") String roleName) { auth.requireManage(); @@ -195,7 +196,7 @@ public class RoleContainerResource extends RoleResource { @Path("{role-name}/composites/realm") @GET @NoCache - @Produces("application/json") + @Produces(MediaType.APPLICATION_JSON) public Set getRealmRoleComposites(final @PathParam("role-name") String roleName) { auth.requireManage(); @@ -207,30 +208,30 @@ public class RoleContainerResource extends RoleResource { } /** - * An app-level roles for a specific app for this role's composite + * An client-level roles for a specific client for this role's composite * * @param roleName role's name (not id!) - * @param appName + * @param clientId * @return */ - @Path("{role-name}/composites/application/{app}") + @Path("{role-name}/composites/client/{clientId}") @GET @NoCache - @Produces("application/json") - public Set getApplicationRoleComposites(final @PathParam("role-name") String roleName, - final @PathParam("app") String appName) { + @Produces(MediaType.APPLICATION_JSON) + public Set getClientRoleComposites(final @PathParam("role-name") String roleName, + final @PathParam("clientId") String clientId) { auth.requireManage(); RoleModel role = roleContainer.getRole(roleName); if (role == null) { throw new NotFoundException("Could not find role: " + roleName); } - ClientModel app = realm.getClientByClientId(appName); + ClientModel app = realm.getClientByClientId(clientId); if (app == null) { - throw new NotFoundException("Could not find application: " + appName); + throw new NotFoundException("Could not find client: " + clientId); } - return getApplicationRoleComposites(app, role); + return getClientRoleComposites(app, role); } @@ -238,27 +239,27 @@ public class RoleContainerResource extends RoleResource { * An app-level roles for a specific app for this role's composite * * @param roleName role's name (not id!) - * @param appId + * @param id * @return */ - @Path("{role-name}/composites/application-by-id/{appId}") + @Path("{role-name}/composites/client-by-id/{id}") @GET @NoCache - @Produces("application/json") - public Set getApplicationByIdRoleComposites(final @PathParam("role-name") String roleName, - final @PathParam("appId") String appId) { + @Produces(MediaType.APPLICATION_JSON) + public Set getClientByIdRoleComposites(final @PathParam("role-name") String roleName, + final @PathParam("id") String id) { auth.requireManage(); RoleModel role = roleContainer.getRole(roleName); if (role == null) { throw new NotFoundException("Could not find role: " + roleName); } - ClientModel app = realm.getClientById(appId); - if (app == null) { - throw new NotFoundException("Could not find application: " + appId); + ClientModel client = realm.getClientById(id); + if (client == null) { + throw new NotFoundException("Could not find client: " + id); } - return getApplicationRoleComposites(app, role); + return getClientRoleComposites(client, role); } @@ -270,7 +271,7 @@ public class RoleContainerResource extends RoleResource { */ @Path("{role-name}/composites") @DELETE - @Consumes("application/json") + @Consumes(MediaType.APPLICATION_JSON) public void deleteComposites(final @PathParam("role-name") String roleName, List roles) { auth.requireManage(); diff --git a/services/src/main/java/org/keycloak/services/resources/admin/RoleResource.java b/services/src/main/java/org/keycloak/services/resources/admin/RoleResource.java index 80b6b42ff2..8196528ccb 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/RoleResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/RoleResource.java @@ -69,7 +69,7 @@ public abstract class RoleResource { return composites; } - protected Set getApplicationRoleComposites(ClientModel app, RoleModel role) { + protected Set getClientRoleComposites(ClientModel app, RoleModel role) { if (!role.isComposite() || role.getComposites().size() == 0) return Collections.emptySet(); Set composites = new HashSet(role.getComposites().size()); diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ScopeMappedApplicationResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ScopeMappedClientResource.java similarity index 59% rename from services/src/main/java/org/keycloak/services/resources/admin/ScopeMappedApplicationResource.java rename to services/src/main/java/org/keycloak/services/resources/admin/ScopeMappedClientResource.java index 9035ef068b..01fe1d67ec 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/ScopeMappedApplicationResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/ScopeMappedClientResource.java @@ -15,6 +15,7 @@ import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; import java.util.ArrayList; import java.util.List; import java.util.Set; @@ -23,33 +24,33 @@ import java.util.Set; * @author Bill Burke * @version $Revision: 1 $ */ -public class ScopeMappedApplicationResource { +public class ScopeMappedClientResource { protected RealmModel realm; private RealmAuth auth; protected ClientModel client; protected KeycloakSession session; - protected ClientModel app; + protected ClientModel scopedClient; - public ScopeMappedApplicationResource(RealmModel realm, RealmAuth auth, ClientModel client, KeycloakSession session, ClientModel app) { + public ScopeMappedClientResource(RealmModel realm, RealmAuth auth, ClientModel client, KeycloakSession session, ClientModel scopedClient) { this.realm = realm; this.auth = auth; this.client = client; this.session = session; - this.app = app; + this.scopedClient = scopedClient; } /** - * Get the roles associated with a client's scope for a specific application. + * Get the roles associated with a client's scope for a specific client. * * @return */ @GET - @Produces("application/json") + @Produces(MediaType.APPLICATION_JSON) @NoCache - public List getApplicationScopeMappings() { + public List getClientScopeMappings() { auth.requireView(); - Set mappings = app.getApplicationScopeMappings(client); + Set mappings = scopedClient.getClientScopeMappings(client); List mapRep = new ArrayList(); for (RoleModel roleModel : mappings) { mapRep.add(ModelToRepresentation.toRepresentation(roleModel)); @@ -58,49 +59,49 @@ public class ScopeMappedApplicationResource { } /** - * The available application-level roles that can be associated with the client's scope + * The available client-level roles that can be associated with the client's scope * * @return */ @Path("available") @GET - @Produces("application/json") + @Produces(MediaType.APPLICATION_JSON) @NoCache - public List getAvailableApplicationScopeMappings() { + public List getAvailableClientScopeMappings() { auth.requireView(); - Set roles = app.getRoles(); + Set roles = scopedClient.getRoles(); return ScopeMappedResource.getAvailable(client, roles); } /** - * Get effective application roles that are associated with the client's scope for a specific application. + * Get effective client roles that are associated with the client's scope for a specific client. * * @return */ @Path("composite") @GET - @Produces("application/json") + @Produces(MediaType.APPLICATION_JSON) @NoCache - public List getCompositeApplicationScopeMappings() { + public List getCompositeClientScopeMappings() { auth.requireView(); - Set roles = app.getRoles(); + Set roles = scopedClient.getRoles(); return ScopeMappedResource.getComposite(client, roles); } /** - * Add application-level roles to the client's scope + * Add client-level roles to the client's scope * * @param roles */ @POST - @Consumes("application/json") - public void addApplicationScopeMapping(List roles) { + @Consumes(MediaType.APPLICATION_JSON) + public void addClientScopeMapping(List roles) { auth.requireManage(); for (RoleRepresentation role : roles) { - RoleModel roleModel = app.getRole(role.getName()); + RoleModel roleModel = scopedClient.getRole(role.getName()); if (roleModel == null) { throw new NotFoundException("Role not found"); } @@ -110,24 +111,24 @@ public class ScopeMappedApplicationResource { } /** - * Remove application-level roles from the client's scope. + * Remove client-level roles from the client's scope. * * @param roles */ @DELETE - @Consumes("application/json") - public void deleteApplicationScopeMapping(List roles) { + @Consumes(MediaType.APPLICATION_JSON) + public void deleteClientScopeMapping(List roles) { auth.requireManage(); if (roles == null) { - Set roleModels = app.getApplicationScopeMappings(client); + Set roleModels = scopedClient.getClientScopeMappings(client); for (RoleModel roleModel : roleModels) { client.deleteScopeMapping(roleModel); } } else { for (RoleRepresentation role : roles) { - RoleModel roleModel = app.getRole(role.getName()); + RoleModel roleModel = scopedClient.getRole(role.getName()); if (roleModel == null) { throw new NotFoundException("Role not found"); } diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ScopeMappedResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ScopeMappedResource.java index 28b63ced08..8d4e005710 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/ScopeMappedResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/ScopeMappedResource.java @@ -18,6 +18,7 @@ import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -25,7 +26,7 @@ import java.util.Map; import java.util.Set; /** - * Base class for managing the scope mappings of a specific client (application or oauth). + * Base class for managing the scope mappings of a specific client. * * @author Bill Burke * @version $Revision: 1 $ @@ -49,7 +50,7 @@ public class ScopeMappedResource { * @return */ @GET - @Produces("application/json") + @Produces(MediaType.APPLICATION_JSON) @NoCache public MappingsRepresentation getScopeMappings() { auth.requireView(); @@ -68,7 +69,7 @@ public class ScopeMappedResource { if (clients.size() > 0) { Map clientMappings = new HashMap(); for (ClientModel client : clients) { - Set roleMappings = client.getApplicationScopeMappings(this.client); + Set roleMappings = client.getClientScopeMappings(this.client); if (roleMappings.size() > 0) { ClientMappingsRepresentation mappings = new ClientMappingsRepresentation(); mappings.setId(client.getId()); @@ -93,7 +94,7 @@ public class ScopeMappedResource { */ @Path("realm") @GET - @Produces("application/json") + @Produces(MediaType.APPLICATION_JSON) @NoCache public List getRealmScopeMappings() { auth.requireView(); @@ -113,7 +114,7 @@ public class ScopeMappedResource { */ @Path("realm/available") @GET - @Produces("application/json") + @Produces(MediaType.APPLICATION_JSON) @NoCache public List getAvailableRealmScopeMappings() { auth.requireView(); @@ -140,7 +141,7 @@ public class ScopeMappedResource { */ @Path("realm/composite") @GET - @Produces("application/json") + @Produces(MediaType.APPLICATION_JSON) @NoCache public List getCompositeRealmScopeMappings() { auth.requireView(); @@ -164,7 +165,7 @@ public class ScopeMappedResource { */ @Path("realm") @POST - @Consumes("application/json") + @Consumes(MediaType.APPLICATION_JSON) public void addRealmScopeMappings(List roles) { auth.requireManage(); @@ -186,7 +187,7 @@ public class ScopeMappedResource { */ @Path("realm") @DELETE - @Consumes("application/json") + @Consumes(MediaType.APPLICATION_JSON) public void deleteRealmScopeMappings(List roles) { auth.requireManage(); @@ -200,32 +201,32 @@ public class ScopeMappedResource { for (RoleRepresentation role : roles) { RoleModel roleModel = realm.getRoleById(role.getId()); if (roleModel == null) { - throw new NotFoundException("Application not found"); + throw new NotFoundException("Client not found"); } client.deleteScopeMapping(roleModel); } } } - @Path("applications/{app}") - public ScopeMappedApplicationResource getApplicationScopeMappings(@PathParam("app") String appName) { - ClientModel app = realm.getClientByClientId(appName); + @Path("clients/{clientId}") + public ScopeMappedClientResource getClientScopeMappings(@PathParam("clientId") String clientId) { + ClientModel app = realm.getClientByClientId(clientId); if (app == null) { throw new NotFoundException("Role not found"); } - return new ScopeMappedApplicationResource(realm, auth, client, session, app); + return new ScopeMappedClientResource(realm, auth, client, session, app); } - @Path("applications-by-id/{appId}") - public ScopeMappedApplicationResource getApplicationByIdScopeMappings(@PathParam("appId") String appId) { - ClientModel app = realm.getClientById(appId); + @Path("clients-by-id/{id}") + public ScopeMappedClientResource getClientByIdScopeMappings(@PathParam("id") String id) { + ClientModel app = realm.getClientById(id); if (app == null) { - throw new NotFoundException("Application not found"); + throw new NotFoundException("Client not found"); } - return new ScopeMappedApplicationResource(realm, auth, client, session, app); + return new ScopeMappedClientResource(realm, auth, client, session, app); } } diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ServerInfoAdminResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ServerInfoAdminResource.java index ec72cc146f..322f60df94 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/ServerInfoAdminResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/ServerInfoAdminResource.java @@ -5,8 +5,8 @@ import org.keycloak.broker.provider.IdentityProvider; import org.keycloak.broker.provider.IdentityProviderFactory; import org.keycloak.events.EventListenerProvider; import org.keycloak.events.EventType; -import org.keycloak.exportimport.ApplicationImporter; -import org.keycloak.exportimport.ApplicationImporterFactory; +import org.keycloak.exportimport.ClientImporter; +import org.keycloak.exportimport.ClientImporterFactory; import org.keycloak.freemarker.Theme; import org.keycloak.freemarker.ThemeProvider; import org.keycloak.models.KeycloakSession; @@ -55,7 +55,7 @@ public class ServerInfoAdminResource { setThemes(info); setEventListeners(info); setProtocols(info); - setApplicationImporters(info); + setClientImporters(info); setProviders(info); setProtocolMapperTypes(info); setBuiltinProtocolMappers(info); @@ -167,14 +167,14 @@ public class ServerInfoAdminResource { } } - private void setApplicationImporters(ServerInfoRepresentation info) { - info.applicationImporters = new LinkedList>(); - for (ProviderFactory p : session.getKeycloakSessionFactory().getProviderFactories(ApplicationImporter.class)) { - ApplicationImporterFactory factory = (ApplicationImporterFactory)p; + private void setClientImporters(ServerInfoRepresentation info) { + info.clientImporters = new LinkedList>(); + for (ProviderFactory p : session.getKeycloakSessionFactory().getProviderFactories(ClientImporter.class)) { + ClientImporterFactory factory = (ClientImporterFactory)p; Map data = new HashMap(); data.put("id", factory.getId()); data.put("name", factory.getDisplayName()); - info.applicationImporters.add(data); + info.clientImporters.add(data); } } @@ -198,7 +198,7 @@ public class ServerInfoAdminResource { private List> socialProviders; public List> identityProviders; private List protocols; - private List> applicationImporters; + private List> clientImporters; private Map> providers; @@ -239,8 +239,8 @@ public class ServerInfoAdminResource { return protocols; } - public List> getApplicationImporters() { - return applicationImporters; + public List> getClientImporters() { + return clientImporters; } public Map> getProviders() { diff --git a/services/src/main/java/org/keycloak/services/resources/admin/UserApplicationRoleMappingsResource.java b/services/src/main/java/org/keycloak/services/resources/admin/UserClientRoleMappingsResource.java similarity index 60% rename from services/src/main/java/org/keycloak/services/resources/admin/UserApplicationRoleMappingsResource.java rename to services/src/main/java/org/keycloak/services/resources/admin/UserClientRoleMappingsResource.java index 2149ef95a5..e838333c61 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/UserApplicationRoleMappingsResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/UserClientRoleMappingsResource.java @@ -16,6 +16,7 @@ import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; import java.util.ArrayList; import java.util.HashSet; import java.util.List; @@ -25,79 +26,73 @@ import java.util.Set; * @author Bill Burke * @version $Revision: 1 $ */ -public class UserApplicationRoleMappingsResource { - protected static final Logger logger = Logger.getLogger(UserApplicationRoleMappingsResource.class); +public class UserClientRoleMappingsResource { + protected static final Logger logger = Logger.getLogger(UserClientRoleMappingsResource.class); protected RealmModel realm; protected RealmAuth auth; protected UserModel user; - protected ClientModel application; + protected ClientModel client; - public UserApplicationRoleMappingsResource(RealmModel realm, RealmAuth auth, UserModel user, ClientModel application) { + public UserClientRoleMappingsResource(RealmModel realm, RealmAuth auth, UserModel user, ClientModel client) { this.realm = realm; this.auth = auth; this.user = user; - this.application = application; + this.client = client; } /** - * Get application-level role mappings for this user for a specific app + * Get client-level role mappings for this user for a specific app * * @return */ @GET - @Produces("application/json") + @Produces(MediaType.APPLICATION_JSON) @NoCache - public List getApplicationRoleMappings() { + public List getClientRoleMappings() { auth.requireView(); - logger.debug("getApplicationRoleMappings"); - - Set mappings = user.getApplicationRoleMappings(application); + Set mappings = user.getClientRoleMappings(client); List mapRep = new ArrayList(); for (RoleModel roleModel : mappings) { mapRep.add(ModelToRepresentation.toRepresentation(roleModel)); } - logger.debugv("getApplicationRoleMappings.size() = {0}", mapRep.size()); return mapRep; } /** - * Get effective application-level role mappings. This recurses any composite roles + * Get effective client-level role mappings. This recurses any composite roles * * @return */ @Path("composite") @GET - @Produces("application/json") + @Produces(MediaType.APPLICATION_JSON) @NoCache - public List getCompositeApplicationRoleMappings() { + public List getCompositeClientRoleMappings() { auth.requireView(); - logger.debug("getCompositeApplicationRoleMappings"); - - Set roles = application.getRoles(); + Set roles = client.getRoles(); List mapRep = new ArrayList(); for (RoleModel roleModel : roles) { if (user.hasRole(roleModel)) mapRep.add(ModelToRepresentation.toRepresentation(roleModel)); } - logger.debugv("getCompositeApplicationRoleMappings.size() = {0}", mapRep.size()); return mapRep; } /** - * Get available application-level roles that can be mapped to the user + * Get available client-level roles that can be mapped to the user * * @return */ @Path("available") @GET - @Produces("application/json") + @Produces(MediaType.APPLICATION_JSON) @NoCache - public List getAvailableApplicationRoleMappings() { + public List getAvailableClientRoleMappings() { auth.requireView(); - Set available = application.getRoles(); + Set available = client.getRoles(); return getAvailableRoles(user, available); } @@ -116,18 +111,17 @@ public class UserApplicationRoleMappingsResource { } /** - * Add application-level roles to the user role mapping. + * Add client-level roles to the user role mapping. * * @param roles */ @POST - @Consumes("application/json") - public void addApplicationRoleMapping(List roles) { + @Consumes(MediaType.APPLICATION_JSON) + public void addClientRoleMapping(List roles) { auth.requireManage(); - logger.debug("addApplicationRoleMapping"); for (RoleRepresentation role : roles) { - RoleModel roleModel = application.getRole(role.getName()); + RoleModel roleModel = client.getRole(role.getName()); if (roleModel == null || !roleModel.getId().equals(role.getId())) { throw new NotFoundException("Role not found"); } @@ -137,28 +131,28 @@ public class UserApplicationRoleMappingsResource { } /** - * Delete application-level roles from user role mapping. + * Delete client-level roles from user role mapping. * * @param roles */ @DELETE - @Consumes("application/json") - public void deleteApplicationRoleMapping(List roles) { + @Consumes(MediaType.APPLICATION_JSON) + public void deleteClientRoleMapping(List roles) { auth.requireManage(); if (roles == null) { - Set roleModels = user.getApplicationRoleMappings(application); + Set roleModels = user.getClientRoleMappings(client); for (RoleModel roleModel : roleModels) { if (!(roleModel.getContainer() instanceof ClientModel)) { - ClientModel app = (ClientModel) roleModel.getContainer(); - if (!app.getId().equals(application.getId())) continue; + ClientModel client = (ClientModel) roleModel.getContainer(); + if (!client.getId().equals(this.client.getId())) continue; } user.deleteRoleMapping(roleModel); } } else { for (RoleRepresentation role : roles) { - RoleModel roleModel = application.getRole(role.getName()); + RoleModel roleModel = client.getRole(role.getName()); if (roleModel == null || !roleModel.getId().equals(role.getId())) { throw new NotFoundException("Role not found"); } diff --git a/services/src/main/java/org/keycloak/services/resources/admin/UserFederationResource.java b/services/src/main/java/org/keycloak/services/resources/admin/UserFederationResource.java index 006124bc15..188cb30ae3 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/UserFederationResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/UserFederationResource.java @@ -28,6 +28,7 @@ import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import javax.ws.rs.core.UriInfo; import java.util.LinkedList; @@ -67,7 +68,7 @@ public class UserFederationResource { @GET @NoCache @Path("providers") - @Produces("application/json") + @Produces(MediaType.APPLICATION_JSON) public List getProviders() { auth.requireView(); List providers = new LinkedList(); @@ -88,7 +89,7 @@ public class UserFederationResource { @GET @NoCache @Path("providers/{id}") - @Produces("application/json") + @Produces(MediaType.APPLICATION_JSON) public UserFederationProviderFactoryRepresentation getProvider(@PathParam("id") String id) { auth.requireView(); for (ProviderFactory factory : session.getKeycloakSessionFactory().getProviderFactories(UserFederationProvider.class)) { @@ -111,7 +112,7 @@ public class UserFederationResource { */ @POST @Path("instances") - @Consumes("application/json") + @Consumes(MediaType.APPLICATION_JSON) public Response createProviderInstance(UserFederationProviderRepresentation rep) { auth.requireManage(); String displayName = rep.getDisplayName(); @@ -133,7 +134,7 @@ public class UserFederationResource { */ @PUT @Path("instances/{id}") - @Consumes("application/json") + @Consumes(MediaType.APPLICATION_JSON) public void updateProviderInstance(@PathParam("id") String id, UserFederationProviderRepresentation rep) { auth.requireManage(); String displayName = rep.getDisplayName(); @@ -155,7 +156,7 @@ public class UserFederationResource { @GET @NoCache @Path("instances/{id}") - @Produces("application/json") + @Produces(MediaType.APPLICATION_JSON) public UserFederationProviderRepresentation getProviderInstance(@PathParam("id") String id) { auth.requireView(); for (UserFederationProviderModel model : realm.getUserFederationProviders()) { @@ -191,7 +192,7 @@ public class UserFederationResource { */ @GET @Path("instances") - @Produces("application/json") + @Produces(MediaType.APPLICATION_JSON) @NoCache public List getUserFederationInstances() { auth.requireManage(); diff --git a/services/src/main/java/org/keycloak/services/resources/admin/UsersResource.java b/services/src/main/java/org/keycloak/services/resources/admin/UsersResource.java index eec34c8d65..8bad8982ef 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/UsersResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/UsersResource.java @@ -106,7 +106,7 @@ public class UsersResource { */ @Path("{username}") @PUT - @Consumes("application/json") + @Consumes(MediaType.APPLICATION_JSON) public Response updateUser(final @PathParam("username") String username, final UserRepresentation rep) { auth.requireManage(); @@ -137,7 +137,7 @@ public class UsersResource { * @return */ @POST - @Consumes("application/json") + @Consumes(MediaType.APPLICATION_JSON) public Response createUser(final @Context UriInfo uriInfo, final UserRepresentation rep) { auth.requireManage(); @@ -209,7 +209,7 @@ public class UsersResource { @Path("{username}") @GET @NoCache - @Produces("application/json") + @Produces(MediaType.APPLICATION_JSON) public UserRepresentation getUser(final @PathParam("username") String username) { auth.requireView(); @@ -311,7 +311,7 @@ public class UsersResource { } /** - * Remove all user sessions associated with this user. And, for all applications that have an admin URL, tell + * Remove all user sessions associated with this user. And, for all client that have an admin URL, tell * them to invalidate the sessions for this particular user. * * @param username username (not id!) @@ -368,7 +368,7 @@ public class UsersResource { */ @GET @NoCache - @Produces("application/json") + @Produces(MediaType.APPLICATION_JSON) public List getUsers(@QueryParam("search") String search, @QueryParam("lastName") String last, @QueryParam("firstName") String first, @@ -418,7 +418,7 @@ public class UsersResource { */ @Path("{username}/role-mappings") @GET - @Produces("application/json") + @Produces(MediaType.APPLICATION_JSON) @NoCache public MappingsRepresentation getRoleMappings(@PathParam("username") String username) { auth.requireView(); @@ -439,21 +439,21 @@ public class UsersResource { all.setRealmMappings(realmRep); } - List applications = realm.getClients(); - if (applications.size() > 0) { + List clients = realm.getClients(); + if (clients.size() > 0) { Map appMappings = new HashMap(); - for (ClientModel application : applications) { - Set roleMappings = user.getApplicationRoleMappings(application); + for (ClientModel client : clients) { + Set roleMappings = user.getClientRoleMappings(client); if (roleMappings.size() > 0) { ClientMappingsRepresentation mappings = new ClientMappingsRepresentation(); - mappings.setId(application.getId()); - mappings.setClient(application.getClientId()); + mappings.setId(client.getId()); + mappings.setClient(client.getClientId()); List roles = new ArrayList(); mappings.setMappings(roles); for (RoleModel role : roleMappings) { roles.add(ModelToRepresentation.toRepresentation(role)); } - appMappings.put(application.getClientId(), mappings); + appMappings.put(client.getClientId(), mappings); all.setClientMappings(appMappings); } } @@ -469,7 +469,7 @@ public class UsersResource { */ @Path("{username}/role-mappings/realm") @GET - @Produces("application/json") + @Produces(MediaType.APPLICATION_JSON) @NoCache public List getRealmRoleMappings(@PathParam("username") String username) { auth.requireView(); @@ -495,7 +495,7 @@ public class UsersResource { */ @Path("{username}/role-mappings/realm/composite") @GET - @Produces("application/json") + @Produces(MediaType.APPLICATION_JSON) @NoCache public List getCompositeRealmRoleMappings(@PathParam("username") String username) { auth.requireView(); @@ -523,7 +523,7 @@ public class UsersResource { */ @Path("{username}/role-mappings/realm/available") @GET - @Produces("application/json") + @Produces(MediaType.APPLICATION_JSON) @NoCache public List getAvailableRealmRoleMappings(@PathParam("username") String username) { auth.requireView(); @@ -534,7 +534,7 @@ public class UsersResource { } Set available = realm.getRoles(); - return UserApplicationRoleMappingsResource.getAvailableRoles(user, available); + return UserClientRoleMappingsResource.getAvailableRoles(user, available); } /** @@ -545,7 +545,7 @@ public class UsersResource { */ @Path("{username}/role-mappings/realm") @POST - @Consumes("application/json") + @Consumes(MediaType.APPLICATION_JSON) public void addRealmRoleMappings(@PathParam("username") String username, List roles) { auth.requireManage(); @@ -574,7 +574,7 @@ public class UsersResource { */ @Path("{username}/role-mappings/realm") @DELETE - @Consumes("application/json") + @Consumes(MediaType.APPLICATION_JSON) public void deleteRealmRoleMappings(@PathParam("username") String username, List roles) { auth.requireManage(); @@ -601,36 +601,36 @@ public class UsersResource { } } - @Path("{username}/role-mappings/applications/{app}") - public UserApplicationRoleMappingsResource getUserApplicationRoleMappingsResource(@PathParam("username") String username, @PathParam("app") String appName) { + @Path("{username}/role-mappings/clients/{clientId}") + public UserClientRoleMappingsResource getUserClientRoleMappingsResource(@PathParam("username") String username, @PathParam("clientId") String clientId) { UserModel user = session.users().getUserByUsername(username, realm); if (user == null) { throw new NotFoundException("User not found"); } - ClientModel application = realm.getClientByClientId(appName); + ClientModel client = realm.getClientByClientId(clientId); - if (application == null) { - throw new NotFoundException("Application not found"); + if (client == null) { + throw new NotFoundException("Client not found"); } - return new UserApplicationRoleMappingsResource(realm, auth, user, application); + return new UserClientRoleMappingsResource(realm, auth, user, client); } - @Path("{username}/role-mappings/applications-by-id/{appId}") - public UserApplicationRoleMappingsResource getUserApplicationRoleMappingsResourceById(@PathParam("username") String username, @PathParam("appId") String appId) { + @Path("{username}/role-mappings/clients-by-id/{id}") + public UserClientRoleMappingsResource getUserClientRoleMappingsResourceById(@PathParam("username") String username, @PathParam("id") String id) { UserModel user = session.users().getUserByUsername(username, realm); if (user == null) { throw new NotFoundException("User not found"); } - ClientModel application = realm.getClientById(appId); + ClientModel client = realm.getClientById(id); - if (application == null) { - throw new NotFoundException("Application not found"); + if (client == null) { + throw new NotFoundException("Client not found"); } - return new UserApplicationRoleMappingsResource(realm, auth, user, application); + return new UserClientRoleMappingsResource(realm, auth, user, client); } /** @@ -642,7 +642,7 @@ public class UsersResource { */ @Path("{username}/reset-password") @PUT - @Consumes("application/json") + @Consumes(MediaType.APPLICATION_JSON) public void resetPassword(@PathParam("username") String username, CredentialRepresentation pass) { auth.requireManage(); @@ -670,7 +670,7 @@ public class UsersResource { */ @Path("{username}/remove-totp") @PUT - @Consumes("application/json") + @Consumes(MediaType.APPLICATION_JSON) public void removeTotp(@PathParam("username") String username) { auth.requireManage(); @@ -685,7 +685,7 @@ public class UsersResource { /** * Send an email to the user with a link they can click to reset their password. * The redirectUri and clientId parameters are optional. The default for the - * redirect is the account application. + * redirect is the account client. * * @param username username (not id!) * @param redirectUri redirect uri @@ -694,7 +694,7 @@ public class UsersResource { */ @Path("{username}/reset-password-email") @PUT - @Consumes("application/json") + @Consumes(MediaType.APPLICATION_JSON) public Response resetPasswordEmail(@PathParam("username") String username, @QueryParam(OIDCLoginProtocol.REDIRECT_URI_PARAM) String redirectUri, @QueryParam(OIDCLoginProtocol.CLIENT_ID_PARAM) String clientId) { auth.requireManage(); @@ -716,7 +716,7 @@ public class UsersResource { } if(clientId == null){ - clientId = Constants.ACCOUNT_MANAGEMENT_APP; + clientId = Constants.ACCOUNT_MANAGEMENT_CLIENT_ID; } ClientModel client = realm.getClientByClientId(clientId); diff --git a/services/src/main/resources/META-INF/services/org.keycloak.provider.Spi b/services/src/main/resources/META-INF/services/org.keycloak.provider.Spi index cb0145565e..e1c0b91282 100755 --- a/services/src/main/resources/META-INF/services/org.keycloak.provider.Spi +++ b/services/src/main/resources/META-INF/services/org.keycloak.provider.Spi @@ -1,4 +1,4 @@ org.keycloak.protocol.LoginProtocolSpi org.keycloak.protocol.ProtocolMapperSpi -org.keycloak.exportimport.ApplicationImportSpi +org.keycloak.exportimport.ClientImportSpi org.keycloak.wellknown.WellKnownSpi \ No newline at end of file diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/account/AccountTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/account/AccountTest.java index 8e22acf35c..999fdb875f 100755 --- a/testsuite/integration/src/test/java/org/keycloak/testsuite/account/AccountTest.java +++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/account/AccountTest.java @@ -25,7 +25,6 @@ import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.ClassRule; -import org.junit.Ignore; import org.junit.Rule; import org.junit.Test; import org.keycloak.events.Details; @@ -75,7 +74,7 @@ public class AccountTest { public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) { UserModel user = manager.getSession().users().getUserByUsername("test-user@localhost", appRealm); - ClientModel accountApp = appRealm.getClientNameMap().get(org.keycloak.models.Constants.ACCOUNT_MANAGEMENT_APP); + ClientModel accountApp = appRealm.getClientNameMap().get(org.keycloak.models.Constants.ACCOUNT_MANAGEMENT_CLIENT_ID); UserModel user2 = manager.getSession().users().addUser(appRealm, "test-user-no-access@localhost"); user2.setEnabled(true); diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/account/ProfileTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/account/ProfileTest.java index a189032dc0..44ebaf1712 100755 --- a/testsuite/integration/src/test/java/org/keycloak/testsuite/account/ProfileTest.java +++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/account/ProfileTest.java @@ -53,7 +53,7 @@ public class ProfileTest { user.setAttribute("key1", "value1"); user.setAttribute("key2", "value2"); - ClientModel accountApp = appRealm.getClientByClientId(org.keycloak.models.Constants.ACCOUNT_MANAGEMENT_APP); + ClientModel accountApp = appRealm.getClientByClientId(org.keycloak.models.Constants.ACCOUNT_MANAGEMENT_CLIENT_ID); UserModel user2 = manager.getSession().users().addUser(appRealm, "test-user-no-access@localhost"); user2.setEnabled(true); diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/AdapterTestStrategy.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/AdapterTestStrategy.java index dcbdcbf6c3..b73b013f10 100755 --- a/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/AdapterTestStrategy.java +++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/AdapterTestStrategy.java @@ -22,7 +22,6 @@ package org.keycloak.testsuite.adapter; import org.junit.Assert; -import org.junit.Test; import org.junit.rules.ExternalResource; import org.keycloak.Config; import org.keycloak.OAuth2Constants; @@ -137,7 +136,7 @@ public class AdapterTestStrategy extends ExternalResource { RealmManager manager = new RealmManager(session); RealmModel adminRealm = manager.getRealm(Config.getAdminRealm()); - ClientModel adminConsole = adminRealm.getClientByClientId(Constants.ADMIN_CONSOLE_APPLICATION); + ClientModel adminConsole = adminRealm.getClientByClientId(Constants.ADMIN_CONSOLE_CLIENT_ID); TokenManager tm = new TokenManager(); UserModel admin = session.users().getUserByUsername("admin", adminRealm); ClientSessionModel clientSession = session.sessions().createClientSession(adminRealm, adminConsole); @@ -574,7 +573,7 @@ public class AdapterTestStrategy extends ExternalResource { loginAndCheckSession(driver, loginPage); // logout mposolda with admin client - Keycloak keycloakAdmin = Keycloak.getInstance(AUTH_SERVER_URL, "master", "admin", "admin", Constants.ADMIN_CONSOLE_APPLICATION); + Keycloak keycloakAdmin = Keycloak.getInstance(AUTH_SERVER_URL, "master", "admin", "admin", Constants.ADMIN_CONSOLE_CLIENT_ID); keycloakAdmin.realm("demo").clients().get("session-portal").logoutUser("mposolda"); // bburke should be still logged with original httpSession in our browser window diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/RelativeUriAdapterTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/RelativeUriAdapterTest.java index b56232ecc0..8361845e77 100755 --- a/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/RelativeUriAdapterTest.java +++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/RelativeUriAdapterTest.java @@ -85,7 +85,7 @@ public class RelativeUriAdapterTest { deployApplication("customer-db", "/customer-db", CustomerDatabaseServlet.class, url.getPath(), "user"); url = getClass().getResource("/adapter-test/product-keycloak-relative.json"); deployApplication("product-portal", "/product-portal", ProductServlet.class, url.getPath(), "user"); - ClientModel adminConsole = adminRealm.getClientByClientId(Constants.ADMIN_CONSOLE_APPLICATION); + ClientModel adminConsole = adminRealm.getClientByClientId(Constants.ADMIN_CONSOLE_CLIENT_ID); TokenManager tm = new TokenManager(); UserModel admin = session.users().getUserByUsername("admin", adminRealm); ClientSessionModel clientSession = session.sessions().createClientSession(realm, adminConsole); diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/admin/AbstractClientTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/admin/AbstractClientTest.java index d221df0669..1a8c554eda 100755 --- a/testsuite/integration/src/test/java/org/keycloak/testsuite/admin/AbstractClientTest.java +++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/admin/AbstractClientTest.java @@ -8,10 +8,8 @@ import org.keycloak.admin.client.resource.RealmResource; import org.keycloak.models.Constants; import org.keycloak.models.RealmModel; import org.keycloak.models.utils.KeycloakModelUtils; -import org.keycloak.representations.idm.ApplicationRepresentation; import org.keycloak.representations.idm.ClientRepresentation; import org.keycloak.representations.idm.IdentityProviderRepresentation; -import org.keycloak.representations.idm.OAuthClientRepresentation; import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.services.managers.RealmManager; import org.keycloak.testsuite.rule.KeycloakRule; @@ -49,7 +47,7 @@ public abstract class AbstractClientTest { } }); - keycloak = Keycloak.getInstance("http://localhost:8081/auth", "master", "admin", "admin", Constants.ADMIN_CONSOLE_APPLICATION); + keycloak = Keycloak.getInstance("http://localhost:8081/auth", "master", "admin", "admin", Constants.ADMIN_CONSOLE_CLIENT_ID); realm = keycloak.realm(REALM_NAME); } diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/admin/AdminAPITest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/admin/AdminAPITest.java index a8a4292049..b3a7ca614e 100755 --- a/testsuite/integration/src/test/java/org/keycloak/testsuite/admin/AdminAPITest.java +++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/admin/AdminAPITest.java @@ -77,7 +77,7 @@ public class AdminAPITest { RealmManager manager = new RealmManager(session); RealmModel adminRealm = manager.getRealm(Config.getAdminRealm()); - ClientModel adminConsole = adminRealm.getClientByClientId(Constants.ADMIN_CONSOLE_APPLICATION); + ClientModel adminConsole = adminRealm.getClientByClientId(Constants.ADMIN_CONSOLE_CLIENT_ID); TokenManager tm = new TokenManager(); UserModel admin = session.users().getUserByUsername("admin", adminRealm); ClientSessionModel clientSession = session.sessions().createClientSession(adminRealm, adminConsole); diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/model/AdapterTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/model/AdapterTest.java index e7440ab20d..0e48914430 100755 --- a/testsuite/integration/src/test/java/org/keycloak/testsuite/model/AdapterTest.java +++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/model/AdapterTest.java @@ -469,7 +469,7 @@ public class AdapterTest extends AbstractModelTest { // Role "foo" is default realm role Assert.assertTrue(user.hasRole(realmModel.getRole("foo"))); - roles = user.getApplicationRoleMappings(application); + roles = user.getClientRoleMappings(application); Assert.assertEquals(roles.size(), 2); assertRolesContains(application.getRole("user"), roles); assertRolesContains(appBarRole, roles); diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/model/ImportTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/model/ImportTest.java index 13b019a434..54f4cbeedd 100755 --- a/testsuite/integration/src/test/java/org/keycloak/testsuite/model/ImportTest.java +++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/model/ImportTest.java @@ -86,7 +86,7 @@ public class ImportTest extends AbstractModelTest { // Test applications imported ClientModel application = realm.getClientByClientId("Application"); ClientModel otherApp = realm.getClientByClientId("OtherApp"); - ClientModel accountApp = realm.getClientByClientId(Constants.ACCOUNT_MANAGEMENT_APP); + ClientModel accountApp = realm.getClientByClientId(Constants.ACCOUNT_MANAGEMENT_CLIENT_ID); ClientModel nonExisting = realm.getClientByClientId("NonExisting"); Assert.assertNotNull(application); Assert.assertNotNull(otherApp); @@ -130,7 +130,7 @@ public class ImportTest extends AbstractModelTest { Assert.assertEquals(1, realmRoles.size()); Assert.assertEquals("admin", realmRoles.iterator().next().getName()); - Set appRoles = admin.getApplicationRoleMappings(application); + Set appRoles = admin.getClientRoleMappings(application); Assert.assertEquals(1, appRoles.size()); Assert.assertEquals("app-admin", appRoles.iterator().next().getName()); @@ -149,7 +149,7 @@ public class ImportTest extends AbstractModelTest { Set realmScopes = oauthClient.getRealmScopeMappings(); Assert.assertTrue(realmScopes.contains(realm.getRole("admin"))); - Set appScopes = application.getApplicationScopeMappings(oauthClient); + Set appScopes = application.getClientScopeMappings(oauthClient); Assert.assertTrue(appScopes.contains(application.getRole("app-user"))); diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/saml/SamlBindingTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/saml/SamlBindingTest.java index 000eaad3f1..6997697aa4 100755 --- a/testsuite/integration/src/test/java/org/keycloak/testsuite/saml/SamlBindingTest.java +++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/saml/SamlBindingTest.java @@ -419,7 +419,7 @@ public class SamlBindingTest { RealmManager manager = new RealmManager(session); RealmModel adminRealm = manager.getRealm(Config.getAdminRealm()); - ClientModel adminConsole = adminRealm.getClientByClientId(Constants.ADMIN_CONSOLE_APPLICATION); + ClientModel adminConsole = adminRealm.getClientByClientId(Constants.ADMIN_CONSOLE_CLIENT_ID); TokenManager tm = new TokenManager(); UserModel admin = session.users().getUserByUsername("admin", adminRealm); ClientSessionModel clientSession = session.sessions().createClientSession(adminRealm, adminConsole); diff --git a/testsuite/integration/src/test/resources/testrealm.json b/testsuite/integration/src/test/resources/testrealm.json index b33febcd54..c9b67085ba 100755 --- a/testsuite/integration/src/test/resources/testrealm.json +++ b/testsuite/integration/src/test/resources/testrealm.json @@ -47,16 +47,6 @@ } } ], - "oauthClients" : [ - { - "name" : "third-party", - "enabled": true, - "redirectUris": [ - "http://localhost:8081/app/*" - ], - "secret": "password" - } - ], "scopeMappings": [ { "client": "third-party", @@ -69,7 +59,7 @@ ], "clients": [ { - "name": "test-app", + "clientId": "test-app", "enabled": true, "baseUrl": "http://localhost:8081/app", "redirectUris": [ @@ -77,7 +67,17 @@ ], "adminUrl": "http://localhost:8081/app/logout", "secret": "password" - } + }, + { + "clientId" : "third-party", + "enabled": true, + "consentRequired": true, + + "redirectUris": [ + "http://localhost:8081/app/*" + ], + "secret": "password" + } ], "roles" : { "realm" : [ From 600353899addb0934a0040f535fcdf2b5045a819 Mon Sep 17 00:00:00 2001 From: Stian Thorgersen Date: Mon, 13 Apr 2015 13:32:18 +0200 Subject: [PATCH 13/15] KEYCLOAK-1187 --- .../exportimport/util/ImportUtils.java | 6 +++--- .../java/org/keycloak/models/AdminRoles.java | 2 +- .../java/org/keycloak/models/ClientModel.java | 2 +- .../models/utils/KeycloakModelUtils.java | 2 +- .../models/utils/RepresentationToModel.java | 18 +++++++++--------- .../models/file/adapter/ClientAdapter.java | 2 +- .../keycloak/models/cache/ClientAdapter.java | 4 ++-- .../org/keycloak/models/jpa/ClientAdapter.java | 2 +- .../mongo/keycloak/adapters/ClientAdapter.java | 2 +- .../testsuite/model/ClientModelTest.java | 2 +- 10 files changed, 21 insertions(+), 21 deletions(-) diff --git a/export-import/export-import-api/src/main/java/org/keycloak/exportimport/util/ImportUtils.java b/export-import/export-import-api/src/main/java/org/keycloak/exportimport/util/ImportUtils.java index 21285c9572..66b106cc04 100755 --- a/export-import/export-import-api/src/main/java/org/keycloak/exportimport/util/ImportUtils.java +++ b/export-import/export-import-api/src/main/java/org/keycloak/exportimport/util/ImportUtils.java @@ -81,7 +81,7 @@ public class ImportUtils { // We just imported master realm. All 'masterAdminApps' need to be refreshed RealmModel adminRealm = realm; for (RealmModel currentRealm : model.getRealms()) { - ClientModel masterApp = adminRealm.getClientByClientId(KeycloakModelUtils.getMasterRealmAdminApplicationName(currentRealm)); + ClientModel masterApp = adminRealm.getClientByClientId(KeycloakModelUtils.getMasterRealmAdminApplicationClientId(currentRealm)); if (masterApp != null) { currentRealm.setMasterAdminClient(masterApp); } else { @@ -91,7 +91,7 @@ public class ImportUtils { } else { // Need to refresh masterApp for current realm RealmModel adminRealm = model.getRealm(adminRealmId); - ClientModel masterApp = adminRealm.getClientByClientId(KeycloakModelUtils.getMasterRealmAdminApplicationName(realm)); + ClientModel masterApp = adminRealm.getClientByClientId(KeycloakModelUtils.getMasterRealmAdminApplicationClientId(realm)); if (masterApp != null) { realm.setMasterAdminClient(masterApp); } else { @@ -119,7 +119,7 @@ public class ImportUtils { } adminRole.setDescription("${role_"+AdminRoles.ADMIN+"}"); - ClientModel realmAdminApp = KeycloakModelUtils.createClient(adminRealm, KeycloakModelUtils.getMasterRealmAdminApplicationName(realm)); + ClientModel realmAdminApp = KeycloakModelUtils.createClient(adminRealm, KeycloakModelUtils.getMasterRealmAdminApplicationClientId(realm)); realmAdminApp.setBearerOnly(true); realm.setMasterAdminClient(realmAdminApp); diff --git a/model/api/src/main/java/org/keycloak/models/AdminRoles.java b/model/api/src/main/java/org/keycloak/models/AdminRoles.java index 73a93c3872..c067a1d842 100755 --- a/model/api/src/main/java/org/keycloak/models/AdminRoles.java +++ b/model/api/src/main/java/org/keycloak/models/AdminRoles.java @@ -9,7 +9,7 @@ public class AdminRoles { public static String ADMIN = "admin"; - // for admin application local to each realm + // for admin client local to each realm public static String REALM_ADMIN = "realm-admin"; public static String CREATE_REALM = "create-realm"; diff --git a/model/api/src/main/java/org/keycloak/models/ClientModel.java b/model/api/src/main/java/org/keycloak/models/ClientModel.java index 9cc51f375c..026e35e242 100755 --- a/model/api/src/main/java/org/keycloak/models/ClientModel.java +++ b/model/api/src/main/java/org/keycloak/models/ClientModel.java @@ -16,7 +16,7 @@ public interface ClientModel extends RoleContainerModel { String PUBLIC_KEY = "publicKey"; String X509CERTIFICATE = "X509Certificate"; - void updateApplication(); + void updateClient(); String getId(); diff --git a/model/api/src/main/java/org/keycloak/models/utils/KeycloakModelUtils.java b/model/api/src/main/java/org/keycloak/models/utils/KeycloakModelUtils.java index bd03cac67e..8ee918bd6f 100755 --- a/model/api/src/main/java/org/keycloak/models/utils/KeycloakModelUtils.java +++ b/model/api/src/main/java/org/keycloak/models/utils/KeycloakModelUtils.java @@ -245,7 +245,7 @@ public final class KeycloakModelUtils { } } - public static String getMasterRealmAdminApplicationName(RealmModel realm) { + public static String getMasterRealmAdminApplicationClientId(RealmModel realm) { return realm.getName() + "-realm"; } } diff --git a/model/api/src/main/java/org/keycloak/models/utils/RepresentationToModel.java b/model/api/src/main/java/org/keycloak/models/utils/RepresentationToModel.java index ae26387bab..f830ac1f24 100755 --- a/model/api/src/main/java/org/keycloak/models/utils/RepresentationToModel.java +++ b/model/api/src/main/java/org/keycloak/models/utils/RepresentationToModel.java @@ -517,7 +517,7 @@ public class RepresentationToModel { * @return */ public static ClientModel createClient(KeycloakSession session, RealmModel realm, ClientRepresentation resourceRep, boolean addDefaultRoles) { - logger.debug("************ CREATE APPLICATION: {0}" + resourceRep.getClientId()); + logger.debug("Create client: {0}" + resourceRep.getClientId()); ClientModel client = resourceRep.getId()!=null ? realm.addClient(resourceRep.getId(), resourceRep.getClientId()) : realm.addClient(resourceRep.getClientId()); if (resourceRep.isEnabled() != null) client.setEnabled(resourceRep.isEnabled()); @@ -540,7 +540,7 @@ public class RepresentationToModel { } else { client.setNodeReRegistrationTimeout(-1); } - client.updateApplication(); + client.updateClient(); if (resourceRep.getNotBefore() != null) { client.setNotBefore(resourceRep.getNotBefore()); @@ -565,7 +565,7 @@ public class RepresentationToModel { } if (resourceRep.getWebOrigins() != null) { for (String webOrigin : resourceRep.getWebOrigins()) { - logger.debugv("Application: {0} webOrigin: {1}", resourceRep.getClientId(), webOrigin); + logger.debugv("Client: {0} webOrigin: {1}", resourceRep.getClientId(), webOrigin); client.addWebOrigin(webOrigin); } } else { @@ -580,7 +580,7 @@ public class RepresentationToModel { if (uri.getPort() != -1) { origin += ":" + uri.getPort(); } - logger.debugv("adding default application origin: {0}" , origin); + logger.debugv("adding default client origin: {0}" , origin); origins.add(origin); } } @@ -627,7 +627,7 @@ public class RepresentationToModel { if (rep.getBaseUrl() != null) resource.setBaseUrl(rep.getBaseUrl()); if (rep.isSurrogateAuthRequired() != null) resource.setSurrogateAuthRequired(rep.isSurrogateAuthRequired()); if (rep.getNodeReRegistrationTimeout() != null) resource.setNodeReRegistrationTimeout(rep.getNodeReRegistrationTimeout()); - resource.updateApplication(); + resource.updateClient(); if (rep.getProtocol() != null) resource.setProtocol(rep.getProtocol()); if (rep.getAttributes() != null) { @@ -725,7 +725,7 @@ public class RepresentationToModel { for (ScopeMappingRepresentation mapping : mappings) { ClientModel client = realm.getClientByClientId(mapping.getClient()); if (client == null) { - throw new RuntimeException("Unknown client specified in application scope mappings"); + throw new RuntimeException("Unknown client specified in client scope mappings"); } for (String roleString : mapping.getRoles()) { RoleModel role = clientModel.getRole(roleString.trim()); @@ -821,15 +821,15 @@ public class RepresentationToModel { // Role mappings - public static void createClientRoleMappings(ClientModel applicationModel, UserModel user, List roleNames) { + public static void createClientRoleMappings(ClientModel clientModel, UserModel user, List roleNames) { if (user == null) { throw new RuntimeException("User not found"); } for (String roleName : roleNames) { - RoleModel role = applicationModel.getRole(roleName.trim()); + RoleModel role = clientModel.getRole(roleName.trim()); if (role == null) { - role = applicationModel.addRole(roleName.trim()); + role = clientModel.addRole(roleName.trim()); } user.grantRole(role); diff --git a/model/file/src/main/java/org/keycloak/models/file/adapter/ClientAdapter.java b/model/file/src/main/java/org/keycloak/models/file/adapter/ClientAdapter.java index e40d25182c..18cc9c858b 100755 --- a/model/file/src/main/java/org/keycloak/models/file/adapter/ClientAdapter.java +++ b/model/file/src/main/java/org/keycloak/models/file/adapter/ClientAdapter.java @@ -62,7 +62,7 @@ public class ClientAdapter implements ClientModel { } @Override - public void updateApplication() { + public void updateClient() { } @Override diff --git a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/ClientAdapter.java b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/ClientAdapter.java index 42d41538db..5330fbc18a 100755 --- a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/ClientAdapter.java +++ b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/ClientAdapter.java @@ -42,8 +42,8 @@ public class ClientAdapter implements ClientModel { } @Override - public void updateApplication() { - if (updated != null) updated.updateApplication(); + public void updateClient() { + if (updated != null) updated.updateClient(); } @Override diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/ClientAdapter.java b/model/jpa/src/main/java/org/keycloak/models/jpa/ClientAdapter.java index 90e83f4c89..b04a92c15e 100755 --- a/model/jpa/src/main/java/org/keycloak/models/jpa/ClientAdapter.java +++ b/model/jpa/src/main/java/org/keycloak/models/jpa/ClientAdapter.java @@ -469,7 +469,7 @@ public class ClientAdapter implements ClientModel { } @Override - public void updateApplication() { + public void updateClient() { em.flush(); } diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/ClientAdapter.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/ClientAdapter.java index a2e1fa04d2..803cedf417 100755 --- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/ClientAdapter.java +++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/ClientAdapter.java @@ -46,7 +46,7 @@ public class ClientAdapter extends AbstractMongoAdapter imple } @Override - public void updateApplication() { + public void updateClient() { updateMongoEntity(); } diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/model/ClientModelTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/model/ClientModelTest.java index a9b1344f2c..f0fc63b14c 100755 --- a/testsuite/integration/src/test/java/org/keycloak/testsuite/model/ClientModelTest.java +++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/model/ClientModelTest.java @@ -48,7 +48,7 @@ public class ClientModelTest extends AbstractModelTest { client.registerNode("node1", 10); client.registerNode("10.20.30.40", 50); - client.updateApplication(); + client.updateClient(); } @Test From 46e386cd43ad2f6fd119fb935f164a344ecea355 Mon Sep 17 00:00:00 2001 From: Stian Thorgersen Date: Mon, 13 Apr 2015 13:54:30 +0200 Subject: [PATCH 14/15] KEYCLOAK-1187 --- .../org/keycloak/admin/client/resource/ClientResource.java | 1 - .../keycloak/admin/client/resource/ClientsResource.java | 7 +++---- .../org/keycloak/admin/client/resource/RealmResource.java | 2 +- .../keycloak/testsuite/adapter/AdapterTestStrategy.java | 2 +- .../keycloak/testsuite/adapter/RelativeUriAdapterTest.java | 2 +- .../java/org/keycloak/testsuite/saml/SamlBindingTest.java | 2 +- 6 files changed, 7 insertions(+), 9 deletions(-) diff --git a/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/ClientResource.java b/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/ClientResource.java index 0bc8ad70a6..94b254d75d 100755 --- a/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/ClientResource.java +++ b/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/ClientResource.java @@ -1,6 +1,5 @@ package org.keycloak.admin.client.resource; -import org.keycloak.representations.idm.ApplicationRepresentation; import org.keycloak.representations.idm.ClientRepresentation; import org.keycloak.representations.idm.CredentialRepresentation; import org.keycloak.representations.idm.UserSessionRepresentation; diff --git a/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/ClientsResource.java b/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/ClientsResource.java index abc94243a4..9843bc53cf 100755 --- a/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/ClientsResource.java +++ b/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/ClientsResource.java @@ -1,6 +1,5 @@ package org.keycloak.admin.client.resource; -import org.keycloak.representations.idm.ApplicationRepresentation; import org.keycloak.representations.idm.ClientRepresentation; import javax.ws.rs.Consumes; @@ -17,8 +16,8 @@ import java.util.List; */ public interface ClientsResource { - @Path("{appName}") - public ClientResource get(@PathParam("appName") String appName); + @Path("{clientId}") + public ClientResource get(@PathParam("clientId") String clientId); @POST @Consumes(MediaType.APPLICATION_JSON) @@ -26,7 +25,7 @@ public interface ClientsResource { @GET @Produces(MediaType.APPLICATION_JSON) - public List findAll(); + public List findAll(); diff --git a/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/RealmResource.java b/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/RealmResource.java index 8cd1d90d5c..4045ecfe69 100644 --- a/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/RealmResource.java +++ b/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/RealmResource.java @@ -23,7 +23,7 @@ public interface RealmResource { @Consumes(MediaType.APPLICATION_JSON) public void update(RealmRepresentation realmRepresentation); - @Path("applications") + @Path("clients") public ClientsResource clients(); @Path("users") diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/AdapterTestStrategy.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/AdapterTestStrategy.java index b73b013f10..ba41ceb4f1 100755 --- a/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/AdapterTestStrategy.java +++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/AdapterTestStrategy.java @@ -212,7 +212,7 @@ public class AdapterTestStrategy extends ExternalResource { Client client = ClientBuilder.newClient(); UriBuilder authBase = UriBuilder.fromUri(AUTH_SERVER_URL); WebTarget adminTarget = client.target(AdminRoot.realmsUrl(authBase)).path("demo"); - Map stats = adminTarget.path("application-session-stats").request() + Map stats = adminTarget.path("client-session-stats").request() .header(HttpHeaders.AUTHORIZATION, "Bearer " + adminToken) .get(new GenericType>() { }); diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/RelativeUriAdapterTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/RelativeUriAdapterTest.java index 8361845e77..4c22533aba 100755 --- a/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/RelativeUriAdapterTest.java +++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/RelativeUriAdapterTest.java @@ -135,7 +135,7 @@ public class RelativeUriAdapterTest { Client client = ClientBuilder.newClient(); UriBuilder authBase = UriBuilder.fromUri("http://localhost:8081/auth"); WebTarget adminTarget = client.target(AdminRoot.realmsUrl(authBase)).path("demo"); - Map stats = adminTarget.path("application-session-stats").request() + Map stats = adminTarget.path("client-session-stats").request() .header(HttpHeaders.AUTHORIZATION, "Bearer " + adminToken) .get(new GenericType>(){}); diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/saml/SamlBindingTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/saml/SamlBindingTest.java index 6997697aa4..e91d58c0b4 100755 --- a/testsuite/integration/src/test/java/org/keycloak/testsuite/saml/SamlBindingTest.java +++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/saml/SamlBindingTest.java @@ -466,7 +466,7 @@ public class SamlBindingTest { Assert.assertNotNull(is); formData.addFormData("file", is, MediaType.APPLICATION_XML_TYPE); - WebTarget upload = adminRealms.path("demo/application-importers/saml2-entity-descriptor/upload"); + WebTarget upload = adminRealms.path("demo/client-importers/saml2-entity-descriptor/upload"); System.out.println(upload.getUri()); Response response = upload.request().post(Entity.entity(formData, MediaType.MULTIPART_FORM_DATA)); Assert.assertEquals(204, response.getStatus()); From 4abd62661f9bb3aaeb73e05bd9a5dc85b4c1781a Mon Sep 17 00:00:00 2001 From: Stian Thorgersen Date: Mon, 13 Apr 2015 14:23:41 +0200 Subject: [PATCH 15/15] Updated example jsons --- examples/admin-client/example-realm.json | 4 ++-- examples/basic-auth/basicauthrealm.json | 4 ++-- .../facebook-identity-provider-realm.json | 4 ++-- .../google-identity-provider-realm.json | 4 ++-- .../saml-broker-authentication-realm.json | 4 ++-- .../saml-broker-realm.json | 2 +- .../twitter-identity-provider-realm.json | 4 ++-- examples/cordova/example-realm.json | 6 +++--- examples/cors/cors-realm.json | 6 +++--- examples/demo-template/testrealm.json | 21 +++++++++---------- examples/fuse/testrealm.json | 17 +++++++-------- examples/js-console/example-realm.json | 6 +++--- examples/kerberos/kerberosrealm.json | 2 +- examples/multi-tenant/tenant1-realm.json | 4 ++-- examples/multi-tenant/tenant2-realm.json | 6 +++--- examples/saml/testsaml.json | 12 +++++------ 16 files changed, 52 insertions(+), 54 deletions(-) diff --git a/examples/admin-client/example-realm.json b/examples/admin-client/example-realm.json index 2615e56676..3317f48f76 100755 --- a/examples/admin-client/example-realm.json +++ b/examples/admin-client/example-realm.json @@ -17,12 +17,12 @@ "value": "password" } ], - "applicationRoles": { + "clientRoles": { "realm-management": [ "realm-admin" ] } } ], - "applications": [ + "clients": [ { "name": "examples-admin-client", "enabled": true, diff --git a/examples/basic-auth/basicauthrealm.json b/examples/basic-auth/basicauthrealm.json index f6bac20a5b..0ed1bf5606 100644 --- a/examples/basic-auth/basicauthrealm.json +++ b/examples/basic-auth/basicauthrealm.json @@ -24,7 +24,7 @@ "value" : "password" } ], "realmRoles": [ "user","admin" ], - "applicationRoles": { + "clientRoles": { "realm-management": [ "realm-admin" ] } } @@ -41,7 +41,7 @@ } ] }, - "applications": [ + "clients": [ { "name": "basic-auth-service", "enabled": true, diff --git a/examples/broker/facebook-authentication/facebook-identity-provider-realm.json b/examples/broker/facebook-authentication/facebook-identity-provider-realm.json index 32a370497a..cc8c636e63 100644 --- a/examples/broker/facebook-authentication/facebook-identity-provider-realm.json +++ b/examples/broker/facebook-authentication/facebook-identity-provider-realm.json @@ -17,7 +17,7 @@ "value" : "password" } ], "realmRoles": [ "user","admin" ], - "applicationRoles": { + "clientRoles": { "realm-management": [ "realm-admin" ] } } @@ -30,7 +30,7 @@ } ] }, - "applications": [ + "clients": [ { "name": "facebook-authentication", "enabled": true, diff --git a/examples/broker/google-authentication/google-identity-provider-realm.json b/examples/broker/google-authentication/google-identity-provider-realm.json index 8b4deef92b..a721e34b13 100644 --- a/examples/broker/google-authentication/google-identity-provider-realm.json +++ b/examples/broker/google-authentication/google-identity-provider-realm.json @@ -17,7 +17,7 @@ "value" : "password" } ], "realmRoles": [ "user","admin" ], - "applicationRoles": { + "clientRoles": { "realm-management": [ "realm-admin" ] } } @@ -30,7 +30,7 @@ } ] }, - "applications": [ + "clients": [ { "name": "google-authentication", "enabled": true, diff --git a/examples/broker/saml-broker-authentication/saml-broker-authentication-realm.json b/examples/broker/saml-broker-authentication/saml-broker-authentication-realm.json index f8fbc8a242..ad757ab414 100644 --- a/examples/broker/saml-broker-authentication/saml-broker-authentication-realm.json +++ b/examples/broker/saml-broker-authentication/saml-broker-authentication-realm.json @@ -17,7 +17,7 @@ "value" : "password" } ], "realmRoles": [ "user","admin" ], - "applicationRoles": { + "clientRoles": { "realm-management": [ "realm-admin" ] } } @@ -30,7 +30,7 @@ } ] }, - "applications": [ + "clients": [ { "name": "saml-broker-authentication", "enabled": true, diff --git a/examples/broker/saml-broker-authentication/saml-broker-realm.json b/examples/broker/saml-broker-authentication/saml-broker-realm.json index 7f1cde0b82..8d0bad467b 100644 --- a/examples/broker/saml-broker-authentication/saml-broker-realm.json +++ b/examples/broker/saml-broker-authentication/saml-broker-realm.json @@ -26,7 +26,7 @@ } ] }, - "applications": [ + "clients": [ { "name": "http://localhost:8080/auth/realms/saml-broker-authentication-realm", "protocol": "saml", diff --git a/examples/broker/twitter-authentication/twitter-identity-provider-realm.json b/examples/broker/twitter-authentication/twitter-identity-provider-realm.json index 4b709044c7..f9add02775 100644 --- a/examples/broker/twitter-authentication/twitter-identity-provider-realm.json +++ b/examples/broker/twitter-authentication/twitter-identity-provider-realm.json @@ -18,7 +18,7 @@ "value" : "password" } ], "realmRoles": [ "user","admin" ], - "applicationRoles": { + "clientRoles": { "realm-management": [ "realm-admin" ] } } @@ -31,7 +31,7 @@ } ] }, - "applications": [ + "clients": [ { "name": "twitter-authentication", "enabled": true, diff --git a/examples/cordova/example-realm.json b/examples/cordova/example-realm.json index f0d6ad282f..d07a5d38a9 100755 --- a/examples/cordova/example-realm.json +++ b/examples/cordova/example-realm.json @@ -18,7 +18,7 @@ "value" : "password" } ], "realmRoles": [ "user" ], - "applicationRoles": { + "clientRoles": { "account": ["view-profile", "manage-account"] } } @@ -41,7 +41,7 @@ "roles": ["user"] } ], - "applications": [ + "clients": [ { "name": "cordova", "enabled": true, @@ -50,7 +50,7 @@ "webOrigins": ["localhost"] } ], - "applicationScopeMappings": { + "clientScopeMappings": { "account": [ { "client": "cordova", diff --git a/examples/cors/cors-realm.json b/examples/cors/cors-realm.json index ab08ee39e7..9e59580675 100755 --- a/examples/cors/cors-realm.json +++ b/examples/cors/cors-realm.json @@ -23,7 +23,7 @@ "value" : "password" } ], "realmRoles": [ "user" ], - "applicationRoles": { + "clientRoles": { "realm-management": [ "realm-admin" ] } } @@ -42,7 +42,7 @@ "roles": ["user"] } ], - "applications": [ + "clients": [ { "name": "angular-cors-product", "enabled": true, @@ -56,7 +56,7 @@ ] } ], - "applicationScopeMappings": { + "clientScopeMappings": { "realm-management": [ { "client": "angular-cors-product", diff --git a/examples/demo-template/testrealm.json b/examples/demo-template/testrealm.json index 031e20bc54..4b4d669fd6 100755 --- a/examples/demo-template/testrealm.json +++ b/examples/demo-template/testrealm.json @@ -24,7 +24,7 @@ "value" : "password" } ], "realmRoles": [ "user" ], - "applicationRoles": { + "clientRoles": { "account": [ "manage-account" ] } }, @@ -39,7 +39,7 @@ "value" : "password" } ], "realmRoles": [ "user" ], - "applicationRoles": { + "clientRoles": { "account": [ "manage-account" ] } }, @@ -54,7 +54,7 @@ "value" : "password" } ], "realmRoles": [ "user" ], - "applicationRoles": { + "clientRoles": { "account": [ "manage-account" ] } }, @@ -69,7 +69,7 @@ "value" : "password" } ], "realmRoles": [ "user","admin" ], - "applicationRoles": { + "clientRoles": { "realm-management": [ "realm-admin" ] } } @@ -92,7 +92,7 @@ "roles": ["user"] } ], - "applications": [ + "clients": [ { "name": "customer-portal", "enabled": true, @@ -146,12 +146,11 @@ "adminUrl": "/database", "baseUrl": "/database", "bearerOnly": true - } - ], - "oauthClients": [ + }, { "name": "third-party", "enabled": true, + "consentRequired": true, "redirectUris": [ "/oauth-client/*", "/oauth-client-cdi/*" @@ -162,11 +161,11 @@ "name": "admin-client", "enabled": true, "publicClient": true, - "directGrantsOnly": true - + "directGrantsOnly": true, + "consentRequired": true } ], - "applicationScopeMappings": { + "clientScopeMappings": { "realm-management": [ { "client": "admin-client", diff --git a/examples/fuse/testrealm.json b/examples/fuse/testrealm.json index 9ec73f9c73..d474e66de4 100644 --- a/examples/fuse/testrealm.json +++ b/examples/fuse/testrealm.json @@ -24,7 +24,7 @@ "value" : "password" } ], "realmRoles": [ "user" ], - "applicationRoles": { + "clientRoles": { "account": [ "manage-account" ] } }, @@ -39,7 +39,7 @@ "value" : "password" } ], "realmRoles": [ "user" ], - "applicationRoles": { + "clientRoles": { "account": [ "manage-account" ] } }, @@ -54,7 +54,7 @@ "value" : "password" } ], "realmRoles": [ "user" ], - "applicationRoles": { + "clientRoles": { "account": [ "manage-account" ] } }, @@ -69,7 +69,7 @@ "value" : "password" } ], "realmRoles": [ "user","admin" ], - "applicationRoles": { + "clientRoles": { "realm-management": [ "realm-admin" ] } }, @@ -84,7 +84,7 @@ "value" : "password" } ], "realmRoles": [ "user", "jmxAdmin" ], - "applicationRoles": { + "clientRoles": { "account": [ "manage-account" ], "realm-management": [ "realm-admin" ] } @@ -134,7 +134,7 @@ } ] }, - "applications": [ + "clients": [ { "name": "customer-portal", "enabled": true, @@ -178,14 +178,13 @@ "adminUrl": "http://localhost:8383/admin-camel-endpoint", "baseUrl": "http://localhost:8383/admin-camel-endpoint", "bearerOnly": true - } - ], - "oauthClients": [ + }, { "name": "ssh-jmx-admin-client", "enabled": true, "publicClient": false, "directGrantsOnly": true, + "consentRequired": true, "secret": "password" } ], diff --git a/examples/js-console/example-realm.json b/examples/js-console/example-realm.json index ddbb6eaf6a..81c92aa1f5 100755 --- a/examples/js-console/example-realm.json +++ b/examples/js-console/example-realm.json @@ -18,7 +18,7 @@ "value" : "password" } ], "realmRoles": [ "user" ], - "applicationRoles": { + "clientRoles": { "account": ["view-profile", "manage-account"] } } @@ -41,7 +41,7 @@ "roles": ["user"] } ], - "applications": [ + "clients": [ { "name": "js-console", "enabled": true, @@ -53,7 +53,7 @@ "webOrigins": [] } ], - "applicationScopeMappings": { + "clientScopeMappings": { "account": [ { "client": "js-console", diff --git a/examples/kerberos/kerberosrealm.json b/examples/kerberos/kerberosrealm.json index 4339e364a5..006961ca0d 100644 --- a/examples/kerberos/kerberosrealm.json +++ b/examples/kerberos/kerberosrealm.json @@ -13,7 +13,7 @@ "roles": [ "user" ] } ], - "applications": [ + "clients": [ { "name": "kerberos-app", "enabled": true, diff --git a/examples/multi-tenant/tenant1-realm.json b/examples/multi-tenant/tenant1-realm.json index e7a9cc9dfa..e759b12644 100644 --- a/examples/multi-tenant/tenant1-realm.json +++ b/examples/multi-tenant/tenant1-realm.json @@ -20,7 +20,7 @@ "value" : "user-tenant1" } ], "realmRoles": [ "user" ], - "applicationRoles": { + "clientRoles": { "multi-tenant": [ "user" ] } } @@ -40,7 +40,7 @@ } ], - "applications": [ + "clients": [ { "name": "multi-tenant", "enabled": true, diff --git a/examples/multi-tenant/tenant2-realm.json b/examples/multi-tenant/tenant2-realm.json index d628b731f1..2cd0e618cf 100644 --- a/examples/multi-tenant/tenant2-realm.json +++ b/examples/multi-tenant/tenant2-realm.json @@ -21,7 +21,7 @@ "value" : "user-tenant2" } ], "realmRoles": [ "user" ], - "applicationRoles": { + "clientRoles": { "multi-tenant": [ "user" ] } } @@ -41,9 +41,9 @@ } ], - "applications": [ + "clients": [ { - "name": "multi-tenant", + "clientId": "multi-tenant", "enabled": true, "adminUrl": "/multitenant/tenant2", "baseUrl": "/multitenant/tenant2", diff --git a/examples/saml/testsaml.json b/examples/saml/testsaml.json index b7f66af0de..7cf4a8ef52 100755 --- a/examples/saml/testsaml.json +++ b/examples/saml/testsaml.json @@ -25,9 +25,9 @@ "realmRoles": ["manager"] } ], - "applications": [ + "clients": [ { - "name": "http://localhost:8080/sales-post/", + "clientId": "http://localhost:8080/sales-post/", "enabled": true, "fullScopeAllowed": true, "protocol": "saml", @@ -41,7 +41,7 @@ } }, { - "name": "http://localhost:8080/sales-post-sig/", + "clientId": "http://localhost:8080/sales-post-sig/", "enabled": true, "protocol": "saml", "fullScopeAllowed": true, @@ -60,7 +60,7 @@ } }, { - "name": "http://localhost:8080/sales-post-enc/", + "clientId": "http://localhost:8080/sales-post-enc/", "enabled": true, "protocol": "saml", "fullScopeAllowed": true, @@ -82,7 +82,7 @@ } }, { - "name": "http://localhost:8080/employee/", + "clientId": "http://localhost:8080/employee/", "enabled": true, "fullScopeAllowed": true, "protocol": "saml", @@ -96,7 +96,7 @@ } }, { - "name": "http://localhost:8080/employee-sig/", + "clientId": "http://localhost:8080/employee-sig/", "enabled": true, "protocol": "saml", "fullScopeAllowed": true,