From e2ad7608c8dd4e935097a079374505e310e619c9 Mon Sep 17 00:00:00 2001 From: fkiss Date: Fri, 22 Jul 2016 16:29:58 +0200 Subject: [PATCH 1/8] KEYCLOAK-2281 added ldap tests over ssl --- .../org/keycloak/testsuite/util/LDAPRule.java | 14 ++++++++++++++ .../admin/UserFederationLdapConnectionTest.java | 16 ++++++++++++++++ .../keycloak/util/ldap/LDAPEmbeddedServer.java | 8 +++++--- 3 files changed, 35 insertions(+), 3 deletions(-) diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/LDAPRule.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/LDAPRule.java index 5cebe8cecd..86b3caecea 100644 --- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/LDAPRule.java +++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/LDAPRule.java @@ -21,6 +21,7 @@ import java.util.Map; import java.util.Properties; import org.junit.rules.ExternalResource; +import org.keycloak.models.LDAPConstants; import org.keycloak.util.ldap.LDAPEmbeddedServer; /** @@ -30,6 +31,14 @@ public class LDAPRule extends ExternalResource { public static final String LDAP_CONNECTION_PROPERTIES_LOCATION = "classpath:ldap/ldap-connection.properties"; + private static final String PROPERTY_ENABLE_SSL = "enableSSL"; + + private static final String PROPERTY_KEYSTORE_FILE = "keystoreFile"; + + private static final String PRIVATE_KEY = "keystore/keycloak.jks"; + + private static final String PROPERTY_CERTIFICATE_PASSWORD = "certificatePassword"; + protected LDAPTestConfiguration ldapTestConfiguration; protected LDAPEmbeddedServer ldapEmbeddedServer; @@ -66,6 +75,11 @@ public class LDAPRule extends ExternalResource { Properties defaultProperties = new Properties(); defaultProperties.setProperty(LDAPEmbeddedServer.PROPERTY_DSF, LDAPEmbeddedServer.DSF_INMEMORY); defaultProperties.setProperty(LDAPEmbeddedServer.PROPERTY_LDIF_FILE, "classpath:ldap/users.ldif"); + defaultProperties.setProperty(LDAPConstants.CONNECTION_URL, "ldaps://localhost:10636"); + defaultProperties.setProperty(LDAPEmbeddedServer.PROPERTY_BIND_PORT, "10636"); + defaultProperties.setProperty(PROPERTY_ENABLE_SSL, "true"); + defaultProperties.setProperty(PROPERTY_CERTIFICATE_PASSWORD, "secret"); + defaultProperties.setProperty(PROPERTY_KEYSTORE_FILE, this.getClass().getClassLoader().getResource(LDAPRule.PRIVATE_KEY).getFile()); return new LDAPEmbeddedServer(defaultProperties); } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/UserFederationLdapConnectionTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/UserFederationLdapConnectionTest.java index 041d58c97a..dc48b7d92b 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/UserFederationLdapConnectionTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/UserFederationLdapConnectionTest.java @@ -57,6 +57,22 @@ public class UserFederationLdapConnectionTest extends AbstractAdminTest { } + @Test + public void testLdapConnectionsSsl() { + + Response response = realm.testLDAPConnection(LDAPConnectionTestManager.TEST_CONNECTION, "ldaps://localhost:10636", "foo", "bar", "false"); + assertStatus(response, 204); + + response = realm.testLDAPConnection(LDAPConnectionTestManager.TEST_CONNECTION, "ldaps://localhostt:10636", "foo", "bar", "false"); + assertStatus(response, 400); + + response = realm.testLDAPConnection(LDAPConnectionTestManager.TEST_AUTHENTICATION, "ldaps://localhost:10636", "foo", "bar", "false"); + assertStatus(response, 400); + + response = realm.testLDAPConnection(LDAPConnectionTestManager.TEST_AUTHENTICATION, "ldaps://localhost:10636", "uid=admin,ou=system", "secret", "true"); + assertStatus(response, 204); + } + private void assertStatus(Response response, int status) { Assert.assertEquals(status, response.getStatus()); response.close(); diff --git a/util/embedded-ldap/src/main/java/org/keycloak/util/ldap/LDAPEmbeddedServer.java b/util/embedded-ldap/src/main/java/org/keycloak/util/ldap/LDAPEmbeddedServer.java index 33e082047b..1754b4c655 100644 --- a/util/embedded-ldap/src/main/java/org/keycloak/util/ldap/LDAPEmbeddedServer.java +++ b/util/embedded-ldap/src/main/java/org/keycloak/util/ldap/LDAPEmbeddedServer.java @@ -219,13 +219,15 @@ public class LDAPEmbeddedServer { ldapServer.setSearchBaseDn(this.baseDN); // Read the transports - Transport ldap = new TcpTransport(this.bindHost, this.bindPort, 3, 50); + Transport ldaps = new TcpTransport(this.bindHost, this.bindPort, 3, 50); if (enableSSL) { - ldap.setEnableSSL(true); + ldaps.setEnableSSL(true); ldapServer.setKeystoreFile(keystoreFile); ldapServer.setCertificatePassword(certPassword); + Transport ldap = new TcpTransport(this.bindHost, 10389, 3, 50); + ldapServer.addTransports( ldap ); } - ldapServer.addTransports( ldap ); + ldapServer.addTransports( ldaps ); // Associate the DS to this LdapServer ldapServer.setDirectoryService( directoryService ); From 2b3859f4628a8fc44865fe0cd2e5ff4b01ff7328 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomislav=20Rajakovi=C4=87?= Date: Thu, 28 Jul 2016 16:34:52 +0200 Subject: [PATCH 2/8] Fixing typo in account resource bundle: editAccountHtmlTtile -> editAccountHtmlTitle --- themes/src/main/resources/theme/base/account/account.ftl | 2 +- .../theme/base/account/messages/messages_ca.properties | 2 +- .../theme/base/account/messages/messages_de.properties | 2 +- .../theme/base/account/messages/messages_en.properties | 2 +- .../theme/base/account/messages/messages_es.properties | 2 +- .../theme/base/account/messages/messages_fr.properties | 2 +- .../theme/base/account/messages/messages_it.properties | 2 +- .../theme/base/account/messages/messages_pt_BR.properties | 2 +- .../theme/base/account/messages/messages_ru.properties | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/themes/src/main/resources/theme/base/account/account.ftl b/themes/src/main/resources/theme/base/account/account.ftl index 34c3e84719..87cd19875a 100755 --- a/themes/src/main/resources/theme/base/account/account.ftl +++ b/themes/src/main/resources/theme/base/account/account.ftl @@ -3,7 +3,7 @@
-

${msg("editAccountHtmlTtile")}

+

${msg("editAccountHtmlTitle")}

* ${msg("requiredFields")} diff --git a/themes/src/main/resources/theme/base/account/messages/messages_ca.properties b/themes/src/main/resources/theme/base/account/messages/messages_ca.properties index 4b148abe48..5820c4f873 100644 --- a/themes/src/main/resources/theme/base/account/messages/messages_ca.properties +++ b/themes/src/main/resources/theme/base/account/messages/messages_ca.properties @@ -5,7 +5,7 @@ doRemove=Elimina doAdd=Afegeix doSignOut=Desconnectar -editAccountHtmlTtile=Edita compte +editAccountHtmlTitle=Edita compte federatedIdentitiesHtmlTitle=Identitats federades accountLogHtmlTitle=Registre del compte changePasswordHtmlTitle=Canvia contrasenya diff --git a/themes/src/main/resources/theme/base/account/messages/messages_de.properties b/themes/src/main/resources/theme/base/account/messages/messages_de.properties index 20ea9cce9f..f9d27e99b5 100644 --- a/themes/src/main/resources/theme/base/account/messages/messages_de.properties +++ b/themes/src/main/resources/theme/base/account/messages/messages_de.properties @@ -5,7 +5,7 @@ doRemove=Entfernen doAdd=Hinzuf\u00FCgen doSignOut=Abmelden -editAccountHtmlTtile=Benutzerkonto Bearbeiten +editAccountHtmlTitle=Benutzerkonto Bearbeiten federatedIdentitiesHtmlTitle=Federated Identities accountLogHtmlTitle=Benutzerkonto Log changePasswordHtmlTitle=Passwort \u00C4ndern diff --git a/themes/src/main/resources/theme/base/account/messages/messages_en.properties b/themes/src/main/resources/theme/base/account/messages/messages_en.properties index 33225a5cbd..5c7ff812a1 100755 --- a/themes/src/main/resources/theme/base/account/messages/messages_en.properties +++ b/themes/src/main/resources/theme/base/account/messages/messages_en.properties @@ -5,7 +5,7 @@ doRemove=Remove doAdd=Add doSignOut=Sign Out -editAccountHtmlTtile=Edit Account +editAccountHtmlTitle=Edit Account federatedIdentitiesHtmlTitle=Federated Identities accountLogHtmlTitle=Account Log changePasswordHtmlTitle=Change Password diff --git a/themes/src/main/resources/theme/base/account/messages/messages_es.properties b/themes/src/main/resources/theme/base/account/messages/messages_es.properties index ce04c52b63..24dfa1a39c 100644 --- a/themes/src/main/resources/theme/base/account/messages/messages_es.properties +++ b/themes/src/main/resources/theme/base/account/messages/messages_es.properties @@ -5,7 +5,7 @@ doRemove=Eliminar doAdd=A\u00F1adir doSignOut=Desconectar -editAccountHtmlTtile=Editar cuenta +editAccountHtmlTitle=Editar cuenta federatedIdentitiesHtmlTitle=Identidades federadas accountLogHtmlTitle=Registro de la cuenta changePasswordHtmlTitle=Cambiar contrase\u00F1a diff --git a/themes/src/main/resources/theme/base/account/messages/messages_fr.properties b/themes/src/main/resources/theme/base/account/messages/messages_fr.properties index ccd3bcb074..34680a3134 100644 --- a/themes/src/main/resources/theme/base/account/messages/messages_fr.properties +++ b/themes/src/main/resources/theme/base/account/messages/messages_fr.properties @@ -8,7 +8,7 @@ doRemove=Supprimer doAdd=Ajouter doSignOut=D\u00e9connexion -editAccountHtmlTtile=Edition du compte +editAccountHtmlTitle=Edition du compte federatedIdentitiesHtmlTitle=Identit\u00e9s f\u00e9d\u00e9r\u00e9es accountLogHtmlTitle=Acc\u00e8s au compte changePasswordHtmlTitle=Changer de mot de passe diff --git a/themes/src/main/resources/theme/base/account/messages/messages_it.properties b/themes/src/main/resources/theme/base/account/messages/messages_it.properties index e14064f0ee..a7e2931145 100755 --- a/themes/src/main/resources/theme/base/account/messages/messages_it.properties +++ b/themes/src/main/resources/theme/base/account/messages/messages_it.properties @@ -5,7 +5,7 @@ doRemove=Elimina doAdd=Aggiungi doSignOut=Sign Out -editAccountHtmlTtile=Gestisci Account +editAccountHtmlTitle=Gestisci Account federatedIdentitiesHtmlTitle=Federated Identities accountLogHtmlTitle=Account Log changePasswordHtmlTitle=Cambia Password diff --git a/themes/src/main/resources/theme/base/account/messages/messages_pt_BR.properties b/themes/src/main/resources/theme/base/account/messages/messages_pt_BR.properties index 8b07e7bfc4..5c4c5b8817 100644 --- a/themes/src/main/resources/theme/base/account/messages/messages_pt_BR.properties +++ b/themes/src/main/resources/theme/base/account/messages/messages_pt_BR.properties @@ -5,7 +5,7 @@ doRemove=Remover doAdd=Adicionar doSignOut=Sair -editAccountHtmlTtile=Editar Conta +editAccountHtmlTitle=Editar Conta federatedIdentitiesHtmlTitle=Identidades Federadas accountLogHtmlTitle=Log da conta changePasswordHtmlTitle=Alterar senha diff --git a/themes/src/main/resources/theme/base/account/messages/messages_ru.properties b/themes/src/main/resources/theme/base/account/messages/messages_ru.properties index 8038b15781..b7d892a19b 100644 --- a/themes/src/main/resources/theme/base/account/messages/messages_ru.properties +++ b/themes/src/main/resources/theme/base/account/messages/messages_ru.properties @@ -5,7 +5,7 @@ doRemove=\u0423\u0434\u0430\u043B\u0438\u0442\u044C doAdd=\u0414\u043E\u0431\u0430\u0432\u0438\u0442\u044C doSignOut=\u0412\u044B\u0445\u043E\u0434 -editAccountHtmlTtile=\u0418\u0437\u043C\u0435\u043D\u0435\u043D\u0438\u0435 \u0443\u0447\u0435\u0442\u043D\u043E\u0439 \u0437\u0430\u043F\u0438\u0441\u0438 +editAccountHtmlTitle=\u0418\u0437\u043C\u0435\u043D\u0435\u043D\u0438\u0435 \u0443\u0447\u0435\u0442\u043D\u043E\u0439 \u0437\u0430\u043F\u0438\u0441\u0438 federatedIdentitiesHtmlTitle=\u0424\u0435\u0434\u0435\u0440\u0430\u0442\u0438\u0432\u043D\u044B\u0435 \u0438\u0434\u0435\u043D\u0442\u0438\u0444\u0438\u043A\u0430\u0442\u043E\u0440\u044B accountLogHtmlTitle=\u041B\u043E\u0433 \u0443\u0447\u0435\u0442\u043D\u043E\u0439 \u0437\u0430\u043F\u0438\u0441\u0438 changePasswordHtmlTitle=\u0421\u043C\u0435\u043D\u0430 \u043F\u0430\u0440\u043E\u043B\u044F From 79c7203fe86d16009e832b3ebe60914d52495d8f Mon Sep 17 00:00:00 2001 From: Thomas Darimont Date: Sat, 30 Jul 2016 16:09:54 +0200 Subject: [PATCH 3/8] KEYCLOAK-3380 Allow to configure paths to skip in KeycloakOIDCFilter We now allow configuration of path patterns which should not be handled by the `KeycloakOIDCFilter` than can be specified via the new init-parameter `keycloak.config.skipPattern` of the `KeycloakOIDCFilter`. Patterns are matched against the requestURI without the context-path. A request for `/myapp/index.html` would be matched with `/index.html` against the skip pattern. This allows for for more flexible path handling when using the `KeycloakOIDCFilter` in combination with existing applications. Signed-off-by: Thomas Darimont --- .../adapters/servlet/KeycloakOIDCFilter.java | 54 ++++++++++++++++--- 1 file changed, 47 insertions(+), 7 deletions(-) diff --git a/adapters/oidc/servlet-filter/src/main/java/org/keycloak/adapters/servlet/KeycloakOIDCFilter.java b/adapters/oidc/servlet-filter/src/main/java/org/keycloak/adapters/servlet/KeycloakOIDCFilter.java index dab75015a6..fc136167d1 100755 --- a/adapters/oidc/servlet-filter/src/main/java/org/keycloak/adapters/servlet/KeycloakOIDCFilter.java +++ b/adapters/oidc/servlet-filter/src/main/java/org/keycloak/adapters/servlet/KeycloakOIDCFilter.java @@ -47,6 +47,7 @@ import java.io.InputStream; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; +import java.util.regex.Pattern; /** * @author Bill Burke @@ -56,10 +57,18 @@ public class KeycloakOIDCFilter implements Filter { protected AdapterDeploymentContext deploymentContext; protected SessionIdMapper idMapper = new InMemorySessionIdMapper(); protected NodesRegistrationManagement nodesRegistrationManagement; + protected Pattern skipPattern; + private final static Logger log = Logger.getLogger(""+KeycloakOIDCFilter.class); @Override public void init(final FilterConfig filterConfig) throws ServletException { + + String skipPatternDefinition = filterConfig.getInitParameter("keycloak.config.skipPattern"); + if (skipPatternDefinition != null) { + skipPattern = Pattern.compile(skipPatternDefinition, Pattern.DOTALL); + } + String configResolverClass = filterConfig.getInitParameter("keycloak.config.resolver"); if (configResolverClass != null) { try { @@ -85,13 +94,7 @@ public class KeycloakOIDCFilter implements Filter { if (pathParam != null) path = pathParam; is = filterConfig.getServletContext().getResourceAsStream(path); } - KeycloakDeployment kd; - if (is == null) { - log.fine("No adapter configuration. Keycloak is unconfigured and will deny all requests."); - kd = new KeycloakDeployment(); - } else { - kd = KeycloakDeploymentBuilder.build(is); - } + KeycloakDeployment kd = createKeycloakDeploymentFrom(is); deploymentContext = new AdapterDeploymentContext(kd); log.fine("Keycloak is using a per-deployment configuration."); } @@ -99,13 +102,30 @@ public class KeycloakOIDCFilter implements Filter { nodesRegistrationManagement = new NodesRegistrationManagement(); } + private KeycloakDeployment createKeycloakDeploymentFrom(InputStream is) { + + if (is == null) { + log.fine("No adapter configuration. Keycloak is unconfigured and will deny all requests."); + return new KeycloakDeployment(); + } + + return KeycloakDeploymentBuilder.build(is); + } + @Override public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { + log.fine("Keycloak OIDC Filter"); //System.err.println("Keycloak OIDC Filter: " + ((HttpServletRequest)req).getRequestURL().toString()); HttpServletRequest request = (HttpServletRequest) req; HttpServletResponse response = (HttpServletResponse) res; + + if (shouldSkip(request)) { + chain.doFilter(req, res); + return; + } + OIDCServletHttpFacade facade = new OIDCServletHttpFacade(request, response); KeycloakDeployment deployment = deploymentContext.resolveDeployment(facade); if (deployment == null || !deployment.isConfigured()) { @@ -171,6 +191,26 @@ public class KeycloakOIDCFilter implements Filter { } + /** + * Decides whether this {@link Filter} should skip the given {@link HttpServletRequest} based on the configured {@link KeycloakOIDCFilter#skipPattern}. + * Patterns are matched against the {@link HttpServletRequest#getRequestURI() requestURI} of a request without the context-path. + * A request for {@code /myapp/index.html} would be tested with {@code /index.html} against the skip pattern. + * Skipped requests will not be processed further by {@link KeycloakOIDCFilter} and immediately delegated to the {@link FilterChain}. + * + * @param request the request to check + * @return {@code true} if the request should not be handled, + * {@code false} otherwise. + */ + private boolean shouldSkip(HttpServletRequest request) { + + if (skipPattern == null) { + return false; + } + + String requestPath = request.getRequestURI().substring(request.getContextPath().length()); + return skipPattern.matcher(requestPath).matches(); + } + @Override public void destroy() { From 57a96fa6aa71fc6204060bfaf7cb9e531d6a2730 Mon Sep 17 00:00:00 2001 From: Thomas Darimont Date: Tue, 2 Aug 2016 15:52:22 +0200 Subject: [PATCH 4/8] KEYCLOAK-3392 Use authUrl prefix for OIDC Configuration link We now use the {{authUrl}} prefix for the OIDC configuration link in the admin-console to honor different web-context paths. Previously when a different web-context than /auth was configured the generated link pointed to the wrong location. Signed-off-by: Thomas Darimont --- .../theme/base/admin/resources/partials/realm-detail.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/themes/src/main/resources/theme/base/admin/resources/partials/realm-detail.html b/themes/src/main/resources/theme/base/admin/resources/partials/realm-detail.html index ce1c61b36e..48fa3a2f7e 100755 --- a/themes/src/main/resources/theme/base/admin/resources/partials/realm-detail.html +++ b/themes/src/main/resources/theme/base/admin/resources/partials/realm-detail.html @@ -34,7 +34,7 @@
{{:: 'realm-detail.oidc-endpoints.tooltip' | translate}}
From 586f6eeeced1b2db8b0b9e1b36d92525bd9dc72e Mon Sep 17 00:00:00 2001 From: Thomas Darimont Date: Mon, 20 Jun 2016 13:32:54 +0200 Subject: [PATCH 5/8] KEYCLOAK-3142 - Capture ResourceType that triggers an AdminEvent Introduced new ResourceType enum for AdminEvents which lists the current supported ResourceTypes for which AdminEvents can be fired. Previously it was difficult for custom EventListeners to figure out which ResourceType triggered an AdminEvent in order to handle it appropriately, effectively forcing users to parse the representation. Having dedicated resource types as a marker on an AdminEvent helps to ease custom EventListener code. We now also allow filtering of admin events by ResourceType in the admin-console. Signed-off-by: Thomas Darimont --- .../idm/AdminEventRepresentation.java | 11 +- .../providers/events/MemAdminEventQuery.java | 22 +++ .../keycloak/events/jpa/AdminEventEntity.java | 14 ++ .../events/jpa/JpaAdminEventQuery.java | 15 +- .../events/jpa/JpaEventStoreProvider.java | 11 ++ .../META-INF/jpa-changelog-2.1.0.xml | 7 + .../events/mongo/MongoAdminEventQuery.java | 13 ++ .../org/keycloak/events/admin/AdminEvent.java | 17 ++ .../events/admin/AdminEventQuery.java | 8 +- .../keycloak/events/admin/ResourceType.java | 155 ++++++++++++++++++ .../models/utils/ModelToRepresentation.java | 3 + .../resources/admin/AdminEventBuilder.java | 10 +- .../admin/AttackDetectionResource.java | 3 +- .../AuthenticationManagementResource.java | 31 ++-- .../ClientAttributeCertificateResource.java | 3 +- .../admin/ClientInitialAccessResource.java | 3 +- .../resources/admin/ClientResource.java | 11 +- .../admin/ClientRoleMappingsResource.java | 3 +- .../admin/ClientTemplateResource.java | 3 +- .../admin/ClientTemplatesResource.java | 3 +- .../resources/admin/ClientsResource.java | 3 +- .../resources/admin/GroupResource.java | 3 +- .../resources/admin/GroupsResource.java | 3 +- .../admin/IdentityProviderResource.java | 9 +- .../admin/ProtocolMappersResource.java | 3 +- .../resources/admin/RealmAdminResource.java | 22 ++- .../resources/admin/RoleByIdResource.java | 15 ++ .../admin/RoleContainerResource.java | 20 +++ .../resources/admin/RoleMapperResource.java | 3 +- .../resources/admin/RoleResource.java | 13 ++ .../admin/ScopeMappedClientResource.java | 3 +- .../resources/admin/ScopeMappedResource.java | 3 +- .../admin/UserFederationProviderResource.java | 9 +- .../UserFederationProvidersResource.java | 3 +- .../resources/admin/UsersResource.java | 9 +- .../admin/info/ServerInfoAdminResource.java | 2 + .../admin/AttackDetectionResourceTest.java | 5 +- .../keycloak/testsuite/admin/ClientTest.java | 47 +++--- .../testsuite/admin/IdentityProviderTest.java | 13 +- .../admin/InitialAccessTokenResourceTest.java | 9 +- .../testsuite/admin/RoleByIdResourceTest.java | 9 +- .../admin/UserFederationMapperTest.java | 21 +-- .../testsuite/admin/UserFederationTest.java | 25 +-- .../keycloak/testsuite/admin/UserTest.java | 43 ++--- .../AbstractAuthenticationTest.java | 3 +- .../AuthenticatorConfigTest.java | 11 +- .../admin/authentication/ExecutionTest.java | 21 +-- .../admin/authentication/FlowTest.java | 11 +- .../authentication/RegistrationFlowTest.java | 5 +- .../authentication/RequiredActionsTest.java | 9 +- .../authentication/ShiftExecutionTest.java | 7 +- .../admin/client/AbstractClientTest.java | 5 +- .../client/AbstractProtocolMapperTest.java | 3 +- .../client/ClientProtocolMapperTest.java | 21 +-- .../admin/client/ClientRolesTest.java | 17 +- .../ClientTemplateProtocolMapperTest.java | 25 +-- .../admin/client/ClientTemplateTest.java | 23 +-- .../testsuite/admin/client/ClientTest.java | 7 +- .../admin/client/CredentialsTest.java | 7 +- .../testsuite/admin/client/SessionTest.java | 5 +- .../testsuite/admin/group/GroupTest.java | 53 +++--- .../testsuite/admin/realm/RealmRolesTest.java | 17 +- .../testsuite/admin/realm/RealmTest.java | 49 +++--- .../testsuite/util/AssertAdminEvents.java | 23 ++- .../messages/admin-messages_en.properties | 3 + .../admin/resources/js/controllers/realm.js | 13 +- .../partials/realm-events-admin.html | 16 +- 67 files changed, 702 insertions(+), 293 deletions(-) create mode 100644 server-spi/src/main/java/org/keycloak/events/admin/ResourceType.java diff --git a/core/src/main/java/org/keycloak/representations/idm/AdminEventRepresentation.java b/core/src/main/java/org/keycloak/representations/idm/AdminEventRepresentation.java index f615cbd032..9aa1e16f8f 100644 --- a/core/src/main/java/org/keycloak/representations/idm/AdminEventRepresentation.java +++ b/core/src/main/java/org/keycloak/representations/idm/AdminEventRepresentation.java @@ -18,7 +18,6 @@ package org.keycloak.representations.idm; /** - * * @author Stan Silvert ssilvert@redhat.com (C) 2016 Red Hat Inc. */ public class AdminEventRepresentation { @@ -27,6 +26,7 @@ public class AdminEventRepresentation { private String realmId; private AuthDetailsRepresentation authDetails; private String operationType; + private String resourceType; private String resourcePath; private String representation; private String error; @@ -63,6 +63,14 @@ public class AdminEventRepresentation { this.operationType = operationType; } + public String getResourceType() { + return resourceType; + } + + public void setResourceType(String resourceType) { + this.resourceType = resourceType; + } + public String getResourcePath() { return resourcePath; } @@ -86,5 +94,4 @@ public class AdminEventRepresentation { public void setError(String error) { this.error = error; } - } diff --git a/examples/providers/event-store-mem/src/main/java/org/keycloak/examples/providers/events/MemAdminEventQuery.java b/examples/providers/event-store-mem/src/main/java/org/keycloak/examples/providers/events/MemAdminEventQuery.java index bffc462e24..168c709ef1 100755 --- a/examples/providers/event-store-mem/src/main/java/org/keycloak/examples/providers/events/MemAdminEventQuery.java +++ b/examples/providers/event-store-mem/src/main/java/org/keycloak/examples/providers/events/MemAdminEventQuery.java @@ -26,6 +26,7 @@ import java.util.regex.Pattern; import org.keycloak.events.admin.AdminEvent; import org.keycloak.events.admin.AdminEventQuery; import org.keycloak.events.admin.OperationType; +import org.keycloak.events.admin.ResourceType; /** * @author Giriraj Sharma @@ -71,6 +72,27 @@ public class MemAdminEventQuery implements AdminEventQuery { } return this; } + + @Override + public AdminEventQuery resourceType(ResourceType... resourceTypes) { + + Iterator itr = this.adminEvents.iterator(); + while (itr.hasNext()) { + AdminEvent next = itr.next(); + boolean include = false; + for (ResourceType e : resourceTypes) { + if (next.getResourceType().equals(e)) { + include = true; + break; + } + } + if (!include) { + itr.remove(); + } + } + + return this; + } @Override public AdminEventQuery authRealm(String authRealmId) { diff --git a/model/jpa/src/main/java/org/keycloak/events/jpa/AdminEventEntity.java b/model/jpa/src/main/java/org/keycloak/events/jpa/AdminEventEntity.java index 6ecebf6164..e6cf93489e 100644 --- a/model/jpa/src/main/java/org/keycloak/events/jpa/AdminEventEntity.java +++ b/model/jpa/src/main/java/org/keycloak/events/jpa/AdminEventEntity.java @@ -17,8 +17,12 @@ package org.keycloak.events.jpa; +import org.keycloak.events.admin.ResourceType; + import javax.persistence.Column; import javax.persistence.Entity; +import javax.persistence.EnumType; +import javax.persistence.Enumerated; import javax.persistence.Id; import javax.persistence.Table; @@ -41,6 +45,9 @@ public class AdminEventEntity { @Column(name="OPERATION_TYPE") private String operationType; + + @Column(name="RESOURCE_TYPE", length = 64) + private String resourceType; @Column(name="AUTH_REALM_ID") private String authRealmId; @@ -151,4 +158,11 @@ public class AdminEventEntity { this.error = error; } + public String getResourceType() { + return resourceType; + } + + public void setResourceType(String resourceType) { + this.resourceType = resourceType; + } } diff --git a/model/jpa/src/main/java/org/keycloak/events/jpa/JpaAdminEventQuery.java b/model/jpa/src/main/java/org/keycloak/events/jpa/JpaAdminEventQuery.java index b26bef69fc..9cccd7d4d2 100755 --- a/model/jpa/src/main/java/org/keycloak/events/jpa/JpaAdminEventQuery.java +++ b/model/jpa/src/main/java/org/keycloak/events/jpa/JpaAdminEventQuery.java @@ -33,6 +33,7 @@ import javax.persistence.criteria.Root; import org.keycloak.events.admin.AdminEvent; import org.keycloak.events.admin.AdminEventQuery; import org.keycloak.events.admin.OperationType; +import org.keycloak.events.admin.ResourceType; /** * @author Giriraj Sharma @@ -71,7 +72,19 @@ public class JpaAdminEventQuery implements AdminEventQuery { predicates.add(root.get("operationType").in(operationStrings)); return this; } - + + @Override + public AdminEventQuery resourceType(ResourceType... resourceTypes) { + + List resourceTypeStrings = new LinkedList(); + for (ResourceType e : resourceTypes) { + resourceTypeStrings.add(e.toString()); + } + predicates.add(root.get("resourceType").in(resourceTypeStrings)); + + return this; + } + @Override public AdminEventQuery authRealm(String authRealmId) { predicates.add(cb.equal(root.get("authRealmId"), authRealmId)); diff --git a/model/jpa/src/main/java/org/keycloak/events/jpa/JpaEventStoreProvider.java b/model/jpa/src/main/java/org/keycloak/events/jpa/JpaEventStoreProvider.java index 017ba6cc5e..b86d83852c 100755 --- a/model/jpa/src/main/java/org/keycloak/events/jpa/JpaEventStoreProvider.java +++ b/model/jpa/src/main/java/org/keycloak/events/jpa/JpaEventStoreProvider.java @@ -28,6 +28,7 @@ import org.keycloak.events.Event; import org.keycloak.events.EventQuery; import org.keycloak.events.EventStoreProvider; import org.keycloak.events.EventType; +import org.keycloak.events.admin.ResourceType; import javax.persistence.EntityManager; @@ -150,6 +151,11 @@ public class JpaEventStoreProvider implements EventStoreProvider { adminEventEntity.setRealmId(adminEvent.getRealmId()); setAuthDetails(adminEventEntity, adminEvent.getAuthDetails()); adminEventEntity.setOperationType(adminEvent.getOperationType().toString()); + + if (adminEvent.getResourceType() != null) { + adminEventEntity.setResourceType(adminEvent.getResourceType().toString()); + } + adminEventEntity.setResourcePath(adminEvent.getResourcePath()); adminEventEntity.setError(adminEvent.getError()); @@ -165,6 +171,11 @@ public class JpaEventStoreProvider implements EventStoreProvider { adminEvent.setRealmId(adminEventEntity.getRealmId()); setAuthDetails(adminEvent, adminEventEntity); adminEvent.setOperationType(OperationType.valueOf(adminEventEntity.getOperationType())); + + if (adminEventEntity.getResourceType() != null) { + adminEvent.setResourceType(ResourceType.valueOf(adminEventEntity.getResourceType())); + } + adminEvent.setResourcePath(adminEventEntity.getResourcePath()); adminEvent.setError(adminEventEntity.getError()); diff --git a/model/jpa/src/main/resources/META-INF/jpa-changelog-2.1.0.xml b/model/jpa/src/main/resources/META-INF/jpa-changelog-2.1.0.xml index 1d118b285f..777a36e6d8 100755 --- a/model/jpa/src/main/resources/META-INF/jpa-changelog-2.1.0.xml +++ b/model/jpa/src/main/resources/META-INF/jpa-changelog-2.1.0.xml @@ -195,4 +195,11 @@ + + + + + + + \ No newline at end of file diff --git a/model/mongo/src/main/java/org/keycloak/events/mongo/MongoAdminEventQuery.java b/model/mongo/src/main/java/org/keycloak/events/mongo/MongoAdminEventQuery.java index b24db9eb7a..bf580823ee 100755 --- a/model/mongo/src/main/java/org/keycloak/events/mongo/MongoAdminEventQuery.java +++ b/model/mongo/src/main/java/org/keycloak/events/mongo/MongoAdminEventQuery.java @@ -29,6 +29,7 @@ import org.keycloak.events.admin.OperationType; import com.mongodb.BasicDBObject; import com.mongodb.DBCollection; import com.mongodb.DBCursor; +import org.keycloak.events.admin.ResourceType; public class MongoAdminEventQuery implements AdminEventQuery{ @@ -57,6 +58,18 @@ public class MongoAdminEventQuery implements AdminEventQuery{ query.put("operationType", new BasicDBObject("$in", operationStrings)); return this; } + + @Override + public AdminEventQuery resourceType(ResourceType... resourceTypes) { + + List resourceTypeStrings = new LinkedList(); + for (ResourceType e : resourceTypes) { + resourceTypeStrings.add(e.toString()); + } + query.put("resourceType", new BasicDBObject("$in", resourceTypeStrings)); + + return this; + } @Override public AdminEventQuery authRealm(String authRealmId) { diff --git a/server-spi/src/main/java/org/keycloak/events/admin/AdminEvent.java b/server-spi/src/main/java/org/keycloak/events/admin/AdminEvent.java index def6a2996d..24e070a133 100644 --- a/server-spi/src/main/java/org/keycloak/events/admin/AdminEvent.java +++ b/server-spi/src/main/java/org/keycloak/events/admin/AdminEvent.java @@ -28,6 +28,11 @@ public class AdminEvent { private AuthDetails authDetails; + /** + * The resource type an AdminEvent was triggered for. + */ + private ResourceType resourceType; + private OperationType operationType; private String resourcePath; @@ -133,4 +138,16 @@ public class AdminEvent { this.error = error; } + /** + * Returns the type of the affected {@link ResourceType} for this {@link AdminEvent}, e.g. {@link ResourceType#USER USER}, {@link ResourceType#GROUP GROUP} etc. + * + * @return + */ + public ResourceType getResourceType() { + return resourceType; + } + + public void setResourceType(ResourceType resourceType) { + this.resourceType = resourceType; + } } diff --git a/server-spi/src/main/java/org/keycloak/events/admin/AdminEventQuery.java b/server-spi/src/main/java/org/keycloak/events/admin/AdminEventQuery.java index d007171e34..8035a14c3b 100644 --- a/server-spi/src/main/java/org/keycloak/events/admin/AdminEventQuery.java +++ b/server-spi/src/main/java/org/keycloak/events/admin/AdminEventQuery.java @@ -73,6 +73,13 @@ public interface AdminEventQuery { */ AdminEventQuery operation(OperationType... operations); + /** + * Search by {@link ResourceType}. + * @param resourceTypes + * @return this for method chaining + */ + AdminEventQuery resourceType(ResourceType ... resourceTypes); + /** * Search by resource path. Supports wildcards * and **. For example: *
    @@ -124,5 +131,4 @@ public interface AdminEventQuery { * @return */ List getResultList(); - } diff --git a/server-spi/src/main/java/org/keycloak/events/admin/ResourceType.java b/server-spi/src/main/java/org/keycloak/events/admin/ResourceType.java new file mode 100644 index 0000000000..045258c08b --- /dev/null +++ b/server-spi/src/main/java/org/keycloak/events/admin/ResourceType.java @@ -0,0 +1,155 @@ +/* + * Copyright 2016 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.keycloak.events.admin; + +/** + * Represents Keycloak resource types for which {@link AdminEvent AdminEvent's} can be triggered. + * + * @author Thomas Darimont + */ +public enum ResourceType { + + /** + * + */ + REALM + + /** + * + */ + , REALM_ROLE + + /** + * + */ + , REALM_ROLE_MAPPING + + /** + * + */ + , REALM_SCOPE_MAPPING + + /** + * + */ + , AUTH_FLOW + + /** + * + */ + , AUTH_EXECUTION_FLOW + + /** + * + */ + , AUTH_EXECUTION + + /** + * + */ + , AUTHENTICATOR_CONFIG + + /** + * + */ + , REQUIRED_ACTION + + /** + * + */ + , IDENTITY_PROVIDER + + /** + * + */ + , IDENTITY_PROVIDER_MAPPER + + /** + * + */ + , PROTOCOL_MAPPER + + /** + * + */ + , USER + + /** + * + */ + , USER_LOGIN_FAILURE + + /** + * + */ + , USER_SESSION + + /** + * + */ + , USER_FEDERATION_PROVIDER + + /** + * + */ + , USER_FEDERATION_MAPPER + + /** + * + */ + , GROUP + + /** + * + */ + , GROUP_MEMBERSHIP + + /** + * + */ + , CLIENT + + /** + * + */ + , CLIENT_INITIAL_ACCESS_MODEL + + /** + * + */ + , CLIENT_ROLE + + /** + * + */ + , CLIENT_ROLE_MAPPING + + /** + * + */ + , CLIENT_TEMPLATE + + /** + * + */ + , CLIENT_SCOPE_MAPPING + + /** + * + */ + , CLUSTER_NODE; +} diff --git a/server-spi/src/main/java/org/keycloak/models/utils/ModelToRepresentation.java b/server-spi/src/main/java/org/keycloak/models/utils/ModelToRepresentation.java index f0c75b7fa9..5afeb65b9c 100755 --- a/server-spi/src/main/java/org/keycloak/models/utils/ModelToRepresentation.java +++ b/server-spi/src/main/java/org/keycloak/models/utils/ModelToRepresentation.java @@ -199,6 +199,9 @@ public class ModelToRepresentation { rep.setAuthDetails(toRepresentation(adminEvent.getAuthDetails())); } rep.setOperationType(adminEvent.getOperationType().toString()); + if (adminEvent.getResourceType() != null) { + rep.setResourceType(adminEvent.getResourceType().toString()); + } rep.setResourcePath(adminEvent.getResourcePath()); rep.setRepresentation(adminEvent.getRepresentation()); rep.setError(adminEvent.getError()); diff --git a/services/src/main/java/org/keycloak/services/resources/admin/AdminEventBuilder.java b/services/src/main/java/org/keycloak/services/resources/admin/AdminEventBuilder.java index 4a271b14b5..f72a3d9d73 100644 --- a/services/src/main/java/org/keycloak/services/resources/admin/AdminEventBuilder.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/AdminEventBuilder.java @@ -26,6 +26,7 @@ import org.keycloak.events.EventStoreProvider; import org.keycloak.events.admin.AdminEvent; import org.keycloak.events.admin.AuthDetails; import org.keycloak.events.admin.OperationType; +import org.keycloak.events.admin.ResourceType; import org.keycloak.models.ClientModel; import org.keycloak.models.KeycloakSession; import org.keycloak.models.RealmModel; @@ -86,8 +87,13 @@ public class AdminEventBuilder { return this; } - public AdminEventBuilder operation(OperationType e) { - adminEvent.setOperationType(e); + public AdminEventBuilder operation(OperationType operationType) { + adminEvent.setOperationType(operationType); + return this; + } + + public AdminEventBuilder resource(ResourceType resourceType){ + adminEvent.setResourceType(resourceType); return this; } diff --git a/services/src/main/java/org/keycloak/services/resources/admin/AttackDetectionResource.java b/services/src/main/java/org/keycloak/services/resources/admin/AttackDetectionResource.java index 18b6d43eb1..bf9252408c 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/AttackDetectionResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/AttackDetectionResource.java @@ -19,6 +19,7 @@ package org.keycloak.services.resources.admin; import org.jboss.resteasy.annotations.cache.NoCache; import org.keycloak.common.ClientConnection; import org.keycloak.events.admin.OperationType; +import org.keycloak.events.admin.ResourceType; import org.keycloak.models.KeycloakSession; import org.keycloak.models.RealmModel; import org.keycloak.models.UserModel; @@ -65,7 +66,7 @@ public class AttackDetectionResource { public AttackDetectionResource(RealmAuth auth, RealmModel realm, AdminEventBuilder adminEvent) { this.auth = auth; this.realm = realm; - this.adminEvent = adminEvent.realm(realm); + this.adminEvent = adminEvent.realm(realm).resource(ResourceType.USER_LOGIN_FAILURE); auth.init(RealmAuth.Resource.USER); } diff --git a/services/src/main/java/org/keycloak/services/resources/admin/AuthenticationManagementResource.java b/services/src/main/java/org/keycloak/services/resources/admin/AuthenticationManagementResource.java index 82e65fb623..4e1d7a4399 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/AuthenticationManagementResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/AuthenticationManagementResource.java @@ -29,6 +29,7 @@ import org.keycloak.authentication.FormAuthenticator; import org.keycloak.authentication.RequiredActionFactory; import org.keycloak.authentication.RequiredActionProvider; import org.keycloak.events.admin.OperationType; +import org.keycloak.events.admin.ResourceType; import org.keycloak.models.AuthenticationExecutionModel; import org.keycloak.models.AuthenticationFlowModel; import org.keycloak.models.AuthenticatorConfigModel; @@ -89,7 +90,7 @@ public class AuthenticationManagementResource { this.session = session; this.auth = auth; this.auth.init(RealmAuth.Resource.REALM); - this.adminEvent = adminEvent; + this.adminEvent = adminEvent.resource(ResourceType.AUTH_FLOW); } /** @@ -375,7 +376,7 @@ public class AuthenticationManagementResource { execution = realm.addAuthenticatorExecution(execution); data.put("id", execution.getId()); - adminEvent.operation(OperationType.CREATE).resourcePath(uriInfo).representation(data).success(); + adminEvent.operation(OperationType.CREATE).resource(ResourceType.AUTH_EXECUTION_FLOW).resourcePath(uriInfo).representation(data).success(); } private int getNextPriority(AuthenticationFlowModel parentFlow) { @@ -428,7 +429,7 @@ public class AuthenticationManagementResource { execution = realm.addAuthenticatorExecution(execution); data.put("id", execution.getId()); - adminEvent.operation(OperationType.CREATE).resourcePath(uriInfo).representation(data).success(); + adminEvent.operation(OperationType.CREATE).resource(ResourceType.AUTH_EXECUTION).resourcePath(uriInfo).representation(data).success(); } /** @@ -543,7 +544,7 @@ public class AuthenticationManagementResource { if (!model.getRequirement().name().equals(rep.getRequirement())) { model.setRequirement(AuthenticationExecutionModel.Requirement.valueOf(rep.getRequirement())); realm.updateAuthenticatorExecution(model); - adminEvent.operation(OperationType.UPDATE).resourcePath(uriInfo).representation(rep).success(); + adminEvent.operation(OperationType.UPDATE).resource(ResourceType.AUTH_EXECUTION).resourcePath(uriInfo).representation(rep).success(); } } @@ -567,7 +568,7 @@ public class AuthenticationManagementResource { model.setPriority(getNextPriority(parentFlow)); model = realm.addAuthenticatorExecution(model); - adminEvent.operation(OperationType.CREATE).resourcePath(uriInfo, model.getId()).representation(execution).success(); + adminEvent.operation(OperationType.CREATE).resource(ResourceType.AUTH_EXECUTION).resourcePath(uriInfo, model.getId()).representation(execution).success(); return Response.created(uriInfo.getAbsolutePathBuilder().path(model.getId()).build()).build(); } @@ -620,7 +621,7 @@ public class AuthenticationManagementResource { model.setPriority(tmp); realm.updateAuthenticatorExecution(model); - adminEvent.operation(OperationType.UPDATE).resourcePath(uriInfo).success(); + adminEvent.operation(OperationType.UPDATE).resource(ResourceType.AUTH_EXECUTION).resourcePath(uriInfo).success(); } public List getSortedExecutions(AuthenticationFlowModel parentFlow) { @@ -665,7 +666,7 @@ public class AuthenticationManagementResource { next.setPriority(tmp); realm.updateAuthenticatorExecution(next); - adminEvent.operation(OperationType.UPDATE).resourcePath(uriInfo).success(); + adminEvent.operation(OperationType.UPDATE).resource(ResourceType.AUTH_EXECUTION).resourcePath(uriInfo).success(); } @@ -698,7 +699,7 @@ public class AuthenticationManagementResource { realm.removeAuthenticatorExecution(model); - adminEvent.operation(OperationType.DELETE).resourcePath(uriInfo).success(); + adminEvent.operation(OperationType.DELETE).resource(ResourceType.AUTH_EXECUTION).resourcePath(uriInfo).success(); } @@ -728,7 +729,7 @@ public class AuthenticationManagementResource { realm.updateAuthenticatorExecution(model); json.setId(config.getId()); - adminEvent.operation(OperationType.CREATE).resourcePath(uriInfo).representation(json).success(); + adminEvent.operation(OperationType.CREATE).resource(ResourceType.AUTH_EXECUTION).resourcePath(uriInfo).representation(json).success(); return Response.created(uriInfo.getAbsolutePathBuilder().path(config.getId()).build()).build(); } @@ -811,7 +812,7 @@ public class AuthenticationManagementResource { requiredAction = realm.addRequiredActionProvider(requiredAction); data.put("id", requiredAction.getId()); - adminEvent.operation(OperationType.CREATE).resourcePath(uriInfo).representation(data).success(); + adminEvent.operation(OperationType.CREATE).resource(ResourceType.REQUIRED_ACTION).resourcePath(uriInfo).representation(data).success(); } @@ -890,7 +891,7 @@ public class AuthenticationManagementResource { update.setConfig(rep.getConfig()); realm.updateRequiredActionProvider(update); - adminEvent.operation(OperationType.UPDATE).resourcePath(uriInfo).representation(rep).success(); + adminEvent.operation(OperationType.UPDATE).resource(ResourceType.REQUIRED_ACTION).resourcePath(uriInfo).representation(rep).success(); } /** @@ -908,7 +909,7 @@ public class AuthenticationManagementResource { } realm.removeRequiredActionProvider(model); - adminEvent.operation(OperationType.DELETE).resourcePath(uriInfo).success(); + adminEvent.operation(OperationType.DELETE).resource(ResourceType.REQUIRED_ACTION).resourcePath(uriInfo).success(); } /** @@ -990,7 +991,7 @@ public class AuthenticationManagementResource { auth.requireManage(); AuthenticatorConfigModel config = realm.addAuthenticatorConfig(RepresentationToModel.toModel(rep)); - adminEvent.operation(OperationType.CREATE).resourcePath(uriInfo, config.getId()).representation(rep).success(); + adminEvent.operation(OperationType.CREATE).resource(ResourceType.AUTHENTICATOR_CONFIG).resourcePath(uriInfo, config.getId()).representation(rep).success(); return Response.created(uriInfo.getAbsolutePathBuilder().path(config.getId()).build()).build(); } @@ -1040,7 +1041,7 @@ public class AuthenticationManagementResource { realm.removeAuthenticatorConfig(config); - adminEvent.operation(OperationType.DELETE).resourcePath(uriInfo).success(); + adminEvent.operation(OperationType.DELETE).resource(ResourceType.AUTHENTICATOR_CONFIG).resourcePath(uriInfo).success(); } /** @@ -1063,6 +1064,6 @@ public class AuthenticationManagementResource { exists.setAlias(rep.getAlias()); exists.setConfig(rep.getConfig()); realm.updateAuthenticatorConfig(exists); - adminEvent.operation(OperationType.UPDATE).resourcePath(uriInfo).representation(rep).success(); + adminEvent.operation(OperationType.UPDATE).resource(ResourceType.AUTHENTICATOR_CONFIG).resourcePath(uriInfo).representation(rep).success(); } } \ No newline at end of file diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ClientAttributeCertificateResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ClientAttributeCertificateResource.java index 4f41596a1c..af0367a80d 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/ClientAttributeCertificateResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/ClientAttributeCertificateResource.java @@ -24,6 +24,7 @@ import org.jboss.resteasy.spi.NotAcceptableException; import org.jboss.resteasy.spi.NotFoundException; import org.keycloak.common.util.StreamUtil; import org.keycloak.events.admin.OperationType; +import org.keycloak.events.admin.ResourceType; import org.keycloak.models.ClientModel; import org.keycloak.models.KeycloakSession; import org.keycloak.models.RealmModel; @@ -79,7 +80,7 @@ public class ClientAttributeCertificateResource { this.attributePrefix = attributePrefix; this.privateAttribute = attributePrefix + "." + PRIVATE_KEY; this.certificateAttribute = attributePrefix + "." + X509CERTIFICATE; - this.adminEvent = adminEvent; + this.adminEvent = adminEvent.resource(ResourceType.CLIENT); } /** diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ClientInitialAccessResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ClientInitialAccessResource.java index de4d49b8dc..696af1851f 100644 --- a/services/src/main/java/org/keycloak/services/resources/admin/ClientInitialAccessResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/ClientInitialAccessResource.java @@ -18,6 +18,7 @@ package org.keycloak.services.resources.admin; import org.keycloak.events.admin.OperationType; +import org.keycloak.events.admin.ResourceType; import org.keycloak.models.ClientInitialAccessModel; import org.keycloak.models.KeycloakSession; import org.keycloak.models.RealmModel; @@ -49,7 +50,7 @@ public class ClientInitialAccessResource { public ClientInitialAccessResource(RealmModel realm, RealmAuth auth, AdminEventBuilder adminEvent) { this.auth = auth; this.realm = realm; - this.adminEvent = adminEvent; + this.adminEvent = adminEvent.resource(ResourceType.CLIENT_INITIAL_ACCESS_MODEL); auth.init(RealmAuth.Resource.CLIENT); } 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 94d4821504..fc5b3c9e93 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 @@ -22,6 +22,7 @@ import org.jboss.resteasy.spi.NotFoundException; import org.jboss.resteasy.spi.ResteasyProviderFactory; import org.keycloak.authorization.admin.AuthorizationService; import org.keycloak.events.admin.OperationType; +import org.keycloak.events.admin.ResourceType; import org.keycloak.models.ClientModel; import org.keycloak.models.ClientSessionModel; import org.keycloak.models.KeycloakSession; @@ -99,7 +100,7 @@ public class ClientResource { this.auth = auth; this.client = clientModel; this.session = session; - this.adminEvent = adminEvent; + this.adminEvent = adminEvent.resource(ResourceType.CLIENT); auth.init(RealmAuth.Resource.CLIENT); } @@ -343,7 +344,7 @@ public class ClientResource { throw new NotFoundException("Could not find client"); } - adminEvent.operation(OperationType.ACTION).resourcePath(uriInfo).success(); + adminEvent.operation(OperationType.ACTION).resourcePath(uriInfo).resource(ResourceType.CLIENT).success(); return new ResourceAdminManager(session).pushClientRevocationPolicy(uriInfo.getRequestUri(), realm, client); } @@ -496,7 +497,7 @@ public class ClientResource { } if (logger.isDebugEnabled()) logger.debug("Register node: " + node); client.registerNode(node, Time.currentTime()); - adminEvent.operation(OperationType.CREATE).resourcePath(uriInfo, node).success(); + adminEvent.operation(OperationType.CREATE).resource(ResourceType.CLUSTER_NODE).resourcePath(uriInfo, node).success(); } /** @@ -521,7 +522,7 @@ public class ClientResource { throw new NotFoundException("Client does not have node "); } client.unregisterNode(node); - adminEvent.operation(OperationType.DELETE).resourcePath(uriInfo).success(); + adminEvent.operation(OperationType.DELETE).resource(ResourceType.CLUSTER_NODE).resourcePath(uriInfo).success(); } /** @@ -544,7 +545,7 @@ public class ClientResource { logger.debug("Test availability of cluster nodes"); GlobalRequestResult result = new ResourceAdminManager(session).testNodesAvailability(uriInfo.getRequestUri(), realm, client); - adminEvent.operation(OperationType.ACTION).resourcePath(uriInfo).representation(result).success(); + adminEvent.operation(OperationType.ACTION).resource(ResourceType.CLUSTER_NODE).resourcePath(uriInfo).representation(result).success(); return result; } diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ClientRoleMappingsResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ClientRoleMappingsResource.java index a1c0433201..11fe9ef3ac 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/ClientRoleMappingsResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/ClientRoleMappingsResource.java @@ -19,6 +19,7 @@ package org.keycloak.services.resources.admin; import org.jboss.resteasy.annotations.cache.NoCache; import org.jboss.resteasy.spi.NotFoundException; import org.keycloak.events.admin.OperationType; +import org.keycloak.events.admin.ResourceType; import org.keycloak.models.ClientModel; import org.keycloak.models.KeycloakSession; import org.keycloak.models.ModelException; @@ -70,7 +71,7 @@ public class ClientRoleMappingsResource { this.auth = auth; this.user = user; this.client = client; - this.adminEvent = adminEvent; + this.adminEvent = adminEvent.resource(ResourceType.CLIENT_ROLE_MAPPING); } /** diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ClientTemplateResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ClientTemplateResource.java index 94e2382377..baf9bb65f3 100644 --- a/services/src/main/java/org/keycloak/services/resources/admin/ClientTemplateResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/ClientTemplateResource.java @@ -20,6 +20,7 @@ import org.jboss.resteasy.annotations.cache.NoCache; import org.jboss.resteasy.spi.NotFoundException; import org.jboss.resteasy.spi.ResteasyProviderFactory; import org.keycloak.events.admin.OperationType; +import org.keycloak.events.admin.ResourceType; import org.keycloak.models.ClientTemplateModel; import org.keycloak.models.KeycloakSession; import org.keycloak.models.ModelDuplicateException; @@ -73,7 +74,7 @@ public class ClientTemplateResource { this.auth = auth; this.template = template; this.session = session; - this.adminEvent = adminEvent; + this.adminEvent = adminEvent.resource(ResourceType.CLIENT_TEMPLATE); auth.init(RealmAuth.Resource.CLIENT); } diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ClientTemplatesResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ClientTemplatesResource.java index 6015a3e212..46bcb5593a 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/ClientTemplatesResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/ClientTemplatesResource.java @@ -20,6 +20,7 @@ import org.jboss.resteasy.annotations.cache.NoCache; import org.jboss.resteasy.spi.NotFoundException; import org.jboss.resteasy.spi.ResteasyProviderFactory; import org.keycloak.events.admin.OperationType; +import org.keycloak.events.admin.ResourceType; import org.keycloak.models.ClientTemplateModel; import org.keycloak.models.KeycloakSession; import org.keycloak.models.ModelDuplicateException; @@ -61,7 +62,7 @@ public class ClientTemplatesResource { public ClientTemplatesResource(RealmModel realm, RealmAuth auth, AdminEventBuilder adminEvent) { this.realm = realm; this.auth = auth; - this.adminEvent = adminEvent; + this.adminEvent = adminEvent.resource(ResourceType.CLIENT_TEMPLATE); auth.init(RealmAuth.Resource.CLIENT); } 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 8690862fae..207f8d1fb5 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 @@ -20,6 +20,7 @@ import org.jboss.resteasy.annotations.cache.NoCache; import org.jboss.resteasy.spi.NotFoundException; import org.jboss.resteasy.spi.ResteasyProviderFactory; import org.keycloak.events.admin.OperationType; +import org.keycloak.events.admin.ResourceType; import org.keycloak.models.ClientModel; import org.keycloak.models.KeycloakSession; import org.keycloak.models.ModelDuplicateException; @@ -63,7 +64,7 @@ public class ClientsResource { public ClientsResource(RealmModel realm, RealmAuth auth, AdminEventBuilder adminEvent) { this.realm = realm; this.auth = auth; - this.adminEvent = adminEvent; + this.adminEvent = adminEvent.resource(ResourceType.CLIENT); auth.init(RealmAuth.Resource.CLIENT); } diff --git a/services/src/main/java/org/keycloak/services/resources/admin/GroupResource.java b/services/src/main/java/org/keycloak/services/resources/admin/GroupResource.java index a22002c4cd..e3cc87fb8b 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/GroupResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/GroupResource.java @@ -20,6 +20,7 @@ import org.jboss.resteasy.annotations.cache.NoCache; import org.jboss.resteasy.spi.NotFoundException; import org.jboss.resteasy.spi.ResteasyProviderFactory; import org.keycloak.events.admin.OperationType; +import org.keycloak.events.admin.ResourceType; import org.keycloak.models.GroupModel; import org.keycloak.models.KeycloakSession; import org.keycloak.models.RealmModel; @@ -62,7 +63,7 @@ public class GroupResource { this.realm = realm; this.session = session; this.auth = auth; - this.adminEvent = adminEvent; + this.adminEvent = adminEvent.resource(ResourceType.GROUP); this.group = group; } diff --git a/services/src/main/java/org/keycloak/services/resources/admin/GroupsResource.java b/services/src/main/java/org/keycloak/services/resources/admin/GroupsResource.java index 7b164a57d4..f670f57413 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/GroupsResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/GroupsResource.java @@ -20,6 +20,7 @@ import org.jboss.resteasy.annotations.cache.NoCache; import org.jboss.resteasy.spi.NotFoundException; import org.jboss.resteasy.spi.ResteasyProviderFactory; import org.keycloak.events.admin.OperationType; +import org.keycloak.events.admin.ResourceType; import org.keycloak.models.GroupModel; import org.keycloak.models.KeycloakSession; import org.keycloak.models.RealmModel; @@ -53,7 +54,7 @@ public class GroupsResource { this.realm = realm; this.session = session; this.auth = auth; - this.adminEvent = adminEvent; + this.adminEvent = adminEvent.resource(ResourceType.GROUP); auth.init(RealmAuth.Resource.USER); } 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 a664b75d16..d92bd46bf0 100644 --- a/services/src/main/java/org/keycloak/services/resources/admin/IdentityProviderResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/IdentityProviderResource.java @@ -22,6 +22,7 @@ import org.keycloak.broker.provider.IdentityProvider; import org.keycloak.broker.provider.IdentityProviderFactory; import org.keycloak.broker.provider.IdentityProviderMapper; import org.keycloak.events.admin.OperationType; +import org.keycloak.events.admin.ResourceType; import org.keycloak.models.FederatedIdentityModel; import org.keycloak.models.IdentityProviderMapperModel; import org.keycloak.models.IdentityProviderModel; @@ -82,7 +83,7 @@ public class IdentityProviderResource { this.session = session; this.identityProviderModel = identityProviderModel; this.auth = auth; - this.adminEvent = adminEvent; + this.adminEvent = adminEvent.resource(ResourceType.IDENTITY_PROVIDER); } /** @@ -317,7 +318,7 @@ public class IdentityProviderResource { IdentityProviderMapperModel model = RepresentationToModel.toModel(mapper); model = realm.addIdentityProviderMapper(model); - adminEvent.operation(OperationType.CREATE).resourcePath(uriInfo, model.getId()) + adminEvent.operation(OperationType.CREATE).resource(ResourceType.IDENTITY_PROVIDER_MAPPER).resourcePath(uriInfo, model.getId()) .representation(mapper).success(); return Response.created(uriInfo.getAbsolutePathBuilder().path(model.getId()).build()).build(); @@ -367,7 +368,7 @@ public class IdentityProviderResource { if (model == null) throw new NotFoundException("Model not found"); model = RepresentationToModel.toModel(rep); realm.updateIdentityProviderMapper(model); - adminEvent.operation(OperationType.UPDATE).resourcePath(uriInfo).representation(rep).success(); + adminEvent.operation(OperationType.UPDATE).resource(ResourceType.IDENTITY_PROVIDER_MAPPER).resourcePath(uriInfo).representation(rep).success(); } @@ -389,7 +390,7 @@ public class IdentityProviderResource { IdentityProviderMapperModel model = realm.getIdentityProviderMapperById(id); if (model == null) throw new NotFoundException("Model not found"); realm.removeIdentityProviderMapper(model); - adminEvent.operation(OperationType.DELETE).resourcePath(uriInfo).success(); + adminEvent.operation(OperationType.DELETE).resource(ResourceType.IDENTITY_PROVIDER_MAPPER).resourcePath(uriInfo).success(); } 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 bb3d325ea3..b9da2bf107 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 @@ package org.keycloak.services.resources.admin; import org.jboss.resteasy.annotations.cache.NoCache; import org.jboss.resteasy.spi.NotFoundException; import org.keycloak.events.admin.OperationType; +import org.keycloak.events.admin.ResourceType; import org.keycloak.models.KeycloakSession; import org.keycloak.models.ModelDuplicateException; import org.keycloak.models.ProtocolMapperContainerModel; @@ -70,7 +71,7 @@ public class ProtocolMappersResource { public ProtocolMappersResource(ProtocolMapperContainerModel client, RealmAuth auth, AdminEventBuilder adminEvent) { this.auth = auth; this.client = client; - this.adminEvent = adminEvent; + this.adminEvent = adminEvent.resource(ResourceType.PROTOCOL_MAPPER); auth.init(Resource.CLIENT); } 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 b58fbe54ba..22441ad5e6 100644 --- a/services/src/main/java/org/keycloak/services/resources/admin/RealmAdminResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/RealmAdminResource.java @@ -31,6 +31,7 @@ import org.keycloak.events.EventType; import org.keycloak.events.admin.AdminEvent; import org.keycloak.events.admin.AdminEventQuery; import org.keycloak.events.admin.OperationType; +import org.keycloak.events.admin.ResourceType; import org.keycloak.exportimport.ClientDescriptionConverter; import org.keycloak.exportimport.ClientDescriptionConverterFactory; import org.keycloak.jose.jws.JWSBuilder; @@ -127,7 +128,7 @@ public class RealmAdminResource { this.auth = auth; this.realm = realm; this.tokenManager = tokenManager; - this.adminEvent = adminEvent.realm(realm); + this.adminEvent = adminEvent.realm(realm).resource(ResourceType.REALM); auth.init(RealmAuth.Resource.REALM); auth.requireAny(); @@ -413,7 +414,7 @@ public class RealmAdminResource { UserSessionModel userSession = session.sessions().getUserSession(realm, sessionId); if (userSession == null) throw new NotFoundException("Sesssion not found"); AuthenticationManager.backchannelLogout(session, realm, userSession, uriInfo, connection, headers, true); - adminEvent.operation(OperationType.DELETE).resourcePath(uriInfo).success(); + adminEvent.operation(OperationType.DELETE).resource(ResourceType.USER_SESSION).resourcePath(uriInfo).success(); } @@ -600,7 +601,8 @@ public class RealmAdminResource { @QueryParam("authUser") String authUser, @QueryParam("authIpAddress") String authIpAddress, @QueryParam("resourcePath") String resourcePath, @QueryParam("dateFrom") String dateFrom, @QueryParam("dateTo") String dateTo, @QueryParam("first") Integer firstResult, - @QueryParam("max") Integer maxResults) { + @QueryParam("max") Integer maxResults, + @QueryParam("resourceTypes") List resourceTypes) { auth.init(RealmAuth.Resource.EVENTS).requireView(); EventStoreProvider eventStore = session.getProvider(EventStoreProvider.class); @@ -634,6 +636,16 @@ public class RealmAdminResource { query.operation(t); } + if (resourceTypes != null && !resourceTypes.isEmpty()) { + ResourceType[] t = new ResourceType[resourceTypes.size()]; + for (int i = 0; i < t.length; i++) { + t[i] = ResourceType.valueOf(resourceTypes.get(i)); + } + query.resourceType(t); + } + + + if(dateFrom != null) { SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd"); Date from = null; @@ -757,7 +769,7 @@ public class RealmAdminResource { } realm.addDefaultGroup(group); - adminEvent.operation(OperationType.CREATE).resourcePath(uriInfo).success(); + adminEvent.operation(OperationType.CREATE).resource(ResourceType.GROUP).resourcePath(uriInfo).success(); } @DELETE @@ -772,7 +784,7 @@ public class RealmAdminResource { } realm.removeDefaultGroup(group); - adminEvent.operation(OperationType.DELETE).resourcePath(uriInfo).success(); + adminEvent.operation(OperationType.DELETE).resource(ResourceType.GROUP).resourcePath(uriInfo).success(); } 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 99ec68a59c..8136db49d1 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 @@ package org.keycloak.services.resources.admin; import org.jboss.resteasy.annotations.cache.NoCache; import org.jboss.resteasy.spi.NotFoundException; import org.keycloak.events.admin.OperationType; +import org.keycloak.events.admin.ResourceType; import org.keycloak.models.ClientModel; import org.keycloak.models.KeycloakSession; import org.keycloak.models.RealmModel; @@ -116,6 +117,13 @@ public class RoleByIdResource extends RoleResource { RoleModel role = getRoleModel(id); deleteRole(role); + + if (role.isClientRole()) { + adminEvent.resource(ResourceType.CLIENT_ROLE); + } else { + adminEvent.resource(ResourceType.REALM_ROLE); + } + adminEvent.operation(OperationType.DELETE).resourcePath(uriInfo).success(); } @@ -133,6 +141,13 @@ public class RoleByIdResource extends RoleResource { RoleModel role = getRoleModel(id); updateRole(rep, role); + + if (role.isClientRole()) { + adminEvent.resource(ResourceType.CLIENT_ROLE); + } else { + adminEvent.resource(ResourceType.REALM_ROLE); + } + adminEvent.operation(OperationType.UPDATE).resourcePath(uriInfo).representation(rep).success(); } 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 e116ca3974..788921fac3 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 @@ package org.keycloak.services.resources.admin; import org.jboss.resteasy.annotations.cache.NoCache; import org.jboss.resteasy.spi.NotFoundException; import org.keycloak.events.admin.OperationType; +import org.keycloak.events.admin.ResourceType; import org.keycloak.models.ClientModel; import org.keycloak.models.ModelDuplicateException; import org.keycloak.models.RealmModel; @@ -116,6 +117,13 @@ public class RoleContainerResource extends RoleResource { role.setScopeParamRequired(scopeParamRequired); rep.setId(role.getId()); + + if (role.isClientRole()) { + adminEvent.resource(ResourceType.CLIENT_ROLE); + } else { + adminEvent.resource(ResourceType.REALM_ROLE); + } + adminEvent.operation(OperationType.CREATE).resourcePath(uriInfo, role.getName()).representation(rep).success(); return Response.created(uriInfo.getAbsolutePathBuilder().path(role.getName()).build()).build(); @@ -171,6 +179,12 @@ public class RoleContainerResource extends RoleResource { } deleteRole(role); + if (role.isClientRole()) { + adminEvent.resource(ResourceType.CLIENT_ROLE); + } else { + adminEvent.resource(ResourceType.REALM_ROLE); + } + adminEvent.operation(OperationType.DELETE).resourcePath(uriInfo).success(); } @@ -199,6 +213,12 @@ public class RoleContainerResource extends RoleResource { try { updateRole(rep, role); + if (role.isClientRole()) { + adminEvent.resource(ResourceType.CLIENT_ROLE); + } else { + adminEvent.resource(ResourceType.REALM_ROLE); + } + adminEvent.operation(OperationType.UPDATE).resourcePath(uriInfo).representation(rep).success(); return Response.noContent().build(); diff --git a/services/src/main/java/org/keycloak/services/resources/admin/RoleMapperResource.java b/services/src/main/java/org/keycloak/services/resources/admin/RoleMapperResource.java index 79ae4dca1c..ecaa4744df 100644 --- a/services/src/main/java/org/keycloak/services/resources/admin/RoleMapperResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/RoleMapperResource.java @@ -20,6 +20,7 @@ import org.jboss.resteasy.annotations.cache.NoCache; import org.jboss.resteasy.spi.NotFoundException; import org.keycloak.common.ClientConnection; import org.keycloak.events.admin.OperationType; +import org.keycloak.events.admin.ResourceType; import org.keycloak.models.ClientModel; import org.keycloak.models.KeycloakSession; import org.keycloak.models.ModelException; @@ -88,7 +89,7 @@ public class RoleMapperResource { public RoleMapperResource(RealmModel realm, RealmAuth auth, RoleMapperModel roleMapper, AdminEventBuilder adminEvent) { this.auth = auth; this.realm = realm; - this.adminEvent = adminEvent; + this.adminEvent = adminEvent.resource(ResourceType.REALM_ROLE_MAPPING); this.roleMapper = roleMapper; } 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 f05572e1e6..6e65c3346f 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 @@ -19,6 +19,7 @@ package org.keycloak.services.resources.admin; import org.jboss.resteasy.spi.NotFoundException; import org.keycloak.events.admin.OperationType; +import org.keycloak.events.admin.ResourceType; import org.keycloak.models.ClientModel; import org.keycloak.models.RealmModel; import org.keycloak.models.RoleModel; @@ -67,6 +68,12 @@ public abstract class RoleResource { role.addCompositeRole(composite); } + if (role.isClientRole()) { + adminEvent.resource(ResourceType.CLIENT_ROLE); + } else { + adminEvent.resource(ResourceType.REALM_ROLE); + } + adminEvent.operation(OperationType.CREATE).resourcePath(uriInfo).representation(roles).success(); } @@ -111,6 +118,12 @@ public abstract class RoleResource { role.removeCompositeRole(composite); } + if (role.isClientRole()) { + adminEvent.resource(ResourceType.CLIENT_ROLE); + } else { + adminEvent.resource(ResourceType.REALM_ROLE); + } + adminEvent.operation(OperationType.DELETE).resourcePath(uriInfo).representation(roles).success(); } } diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ScopeMappedClientResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ScopeMappedClientResource.java index eb685e4dd0..903c2cea59 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/ScopeMappedClientResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/ScopeMappedClientResource.java @@ -20,6 +20,7 @@ package org.keycloak.services.resources.admin; import org.jboss.resteasy.annotations.cache.NoCache; import org.jboss.resteasy.spi.NotFoundException; import org.keycloak.events.admin.OperationType; +import org.keycloak.events.admin.ResourceType; import org.keycloak.models.ClientModel; import org.keycloak.models.KeycloakSession; import org.keycloak.models.RealmModel; @@ -60,7 +61,7 @@ public class ScopeMappedClientResource { this.scopeContainer = scopeContainer; this.session = session; this.scopedClient = scopedClient; - this.adminEvent = adminEvent; + this.adminEvent = adminEvent.resource(ResourceType.CLIENT_SCOPE_MAPPING); } /** 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 bf3cb88fa7..e4fe22fb4c 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 @@ -20,6 +20,7 @@ package org.keycloak.services.resources.admin; import org.jboss.resteasy.annotations.cache.NoCache; import org.jboss.resteasy.spi.NotFoundException; import org.keycloak.events.admin.OperationType; +import org.keycloak.events.admin.ResourceType; import org.keycloak.models.ClientModel; import org.keycloak.models.KeycloakSession; import org.keycloak.models.RealmModel; @@ -65,7 +66,7 @@ public class ScopeMappedResource { this.auth = auth; this.scopeContainer = scopeContainer; this.session = session; - this.adminEvent = adminEvent; + this.adminEvent = adminEvent.resource(ResourceType.REALM_SCOPE_MAPPING); } /** diff --git a/services/src/main/java/org/keycloak/services/resources/admin/UserFederationProviderResource.java b/services/src/main/java/org/keycloak/services/resources/admin/UserFederationProviderResource.java index c8cf4fd5e9..dca3829fb0 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/UserFederationProviderResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/UserFederationProviderResource.java @@ -42,6 +42,7 @@ import javax.ws.rs.core.UriInfo; import org.jboss.resteasy.annotations.cache.NoCache; import org.jboss.resteasy.spi.NotFoundException; import org.keycloak.events.admin.OperationType; +import org.keycloak.events.admin.ResourceType; import org.keycloak.mappers.FederationConfigValidationException; import org.keycloak.mappers.UserFederationMapper; import org.keycloak.mappers.UserFederationMapperFactory; @@ -87,7 +88,7 @@ public class UserFederationProviderResource { this.realm = realm; this.auth = auth; this.federationProviderModel = federationProviderModel; - this.adminEvent = adminEvent; + this.adminEvent = adminEvent.resource(ResourceType.USER_FEDERATION_PROVIDER); } /** @@ -311,7 +312,7 @@ public class UserFederationProviderResource { model = realm.addUserFederationMapper(model); - adminEvent.operation(OperationType.CREATE).resourcePath(uriInfo, model.getId()) + adminEvent.operation(OperationType.CREATE).resource(ResourceType.USER_FEDERATION_MAPPER).resourcePath(uriInfo, model.getId()) .representation(mapper).success(); return Response.created(uriInfo.getAbsolutePathBuilder().path(model.getId()).build()).build(); @@ -364,7 +365,7 @@ public class UserFederationProviderResource { validateModel(model); realm.updateUserFederationMapper(model); - adminEvent.operation(OperationType.UPDATE).resourcePath(uriInfo).representation(rep).success(); + adminEvent.operation(OperationType.UPDATE).resource(ResourceType.USER_FEDERATION_MAPPER).resourcePath(uriInfo).representation(rep).success(); } @@ -386,7 +387,7 @@ public class UserFederationProviderResource { UserFederationMapperModel model = realm.getUserFederationMapperById(id); if (model == null) throw new NotFoundException("Model not found"); realm.removeUserFederationMapper(model); - adminEvent.operation(OperationType.DELETE).resourcePath(uriInfo).success(); + adminEvent.operation(OperationType.DELETE).resource(ResourceType.USER_FEDERATION_MAPPER).resourcePath(uriInfo).success(); } diff --git a/services/src/main/java/org/keycloak/services/resources/admin/UserFederationProvidersResource.java b/services/src/main/java/org/keycloak/services/resources/admin/UserFederationProvidersResource.java index 3afa1e99af..b782462121 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/UserFederationProvidersResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/UserFederationProvidersResource.java @@ -21,6 +21,7 @@ import org.jboss.resteasy.spi.NotFoundException; import org.jboss.resteasy.spi.ResteasyProviderFactory; import org.keycloak.common.constants.KerberosConstants; import org.keycloak.events.admin.OperationType; +import org.keycloak.events.admin.ResourceType; import org.keycloak.mappers.FederationConfigValidationException; import org.keycloak.models.AuthenticationExecutionModel; import org.keycloak.models.KeycloakSession; @@ -84,7 +85,7 @@ public class UserFederationProvidersResource { public UserFederationProvidersResource(RealmModel realm, RealmAuth auth, AdminEventBuilder adminEvent) { this.auth = auth; this.realm = realm; - this.adminEvent = adminEvent; + this.adminEvent = adminEvent.resource(ResourceType.USER_FEDERATION_PROVIDER); auth.init(RealmAuth.Resource.USER); } 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 367217c9a1..3986988f87 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 @@ -28,6 +28,7 @@ import org.keycloak.events.Details; import org.keycloak.events.EventBuilder; import org.keycloak.events.EventType; import org.keycloak.events.admin.OperationType; +import org.keycloak.events.admin.ResourceType; import org.keycloak.models.ClientModel; import org.keycloak.models.ClientSessionModel; import org.keycloak.models.Constants; @@ -99,6 +100,8 @@ import org.keycloak.services.resources.AccountService; import org.keycloak.common.util.Time; import org.keycloak.services.validation.Validation; +import static org.keycloak.events.admin.ResourceType.GROUP_MEMBERSHIP; + /** * Base resource for managing users * @@ -129,7 +132,7 @@ public class UsersResource { public UsersResource(RealmModel realm, RealmAuth auth, AdminEventBuilder adminEvent) { this.auth = auth; this.realm = realm; - this.adminEvent = adminEvent; + this.adminEvent = adminEvent.resource(ResourceType.USER); auth.init(RealmAuth.Resource.USER); } @@ -961,7 +964,7 @@ public class UsersResource { try { if (user.isMemberOf(group)){ user.leaveGroup(group); - adminEvent.operation(OperationType.DELETE).representation(ModelToRepresentation.toRepresentation(group, true)).resourcePath(uriInfo).success(); + adminEvent.operation(OperationType.DELETE).resource(ResourceType.GROUP_MEMBERSHIP).representation(ModelToRepresentation.toRepresentation(group, true)).resourcePath(uriInfo).success(); } } catch (ModelException me) { Properties messages = AdminRoot.getMessages(session, realm, auth.getAuth().getToken().getLocale()); @@ -986,7 +989,7 @@ public class UsersResource { } if (!user.isMemberOf(group)){ user.joinGroup(group); - adminEvent.operation(OperationType.CREATE).representation(ModelToRepresentation.toRepresentation(group, true)).resourcePath(uriInfo).success(); + adminEvent.operation(OperationType.CREATE).resource(ResourceType.GROUP_MEMBERSHIP).representation(ModelToRepresentation.toRepresentation(group, true)).resourcePath(uriInfo).success(); } } diff --git a/services/src/main/java/org/keycloak/services/resources/admin/info/ServerInfoAdminResource.java b/services/src/main/java/org/keycloak/services/resources/admin/info/ServerInfoAdminResource.java index e1c2363efe..d4312c8d44 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/info/ServerInfoAdminResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/info/ServerInfoAdminResource.java @@ -25,6 +25,7 @@ import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; +import java.util.ServiceLoader; import javax.ws.rs.GET; import javax.ws.rs.WebApplicationException; @@ -35,6 +36,7 @@ import org.keycloak.broker.provider.IdentityProviderFactory; import org.keycloak.common.util.MultivaluedHashMap; import org.keycloak.events.EventType; import org.keycloak.events.admin.OperationType; +import org.keycloak.models.PasswordPolicy; import org.keycloak.policy.PasswordPolicyProvider; import org.keycloak.policy.PasswordPolicyProviderFactory; import org.keycloak.provider.*; diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/AttackDetectionResourceTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/AttackDetectionResourceTest.java index 008919294f..edcaecbb86 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/AttackDetectionResourceTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/AttackDetectionResourceTest.java @@ -21,6 +21,7 @@ import org.jboss.arquillian.test.api.ArquillianResource; import org.junit.Test; import org.keycloak.admin.client.resource.AttackDetectionResource; import org.keycloak.events.admin.OperationType; +import org.keycloak.events.admin.ResourceType; import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.testsuite.util.AdminEventPaths; import org.keycloak.testsuite.util.OAuthClient; @@ -67,13 +68,13 @@ public class AttackDetectionResourceTest extends AbstractAdminTest { assertBruteForce(detection.bruteForceUserStatus("nosuchuser"), 0, false, false); detection.clearBruteForceForUser(findUser("test-user@localhost").getId()); - assertAdminEvents.assertEvent("test", OperationType.DELETE, AdminEventPaths.attackDetectionClearBruteForceForUserPath(findUser("test-user@localhost").getId())); + assertAdminEvents.assertEvent("test", OperationType.DELETE, AdminEventPaths.attackDetectionClearBruteForceForUserPath(findUser("test-user@localhost").getId()), ResourceType.USER); assertBruteForce(detection.bruteForceUserStatus(findUser("test-user@localhost").getId()), 0, false, false); assertBruteForce(detection.bruteForceUserStatus(findUser("test-user2").getId()), 2, true, true); detection.clearAllBruteForce(); - assertAdminEvents.assertEvent("test", OperationType.DELETE, AdminEventPaths.attackDetectionClearAllBruteForcePath()); + assertAdminEvents.assertEvent("test", OperationType.DELETE, AdminEventPaths.attackDetectionClearAllBruteForcePath(), ResourceType.USER); assertBruteForce(detection.bruteForceUserStatus(findUser("test-user@localhost").getId()), 0, false, false); assertBruteForce(detection.bruteForceUserStatus(findUser("test-user2").getId()), 0, false, false); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/ClientTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/ClientTest.java index 2a9c643f3b..1b7df9465c 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/ClientTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/ClientTest.java @@ -24,6 +24,7 @@ import org.keycloak.admin.client.resource.ProtocolMappersResource; import org.keycloak.admin.client.resource.RoleMappingResource; import org.keycloak.common.util.Time; import org.keycloak.events.admin.OperationType; +import org.keycloak.events.admin.ResourceType; import org.keycloak.models.AccountRoles; import org.keycloak.models.Constants; import org.keycloak.protocol.oidc.OIDCLoginProtocolFactory; @@ -77,7 +78,7 @@ public class ClientTest extends AbstractAdminTest { response.close(); String id = ApiUtil.getCreatedId(response); - assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.clientResourcePath(id), rep); + assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.clientResourcePath(id), rep, ResourceType.CLIENT); rep.setId(id); @@ -98,7 +99,7 @@ public class ClientTest extends AbstractAdminTest { realm.clients().get(id).remove(); - assertAdminEvents.assertEvent(realmId, OperationType.DELETE, AdminEventPaths.clientResourcePath(id)); + assertAdminEvents.assertEvent(realmId, OperationType.DELETE, AdminEventPaths.clientResourcePath(id), ResourceType.CLIENT); } @Test @@ -151,19 +152,19 @@ public class ClientTest extends AbstractAdminTest { RoleRepresentation role = new RoleRepresentation("test", "test", false); realm.clients().get(id).roles().create(role); - assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.clientRoleResourcePath(id, "test"), role); + assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.clientRoleResourcePath(id, "test"), role, ResourceType.CLIENT_ROLE); ClientRepresentation foundClientRep = realm.clients().get(id).toRepresentation(); foundClientRep.setDefaultRoles(new String[]{"test"}); realm.clients().get(id).update(foundClientRep); - assertAdminEvents.assertEvent(realmId, OperationType.UPDATE, AdminEventPaths.clientResourcePath(id), rep); + assertAdminEvents.assertEvent(realmId, OperationType.UPDATE, AdminEventPaths.clientResourcePath(id), rep, ResourceType.CLIENT_ROLE); assertArrayEquals(new String[]{"test"}, realm.clients().get(id).toRepresentation().getDefaultRoles()); realm.clients().get(id).roles().deleteRole("test"); - assertAdminEvents.assertEvent(realmId, OperationType.DELETE, AdminEventPaths.clientRoleResourcePath(id, "test")); + assertAdminEvents.assertEvent(realmId, OperationType.DELETE, AdminEventPaths.clientRoleResourcePath(id, "test"), ResourceType.CLIENT_ROLE); assertNull(realm.clients().get(id).toRepresentation().getDefaultRoles()); } @@ -187,7 +188,7 @@ public class ClientTest extends AbstractAdminTest { realm.clients().get(client.getId()).update(newClient); - assertAdminEvents.assertEvent(realmId, OperationType.UPDATE, AdminEventPaths.clientResourcePath(client.getId()), newClient); + assertAdminEvents.assertEvent(realmId, OperationType.UPDATE, AdminEventPaths.clientResourcePath(client.getId()), newClient, ResourceType.CLIENT); ClientRepresentation storedClient = realm.clients().get(client.getId()).toRepresentation(); @@ -197,7 +198,7 @@ public class ClientTest extends AbstractAdminTest { realm.clients().get(client.getId()).update(newClient); - assertAdminEvents.assertEvent(realmId, OperationType.UPDATE, AdminEventPaths.clientResourcePath(client.getId()), newClient); + assertAdminEvents.assertEvent(realmId, OperationType.UPDATE, AdminEventPaths.clientResourcePath(client.getId()), newClient, ResourceType.CLIENT); storedClient = realm.clients().get(client.getId()).toRepresentation(); assertClient(client, storedClient); @@ -223,7 +224,7 @@ public class ClientTest extends AbstractAdminTest { PushNotBeforeAction pushNotBefore = testingClient.testApp().getAdminPushNotBefore(); assertEquals(client.getNotBefore().intValue(), pushNotBefore.getNotBefore()); - assertAdminEvents.assertEvent(realmId, OperationType.ACTION, AdminEventPaths.clientPushRevocationPath(id)); + assertAdminEvents.assertEvent(realmId, OperationType.ACTION, AdminEventPaths.clientPushRevocationPath(id), ResourceType.CLIENT); } private ClientRepresentation createAppClient() { @@ -242,7 +243,7 @@ public class ClientTest extends AbstractAdminTest { String id = ApiUtil.getCreatedId(response); response.close(); - assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.clientResourcePath(id), client); + assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.clientResourcePath(id), client, ResourceType.CLIENT); client.setId(id); return client; @@ -259,14 +260,14 @@ public class ClientTest extends AbstractAdminTest { realm.clients().get(id).registerNode(Collections.singletonMap("node", myhost)); realm.clients().get(id).registerNode(Collections.singletonMap("node", "invalid")); - assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.clientNodePath(id, myhost)); - assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.clientNodePath(id, "invalid")); + assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.clientNodePath(id, myhost), ResourceType.CLUSTER_NODE); + assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.clientNodePath(id, "invalid"), ResourceType.CLUSTER_NODE); GlobalRequestResult result = realm.clients().get(id).testNodesAvailable(); assertEquals(1, result.getSuccessRequests().size()); assertEquals(1, result.getFailedRequests().size()); - assertAdminEvents.assertEvent(realmId, OperationType.ACTION, AdminEventPaths.clientTestNodesAvailablePath(id), result); + assertAdminEvents.assertEvent(realmId, OperationType.ACTION, AdminEventPaths.clientTestNodesAvailablePath(id), result, ResourceType.CLUSTER_NODE); TestAvailabilityAction testAvailable = testingClient.testApp().getTestAvailable(); assertEquals("test-app", testAvailable.getResource()); @@ -275,7 +276,7 @@ public class ClientTest extends AbstractAdminTest { realm.clients().get(id).unregisterNode("invalid"); - assertAdminEvents.assertEvent(realmId, OperationType.DELETE, AdminEventPaths.clientNodePath(id, "invalid")); + assertAdminEvents.assertEvent(realmId, OperationType.DELETE, AdminEventPaths.clientNodePath(id, "invalid"), ResourceType.CLUSTER_NODE); assertEquals(1, realm.clients().get(id).toRepresentation().getRegisteredNodes().size()); } @@ -338,24 +339,24 @@ public class ClientTest extends AbstractAdminTest { realm.roles().create(roleRep1); realm.roles().create(roleRep2); - assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.roleResourcePath("role1"), roleRep1); - assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.roleResourcePath("role2"), roleRep2); + assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.roleResourcePath("role1"), roleRep1, ResourceType.CLIENT_ROLE); + assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.roleResourcePath("role2"), roleRep2, ResourceType.CLIENT_ROLE); roleRep1 = realm.roles().get("role1").toRepresentation(); roleRep2 = realm.roles().get("role2").toRepresentation(); realm.roles().get("role1").addComposites(Collections.singletonList(roleRep2)); - assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.roleResourceCompositesPath("role1"), Collections.singletonList(roleRep2)); + assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.roleResourceCompositesPath("role1"), Collections.singletonList(roleRep2), ResourceType.REALM_ROLE); String accountMgmtId = realm.clients().findByClientId(Constants.ACCOUNT_MANAGEMENT_CLIENT_ID).get(0).getId(); RoleRepresentation viewAccountRoleRep = realm.clients().get(accountMgmtId).roles().get(AccountRoles.VIEW_PROFILE).toRepresentation(); scopesResource.realmLevel().add(Collections.singletonList(roleRep1)); - assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.clientScopeMappingsRealmLevelPath(id), Collections.singletonList(roleRep1)); + assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.clientScopeMappingsRealmLevelPath(id), Collections.singletonList(roleRep1), ResourceType.REALM_SCOPE_MAPPING); scopesResource.clientLevel(accountMgmtId).add(Collections.singletonList(viewAccountRoleRep)); - assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.clientScopeMappingsClientLevelPath(id, accountMgmtId), Collections.singletonList(viewAccountRoleRep)); + assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.clientScopeMappingsClientLevelPath(id, accountMgmtId), Collections.singletonList(viewAccountRoleRep), ResourceType.CLIENT_SCOPE_MAPPING); Assert.assertNames(scopesResource.realmLevel().listAll(), "role1"); Assert.assertNames(scopesResource.realmLevel().listEffective(), "role1", "role2"); @@ -369,10 +370,10 @@ public class ClientTest extends AbstractAdminTest { Assert.assertNames(scopesResource.getAll().getClientMappings().get(Constants.ACCOUNT_MANAGEMENT_CLIENT_ID).getMappings(), AccountRoles.VIEW_PROFILE); scopesResource.realmLevel().remove(Collections.singletonList(roleRep1)); - assertAdminEvents.assertEvent(realmId, OperationType.DELETE, AdminEventPaths.clientScopeMappingsRealmLevelPath(id), Collections.singletonList(roleRep1)); + assertAdminEvents.assertEvent(realmId, OperationType.DELETE, AdminEventPaths.clientScopeMappingsRealmLevelPath(id), Collections.singletonList(roleRep1), ResourceType.REALM_SCOPE_MAPPING); scopesResource.clientLevel(accountMgmtId).remove(Collections.singletonList(viewAccountRoleRep)); - assertAdminEvents.assertEvent(realmId, OperationType.DELETE, AdminEventPaths.clientScopeMappingsClientLevelPath(id, accountMgmtId), Collections.singletonList(viewAccountRoleRep)); + assertAdminEvents.assertEvent(realmId, OperationType.DELETE, AdminEventPaths.clientScopeMappingsClientLevelPath(id, accountMgmtId), Collections.singletonList(viewAccountRoleRep), ResourceType.CLIENT_SCOPE_MAPPING); Assert.assertNames(scopesResource.realmLevel().listAll()); Assert.assertNames(scopesResource.realmLevel().listEffective()); @@ -414,7 +415,7 @@ public class ClientTest extends AbstractAdminTest { fooMapperId = location.substring(location.lastIndexOf("/") + 1); response.close(); - assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.clientProtocolMapperPath(clientDbId, fooMapperId), fooMapper); + assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.clientProtocolMapperPath(clientDbId, fooMapperId), fooMapper, ResourceType.PROTOCOL_MAPPER); fooMapper = mappersResource.getMapperById(fooMapperId); assertEquals(fooMapper.getName(), "foo"); @@ -423,14 +424,14 @@ public class ClientTest extends AbstractAdminTest { fooMapper.setProtocolMapper("foo-mapper-updated"); mappersResource.update(fooMapperId, fooMapper); - assertAdminEvents.assertEvent(realmId, OperationType.UPDATE, AdminEventPaths.clientProtocolMapperPath(clientDbId, fooMapperId), fooMapper); + assertAdminEvents.assertEvent(realmId, OperationType.UPDATE, AdminEventPaths.clientProtocolMapperPath(clientDbId, fooMapperId), fooMapper, ResourceType.PROTOCOL_MAPPER); fooMapper = mappersResource.getMapperById(fooMapperId); assertEquals(fooMapper.getProtocolMapper(), "foo-mapper-updated"); // Remove foo mapper mappersResource.delete(fooMapperId); - assertAdminEvents.assertEvent(realmId, OperationType.DELETE, AdminEventPaths.clientProtocolMapperPath(clientDbId, fooMapperId)); + assertAdminEvents.assertEvent(realmId, OperationType.DELETE, AdminEventPaths.clientProtocolMapperPath(clientDbId, fooMapperId), ResourceType.PROTOCOL_MAPPER); try { mappersResource.getMapperById(fooMapperId); fail("Not expected to find deleted mapper"); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/IdentityProviderTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/IdentityProviderTest.java index a283cfce07..b9102e118a 100755 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/IdentityProviderTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/IdentityProviderTest.java @@ -26,6 +26,7 @@ import org.keycloak.dom.saml.v2.metadata.IndexedEndpointType; import org.keycloak.dom.saml.v2.metadata.KeyTypes; import org.keycloak.dom.saml.v2.metadata.SPSSODescriptorType; import org.keycloak.events.admin.OperationType; +import org.keycloak.events.admin.ResourceType; import org.keycloak.representations.idm.IdentityProviderMapperRepresentation; import org.keycloak.representations.idm.IdentityProviderMapperTypeRepresentation; import org.keycloak.representations.idm.IdentityProviderRepresentation; @@ -122,7 +123,7 @@ public class IdentityProviderTest extends AbstractAdminTest { representation.getConfig().put("clientId", "changedClientId"); identityProviderResource.update(representation); - assertAdminEvents.assertEvent(realmId, OperationType.UPDATE, AdminEventPaths.identityProviderPath("update-identity-provider"), representation); + assertAdminEvents.assertEvent(realmId, OperationType.UPDATE, AdminEventPaths.identityProviderPath("update-identity-provider"), representation, ResourceType.IDENTITY_PROVIDER); identityProviderResource = realm.identityProviders().get(representation.getInternalId()); @@ -150,7 +151,7 @@ public class IdentityProviderTest extends AbstractAdminTest { assertNotNull(representation); identityProviderResource.remove(); - assertAdminEvents.assertEvent(realmId, OperationType.DELETE, AdminEventPaths.identityProviderPath("remove-identity-provider")); + assertAdminEvents.assertEvent(realmId, OperationType.DELETE, AdminEventPaths.identityProviderPath("remove-identity-provider"), ResourceType.IDENTITY_PROVIDER); try { realm.identityProviders().get("remove-identity-provider").toRepresentation(); @@ -165,7 +166,7 @@ public class IdentityProviderTest extends AbstractAdminTest { Assert.assertNotNull(ApiUtil.getCreatedId(response)); response.close(); - assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.identityProviderPath(idpRep.getAlias()), idpRep); + assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.identityProviderPath(idpRep.getAlias()), idpRep, ResourceType.IDENTITY_PROVIDER); } private IdentityProviderRepresentation createRep(String id, String providerId) { @@ -320,7 +321,7 @@ public class IdentityProviderTest extends AbstractAdminTest { String id = ApiUtil.getCreatedId(response); Assert.assertNotNull(id); response.close(); - assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.identityProviderMapperPath("google", id), mapper); + assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.identityProviderMapperPath("google", id), mapper, ResourceType.IDENTITY_PROVIDER_MAPPER); // list mappers List mappers = provider.getMappers(); @@ -337,7 +338,7 @@ public class IdentityProviderTest extends AbstractAdminTest { // update mapper mapper.getConfig().put("role", "master-realm.manage-realm"); provider.update(id, mapper); - assertAdminEvents.assertEvent(realmId, OperationType.UPDATE, AdminEventPaths.identityProviderMapperPath("google", id), mapper); + assertAdminEvents.assertEvent(realmId, OperationType.UPDATE, AdminEventPaths.identityProviderMapperPath("google", id), mapper, ResourceType.IDENTITY_PROVIDER_MAPPER); mapper = provider.getMapperById(id); Assert.assertNotNull("mapperById not null", mapper); @@ -345,7 +346,7 @@ public class IdentityProviderTest extends AbstractAdminTest { // delete mapper provider.delete(id); - assertAdminEvents.assertEvent(realmId, OperationType.DELETE, AdminEventPaths.identityProviderMapperPath("google", id)); + assertAdminEvents.assertEvent(realmId, OperationType.DELETE, AdminEventPaths.identityProviderMapperPath("google", id), ResourceType.IDENTITY_PROVIDER_MAPPER); try { provider.getMapperById(id); Assert.fail("Should fail with NotFoundException"); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/InitialAccessTokenResourceTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/InitialAccessTokenResourceTest.java index 9f9538d46a..055bfa25ad 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/InitialAccessTokenResourceTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/InitialAccessTokenResourceTest.java @@ -22,6 +22,7 @@ import org.junit.Test; import org.keycloak.admin.client.resource.ClientInitialAccessResource; import org.keycloak.common.util.Time; import org.keycloak.events.admin.OperationType; +import org.keycloak.events.admin.ResourceType; import org.keycloak.representations.idm.ClientInitialAccessCreatePresentation; import org.keycloak.representations.idm.ClientInitialAccessPresentation; import org.keycloak.testsuite.util.AdminEventPaths; @@ -54,7 +55,7 @@ public class InitialAccessTokenResourceTest extends AbstractAdminTest { int time = Time.currentTime(); ClientInitialAccessPresentation response = resource.create(rep); - assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.clientInitialAccessPath(response.getId()), rep); + assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.clientInitialAccessPath(response.getId()), rep, ResourceType.CLIENT_INITIAL_ACCESS_MODEL); assertNotNull(response.getId()); assertEquals(new Integer(2), response.getCount()); @@ -65,12 +66,12 @@ public class InitialAccessTokenResourceTest extends AbstractAdminTest { rep.setCount(3); response = resource.create(rep); - assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.clientInitialAccessPath(response.getId()), rep); + assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.clientInitialAccessPath(response.getId()), rep, ResourceType.CLIENT_INITIAL_ACCESS_MODEL); rep.setCount(4); response = resource.create(rep); String lastId = response.getId(); - assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.clientInitialAccessPath(lastId), rep); + assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.clientInitialAccessPath(lastId), rep, ResourceType.CLIENT_INITIAL_ACCESS_MODEL); List list = resource.list(); assertEquals(3, list.size()); @@ -80,7 +81,7 @@ public class InitialAccessTokenResourceTest extends AbstractAdminTest { // Delete last and assert it was deleted resource.delete(lastId); - assertAdminEvents.assertEvent(realmId, OperationType.DELETE, AdminEventPaths.clientInitialAccessPath(lastId)); + assertAdminEvents.assertEvent(realmId, OperationType.DELETE, AdminEventPaths.clientInitialAccessPath(lastId), ResourceType.CLIENT_INITIAL_ACCESS_MODEL); list = resource.list(); assertEquals(2, list.size()); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/RoleByIdResourceTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/RoleByIdResourceTest.java index 6db07e115e..9297b0fe4e 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/RoleByIdResourceTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/RoleByIdResourceTest.java @@ -21,6 +21,7 @@ import org.junit.Before; import org.junit.Test; import org.keycloak.admin.client.resource.RoleByIdResource; import org.keycloak.events.admin.OperationType; +import org.keycloak.events.admin.ResourceType; import org.keycloak.representations.idm.RoleRepresentation; import org.keycloak.testsuite.Assert; import org.keycloak.testsuite.util.AdminEventPaths; @@ -86,7 +87,7 @@ public class RoleByIdResourceTest extends AbstractAdminTest { role.setDescription("Role A New"); resource.updateRole(ids.get("role-a"), role); - assertAdminEvents.assertEvent(realmId, OperationType.UPDATE, AdminEventPaths.roleByIdResourcePath(ids.get("role-a")), role); + assertAdminEvents.assertEvent(realmId, OperationType.UPDATE, AdminEventPaths.roleByIdResourcePath(ids.get("role-a")), role, ResourceType.REALM_ROLE); role = resource.getRole(ids.get("role-a")); @@ -100,7 +101,7 @@ public class RoleByIdResourceTest extends AbstractAdminTest { public void deleteRole() { assertNotNull(resource.getRole(ids.get("role-a"))); resource.deleteRole(ids.get("role-a")); - assertAdminEvents.assertEvent(realmId, OperationType.DELETE, AdminEventPaths.roleByIdResourcePath(ids.get("role-a"))); + assertAdminEvents.assertEvent(realmId, OperationType.DELETE, AdminEventPaths.roleByIdResourcePath(ids.get("role-a")), ResourceType.REALM_ROLE); try { resource.getRole(ids.get("role-a")); @@ -119,7 +120,7 @@ public class RoleByIdResourceTest extends AbstractAdminTest { l.add(RoleBuilder.create().id(ids.get("role-c")).build()); resource.addComposites(ids.get("role-a"), l); - assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.roleByIdResourceCompositesPath(ids.get("role-a")), l); + assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.roleByIdResourceCompositesPath(ids.get("role-a")), l, ResourceType.REALM_ROLE); Set composites = resource.getRoleComposites(ids.get("role-a")); @@ -133,7 +134,7 @@ public class RoleByIdResourceTest extends AbstractAdminTest { Assert.assertNames(clientComposites, "role-c"); resource.deleteComposites(ids.get("role-a"), l); - assertAdminEvents.assertEvent(realmId, OperationType.DELETE, AdminEventPaths.roleByIdResourceCompositesPath(ids.get("role-a")), l); + assertAdminEvents.assertEvent(realmId, OperationType.DELETE, AdminEventPaths.roleByIdResourceCompositesPath(ids.get("role-a")), l, ResourceType.REALM_ROLE); assertFalse(resource.getRole(ids.get("role-a")).isComposite()); assertEquals(0, resource.getRoleComposites(ids.get("role-a")).size()); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/UserFederationMapperTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/UserFederationMapperTest.java index 52e16997ff..2ad95a80e8 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/UserFederationMapperTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/UserFederationMapperTest.java @@ -33,6 +33,7 @@ import org.junit.Before; import org.junit.Test; import org.keycloak.admin.client.resource.UserFederationProviderResource; import org.keycloak.events.admin.OperationType; +import org.keycloak.events.admin.ResourceType; import org.keycloak.federation.ldap.mappers.UserAttributeLDAPFederationMapper; import org.keycloak.federation.ldap.mappers.UserAttributeLDAPFederationMapperFactory; import org.keycloak.federation.ldap.mappers.membership.role.RoleLDAPFederationMapperFactory; @@ -65,7 +66,7 @@ public class UserFederationMapperTest extends AbstractAdminTest { Response resp = realm.userFederation().create(ldapRep); this.ldapProviderId = ApiUtil.getCreatedId(resp); resp.close(); - assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.userFederationResourcePath(this.ldapProviderId), ldapRep); + assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.userFederationResourcePath(this.ldapProviderId), ldapRep, ResourceType.USER_FEDERATION_PROVIDER); UserFederationProviderRepresentation dummyRep = UserFederationProviderBuilder.create() .displayName("dummy-1") @@ -75,16 +76,16 @@ public class UserFederationMapperTest extends AbstractAdminTest { resp = realm.userFederation().create(dummyRep); this.dummyProviderId = ApiUtil.getCreatedId(resp); resp.close(); - assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.userFederationResourcePath(this.dummyProviderId), dummyRep); + assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.userFederationResourcePath(this.dummyProviderId), dummyRep, ResourceType.USER_FEDERATION_PROVIDER); } @After public void cleanFederationProviders() { realm.userFederation().get(ldapProviderId).remove(); - assertAdminEvents.assertEvent(realmId, OperationType.DELETE, AdminEventPaths.userFederationResourcePath(ldapProviderId)); + assertAdminEvents.assertEvent(realmId, OperationType.DELETE, AdminEventPaths.userFederationResourcePath(ldapProviderId), ResourceType.USER_FEDERATION_PROVIDER); realm.userFederation().get(dummyProviderId).remove(); - assertAdminEvents.assertEvent(realmId, OperationType.DELETE, AdminEventPaths.userFederationResourcePath(dummyProviderId)); + assertAdminEvents.assertEvent(realmId, OperationType.DELETE, AdminEventPaths.userFederationResourcePath(dummyProviderId), ResourceType.USER_FEDERATION_PROVIDER); } @@ -169,14 +170,14 @@ public class UserFederationMapperTest extends AbstractAdminTest { mapperRep.getConfig().put(UserAttributeLDAPFederationMapper.USER_MODEL_ATTRIBUTE, "email-updated"); mapperRep.getConfig().put(UserAttributeLDAPFederationMapper.LDAP_ATTRIBUTE, "mail-updated"); ldapProviderResource().updateMapper(mapperId, mapperRep); - assertAdminEvents.assertEvent(realmId, OperationType.UPDATE, AdminEventPaths.userFederationMapperResourcePath(ldapProviderId, mapperId), mapperRep); + assertAdminEvents.assertEvent(realmId, OperationType.UPDATE, AdminEventPaths.userFederationMapperResourcePath(ldapProviderId, mapperId), mapperRep, ResourceType.USER_FEDERATION_MAPPER); mapperRep = ldapProviderResource().getMapperById(mapperId); assertMapper(mapperRep, mapperId, "email-mapper", UserAttributeLDAPFederationMapperFactory.PROVIDER_ID, UserAttributeLDAPFederationMapper.USER_MODEL_ATTRIBUTE, "email-updated", UserAttributeLDAPFederationMapper.LDAP_ATTRIBUTE, "mail-updated"); // Test removed successfully ldapProviderResource().removeMapper(mapperId); - assertAdminEvents.assertEvent(realmId, OperationType.DELETE, AdminEventPaths.userFederationMapperResourcePath(ldapProviderId, mapperId)); + assertAdminEvents.assertEvent(realmId, OperationType.DELETE, AdminEventPaths.userFederationMapperResourcePath(ldapProviderId, mapperId), ResourceType.USER_FEDERATION_MAPPER); try { ldapProviderResource().getMapperById(mapperId); @@ -192,7 +193,7 @@ public class UserFederationMapperTest extends AbstractAdminTest { response.close(); String mapperId = ApiUtil.getCreatedId(response); - assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.userFederationMapperResourcePath(userFederationProviderId , mapperId), mapper); + assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.userFederationMapperResourcePath(userFederationProviderId , mapperId), mapper, ResourceType.USER_FEDERATION_MAPPER); return mapperId; } @@ -227,7 +228,7 @@ public class UserFederationMapperTest extends AbstractAdminTest { // Remove role mapper and assert not found anymore ldapProviderResource().removeMapper(roleMapperId); - assertAdminEvents.assertEvent(realmId, OperationType.DELETE, AdminEventPaths.userFederationMapperResourcePath(ldapProviderId, roleMapperId)); + assertAdminEvents.assertEvent(realmId, OperationType.DELETE, AdminEventPaths.userFederationMapperResourcePath(ldapProviderId, roleMapperId), ResourceType.USER_FEDERATION_MAPPER); mappers = ldapProviderResource().getMappers(); Assert.assertNull(findMapperByName(mappers, "role-mapper")); @@ -257,14 +258,14 @@ public class UserFederationMapperTest extends AbstractAdminTest { Map eventRep = new HashMap<>(); eventRep.put("action", "fedToKeycloak"); - assertAdminEvents.assertEvent(realmId, OperationType.ACTION, AdminEventPaths.userFederationMapperResourcePath(ldapProviderId, mapperId) + "/sync", eventRep); + assertAdminEvents.assertEvent(realmId, OperationType.ACTION, AdminEventPaths.userFederationMapperResourcePath(ldapProviderId, mapperId) + "/sync", eventRep, ResourceType.USER_FEDERATION_MAPPER); // Try keycloak to fed result = ldapProviderResource().syncMapperData(mapperId, "keycloakToFed"); Assert.assertEquals("dummyKeycloakToFedSuccess mapper=some-dummy", result.getStatus()); eventRep.put("action", "keycloakToFed"); - assertAdminEvents.assertEvent(realmId, OperationType.ACTION, AdminEventPaths.userFederationMapperResourcePath(ldapProviderId, mapperId) + "/sync"); + assertAdminEvents.assertEvent(realmId, OperationType.ACTION, AdminEventPaths.userFederationMapperResourcePath(ldapProviderId, mapperId) + "/sync", ResourceType.USER_FEDERATION_MAPPER); } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/UserFederationTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/UserFederationTest.java index 2018e27ff5..ef3544f3cb 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/UserFederationTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/UserFederationTest.java @@ -30,6 +30,7 @@ import org.junit.Test; import org.keycloak.admin.client.resource.UserFederationProvidersResource; import org.keycloak.common.constants.KerberosConstants; import org.keycloak.events.admin.OperationType; +import org.keycloak.events.admin.ResourceType; import org.keycloak.models.AuthenticationExecutionModel; import org.keycloak.models.LDAPConstants; import org.keycloak.provider.ProviderConfigProperty; @@ -209,7 +210,7 @@ public class UserFederationTest extends AbstractAdminTest { // Change filter to be valid ldapRep.getConfig().put(LDAPConstants.CUSTOM_USER_SEARCH_FILTER, "(dc=something2)"); userFederation().get(id).update(ldapRep); - assertAdminEvents.assertEvent(realmId, OperationType.UPDATE, AdminEventPaths.userFederationResourcePath(id), ldapRep); + assertAdminEvents.assertEvent(realmId, OperationType.UPDATE, AdminEventPaths.userFederationResourcePath(id), ldapRep, ResourceType.USER_FEDERATION_PROVIDER); // Assert updated successfully ldapRep = userFederation().get(id).toRepresentation(); @@ -219,7 +220,7 @@ public class UserFederationTest extends AbstractAdminTest { // Assert update displayName ldapRep.setDisplayName("ldap2"); userFederation().get(id).update(ldapRep); - assertAdminEvents.assertEvent(realmId, OperationType.UPDATE, AdminEventPaths.userFederationResourcePath(id), ldapRep); + assertAdminEvents.assertEvent(realmId, OperationType.UPDATE, AdminEventPaths.userFederationResourcePath(id), ldapRep, ResourceType.USER_FEDERATION_PROVIDER); assertFederationProvider(userFederation().get(id).toRepresentation(), id, "ldap2", "ldap", 2, -1, -1, -1, LDAPConstants.BIND_DN, "cn=manager-updated", LDAPConstants.BIND_CREDENTIAL, "password", LDAPConstants.CUSTOM_USER_SEARCH_FILTER, "(dc=something2)"); @@ -253,12 +254,12 @@ public class UserFederationTest extends AbstractAdminTest { // Switch kerberos authenticator to DISABLED kerberosExecution.setRequirement(AuthenticationExecutionModel.Requirement.DISABLED.toString()); realm.flows().updateExecutions("browser", kerberosExecution); - assertAdminEvents.assertEvent(realmId, OperationType.UPDATE, AdminEventPaths.authUpdateExecutionPath("browser"), kerberosExecution); + assertAdminEvents.assertEvent(realmId, OperationType.UPDATE, AdminEventPaths.authUpdateExecutionPath("browser"), kerberosExecution, ResourceType.AUTH_EXECUTION); // update LDAP provider with kerberos ldapRep = userFederation().get(id).toRepresentation(); userFederation().get(id).update(ldapRep); - assertAdminEvents.assertEvent(realmId, OperationType.UPDATE, AdminEventPaths.userFederationResourcePath(id), ldapRep); + assertAdminEvents.assertEvent(realmId, OperationType.UPDATE, AdminEventPaths.userFederationResourcePath(id), ldapRep, ResourceType.USER_FEDERATION_PROVIDER); // Assert kerberos authenticator ALTERNATIVE kerberosExecution = findKerberosExecution(); @@ -267,7 +268,7 @@ public class UserFederationTest extends AbstractAdminTest { // Cleanup kerberosExecution.setRequirement(AuthenticationExecutionModel.Requirement.DISABLED.toString()); realm.flows().updateExecutions("browser", kerberosExecution); - assertAdminEvents.assertEvent(realmId, OperationType.UPDATE, AdminEventPaths.authUpdateExecutionPath("browser"), kerberosExecution); + assertAdminEvents.assertEvent(realmId, OperationType.UPDATE, AdminEventPaths.authUpdateExecutionPath("browser"), kerberosExecution, ResourceType.AUTH_EXECUTION); removeUserFederationProvider(id); } @@ -277,7 +278,7 @@ public class UserFederationTest extends AbstractAdminTest { AuthenticationExecutionInfoRepresentation kerberosExecution = findKerberosExecution(); kerberosExecution.setRequirement(AuthenticationExecutionModel.Requirement.REQUIRED.toString()); realm.flows().updateExecutions("browser", kerberosExecution); - assertAdminEvents.assertEvent(realmId, OperationType.UPDATE, AdminEventPaths.authUpdateExecutionPath("browser"), kerberosExecution); + assertAdminEvents.assertEvent(realmId, OperationType.UPDATE, AdminEventPaths.authUpdateExecutionPath("browser"), kerberosExecution, ResourceType.AUTH_EXECUTION); // create LDAP provider with kerberos UserFederationProviderRepresentation ldapRep = UserFederationProviderBuilder.create() @@ -295,7 +296,7 @@ public class UserFederationTest extends AbstractAdminTest { // update LDAP provider with kerberos ldapRep = userFederation().get(id).toRepresentation(); userFederation().get(id).update(ldapRep); - assertAdminEvents.assertEvent(realmId, OperationType.UPDATE, AdminEventPaths.userFederationResourcePath(id), ldapRep); + assertAdminEvents.assertEvent(realmId, OperationType.UPDATE, AdminEventPaths.userFederationResourcePath(id), ldapRep, ResourceType.REALM); // Assert kerberos authenticator still REQUIRED kerberosExecution = findKerberosExecution(); @@ -304,7 +305,7 @@ public class UserFederationTest extends AbstractAdminTest { // Cleanup kerberosExecution.setRequirement(AuthenticationExecutionModel.Requirement.DISABLED.toString()); realm.flows().updateExecutions("browser", kerberosExecution); - assertAdminEvents.assertEvent(realmId, OperationType.UPDATE, AdminEventPaths.authUpdateExecutionPath("browser"), kerberosExecution); + assertAdminEvents.assertEvent(realmId, OperationType.UPDATE, AdminEventPaths.authUpdateExecutionPath("browser"), kerberosExecution, ResourceType.REALM); removeUserFederationProvider(id); } @@ -342,7 +343,7 @@ public class UserFederationTest extends AbstractAdminTest { Map eventRep = new HashMap<>(); eventRep.put("action", "triggerFullSync"); - assertAdminEvents.assertEvent(realmId, OperationType.ACTION, AdminEventPaths.userFederationResourcePath(id1) + "/sync", eventRep); + assertAdminEvents.assertEvent(realmId, OperationType.ACTION, AdminEventPaths.userFederationResourcePath(id1) + "/sync", eventRep, ResourceType.USER_FEDERATION_PROVIDER); int fullSyncTime = userFederation().get(id1).toRepresentation().getLastSync(); Assert.assertTrue(fullSyncTime > 0); @@ -352,7 +353,7 @@ public class UserFederationTest extends AbstractAdminTest { syncResult = userFederation().get(id1).syncUsers("triggerChangedUsersSync"); eventRep.put("action", "triggerChangedUsersSync"); - assertAdminEvents.assertEvent(realmId, OperationType.ACTION, AdminEventPaths.userFederationResourcePath(id1) + "/sync", eventRep); + assertAdminEvents.assertEvent(realmId, OperationType.ACTION, AdminEventPaths.userFederationResourcePath(id1) + "/sync", eventRep, ResourceType.USER_FEDERATION_PROVIDER); Assert.assertEquals("0 imported users, 0 updated users", syncResult.getStatus()); int changedSyncTime = userFederation().get(id1).toRepresentation().getLastSync(); @@ -370,13 +371,13 @@ public class UserFederationTest extends AbstractAdminTest { resp.close(); String federationProviderId = ApiUtil.getCreatedId(resp); - assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.userFederationResourcePath(federationProviderId), rep); + assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.userFederationResourcePath(federationProviderId), rep, ResourceType.USER_FEDERATION_PROVIDER); return federationProviderId; } private void removeUserFederationProvider(String id) { userFederation().get(id).remove(); - assertAdminEvents.assertEvent(realmId, OperationType.DELETE, AdminEventPaths.userFederationResourcePath(id)); + assertAdminEvents.assertEvent(realmId, OperationType.DELETE, AdminEventPaths.userFederationResourcePath(id), ResourceType.USER_FEDERATION_PROVIDER); } private void assertFederationProvider(UserFederationProviderRepresentation rep, String id, String displayName, String providerName, diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/UserTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/UserTest.java index f24caa8dd3..58b66174db 100755 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/UserTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/UserTest.java @@ -29,6 +29,7 @@ import org.keycloak.admin.client.resource.RealmResource; import org.keycloak.admin.client.resource.RoleMappingResource; import org.keycloak.admin.client.resource.UserResource; import org.keycloak.events.admin.OperationType; +import org.keycloak.events.admin.ResourceType; import org.keycloak.models.Constants; import org.keycloak.models.UserModel; import org.keycloak.representations.idm.CredentialRepresentation; @@ -111,13 +112,13 @@ public class UserTest extends AbstractAdminTest { String createdId = ApiUtil.getCreatedId(response); response.close(); - assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.userResourcePath(createdId), userRep); + assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.userResourcePath(createdId), userRep, ResourceType.USER); return createdId; } private void updateUser(UserResource user, UserRepresentation userRep) { user.update(userRep); - assertAdminEvents.assertEvent(realmId, OperationType.UPDATE, AdminEventPaths.userResourcePath(userRep.getId()), userRep); + assertAdminEvents.assertEvent(realmId, OperationType.UPDATE, AdminEventPaths.userResourcePath(userRep.getId()), userRep, ResourceType.USER); } @Test @@ -277,7 +278,7 @@ public class UserTest extends AbstractAdminTest { Response response = realm.users().delete( userId ); assertEquals(204, response.getStatus()); response.close(); - assertAdminEvents.assertEvent(realmId, OperationType.DELETE, AdminEventPaths.userResourcePath(userId)); + assertAdminEvents.assertEvent(realmId, OperationType.DELETE, AdminEventPaths.userResourcePath(userId), ResourceType.USER); } @Test @@ -326,7 +327,7 @@ public class UserTest extends AbstractAdminTest { link.setUserName("social-username"); Response response = user.addFederatedIdentity("social-provider-id", link); assertEquals(204, response.getStatus()); - assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.userFederatedIdentityLink(id, "social-provider-id"), link); + assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.userFederatedIdentityLink(id, "social-provider-id"), link, ResourceType.USER); // Verify social link is here user = realm.users().get(id); @@ -339,7 +340,7 @@ public class UserTest extends AbstractAdminTest { // Remove social link now user.removeFederatedIdentity("social-provider-id"); - assertAdminEvents.assertEvent(realmId, OperationType.DELETE, AdminEventPaths.userFederatedIdentityLink(id, "social-provider-id")); + assertAdminEvents.assertEvent(realmId, OperationType.DELETE, AdminEventPaths.userFederatedIdentityLink(id, "social-provider-id"), ResourceType.USER); assertEquals(0, user.getFederatedIdentity().size()); removeSampleIdentityProvider(); @@ -354,14 +355,14 @@ public class UserTest extends AbstractAdminTest { rep.setProviderId("social-provider-type"); realm.identityProviders().create(rep); - assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.identityProviderPath(rep.getAlias()), rep); + assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.identityProviderPath(rep.getAlias()), rep, ResourceType.IDENTITY_PROVIDER); } private void removeSampleIdentityProvider() { IdentityProviderResource resource = realm.identityProviders().get("social-provider-id"); Assert.assertNotNull(resource); resource.remove(); - assertAdminEvents.assertEvent(realmId, OperationType.DELETE, AdminEventPaths.identityProviderPath("social-provider-id")); + assertAdminEvents.assertEvent(realmId, OperationType.DELETE, AdminEventPaths.identityProviderPath("social-provider-id"), ResourceType.IDENTITY_PROVIDER); } @Test @@ -519,7 +520,7 @@ public class UserTest extends AbstractAdminTest { List actions = new LinkedList<>(); actions.add(UserModel.RequiredAction.UPDATE_PASSWORD.name()); user.executeActionsEmail("account", actions); - assertAdminEvents.assertEvent(realmId, OperationType.ACTION, AdminEventPaths.userResourcePath(id) + "/execute-actions-email"); + assertAdminEvents.assertEvent(realmId, OperationType.ACTION, AdminEventPaths.userResourcePath(id) + "/execute-actions-email", ResourceType.USER); Assert.assertEquals(1, greenMail.getReceivedMessages().length); @@ -587,7 +588,7 @@ public class UserTest extends AbstractAdminTest { } user.sendVerifyEmail(); - assertAdminEvents.assertEvent(realmId, OperationType.ACTION, AdminEventPaths.userResourcePath(id) + "/send-verify-email"); + assertAdminEvents.assertEvent(realmId, OperationType.ACTION, AdminEventPaths.userResourcePath(id) + "/send-verify-email", ResourceType.USER); Assert.assertEquals(1, greenMail.getReceivedMessages().length); @@ -626,13 +627,13 @@ public class UserTest extends AbstractAdminTest { rep.setFirstName("Firstname"); user.update(rep); - assertAdminEvents.assertEvent(realmId, OperationType.UPDATE, AdminEventPaths.userResourcePath(id), rep); + assertAdminEvents.assertEvent(realmId, OperationType.UPDATE, AdminEventPaths.userResourcePath(id), rep, ResourceType.USER); rep = new UserRepresentation(); rep.setLastName("Lastname"); user.update(rep); - assertAdminEvents.assertEvent(realmId, OperationType.UPDATE, AdminEventPaths.userResourcePath(id), rep); + assertAdminEvents.assertEvent(realmId, OperationType.UPDATE, AdminEventPaths.userResourcePath(id), rep, ResourceType.USER); rep = realm.users().get(id).toRepresentation(); @@ -709,7 +710,7 @@ public class UserTest extends AbstractAdminTest { cred.setTemporary(false); realm.users().get(userId).resetPassword(cred); - assertAdminEvents.assertEvent(realmId, OperationType.ACTION, AdminEventPaths.userResetPasswordPath(userId)); + assertAdminEvents.assertEvent(realmId, OperationType.ACTION, AdminEventPaths.userResetPasswordPath(userId), ResourceType.USER); String accountUrl = RealmsResource.accountUrl(UriBuilder.fromUri(getAuthServerRoot())).build(REALM_NAME).toString(); @@ -746,7 +747,7 @@ public class UserTest extends AbstractAdminTest { RequiredActionProviderRepresentation updatePasswordReqAction = realm.flows().getRequiredAction(UserModel.RequiredAction.UPDATE_PASSWORD.toString()); updatePasswordReqAction.setDefaultAction(true); realm.flows().updateRequiredAction(UserModel.RequiredAction.UPDATE_PASSWORD.toString(), updatePasswordReqAction); - assertAdminEvents.assertEvent(realmId, OperationType.UPDATE, AdminEventPaths.authRequiredActionPath(UserModel.RequiredAction.UPDATE_PASSWORD.toString()), updatePasswordReqAction); + assertAdminEvents.assertEvent(realmId, OperationType.UPDATE, AdminEventPaths.authRequiredActionPath(UserModel.RequiredAction.UPDATE_PASSWORD.toString()), updatePasswordReqAction, ResourceType.USER); // Create user String userId = createUser("user1", "user1@localhost"); @@ -759,7 +760,7 @@ public class UserTest extends AbstractAdminTest { updatePasswordReqAction = realm.flows().getRequiredAction(UserModel.RequiredAction.UPDATE_PASSWORD.toString()); updatePasswordReqAction.setDefaultAction(true); realm.flows().updateRequiredAction(UserModel.RequiredAction.UPDATE_PASSWORD.toString(), updatePasswordReqAction); - assertAdminEvents.assertEvent(realmId, OperationType.UPDATE, AdminEventPaths.authRequiredActionPath(UserModel.RequiredAction.UPDATE_PASSWORD.toString()), updatePasswordReqAction); + assertAdminEvents.assertEvent(realmId, OperationType.UPDATE, AdminEventPaths.authRequiredActionPath(UserModel.RequiredAction.UPDATE_PASSWORD.toString()), updatePasswordReqAction, ResourceType.USER); } @Test @@ -800,16 +801,16 @@ public class UserTest extends AbstractAdminTest { l.add(realm.roles().get("realm-role").toRepresentation()); l.add(realm.roles().get("realm-composite").toRepresentation()); roles.realmLevel().add(l); - assertAdminEvents.assertEvent("test", OperationType.CREATE, AdminEventPaths.userRealmRoleMappingsPath(userId), l); + assertAdminEvents.assertEvent("test", OperationType.CREATE, AdminEventPaths.userRealmRoleMappingsPath(userId), l, ResourceType.REALM_ROLE_MAPPING); // Add client roles List list = Collections.singletonList(realm.clients().get(clientUuid).roles().get("client-role").toRepresentation()); roles.clientLevel(clientUuid).add(list); - assertAdminEvents.assertEvent("test", OperationType.CREATE, AdminEventPaths.userClientRoleMappingsPath(userId, clientUuid), list); + assertAdminEvents.assertEvent("test", OperationType.CREATE, AdminEventPaths.userClientRoleMappingsPath(userId, clientUuid), list, ResourceType.CLIENT_ROLE_MAPPING); list = Collections.singletonList(realm.clients().get(clientUuid).roles().get("client-composite").toRepresentation()); roles.clientLevel(clientUuid).add(list); - assertAdminEvents.assertEvent("test", OperationType.CREATE, AdminEventPaths.userClientRoleMappingsPath(userId, clientUuid), list); + assertAdminEvents.assertEvent("test", OperationType.CREATE, AdminEventPaths.userClientRoleMappingsPath(userId, clientUuid), ResourceType.CLIENT_ROLE_MAPPING); // List realm roles assertNames(roles.realmLevel().listAll(), "realm-role", "realm-composite", "user", "offline_access", Constants.AUTHZ_UMA_AUTHORIZATION); @@ -831,14 +832,14 @@ public class UserTest extends AbstractAdminTest { // Remove realm role RoleRepresentation realmRoleRep = realm.roles().get("realm-role").toRepresentation(); roles.realmLevel().remove(Collections.singletonList(realmRoleRep)); - assertAdminEvents.assertEvent("test", OperationType.DELETE, AdminEventPaths.userRealmRoleMappingsPath(userId), Collections.singletonList(realmRoleRep)); + assertAdminEvents.assertEvent("test", OperationType.DELETE, AdminEventPaths.userRealmRoleMappingsPath(userId), Collections.singletonList(realmRoleRep), ResourceType.REALM_ROLE_MAPPING); assertNames(roles.realmLevel().listAll(), "realm-composite", "user", "offline_access", Constants.AUTHZ_UMA_AUTHORIZATION); // Remove client role RoleRepresentation clientRoleRep = realm.clients().get(clientUuid).roles().get("client-role").toRepresentation(); roles.clientLevel(clientUuid).remove(Collections.singletonList(clientRoleRep)); - assertAdminEvents.assertEvent("test", OperationType.DELETE, AdminEventPaths.userClientRoleMappingsPath(userId, clientUuid), Collections.singletonList(clientRoleRep)); + assertAdminEvents.assertEvent("test", OperationType.DELETE, AdminEventPaths.userClientRoleMappingsPath(userId, clientUuid), Collections.singletonList(clientRoleRep), ResourceType.CLIENT_ROLE_MAPPING); assertNames(roles.clientLevel(clientUuid).listAll(), "client-composite"); } @@ -847,14 +848,14 @@ public class UserTest extends AbstractAdminTest { RealmRepresentation rep = realm.toRepresentation(); rep.setEditUsernameAllowed(true); realm.update(rep); - assertAdminEvents.assertEvent(realmId, OperationType.UPDATE, Matchers.nullValue(String.class), rep); + assertAdminEvents.assertEvent(realmId, OperationType.UPDATE, Matchers.nullValue(String.class), rep, ResourceType.REALM); } private void enableBruteForce() { RealmRepresentation rep = realm.toRepresentation(); rep.setBruteForceProtected(true); realm.update(rep); - assertAdminEvents.assertEvent(realmId, OperationType.UPDATE, Matchers.nullValue(String.class), rep); + assertAdminEvents.assertEvent(realmId, OperationType.UPDATE, Matchers.nullValue(String.class), rep, ResourceType.REALM); } } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/authentication/AbstractAuthenticationTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/authentication/AbstractAuthenticationTest.java index d77c76ce96..f115c49326 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/authentication/AbstractAuthenticationTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/authentication/AbstractAuthenticationTest.java @@ -23,6 +23,7 @@ import org.junit.Rule; import org.keycloak.admin.client.resource.AuthenticationManagementResource; import org.keycloak.admin.client.resource.RealmResource; import org.keycloak.events.admin.OperationType; +import org.keycloak.events.admin.ResourceType; import org.keycloak.representations.idm.AuthenticationExecutionExportRepresentation; import org.keycloak.representations.idm.AuthenticationExecutionInfoRepresentation; import org.keycloak.representations.idm.AuthenticationFlowRepresentation; @@ -196,6 +197,6 @@ public abstract class AbstractAuthenticationTest extends AbstractKeycloakTest { Response response = authMgmtResource.createFlow(flowRep); org.keycloak.testsuite.Assert.assertEquals(201, response.getStatus()); response.close(); - assertAdminEvents.assertEvent(REALM_NAME, OperationType.CREATE, AssertAdminEvents.isExpectedPrefixFollowedByUuid(AdminEventPaths.authFlowsPath()), flowRep); + assertAdminEvents.assertEvent(REALM_NAME, OperationType.CREATE, AssertAdminEvents.isExpectedPrefixFollowedByUuid(AdminEventPaths.authFlowsPath()), flowRep, ResourceType.AUTH_FLOW); } } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/authentication/AuthenticatorConfigTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/authentication/AuthenticatorConfigTest.java index eb1cda5a5d..00c1943479 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/authentication/AuthenticatorConfigTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/authentication/AuthenticatorConfigTest.java @@ -29,6 +29,7 @@ import org.junit.Test; import org.keycloak.authentication.authenticators.broker.IdpCreateUserIfUniqueAuthenticator; import org.keycloak.authentication.authenticators.broker.IdpCreateUserIfUniqueAuthenticatorFactory; import org.keycloak.events.admin.OperationType; +import org.keycloak.events.admin.ResourceType; import org.keycloak.representations.idm.AuthenticationExecutionInfoRepresentation; import org.keycloak.representations.idm.AuthenticationFlowRepresentation; import org.keycloak.representations.idm.AuthenticatorConfigRepresentation; @@ -52,7 +53,7 @@ public class AuthenticatorConfigTest extends AbstractAuthenticationTest { HashMap params = new HashMap<>(); params.put("provider", IdpCreateUserIfUniqueAuthenticatorFactory.PROVIDER_ID); authMgmtResource.addExecution("firstBrokerLogin2", params); - assertAdminEvents.assertEvent(REALM_NAME, OperationType.CREATE, AdminEventPaths.authAddExecutionPath("firstBrokerLogin2"), params); + assertAdminEvents.assertEvent(REALM_NAME, OperationType.CREATE, AdminEventPaths.authAddExecutionPath("firstBrokerLogin2"), params, ResourceType.AUTH_EXECUTION); List executionReps = authMgmtResource.getExecutions("firstBrokerLogin2"); AuthenticationExecutionInfoRepresentation exec = findExecutionByProvider(IdpCreateUserIfUniqueAuthenticatorFactory.PROVIDER_ID, executionReps); @@ -79,7 +80,7 @@ public class AuthenticatorConfigTest extends AbstractAuthenticationTest { // Cleanup authMgmtResource.removeAuthenticatorConfig(cfgId); - assertAdminEvents.assertEvent(REALM_NAME, OperationType.DELETE, AdminEventPaths.authExecutionConfigPath(cfgId)); + assertAdminEvents.assertEvent(REALM_NAME, OperationType.DELETE, AdminEventPaths.authExecutionConfigPath(cfgId), ResourceType.AUTHENTICATOR_CONFIG); } @@ -105,7 +106,7 @@ public class AuthenticatorConfigTest extends AbstractAuthenticationTest { cfgRep.setAlias("foo2"); cfgRep.getConfig().put("configKey2", "configValue2"); authMgmtResource.updateAuthenticatorConfig(cfgRep.getId(), cfgRep); - assertAdminEvents.assertEvent(REALM_NAME, OperationType.UPDATE, AdminEventPaths.authExecutionConfigPath(cfgId), cfgRep); + assertAdminEvents.assertEvent(REALM_NAME, OperationType.UPDATE, AdminEventPaths.authExecutionConfigPath(cfgId), cfgRep, ResourceType.AUTHENTICATOR_CONFIG); // Assert updated cfgRep = authMgmtResource.getAuthenticatorConfig(cfgRep.getId()); @@ -137,7 +138,7 @@ public class AuthenticatorConfigTest extends AbstractAuthenticationTest { // Test remove our config authMgmtResource.removeAuthenticatorConfig(cfgId); - assertAdminEvents.assertEvent(REALM_NAME, OperationType.DELETE, AdminEventPaths.authExecutionConfigPath(cfgId)); + assertAdminEvents.assertEvent(REALM_NAME, OperationType.DELETE, AdminEventPaths.authExecutionConfigPath(cfgId), ResourceType.AUTHENTICATOR_CONFIG); // Assert config not found try { @@ -159,7 +160,7 @@ public class AuthenticatorConfigTest extends AbstractAuthenticationTest { Assert.assertEquals(201, resp.getStatus()); String cfgId = ApiUtil.getCreatedId(resp); Assert.assertNotNull(cfgId); - assertAdminEvents.assertEvent(REALM_NAME, OperationType.CREATE, AdminEventPaths.authAddExecutionConfigPath(executionId), cfg); + assertAdminEvents.assertEvent(REALM_NAME, OperationType.CREATE, AdminEventPaths.authAddExecutionConfigPath(executionId), cfg, ResourceType.AUTH_EXECUTION); return cfgId; } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/authentication/ExecutionTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/authentication/ExecutionTest.java index ae19ff6179..35b06d603e 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/authentication/ExecutionTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/authentication/ExecutionTest.java @@ -22,6 +22,7 @@ import org.junit.Test; import org.keycloak.authentication.AuthenticationFlow; import org.keycloak.authentication.authenticators.client.ClientIdAndSecretAuthenticator; import org.keycloak.events.admin.OperationType; +import org.keycloak.events.admin.ResourceType; import org.keycloak.representations.idm.AuthenticationExecutionInfoRepresentation; import org.keycloak.representations.idm.AuthenticationExecutionRepresentation; import org.keycloak.representations.idm.AuthenticationFlowRepresentation; @@ -64,7 +65,7 @@ public class ExecutionTest extends AbstractAuthenticationTest { // copy built-in flow so we get a new editable flow params.put("newName", "Copy-of-browser"); Response response = authMgmtResource.copy("browser", params); - assertAdminEvents.assertEvent(REALM_NAME, OperationType.CREATE, AdminEventPaths.authCopyFlowPath("browser"), params); + assertAdminEvents.assertEvent(REALM_NAME, OperationType.CREATE, AdminEventPaths.authCopyFlowPath("browser"), params, ResourceType.AUTH_FLOW); try { Assert.assertEquals("Copy flow", 201, response.getStatus()); } finally { @@ -83,7 +84,7 @@ public class ExecutionTest extends AbstractAuthenticationTest { // add execution - should succeed params.put("provider", "idp-review-profile"); authMgmtResource.addExecution("Copy-of-browser", params); - assertAdminEvents.assertEvent(REALM_NAME, OperationType.CREATE, AdminEventPaths.authAddExecutionPath("Copy-of-browser"), params); + assertAdminEvents.assertEvent(REALM_NAME, OperationType.CREATE, AdminEventPaths.authAddExecutionPath("Copy-of-browser"), params, ResourceType.AUTH_EXECUTION_FLOW); // check execution was added List executionReps = authMgmtResource.getExecutions("Copy-of-browser"); @@ -97,7 +98,7 @@ public class ExecutionTest extends AbstractAuthenticationTest { // remove execution authMgmtResource.removeExecution(exec.getId()); - assertAdminEvents.assertEvent(REALM_NAME, OperationType.DELETE, AdminEventPaths.authExecutionPath(exec.getId())); + assertAdminEvents.assertEvent(REALM_NAME, OperationType.DELETE, AdminEventPaths.authExecutionPath(exec.getId()), ResourceType.AUTH_EXECUTION); // check execution was removed executionReps = authMgmtResource.getExecutions("Copy-of-browser"); @@ -108,7 +109,7 @@ public class ExecutionTest extends AbstractAuthenticationTest { // delete auth-cookie authMgmtResource.removeExecution(authCookieExec.getId()); - assertAdminEvents.assertEvent(REALM_NAME, OperationType.DELETE, AdminEventPaths.authExecutionPath(authCookieExec.getId())); + assertAdminEvents.assertEvent(REALM_NAME, OperationType.DELETE, AdminEventPaths.authExecutionPath(authCookieExec.getId()), ResourceType.AUTH_EXECUTION); AuthenticationExecutionRepresentation rep = new AuthenticationExecutionRepresentation(); rep.setPriority(10); @@ -149,7 +150,7 @@ public class ExecutionTest extends AbstractAuthenticationTest { // add execution - should succeed response = authMgmtResource.addExecution(rep); - assertAdminEvents.assertEvent(REALM_NAME, OperationType.CREATE, AssertAdminEvents.isExpectedPrefixFollowedByUuid(AdminEventPaths.authMgmtBasePath() + "/executions"), rep); + assertAdminEvents.assertEvent(REALM_NAME, OperationType.CREATE, AssertAdminEvents.isExpectedPrefixFollowedByUuid(AdminEventPaths.authMgmtBasePath() + "/executions"), rep, ResourceType.AUTH_EXECUTION); try { Assert.assertEquals("added execution", 201, response.getStatus()); } finally { @@ -178,7 +179,7 @@ public class ExecutionTest extends AbstractAuthenticationTest { // switch from DISABLED to ALTERNATIVE exec.setRequirement(DISABLED); authMgmtResource.updateExecutions("browser", exec); - assertAdminEvents.assertEvent(REALM_NAME, OperationType.UPDATE, AdminEventPaths.authUpdateExecutionPath("browser"), exec); + assertAdminEvents.assertEvent(REALM_NAME, OperationType.UPDATE, AdminEventPaths.authUpdateExecutionPath("browser"), exec, ResourceType.AUTH_EXECUTION); // make sure the change is visible executionReps = authMgmtResource.getExecutions("browser"); @@ -198,7 +199,7 @@ public class ExecutionTest extends AbstractAuthenticationTest { Map executionData = new HashMap<>(); executionData.put("provider", ClientIdAndSecretAuthenticator.PROVIDER_ID); authMgmtResource.addExecution("new-client-flow", executionData); - assertAdminEvents.assertEvent(REALM_NAME, OperationType.CREATE, AdminEventPaths.authAddExecutionPath("new-client-flow"), executionData); + assertAdminEvents.assertEvent(REALM_NAME, OperationType.CREATE, AdminEventPaths.authAddExecutionPath("new-client-flow"), executionData, ResourceType.AUTH_EXECUTION); // Check executions of not-existent flow - SHOULD FAIL try { @@ -234,7 +235,7 @@ public class ExecutionTest extends AbstractAuthenticationTest { // Update success executionRep.setRequirement(ALTERNATIVE); authMgmtResource.updateExecutions("new-client-flow", executionRep); - assertAdminEvents.assertEvent(REALM_NAME, OperationType.UPDATE, AdminEventPaths.authUpdateExecutionPath("new-client-flow"), executionRep); + assertAdminEvents.assertEvent(REALM_NAME, OperationType.UPDATE, AdminEventPaths.authUpdateExecutionPath("new-client-flow"), executionRep, ResourceType.AUTH_EXECUTION); // Check updated executionRep = findExecutionByProvider(ClientIdAndSecretAuthenticator.PROVIDER_ID, authMgmtResource.getExecutions("new-client-flow")); @@ -250,10 +251,10 @@ public class ExecutionTest extends AbstractAuthenticationTest { // Successfuly remove execution and flow authMgmtResource.removeExecution(executionRep.getId()); - assertAdminEvents.assertEvent(REALM_NAME, OperationType.DELETE, AdminEventPaths.authExecutionPath(executionRep.getId())); + assertAdminEvents.assertEvent(REALM_NAME, OperationType.DELETE, AdminEventPaths.authExecutionPath(executionRep.getId()), ResourceType.AUTH_EXECUTION); AuthenticationFlowRepresentation rep = findFlowByAlias("new-client-flow", authMgmtResource.getFlows()); authMgmtResource.deleteFlow(rep.getId()); - assertAdminEvents.assertEvent(REALM_NAME, OperationType.DELETE, AdminEventPaths.authFlowPath(rep.getId())); + assertAdminEvents.assertEvent(REALM_NAME, OperationType.DELETE, AdminEventPaths.authFlowPath(rep.getId()), ResourceType.AUTH_FLOW); } } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/authentication/FlowTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/authentication/FlowTest.java index 7e2f4a8d17..de87a7a5a5 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/authentication/FlowTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/authentication/FlowTest.java @@ -20,6 +20,7 @@ package org.keycloak.testsuite.admin.authentication; import org.junit.Assert; import org.junit.Test; import org.keycloak.events.admin.OperationType; +import org.keycloak.events.admin.ResourceType; import org.keycloak.representations.idm.AuthenticationExecutionExportRepresentation; import org.keycloak.representations.idm.AuthenticationFlowRepresentation; import org.keycloak.testsuite.util.AdminEventPaths; @@ -119,7 +120,7 @@ public class FlowTest extends AbstractAuthenticationTest { // Successfully add flow data.put("alias", "SomeFlow"); authMgmtResource.addExecutionFlow("browser-2", data); - assertAdminEvents.assertEvent(REALM_NAME, OperationType.CREATE, AdminEventPaths.authAddExecutionFlowPath("browser-2"), data); + assertAdminEvents.assertEvent(REALM_NAME, OperationType.CREATE, AdminEventPaths.authAddExecutionFlowPath("browser-2"), data, ResourceType.AUTH_EXECUTION_FLOW); // check that new flow is returned in a children list flows = authMgmtResource.getFlows(); @@ -141,7 +142,7 @@ public class FlowTest extends AbstractAuthenticationTest { // delete non-built-in flow authMgmtResource.deleteFlow(found.getId()); - assertAdminEvents.assertEvent(REALM_NAME, OperationType.DELETE, AdminEventPaths.authFlowPath(found.getId())); + assertAdminEvents.assertEvent(REALM_NAME, OperationType.DELETE, AdminEventPaths.authFlowPath(found.getId()), ResourceType.AUTH_EXECUTION_FLOW); // check the deleted flow is no longer returned flows = authMgmtResource.getFlows(); @@ -184,7 +185,7 @@ public class FlowTest extends AbstractAuthenticationTest { // copy that should succeed params.put("newName", "Copy of browser"); response = authMgmtResource.copy("browser", params); - assertAdminEvents.assertEvent(REALM_NAME, OperationType.CREATE, AdminEventPaths.authCopyFlowPath("browser"), params); + assertAdminEvents.assertEvent(REALM_NAME, OperationType.CREATE, AdminEventPaths.authCopyFlowPath("browser"), params, ResourceType.AUTH_FLOW); try { Assert.assertEquals("Copy flow", 201, response.getStatus()); } finally { @@ -219,7 +220,7 @@ public class FlowTest extends AbstractAuthenticationTest { Response response = authMgmtResource.copy("browser", params); Assert.assertEquals(201, response.getStatus()); response.close(); - assertAdminEvents.assertEvent(REALM_NAME, OperationType.CREATE, AdminEventPaths.authCopyFlowPath("browser"), params); + assertAdminEvents.assertEvent(REALM_NAME, OperationType.CREATE, AdminEventPaths.authCopyFlowPath("browser"), params, ResourceType.AUTH_FLOW); params = new HashMap<>(); params.put("alias", "child"); @@ -228,7 +229,7 @@ public class FlowTest extends AbstractAuthenticationTest { params.put("type", "basic-flow"); authMgmtResource.addExecutionFlow("parent", params); - assertAdminEvents.assertEvent(REALM_NAME, OperationType.CREATE, AdminEventPaths.authAddExecutionFlowPath("parent"), params); + assertAdminEvents.assertEvent(REALM_NAME, OperationType.CREATE, AdminEventPaths.authAddExecutionFlowPath("parent"), params, ResourceType.AUTH_EXECUTION_FLOW); } } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/authentication/RegistrationFlowTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/authentication/RegistrationFlowTest.java index d7e25b6401..30d6916b17 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/authentication/RegistrationFlowTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/authentication/RegistrationFlowTest.java @@ -26,6 +26,7 @@ import javax.ws.rs.core.Response; import org.junit.Assert; import org.junit.Test; import org.keycloak.events.admin.OperationType; +import org.keycloak.events.admin.ResourceType; import org.keycloak.representations.idm.AuthenticationFlowRepresentation; import org.keycloak.testsuite.util.AdminEventPaths; @@ -47,7 +48,7 @@ public class RegistrationFlowTest extends AbstractAuthenticationTest { data.put("description", "registrationForm2 flow"); data.put("provider", "registration-page-form"); authMgmtResource.addExecutionFlow("registration2", data); - assertAdminEvents.assertEvent(REALM_NAME, OperationType.CREATE, AdminEventPaths.authAddExecutionFlowPath("registration2"), data); + assertAdminEvents.assertEvent(REALM_NAME, OperationType.CREATE, AdminEventPaths.authAddExecutionFlowPath("registration2"), data, ResourceType.AUTH_EXECUTION_FLOW); // Should fail to add execution under top level flow Map data2 = new HashMap<>(); @@ -62,7 +63,7 @@ public class RegistrationFlowTest extends AbstractAuthenticationTest { // Should success to add execution under form flow authMgmtResource.addExecution("registrationForm2", data2); - assertAdminEvents.assertEvent(REALM_NAME, OperationType.CREATE, AdminEventPaths.authAddExecutionPath("registrationForm2"), data2); + assertAdminEvents.assertEvent(REALM_NAME, OperationType.CREATE, AdminEventPaths.authAddExecutionPath("registrationForm2"), data2, ResourceType.AUTH_EXECUTION_FLOW); } // TODO: More type-safety instead of passing generic maps diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/authentication/RequiredActionsTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/authentication/RequiredActionsTest.java index 5354626b36..1b7f79f144 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/authentication/RequiredActionsTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/authentication/RequiredActionsTest.java @@ -20,6 +20,7 @@ package org.keycloak.testsuite.admin.authentication; import org.junit.Assert; import org.junit.Test; import org.keycloak.events.admin.OperationType; +import org.keycloak.events.admin.ResourceType; import org.keycloak.representations.idm.RequiredActionProviderRepresentation; import org.keycloak.representations.idm.RequiredActionProviderSimpleRepresentation; import org.keycloak.testsuite.actions.DummyRequiredActionFactory; @@ -61,7 +62,7 @@ public class RequiredActionsTest extends AbstractAuthenticationTest { forUpdate.setConfig(Collections.emptyMap()); authMgmtResource.updateRequiredAction(forUpdate.getAlias(), forUpdate); - assertAdminEvents.assertEvent(REALM_NAME, OperationType.UPDATE, AdminEventPaths.authRequiredActionPath(forUpdate.getAlias())); + assertAdminEvents.assertEvent(REALM_NAME, OperationType.UPDATE, AdminEventPaths.authRequiredActionPath(forUpdate.getAlias()), ResourceType.REQUIRED_ACTION); result = authMgmtResource.getRequiredActions(); RequiredActionProviderRepresentation updated = findRequiredActionByAlias(forUpdate.getAlias(), result); @@ -81,7 +82,7 @@ public class RequiredActionsTest extends AbstractAuthenticationTest { // Register it authMgmtResource.registerRequiredAction(action); - assertAdminEvents.assertEvent(REALM_NAME, OperationType.CREATE, AdminEventPaths.authMgmtBasePath() + "/register-required-action", action); + assertAdminEvents.assertEvent(REALM_NAME, OperationType.CREATE, AdminEventPaths.authMgmtBasePath() + "/register-required-action", action, ResourceType.REQUIRED_ACTION); // Try to find not-existent action - should fail try { @@ -107,7 +108,7 @@ public class RequiredActionsTest extends AbstractAuthenticationTest { // Update (set it as defaultAction) rep.setDefaultAction(true); authMgmtResource.updateRequiredAction(DummyRequiredActionFactory.PROVIDER_ID, rep); - assertAdminEvents.assertEvent(REALM_NAME, OperationType.UPDATE, AdminEventPaths.authRequiredActionPath(rep.getAlias()), rep); + assertAdminEvents.assertEvent(REALM_NAME, OperationType.UPDATE, AdminEventPaths.authRequiredActionPath(rep.getAlias()), rep, ResourceType.REQUIRED_ACTION); compareRequiredAction(rep, newRequiredAction(DummyRequiredActionFactory.PROVIDER_ID, "Dummy Action", true, true, Collections.emptyMap())); @@ -121,7 +122,7 @@ public class RequiredActionsTest extends AbstractAuthenticationTest { // Remove success authMgmtResource.removeRequiredAction(DummyRequiredActionFactory.PROVIDER_ID); - assertAdminEvents.assertEvent(REALM_NAME, OperationType.DELETE, AdminEventPaths.authRequiredActionPath(rep.getAlias())); + assertAdminEvents.assertEvent(REALM_NAME, OperationType.DELETE, AdminEventPaths.authRequiredActionPath(rep.getAlias()), ResourceType.REQUIRED_ACTION); } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/authentication/ShiftExecutionTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/authentication/ShiftExecutionTest.java index ba8ae09197..ac2ab44366 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/authentication/ShiftExecutionTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/authentication/ShiftExecutionTest.java @@ -20,6 +20,7 @@ package org.keycloak.testsuite.admin.authentication; import org.junit.Assert; import org.junit.Test; import org.keycloak.events.admin.OperationType; +import org.keycloak.events.admin.ResourceType; import org.keycloak.representations.idm.AuthenticationExecutionInfoRepresentation; import org.keycloak.testsuite.util.AdminEventPaths; @@ -41,7 +42,7 @@ public class ShiftExecutionTest extends AbstractAuthenticationTest { HashMap params = new HashMap<>(); params.put("newName", "Copy of browser"); Response response = authMgmtResource.copy("browser", params); - assertAdminEvents.assertEvent(REALM_NAME, OperationType.CREATE, AdminEventPaths.authCopyFlowPath("browser"), params); + assertAdminEvents.assertEvent(REALM_NAME, OperationType.CREATE, AdminEventPaths.authCopyFlowPath("browser"), params, ResourceType.AUTH_FLOW); try { Assert.assertEquals("Copy flow", 201, response.getStatus()); } finally { @@ -64,7 +65,7 @@ public class ShiftExecutionTest extends AbstractAuthenticationTest { // shift last execution up authMgmtResource.raisePriority(last.getId()); - assertAdminEvents.assertEvent(REALM_NAME, OperationType.UPDATE, AdminEventPaths.authRaiseExecutionPath(last.getId())); + assertAdminEvents.assertEvent(REALM_NAME, OperationType.UPDATE, AdminEventPaths.authRaiseExecutionPath(last.getId()), ResourceType.AUTH_EXECUTION); List executions2 = authMgmtResource.getExecutions("Copy of browser"); @@ -84,7 +85,7 @@ public class ShiftExecutionTest extends AbstractAuthenticationTest { // shift one before last down authMgmtResource.lowerPriority(oneButLast2.getId()); - assertAdminEvents.assertEvent(REALM_NAME, OperationType.UPDATE, AdminEventPaths.authLowerExecutionPath(oneButLast2.getId())); + assertAdminEvents.assertEvent(REALM_NAME, OperationType.UPDATE, AdminEventPaths.authLowerExecutionPath(oneButLast2.getId()), ResourceType.AUTH_EXECUTION); executions2 = authMgmtResource.getExecutions("Copy of browser"); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/AbstractClientTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/AbstractClientTest.java index 2fb5ccd411..813f0678b6 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/AbstractClientTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/AbstractClientTest.java @@ -25,6 +25,7 @@ import org.junit.Before; import org.junit.Rule; import org.keycloak.admin.client.resource.ClientResource; import org.keycloak.events.admin.OperationType; +import org.keycloak.events.admin.ResourceType; import org.keycloak.representations.idm.ClientRepresentation; import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.representations.idm.UserRepresentation; @@ -97,7 +98,7 @@ public abstract class AbstractClientTest extends AbstractAuthTest { resp.close(); String id = ApiUtil.getCreatedId(resp); - assertAdminEvents.assertEvent(getRealmId(), OperationType.CREATE, AdminEventPaths.clientResourcePath(id), clientRep); + assertAdminEvents.assertEvent(getRealmId(), OperationType.CREATE, AdminEventPaths.clientResourcePath(id), clientRep, ResourceType.CLIENT); return id; } @@ -105,7 +106,7 @@ public abstract class AbstractClientTest extends AbstractAuthTest { protected void removeClient(String clientDbId) { testRealmResource().clients().get(clientDbId).remove(); - assertAdminEvents.assertEvent(getRealmId(), OperationType.DELETE, AdminEventPaths.clientResourcePath(clientDbId)); + assertAdminEvents.assertEvent(getRealmId(), OperationType.DELETE, AdminEventPaths.clientResourcePath(clientDbId), ResourceType.CLIENT); } protected ClientRepresentation findClientRepresentation(String name) { diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/AbstractProtocolMapperTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/AbstractProtocolMapperTest.java index e245e428ef..af7cf3b517 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/AbstractProtocolMapperTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/AbstractProtocolMapperTest.java @@ -27,6 +27,7 @@ import java.util.Map; import com.fasterxml.jackson.core.type.TypeReference; import org.keycloak.admin.client.resource.ProtocolMappersResource; import org.keycloak.events.admin.OperationType; +import org.keycloak.events.admin.ResourceType; import org.keycloak.representations.idm.AdminEventRepresentation; import org.keycloak.representations.idm.ProtocolMapperRepresentation; import org.keycloak.testsuite.Assert; @@ -109,7 +110,7 @@ public abstract class AbstractProtocolMapperTest extends AbstractClientTest { // This is used by admin console to add builtin mappers resource.createMapper(mappersToAdd); - AdminEventRepresentation adminEvent = assertAdminEvents.assertEvent(getRealmId(), OperationType.CREATE, adminEventPath + "/add-models"); + AdminEventRepresentation adminEvent = assertAdminEvents.assertEvent(getRealmId(), OperationType.CREATE, adminEventPath + "/add-models", ResourceType.PROTOCOL_MAPPER); try { List eventMappers = JsonSerialization.readValue(new ByteArrayInputStream(adminEvent.getRepresentation().getBytes()), new TypeReference>() { }); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/ClientProtocolMapperTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/ClientProtocolMapperTest.java index 439c0df9d7..3f609b7477 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/ClientProtocolMapperTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/ClientProtocolMapperTest.java @@ -25,6 +25,7 @@ import org.junit.Test; import org.keycloak.admin.client.resource.ClientResource; import org.keycloak.admin.client.resource.ProtocolMappersResource; import org.keycloak.events.admin.OperationType; +import org.keycloak.events.admin.ResourceType; import org.keycloak.representations.idm.ProtocolMapperRepresentation; import org.keycloak.testsuite.Assert; import org.keycloak.testsuite.admin.ApiUtil; @@ -97,7 +98,7 @@ public class ClientProtocolMapperTest extends AbstractProtocolMapperTest { Response resp = samlMappersRsc.createMapper(rep); resp.close(); String createdId = ApiUtil.getCreatedId(resp); - assertAdminEvents.assertEvent(getRealmId(), OperationType.CREATE, AdminEventPaths.clientProtocolMapperPath(samlClientId, createdId), rep); + assertAdminEvents.assertEvent(getRealmId(), OperationType.CREATE, AdminEventPaths.clientProtocolMapperPath(samlClientId, createdId), rep, ResourceType.PROTOCOL_MAPPER); assertEquals(totalMappers + 1, samlMappersRsc.getMappers().size()); assertEquals(totalSamlMappers + 1, samlMappersRsc.getMappersPerProtocol("saml").size()); @@ -121,7 +122,7 @@ public class ClientProtocolMapperTest extends AbstractProtocolMapperTest { Response resp = oidcMappersRsc.createMapper(rep); resp.close(); String createdId = ApiUtil.getCreatedId(resp); - assertAdminEvents.assertEvent(getRealmId(), OperationType.CREATE, AdminEventPaths.clientProtocolMapperPath(oidcClientId, createdId), rep); + assertAdminEvents.assertEvent(getRealmId(), OperationType.CREATE, AdminEventPaths.clientProtocolMapperPath(oidcClientId, createdId), rep, ResourceType.PROTOCOL_MAPPER); assertEquals(totalMappers + 1, oidcMappersRsc.getMappers().size()); assertEquals(totalOidcMappers + 1, oidcMappersRsc.getMappersPerProtocol("openid-connect").size()); @@ -138,13 +139,13 @@ public class ClientProtocolMapperTest extends AbstractProtocolMapperTest { Response resp = samlMappersRsc.createMapper(rep); resp.close(); String createdId = ApiUtil.getCreatedId(resp); - assertAdminEvents.assertEvent(getRealmId(), OperationType.CREATE, AdminEventPaths.clientProtocolMapperPath(samlClientId, createdId), rep); + assertAdminEvents.assertEvent(getRealmId(), OperationType.CREATE, AdminEventPaths.clientProtocolMapperPath(samlClientId, createdId), rep, ResourceType.PROTOCOL_MAPPER); rep.getConfig().put("role", "account.manage-account"); rep.setId(createdId); rep.setConsentRequired(false); samlMappersRsc.update(createdId, rep); - assertAdminEvents.assertEvent(getRealmId(), OperationType.UPDATE, AdminEventPaths.clientProtocolMapperPath(samlClientId, createdId), rep); + assertAdminEvents.assertEvent(getRealmId(), OperationType.UPDATE, AdminEventPaths.clientProtocolMapperPath(samlClientId, createdId), rep, ResourceType.PROTOCOL_MAPPER); ProtocolMapperRepresentation updated = samlMappersRsc.getMapperById(createdId); assertEqualMappers(rep, updated); @@ -157,13 +158,13 @@ public class ClientProtocolMapperTest extends AbstractProtocolMapperTest { Response resp = oidcMappersRsc.createMapper(rep); resp.close(); String createdId = ApiUtil.getCreatedId(resp); - assertAdminEvents.assertEvent(getRealmId(), OperationType.CREATE, AdminEventPaths.clientProtocolMapperPath(oidcClientId, createdId), rep); + assertAdminEvents.assertEvent(getRealmId(), OperationType.CREATE, AdminEventPaths.clientProtocolMapperPath(oidcClientId, createdId), rep, ResourceType.PROTOCOL_MAPPER); rep.getConfig().put("role", "myotherrole"); rep.setId(createdId); rep.setConsentRequired(false); oidcMappersRsc.update(createdId, rep); - assertAdminEvents.assertEvent(getRealmId(), OperationType.UPDATE, AdminEventPaths.clientProtocolMapperPath(oidcClientId, createdId), rep); + assertAdminEvents.assertEvent(getRealmId(), OperationType.UPDATE, AdminEventPaths.clientProtocolMapperPath(oidcClientId, createdId), rep, ResourceType.PROTOCOL_MAPPER); ProtocolMapperRepresentation updated = oidcMappersRsc.getMapperById(createdId); assertEqualMappers(rep, updated); @@ -176,10 +177,10 @@ public class ClientProtocolMapperTest extends AbstractProtocolMapperTest { Response resp = samlMappersRsc.createMapper(rep); resp.close(); String createdId = ApiUtil.getCreatedId(resp); - assertAdminEvents.assertEvent(getRealmId(), OperationType.CREATE, AdminEventPaths.clientProtocolMapperPath(samlClientId, createdId), rep); + assertAdminEvents.assertEvent(getRealmId(), OperationType.CREATE, AdminEventPaths.clientProtocolMapperPath(samlClientId, createdId), rep, ResourceType.PROTOCOL_MAPPER); samlMappersRsc.delete(createdId); - assertAdminEvents.assertEvent(getRealmId(), OperationType.DELETE, AdminEventPaths.clientProtocolMapperPath(samlClientId, createdId)); + assertAdminEvents.assertEvent(getRealmId(), OperationType.DELETE, AdminEventPaths.clientProtocolMapperPath(samlClientId, createdId), ResourceType.PROTOCOL_MAPPER); try { samlMappersRsc.getMapperById(createdId); @@ -196,10 +197,10 @@ public class ClientProtocolMapperTest extends AbstractProtocolMapperTest { Response resp = oidcMappersRsc.createMapper(rep); resp.close(); String createdId = ApiUtil.getCreatedId(resp); - assertAdminEvents.assertEvent(getRealmId(), OperationType.CREATE, AdminEventPaths.clientProtocolMapperPath(oidcClientId, createdId), rep); + assertAdminEvents.assertEvent(getRealmId(), OperationType.CREATE, AdminEventPaths.clientProtocolMapperPath(oidcClientId, createdId), rep, ResourceType.PROTOCOL_MAPPER); oidcMappersRsc.delete(createdId); - assertAdminEvents.assertEvent(getRealmId(), OperationType.DELETE, AdminEventPaths.clientProtocolMapperPath(oidcClientId, createdId)); + assertAdminEvents.assertEvent(getRealmId(), OperationType.DELETE, AdminEventPaths.clientProtocolMapperPath(oidcClientId, createdId), ResourceType.PROTOCOL_MAPPER); try { oidcMappersRsc.getMapperById(createdId); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/ClientRolesTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/ClientRolesTest.java index aed3461aa4..2aa5933712 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/ClientRolesTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/ClientRolesTest.java @@ -23,6 +23,7 @@ import org.junit.Test; import org.keycloak.admin.client.resource.ClientResource; import org.keycloak.admin.client.resource.RolesResource; import org.keycloak.events.admin.OperationType; +import org.keycloak.events.admin.ResourceType; import org.keycloak.representations.idm.RoleRepresentation; import org.keycloak.testsuite.Assert; import org.keycloak.testsuite.util.AdminEventPaths; @@ -75,7 +76,7 @@ public class ClientRolesTest extends AbstractClientTest { public void testAddRole() { RoleRepresentation role1 = makeRole("role1"); rolesRsc.create(role1); - assertAdminEvents.assertEvent(getRealmId(), OperationType.CREATE, AdminEventPaths.clientRoleResourcePath(clientDbId, "role1"), role1); + assertAdminEvents.assertEvent(getRealmId(), OperationType.CREATE, AdminEventPaths.clientRoleResourcePath(clientDbId, "role1"), role1, ResourceType.CLIENT_ROLE); assertTrue(hasRole(rolesRsc, "role1")); } @@ -83,10 +84,10 @@ public class ClientRolesTest extends AbstractClientTest { public void testRemoveRole() { RoleRepresentation role2 = makeRole("role2"); rolesRsc.create(role2); - assertAdminEvents.assertEvent(getRealmId(), OperationType.CREATE, AdminEventPaths.clientRoleResourcePath(clientDbId, "role2"), role2); + assertAdminEvents.assertEvent(getRealmId(), OperationType.CREATE, AdminEventPaths.clientRoleResourcePath(clientDbId, "role2"), role2, ResourceType.CLIENT_ROLE); rolesRsc.deleteRole("role2"); - assertAdminEvents.assertEvent(getRealmId(), OperationType.DELETE, AdminEventPaths.clientRoleResourcePath(clientDbId, "role2")); + assertAdminEvents.assertEvent(getRealmId(), OperationType.DELETE, AdminEventPaths.clientRoleResourcePath(clientDbId, "role2"), ResourceType.CLIENT_ROLE); assertFalse(hasRole(rolesRsc, "role2")); } @@ -95,24 +96,24 @@ public class ClientRolesTest extends AbstractClientTest { public void testComposites() { RoleRepresentation roleA = makeRole("role-a"); rolesRsc.create(roleA); - assertAdminEvents.assertEvent(getRealmId(), OperationType.CREATE, AdminEventPaths.clientRoleResourcePath(clientDbId, "role-a"), roleA); + assertAdminEvents.assertEvent(getRealmId(), OperationType.CREATE, AdminEventPaths.clientRoleResourcePath(clientDbId, "role-a"), roleA, ResourceType.CLIENT_ROLE); assertFalse(rolesRsc.get("role-a").toRepresentation().isComposite()); assertEquals(0, rolesRsc.get("role-a").getRoleComposites().size()); RoleRepresentation roleB = makeRole("role-b"); rolesRsc.create(roleB); - assertAdminEvents.assertEvent(getRealmId(), OperationType.CREATE, AdminEventPaths.clientRoleResourcePath(clientDbId, "role-b"), roleB); + assertAdminEvents.assertEvent(getRealmId(), OperationType.CREATE, AdminEventPaths.clientRoleResourcePath(clientDbId, "role-b"), roleB, ResourceType.CLIENT_ROLE); RoleRepresentation roleC = makeRole("role-c"); testRealmResource().roles().create(roleC); - assertAdminEvents.assertEvent(getRealmId(), OperationType.CREATE, AdminEventPaths.roleResourcePath("role-c"), roleC); + assertAdminEvents.assertEvent(getRealmId(), OperationType.CREATE, AdminEventPaths.roleResourcePath("role-c"), roleC, ResourceType.REALM_ROLE); List l = new LinkedList<>(); l.add(rolesRsc.get("role-b").toRepresentation()); l.add(testRealmResource().roles().get("role-c").toRepresentation()); rolesRsc.get("role-a").addComposites(l); - assertAdminEvents.assertEvent(getRealmId(), OperationType.CREATE, AdminEventPaths.clientRoleResourceCompositesPath(clientDbId, "role-a"), l); + assertAdminEvents.assertEvent(getRealmId(), OperationType.CREATE, AdminEventPaths.clientRoleResourceCompositesPath(clientDbId, "role-a"), l, ResourceType.CLIENT_ROLE); Set composites = rolesRsc.get("role-a").getRoleComposites(); @@ -126,7 +127,7 @@ public class ClientRolesTest extends AbstractClientTest { Assert.assertNames(clientComposites, "role-b"); rolesRsc.get("role-a").deleteComposites(l); - assertAdminEvents.assertEvent(getRealmId(), OperationType.DELETE, AdminEventPaths.clientRoleResourceCompositesPath(clientDbId, "role-a"), l); + assertAdminEvents.assertEvent(getRealmId(), OperationType.DELETE, AdminEventPaths.clientRoleResourceCompositesPath(clientDbId, "role-a"), l, ResourceType.CLIENT_ROLE); assertFalse(rolesRsc.get("role-a").toRepresentation().isComposite()); assertEquals(0, rolesRsc.get("role-a").getRoleComposites().size()); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/ClientTemplateProtocolMapperTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/ClientTemplateProtocolMapperTest.java index 1036005056..5a82f0d939 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/ClientTemplateProtocolMapperTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/ClientTemplateProtocolMapperTest.java @@ -29,6 +29,7 @@ import org.junit.runners.MethodSorters; import org.keycloak.admin.client.resource.ClientTemplatesResource; import org.keycloak.admin.client.resource.ProtocolMappersResource; import org.keycloak.events.admin.OperationType; +import org.keycloak.events.admin.ResourceType; import org.keycloak.protocol.oidc.OIDCLoginProtocol; import org.keycloak.protocol.saml.SamlProtocol; import org.keycloak.representations.idm.ClientTemplateRepresentation; @@ -100,7 +101,7 @@ public class ClientTemplateProtocolMapperTest extends AbstractProtocolMapperTest resp.close(); String createdId = ApiUtil.getCreatedId(resp); - assertAdminEvents.assertEvent(getRealmId(), OperationType.CREATE, AdminEventPaths.clientTemplateProtocolMapperPath(samlClientTemplateId, createdId), rep); + assertAdminEvents.assertEvent(getRealmId(), OperationType.CREATE, AdminEventPaths.clientTemplateProtocolMapperPath(samlClientTemplateId, createdId), rep, ResourceType.PROTOCOL_MAPPER); assertEquals(totalMappers + 1, samlMappersRsc.getMappers().size()); assertEquals(totalSamlMappers + 1, samlMappersRsc.getMappersPerProtocol("saml").size()); @@ -125,7 +126,7 @@ public class ClientTemplateProtocolMapperTest extends AbstractProtocolMapperTest resp.close(); String createdId = ApiUtil.getCreatedId(resp); - assertAdminEvents.assertEvent(getRealmId(), OperationType.CREATE, AdminEventPaths.clientTemplateProtocolMapperPath(oidcClientTemplateId, createdId), rep); + assertAdminEvents.assertEvent(getRealmId(), OperationType.CREATE, AdminEventPaths.clientTemplateProtocolMapperPath(oidcClientTemplateId, createdId), rep, ResourceType.PROTOCOL_MAPPER); assertEquals(totalMappers + 1, oidcMappersRsc.getMappers().size()); assertEquals(totalOidcMappers + 1, oidcMappersRsc.getMappersPerProtocol("openid-connect").size()); @@ -141,13 +142,13 @@ public class ClientTemplateProtocolMapperTest extends AbstractProtocolMapperTest Response resp = samlMappersRsc.createMapper(rep); resp.close(); String createdId = ApiUtil.getCreatedId(resp); - assertAdminEvents.assertEvent(getRealmId(), OperationType.CREATE, AdminEventPaths.clientTemplateProtocolMapperPath(samlClientTemplateId, createdId), rep); + assertAdminEvents.assertEvent(getRealmId(), OperationType.CREATE, AdminEventPaths.clientTemplateProtocolMapperPath(samlClientTemplateId, createdId), rep, ResourceType.PROTOCOL_MAPPER); rep.getConfig().put("role", "account.manage-account"); rep.setId(createdId); rep.setConsentRequired(false); samlMappersRsc.update(createdId, rep); - assertAdminEvents.assertEvent(getRealmId(), OperationType.UPDATE, AdminEventPaths.clientTemplateProtocolMapperPath(samlClientTemplateId, createdId), rep); + assertAdminEvents.assertEvent(getRealmId(), OperationType.UPDATE, AdminEventPaths.clientTemplateProtocolMapperPath(samlClientTemplateId, createdId), rep, ResourceType.PROTOCOL_MAPPER); ProtocolMapperRepresentation updated = samlMappersRsc.getMapperById(createdId); assertEqualMappers(rep, updated); @@ -160,13 +161,13 @@ public class ClientTemplateProtocolMapperTest extends AbstractProtocolMapperTest Response resp = oidcMappersRsc.createMapper(rep); resp.close(); String createdId = ApiUtil.getCreatedId(resp); - assertAdminEvents.assertEvent(getRealmId(), OperationType.CREATE, AdminEventPaths.clientTemplateProtocolMapperPath(oidcClientTemplateId, createdId), rep); + assertAdminEvents.assertEvent(getRealmId(), OperationType.CREATE, AdminEventPaths.clientTemplateProtocolMapperPath(oidcClientTemplateId, createdId), rep, ResourceType.PROTOCOL_MAPPER); rep.getConfig().put("role", "myotherrole"); rep.setId(createdId); rep.setConsentRequired(false); oidcMappersRsc.update(createdId, rep); - assertAdminEvents.assertEvent(getRealmId(), OperationType.UPDATE, AdminEventPaths.clientTemplateProtocolMapperPath(oidcClientTemplateId, createdId), rep); + assertAdminEvents.assertEvent(getRealmId(), OperationType.UPDATE, AdminEventPaths.clientTemplateProtocolMapperPath(oidcClientTemplateId, createdId), rep, ResourceType.PROTOCOL_MAPPER); ProtocolMapperRepresentation updated = oidcMappersRsc.getMapperById(createdId); assertEqualMappers(rep, updated); @@ -179,10 +180,10 @@ public class ClientTemplateProtocolMapperTest extends AbstractProtocolMapperTest Response resp = samlMappersRsc.createMapper(rep); resp.close(); String createdId = ApiUtil.getCreatedId(resp); - assertAdminEvents.assertEvent(getRealmId(), OperationType.CREATE, AdminEventPaths.clientTemplateProtocolMapperPath(samlClientTemplateId, createdId), rep); + assertAdminEvents.assertEvent(getRealmId(), OperationType.CREATE, AdminEventPaths.clientTemplateProtocolMapperPath(samlClientTemplateId, createdId), rep, ResourceType.PROTOCOL_MAPPER); samlMappersRsc.delete(createdId); - assertAdminEvents.assertEvent(getRealmId(), OperationType.DELETE, AdminEventPaths.clientTemplateProtocolMapperPath(samlClientTemplateId, createdId)); + assertAdminEvents.assertEvent(getRealmId(), OperationType.DELETE, AdminEventPaths.clientTemplateProtocolMapperPath(samlClientTemplateId, createdId), ResourceType.PROTOCOL_MAPPER); try { samlMappersRsc.getMapperById(createdId); @@ -199,10 +200,10 @@ public class ClientTemplateProtocolMapperTest extends AbstractProtocolMapperTest Response resp = oidcMappersRsc.createMapper(rep); resp.close(); String createdId = ApiUtil.getCreatedId(resp); - assertAdminEvents.assertEvent(getRealmId(), OperationType.CREATE, AdminEventPaths.clientTemplateProtocolMapperPath(oidcClientTemplateId, createdId), rep); + assertAdminEvents.assertEvent(getRealmId(), OperationType.CREATE, AdminEventPaths.clientTemplateProtocolMapperPath(oidcClientTemplateId, createdId), rep, ResourceType.PROTOCOL_MAPPER); oidcMappersRsc.delete(createdId); - assertAdminEvents.assertEvent(getRealmId(), OperationType.DELETE, AdminEventPaths.clientTemplateProtocolMapperPath(oidcClientTemplateId, createdId)); + assertAdminEvents.assertEvent(getRealmId(), OperationType.DELETE, AdminEventPaths.clientTemplateProtocolMapperPath(oidcClientTemplateId, createdId), ResourceType.PROTOCOL_MAPPER); try { oidcMappersRsc.getMapperById(createdId); @@ -227,13 +228,13 @@ public class ClientTemplateProtocolMapperTest extends AbstractProtocolMapperTest resp.close(); String templateId = ApiUtil.getCreatedId(resp); - assertAdminEvents.assertEvent(getRealmId(), OperationType.CREATE, AdminEventPaths.clientTemplateResourcePath(templateId), rep); + assertAdminEvents.assertEvent(getRealmId(), OperationType.CREATE, AdminEventPaths.clientTemplateResourcePath(templateId), rep, ResourceType.CLIENT_TEMPLATE); return templateId; } private void removeTemplate(String templateId) { clientTemplates().get(templateId).remove(); - assertAdminEvents.assertEvent(getRealmId(), OperationType.DELETE, AdminEventPaths.clientTemplateResourcePath(templateId)); + assertAdminEvents.assertEvent(getRealmId(), OperationType.DELETE, AdminEventPaths.clientTemplateResourcePath(templateId), ResourceType.CLIENT_TEMPLATE); } } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/ClientTemplateTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/ClientTemplateTest.java index 2b469a9b5f..33cf14b115 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/ClientTemplateTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/ClientTemplateTest.java @@ -32,6 +32,7 @@ import org.junit.Test; import org.keycloak.admin.client.resource.ClientTemplatesResource; import org.keycloak.admin.client.resource.RoleMappingResource; import org.keycloak.events.admin.OperationType; +import org.keycloak.events.admin.ResourceType; import org.keycloak.models.AccountRoles; import org.keycloak.models.Constants; import org.keycloak.protocol.oidc.OIDCLoginProtocol; @@ -137,7 +138,7 @@ public class ClientTemplateTest extends AbstractClientTest { clientTemplates().get(template1Id).update(templateRep); - assertAdminEvents.assertEvent(getRealmId(), OperationType.UPDATE, AdminEventPaths.clientTemplateResourcePath(template1Id), templateRep); + assertAdminEvents.assertEvent(getRealmId(), OperationType.UPDATE, AdminEventPaths.clientTemplateResourcePath(template1Id), templateRep, ResourceType.CLIENT_TEMPLATE); // Assert updated attributes templateRep = clientTemplates().get(template1Id).toRepresentation(); @@ -161,7 +162,7 @@ public class ClientTemplateTest extends AbstractClientTest { // Add role2 as composite to role1 testRealmResource().roles().get("role1").addComposites(Collections.singletonList(roleRep2)); - assertAdminEvents.assertEvent(getRealmId(), OperationType.CREATE, AdminEventPaths.roleResourceCompositesPath("role1"), Collections.singletonList(roleRep2)); + assertAdminEvents.assertEvent(getRealmId(), OperationType.CREATE, AdminEventPaths.roleResourceCompositesPath("role1"), Collections.singletonList(roleRep2), ResourceType.REALM_ROLE); // create client template ClientTemplateRepresentation templateRep = new ClientTemplateRepresentation(); @@ -175,10 +176,10 @@ public class ClientTemplateTest extends AbstractClientTest { RoleMappingResource scopesResource = clientTemplates().get(templateId).getScopeMappings(); scopesResource.realmLevel().add(Collections.singletonList(roleRep1)); - assertAdminEvents.assertEvent(getRealmId(), OperationType.CREATE, AdminEventPaths.clientTemplateScopeMappingsRealmLevelPath(templateId), Collections.singletonList(roleRep1)); + assertAdminEvents.assertEvent(getRealmId(), OperationType.CREATE, AdminEventPaths.clientTemplateScopeMappingsRealmLevelPath(templateId), Collections.singletonList(roleRep1), ResourceType.CLIENT_TEMPLATE); scopesResource.clientLevel(accountMgmtId).add(Collections.singletonList(viewAccountRoleRep)); - assertAdminEvents.assertEvent(getRealmId(), OperationType.CREATE, AdminEventPaths.clientTemplateScopeMappingsClientLevelPath(templateId, accountMgmtId), Collections.singletonList(viewAccountRoleRep)); + assertAdminEvents.assertEvent(getRealmId(), OperationType.CREATE, AdminEventPaths.clientTemplateScopeMappingsClientLevelPath(templateId, accountMgmtId), Collections.singletonList(viewAccountRoleRep), ResourceType.CLIENT_TEMPLATE); // test that scopes are available (also through composite role) List allRealm = scopesResource.realmLevel().listAll(); @@ -197,10 +198,10 @@ public class ClientTemplateTest extends AbstractClientTest { // remove scopes scopesResource.realmLevel().remove(Collections.singletonList(roleRep1)); - assertAdminEvents.assertEvent(getRealmId(), OperationType.DELETE, AdminEventPaths.clientTemplateScopeMappingsRealmLevelPath(templateId), Collections.singletonList(roleRep1)); + assertAdminEvents.assertEvent(getRealmId(), OperationType.DELETE, AdminEventPaths.clientTemplateScopeMappingsRealmLevelPath(templateId), Collections.singletonList(roleRep1), ResourceType.CLIENT_TEMPLATE); scopesResource.clientLevel(accountMgmtId).remove(Collections.singletonList(viewAccountRoleRep)); - assertAdminEvents.assertEvent(getRealmId(), OperationType.DELETE, AdminEventPaths.clientTemplateScopeMappingsClientLevelPath(templateId, accountMgmtId), Collections.singletonList(viewAccountRoleRep)); + assertAdminEvents.assertEvent(getRealmId(), OperationType.DELETE, AdminEventPaths.clientTemplateScopeMappingsClientLevelPath(templateId, accountMgmtId), Collections.singletonList(viewAccountRoleRep), ResourceType.CLIENT_TEMPLATE); // assert scopes are removed allRealm = scopesResource.realmLevel().listAll(); @@ -255,7 +256,7 @@ public class ClientTemplateTest extends AbstractClientTest { // Add realm role to scopes of clientTemplate clientTemplates().get(templateId).getScopeMappings().realmLevel().add(Collections.singletonList(roleRep)); - assertAdminEvents.assertEvent(getRealmId(), OperationType.CREATE, AdminEventPaths.clientTemplateScopeMappingsRealmLevelPath(templateId), Collections.singletonList(roleRep)); + assertAdminEvents.assertEvent(getRealmId(), OperationType.CREATE, AdminEventPaths.clientTemplateScopeMappingsRealmLevelPath(templateId), Collections.singletonList(roleRep), ResourceType.CLIENT_TEMPLATE); List roleReps = clientTemplates().get(templateId).getScopeMappings().realmLevel().listAll(); Assert.assertEquals(1, roleReps.size()); @@ -263,7 +264,7 @@ public class ClientTemplateTest extends AbstractClientTest { // Remove realm role testRealmResource().roles().deleteRole("foo-role"); - assertAdminEvents.assertEvent(getRealmId(), OperationType.DELETE, AdminEventPaths.roleResourcePath("foo-role")); + assertAdminEvents.assertEvent(getRealmId(), OperationType.DELETE, AdminEventPaths.roleResourcePath("foo-role"), ResourceType.REALM_ROLE); // Get scope mappings roleReps = clientTemplates().get(templateId).getScopeMappings().realmLevel().listAll(); @@ -278,7 +279,7 @@ public class ClientTemplateTest extends AbstractClientTest { roleRep.setName(roleName); testRealmResource().roles().create(roleRep); - assertAdminEvents.assertEvent(getRealmId(), OperationType.CREATE, AdminEventPaths.roleResourcePath(roleName), roleRep); + assertAdminEvents.assertEvent(getRealmId(), OperationType.CREATE, AdminEventPaths.roleResourcePath(roleName), roleRep, ResourceType.REALM_ROLE); return testRealmResource().roles().get(roleName).toRepresentation(); } @@ -329,14 +330,14 @@ public class ClientTemplateTest extends AbstractClientTest { resp.close(); String templateId = ApiUtil.getCreatedId(resp); - assertAdminEvents.assertEvent(getRealmId(), OperationType.CREATE, AdminEventPaths.clientTemplateResourcePath(templateId), templateRep); + assertAdminEvents.assertEvent(getRealmId(), OperationType.CREATE, AdminEventPaths.clientTemplateResourcePath(templateId), templateRep, ResourceType.CLIENT_TEMPLATE); return templateId; } private void removeTemplate(String templateId) { clientTemplates().get(templateId).remove(); - assertAdminEvents.assertEvent(getRealmId(), OperationType.DELETE, AdminEventPaths.clientTemplateResourcePath(templateId)); + assertAdminEvents.assertEvent(getRealmId(), OperationType.DELETE, AdminEventPaths.clientTemplateResourcePath(templateId), ResourceType.CLIENT_TEMPLATE); } } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/ClientTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/ClientTest.java index 5216c3649e..5dddbc5126 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/ClientTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/ClientTest.java @@ -19,13 +19,12 @@ package org.keycloak.testsuite.admin.client; import java.util.List; -import org.junit.Rule; import org.junit.Test; import org.keycloak.admin.client.resource.ClientResource; import org.keycloak.events.admin.OperationType; +import org.keycloak.events.admin.ResourceType; import org.keycloak.representations.idm.ClientRepresentation; import org.keycloak.testsuite.util.AdminEventPaths; -import org.keycloak.testsuite.util.AssertAdminEvents; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -66,7 +65,7 @@ public class ClientTest extends AbstractClientTest { clientRsc.remove(); assertNull(findClientResource("deleteMe")); - assertAdminEvents.assertEvent(getRealmId(), OperationType.DELETE, AdminEventPaths.clientResourcePath(clientDbId)); + assertAdminEvents.assertEvent(getRealmId(), OperationType.DELETE, AdminEventPaths.clientResourcePath(clientDbId), ResourceType.CLIENT); } @Test @@ -87,7 +86,7 @@ public class ClientTest extends AbstractClientTest { ClientRepresentation expectedClientRep = new ClientRepresentation(); expectedClientRep.setClientId("updateMe"); expectedClientRep.setName("iWasUpdated"); - assertAdminEvents.assertEvent(getRealmId(), OperationType.UPDATE, AdminEventPaths.clientResourcePath(clientRep.getId()), expectedClientRep); + assertAdminEvents.assertEvent(getRealmId(), OperationType.UPDATE, AdminEventPaths.clientResourcePath(clientRep.getId()), expectedClientRep, ResourceType.CLIENT); } @Test diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/CredentialsTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/CredentialsTest.java index 0b2ffafbf2..b76e6704a7 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/CredentialsTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/CredentialsTest.java @@ -22,6 +22,7 @@ import org.junit.Before; import org.junit.Test; import org.keycloak.admin.client.resource.ClientAttributeCertificateResource; import org.keycloak.admin.client.resource.ClientResource; +import org.keycloak.events.admin.ResourceType; import org.keycloak.models.utils.KeycloakModelUtils; import org.keycloak.representations.KeyStoreConfig; import org.keycloak.events.admin.OperationType; @@ -70,7 +71,7 @@ public class CredentialsTest extends AbstractClientTest { CredentialRepresentation secretRep = new CredentialRepresentation(); secretRep.setType(CredentialRepresentation.SECRET); - assertAdminEvents.assertEvent(getRealmId(), OperationType.ACTION, AdminEventPaths.clientGenerateSecretPath(accountClientDbId), secretRep); + assertAdminEvents.assertEvent(getRealmId(), OperationType.ACTION, AdminEventPaths.clientGenerateSecretPath(accountClientDbId), secretRep, ResourceType.CLIENT); assertNotNull(oldCredential); assertNotNull(newCredential); @@ -91,7 +92,7 @@ public class CredentialsTest extends AbstractClientTest { ClientRepresentation testedRep = new ClientRepresentation(); testedRep.setClientId(rep.getClientId()); testedRep.setRegistrationAccessToken(newToken); - assertAdminEvents.assertEvent(getRealmId(), OperationType.ACTION, AdminEventPaths.clientRegenerateRegistrationAccessTokenPath(accountClientDbId), testedRep); + assertAdminEvents.assertEvent(getRealmId(), OperationType.ACTION, AdminEventPaths.clientRegenerateRegistrationAccessTokenPath(accountClientDbId), testedRep, ResourceType.CLIENT); } @Test @@ -102,7 +103,7 @@ public class CredentialsTest extends AbstractClientTest { assertEquals(cert.getCertificate(), certFromGet.getCertificate()); assertEquals(cert.getPrivateKey(), certFromGet.getPrivateKey()); - assertAdminEvents.assertEvent(getRealmId(), OperationType.ACTION, AdminEventPaths.clientCertificateGenerateSecretPath(accountClientDbId, "jwt.credential"), cert); + assertAdminEvents.assertEvent(getRealmId(), OperationType.ACTION, AdminEventPaths.clientCertificateGenerateSecretPath(accountClientDbId, "jwt.credential"), cert, ResourceType.CLIENT); } @Test diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/SessionTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/SessionTest.java index 8685603452..0ba2a41ad8 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/SessionTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/SessionTest.java @@ -23,6 +23,7 @@ import org.junit.Before; import org.junit.Test; import org.keycloak.admin.client.resource.ClientResource; import org.keycloak.events.admin.OperationType; +import org.keycloak.events.admin.ResourceType; import org.keycloak.representations.idm.UserRepresentation; import org.keycloak.representations.idm.UserSessionRepresentation; import org.keycloak.testsuite.auth.page.account.AccountManagement; @@ -47,8 +48,8 @@ public class SessionTest extends AbstractClientTest { if (!testUserCreated) { createTestUserWithAdminClient(); - assertAdminEvents.assertEvent(getRealmId(), OperationType.CREATE, AdminEventPaths.userResourcePath(testUser.getId())); - assertAdminEvents.assertEvent(getRealmId(), OperationType.ACTION, AdminEventPaths.userResetPasswordPath(testUser.getId())); + assertAdminEvents.assertEvent(getRealmId(), OperationType.CREATE, AdminEventPaths.userResourcePath(testUser.getId()), ResourceType.USER); + assertAdminEvents.assertEvent(getRealmId(), OperationType.ACTION, AdminEventPaths.userResetPasswordPath(testUser.getId()), ResourceType.USER); } testUserCreated = true; } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/group/GroupTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/group/GroupTest.java index 9ac45d0437..d8e13c89b4 100755 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/group/GroupTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/group/GroupTest.java @@ -23,6 +23,7 @@ import org.junit.Test; import org.keycloak.admin.client.resource.RealmResource; import org.keycloak.admin.client.resource.RoleMappingResource; import org.keycloak.events.admin.OperationType; +import org.keycloak.events.admin.ResourceType; import org.keycloak.models.Constants; import org.keycloak.models.RoleModel; import org.keycloak.representations.AccessToken; @@ -105,13 +106,13 @@ public class GroupTest extends AbstractGroupTest { Response response = realm.clients().create(client); response.close(); String clientUuid = ApiUtil.getCreatedId(response); - assertAdminEvents.assertEvent("test", OperationType.CREATE, AdminEventPaths.clientResourcePath(clientUuid), client); + assertAdminEvents.assertEvent("test", OperationType.CREATE, AdminEventPaths.clientResourcePath(clientUuid), client, ResourceType.CLIENT); client = realm.clients().findByClientId("foo").get(0); RoleRepresentation role = new RoleRepresentation(); role.setName("foo-role"); realm.clients().get(client.getId()).roles().create(role); - assertAdminEvents.assertEvent("test", OperationType.CREATE, AdminEventPaths.clientRoleResourcePath(clientUuid, "foo-role"), role); + assertAdminEvents.assertEvent("test", OperationType.CREATE, AdminEventPaths.clientRoleResourcePath(clientUuid, "foo-role"), role, ResourceType.CLIENT_ROLE); role = realm.clients().get(client.getId()).roles().get("foo-role").toRepresentation(); GroupRepresentation group = new GroupRepresentation(); @@ -121,10 +122,10 @@ public class GroupTest extends AbstractGroupTest { List list = new LinkedList<>(); list.add(role); realm.groups().group(group.getId()).roles().clientLevel(client.getId()).add(list); - assertAdminEvents.assertEvent("test", OperationType.CREATE, AdminEventPaths.groupRolesClientRolesPath(group.getId(), clientUuid), list); + assertAdminEvents.assertEvent("test", OperationType.CREATE, AdminEventPaths.groupRolesClientRolesPath(group.getId(), clientUuid), list, ResourceType.CLIENT_ROLE); realm.clients().get(client.getId()).remove(); - assertAdminEvents.assertEvent("test", OperationType.DELETE, AdminEventPaths.clientResourcePath(clientUuid)); + assertAdminEvents.assertEvent("test", OperationType.DELETE, AdminEventPaths.clientResourcePath(clientUuid), ResourceType.CLIENT); } private GroupRepresentation createGroup(RealmResource realm, GroupRepresentation group) { @@ -132,7 +133,7 @@ public class GroupTest extends AbstractGroupTest { String groupId = ApiUtil.getCreatedId(response); response.close(); - assertAdminEvents.assertEvent("test", OperationType.CREATE, AdminEventPaths.groupPath(groupId), group); + assertAdminEvents.assertEvent("test", OperationType.CREATE, AdminEventPaths.groupPath(groupId), group, ResourceType.GROUP); // Set ID to the original rep group.setId(groupId); @@ -171,13 +172,13 @@ public class GroupTest extends AbstractGroupTest { List roles = new LinkedList<>(); roles.add(topRole); realm.groups().group(topGroup.getId()).roles().realmLevel().add(roles); - assertAdminEvents.assertEvent("test", OperationType.CREATE, AdminEventPaths.groupRolesRealmRolesPath(topGroup.getId()), roles); + assertAdminEvents.assertEvent("test", OperationType.CREATE, AdminEventPaths.groupRolesRealmRolesPath(topGroup.getId()), roles, ResourceType.GROUP); GroupRepresentation level2Group = new GroupRepresentation(); level2Group.setName("level2"); Response response = realm.groups().group(topGroup.getId()).subGroup(level2Group); response.close(); - assertAdminEvents.assertEvent("test", OperationType.CREATE, AdminEventPaths.groupSubgroupsPath(topGroup.getId()), level2Group); + assertAdminEvents.assertEvent("test", OperationType.CREATE, AdminEventPaths.groupSubgroupsPath(topGroup.getId()), level2Group, ResourceType.GROUP); URI location = response.getLocation(); final String level2Id = ApiUtil.getCreatedId(response); @@ -198,20 +199,20 @@ public class GroupTest extends AbstractGroupTest { roles.clear(); roles.add(level2Role); realm.groups().group(level2Group.getId()).roles().realmLevel().add(roles); - assertAdminEvents.assertEvent("test", OperationType.CREATE, AdminEventPaths.groupRolesRealmRolesPath(level2Group.getId()), roles); + assertAdminEvents.assertEvent("test", OperationType.CREATE, AdminEventPaths.groupRolesRealmRolesPath(level2Group.getId()), roles, ResourceType.REALM_ROLE); GroupRepresentation level3Group = new GroupRepresentation(); level3Group.setName("level3"); response = realm.groups().group(level2Group.getId()).subGroup(level3Group); response.close(); - assertAdminEvents.assertEvent("test", OperationType.CREATE, AdminEventPaths.groupSubgroupsPath(level2Group.getId()), level3Group); + assertAdminEvents.assertEvent("test", OperationType.CREATE, AdminEventPaths.groupSubgroupsPath(level2Group.getId()), level3Group, ResourceType.GROUP); level3Group = realm.getGroupByPath("/top/level2/level3"); Assert.assertNotNull(level3Group); roles.clear(); roles.add(level3Role); realm.groups().group(level3Group.getId()).roles().realmLevel().add(roles); - assertAdminEvents.assertEvent("test", OperationType.CREATE, AdminEventPaths.groupRolesRealmRolesPath(level3Group.getId()), roles); + assertAdminEvents.assertEvent("test", OperationType.CREATE, AdminEventPaths.groupRolesRealmRolesPath(level3Group.getId()), roles, ResourceType.REALM_ROLE); topGroup = realm.getGroupByPath("/top"); assertEquals(1, topGroup.getRealmRoles().size()); @@ -231,7 +232,7 @@ public class GroupTest extends AbstractGroupTest { UserRepresentation user = realm.users().search("direct-login", -1, -1).get(0); realm.users().get(user.getId()).joinGroup(level3Group.getId()); - assertAdminEvents.assertEvent("test", OperationType.CREATE, AdminEventPaths.userGroupPath(user.getId(), level3Group.getId())); + assertAdminEvents.assertEvent("test", OperationType.CREATE, AdminEventPaths.userGroupPath(user.getId(), level3Group.getId()), ResourceType.GROUP_MEMBERSHIP); List membership = realm.users().get(user.getId()).groups(); assertEquals(1, membership.size()); @@ -243,7 +244,7 @@ public class GroupTest extends AbstractGroupTest { assertTrue(token.getRealmAccess().getRoles().contains("level3Role")); realm.addDefaultGroup(level3Group.getId()); - assertAdminEvents.assertEvent("test", OperationType.CREATE, AdminEventPaths.defaultGroupPath(level3Group.getId())); + assertAdminEvents.assertEvent("test", OperationType.CREATE, AdminEventPaths.defaultGroupPath(level3Group.getId()), ResourceType.GROUP); List defaultGroups = realm.getDefaultGroups(); assertEquals(1, defaultGroups.size()); @@ -255,20 +256,20 @@ public class GroupTest extends AbstractGroupTest { response = realm.users().create(newUser); String userId = ApiUtil.getCreatedId(response); response.close(); - assertAdminEvents.assertEvent("test", OperationType.CREATE, AdminEventPaths.userResourcePath(userId), newUser); + assertAdminEvents.assertEvent("test", OperationType.CREATE, AdminEventPaths.userResourcePath(userId), newUser, ResourceType.USER); membership = realm.users().get(userId).groups(); assertEquals(1, membership.size()); assertEquals("level3", membership.get(0).getName()); realm.removeDefaultGroup(level3Group.getId()); - assertAdminEvents.assertEvent("test", OperationType.DELETE, AdminEventPaths.defaultGroupPath(level3Group.getId())); + assertAdminEvents.assertEvent("test", OperationType.DELETE, AdminEventPaths.defaultGroupPath(level3Group.getId()), ResourceType.GROUP); defaultGroups = realm.getDefaultGroups(); assertEquals(0, defaultGroups.size()); realm.groups().group(topGroup.getId()).remove(); - assertAdminEvents.assertEvent("test", OperationType.DELETE, AdminEventPaths.groupPath(topGroup.getId())); + assertAdminEvents.assertEvent("test", OperationType.DELETE, AdminEventPaths.groupPath(topGroup.getId()), ResourceType.GROUP); try { realm.getGroupByPath("/top/level2/level3"); @@ -320,7 +321,7 @@ public class GroupTest extends AbstractGroupTest { group.getAttributes().put("attr3", Collections.singletonList("attrval2")); realm.groups().group(group.getId()).update(group); - assertAdminEvents.assertEvent("test", OperationType.UPDATE, AdminEventPaths.groupPath(group.getId()), group); + assertAdminEvents.assertEvent("test", OperationType.UPDATE, AdminEventPaths.groupPath(group.getId()), group, ResourceType.GROUP); group = realm.getGroupByPath("/group-new"); @@ -341,27 +342,27 @@ public class GroupTest extends AbstractGroupTest { Response response = realm.users().create(UserBuilder.create().username("user-a").build()); String userAId = ApiUtil.getCreatedId(response); response.close(); - assertAdminEvents.assertEvent("test", OperationType.CREATE, AdminEventPaths.userResourcePath(userAId)); + assertAdminEvents.assertEvent("test", OperationType.CREATE, AdminEventPaths.userResourcePath(userAId), ResourceType.USER); response = realm.users().create(UserBuilder.create().username("user-b").build()); String userBId = ApiUtil.getCreatedId(response); response.close(); - assertAdminEvents.assertEvent("test", OperationType.CREATE, AdminEventPaths.userResourcePath(userBId)); + assertAdminEvents.assertEvent("test", OperationType.CREATE, AdminEventPaths.userResourcePath(userBId), ResourceType.USER); realm.users().get(userAId).joinGroup(groupId); - assertAdminEvents.assertEvent("test", OperationType.CREATE, AdminEventPaths.userGroupPath(userAId, groupId), group); + assertAdminEvents.assertEvent("test", OperationType.CREATE, AdminEventPaths.userGroupPath(userAId, groupId), group, ResourceType.GROUP_MEMBERSHIP); List members = realm.groups().group(groupId).members(0, 10); assertNames(members, "user-a"); realm.users().get(userBId).joinGroup(groupId); - assertAdminEvents.assertEvent("test", OperationType.CREATE, AdminEventPaths.userGroupPath(userBId, groupId), group); + assertAdminEvents.assertEvent("test", OperationType.CREATE, AdminEventPaths.userGroupPath(userBId, groupId), group, ResourceType.GROUP_MEMBERSHIP); members = realm.groups().group(groupId).members(0, 10); assertNames(members, "user-a", "user-b"); realm.users().get(userAId).leaveGroup(groupId); - assertAdminEvents.assertEvent("test", OperationType.DELETE, AdminEventPaths.userGroupPath(userAId, groupId), group); + assertAdminEvents.assertEvent("test", OperationType.DELETE, AdminEventPaths.userGroupPath(userAId, groupId), group, ResourceType.GROUP_MEMBERSHIP); members = realm.groups().group(groupId).members(0, 10); assertNames(members, "user-b"); @@ -419,15 +420,15 @@ public class GroupTest extends AbstractGroupTest { l.add(realm.roles().get("realm-role").toRepresentation()); l.add(realm.roles().get("realm-composite").toRepresentation()); roles.realmLevel().add(l); - assertAdminEvents.assertEvent("test", OperationType.CREATE, AdminEventPaths.groupRolesRealmRolesPath(group.getId()), l); + assertAdminEvents.assertEvent("test", OperationType.CREATE, AdminEventPaths.groupRolesRealmRolesPath(group.getId()), l, ResourceType.REALM_ROLE); // Add client roles RoleRepresentation clientRole = realm.clients().get(clientId).roles().get("client-role").toRepresentation(); RoleRepresentation clientComposite = realm.clients().get(clientId).roles().get("client-composite").toRepresentation(); roles.clientLevel(clientId).add(Collections.singletonList(clientRole)); roles.clientLevel(clientId).add(Collections.singletonList(clientComposite)); - assertAdminEvents.assertEvent("test", OperationType.CREATE, AdminEventPaths.groupRolesClientRolesPath(group.getId(), clientId), Collections.singletonList(clientRole)); - assertAdminEvents.assertEvent("test", OperationType.CREATE, AdminEventPaths.groupRolesClientRolesPath(group.getId(), clientId), Collections.singletonList(clientComposite)); + assertAdminEvents.assertEvent("test", OperationType.CREATE, AdminEventPaths.groupRolesClientRolesPath(group.getId(), clientId), Collections.singletonList(clientRole), ResourceType.CLIENT_ROLE); + assertAdminEvents.assertEvent("test", OperationType.CREATE, AdminEventPaths.groupRolesClientRolesPath(group.getId(), clientId), Collections.singletonList(clientComposite), ResourceType.CLIENT_ROLE); // List realm roles assertNames(roles.realmLevel().listAll(), "realm-role", "realm-composite"); @@ -448,13 +449,13 @@ public class GroupTest extends AbstractGroupTest { // Remove realm role RoleRepresentation realmRoleRep = realm.roles().get("realm-role").toRepresentation(); roles.realmLevel().remove(Collections.singletonList(realmRoleRep)); - assertAdminEvents.assertEvent("test", OperationType.DELETE, AdminEventPaths.groupRolesRealmRolesPath(group.getId()), Collections.singletonList(realmRoleRep)); + assertAdminEvents.assertEvent("test", OperationType.DELETE, AdminEventPaths.groupRolesRealmRolesPath(group.getId()), Collections.singletonList(realmRoleRep), ResourceType.REALM_ROLE); assertNames(roles.realmLevel().listAll(), "realm-composite"); // Remove client role RoleRepresentation clientRoleRep = realm.clients().get(clientId).roles().get("client-role").toRepresentation(); roles.clientLevel(clientId).remove(Collections.singletonList(clientRoleRep)); - assertAdminEvents.assertEvent("test", OperationType.DELETE, AdminEventPaths.groupRolesClientRolesPath(group.getId(), clientId), Collections.singletonList(clientRoleRep)); + assertAdminEvents.assertEvent("test", OperationType.DELETE, AdminEventPaths.groupRolesClientRolesPath(group.getId(), clientId), Collections.singletonList(clientRoleRep), ResourceType.CLIENT_ROLE); assertNames(roles.clientLevel(clientId).listAll(), "client-composite"); } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/realm/RealmRolesTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/realm/RealmRolesTest.java index 04221c022b..bf9c7947ff 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/realm/RealmRolesTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/realm/RealmRolesTest.java @@ -21,6 +21,7 @@ import org.junit.Before; import org.junit.Test; import org.keycloak.admin.client.resource.RolesResource; import org.keycloak.events.admin.OperationType; +import org.keycloak.events.admin.ResourceType; import org.keycloak.representations.idm.ClientRepresentation; import org.keycloak.representations.idm.RoleRepresentation; import org.keycloak.testsuite.Assert; @@ -78,11 +79,11 @@ public class RealmRolesTest extends AbstractAdminTest { resource = adminClient.realm(REALM_NAME).roles(); - assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.roleResourcePath("role-a"), roleA); - assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.roleResourcePath("role-b"), roleB); + assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.roleResourcePath("role-a"), roleA, ResourceType.REALM_ROLE); + assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.roleResourcePath("role-b"), roleB, ResourceType.REALM_ROLE); - assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.clientResourcePath(clientUuid), clientRep); - assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.clientRoleResourcePath(clientUuid, "role-c"), roleC); + assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.clientResourcePath(clientUuid), clientRep, ResourceType.CLIENT); + assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.clientRoleResourcePath(clientUuid, "role-c"), roleC, ResourceType.CLIENT_ROLE); } @Test @@ -102,7 +103,7 @@ public class RealmRolesTest extends AbstractAdminTest { role.setDescription("Role A New"); resource.get("role-a").update(role); - assertAdminEvents.assertEvent(realmId, OperationType.UPDATE, AdminEventPaths.roleResourcePath("role-a"), role); + assertAdminEvents.assertEvent(realmId, OperationType.UPDATE, AdminEventPaths.roleResourcePath("role-a"), role, ResourceType.REALM_ROLE); role = resource.get("role-a-new").toRepresentation(); @@ -116,7 +117,7 @@ public class RealmRolesTest extends AbstractAdminTest { public void deleteRole() { assertNotNull(resource.get("role-a")); resource.deleteRole("role-a"); - assertAdminEvents.assertEvent(realmId, OperationType.DELETE, AdminEventPaths.roleResourcePath("role-a")); + assertAdminEvents.assertEvent(realmId, OperationType.DELETE, AdminEventPaths.roleResourcePath("role-a"), ResourceType.REALM_ROLE); try { resource.get("role-a").toRepresentation(); @@ -136,7 +137,7 @@ public class RealmRolesTest extends AbstractAdminTest { l.add(RoleBuilder.create().id(ids.get("role-c")).build()); resource.get("role-a").addComposites(l); - assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.roleResourceCompositesPath("role-a"), l); + assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.roleResourceCompositesPath("role-a"), l, ResourceType.REALM_ROLE); Set composites = resource.get("role-a").getRoleComposites(); @@ -150,7 +151,7 @@ public class RealmRolesTest extends AbstractAdminTest { Assert.assertNames(clientComposites, "role-c"); resource.get("role-a").deleteComposites(l); - assertAdminEvents.assertEvent(realmId, OperationType.DELETE, AdminEventPaths.roleResourceCompositesPath("role-a"), l); + assertAdminEvents.assertEvent(realmId, OperationType.DELETE, AdminEventPaths.roleResourceCompositesPath("role-a"), l, ResourceType.REALM_ROLE); assertFalse(resource.get("role-a").toRepresentation().isComposite()); assertEquals(0, resource.get("role-a").getRoleComposites().size()); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/realm/RealmTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/realm/RealmTest.java index d2e64283ff..f08f79059e 100755 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/realm/RealmTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/realm/RealmTest.java @@ -27,6 +27,7 @@ import org.keycloak.admin.client.resource.ServerInfoResource; import org.keycloak.common.util.StreamUtil; import org.keycloak.common.util.Time; import org.keycloak.events.admin.OperationType; +import org.keycloak.events.admin.ResourceType; import org.keycloak.models.Constants; import org.keycloak.representations.adapters.action.GlobalRequestResult; import org.keycloak.representations.adapters.action.PushNotBeforeAction; @@ -213,7 +214,7 @@ public class RealmTest extends AbstractAdminTest { rep.setEditUsernameAllowed(true); realm.update(rep); - assertAdminEvents.assertEvent(realmId, OperationType.UPDATE, Matchers.nullValue(String.class), rep); + assertAdminEvents.assertEvent(realmId, OperationType.UPDATE, Matchers.nullValue(String.class), rep, ResourceType.REALM); rep = realm.toRepresentation(); @@ -230,7 +231,7 @@ public class RealmTest extends AbstractAdminTest { rep.setEditUsernameAllowed(false); realm.update(rep); - assertAdminEvents.assertEvent(realmId, OperationType.UPDATE, Matchers.nullValue(String.class), rep); + assertAdminEvents.assertEvent(realmId, OperationType.UPDATE, Matchers.nullValue(String.class), rep, ResourceType.REALM); rep = realm.toRepresentation(); assertEquals(Boolean.FALSE, rep.isRegistrationAllowed()); @@ -246,7 +247,7 @@ public class RealmTest extends AbstractAdminTest { rep.setSupportedLocales(new HashSet<>(Arrays.asList("en", "de"))); realm.update(rep); - assertAdminEvents.assertEvent(realmId, OperationType.UPDATE, Matchers.nullValue(String.class), rep); + assertAdminEvents.assertEvent(realmId, OperationType.UPDATE, Matchers.nullValue(String.class), rep, ResourceType.REALM); rep = realm.toRepresentation(); @@ -258,7 +259,7 @@ public class RealmTest extends AbstractAdminTest { rep.setEditUsernameAllowed(false); realm.update(rep); - assertAdminEvents.assertEvent(realmId, OperationType.UPDATE, Matchers.nullValue(String.class), rep); + assertAdminEvents.assertEvent(realmId, OperationType.UPDATE, Matchers.nullValue(String.class), rep, ResourceType.REALM); rep = realm.toRepresentation(); assertEquals(Boolean.FALSE, rep.isEditUsernameAllowed()); @@ -282,7 +283,7 @@ public class RealmTest extends AbstractAdminTest { public void deleteDefaultRole() { RoleRepresentation role = new RoleRepresentation("test", "test", false); realm.roles().create(role); - assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.roleResourcePath("test"), role); + assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.roleResourcePath("test"), role, ResourceType.REALM_ROLE); assertNotNull(realm.roles().get("test").toRepresentation()); @@ -291,10 +292,10 @@ public class RealmTest extends AbstractAdminTest { rep.getDefaultRoles().add("test"); realm.update(rep); - assertAdminEvents.assertEvent(realmId, OperationType.UPDATE, Matchers.nullValue(String.class), rep); + assertAdminEvents.assertEvent(realmId, OperationType.UPDATE, Matchers.nullValue(String.class), rep, ResourceType.REALM); realm.roles().deleteRole("test"); - assertAdminEvents.assertEvent(realmId, OperationType.DELETE, AdminEventPaths.roleResourcePath("test")); + assertAdminEvents.assertEvent(realmId, OperationType.DELETE, AdminEventPaths.roleResourcePath("test"), ResourceType.REALM_ROLE); try { realm.roles().get("testsadfsadf").toRepresentation(); @@ -425,7 +426,7 @@ public class RealmTest extends AbstractAdminTest { rep.setPublicKey(PUBLIC_KEY); realm.update(rep); - assertAdminEvents.assertEvent(realmId, OperationType.UPDATE, Matchers.nullValue(String.class), rep); + assertAdminEvents.assertEvent(realmId, OperationType.UPDATE, Matchers.nullValue(String.class), rep, ResourceType.REALM); assertEquals(PUBLIC_KEY, rep.getPublicKey()); @@ -460,7 +461,7 @@ public class RealmTest extends AbstractAdminTest { rep.setPublicKey(publicKey2048); realm.update(rep); - assertAdminEvents.assertEvent(realmId, OperationType.UPDATE, Matchers.nullValue(String.class), rep); + assertAdminEvents.assertEvent(realmId, OperationType.UPDATE, Matchers.nullValue(String.class), rep, ResourceType.REALM); Assert.assertEquals(publicKey2048, realm.toRepresentation().getPublicKey()); @@ -470,7 +471,7 @@ public class RealmTest extends AbstractAdminTest { rep.setPublicKey(publicKey4096); realm.update(rep); - assertAdminEvents.assertEvent(realmId, OperationType.UPDATE, Matchers.nullValue(String.class), rep); + assertAdminEvents.assertEvent(realmId, OperationType.UPDATE, Matchers.nullValue(String.class), rep, ResourceType.REALM); Assert.assertEquals(publicKey4096, realm.toRepresentation().getPublicKey()); } @@ -481,7 +482,7 @@ public class RealmTest extends AbstractAdminTest { rep.setCertificate(CERTIFICATE); realm.update(rep); - assertAdminEvents.assertEvent(realmId, OperationType.UPDATE, Matchers.nullValue(String.class), rep); + assertAdminEvents.assertEvent(realmId, OperationType.UPDATE, Matchers.nullValue(String.class), rep, ResourceType.REALM); assertEquals(CERTIFICATE, rep.getCertificate()); @@ -489,7 +490,7 @@ public class RealmTest extends AbstractAdminTest { rep.setCertificate(certificate); realm.update(rep); - assertAdminEvents.assertEvent(realmId, OperationType.UPDATE, Matchers.nullValue(String.class), rep); + assertAdminEvents.assertEvent(realmId, OperationType.UPDATE, Matchers.nullValue(String.class), rep, ResourceType.REALM); assertEquals(certificate, realm.toRepresentation().getCertificate()); @@ -520,7 +521,7 @@ public class RealmTest extends AbstractAdminTest { assertTrue(testingClient.testing().isCached("realms", realmRep.getId())); realm.clearRealmCache(); - assertAdminEvents.assertEvent(realmId, OperationType.ACTION, "clear-realm-cache"); + assertAdminEvents.assertEvent(realmId, OperationType.ACTION, "clear-realm-cache", ResourceType.REALM); assertFalse(testingClient.testing().isCached("realms", realmRep.getId())); } @@ -532,14 +533,14 @@ public class RealmTest extends AbstractAdminTest { Response response = realm.users().create(user); String userId = ApiUtil.getCreatedId(response); response.close(); - assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.userResourcePath(userId), user); + assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.userResourcePath(userId), user, ResourceType.USER); realm.users().get(userId).toRepresentation(); assertTrue(testingClient.testing().isCached("users", userId)); realm.clearUserCache(); - assertAdminEvents.assertEvent(realmId, OperationType.ACTION, "clear-user-cache"); + assertAdminEvents.assertEvent(realmId, OperationType.ACTION, "clear-user-cache", ResourceType.REALM); assertFalse(testingClient.testing().isCached("users", userId)); } @@ -553,10 +554,10 @@ public class RealmTest extends AbstractAdminTest { RealmRepresentation rep = realm.toRepresentation(); rep.setNotBefore(time); realm.update(rep); - assertAdminEvents.assertEvent(realmId, OperationType.UPDATE, Matchers.nullValue(String.class), rep); + assertAdminEvents.assertEvent(realmId, OperationType.UPDATE, Matchers.nullValue(String.class), rep, ResourceType.REALM); GlobalRequestResult globalRequestResult = realm.pushRevocation(); - assertAdminEvents.assertEvent(realmId, OperationType.ACTION, "push-revocation", globalRequestResult); + assertAdminEvents.assertEvent(realmId, OperationType.ACTION, "push-revocation", globalRequestResult, ResourceType.REALM); assertEquals(1, globalRequestResult.getSuccessRequests().size()); assertEquals("http://localhost:8180/auth/realms/master/app/admin", globalRequestResult.getSuccessRequests().get(0)); @@ -573,15 +574,15 @@ public class RealmTest extends AbstractAdminTest { Response response = realm.users().create(UserBuilder.create().username("user").build()); String userId = ApiUtil.getCreatedId(response); response.close(); - assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.userResourcePath(userId)); + assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.userResourcePath(userId), ResourceType.USER); realm.users().get(userId).resetPassword(CredentialBuilder.create().password("password").build()); - assertAdminEvents.assertEvent(realmId, OperationType.ACTION, AdminEventPaths.userResetPasswordPath(userId)); + assertAdminEvents.assertEvent(realmId, OperationType.ACTION, AdminEventPaths.userResetPasswordPath(userId), ResourceType.USER); oauth.doLogin("user", "password"); GlobalRequestResult globalRequestResult = realm.logoutAll(); - assertAdminEvents.assertEvent(realmId, OperationType.ACTION, "logout-all", globalRequestResult); + assertAdminEvents.assertEvent(realmId, OperationType.ACTION, "logout-all", globalRequestResult, ResourceType.REALM); assertEquals(1, globalRequestResult.getSuccessRequests().size()); assertEquals("http://localhost:8180/auth/realms/master/app/admin", globalRequestResult.getSuccessRequests().get(0)); @@ -602,7 +603,7 @@ public class RealmTest extends AbstractAdminTest { assertNotNull(event); realm.deleteSession(event.getSessionId()); - assertAdminEvents.assertEvent(realmId, OperationType.DELETE, AdminEventPaths.deleteSessionPath(event.getSessionId())); + assertAdminEvents.assertEvent(realmId, OperationType.DELETE, AdminEventPaths.deleteSessionPath(event.getSessionId()), ResourceType.USER_SESSION); try { realm.deleteSession(event.getSessionId()); fail("Expected 404"); @@ -649,7 +650,7 @@ public class RealmTest extends AbstractAdminTest { Response resp = realm.clients().create(client); String clientDbId = ApiUtil.getCreatedId(resp); resp.close(); - assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.clientResourcePath(clientDbId), client); + assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.clientResourcePath(clientDbId), client, ResourceType.CLIENT); oauth.realm(REALM_NAME); oauth.redirectUri(redirectUri); @@ -658,10 +659,10 @@ public class RealmTest extends AbstractAdminTest { Response response = realm.users().create(userRep); String userId = ApiUtil.getCreatedId(response); response.close(); - assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.userResourcePath(userId), userRep); + assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.userResourcePath(userId), userRep, ResourceType.USER); realm.users().get(userId).resetPassword(CredentialBuilder.create().password("password").build()); - assertAdminEvents.assertEvent(realmId, OperationType.ACTION, AdminEventPaths.userResetPasswordPath(userId)); + assertAdminEvents.assertEvent(realmId, OperationType.ACTION, AdminEventPaths.userResetPasswordPath(userId), ResourceType.USER); testingClient.testApp().clearAdminActions(); } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/AssertAdminEvents.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/AssertAdminEvents.java index 58f8e9ab10..8813f707b4 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/AssertAdminEvents.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/AssertAdminEvents.java @@ -38,6 +38,7 @@ import org.junit.runners.model.Statement; import org.keycloak.common.util.ObjectUtil; import org.keycloak.common.util.reflections.Reflections; import org.keycloak.events.admin.OperationType; +import org.keycloak.events.admin.ResourceType; import org.keycloak.jose.jws.JWSInput; import org.keycloak.jose.jws.JWSInputException; import org.keycloak.representations.AccessToken; @@ -106,22 +107,23 @@ public class AssertAdminEvents implements TestRule { - public AdminEventRepresentation assertEvent(String realmId, OperationType operationType, String resourcePath) { - return assertEvent(realmId, operationType, resourcePath, null); + public AdminEventRepresentation assertEvent(String realmId, OperationType operationType, String resourcePath, ResourceType resourceType) { + return assertEvent(realmId, operationType, resourcePath, null, resourceType); } - public AdminEventRepresentation assertEvent(String realmId, OperationType operationType, Matcher resourcePath) { - return assertEvent(realmId, operationType, resourcePath, null); + public AdminEventRepresentation assertEvent(String realmId, OperationType operationType, Matcher resourcePath, ResourceType resourceType) { + return assertEvent(realmId, operationType, resourcePath, null, resourceType); } - public AdminEventRepresentation assertEvent(String realmId, OperationType operationType, String resourcePath, Object representation) { - return assertEvent(realmId, operationType, Matchers.equalTo(resourcePath), representation); + public AdminEventRepresentation assertEvent(String realmId, OperationType operationType, String resourcePath, Object representation, ResourceType resourceType) { + return assertEvent(realmId, operationType, Matchers.equalTo(resourcePath), representation, resourceType); } - public AdminEventRepresentation assertEvent(String realmId, OperationType operationType, Matcher resourcePath, Object representation) { + public AdminEventRepresentation assertEvent(String realmId, OperationType operationType, Matcher resourcePath, Object representation, ResourceType resourceType) { return expect().realmId(realmId) .operationType(operationType) .resourcePath(resourcePath) + .resourceType(resourceType) .representation(representation) .assertEvent(); } @@ -132,6 +134,7 @@ public class AssertAdminEvents implements TestRule { private AdminEventRepresentation expected = new AdminEventRepresentation(); private Matcher resourcePath; + private ResourceType resourceType; private Object expectedRep; public ExpectedAdminEvent realmId(String realmId) { @@ -158,6 +161,11 @@ public class AssertAdminEvents implements TestRule { return this; } + public ExpectedAdminEvent resourceType(ResourceType resourceType){ + this.resourceType = resourceType; + return this; + } + public ExpectedAdminEvent error(String error) { expected.setError(error); updateOperationTypeIfError(); @@ -191,6 +199,7 @@ public class AssertAdminEvents implements TestRule { public AdminEventRepresentation assertEvent(AdminEventRepresentation actual) { Assert.assertEquals(expected.getRealmId(), actual.getRealmId()); Assert.assertThat(actual.getResourcePath(), resourcePath); + Assert.assertEquals(actual.getResourceType(), resourceType); Assert.assertEquals(expected.getOperationType(), actual.getOperationType()); Assert.assertTrue(ObjectUtil.isEqualOrBothNull(expected.getError(), actual.getError())); diff --git a/themes/src/main/resources/theme/base/admin/messages/admin-messages_en.properties b/themes/src/main/resources/theme/base/admin/messages/admin-messages_en.properties index a867747016..26a11e00a1 100644 --- a/themes/src/main/resources/theme/base/admin/messages/admin-messages_en.properties +++ b/themes/src/main/resources/theme/base/admin/messages/admin-messages_en.properties @@ -745,7 +745,9 @@ filter=Filter update=Update reset=Reset operation-types=Operation Types +resource-types=Resource Types select-operations.placeholder=Select operations... +select-resource-types.placeholder=Select resource types... resource-path=Resource Path resource-path.tooltip=Filter by resource path. Supports wildcards '*' to match a single part of the path and '**' matches multiple parts. For example 'realms/*/clients/asbc' matches client with id asbc in any realm, while or 'realms/master/**' matches anything in the master realm. date-(from)=Date (From) @@ -754,6 +756,7 @@ authentication-details=Authentication Details ip-address=IP Address time=Time operation-type=Operation Type +resource-type=Resource Type auth=Auth representation=Representation register=Register diff --git a/themes/src/main/resources/theme/base/admin/resources/js/controllers/realm.js b/themes/src/main/resources/theme/base/admin/resources/js/controllers/realm.js index 68a4049a9a..317b376477 100755 --- a/themes/src/main/resources/theme/base/admin/resources/js/controllers/realm.js +++ b/themes/src/main/resources/theme/base/admin/resources/js/controllers/realm.js @@ -1482,13 +1482,19 @@ module.controller('RealmAdminEventsCtrl', function($scope, RealmAdminEvents, rea id : realm.realm, max : 5, first : 0 - } + }; $scope.adminEnabledEventOperationsOptions = { 'multiple': true, 'simple_tags': true, 'tags': serverInfo.enums['operationType'] }; + + $scope.adminEnabledEventResourceTypesOptions = { + 'multiple': true, + 'simple_tags': true, + 'tags': serverInfo.enums['resourceType'] + }; $scope.update = function() { $scope.query.first = 0; @@ -1498,12 +1504,13 @@ module.controller('RealmAdminEventsCtrl', function($scope, RealmAdminEvents, rea } } $scope.events = RealmAdminEvents.query($scope.query); - } + }; $scope.reset = function() { $scope.query.first = 0; $scope.query.max = 5; $scope.query.operationTypes = ''; + $scope.query.resourceTypes = ''; $scope.query.resourcePath = ''; $scope.query.authRealm = ''; $scope.query.authClient = ''; @@ -1513,7 +1520,7 @@ module.controller('RealmAdminEventsCtrl', function($scope, RealmAdminEvents, rea $scope.query.dateTo = ''; $scope.update(); - } + }; $scope.queryUpdate = function() { for (var i in $scope.query) { diff --git a/themes/src/main/resources/theme/base/admin/resources/partials/realm-events-admin.html b/themes/src/main/resources/theme/base/admin/resources/partials/realm-events-admin.html index d380d11838..04a63111e8 100755 --- a/themes/src/main/resources/theme/base/admin/resources/partials/realm-events-admin.html +++ b/themes/src/main/resources/theme/base/admin/resources/partials/realm-events-admin.html @@ -33,11 +33,17 @@
- -
+ +
-
-
+
+
+
+ +
+ +
+
@@ -93,6 +99,7 @@ {{:: 'time' | translate}} {{:: 'operation-type' | translate}} + {{:: 'resource-type' | translate}} {{:: 'resource-path' | translate}} {{:: 'details' | translate}} @@ -110,6 +117,7 @@ {{event.time|date:'shortDate'}}
{{event.time|date:'mediumTime'}} {{event.operationType}} + {{event.resourceType}} {{event.resourcePath}} + @@ -108,6 +109,20 @@ output(o); } + function showError() { + output("Error: " + getParameterByName("error") + "\n" + "Error description: " + getParameterByName("error_description")); + } + + function getParameterByName(name, url) { + if (!url) url = window.location.href; + name = name.replace(/[\[\]]/g, "\\$&"); + var regex = new RegExp("[?&#]" + name + "(=([^&#]*)|&|#|$)"), + results = regex.exec(url); + if (!results) return null; + if (!results[2]) return ''; + return decodeURIComponent(results[2].replace(/\+/g, " ")); + } + function output(data) { if (typeof data === 'object') { data = JSON.stringify(data, null, ' '); diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/adapter/page/JSConsoleTestApp.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/adapter/page/JSConsoleTestApp.java index fef0d114fc..2a5773930e 100755 --- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/adapter/page/JSConsoleTestApp.java +++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/adapter/page/JSConsoleTestApp.java @@ -59,6 +59,8 @@ public class JSConsoleTestApp extends AbstractPageWithInjectedUrl { @FindBy(xpath = "//button[text() = 'Get Profile']") private WebElement getProfileButton; + @FindBy(xpath = "//button[text() = 'Show Error Response']") + private WebElement showErrorButton; @FindBy(xpath = "//button[text() = 'Show Token']") private WebElement showTokenButton; @FindBy(xpath = "//button[text() = 'Show Refresh Token']") @@ -137,4 +139,8 @@ public class JSConsoleTestApp extends AbstractPageWithInjectedUrl { public WebElement getInitButtonElement() { return initButton; } + + public void showErrorResponse() { + showErrorButton.click(); + } } diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/adapter/page/PhotozClientAuthzTestApp.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/adapter/page/PhotozClientAuthzTestApp.java index 0e07157fe4..c76747a2f1 100644 --- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/adapter/page/PhotozClientAuthzTestApp.java +++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/adapter/page/PhotozClientAuthzTestApp.java @@ -23,21 +23,27 @@ import org.keycloak.testsuite.auth.page.login.OIDCLogin; import org.keycloak.testsuite.page.AbstractPageWithInjectedUrl; import org.keycloak.testsuite.page.Form; import org.keycloak.testsuite.pages.ConsentPage; +import org.keycloak.testsuite.util.URLUtils; import org.keycloak.testsuite.util.WaitUtils; import org.openqa.selenium.By; import org.openqa.selenium.WebElement; +import org.openqa.selenium.support.FindBy; import java.net.URL; import java.util.List; +import static org.keycloak.testsuite.util.WaitUtils.IMPLICIT_ELEMENT_WAIT_MILLIS; import static org.keycloak.testsuite.util.WaitUtils.pause; +import static org.keycloak.testsuite.util.WaitUtils.waitForPageToLoad; /** * @author Pedro Igor + * @author Vaclav Muzikar */ public class PhotozClientAuthzTestApp extends AbstractPageWithInjectedUrl { public static final String DEPLOYMENT_NAME = "photoz-html5-client"; + public static final int WAIT_AFTER_OPERATION = 2000; @ArquillianResource @OperateOnDeployment(DEPLOYMENT_NAME) @@ -49,14 +55,16 @@ public class PhotozClientAuthzTestApp extends AbstractPageWithInjectedUrl { @Page protected ConsentPage consentPage; + @FindBy(xpath = "//a[@ng-click = 'Identity.logout()']") + WebElement signOutButton; + public void createAlbum(String name) { navigateTo(); - By id = By.id("create-album"); - WaitUtils.waitUntilElement(id); - this.driver.findElement(id).click(); + this.driver.findElement(By.id("create-album")).click(); Form.setInputValue(this.driver.findElement(By.id("album.name")), name); + pause(200); // We need to wait a bit for the form to "accept" the input (otherwise it registers the input as empty) this.driver.findElement(By.id("save-album")).click(); - pause(500); + pause(WAIT_AFTER_OPERATION); } @Override @@ -65,76 +73,44 @@ public class PhotozClientAuthzTestApp extends AbstractPageWithInjectedUrl { } public void deleteAlbum(String name) { - By id = By.id("delete-" + name); - WaitUtils.waitUntilElement(id); - this.driver.findElements(id).forEach(WebElement::click); - pause(500); + driver.findElements(By.xpath("//a[text()='" + name + "']/following-sibling::a[text()='X']")).forEach(WebElement::click); + pause(WAIT_AFTER_OPERATION); } public void navigateToAdminAlbum() { - this.driver.navigate().to(this.getInjectedUrl().toString() + "/#/admin/album"); - pause(500); + URLUtils.navigateToUri(driver, toString() + "/#/admin/album", true); + driver.navigate().refresh(); // This is sometimes necessary for loading the new policy settings + waitForPageToLoad(driver); + pause(WAIT_AFTER_OPERATION); } public void logOut() { - navigateTo(); - By by = By.xpath("//a[text() = 'Sign Out']"); - WaitUtils.waitUntilElement(by); - this.driver.findElement(by).click(); - pause(500); + signOutButton.click(); // Sometimes doesn't work in PhantomJS! + pause(WAIT_AFTER_OPERATION); } - public void login(String username, String password) throws InterruptedException { - navigateTo(); - Thread.sleep(2000); - if (this.driver.getCurrentUrl().startsWith(getInjectedUrl().toString())) { - Thread.sleep(2000); - logOut(); - navigateTo(); - } + public void login(String username, String password, String... scopes) { + if (scopes.length > 0) { + StringBuilder scopesValue = new StringBuilder(); - Thread.sleep(2000); - - this.loginPage.form().login(username, password); - - // simple check if we are at the consent page, if so just click 'Yes' - if (this.consentPage.isCurrent()) { - consentPage.confirm(); - Thread.sleep(2000); - } - } - - public void loginWithScopes(String username, String password, String... scopes) throws Exception { - navigateTo(); - Thread.sleep(2000); - if (this.driver.getCurrentUrl().startsWith(getInjectedUrl().toString())) { - Thread.sleep(2000); - logOut(); - navigateTo(); - } - - Thread.sleep(2000); - - StringBuilder scopesValue = new StringBuilder(); - - for (String scope : scopes) { - if (scopesValue.length() != 0) { - scopesValue.append(" "); + for (String scope : scopes) { + if (scopesValue.length() != 0) { + scopesValue.append(" "); + } + scopesValue.append(scope); } - scopesValue.append(scope); + + URLUtils.navigateToUri(driver, this.driver.getCurrentUrl() + " " + scopesValue, true); } - this.driver.navigate().to(this.driver.getCurrentUrl() + " " + scopesValue); - - Thread.sleep(2000); - this.loginPage.form().login(username, password); // simple check if we are at the consent page, if so just click 'Yes' if (this.consentPage.isCurrent()) { consentPage.confirm(); - Thread.sleep(2000); } + + pause(WAIT_AFTER_OPERATION); } public boolean wasDenied() { @@ -142,10 +118,20 @@ public class PhotozClientAuthzTestApp extends AbstractPageWithInjectedUrl { } public void viewAlbum(String name) throws InterruptedException { - Thread.sleep(2000); - By id = By.id("view-" + name); - WaitUtils.waitUntilElement(id); - this.driver.findElements(id).forEach(WebElement::click); - pause(500); + this.driver.findElement(By.xpath("//a[text() = '" + name + "']")).click(); + waitForPageToLoad(driver); + driver.navigate().refresh(); // This is sometimes necessary for loading the new policy settings + pause(WAIT_AFTER_OPERATION); + } + + @Override + public void navigateTo(boolean waitForMatch) { + super.navigateTo(waitForMatch); + pause(WAIT_AFTER_OPERATION); + } + + @Override + public boolean isCurrent() { + return URLUtils.currentUrlStartWith(driver, toString()); } } diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/URLUtils.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/URLUtils.java index dcf3795115..1147bc7250 100644 --- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/URLUtils.java +++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/URLUtils.java @@ -40,8 +40,12 @@ public final class URLUtils { driver.navigate().to(uri); if (waitForMatch) { + // Possible login URL; this is to eliminate unnecessary wait when navigating to a secured page and being + // redirected to the login page + String loginUrl = "^[^\\?]+/auth/realms/[^/]+/(protocol|login-actions).+$"; + try { - (new WebDriverWait(driver, 3)).until(urlMatches("^" + Pattern.quote(uri) + ".*$")); + (new WebDriverWait(driver, 3)).until(or(urlMatches("^" + Pattern.quote(uri) + ".*$"), urlMatches(loginUrl))); } catch (TimeoutException e) { log.info("new current URL doesn't start with desired URL"); } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/AbstractAuthTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/AbstractAuthTest.java index 4057d2004e..570c9e8815 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/AbstractAuthTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/AbstractAuthTest.java @@ -101,10 +101,7 @@ public abstract class AbstractAuthTest extends AbstractKeycloakTest { } public void deleteAllCookiesForTestRealm() { - // testRealmPage.navigateTo(); - testRealmAccountPage.navigateTo(); // Because IE webdriver freezes when loading a JSON page (realm page), we need to use this alternative - log.debug("deleting cookies in test realm"); - driver.manage().deleteAllCookies(); + deleteAllCookiesForRealm(testRealmAccountPage); } public void listCookies() { diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/AbstractKeycloakTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/AbstractKeycloakTest.java index ae0dcb641e..2ee8f73c10 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/AbstractKeycloakTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/AbstractKeycloakTest.java @@ -169,9 +169,13 @@ public abstract class AbstractKeycloakTest { } public void deleteAllCookiesForMasterRealm() { + deleteAllCookiesForRealm(accountPage); + } + + protected void deleteAllCookiesForRealm(Account realmAccountPage) { // masterRealmPage.navigateTo(); - accountPage.navigateTo(); // Because IE webdriver freezes when loading a JSON page (realm page), we need to use this alternative - log.debug("deleting cookies in master realm"); + realmAccountPage.navigateTo(); // Because IE webdriver freezes when loading a JSON page (realm page), we need to use this alternative + log.info("deleting cookies in '" + realmAccountPage.getAuthRealm() + "' realm"); driver.manage().deleteAllCookies(); } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/AbstractJSConsoleExampleAdapterTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/AbstractJSConsoleExampleAdapterTest.java index 7be3cbd2c7..a91b26b5d3 100755 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/AbstractJSConsoleExampleAdapterTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/AbstractJSConsoleExampleAdapterTest.java @@ -268,14 +268,14 @@ public abstract class AbstractJSConsoleExampleAdapterTest extends AbstractExampl jsConsoleTestAppPage.init(); jsConsoleTestAppPage.logIn(); - assertTrue(driver.getPageSource().contains("Implicit flow is disabled for the client")); + assertResponseError("Implicit flow is disabled for the client"); - setImplicitFlowFroClient(); + setImplicitFlowForClient(); jsConsoleTestAppPage.navigateTo(); jsConsoleTestAppPage.init(); jsConsoleTestAppPage.logIn(); - assertTrue(driver.getPageSource().contains("Standard flow is disabled for the client")); + assertResponseError("Standard flow is disabled for the client"); logInAndInit("implicit"); @@ -284,19 +284,19 @@ public abstract class AbstractJSConsoleExampleAdapterTest extends AbstractExampl @Test public void implicitFlowQueryTest() { - setImplicitFlowFroClient(); + setImplicitFlowForClient(); jsConsoleTestAppPage.navigateTo(); jsConsoleTestAppPage.setFlow("implicit"); jsConsoleTestAppPage.setResponseMode("query"); jsConsoleTestAppPage.init(); jsConsoleTestAppPage.logIn(); - assertTrue(driver.getPageSource().contains("Invalid parameter: response_mode")); + assertResponseError("Response_mode 'query' not allowed"); } @Test public void implicitFlowRefreshTokenTest() { - setImplicitFlowFroClient(); + setImplicitFlowForClient(); logInAndInit("implicit"); @@ -311,7 +311,7 @@ public abstract class AbstractJSConsoleExampleAdapterTest extends AbstractExampl realm.setAccessTokenLifespanForImplicitFlow(5); testRealmResource().update(realm); - setImplicitFlowFroClient(); + setImplicitFlowForClient(); logInAndInit("implicit"); @@ -351,7 +351,7 @@ public abstract class AbstractJSConsoleExampleAdapterTest extends AbstractExampl waitUntilElement(jsConsoleTestAppPage.getOutputElement()).text().contains("Init Success (Authenticated)"); } - private void setImplicitFlowFroClient() { + private void setImplicitFlowForClient() { ClientResource clientResource = ApiUtil.findClientResourceByClientId(testRealmResource(), "js-console"); ClientRepresentation client = clientResource.toRepresentation(); client.setImplicitFlowEnabled(true); @@ -373,4 +373,9 @@ public abstract class AbstractJSConsoleExampleAdapterTest extends AbstractExampl logInAndInit(flow, "user"); } + private void assertResponseError(String errorDescription) { + jsConsoleTestAppPage.showErrorResponse(); + assertTrue(jsConsoleTestAppPage.getOutputElement().getText().contains(errorDescription)); + } + } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/AbstractSAMLExampleAdapterTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/AbstractSAMLExampleAdapterTest.java index 4b78c0595e..3a0676e499 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/AbstractSAMLExampleAdapterTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/AbstractSAMLExampleAdapterTest.java @@ -118,7 +118,7 @@ public abstract class AbstractSAMLExampleAdapterTest extends AbstractExampleAdap waitUntilElement(By.xpath("//body")).text().contains("Welcome to the Employee Tool,"); samlRedirectSigExamplePage.logout(); - waitUntilElement(By.xpath("//body")).text().contains("Logged out."); + URLAssert.assertCurrentUrlStartsWith(testRealmSAMLRedirectLoginPage); samlRedirectSigExamplePage.navigateTo(); URLAssert.assertCurrentUrlStartsWith(testRealmSAMLRedirectLoginPage); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/authorization/AbstractPhotozExampleAdapterTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/authorization/AbstractPhotozExampleAdapterTest.java index 9a0fb262dd..66702a98a0 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/authorization/AbstractPhotozExampleAdapterTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/authorization/AbstractPhotozExampleAdapterTest.java @@ -21,6 +21,7 @@ import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.graphene.page.Page; import org.jboss.arquillian.test.api.ArquillianResource; import org.jboss.shrinkwrap.api.spec.WebArchive; +import org.junit.Before; import org.junit.Test; import org.keycloak.admin.client.resource.AuthorizationResource; import org.keycloak.admin.client.resource.ClientResource; @@ -47,10 +48,8 @@ import java.io.IOException; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; -import java.util.HashSet; import java.util.List; import java.util.Map; -import java.util.function.Consumer; import java.util.function.Predicate; import java.util.stream.Collectors; @@ -74,6 +73,17 @@ public abstract class AbstractPhotozExampleAdapterTest extends AbstractExampleAd @Page private PhotozClientAuthzTestApp clientPage; + @Override + public void setDefaultPageUriParameters() { + super.setDefaultPageUriParameters(); + testRealmPage.setAuthRealm(REALM_NAME); + } + + @Before + public void beforePhotozExampleAdapterTest() { + deleteAllCookiesForClientPage(); + } + @Override public void addAdapterTestRealms(List testRealms) { RealmRepresentation realm = loadRealm(new File(TEST_APPS_HOME_DIR + "/photoz/photoz-realm.json")); @@ -104,7 +114,7 @@ public abstract class AbstractPhotozExampleAdapterTest extends AbstractExampleAd try { this.deployer.deploy(RESOURCE_SERVER_ID); - this.clientPage.login("alice", "alice"); + loginToClientPage("alice", "alice"); this.clientPage.createAlbum("Alice Family Album"); List resources = getAuthorizationResource().resources().resources(); @@ -123,10 +133,10 @@ public abstract class AbstractPhotozExampleAdapterTest extends AbstractExampleAd public void testOnlyOwnerCanDeleteAlbum() throws Exception { try { this.deployer.deploy(RESOURCE_SERVER_ID); - this.clientPage.login("alice", "alice"); + loginToClientPage("alice", "alice"); this.clientPage.createAlbum("Alice-Family-Album"); - this.clientPage.login("admin", "admin"); + loginToClientPage("admin", "admin"); this.clientPage.navigateToAdminAlbum(); List resources = getAuthorizationResource().resources().resources(); @@ -139,7 +149,7 @@ public abstract class AbstractPhotozExampleAdapterTest extends AbstractExampleAd } } - this.clientPage.login("admin", "admin"); + loginToClientPage("admin", "admin"); this.clientPage.navigateToAdminAlbum(); this.clientPage.deleteAlbum("Alice-Family-Album"); @@ -169,7 +179,7 @@ public abstract class AbstractPhotozExampleAdapterTest extends AbstractExampleAd try { this.deployer.deploy(RESOURCE_SERVER_ID); - this.clientPage.login("alice", "alice"); + loginToClientPage("alice", "alice"); this.clientPage.navigateToAdminAlbum(); assertTrue(this.clientPage.wasDenied()); } finally { @@ -182,7 +192,7 @@ public abstract class AbstractPhotozExampleAdapterTest extends AbstractExampleAd try { this.deployer.deploy(RESOURCE_SERVER_ID); - this.clientPage.login("admin", "admin"); + loginToClientPage("admin", "admin"); this.clientPage.navigateToAdminAlbum(); assertFalse(this.clientPage.wasDenied()); @@ -206,10 +216,10 @@ public abstract class AbstractPhotozExampleAdapterTest extends AbstractExampleAd try { this.deployer.deploy(RESOURCE_SERVER_ID); - this.clientPage.login("alice", "alice"); + loginToClientPage("alice", "alice"); this.clientPage.createAlbum("Alice Family Album"); - this.clientPage.login("admin", "admin"); + loginToClientPage("admin", "admin"); this.clientPage.navigateToAdminAlbum(); assertFalse(this.clientPage.wasDenied()); @@ -269,10 +279,10 @@ public abstract class AbstractPhotozExampleAdapterTest extends AbstractExampleAd try { this.deployer.deploy(RESOURCE_SERVER_ID); - this.clientPage.login("alice", "alice"); + loginToClientPage("alice", "alice"); this.clientPage.createAlbum("Alice Family Album"); - this.clientPage.login("admin", "admin"); + loginToClientPage("admin", "admin"); this.clientPage.navigateToAdminAlbum(); assertFalse(this.clientPage.wasDenied()); @@ -288,10 +298,10 @@ public abstract class AbstractPhotozExampleAdapterTest extends AbstractExampleAd } } - this.clientPage.login("alice", "alice"); + loginToClientPage("alice", "alice"); this.clientPage.createAlbum("Alice Family Album"); - this.clientPage.login("admin", "admin"); + loginToClientPage("admin", "admin"); this.clientPage.navigateToAdminAlbum(); this.clientPage.viewAlbum("Alice Family Album"); assertFalse(this.clientPage.wasDenied()); @@ -324,7 +334,7 @@ public abstract class AbstractPhotozExampleAdapterTest extends AbstractExampleAd try { this.deployer.deploy(RESOURCE_SERVER_ID); - this.clientPage.login("alice", "alice"); + loginToClientPage("alice", "alice"); assertFalse(this.clientPage.wasDenied()); UsersResource usersResource = realmsResouce().realm(REALM_NAME).users(); @@ -347,10 +357,10 @@ public abstract class AbstractPhotozExampleAdapterTest extends AbstractExampleAd roleResource.update(roleRepresentation); - this.clientPage.login("alice", "alice"); + loginToClientPage("alice", "alice"); assertTrue(this.clientPage.wasDenied()); - this.clientPage.loginWithScopes("alice", "alice", RESOURCE_SERVER_ID + "/manage-albums"); + loginToClientPage("alice", "alice", RESOURCE_SERVER_ID + "/manage-albums"); assertFalse(this.clientPage.wasDenied()); } finally { this.deployer.undeploy(RESOURCE_SERVER_ID); @@ -362,7 +372,7 @@ public abstract class AbstractPhotozExampleAdapterTest extends AbstractExampleAd try { this.deployer.deploy(RESOURCE_SERVER_ID); - this.clientPage.login("alice", "alice"); + loginToClientPage("alice", "alice"); assertFalse(this.clientPage.wasDenied()); @@ -386,7 +396,7 @@ public abstract class AbstractPhotozExampleAdapterTest extends AbstractExampleAd manageAlbumRole.update(roleRepresentation); - this.clientPage.login("alice", "alice"); + loginToClientPage("alice", "alice"); assertTrue(this.clientPage.wasDenied()); for (PolicyRepresentation policy : getAuthorizationResource().policies().policies()) { @@ -405,7 +415,7 @@ public abstract class AbstractPhotozExampleAdapterTest extends AbstractExampleAd } } - this.clientPage.login("alice", "alice"); + loginToClientPage("alice", "alice"); assertFalse(this.clientPage.wasDenied()); } finally { this.deployer.undeploy(RESOURCE_SERVER_ID); @@ -417,7 +427,7 @@ public abstract class AbstractPhotozExampleAdapterTest extends AbstractExampleAd try { this.deployer.deploy(RESOURCE_SERVER_ID); - this.clientPage.login("alice", "alice"); + loginToClientPage("alice", "alice"); String resourceName = "My Resource Instance"; this.clientPage.createAlbum(resourceName); assertFalse(this.clientPage.wasDenied()); @@ -431,7 +441,7 @@ public abstract class AbstractPhotozExampleAdapterTest extends AbstractExampleAd this.clientPage.createAlbum(resourceName); - this.clientPage.login("admin", "admin"); + loginToClientPage("admin", "admin"); this.clientPage.navigateToAdminAlbum(); this.clientPage.viewAlbum(resourceName); @@ -441,7 +451,7 @@ public abstract class AbstractPhotozExampleAdapterTest extends AbstractExampleAd this.clientPage.deleteAlbum(resourceName); assertFalse(this.clientPage.wasDenied()); - this.clientPage.login("alice", "alice"); + loginToClientPage("alice", "alice"); this.clientPage.createAlbum(resourceName); assertFalse(this.clientPage.wasDenied()); @@ -466,7 +476,7 @@ public abstract class AbstractPhotozExampleAdapterTest extends AbstractExampleAd } }); - this.clientPage.login("admin", "admin"); + loginToClientPage("admin", "admin"); this.clientPage.navigateToAdminAlbum(); this.clientPage.viewAlbum(resourceName); @@ -476,7 +486,7 @@ public abstract class AbstractPhotozExampleAdapterTest extends AbstractExampleAd this.clientPage.deleteAlbum(resourceName); assertTrue(this.clientPage.wasDenied()); - this.clientPage.login("alice", "alice"); + loginToClientPage("alice", "alice"); this.clientPage.deleteAlbum(resourceName); assertFalse(this.clientPage.wasDenied()); @@ -493,7 +503,7 @@ public abstract class AbstractPhotozExampleAdapterTest extends AbstractExampleAd try { this.deployer.deploy(RESOURCE_SERVER_ID); - this.clientPage.login("alice", "alice"); + loginToClientPage("alice", "alice"); String resourceName = "My Resource Instance"; this.clientPage.createAlbum(resourceName); @@ -508,7 +518,7 @@ public abstract class AbstractPhotozExampleAdapterTest extends AbstractExampleAd this.clientPage.createAlbum(resourceName); - this.clientPage.login("admin", "admin"); + loginToClientPage("admin", "admin"); this.clientPage.navigateToAdminAlbum(); this.clientPage.viewAlbum(resourceName); @@ -518,7 +528,7 @@ public abstract class AbstractPhotozExampleAdapterTest extends AbstractExampleAd this.clientPage.deleteAlbum(resourceName); assertFalse(this.clientPage.wasDenied()); - this.clientPage.login("alice", "alice"); + loginToClientPage("alice", "alice"); this.clientPage.createAlbum(resourceName); assertFalse(this.clientPage.wasDenied()); @@ -544,7 +554,7 @@ public abstract class AbstractPhotozExampleAdapterTest extends AbstractExampleAd } }); - this.clientPage.login("admin", "admin"); + loginToClientPage("admin", "admin"); this.clientPage.navigateToAdminAlbum(); this.clientPage.viewAlbum(resourceName); @@ -561,7 +571,7 @@ public abstract class AbstractPhotozExampleAdapterTest extends AbstractExampleAd } }); - this.clientPage.login("admin", "admin"); + loginToClientPage("admin", "admin"); this.clientPage.navigateToAdminAlbum(); this.clientPage.viewAlbum(resourceName); @@ -571,7 +581,7 @@ public abstract class AbstractPhotozExampleAdapterTest extends AbstractExampleAd this.clientPage.deleteAlbum(resourceName); assertTrue(this.clientPage.wasDenied()); - this.clientPage.login("alice", "alice"); + loginToClientPage("alice", "alice"); this.clientPage.deleteAlbum(resourceName); assertFalse(this.clientPage.wasDenied()); List resources = resourcesResource.resources(); @@ -601,4 +611,17 @@ public abstract class AbstractPhotozExampleAdapterTest extends AbstractExampleAd ClientRepresentation resourceServer = clients.findByClientId(clientId).get(0); return clients.get(resourceServer.getId()); } + + private void deleteAllCookiesForClientPage() { + clientPage.navigateTo(); + driver.manage().deleteAllCookies(); + } + + private void loginToClientPage(String username, String password, String... scopes) { + // We need to log out by deleting cookies because the log out button sometimes doesn't work in PhantomJS + deleteAllCookiesForClientPage(); + deleteAllCookiesForTestRealm(); + clientPage.navigateTo(); + clientPage.login(username, password, scopes); + } } \ No newline at end of file diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/AbstractDemoServletsAdapterTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/AbstractDemoServletsAdapterTest.java index 5191e55869..083867f514 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/AbstractDemoServletsAdapterTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/AbstractDemoServletsAdapterTest.java @@ -21,6 +21,7 @@ import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.graphene.page.Page; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Assert; +import org.junit.Before; import org.junit.Ignore; import org.junit.Test; import org.keycloak.OAuth2Constants; @@ -118,6 +119,13 @@ public abstract class AbstractDemoServletsAdapterTest extends AbstractServletsAd return servletDeployment(TokenMinTTLPage.DEPLOYMENT_NAME, AdapterActionsFilter.class, AbstractShowTokensServlet.class, TokenMinTTLServlet.class, ErrorServlet.class); } + @Before + public void beforeDemoServletsAdapterTest() { + // Delete all cookies from token-min-ttl page to be sure we are logged out + tokenMinTTLPage.navigateTo(); + driver.manage().deleteAllCookies(); + } + @Test public void testCustomerPortalWithSubsystemSettings() { customerPortalSubsystem.navigateTo(); From e49afb2d839f494a4700a77755296ffe7e12db54 Mon Sep 17 00:00:00 2001 From: Thomas Darimont Date: Thu, 4 Aug 2016 21:21:30 +0200 Subject: [PATCH 7/8] KEYCLOAK-3142 - Revised according to codereview Liquibase Moved schema evolution configuration from jpa-changelog-2.1.0 to jpa-changelog-2.2.0. Corrected wrong ResourceType references in tests. Adapted AdminEvents copy-routines to be aware of resourceType attribute. Added ResourceType enum to exposed ENUMS of ServerInfoAdminResource. Signed-off-by: Thomas Darimont --- .../META-INF/jpa-changelog-2.1.0.xml | 6 ----- .../META-INF/jpa-changelog-2.2.0.xml | 27 +++++++++++++++++++ .../META-INF/jpa-changelog-master.xml | 1 + .../events/mongo/MongoEventStoreProvider.java | 4 +++ .../admin/IdentityProvidersResource.java | 3 ++- .../admin/RoleContainerResource.java | 1 - .../admin/info/ServerInfoAdminResource.java | 3 ++- .../events/EventsListenerProvider.java | 1 + .../rest/TestingResourceProvider.java | 4 +++ .../admin/AttackDetectionResourceTest.java | 4 +-- .../keycloak/testsuite/admin/ClientTest.java | 6 ++--- .../admin/UserFederationMapperTest.java | 4 +-- .../testsuite/admin/UserFederationTest.java | 4 +-- .../keycloak/testsuite/admin/UserTest.java | 4 +-- .../admin/authentication/ExecutionTest.java | 2 +- .../admin/authentication/FlowTest.java | 2 +- .../authentication/RegistrationFlowTest.java | 2 +- .../admin/client/ClientTemplateTest.java | 10 +++---- .../event/AdminEventAuthDetailsTest.java | 2 ++ .../testsuite/admin/group/GroupTest.java | 18 ++++++------- .../testsuite/util/AssertAdminEvents.java | 4 +-- 21 files changed, 73 insertions(+), 39 deletions(-) create mode 100755 model/jpa/src/main/resources/META-INF/jpa-changelog-2.2.0.xml diff --git a/model/jpa/src/main/resources/META-INF/jpa-changelog-2.1.0.xml b/model/jpa/src/main/resources/META-INF/jpa-changelog-2.1.0.xml index 777a36e6d8..eb4dd1f3b1 100755 --- a/model/jpa/src/main/resources/META-INF/jpa-changelog-2.1.0.xml +++ b/model/jpa/src/main/resources/META-INF/jpa-changelog-2.1.0.xml @@ -196,10 +196,4 @@ - - - - - - \ No newline at end of file diff --git a/model/jpa/src/main/resources/META-INF/jpa-changelog-2.2.0.xml b/model/jpa/src/main/resources/META-INF/jpa-changelog-2.2.0.xml new file mode 100755 index 0000000000..63afbb2dcf --- /dev/null +++ b/model/jpa/src/main/resources/META-INF/jpa-changelog-2.2.0.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/model/jpa/src/main/resources/META-INF/jpa-changelog-master.xml b/model/jpa/src/main/resources/META-INF/jpa-changelog-master.xml index 333ab762ef..55a52b60cb 100755 --- a/model/jpa/src/main/resources/META-INF/jpa-changelog-master.xml +++ b/model/jpa/src/main/resources/META-INF/jpa-changelog-master.xml @@ -35,4 +35,5 @@ + diff --git a/model/mongo/src/main/java/org/keycloak/events/mongo/MongoEventStoreProvider.java b/model/mongo/src/main/java/org/keycloak/events/mongo/MongoEventStoreProvider.java index 3e5c768cd4..e0f8512a5e 100755 --- a/model/mongo/src/main/java/org/keycloak/events/mongo/MongoEventStoreProvider.java +++ b/model/mongo/src/main/java/org/keycloak/events/mongo/MongoEventStoreProvider.java @@ -29,6 +29,7 @@ import org.keycloak.events.Event; import org.keycloak.events.EventQuery; import org.keycloak.events.EventStoreProvider; import org.keycloak.events.EventType; +import org.keycloak.events.admin.ResourceType; import java.util.HashMap; import java.util.Map; @@ -172,6 +173,9 @@ public class MongoEventStoreProvider implements EventStoreProvider { adminEvent.setTime(o.getLong("time")); adminEvent.setRealmId(o.getString("realmId")); adminEvent.setOperationType(OperationType.valueOf(o.getString("operationType"))); + if (o.getString("resourceType") != null) { + adminEvent.setResourceType(ResourceType.valueOf(o.getString("resourceType"))); + } setAuthDetails(adminEvent, o); adminEvent.setResourcePath(o.getString("resourcePath")); adminEvent.setError(o.getString("error")); 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 953cb38712..958a8494e0 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 @@ -25,6 +25,7 @@ import org.keycloak.broker.provider.IdentityProvider; import org.keycloak.broker.provider.IdentityProviderFactory; import org.keycloak.connections.httpclient.HttpClientProvider; import org.keycloak.events.admin.OperationType; +import org.keycloak.events.admin.ResourceType; import org.keycloak.models.IdentityProviderModel; import org.keycloak.models.KeycloakSession; import org.keycloak.models.ModelDuplicateException; @@ -71,7 +72,7 @@ public class IdentityProvidersResource { this.session = session; this.auth = auth; this.auth.init(RealmAuth.Resource.IDENTITY_PROVIDER); - this.adminEvent = adminEvent; + this.adminEvent = adminEvent.resource(ResourceType.IDENTITY_PROVIDER); } /** 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 788921fac3..15e163dcad 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 @@ -172,7 +172,6 @@ public class RoleContainerResource extends RoleResource { throw new NotFoundException("Could not find client"); } - RoleRepresentation rep = getRole(roleName); RoleModel role = roleContainer.getRole(roleName); if (role == null) { throw new NotFoundException("Could not find role"); diff --git a/services/src/main/java/org/keycloak/services/resources/admin/info/ServerInfoAdminResource.java b/services/src/main/java/org/keycloak/services/resources/admin/info/ServerInfoAdminResource.java index d4312c8d44..a7195e12c7 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/info/ServerInfoAdminResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/info/ServerInfoAdminResource.java @@ -36,6 +36,7 @@ import org.keycloak.broker.provider.IdentityProviderFactory; import org.keycloak.common.util.MultivaluedHashMap; import org.keycloak.events.EventType; import org.keycloak.events.admin.OperationType; +import org.keycloak.events.admin.ResourceType; import org.keycloak.models.PasswordPolicy; import org.keycloak.policy.PasswordPolicyProvider; import org.keycloak.policy.PasswordPolicyProviderFactory; @@ -68,7 +69,7 @@ import org.keycloak.representations.info.ThemeInfoRepresentation; */ public class ServerInfoAdminResource { - private static final Map> ENUMS = createEnumsMap(EventType.class, OperationType.class); + private static final Map> ENUMS = createEnumsMap(EventType.class, OperationType.class, ResourceType.class); @Context private KeycloakSession session; diff --git a/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/events/EventsListenerProvider.java b/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/events/EventsListenerProvider.java index 87606ca984..b0ea56af8d 100644 --- a/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/events/EventsListenerProvider.java +++ b/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/events/EventsListenerProvider.java @@ -69,6 +69,7 @@ public class EventsListenerProvider implements EventListenerProvider { newEvent.setAuthDetails(adminEvent.getAuthDetails()); newEvent.setError(adminEvent.getError()); newEvent.setOperationType(adminEvent.getOperationType()); + newEvent.setResourceType(adminEvent.getResourceType()); newEvent.setRealmId(adminEvent.getRealmId()); newEvent.setRepresentation(adminEvent.getRepresentation()); newEvent.setResourcePath(adminEvent.getResourcePath()); diff --git a/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/rest/TestingResourceProvider.java b/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/rest/TestingResourceProvider.java index bbc9f276ae..c65e85cb27 100644 --- a/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/rest/TestingResourceProvider.java +++ b/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/rest/TestingResourceProvider.java @@ -26,6 +26,7 @@ import org.keycloak.common.util.Time; import org.keycloak.connections.infinispan.InfinispanConnectionProvider; import org.keycloak.events.Event; import org.keycloak.events.admin.AdminEvent; +import org.keycloak.events.admin.ResourceType; import org.keycloak.models.KeycloakSession; import org.keycloak.models.RealmModel; import org.keycloak.models.UserSessionModel; @@ -492,6 +493,9 @@ public class TestingResourceProvider implements RealmResourceProvider { event.setAuthDetails(repToModel(rep.getAuthDetails())); event.setError(rep.getError()); event.setOperationType(OperationType.valueOf(rep.getOperationType())); + if (rep.getResourceType() != null) { + event.setResourceType(ResourceType.valueOf(rep.getResourceType())); + } event.setRealmId(rep.getRealmId()); event.setRepresentation(rep.getRepresentation()); event.setResourcePath(rep.getResourcePath()); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/AttackDetectionResourceTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/AttackDetectionResourceTest.java index edcaecbb86..531b55696c 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/AttackDetectionResourceTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/AttackDetectionResourceTest.java @@ -68,13 +68,13 @@ public class AttackDetectionResourceTest extends AbstractAdminTest { assertBruteForce(detection.bruteForceUserStatus("nosuchuser"), 0, false, false); detection.clearBruteForceForUser(findUser("test-user@localhost").getId()); - assertAdminEvents.assertEvent("test", OperationType.DELETE, AdminEventPaths.attackDetectionClearBruteForceForUserPath(findUser("test-user@localhost").getId()), ResourceType.USER); + assertAdminEvents.assertEvent("test", OperationType.DELETE, AdminEventPaths.attackDetectionClearBruteForceForUserPath(findUser("test-user@localhost").getId()), ResourceType.USER_LOGIN_FAILURE); assertBruteForce(detection.bruteForceUserStatus(findUser("test-user@localhost").getId()), 0, false, false); assertBruteForce(detection.bruteForceUserStatus(findUser("test-user2").getId()), 2, true, true); detection.clearAllBruteForce(); - assertAdminEvents.assertEvent("test", OperationType.DELETE, AdminEventPaths.attackDetectionClearAllBruteForcePath(), ResourceType.USER); + assertAdminEvents.assertEvent("test", OperationType.DELETE, AdminEventPaths.attackDetectionClearAllBruteForcePath(), ResourceType.USER_LOGIN_FAILURE); assertBruteForce(detection.bruteForceUserStatus(findUser("test-user@localhost").getId()), 0, false, false); assertBruteForce(detection.bruteForceUserStatus(findUser("test-user2").getId()), 0, false, false); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/ClientTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/ClientTest.java index 1b7df9465c..4e2bdd94f5 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/ClientTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/ClientTest.java @@ -158,7 +158,7 @@ public class ClientTest extends AbstractAdminTest { foundClientRep.setDefaultRoles(new String[]{"test"}); realm.clients().get(id).update(foundClientRep); - assertAdminEvents.assertEvent(realmId, OperationType.UPDATE, AdminEventPaths.clientResourcePath(id), rep, ResourceType.CLIENT_ROLE); + assertAdminEvents.assertEvent(realmId, OperationType.UPDATE, AdminEventPaths.clientResourcePath(id), rep, ResourceType.CLIENT); assertArrayEquals(new String[]{"test"}, realm.clients().get(id).toRepresentation().getDefaultRoles()); @@ -339,8 +339,8 @@ public class ClientTest extends AbstractAdminTest { realm.roles().create(roleRep1); realm.roles().create(roleRep2); - assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.roleResourcePath("role1"), roleRep1, ResourceType.CLIENT_ROLE); - assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.roleResourcePath("role2"), roleRep2, ResourceType.CLIENT_ROLE); + assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.roleResourcePath("role1"), roleRep1, ResourceType.REALM_ROLE); + assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.roleResourcePath("role2"), roleRep2, ResourceType.REALM_ROLE); roleRep1 = realm.roles().get("role1").toRepresentation(); roleRep2 = realm.roles().get("role2").toRepresentation(); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/UserFederationMapperTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/UserFederationMapperTest.java index 2ad95a80e8..6ee35a76c2 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/UserFederationMapperTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/UserFederationMapperTest.java @@ -258,14 +258,14 @@ public class UserFederationMapperTest extends AbstractAdminTest { Map eventRep = new HashMap<>(); eventRep.put("action", "fedToKeycloak"); - assertAdminEvents.assertEvent(realmId, OperationType.ACTION, AdminEventPaths.userFederationMapperResourcePath(ldapProviderId, mapperId) + "/sync", eventRep, ResourceType.USER_FEDERATION_MAPPER); + assertAdminEvents.assertEvent(realmId, OperationType.ACTION, AdminEventPaths.userFederationMapperResourcePath(ldapProviderId, mapperId) + "/sync", eventRep, ResourceType.USER_FEDERATION_PROVIDER); // Try keycloak to fed result = ldapProviderResource().syncMapperData(mapperId, "keycloakToFed"); Assert.assertEquals("dummyKeycloakToFedSuccess mapper=some-dummy", result.getStatus()); eventRep.put("action", "keycloakToFed"); - assertAdminEvents.assertEvent(realmId, OperationType.ACTION, AdminEventPaths.userFederationMapperResourcePath(ldapProviderId, mapperId) + "/sync", ResourceType.USER_FEDERATION_MAPPER); + assertAdminEvents.assertEvent(realmId, OperationType.ACTION, AdminEventPaths.userFederationMapperResourcePath(ldapProviderId, mapperId) + "/sync", ResourceType.USER_FEDERATION_PROVIDER); } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/UserFederationTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/UserFederationTest.java index ef3544f3cb..8cef8a1bbc 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/UserFederationTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/UserFederationTest.java @@ -296,7 +296,7 @@ public class UserFederationTest extends AbstractAdminTest { // update LDAP provider with kerberos ldapRep = userFederation().get(id).toRepresentation(); userFederation().get(id).update(ldapRep); - assertAdminEvents.assertEvent(realmId, OperationType.UPDATE, AdminEventPaths.userFederationResourcePath(id), ldapRep, ResourceType.REALM); + assertAdminEvents.assertEvent(realmId, OperationType.UPDATE, AdminEventPaths.userFederationResourcePath(id), ldapRep, ResourceType.USER_FEDERATION_PROVIDER); // Assert kerberos authenticator still REQUIRED kerberosExecution = findKerberosExecution(); @@ -305,7 +305,7 @@ public class UserFederationTest extends AbstractAdminTest { // Cleanup kerberosExecution.setRequirement(AuthenticationExecutionModel.Requirement.DISABLED.toString()); realm.flows().updateExecutions("browser", kerberosExecution); - assertAdminEvents.assertEvent(realmId, OperationType.UPDATE, AdminEventPaths.authUpdateExecutionPath("browser"), kerberosExecution, ResourceType.REALM); + assertAdminEvents.assertEvent(realmId, OperationType.UPDATE, AdminEventPaths.authUpdateExecutionPath("browser"), kerberosExecution, ResourceType.AUTH_EXECUTION); removeUserFederationProvider(id); } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/UserTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/UserTest.java index 58b66174db..dd5729a8a0 100755 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/UserTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/UserTest.java @@ -747,7 +747,7 @@ public class UserTest extends AbstractAdminTest { RequiredActionProviderRepresentation updatePasswordReqAction = realm.flows().getRequiredAction(UserModel.RequiredAction.UPDATE_PASSWORD.toString()); updatePasswordReqAction.setDefaultAction(true); realm.flows().updateRequiredAction(UserModel.RequiredAction.UPDATE_PASSWORD.toString(), updatePasswordReqAction); - assertAdminEvents.assertEvent(realmId, OperationType.UPDATE, AdminEventPaths.authRequiredActionPath(UserModel.RequiredAction.UPDATE_PASSWORD.toString()), updatePasswordReqAction, ResourceType.USER); + assertAdminEvents.assertEvent(realmId, OperationType.UPDATE, AdminEventPaths.authRequiredActionPath(UserModel.RequiredAction.UPDATE_PASSWORD.toString()), updatePasswordReqAction, ResourceType.REQUIRED_ACTION); // Create user String userId = createUser("user1", "user1@localhost"); @@ -760,7 +760,7 @@ public class UserTest extends AbstractAdminTest { updatePasswordReqAction = realm.flows().getRequiredAction(UserModel.RequiredAction.UPDATE_PASSWORD.toString()); updatePasswordReqAction.setDefaultAction(true); realm.flows().updateRequiredAction(UserModel.RequiredAction.UPDATE_PASSWORD.toString(), updatePasswordReqAction); - assertAdminEvents.assertEvent(realmId, OperationType.UPDATE, AdminEventPaths.authRequiredActionPath(UserModel.RequiredAction.UPDATE_PASSWORD.toString()), updatePasswordReqAction, ResourceType.USER); + assertAdminEvents.assertEvent(realmId, OperationType.UPDATE, AdminEventPaths.authRequiredActionPath(UserModel.RequiredAction.UPDATE_PASSWORD.toString()), updatePasswordReqAction, ResourceType.REQUIRED_ACTION); } @Test diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/authentication/ExecutionTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/authentication/ExecutionTest.java index 35b06d603e..42015edce0 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/authentication/ExecutionTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/authentication/ExecutionTest.java @@ -84,7 +84,7 @@ public class ExecutionTest extends AbstractAuthenticationTest { // add execution - should succeed params.put("provider", "idp-review-profile"); authMgmtResource.addExecution("Copy-of-browser", params); - assertAdminEvents.assertEvent(REALM_NAME, OperationType.CREATE, AdminEventPaths.authAddExecutionPath("Copy-of-browser"), params, ResourceType.AUTH_EXECUTION_FLOW); + assertAdminEvents.assertEvent(REALM_NAME, OperationType.CREATE, AdminEventPaths.authAddExecutionPath("Copy-of-browser"), params, ResourceType.AUTH_EXECUTION); // check execution was added List executionReps = authMgmtResource.getExecutions("Copy-of-browser"); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/authentication/FlowTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/authentication/FlowTest.java index de87a7a5a5..fc50bc6916 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/authentication/FlowTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/authentication/FlowTest.java @@ -142,7 +142,7 @@ public class FlowTest extends AbstractAuthenticationTest { // delete non-built-in flow authMgmtResource.deleteFlow(found.getId()); - assertAdminEvents.assertEvent(REALM_NAME, OperationType.DELETE, AdminEventPaths.authFlowPath(found.getId()), ResourceType.AUTH_EXECUTION_FLOW); + assertAdminEvents.assertEvent(REALM_NAME, OperationType.DELETE, AdminEventPaths.authFlowPath(found.getId()), ResourceType.AUTH_FLOW); // check the deleted flow is no longer returned flows = authMgmtResource.getFlows(); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/authentication/RegistrationFlowTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/authentication/RegistrationFlowTest.java index 30d6916b17..c38086ba01 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/authentication/RegistrationFlowTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/authentication/RegistrationFlowTest.java @@ -63,7 +63,7 @@ public class RegistrationFlowTest extends AbstractAuthenticationTest { // Should success to add execution under form flow authMgmtResource.addExecution("registrationForm2", data2); - assertAdminEvents.assertEvent(REALM_NAME, OperationType.CREATE, AdminEventPaths.authAddExecutionPath("registrationForm2"), data2, ResourceType.AUTH_EXECUTION_FLOW); + assertAdminEvents.assertEvent(REALM_NAME, OperationType.CREATE, AdminEventPaths.authAddExecutionPath("registrationForm2"), data2, ResourceType.AUTH_EXECUTION); } // TODO: More type-safety instead of passing generic maps diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/ClientTemplateTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/ClientTemplateTest.java index 33cf14b115..113630a828 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/ClientTemplateTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/ClientTemplateTest.java @@ -176,10 +176,10 @@ public class ClientTemplateTest extends AbstractClientTest { RoleMappingResource scopesResource = clientTemplates().get(templateId).getScopeMappings(); scopesResource.realmLevel().add(Collections.singletonList(roleRep1)); - assertAdminEvents.assertEvent(getRealmId(), OperationType.CREATE, AdminEventPaths.clientTemplateScopeMappingsRealmLevelPath(templateId), Collections.singletonList(roleRep1), ResourceType.CLIENT_TEMPLATE); + assertAdminEvents.assertEvent(getRealmId(), OperationType.CREATE, AdminEventPaths.clientTemplateScopeMappingsRealmLevelPath(templateId), Collections.singletonList(roleRep1), ResourceType.REALM_SCOPE_MAPPING); scopesResource.clientLevel(accountMgmtId).add(Collections.singletonList(viewAccountRoleRep)); - assertAdminEvents.assertEvent(getRealmId(), OperationType.CREATE, AdminEventPaths.clientTemplateScopeMappingsClientLevelPath(templateId, accountMgmtId), Collections.singletonList(viewAccountRoleRep), ResourceType.CLIENT_TEMPLATE); + assertAdminEvents.assertEvent(getRealmId(), OperationType.CREATE, AdminEventPaths.clientTemplateScopeMappingsClientLevelPath(templateId, accountMgmtId), Collections.singletonList(viewAccountRoleRep), ResourceType.CLIENT_SCOPE_MAPPING); // test that scopes are available (also through composite role) List allRealm = scopesResource.realmLevel().listAll(); @@ -198,10 +198,10 @@ public class ClientTemplateTest extends AbstractClientTest { // remove scopes scopesResource.realmLevel().remove(Collections.singletonList(roleRep1)); - assertAdminEvents.assertEvent(getRealmId(), OperationType.DELETE, AdminEventPaths.clientTemplateScopeMappingsRealmLevelPath(templateId), Collections.singletonList(roleRep1), ResourceType.CLIENT_TEMPLATE); + assertAdminEvents.assertEvent(getRealmId(), OperationType.DELETE, AdminEventPaths.clientTemplateScopeMappingsRealmLevelPath(templateId), Collections.singletonList(roleRep1), ResourceType.REALM_SCOPE_MAPPING); scopesResource.clientLevel(accountMgmtId).remove(Collections.singletonList(viewAccountRoleRep)); - assertAdminEvents.assertEvent(getRealmId(), OperationType.DELETE, AdminEventPaths.clientTemplateScopeMappingsClientLevelPath(templateId, accountMgmtId), Collections.singletonList(viewAccountRoleRep), ResourceType.CLIENT_TEMPLATE); + assertAdminEvents.assertEvent(getRealmId(), OperationType.DELETE, AdminEventPaths.clientTemplateScopeMappingsClientLevelPath(templateId, accountMgmtId), Collections.singletonList(viewAccountRoleRep), ResourceType.CLIENT_SCOPE_MAPPING); // assert scopes are removed allRealm = scopesResource.realmLevel().listAll(); @@ -256,7 +256,7 @@ public class ClientTemplateTest extends AbstractClientTest { // Add realm role to scopes of clientTemplate clientTemplates().get(templateId).getScopeMappings().realmLevel().add(Collections.singletonList(roleRep)); - assertAdminEvents.assertEvent(getRealmId(), OperationType.CREATE, AdminEventPaths.clientTemplateScopeMappingsRealmLevelPath(templateId), Collections.singletonList(roleRep), ResourceType.CLIENT_TEMPLATE); + assertAdminEvents.assertEvent(getRealmId(), OperationType.CREATE, AdminEventPaths.clientTemplateScopeMappingsRealmLevelPath(templateId), Collections.singletonList(roleRep), ResourceType.REALM_SCOPE_MAPPING); List roleReps = clientTemplates().get(templateId).getScopeMappings().realmLevel().listAll(); Assert.assertEquals(1, roleReps.size()); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/event/AdminEventAuthDetailsTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/event/AdminEventAuthDetailsTest.java index 9413836c85..195f733665 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/event/AdminEventAuthDetailsTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/event/AdminEventAuthDetailsTest.java @@ -27,6 +27,7 @@ import org.junit.Test; import org.keycloak.admin.client.Keycloak; import org.keycloak.admin.client.resource.RealmResource; import org.keycloak.events.admin.OperationType; +import org.keycloak.events.admin.ResourceType; import org.keycloak.models.AdminRoles; import org.keycloak.models.Constants; import org.keycloak.models.utils.KeycloakModelUtils; @@ -136,6 +137,7 @@ public class AdminEventAuthDetailsTest extends AbstractAuthTest { .realmId(realmUuid) .operationType(OperationType.UPDATE) .resourcePath(AdminEventPaths.userResourcePath(appUserId)) + .resourceType(ResourceType.USER) .representation(rep) .authDetails(expectedRealmId, expectedClientUuid, expectedUserId) .assertEvent(); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/group/GroupTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/group/GroupTest.java index d8e13c89b4..f4553031c9 100755 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/group/GroupTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/group/GroupTest.java @@ -122,7 +122,7 @@ public class GroupTest extends AbstractGroupTest { List list = new LinkedList<>(); list.add(role); realm.groups().group(group.getId()).roles().clientLevel(client.getId()).add(list); - assertAdminEvents.assertEvent("test", OperationType.CREATE, AdminEventPaths.groupRolesClientRolesPath(group.getId(), clientUuid), list, ResourceType.CLIENT_ROLE); + assertAdminEvents.assertEvent("test", OperationType.CREATE, AdminEventPaths.groupRolesClientRolesPath(group.getId(), clientUuid), list, ResourceType.CLIENT_ROLE_MAPPING); realm.clients().get(client.getId()).remove(); assertAdminEvents.assertEvent("test", OperationType.DELETE, AdminEventPaths.clientResourcePath(clientUuid), ResourceType.CLIENT); @@ -172,7 +172,7 @@ public class GroupTest extends AbstractGroupTest { List roles = new LinkedList<>(); roles.add(topRole); realm.groups().group(topGroup.getId()).roles().realmLevel().add(roles); - assertAdminEvents.assertEvent("test", OperationType.CREATE, AdminEventPaths.groupRolesRealmRolesPath(topGroup.getId()), roles, ResourceType.GROUP); + assertAdminEvents.assertEvent("test", OperationType.CREATE, AdminEventPaths.groupRolesRealmRolesPath(topGroup.getId()), roles, ResourceType.REALM_ROLE_MAPPING); GroupRepresentation level2Group = new GroupRepresentation(); level2Group.setName("level2"); @@ -199,7 +199,7 @@ public class GroupTest extends AbstractGroupTest { roles.clear(); roles.add(level2Role); realm.groups().group(level2Group.getId()).roles().realmLevel().add(roles); - assertAdminEvents.assertEvent("test", OperationType.CREATE, AdminEventPaths.groupRolesRealmRolesPath(level2Group.getId()), roles, ResourceType.REALM_ROLE); + assertAdminEvents.assertEvent("test", OperationType.CREATE, AdminEventPaths.groupRolesRealmRolesPath(level2Group.getId()), roles, ResourceType.REALM_ROLE_MAPPING); GroupRepresentation level3Group = new GroupRepresentation(); level3Group.setName("level3"); @@ -212,7 +212,7 @@ public class GroupTest extends AbstractGroupTest { roles.clear(); roles.add(level3Role); realm.groups().group(level3Group.getId()).roles().realmLevel().add(roles); - assertAdminEvents.assertEvent("test", OperationType.CREATE, AdminEventPaths.groupRolesRealmRolesPath(level3Group.getId()), roles, ResourceType.REALM_ROLE); + assertAdminEvents.assertEvent("test", OperationType.CREATE, AdminEventPaths.groupRolesRealmRolesPath(level3Group.getId()), roles, ResourceType.REALM_ROLE_MAPPING); topGroup = realm.getGroupByPath("/top"); assertEquals(1, topGroup.getRealmRoles().size()); @@ -420,15 +420,15 @@ public class GroupTest extends AbstractGroupTest { l.add(realm.roles().get("realm-role").toRepresentation()); l.add(realm.roles().get("realm-composite").toRepresentation()); roles.realmLevel().add(l); - assertAdminEvents.assertEvent("test", OperationType.CREATE, AdminEventPaths.groupRolesRealmRolesPath(group.getId()), l, ResourceType.REALM_ROLE); + assertAdminEvents.assertEvent("test", OperationType.CREATE, AdminEventPaths.groupRolesRealmRolesPath(group.getId()), l, ResourceType.REALM_ROLE_MAPPING); // Add client roles RoleRepresentation clientRole = realm.clients().get(clientId).roles().get("client-role").toRepresentation(); RoleRepresentation clientComposite = realm.clients().get(clientId).roles().get("client-composite").toRepresentation(); roles.clientLevel(clientId).add(Collections.singletonList(clientRole)); roles.clientLevel(clientId).add(Collections.singletonList(clientComposite)); - assertAdminEvents.assertEvent("test", OperationType.CREATE, AdminEventPaths.groupRolesClientRolesPath(group.getId(), clientId), Collections.singletonList(clientRole), ResourceType.CLIENT_ROLE); - assertAdminEvents.assertEvent("test", OperationType.CREATE, AdminEventPaths.groupRolesClientRolesPath(group.getId(), clientId), Collections.singletonList(clientComposite), ResourceType.CLIENT_ROLE); + assertAdminEvents.assertEvent("test", OperationType.CREATE, AdminEventPaths.groupRolesClientRolesPath(group.getId(), clientId), Collections.singletonList(clientRole), ResourceType.CLIENT_ROLE_MAPPING); + assertAdminEvents.assertEvent("test", OperationType.CREATE, AdminEventPaths.groupRolesClientRolesPath(group.getId(), clientId), Collections.singletonList(clientComposite), ResourceType.CLIENT_ROLE_MAPPING); // List realm roles assertNames(roles.realmLevel().listAll(), "realm-role", "realm-composite"); @@ -449,13 +449,13 @@ public class GroupTest extends AbstractGroupTest { // Remove realm role RoleRepresentation realmRoleRep = realm.roles().get("realm-role").toRepresentation(); roles.realmLevel().remove(Collections.singletonList(realmRoleRep)); - assertAdminEvents.assertEvent("test", OperationType.DELETE, AdminEventPaths.groupRolesRealmRolesPath(group.getId()), Collections.singletonList(realmRoleRep), ResourceType.REALM_ROLE); + assertAdminEvents.assertEvent("test", OperationType.DELETE, AdminEventPaths.groupRolesRealmRolesPath(group.getId()), Collections.singletonList(realmRoleRep), ResourceType.REALM_ROLE_MAPPING); assertNames(roles.realmLevel().listAll(), "realm-composite"); // Remove client role RoleRepresentation clientRoleRep = realm.clients().get(clientId).roles().get("client-role").toRepresentation(); roles.clientLevel(clientId).remove(Collections.singletonList(clientRoleRep)); - assertAdminEvents.assertEvent("test", OperationType.DELETE, AdminEventPaths.groupRolesClientRolesPath(group.getId(), clientId), Collections.singletonList(clientRoleRep), ResourceType.CLIENT_ROLE); + assertAdminEvents.assertEvent("test", OperationType.DELETE, AdminEventPaths.groupRolesClientRolesPath(group.getId(), clientId), Collections.singletonList(clientRoleRep), ResourceType.CLIENT_ROLE_MAPPING); assertNames(roles.clientLevel(clientId).listAll(), "client-composite"); } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/AssertAdminEvents.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/AssertAdminEvents.java index 8813f707b4..c50c022837 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/AssertAdminEvents.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/AssertAdminEvents.java @@ -162,7 +162,7 @@ public class AssertAdminEvents implements TestRule { } public ExpectedAdminEvent resourceType(ResourceType resourceType){ - this.resourceType = resourceType; + expected.setResourceType(resourceType.toString()); return this; } @@ -199,7 +199,7 @@ public class AssertAdminEvents implements TestRule { public AdminEventRepresentation assertEvent(AdminEventRepresentation actual) { Assert.assertEquals(expected.getRealmId(), actual.getRealmId()); Assert.assertThat(actual.getResourcePath(), resourcePath); - Assert.assertEquals(actual.getResourceType(), resourceType); + Assert.assertEquals(expected.getResourceType(), actual.getResourceType()); Assert.assertEquals(expected.getOperationType(), actual.getOperationType()); Assert.assertTrue(ObjectUtil.isEqualOrBothNull(expected.getError(), actual.getError())); From e0a59baaf247024304588542992d6e7f553ed9c9 Mon Sep 17 00:00:00 2001 From: mposolda Date: Fri, 5 Aug 2016 13:08:05 +0200 Subject: [PATCH 8/8] KEYCLOAK-3321 OIDC requests without 'nonce' claim should be rejected unless using the code flow. Started responseType tests --- .../java/org/keycloak/OAuth2Constants.java | 4 + .../protocol/oidc/OIDCLoginProtocol.java | 4 +- .../oidc/endpoints/AuthorizationEndpoint.java | 6 + .../keycloak/testsuite/util/OAuthClient.java | 37 +++++- .../testsuite/TestRealmKeycloakTest.java | 2 +- .../keycloak/testsuite/admin/ClientTest.java | 2 +- .../oauth/AuthorizationCodeTest.java | 12 +- .../testsuite/oauth/OAuthRedirectUriTest.java | 4 +- .../oidc/OIDCAdvancedRequestParamsTest.java | 43 +----- .../AbstractOIDCResponseTypeTest.java | 123 ++++++++++++++++++ .../OIDCBasicResponseTypeCodeTest.java | 72 ++++++++++ ...OIDCHybridResponseTypeCodeIDTokenTest.java | 76 +++++++++++ .../OIDCImplicitResponseTypeIDTokenTest.java | 72 ++++++++++ .../testsuite/util/ClientManager.java | 14 ++ .../src/test/resources/log4j.properties | 3 + 15 files changed, 419 insertions(+), 55 deletions(-) create mode 100644 testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oidc/resptype/AbstractOIDCResponseTypeTest.java create mode 100644 testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oidc/resptype/OIDCBasicResponseTypeCodeTest.java create mode 100644 testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oidc/resptype/OIDCHybridResponseTypeCodeIDTokenTest.java create mode 100644 testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oidc/resptype/OIDCImplicitResponseTypeIDTokenTest.java diff --git a/core/src/main/java/org/keycloak/OAuth2Constants.java b/core/src/main/java/org/keycloak/OAuth2Constants.java index 188d7593b9..2a7d37b4f7 100644 --- a/core/src/main/java/org/keycloak/OAuth2Constants.java +++ b/core/src/main/java/org/keycloak/OAuth2Constants.java @@ -42,6 +42,10 @@ public interface OAuth2Constants { String RESPONSE_TYPE = "response_type"; + String ACCESS_TOKEN = "access_token"; + + String ID_TOKEN = "id_token"; + String REFRESH_TOKEN = "refresh_token"; String AUTHORIZATION_CODE = "authorization_code"; diff --git a/services/src/main/java/org/keycloak/protocol/oidc/OIDCLoginProtocol.java b/services/src/main/java/org/keycloak/protocol/oidc/OIDCLoginProtocol.java index 3105122cf1..8271cc70c7 100755 --- a/services/src/main/java/org/keycloak/protocol/oidc/OIDCLoginProtocol.java +++ b/services/src/main/java/org/keycloak/protocol/oidc/OIDCLoginProtocol.java @@ -171,11 +171,11 @@ public class OIDCLoginProtocol implements LoginProtocol { .build(); if (responseType.hasResponseType(OIDCResponseType.ID_TOKEN)) { - redirectUri.addParam("id_token", res.getIdToken()); + redirectUri.addParam(OAuth2Constants.ID_TOKEN, res.getIdToken()); } if (responseType.hasResponseType(OIDCResponseType.TOKEN)) { - redirectUri.addParam("access_token", res.getToken()); + redirectUri.addParam(OAuth2Constants.ACCESS_TOKEN, res.getToken()); redirectUri.addParam("token_type", res.getTokenType()); redirectUri.addParam("session_state", res.getSessionState()); redirectUri.addParam("expires_in", String.valueOf(res.getExpiresIn())); diff --git a/services/src/main/java/org/keycloak/protocol/oidc/endpoints/AuthorizationEndpoint.java b/services/src/main/java/org/keycloak/protocol/oidc/endpoints/AuthorizationEndpoint.java index 95aa9a6f56..b08d3d8298 100755 --- a/services/src/main/java/org/keycloak/protocol/oidc/endpoints/AuthorizationEndpoint.java +++ b/services/src/main/java/org/keycloak/protocol/oidc/endpoints/AuthorizationEndpoint.java @@ -340,6 +340,12 @@ public class AuthorizationEndpoint extends AuthorizationEndpointBase { return redirectErrorToClient(parsedResponseMode, OAuthErrorException.REQUEST_URI_NOT_SUPPORTED, null); } + if (parsedResponseType.isImplicitOrHybridFlow() && nonce == null) { + logger.missingParameter(OIDCLoginProtocol.NONCE_PARAM); + event.error(Errors.INVALID_REQUEST); + return redirectErrorToClient(parsedResponseMode, OAuthErrorException.INVALID_REQUEST, "Missing parameter: nonce"); + } + return null; } diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/OAuthClient.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/OAuthClient.java index 8c7b2908e5..1d632c1051 100644 --- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/OAuthClient.java +++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/OAuthClient.java @@ -41,6 +41,7 @@ import org.keycloak.jose.jws.crypto.RSAProvider; import org.keycloak.protocol.oidc.OIDCLoginProtocol; import org.keycloak.protocol.oidc.OIDCLoginProtocolService; import org.keycloak.protocol.oidc.representations.JSONWebKeySet; +import org.keycloak.protocol.oidc.utils.OIDCResponseType; import org.keycloak.representations.AccessToken; import org.keycloak.representations.IDToken; import org.keycloak.representations.RefreshToken; @@ -120,7 +121,7 @@ public class OAuthClient { maxAge = null; } - public AuthorizationCodeResponse doLogin(String username, String password) { + public AuthorizationEndpointResponse doLogin(String username, String password) { openLoginForm(); String src = driver.getPageSource(); try { @@ -132,7 +133,7 @@ public class OAuthClient { throw t; } - return new AuthorizationCodeResponse(this); + return new AuthorizationEndpointResponse(this); } public void doLoginGrant(String username, String password) { @@ -637,7 +638,7 @@ public class OAuthClient { return realm; } - public static class AuthorizationCodeResponse { + public static class AuthorizationEndpointResponse { private boolean isRedirected; private String code; @@ -645,11 +646,25 @@ public class OAuthClient { private String error; private String errorDescription; - public AuthorizationCodeResponse(OAuthClient client) { - this(client, false); + // Just during OIDC implicit or hybrid flow + private String accessToken; + private String idToken; + + public AuthorizationEndpointResponse(OAuthClient client) { + boolean fragment; + try { + fragment = client.responseType != null && OIDCResponseType.parse(client.responseType).isImplicitOrHybridFlow(); + } catch (IllegalArgumentException iae) { + fragment = false; + } + init (client, fragment); } - public AuthorizationCodeResponse(OAuthClient client, boolean fragment) { + public AuthorizationEndpointResponse(OAuthClient client, boolean fragment) { + init(client, fragment); + } + + private void init(OAuthClient client, boolean fragment) { isRedirected = client.getCurrentRequest().equals(client.getRedirectUri()); Map params = fragment ? client.getCurrentFragment() : client.getCurrentQuery(); @@ -657,6 +672,8 @@ public class OAuthClient { state = params.get(OAuth2Constants.STATE); error = params.get(OAuth2Constants.ERROR); errorDescription = params.get(OAuth2Constants.ERROR_DESCRIPTION); + accessToken = params.get(OAuth2Constants.ACCESS_TOKEN); + idToken = params.get(OAuth2Constants.ID_TOKEN); } public boolean isRedirected() { @@ -678,6 +695,14 @@ public class OAuthClient { public String getErrorDescription() { return errorDescription; } + + public String getAccessToken() { + return accessToken; + } + + public String getIdToken() { + return idToken; + } } public static class AccessTokenResponse { diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/TestRealmKeycloakTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/TestRealmKeycloakTest.java index 0e10c589ce..040bb4c593 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/TestRealmKeycloakTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/TestRealmKeycloakTest.java @@ -86,7 +86,7 @@ public abstract class TestRealmKeycloakTest extends AbstractKeycloakTest { String sessionId = loginEvent.getSessionId(); String codeId = loginEvent.getDetails().get(Details.CODE_ID); - String code = oauth.getCurrentQuery().get(OAuth2Constants.CODE); + String code = new OAuthClient.AuthorizationEndpointResponse(oauth).getCode(); OAuthClient.AccessTokenResponse response = oauth.doAccessTokenRequest(code, "password"); Assert.assertEquals(200, response.getStatusCode()); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/ClientTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/ClientTest.java index 2a9c643f3b..5202cda067 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/ClientTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/ClientTest.java @@ -128,7 +128,7 @@ public class ClientTest extends AbstractAdminTest { OAuthClient.AccessTokenResponse response = oauth.doGrantAccessTokenRequest("password", "test-user@localhost", "password"); assertEquals(200, response.getStatusCode()); - OAuthClient.AuthorizationCodeResponse codeResponse = oauth.doLogin("test-user@localhost", "password"); + OAuthClient.AuthorizationEndpointResponse codeResponse = oauth.doLogin("test-user@localhost", "password"); OAuthClient.AccessTokenResponse response2 = oauth.doAccessTokenRequest(codeResponse.getCode(), "password"); assertEquals(200, response2.getStatusCode()); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/AuthorizationCodeTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/AuthorizationCodeTest.java index ece81d876e..cf69f74883 100755 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/AuthorizationCodeTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/AuthorizationCodeTest.java @@ -78,7 +78,7 @@ public class AuthorizationCodeTest extends AbstractKeycloakTest { public void authorizationRequest() throws IOException { oauth.state("OpenIdConnect.AuthenticationProperties=2302984sdlk"); - OAuthClient.AuthorizationCodeResponse response = oauth.doLogin("test-user@localhost", "password"); + OAuthClient.AuthorizationEndpointResponse response = oauth.doLogin("test-user@localhost", "password"); Assert.assertTrue(response.isRedirected()); Assert.assertNotNull(response.getCode()); @@ -116,7 +116,7 @@ public class AuthorizationCodeTest extends AbstractKeycloakTest { oauth.state("mystate"); - OAuthClient.AuthorizationCodeResponse response = oauth.doLogin("test-user@localhost", "password"); + OAuthClient.AuthorizationEndpointResponse response = oauth.doLogin("test-user@localhost", "password"); Assert.assertTrue(response.isRedirected()); Assert.assertNotNull(response.getCode()); @@ -131,7 +131,7 @@ public class AuthorizationCodeTest extends AbstractKeycloakTest { public void authorizationRequestNoState() throws IOException { oauth.state(null); - OAuthClient.AuthorizationCodeResponse response = oauth.doLogin("test-user@localhost", "password"); + OAuthClient.AuthorizationEndpointResponse response = oauth.doLogin("test-user@localhost", "password"); Assert.assertTrue(response.isRedirected()); Assert.assertNotNull(response.getCode()); @@ -150,7 +150,7 @@ public class AuthorizationCodeTest extends AbstractKeycloakTest { UriBuilder b = UriBuilder.fromUri(oauth.getLoginFormUrl()); driver.navigate().to(b.build().toURL()); - OAuthClient.AuthorizationCodeResponse errorResponse = new OAuthClient.AuthorizationCodeResponse(oauth, true); + OAuthClient.AuthorizationEndpointResponse errorResponse = new OAuthClient.AuthorizationEndpointResponse(oauth, true); Assert.assertTrue(errorResponse.isRedirected()); Assert.assertEquals(errorResponse.getError(), OAuthErrorException.UNSUPPORTED_RESPONSE_TYPE); Assert.assertEquals(errorResponse.getErrorDescription(), "Client is not allowed to initiate browser login with given response_type. Implicit flow is disabled for the client."); @@ -164,7 +164,7 @@ public class AuthorizationCodeTest extends AbstractKeycloakTest { UriBuilder b = UriBuilder.fromUri(oauth.getLoginFormUrl()); driver.navigate().to(b.build().toURL()); - OAuthClient.AuthorizationCodeResponse errorResponse = new OAuthClient.AuthorizationCodeResponse(oauth); + OAuthClient.AuthorizationEndpointResponse errorResponse = new OAuthClient.AuthorizationEndpointResponse(oauth); Assert.assertTrue(errorResponse.isRedirected()); Assert.assertEquals(errorResponse.getError(), OAuthErrorException.INVALID_REQUEST); @@ -177,7 +177,7 @@ public class AuthorizationCodeTest extends AbstractKeycloakTest { UriBuilder b = UriBuilder.fromUri(oauth.getLoginFormUrl()); driver.navigate().to(b.build().toURL()); - OAuthClient.AuthorizationCodeResponse errorResponse = new OAuthClient.AuthorizationCodeResponse(oauth); + OAuthClient.AuthorizationEndpointResponse errorResponse = new OAuthClient.AuthorizationEndpointResponse(oauth); Assert.assertTrue(errorResponse.isRedirected()); Assert.assertEquals(errorResponse.getError(), OAuthErrorException.UNSUPPORTED_RESPONSE_TYPE); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/OAuthRedirectUriTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/OAuthRedirectUriTest.java index 853b38b09d..f80e789ef7 100755 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/OAuthRedirectUriTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/OAuthRedirectUriTest.java @@ -154,7 +154,7 @@ public class OAuthRedirectUriTest extends AbstractKeycloakTest { @Test public void testValid() throws IOException { oauth.redirectUri(APP_ROOT + "/auth"); - OAuthClient.AuthorizationCodeResponse response = oauth.doLogin("test-user@localhost", "password"); + OAuthClient.AuthorizationEndpointResponse response = oauth.doLogin("test-user@localhost", "password"); Assert.assertNotNull(response.getCode()); URL url = new URL(driver.getCurrentUrl()); @@ -175,7 +175,7 @@ public class OAuthRedirectUriTest extends AbstractKeycloakTest { @Test public void testWithParams() throws IOException { oauth.redirectUri(APP_ROOT + "/auth?key=value"); - OAuthClient.AuthorizationCodeResponse response = oauth.doLogin("test-user@localhost", "password"); + OAuthClient.AuthorizationEndpointResponse response = oauth.doLogin("test-user@localhost", "password"); Assert.assertNotNull(response.getCode()); URL url = new URL(driver.getCurrentUrl()); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oidc/OIDCAdvancedRequestParamsTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oidc/OIDCAdvancedRequestParamsTest.java index 2296908243..191581e600 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oidc/OIDCAdvancedRequestParamsTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oidc/OIDCAdvancedRequestParamsTest.java @@ -47,7 +47,7 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; /** - * Test for supporting advanced parameters of OIDC specs (max_age, nonce, prompt, ...) + * Test for supporting advanced parameters of OIDC specs (max_age, prompt, ...) * * @author Marek Posolda */ @@ -169,7 +169,7 @@ public class OIDCAdvancedRequestParamsTest extends TestRealmKeycloakTest { events.assertEmpty(); // Assert error response was sent because not logged in - OAuthClient.AuthorizationCodeResponse resp = new OAuthClient.AuthorizationCodeResponse(oauth); + OAuthClient.AuthorizationEndpointResponse resp = new OAuthClient.AuthorizationEndpointResponse(oauth); Assert.assertNull(resp.getCode()); Assert.assertEquals(OAuthErrorException.LOGIN_REQUIRED, resp.getError()); @@ -224,7 +224,7 @@ public class OIDCAdvancedRequestParamsTest extends TestRealmKeycloakTest { assertTrue(appPage.isCurrent()); Assert.assertEquals(AppPage.RequestType.AUTH_RESPONSE, appPage.getRequestType()); - OAuthClient.AuthorizationCodeResponse resp = new OAuthClient.AuthorizationCodeResponse(oauth); + OAuthClient.AuthorizationEndpointResponse resp = new OAuthClient.AuthorizationEndpointResponse(oauth); Assert.assertNull(resp.getCode()); Assert.assertEquals(OAuthErrorException.INTERACTION_REQUIRED, resp.getError()); @@ -242,7 +242,7 @@ public class OIDCAdvancedRequestParamsTest extends TestRealmKeycloakTest { driver.navigate().to(oauth.getLoginFormUrl() + "&prompt=none"); Assert.assertEquals(AppPage.RequestType.AUTH_RESPONSE, appPage.getRequestType()); - resp = new OAuthClient.AuthorizationCodeResponse(oauth); + resp = new OAuthClient.AuthorizationEndpointResponse(oauth); Assert.assertNotNull(resp.getCode()); Assert.assertNull(resp.getError()); @@ -289,37 +289,6 @@ public class OIDCAdvancedRequestParamsTest extends TestRealmKeycloakTest { } - - // NONCE - - @Test - public void nonceNotUsed() { - driver.navigate().to(oauth.getLoginFormUrl()); - - loginPage.assertCurrent(); - loginPage.login("test-user@localhost", "password"); - Assert.assertEquals(AppPage.RequestType.AUTH_RESPONSE, appPage.getRequestType()); - - EventRepresentation loginEvent = events.expectLogin().detail(Details.USERNAME, "test-user@localhost").assertEvent(); - IDToken idToken = sendTokenRequestAndGetIDToken(loginEvent); - - Assert.assertNull(idToken.getNonce()); - } - - @Test - public void nonceMatches() { - driver.navigate().to(oauth.getLoginFormUrl() + "&nonce=abcdef123456"); - - loginPage.assertCurrent(); - loginPage.login("test-user@localhost", "password"); - Assert.assertEquals(AppPage.RequestType.AUTH_RESPONSE, appPage.getRequestType()); - - EventRepresentation loginEvent = events.expectLogin().detail(Details.USERNAME, "test-user@localhost").assertEvent(); - IDToken idToken = sendTokenRequestAndGetIDToken(loginEvent); - - Assert.assertEquals("abcdef123456", idToken.getNonce()); - } - // DISPLAY & OTHERS @Test @@ -346,7 +315,7 @@ public class OIDCAdvancedRequestParamsTest extends TestRealmKeycloakTest { assertTrue(appPage.isCurrent()); // Assert error response was sent because not logged in - OAuthClient.AuthorizationCodeResponse resp = new OAuthClient.AuthorizationCodeResponse(oauth); + OAuthClient.AuthorizationEndpointResponse resp = new OAuthClient.AuthorizationEndpointResponse(oauth); Assert.assertNull(resp.getCode()); Assert.assertEquals(OAuthErrorException.REQUEST_NOT_SUPPORTED, resp.getError()); } @@ -359,7 +328,7 @@ public class OIDCAdvancedRequestParamsTest extends TestRealmKeycloakTest { assertTrue(appPage.isCurrent()); // Assert error response was sent because not logged in - OAuthClient.AuthorizationCodeResponse resp = new OAuthClient.AuthorizationCodeResponse(oauth); + OAuthClient.AuthorizationEndpointResponse resp = new OAuthClient.AuthorizationEndpointResponse(oauth); Assert.assertNull(resp.getCode()); Assert.assertEquals(OAuthErrorException.REQUEST_URI_NOT_SUPPORTED, resp.getError()); } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oidc/resptype/AbstractOIDCResponseTypeTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oidc/resptype/AbstractOIDCResponseTypeTest.java new file mode 100644 index 0000000000..047a62d4c9 --- /dev/null +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oidc/resptype/AbstractOIDCResponseTypeTest.java @@ -0,0 +1,123 @@ +/* + * Copyright 2016 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.keycloak.testsuite.oidc.resptype; + +import java.util.List; + +import org.jboss.arquillian.graphene.page.Page; +import org.junit.Rule; +import org.keycloak.OAuthErrorException; +import org.keycloak.events.Details; +import org.keycloak.representations.IDToken; +import org.keycloak.representations.idm.EventRepresentation; +import org.keycloak.representations.idm.RealmRepresentation; +import org.keycloak.testsuite.Assert; +import org.keycloak.testsuite.AssertEvents; +import org.keycloak.testsuite.TestRealmKeycloakTest; +import org.keycloak.testsuite.admin.AbstractAdminTest; +import org.keycloak.testsuite.pages.AccountUpdateProfilePage; +import org.keycloak.testsuite.pages.AppPage; +import org.keycloak.testsuite.pages.LoginPage; +import org.keycloak.testsuite.pages.OAuthGrantPage; +import org.keycloak.testsuite.util.OAuthClient; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +/** + * Abstract test for various values of response_type + * + * @author Marek Posolda + */ +public abstract class AbstractOIDCResponseTypeTest extends TestRealmKeycloakTest { + + @Rule + public AssertEvents events = new AssertEvents(this); + + @Page + protected AppPage appPage; + + @Page + protected LoginPage loginPage; + + @Page + protected AccountUpdateProfilePage profilePage; + + @Page + protected OAuthGrantPage grantPage; + + @Override + public void configureTestRealm(RealmRepresentation testRealm) { + } + + + @Override + public void addTestRealms(List testRealms) { + RealmRepresentation realm = AbstractAdminTest.loadJson(getClass().getResourceAsStream("/testrealm.json"), RealmRepresentation.class); + testRealms.add(realm); + } + + + protected void nonceMatches() { + driver.navigate().to(oauth.getLoginFormUrl() + "&nonce=abcdef123456"); + + loginPage.assertCurrent(); + loginPage.login("test-user@localhost", "password"); + Assert.assertEquals(AppPage.RequestType.AUTH_RESPONSE, appPage.getRequestType()); + + EventRepresentation loginEvent = events.expectLogin().detail(Details.USERNAME, "test-user@localhost").assertEvent(); + List idTokens = retrieveIDTokens(loginEvent); + + for (IDToken idToken : idTokens) { + Assert.assertEquals("abcdef123456", idToken.getNonce()); + } + } + + + protected void nonceNotUsed() { + driver.navigate().to(oauth.getLoginFormUrl()); + + loginPage.assertCurrent(); + loginPage.login("test-user@localhost", "password"); + Assert.assertEquals(AppPage.RequestType.AUTH_RESPONSE, appPage.getRequestType()); + + EventRepresentation loginEvent = events.expectLogin().detail(Details.USERNAME, "test-user@localhost").assertEvent(); + + List idTokens = retrieveIDTokens(loginEvent); + for (IDToken idToken : idTokens) { + Assert.assertNull(idToken.getNonce()); + } + } + + + protected void nonceNotUsedErrorExpected() { + driver.navigate().to(oauth.getLoginFormUrl()); + + assertFalse(loginPage.isCurrent()); + assertTrue(appPage.isCurrent()); + + // Assert error response was sent because not logged in + OAuthClient.AuthorizationEndpointResponse resp = new OAuthClient.AuthorizationEndpointResponse(oauth); + Assert.assertNull(resp.getCode()); + Assert.assertNull(resp.getIdToken()); + Assert.assertEquals(OAuthErrorException.INVALID_REQUEST, resp.getError()); + Assert.assertEquals("Missing parameter: nonce", resp.getErrorDescription()); + } + + protected abstract List retrieveIDTokens(EventRepresentation loginEvent); +} diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oidc/resptype/OIDCBasicResponseTypeCodeTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oidc/resptype/OIDCBasicResponseTypeCodeTest.java new file mode 100644 index 0000000000..a8f51fb96e --- /dev/null +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oidc/resptype/OIDCBasicResponseTypeCodeTest.java @@ -0,0 +1,72 @@ +/* + * Copyright 2016 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.keycloak.testsuite.oidc.resptype; + +import java.util.Collections; +import java.util.List; + +import org.junit.Before; +import org.junit.Test; +import org.keycloak.events.Details; +import org.keycloak.protocol.oidc.utils.OIDCResponseType; +import org.keycloak.representations.IDToken; +import org.keycloak.representations.idm.EventRepresentation; +import org.keycloak.testsuite.Assert; +import org.keycloak.testsuite.util.ClientManager; +import org.keycloak.testsuite.util.OAuthClient; + +/** + * Test for response_type=code + * + * @author Marek Posolda + */ +public class OIDCBasicResponseTypeCodeTest extends AbstractOIDCResponseTypeTest { + + @Before + public void clientConfiguration() { + ClientManager.realm(adminClient.realm("test")).clientId("test-app").standardFlow(true).implicitFlow(false); + + oauth.clientId("test-app"); + oauth.responseType(OIDCResponseType.CODE); + } + + + protected List retrieveIDTokens(EventRepresentation loginEvent) { + Assert.assertEquals(OIDCResponseType.CODE, loginEvent.getDetails().get(Details.RESPONSE_TYPE)); + + OAuthClient.AuthorizationEndpointResponse authzResponse = new OAuthClient.AuthorizationEndpointResponse(oauth, false); + Assert.assertNull(authzResponse.getAccessToken()); + Assert.assertNull(authzResponse.getIdToken()); + + IDToken idToken = sendTokenRequestAndGetIDToken(loginEvent); + + return Collections.singletonList(idToken); + } + + + @Test + public void nonceNotUsed() { + super.nonceNotUsed(); + } + + + @Test + public void nonceMatches() { + super.nonceMatches(); + } +} diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oidc/resptype/OIDCHybridResponseTypeCodeIDTokenTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oidc/resptype/OIDCHybridResponseTypeCodeIDTokenTest.java new file mode 100644 index 0000000000..ff16927a52 --- /dev/null +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oidc/resptype/OIDCHybridResponseTypeCodeIDTokenTest.java @@ -0,0 +1,76 @@ +/* + * Copyright 2016 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.keycloak.testsuite.oidc.resptype; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import org.junit.Before; +import org.junit.Test; +import org.keycloak.events.Details; +import org.keycloak.protocol.oidc.utils.OIDCResponseType; +import org.keycloak.representations.IDToken; +import org.keycloak.representations.idm.EventRepresentation; +import org.keycloak.testsuite.Assert; +import org.keycloak.testsuite.util.ClientManager; +import org.keycloak.testsuite.util.OAuthClient; + +/** + * Tests with response_type=code id_token + * + * @author Marek Posolda + */ +public class OIDCHybridResponseTypeCodeIDTokenTest extends AbstractOIDCResponseTypeTest { + + @Before + public void clientConfiguration() { + ClientManager.realm(adminClient.realm("test")).clientId("test-app").standardFlow(true).implicitFlow(true); + + oauth.clientId("test-app"); + oauth.responseType(OIDCResponseType.CODE + " " + OIDCResponseType.ID_TOKEN); + } + + + protected List retrieveIDTokens(EventRepresentation loginEvent) { + Assert.assertEquals(OIDCResponseType.CODE + " " + OIDCResponseType.ID_TOKEN, loginEvent.getDetails().get(Details.RESPONSE_TYPE)); + + // IDToken from the authorization response + OAuthClient.AuthorizationEndpointResponse authzResponse = new OAuthClient.AuthorizationEndpointResponse(oauth, true); + Assert.assertNull(authzResponse.getAccessToken()); + String idTokenStr = authzResponse.getIdToken(); + IDToken idToken = oauth.verifyIDToken(idTokenStr); + + // IDToken exchanged for the code + IDToken idToken2 = sendTokenRequestAndGetIDToken(loginEvent); + + return Arrays.asList(idToken, idToken2); + } + + + @Test + public void nonceNotUsedErrorExpected() { + super.nonceNotUsedErrorExpected(); + } + + + @Test + public void nonceMatches() { + super.nonceMatches(); + } +} diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oidc/resptype/OIDCImplicitResponseTypeIDTokenTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oidc/resptype/OIDCImplicitResponseTypeIDTokenTest.java new file mode 100644 index 0000000000..4bcdc6508c --- /dev/null +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oidc/resptype/OIDCImplicitResponseTypeIDTokenTest.java @@ -0,0 +1,72 @@ +/* + * Copyright 2016 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.keycloak.testsuite.oidc.resptype; + +import java.util.Collections; +import java.util.List; + +import org.junit.Before; +import org.junit.Test; +import org.keycloak.events.Details; +import org.keycloak.protocol.oidc.utils.OIDCResponseType; +import org.keycloak.representations.IDToken; +import org.keycloak.representations.idm.EventRepresentation; +import org.keycloak.testsuite.Assert; +import org.keycloak.testsuite.util.ClientManager; +import org.keycloak.testsuite.util.OAuthClient; + +/** + * Tests with response_type=id_token + * + * @author Marek Posolda + */ +public class OIDCImplicitResponseTypeIDTokenTest extends AbstractOIDCResponseTypeTest { + + @Before + public void clientConfiguration() { + ClientManager.realm(adminClient.realm("test")).clientId("test-app").standardFlow(false).implicitFlow(true); + + oauth.clientId("test-app"); + oauth.responseType(OIDCResponseType.ID_TOKEN); + } + + + protected List retrieveIDTokens(EventRepresentation loginEvent) { + Assert.assertEquals(OIDCResponseType.ID_TOKEN, loginEvent.getDetails().get(Details.RESPONSE_TYPE)); + + OAuthClient.AuthorizationEndpointResponse authzResponse = new OAuthClient.AuthorizationEndpointResponse(oauth, true); + Assert.assertNull(authzResponse.getAccessToken()); + String idTokenStr = authzResponse.getIdToken(); + IDToken idToken = oauth.verifyIDToken(idTokenStr); + + return Collections.singletonList(idToken); + } + + + @Test + public void nonceNotUsedErrorExpected() { + super.nonceNotUsedErrorExpected(); + } + + + @Test + public void nonceMatches() { + super.nonceMatches(); + } + +} diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/ClientManager.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/ClientManager.java index 6702ec57eb..6bc7151772 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/ClientManager.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/ClientManager.java @@ -67,6 +67,20 @@ public class ClientManager { clientResource.update(app); } + public ClientManagerBuilder standardFlow(Boolean enable) { + ClientRepresentation app = clientResource.toRepresentation(); + app.setStandardFlowEnabled(enable); + clientResource.update(app); + return this; + } + + public ClientManagerBuilder implicitFlow(Boolean enable) { + ClientRepresentation app = clientResource.toRepresentation(); + app.setImplicitFlowEnabled(enable); + clientResource.update(app); + return this; + } + public void fullScopeAllowed(boolean enable) { ClientRepresentation app = clientResource.toRepresentation(); app.setFullScopeAllowed(enable); diff --git a/testsuite/integration/src/test/resources/log4j.properties b/testsuite/integration/src/test/resources/log4j.properties index 327102e806..5d5369c20b 100755 --- a/testsuite/integration/src/test/resources/log4j.properties +++ b/testsuite/integration/src/test/resources/log4j.properties @@ -56,6 +56,9 @@ log4j.logger.org.keycloak.connections.jpa.DefaultJpaConnectionProviderFactory=${ # Enable to view hibernate statistics log4j.logger.org.keycloak.connections.jpa.HibernateStatsReporter=debug +# Enable to view ldap logging +# log4j.logger.org.keycloak.federation.ldap=trace + # Enable to view kerberos/spnego logging # log4j.logger.org.keycloak.federation.kerberos=trace