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 ca5156b926..e484645326 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 @@ -61,7 +61,19 @@ import org.keycloak.events.EventType; import org.keycloak.events.admin.AdminEventQuery; import org.keycloak.events.admin.AuthDetails; import org.keycloak.events.admin.OperationType; +import org.keycloak.exportimport.ExportImportManager; +import org.keycloak.models.AuthenticationFlowModel; +import org.keycloak.models.ClientModel; +import org.keycloak.models.FederatedIdentityModel; +import org.keycloak.models.RealmProvider; +import org.keycloak.models.UserCredentialModel; +import org.keycloak.models.UserFederationProvider; +import org.keycloak.models.UserFederationProviderFactory; +import org.keycloak.models.UserModel; +import org.keycloak.models.UserProvider; import org.keycloak.representations.idm.AuthDetailsRepresentation; +import org.keycloak.representations.idm.AuthenticationFlowRepresentation; +import org.keycloak.representations.idm.UserRepresentation; /** * @author Stian Thorgersen @@ -544,4 +556,93 @@ public class TestingResourceProvider implements RealmResourceProvider { result.setUsername(PassThroughAuthenticator.username); return result; } + + @GET + @Path("/run-import") + @Produces(MediaType.APPLICATION_JSON) + public Response runImport() { + new ExportImportManager(session).runImport(); + return Response.ok().build(); + } + + @GET + @Path("/run-export") + @Produces(MediaType.APPLICATION_JSON) + public Response runExport() { + new ExportImportManager(session).runExport(); + return Response.ok().build(); + } + + @GET + @Path("/valid-credentials") + @Produces(MediaType.APPLICATION_JSON) + public boolean validCredentials(@QueryParam("realmName") String realmName, @QueryParam("userName") String userName, @QueryParam("password") String password) { + RealmModel realm = session.realms().getRealm(realmName); + if (realm == null) return false; + UserProvider userProvider = session.getProvider(UserProvider.class); + UserModel user = userProvider.getUserByUsername(userName, realm); + return userProvider.validCredentials(session, realm, user, UserCredentialModel.password(password)); + } + + @GET + @Path("/user-by-federated-identity") + @Produces(MediaType.APPLICATION_JSON) + public UserRepresentation getUserByFederatedIdentity(@QueryParam("realmName") String realmName, + @QueryParam("identityProvider") String identityProvider, + @QueryParam("userId") String userId, + @QueryParam("userName") String userName) { + RealmModel realm = getRealmByName(realmName); + UserModel foundFederatedUser = session.users().getUserByFederatedIdentity(new FederatedIdentityModel(identityProvider, userId, userName), realm); + if (foundFederatedUser == null) return null; + return ModelToRepresentation.toRepresentation(foundFederatedUser); + } + + @GET + @Path("/user-by-username-from-fed-factory") + @Produces(MediaType.APPLICATION_JSON) + public UserRepresentation getUserByUsernameFromFedProviderFactory(@QueryParam("realmName") String realmName, + @QueryParam("userName") String userName) { + RealmModel realm = getRealmByName(realmName); + UserFederationProviderFactory factory = (UserFederationProviderFactory)session.getKeycloakSessionFactory().getProviderFactory(UserFederationProvider.class, "dummy"); + UserModel user = factory.getInstance(session, null).getUserByUsername(realm, userName); + if (user == null) return null; + return ModelToRepresentation.toRepresentation(user); + } + + @GET + @Path("/get-client-auth-flow") + @Produces(MediaType.APPLICATION_JSON) + public AuthenticationFlowRepresentation getClientAuthFlow(@QueryParam("realmName") String realmName) { + RealmModel realm = getRealmByName(realmName); + AuthenticationFlowModel flow = realm.getClientAuthenticationFlow(); + if (flow == null) return null; + return ModelToRepresentation.toRepresentation(realm, flow); + } + + @GET + @Path("/get-reset-cred-flow") + @Produces(MediaType.APPLICATION_JSON) + public AuthenticationFlowRepresentation getResetCredFlow(@QueryParam("realmName") String realmName) { + RealmModel realm = getRealmByName(realmName); + AuthenticationFlowModel flow = realm.getResetCredentialsFlow(); + if (flow == null) return null; + return ModelToRepresentation.toRepresentation(realm, flow); + } + + @GET + @Path("/get-user-by-service-account-client") + @Produces(MediaType.APPLICATION_JSON) + public UserRepresentation getUserByServiceAccountClient(@QueryParam("realmName") String realmName, @QueryParam("clientId") String clientId) { + RealmModel realm = getRealmByName(realmName); + ClientModel client = realm.getClientByClientId(clientId); + UserModel user = session.users().getUserByServiceAccountClient(client); + if (user == null) return null; + return ModelToRepresentation.toRepresentation(user); + } + + private RealmModel getRealmByName(String realmName) { + RealmProvider realmProvider = session.getProvider(RealmProvider.class); + return realmProvider.getRealmByName(realmName); + } + } diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/client/resources/TestingResource.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/client/resources/TestingResource.java index 23d2d012b8..8bd36f3f64 100644 --- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/client/resources/TestingResource.java +++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/client/resources/TestingResource.java @@ -20,7 +20,9 @@ package org.keycloak.testsuite.client.resources; import java.util.Date; import java.util.List; import org.keycloak.representations.idm.AdminEventRepresentation; +import org.keycloak.representations.idm.AuthenticationFlowRepresentation; import org.keycloak.representations.idm.EventRepresentation; +import org.keycloak.representations.idm.UserRepresentation; import org.keycloak.testsuite.rest.representation.AuthenticatorState; import javax.ws.rs.Consumes; @@ -35,6 +37,7 @@ import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import java.util.Map; import org.jboss.resteasy.annotations.cache.NoCache; +import org.keycloak.exportimport.ExportImportManager; /** * @author Marko Strukelj @@ -202,4 +205,48 @@ public interface TestingResource { @Path("/update-pass-through-auth-state") @Produces(MediaType.APPLICATION_JSON) AuthenticatorState updateAuthenticator(AuthenticatorState state); + + @GET + @Path("/run-import") + @Produces(MediaType.APPLICATION_JSON) + public Response runImport(); + + @GET + @Path("/run-export") + @Produces(MediaType.APPLICATION_JSON) + public Response runExport(); + + @GET + @Path("/valid-credentials") + @Produces(MediaType.APPLICATION_JSON) + public boolean validCredentials(@QueryParam("realmName") String realmName, @QueryParam("userName") String userName, @QueryParam("password") String password); + + @GET + @Path("/user-by-federated-identity") + @Produces(MediaType.APPLICATION_JSON) + public UserRepresentation getUserByFederatedIdentity(@QueryParam("realmName") String realmName, + @QueryParam("identityProvider") String identityProvider, + @QueryParam("userId") String userId, + @QueryParam("userName") String userName); + + @GET + @Path("/user-by-username-from-fed-factory") + @Produces(MediaType.APPLICATION_JSON) + public UserRepresentation getUserByUsernameFromFedProviderFactory(@QueryParam("realmName") String realmName, + @QueryParam("userName") String userName); + + @GET + @Path("/get-client-auth-flow") + @Produces(MediaType.APPLICATION_JSON) + public AuthenticationFlowRepresentation getClientAuthFlow(@QueryParam("realmName") String realmName); + + @GET + @Path("/get-reset-cred-flow") + @Produces(MediaType.APPLICATION_JSON) + public AuthenticationFlowRepresentation getResetCredFlow(@QueryParam("realmName") String realmName); + + @GET + @Path("/get-user-by-service-account-client") + @Produces(MediaType.APPLICATION_JSON) + public UserRepresentation getUserByServiceAccountClient(@QueryParam("realmName") String realmName, @QueryParam("clientId") String clientId); } 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 0e41cee957..4eaba86045 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 @@ -28,28 +28,12 @@ import static org.keycloak.testsuite.admin.AbstractAdminTest.loadJson; /** * This class provides loading of the testRealm called "test". It also - * provides an OAuthClient for the testRealm. + * provides a few utility methods for the testRealm. * * @author Stan Silvert ssilvert@redhat.com (C) 2016 Red Hat Inc. */ public abstract class TestRealmKeycloakTest extends AbstractKeycloakTest { - protected UserRepresentation findUserInRealmRep(RealmRepresentation testRealm, String userName) { - for (UserRepresentation user : testRealm.getUsers()) { - if (user.getUsername().equals(userName)) return user; - } - - return null; - } - - protected ClientRepresentation findClientInRealmRep(RealmRepresentation testRealm, String clientId) { - for (ClientRepresentation client : testRealm.getClients()) { - if (client.getClientId().equals(clientId)) return client; - } - - return null; - } - protected RealmResource testRealm() { return adminClient.realm("test"); } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/account/ProfileTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/account/ProfileTest.java index 670e340919..a1a1813f01 100755 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/account/ProfileTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/account/ProfileTest.java @@ -53,6 +53,7 @@ import org.keycloak.testsuite.TestRealmKeycloakTest; import org.keycloak.testsuite.admin.ApiUtil; import org.keycloak.testsuite.util.ClientBuilder; import org.keycloak.testsuite.util.RealmBuilder; +import org.keycloak.testsuite.util.RealmRepUtil; import org.keycloak.testsuite.util.UserBuilder; import twitter4j.JSONArray; import twitter4j.JSONObject; @@ -68,7 +69,7 @@ public class ProfileTest extends TestRealmKeycloakTest { @Override public void configureTestRealm(RealmRepresentation testRealm) { - UserRepresentation user = findUserInRealmRep(testRealm, "test-user@localhost"); + UserRepresentation user = RealmRepUtil.findUser(testRealm, "test-user@localhost"); user.setFirstName("First"); user.setLastName("Last"); Map attributes = user.getAttributes(); @@ -87,7 +88,7 @@ public class ProfileTest extends TestRealmKeycloakTest { RealmBuilder.edit(testRealm) .user(user2); - ClientBuilder.edit(findClientInRealmRep(testRealm, "test-app")) + ClientBuilder.edit(RealmRepUtil.findClientByClientId(testRealm, "test-app")) .addWebOrigin("http://localtest.me:8180"); } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/account/TrustStoreEmailTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/account/TrustStoreEmailTest.java index 499e387741..75ba24ebf1 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/account/TrustStoreEmailTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/account/TrustStoreEmailTest.java @@ -59,7 +59,7 @@ public class TrustStoreEmailTest extends TestRealmKeycloakTest { public void configureTestRealm(RealmRepresentation testRealm) { log.info("enable verify email and configure smtp server to run with ssl in test realm"); - user = findUserInRealmRep(testRealm, "test-user@localhost"); + user = RealmRepUtil.findUser(testRealm, "test-user@localhost"); testRealm.setSmtpServer(SslMailServer.getServerConfiguration()); testRealm.setVerifyEmail(true); } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/ApiUtil.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/ApiUtil.java index dca666fab9..d7946ce6c7 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/ApiUtil.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/ApiUtil.java @@ -60,6 +60,15 @@ public class ApiUtil { return path.substring(path.lastIndexOf('/') + 1); } + public static ClientResource findClientResourceById(RealmResource realm, String id) { + for (ClientRepresentation c : realm.clients().findAll()) { + if (c.getId().equals(id)) { + return realm.clients().get(c.getId()); + } + } + return null; + } + public static ClientResource findClientResourceByClientId(RealmResource realm, String clientId) { for (ClientRepresentation c : realm.clients().findAll()) { if (c.getClientId().equals(clientId)) { diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/exportimport/ExportImportTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/exportimport/ExportImportTest.java new file mode 100755 index 0000000000..3a6a1bbe2b --- /dev/null +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/exportimport/ExportImportTest.java @@ -0,0 +1,240 @@ +/* + * 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.exportimport; + +import org.junit.Assert; +import org.junit.Test; +import org.keycloak.exportimport.ExportImportConfig; +import org.keycloak.exportimport.dir.DirExportProvider; +import org.keycloak.exportimport.dir.DirExportProviderFactory; +import org.keycloak.exportimport.singlefile.SingleFileExportProviderFactory; +import org.keycloak.representations.idm.RealmRepresentation; + +import java.io.File; +import java.net.URL; +import java.util.List; +import java.util.regex.Matcher; +import org.jboss.arquillian.container.spi.client.container.LifecycleException; +import org.junit.After; +import org.keycloak.admin.client.resource.RealmResource; +import org.keycloak.representations.idm.UserRepresentation; +import org.keycloak.testsuite.util.UserBuilder; + +import static org.keycloak.testsuite.admin.AbstractAdminTest.loadJson; + +/** + * + * + * @author Marek Posolda + * @author Stan Silvert ssilvert@redhat.com (C) 2016 Red Hat Inc. + */ +public class ExportImportTest extends AbstractExportImportTest { + + @Override + public void addTestRealms(List testRealms) { + RealmRepresentation testRealm1 = loadJson(getClass().getResourceAsStream("/testrealm.json"), RealmRepresentation.class); + testRealm1.getUsers().add(makeUser("user1")); + testRealm1.getUsers().add(makeUser("user2")); + testRealm1.getUsers().add(makeUser("user3")); + testRealms.add(testRealm1); + + RealmRepresentation testRealm2 = loadJson(getClass().getResourceAsStream("/model/testrealm.json"), RealmRepresentation.class); + testRealm2.setId("test-realm"); + testRealms.add(testRealm2); + } + + private UserRepresentation makeUser(String userName) { + return UserBuilder.create() + .username(userName) + .email(userName + "@test.com") + .password("password") + .build(); + } + + @After + public void clearExportImportProps() throws LifecycleException { + clearExportImportProperties(); + } + + @Test + public void testDirFullExportImport() throws Throwable { + ExportImportConfig.setProvider(DirExportProviderFactory.PROVIDER_ID); + String targetDirPath = getExportImportTestDirectory() + File.separator + "dirExport"; + DirExportProvider.recursiveDeleteDir(new File(targetDirPath)); + ExportImportConfig.setDir(targetDirPath); + ExportImportConfig.setUsersPerFile(ExportImportConfig.DEFAULT_USERS_PER_FILE); + + testFullExportImport(); + + // There should be 6 files in target directory (3 realm, 3 user) + Assert.assertEquals(6, new File(targetDirPath).listFiles().length); + } + + @Test + public void testDirRealmExportImport() throws Throwable { + ExportImportConfig.setProvider(DirExportProviderFactory.PROVIDER_ID); + String targetDirPath = getExportImportTestDirectory() + File.separator + "dirRealmExport"; + DirExportProvider.recursiveDeleteDir(new File(targetDirPath)); + ExportImportConfig.setDir(targetDirPath); + ExportImportConfig.setUsersPerFile(3); + + testRealmExportImport(); + + // There should be 3 files in target directory (1 realm, 3 user) + File[] files = new File(targetDirPath).listFiles(); + Assert.assertEquals(4, files.length); + } + + @Test + public void testSingleFileFullExportImport() throws Throwable { + ExportImportConfig.setProvider(SingleFileExportProviderFactory.PROVIDER_ID); + String targetFilePath = getExportImportTestDirectory() + File.separator + "singleFile-full.json"; + ExportImportConfig.setFile(targetFilePath); + + testFullExportImport(); + } + + @Test + public void testSingleFileRealmExportImport() throws Throwable { + ExportImportConfig.setProvider(SingleFileExportProviderFactory.PROVIDER_ID); + String targetFilePath = getExportImportTestDirectory() + File.separator + "singleFile-realm.json"; + ExportImportConfig.setFile(targetFilePath); + + testRealmExportImport(); + } + + @Test + public void testSingleFileRealmWithoutBuiltinsImport() throws Throwable { + // Remove test realm + removeRealm("test-realm"); + + // Set the realm, which doesn't have builtin clients/roles inside JSON + ExportImportConfig.setProvider(SingleFileExportProviderFactory.PROVIDER_ID); + URL url = ExportImportTest.class.getResource("/model/testrealm.json"); + String targetFilePath = new File(url.getFile()).getAbsolutePath(); + ExportImportConfig.setFile(targetFilePath); + + ExportImportConfig.setAction(ExportImportConfig.ACTION_IMPORT); + + testingClient.testing().runImport(); + + RealmResource testRealmRealm = adminClient.realm("test-realm"); + + ExportImportUtil.assertDataImportedInRealm(adminClient, testingClient, testRealmRealm.toRepresentation()); + } + + + private void removeRealm(String realmName) { + adminClient.realm(realmName).remove(); + } + + private void testFullExportImport() throws LifecycleException { + ExportImportConfig.setAction(ExportImportConfig.ACTION_EXPORT); + ExportImportConfig.setRealmName(null); + + testingClient.testing().runExport(); + + removeRealm("test"); + removeRealm("test-realm"); + Assert.assertEquals(1, adminClient.realms().findAll().size()); + + assertNotAuthenticated("test", "test-user@localhost", "password"); + assertNotAuthenticated("test", "user1", "password"); + assertNotAuthenticated("test", "user2", "password"); + assertNotAuthenticated("test", "user3", "password"); + + // Configure import + ExportImportConfig.setAction(ExportImportConfig.ACTION_IMPORT); + + testingClient.testing().runImport(); + + // Ensure data are imported back + Assert.assertEquals(3, adminClient.realms().findAll().size()); + + assertAuthenticated("test", "test-user@localhost", "password"); + assertAuthenticated("test", "user1", "password"); + assertAuthenticated("test", "user2", "password"); + assertAuthenticated("test", "user3", "password"); + } + + private void testRealmExportImport() throws LifecycleException { + ExportImportConfig.setAction(ExportImportConfig.ACTION_EXPORT); + ExportImportConfig.setRealmName("test"); + + testingClient.testing().runExport(); + + // Delete some realm (and some data in admin realm) + adminClient.realm("test").remove(); + + Assert.assertEquals(2, adminClient.realms().findAll().size()); + + assertNotAuthenticated("test", "test-user@localhost", "password"); + assertNotAuthenticated("test", "user1", "password"); + assertNotAuthenticated("test", "user2", "password"); + assertNotAuthenticated("test", "user3", "password"); + + // Configure import + ExportImportConfig.setAction(ExportImportConfig.ACTION_IMPORT); + + testingClient.testing().runImport(); + + // Ensure data are imported back, but just for "test" realm + Assert.assertEquals(3, adminClient.realms().findAll().size()); + + assertAuthenticated("test", "test-user@localhost", "password"); + assertAuthenticated("test", "user1", "password"); + assertAuthenticated("test", "user2", "password"); + assertAuthenticated("test", "user3", "password"); + } + + private void assertAuthenticated(String realmName, String username, String password) { + assertAuth(true, realmName, username, password); + } + + private void assertNotAuthenticated(String realmName, String username, String password) { + assertAuth(false, realmName, username, password); + } + + private void assertAuth(boolean expectedResult, String realmName, String username, String password) { + Assert.assertEquals(expectedResult, testingClient.testing().validCredentials(realmName, username, password)); + } + + private static String getExportImportTestDirectory() { + String dirPath = null; + String relativeDirExportImportPath = "testsuite" + File.separator + + "integration-arquillian" + File.separator + + "tests" + File.separator + + "base" + File.separator + + "target" + File.separator + + "export-import"; + + if (System.getProperties().containsKey("maven.home")) { + dirPath = System.getProperty("user.dir").replaceFirst("testsuite.integration.*", Matcher.quoteReplacement(relativeDirExportImportPath)); + } else { + for (String c : System.getProperty("java.class.path").split(File.pathSeparator)) { + if (c.contains(File.separator + "testsuite" + File.separator + "integration-arquillian" + File.separator)) { + dirPath = c.replaceFirst("testsuite.integration-arquillian.*", Matcher.quoteReplacement(relativeDirExportImportPath)); + } + } + } + + String absolutePath = new File(dirPath).getAbsolutePath(); + return absolutePath; + } + +} diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/exportimport/ExportImportUtil.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/exportimport/ExportImportUtil.java new file mode 100644 index 0000000000..95b327fb2a --- /dev/null +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/exportimport/ExportImportUtil.java @@ -0,0 +1,547 @@ +/* + * Copyright 2016 Red Hat Inc. and/or its affiliates and other contributors + * as indicated by the @author tags. All rights reserved. + * + * 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.exportimport; + +import java.util.Collection; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Set; +import org.junit.Assert; +import org.keycloak.admin.client.Keycloak; +import org.keycloak.admin.client.resource.ClientResource; +import org.keycloak.admin.client.resource.ClientTemplateResource; +import org.keycloak.admin.client.resource.RealmResource; +import org.keycloak.admin.client.resource.UserResource; +import org.keycloak.common.constants.KerberosConstants; +import org.keycloak.federation.ldap.mappers.FullNameLDAPFederationMapper; +import org.keycloak.federation.ldap.mappers.FullNameLDAPFederationMapperFactory; +import org.keycloak.models.Constants; +import org.keycloak.models.LDAPConstants; +import org.keycloak.models.utils.DefaultAuthenticationFlows; +import org.keycloak.protocol.oidc.OIDCLoginProtocol; +import org.keycloak.protocol.oidc.mappers.OIDCAttributeMapperHelper; +import org.keycloak.protocol.oidc.mappers.UserSessionNoteMapper; +import org.keycloak.representations.idm.AuthenticationFlowRepresentation; +import org.keycloak.representations.idm.ClientMappingsRepresentation; +import org.keycloak.representations.idm.ClientRepresentation; +import org.keycloak.representations.idm.ClientTemplateRepresentation; +import org.keycloak.representations.idm.FederatedIdentityRepresentation; +import org.keycloak.representations.idm.IdentityProviderRepresentation; +import org.keycloak.representations.idm.ProtocolMapperRepresentation; +import org.keycloak.representations.idm.RealmRepresentation; +import org.keycloak.representations.idm.RoleRepresentation; +import org.keycloak.representations.idm.UserFederationMapperRepresentation; +import org.keycloak.representations.idm.UserFederationProviderRepresentation; +import org.keycloak.representations.idm.UserRepresentation; +import org.keycloak.testsuite.admin.ApiUtil; +import org.keycloak.testsuite.client.KeycloakTestingClient; +import org.keycloak.testsuite.util.RealmRepUtil; + +/** + * + * @author Stan Silvert ssilvert@redhat.com (C) 2016 Red Hat Inc. + */ +public class ExportImportUtil { + + // In the old testsuite, this method exists as a public method of ImportTest from the model package. + // However, model package is not ready to be migrated yet. + public static void assertDataImportedInRealm(Keycloak adminClient, KeycloakTestingClient testingClient, RealmRepresentation realm) { + Assert.assertTrue(realm.isVerifyEmail()); + Assert.assertEquals((Integer)3600000, realm.getOfflineSessionIdleTimeout()); + Assert.assertEquals((Integer)1500, realm.getAccessTokenLifespanForImplicitFlow()); + + Set creds = realm.getRequiredCredentials(); + Assert.assertEquals(1, creds.size()); + String cred = (String)creds.iterator().next(); + Assert.assertEquals("password", cred); + Assert.assertEquals(4, realm.getDefaultRoles().size()); + + Assert.assertNotNull(RealmRepUtil.findDefaultRole(realm, "foo")); + Assert.assertNotNull(RealmRepUtil.findDefaultRole(realm, "bar")); + + RealmResource realmRsc = adminClient.realm(realm.getRealm()); + + /* See KEYCLOAK-3104*/ + UserRepresentation user = findByUsername(realmRsc, "loginclient"); + Assert.assertNotNull(user); + + UserResource userRsc = realmRsc.users().get(user.getId()); + Assert.assertEquals(0, userRsc.getFederatedIdentity().size()); + + List resources = realmRsc.clients().findAll(); + Assert.assertEquals(8, resources.size()); + + // Test applications imported + ClientRepresentation application = ApiUtil.findClientByClientId(realmRsc, "Application").toRepresentation(); + ClientRepresentation otherApp = ApiUtil.findClientByClientId(realmRsc, "OtherApp").toRepresentation(); + ClientRepresentation accountApp = ApiUtil.findClientByClientId(realmRsc, Constants.ACCOUNT_MANAGEMENT_CLIENT_ID).toRepresentation(); + ClientResource nonExisting = ApiUtil.findClientByClientId(realmRsc, "NonExisting"); + Assert.assertNotNull(application); + Assert.assertNotNull(otherApp); + Assert.assertNull(nonExisting); + List clients = realmRsc.clients().findAll(); + Assert.assertEquals(8, clients.size()); + Assert.assertTrue(hasClient(clients, application)); + Assert.assertTrue(hasClient(clients, otherApp)); + Assert.assertTrue(hasClient(clients, accountApp)); + + Assert.assertEquals("Applicationn", application.getName()); + Assert.assertEquals((Integer)50, application.getNodeReRegistrationTimeout()); + Map appRegisteredNodes = application.getRegisteredNodes(); + Assert.assertEquals(2, appRegisteredNodes.size()); + Assert.assertTrue(10 == appRegisteredNodes.get("node1")); + Assert.assertTrue(20 == appRegisteredNodes.get("172.10.15.20")); + + // test clientAuthenticatorType + Assert.assertEquals("client-secret", application.getClientAuthenticatorType()); + Assert.assertEquals("client-jwt", otherApp.getClientAuthenticatorType()); + + // Test finding applications by ID + Assert.assertNull(ApiUtil.findClientResourceById(realmRsc, "982734")); + Assert.assertEquals(application.getId(), ApiUtil.findClientResourceById(realmRsc, application.getId()).toRepresentation().getId()); + + + // Test role mappings + UserRepresentation admin = findByUsername(realmRsc, "admin"); + // user without creation timestamp in import + Assert.assertNull(admin.getCreatedTimestamp()); + Set allRoles = allRoles(realmRsc, admin); + Assert.assertEquals(3, allRoles.size()); + Assert.assertTrue(containsRole(allRoles, findRealmRole(realmRsc, "admin"))); + Assert.assertTrue(containsRole(allRoles, findClientRole(realmRsc, application.getId(), "app-admin"))); + Assert.assertTrue(containsRole(allRoles, findClientRole(realmRsc, otherApp.getId(), "otherapp-admin"))); + + Assert.assertTrue(findClientRole(realmRsc, application.getId(), "app-admin").isScopeParamRequired()); + Assert.assertFalse(findClientRole(realmRsc, otherApp.getId(), "otherapp-admin").isScopeParamRequired()); + Assert.assertFalse(findClientRole(realmRsc, otherApp.getId(), "otherapp-user").isScopeParamRequired()); + + UserRepresentation wburke = findByUsername(realmRsc, "wburke"); + // user with creation timestamp in import + Assert.assertEquals(new Long(123654), wburke.getCreatedTimestamp()); + allRoles = allRoles(realmRsc, wburke); + Assert.assertEquals(2, allRoles.size()); + Assert.assertFalse(containsRole(allRoles, findRealmRole(realmRsc, "admin"))); + Assert.assertTrue(containsRole(allRoles, findClientRole(realmRsc, application.getId(), "app-user"))); + Assert.assertTrue(containsRole(allRoles, findClientRole(realmRsc, otherApp.getId(), "otherapp-user"))); + + Assert.assertNull(realmRsc.users().get(wburke.getId()).roles().getAll().getRealmMappings()); + + UserRepresentation loginclient = findByUsername(realmRsc, "loginclient"); + // user with creation timestamp as string in import + Assert.assertEquals(new Long(123655), loginclient.getCreatedTimestamp()); + + List realmRoles = realmRolesForUser(realmRsc, admin); + Assert.assertEquals(1, realmRoles.size()); + Assert.assertEquals("admin", realmRoles.iterator().next().getName()); + + List appRoles = clientRolesForUser(realmRsc, application, admin); + Assert.assertEquals(1, appRoles.size()); + Assert.assertEquals("app-admin", appRoles.iterator().next().getName()); + + // Test attributes + Map> attrs = wburke.getAttributesAsListValues(); + Assert.assertEquals(1, attrs.size()); + List attrVals = attrs.get("email"); + Assert.assertEquals(1, attrVals.size()); + Assert.assertEquals("bburke@redhat.com", attrVals.get(0)); + + attrs = admin.getAttributesAsListValues(); + Assert.assertEquals(2, attrs.size()); + attrVals = attrs.get("key1"); + Assert.assertEquals(1, attrVals.size()); + Assert.assertEquals("val1", attrVals.get(0)); + attrVals = attrs.get("key2"); + Assert.assertEquals(2, attrVals.size()); + Assert.assertTrue(attrVals.contains("val21") && attrVals.contains("val22")); + + // Test client + ClientResource oauthClient = ApiUtil.findClientResourceByClientId(realmRsc, "oauthclient"); + ClientRepresentation oauthClientRep = oauthClient.toRepresentation(); + Assert.assertEquals("clientpassword", oauthClient.getSecret().getValue()); + Assert.assertTrue(oauthClientRep.isEnabled()); + Assert.assertNotNull(oauthClientRep); + + // Test scope relationship + Set allScopes = allScopeMappings(oauthClient); + Assert.assertEquals(2, allScopes.size()); + Assert.assertTrue(containsRole(allScopes, findRealmRole(realmRsc, "admin"))); + Assert.assertTrue(containsRole(allScopes, findClientRole(realmRsc, application.getId(), "app-user"))); + + List realmScopes = realmScopeMappings(oauthClient); + Assert.assertTrue(containsRole(realmScopes, findRealmRole(realmRsc, "admin"))); + + List appScopes = clientScopeMappings(oauthClient); + Assert.assertTrue(containsRole(appScopes, findClientRole(realmRsc, application.getId(), "app-user"))); + + // Test social linking + UserResource socialUser = realmRsc.users().get(findByUsername(realmRsc, "mySocialUser").getId()); + List socialLinks = socialUser.getFederatedIdentity(); + Assert.assertEquals(3, socialLinks.size()); + boolean facebookFound = false; + boolean googleFound = false; + boolean twitterFound = false; + FederatedIdentityRepresentation facebookIdentityRep = null; + for (FederatedIdentityRepresentation federatedIdentityRep : socialLinks) { + if ("facebook1".equals(federatedIdentityRep.getIdentityProvider())) { + facebookFound = true; + facebookIdentityRep = federatedIdentityRep; + Assert.assertEquals("facebook1",federatedIdentityRep.getUserId()); + Assert.assertEquals("fbuser1", federatedIdentityRep.getUserName()); + } else if ("google1".equals(federatedIdentityRep.getIdentityProvider())) { + googleFound = true; + Assert.assertEquals("google1", federatedIdentityRep.getUserId()); + Assert.assertEquals("mysocialuser@gmail.com", federatedIdentityRep.getUserName()); + } else if ("twitter1".equals(federatedIdentityRep.getIdentityProvider())) { + twitterFound = true; + Assert.assertEquals("twitter1", federatedIdentityRep.getUserId()); + Assert.assertEquals("twuser1", federatedIdentityRep.getUserName()); + } + } + Assert.assertTrue(facebookFound && twitterFound && googleFound); + + UserRepresentation foundSocialUser = testingClient.testing().getUserByFederatedIdentity(realm.getRealm(), "facebook1", "facebook1", "fbuser1"); + Assert.assertEquals(foundSocialUser.getUsername(), socialUser.toRepresentation().getUsername()); + Assert.assertNull(testingClient.testing().getUserByFederatedIdentity(realm.getRealm(), "facebook", "not-existing", "not-existing")); + + Assert.assertEquals("facebook1", facebookIdentityRep.getUserId()); + Assert.assertEquals("fbuser1", facebookIdentityRep.getUserName()); + Assert.assertEquals("facebook1", facebookIdentityRep.getIdentityProvider()); + + // Test remove/add social link + socialUser.removeFederatedIdentity("facebook1"); + Assert.assertEquals(2, socialUser.getFederatedIdentity().size()); + socialUser.addFederatedIdentity("facebook1", facebookIdentityRep); + Assert.assertEquals(3, socialUser.getFederatedIdentity().size()); + + // Test smtp config + Map smtpConfig = realm.getSmtpServer(); + Assert.assertTrue(smtpConfig.size() == 3); + Assert.assertEquals("auto@keycloak.org", smtpConfig.get("from")); + Assert.assertEquals("localhost", smtpConfig.get("host")); + Assert.assertEquals("3025", smtpConfig.get("port")); + + // Test identity providers + List identityProviders = realm.getIdentityProviders(); + Assert.assertEquals(3, identityProviders.size()); + IdentityProviderRepresentation google = null; + for (IdentityProviderRepresentation idpRep : identityProviders) { + if (idpRep.getAlias().equals("google1")) google = idpRep; + } + Assert.assertNotNull(google); + Assert.assertEquals("google1", google.getAlias()); + Assert.assertEquals("google", google.getProviderId()); + Assert.assertTrue(google.isEnabled()); + Assert.assertEquals("googleId", google.getConfig().get("clientId")); + Assert.assertEquals("googleSecret", google.getConfig().get("clientSecret")); + + // Test federation providers + List fedProviders = realm.getUserFederationProviders(); + Assert.assertTrue(fedProviders.size() == 2); + UserFederationProviderRepresentation ldap1 = fedProviders.get(0); + Assert.assertEquals("MyLDAPProvider1", ldap1.getDisplayName()); + Assert.assertEquals("ldap", ldap1.getProviderName()); + Assert.assertEquals(1, ldap1.getPriority()); + Assert.assertEquals("ldap://foo", ldap1.getConfig().get(LDAPConstants.CONNECTION_URL)); + + UserFederationProviderRepresentation ldap2 = fedProviders.get(1); + Assert.assertEquals("MyLDAPProvider2", ldap2.getDisplayName()); + Assert.assertEquals("ldap://bar", ldap2.getConfig().get(LDAPConstants.CONNECTION_URL)); + + // Test federation mappers + List fedMappers1 = realmRsc.userFederation().get(ldap1.getId()).getMappers(); + Assert.assertTrue(fedMappers1.size() == 1); + UserFederationMapperRepresentation fullNameMapper = fedMappers1.iterator().next(); + Assert.assertEquals("FullNameMapper", fullNameMapper.getName()); + Assert.assertEquals(FullNameLDAPFederationMapperFactory.PROVIDER_ID, fullNameMapper.getFederationMapperType()); + //Assert.assertEquals(ldap1.getId(), fullNameMapper.getFederationProviderId()); + Assert.assertEquals("cn", fullNameMapper.getConfig().get(FullNameLDAPFederationMapper.LDAP_FULL_NAME_ATTRIBUTE)); + + // All builtin LDAP mappers should be here + List fedMappers2 = realmRsc.userFederation().get(ldap2.getId()).getMappers(); + Assert.assertTrue(fedMappers2.size() > 3); + List allMappers = realm.getUserFederationMappers(); + Assert.assertEquals(allMappers.size(), fedMappers1.size() + fedMappers2.size()); + + // Assert that federation link wasn't created during import + Assert.assertNull(testingClient.testing().getUserByUsernameFromFedProviderFactory(realm.getRealm(), "wburke")); + + // Test builtin authentication flows + AuthenticationFlowRepresentation clientFlow = testingClient.testing().getClientAuthFlow(realm.getRealm()); + Assert.assertEquals(DefaultAuthenticationFlows.CLIENT_AUTHENTICATION_FLOW, clientFlow.getAlias()); + Assert.assertNotNull(realmRsc.flows().getFlow(clientFlow.getId())); + Assert.assertTrue(realmRsc.flows().getExecutions(clientFlow.getAlias()).size() > 0); + + AuthenticationFlowRepresentation resetFlow = testingClient.testing().getResetCredFlow(realm.getRealm()); + Assert.assertEquals(DefaultAuthenticationFlows.RESET_CREDENTIALS_FLOW, resetFlow.getAlias()); + Assert.assertNotNull(realmRsc.flows().getFlow(resetFlow.getId())); + Assert.assertTrue(realmRsc.flows().getExecutions(resetFlow.getAlias()).size() > 0); + + // Test protocol mappers. Default application has all the builtin protocol mappers. OtherApp just gss credential + List applicationMappers = application.getProtocolMappers(); + Assert.assertNotNull(findMapperByName(applicationMappers, OIDCLoginProtocol.LOGIN_PROTOCOL, "username"));//application.getProtocolMapperByName(OIDCLoginProtocol.LOGIN_PROTOCOL, "username")); + Assert.assertNotNull(findMapperByName(applicationMappers, OIDCLoginProtocol.LOGIN_PROTOCOL, "email")); + Assert.assertNotNull(findMapperByName(applicationMappers, OIDCLoginProtocol.LOGIN_PROTOCOL, "given name")); + Assert.assertNull(findMapperByName(applicationMappers, OIDCLoginProtocol.LOGIN_PROTOCOL, KerberosConstants.GSS_DELEGATION_CREDENTIAL_DISPLAY_NAME)); + + Assert.assertEquals(1, otherApp.getProtocolMappers().size()); + List otherAppMappers = otherApp.getProtocolMappers(); + Assert.assertNull(findMapperByName(otherAppMappers, OIDCLoginProtocol.LOGIN_PROTOCOL, "username")); + ProtocolMapperRepresentation gssCredentialMapper = findMapperByName(otherAppMappers, OIDCLoginProtocol.LOGIN_PROTOCOL, KerberosConstants.GSS_DELEGATION_CREDENTIAL_DISPLAY_NAME); + assertGssProtocolMapper(gssCredentialMapper); + + // Test clientTemplates + List clientTemplates = realmRsc.clientTemplates().findAll(); + Assert.assertEquals(1, clientTemplates.size()); + ClientTemplateRepresentation clientTemplate = clientTemplates.get(0); + Assert.assertEquals("foo-template", clientTemplate.getName()); + Assert.assertEquals("foo-template-desc", clientTemplate.getDescription()); + Assert.assertEquals(OIDCLoginProtocol.LOGIN_PROTOCOL, clientTemplate.getProtocol()); + Assert.assertEquals(1, clientTemplate.getProtocolMappers().size()); + List clientTemplateMappers = clientTemplate.getProtocolMappers(); + ProtocolMapperRepresentation templateGssCredentialMapper = findMapperByName(clientTemplateMappers, OIDCLoginProtocol.LOGIN_PROTOCOL, KerberosConstants.GSS_DELEGATION_CREDENTIAL_DISPLAY_NAME); + assertGssProtocolMapper(templateGssCredentialMapper); + + // Test client template scopes + Set allClientTemplateScopes = allScopeMappings(realmRsc.clientTemplates().get(clientTemplate.getId())); + Assert.assertEquals(3, allClientTemplateScopes.size()); + Assert.assertTrue(containsRole(allClientTemplateScopes, findRealmRole(realmRsc, "admin")));//allClientTemplateScopes.contains(realm.getRole("admin"))); + Assert.assertTrue(containsRole(allClientTemplateScopes, findClientRole(realmRsc, application.getId(), "app-user")));//allClientTemplateScopes.contains(application.getRole("app-user"))); + Assert.assertTrue(containsRole(allClientTemplateScopes, findClientRole(realmRsc, application.getId(), "app-admin")));//allClientTemplateScopes.contains(application.getRole("app-admin"))); + + List clientTemplateRealmScopes = realmScopeMappings(realmRsc.clientTemplates().get(clientTemplate.getId())); + Assert.assertTrue(containsRole(clientTemplateRealmScopes, findRealmRole(realmRsc, "admin")));//clientTemplateRealmScopes.contains(realm.getRole("admin"))); + + List clientTemplateAppScopes = clientScopeMappings(realmRsc.clientTemplates().get(clientTemplate.getId()));//application.getClientScopeMappings(oauthClient); + Assert.assertTrue(containsRole(clientTemplateAppScopes, findClientRole(realmRsc, application.getId(), "app-user")));//clientTemplateAppScopes.contains(application.getRole("app-user"))); + Assert.assertTrue(containsRole(clientTemplateAppScopes, findClientRole(realmRsc, application.getId(), "app-admin")));//clientTemplateAppScopes.contains(application.getRole("app-admin"))); + + // Test user consents + //admin = session.users().getUserByUsername("admin", realm); + + UserResource adminRsc = realmRsc.users().get(admin.getId()); + List> consents = adminRsc.getConsents(); + Assert.assertEquals(2, consents.size());//.getConsents().size()); + + Map appAdminConsent = findConsentByClientId(consents, application.getClientId()); + Assert.assertEquals(2, calcNumberGrantedRoles(appAdminConsent)); + Assert.assertTrue(getGrantedProtocolMappers(appAdminConsent) == null || getGrantedProtocolMappers(appAdminConsent).isEmpty()); + Assert.assertTrue(isRealmRoleGranted(appAdminConsent, "admin"));//appAdminConsent.isRoleGranted(realm.getRole("admin"))); + Assert.assertTrue(isClientRoleGranted(appAdminConsent, application.getClientId(), "app-admin"));//appAdminConsent.isRoleGranted(application.getRole("app-admin"))); + + Map otherAppAdminConsent = findConsentByClientId(consents, otherApp.getClientId());//admin.getConsentByClient(otherApp.getId()); + Assert.assertEquals(1, calcNumberGrantedRoles(otherAppAdminConsent)); + Assert.assertEquals(1, getGrantedProtocolMappers(otherAppAdminConsent).size());//otherAppAdminConsent.getGrantedProtocolMappers().size()); + Assert.assertTrue(isRealmRoleGranted(otherAppAdminConsent, "admin"));//otherAppAdminConsent.isRoleGranted(realm.getRole("admin"))); + Assert.assertFalse(isClientRoleGranted(otherAppAdminConsent, application.getClientId(), "app-admin"));//otherAppAdminConsent.isRoleGranted(application.getRole("app-admin"))); + Assert.assertTrue(isProtocolMapperGranted(otherAppAdminConsent, gssCredentialMapper)); + + Assert.assertTrue(application.isStandardFlowEnabled()); + Assert.assertTrue(application.isImplicitFlowEnabled()); + Assert.assertTrue(application.isDirectAccessGrantsEnabled()); + Assert.assertFalse(otherApp.isStandardFlowEnabled()); + Assert.assertFalse(otherApp.isImplicitFlowEnabled()); + Assert.assertFalse(otherApp.isDirectAccessGrantsEnabled()); + + // Test service accounts + Assert.assertFalse(application.isServiceAccountsEnabled()); + Assert.assertTrue(otherApp.isServiceAccountsEnabled()); + Assert.assertNull(testingClient.testing().getUserByServiceAccountClient(realm.getRealm(), application.getClientId()));//session.users().getUserByServiceAccountClient(application)); + UserRepresentation linked = testingClient.testing().getUserByServiceAccountClient(realm.getRealm(), otherApp.getClientId());//session.users().getUserByServiceAccountClient(otherApp); + Assert.assertNotNull(linked); + Assert.assertEquals("my-service-user", linked.getUsername()); + } + + private static boolean isProtocolMapperGranted(Map consent, ProtocolMapperRepresentation mapperRep) { + Map grantedMappers = (Map)consent.get("grantedProtocolMappers"); + if (grantedMappers == null) return false; + List mappers = grantedMappers.get(mapperRep.getProtocol()); + if (mappers == null) return false; + return mappers.contains(mapperRep.getName()); + } + + private static boolean isRealmRoleGranted(Map consent, String roleName) { + if (consent.get("grantedRealmRoles") == null) return false; + return ((List)consent.get("grantedRealmRoles")).contains(roleName); + } + + private static boolean isClientRoleGranted(Map consent, String clientId, String roleName) { + if (consent.get("grantedClientRoles") == null) return false; + Map grantedClientRoles = (Map)consent.get("grantedClientRoles"); + List rolesForClient = grantedClientRoles.get(clientId); + if (rolesForClient == null) return false; + return rolesForClient.contains(roleName); + } + + private static Map> getGrantedProtocolMappers(Map consent) { + return (Map>)consent.get("grantedProtocolMappers"); + } + + private static int calcNumberGrantedRoles(Map consent) { + int numGranted = 0; + List realmRoles = (List)consent.get("grantedRealmRoles"); + if (realmRoles != null) numGranted += realmRoles.size(); + Map clientRoles = (Map)consent.get("grantedClientRoles"); + if (clientRoles != null) numGranted += clientRoles.size(); + return numGranted; + } + + private static Map findConsentByClientId(List> consents, String clientId) { + for (Map consent : consents) { + if (clientId.equals(consent.get("clientId"))) return consent; + } + return null; + } + + private static void assertGssProtocolMapper(ProtocolMapperRepresentation gssCredentialMapper) { + Assert.assertEquals(KerberosConstants.GSS_DELEGATION_CREDENTIAL_DISPLAY_NAME, gssCredentialMapper.getName()); + Assert.assertEquals( OIDCLoginProtocol.LOGIN_PROTOCOL, gssCredentialMapper.getProtocol()); + Assert.assertEquals(UserSessionNoteMapper.PROVIDER_ID, gssCredentialMapper.getProtocolMapper()); + String includeInAccessToken = gssCredentialMapper.getConfig().get(OIDCAttributeMapperHelper.INCLUDE_IN_ACCESS_TOKEN); + String includeInIdToken = gssCredentialMapper.getConfig().get(OIDCAttributeMapperHelper.INCLUDE_IN_ID_TOKEN); + Assert.assertTrue(includeInAccessToken.equalsIgnoreCase("true")); + Assert.assertTrue(includeInIdToken == null || Boolean.parseBoolean(includeInIdToken) == false); + } + + private static ProtocolMapperRepresentation findMapperByName(List mappers, String type, String name) { + for (ProtocolMapperRepresentation mapper : mappers) { + if (mapper.getProtocol().equals(type) && + mapper.getName().equals(name)) { + return mapper; + } + } + return null; + } + + private static boolean hasClient(List clients, ClientRepresentation client) { + for (ClientRepresentation clientRep : clients) { + if (client.getId().equals(clientRep.getId())) return true; + } + return false; + } + + // Workaround for KEYCLOAK-3104. For this realm, search() only works if username is null. + private static UserRepresentation findByUsername(RealmResource realmRsc, String username) { + for (UserRepresentation user : realmRsc.users().search(null, 0, Integer.MAX_VALUE)) { + if (user.getUsername().equalsIgnoreCase(username)) return user; + } + return null; + } + + private static Set allScopeMappings(ClientResource client) { + Set allRoles = new HashSet<>(); + List realmRoles = realmScopeMappings(client); + if (realmRoles != null) allRoles.addAll(realmRoles); + + allRoles.addAll(clientScopeMappings(client)); + + return allRoles; + } + + private static Set allScopeMappings(ClientTemplateResource client) { + Set allRoles = new HashSet<>(); + List realmRoles = realmScopeMappings(client); + if (realmRoles != null) allRoles.addAll(realmRoles); + + allRoles.addAll(clientScopeMappings(client)); + + return allRoles; + } + + private static List clientScopeMappings(ClientResource client) { + List clientScopeMappings = new LinkedList<>(); + Map clientRoles = client.getScopeMappings().getAll().getClientMappings(); + if (clientRoles == null) return clientScopeMappings; + + for (String clientKey : clientRoles.keySet()) { + List clientRoleScopeMappings = clientRoles.get(clientKey).getMappings(); + if (clientRoleScopeMappings != null) clientScopeMappings.addAll(clientRoleScopeMappings); + } + + return clientScopeMappings; + } + + private static List clientScopeMappings(ClientTemplateResource client) { + List clientScopeMappings = new LinkedList<>(); + Map clientRoles = client.getScopeMappings().getAll().getClientMappings(); + if (clientRoles == null) return clientScopeMappings; + + for (String clientKey : clientRoles.keySet()) { + List clientRoleScopeMappings = clientRoles.get(clientKey).getMappings(); + if (clientRoleScopeMappings != null) clientScopeMappings.addAll(clientRoleScopeMappings); + } + + return clientScopeMappings; + } + + private static List realmScopeMappings(ClientResource client) { + return client.getScopeMappings().realmLevel().listAll(); + } + + private static List realmScopeMappings(ClientTemplateResource client) { + return client.getScopeMappings().realmLevel().listAll(); + } + + private static Set allRoles(RealmResource realmRsc, UserRepresentation user) { + UserResource userRsc = realmRsc.users().get(user.getId()); + Set roles = new HashSet<>(); + + List realmRoles = userRsc.roles().getAll().getRealmMappings(); + if (realmRoles != null) roles.addAll(realmRoles); + + roles.addAll(allClientRolesForUser(realmRsc, user)); + + return roles; + } + + private static List realmRolesForUser(RealmResource realmRsc, UserRepresentation user) { + return realmRsc.users().get(user.getId()).roles().getAll().getRealmMappings(); + } + + private static List allClientRolesForUser(RealmResource realmRsc, UserRepresentation user) { + UserResource userRsc = realmRsc.users().get(user.getId()); + List roles = new LinkedList<>(); + for(String client : userRsc.roles().getAll().getClientMappings().keySet()) { + List clientRoles = userRsc.roles().getAll().getClientMappings().get(client).getMappings(); + if (clientRoles != null) roles.addAll(clientRoles); + } + return roles; + } + + private static List clientRolesForUser(RealmResource realmRsc, ClientRepresentation client, UserRepresentation user) { + UserResource userRsc = realmRsc.users().get(user.getId()); + return userRsc.roles().clientLevel(client.getId()).listAll(); + } + + private static RoleRepresentation findRealmRole(RealmResource realmRsc, String roleName) { + return realmRsc.roles().get(roleName).toRepresentation(); + } + + private static RoleRepresentation findClientRole(RealmResource realmRsc, String clientDbId, String roleName) { + return realmRsc.clients().get(clientDbId).roles().get(roleName).toRepresentation(); + } + + private static boolean containsRole(Collection roles, RoleRepresentation role) { + for (RoleRepresentation setRole : roles) { + if (setRole.getId().equals(role.getId())) return true; + } + return false; + } + +} diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/BruteForceTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/BruteForceTest.java index 0d6de842d3..90178a9dab 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/BruteForceTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/BruteForceTest.java @@ -41,6 +41,7 @@ import org.keycloak.testsuite.TestRealmKeycloakTest; import org.keycloak.testsuite.util.GreenMailRule; import org.keycloak.testsuite.util.OAuthClient; import org.keycloak.testsuite.util.UserBuilder; +import org.keycloak.testsuite.util.RealmRepUtil; /** * @author Stian Thorgersen @@ -50,7 +51,7 @@ public class BruteForceTest extends TestRealmKeycloakTest { @Override public void configureTestRealm(RealmRepresentation testRealm) { - UserRepresentation user = findUserInRealmRep(testRealm, "test-user@localhost"); + UserRepresentation user = RealmRepUtil.findUser(testRealm, "test-user@localhost"); CredentialRepresentation credRep = new CredentialRepresentation(); credRep.setType(CredentialRepresentation.TOTP); credRep.setValue("totpSecret"); @@ -60,8 +61,7 @@ public class BruteForceTest extends TestRealmKeycloakTest { testRealm.setBruteForceProtected(true); testRealm.setFailureFactor(2); - findClientInRealmRep(testRealm, "test-app").setDirectAccessGrantsEnabled(true); - + RealmRepUtil.findClientByClientId(testRealm, "test-app").setDirectAccessGrantsEnabled(true); testRealm.getUsers().add(UserBuilder.create().username("user2").email("user2@localhost").password("password").build()); } @@ -146,8 +146,8 @@ public class BruteForceTest extends TestRealmKeycloakTest { OAuthClient.AccessTokenResponse response = getTestToken("password", totpSecret); Assert.assertNull(response.getAccessToken()); Assert.assertNotNull(response.getError()); - Assert.assertEquals(response.getError(), "invalid_grant"); - Assert.assertEquals(response.getErrorDescription(), "Account temporarily disabled"); + Assert.assertEquals("invalid_grant", response.getError()); + Assert.assertEquals("Account temporarily disabled", response.getErrorDescription()); events.clear(); } clearUserFailures(); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/CustomFlowTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/CustomFlowTest.java index d9f21821e4..73b2af4ace 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/CustomFlowTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/CustomFlowTest.java @@ -45,6 +45,7 @@ import org.keycloak.testsuite.util.ClientBuilder; import org.keycloak.testsuite.util.ExecutionBuilder; import org.keycloak.testsuite.util.FlowBuilder; import org.keycloak.testsuite.util.OAuthClient; +import org.keycloak.testsuite.util.RealmRepUtil; import org.keycloak.testsuite.util.UserBuilder; import static org.junit.Assert.assertEquals; @@ -73,7 +74,7 @@ public class CustomFlowTest extends AbstractFlowTest { .build(); testRealm.getClients().add(dummyClient); - ClientRepresentation testApp = findClientInRealmRep(testRealm, "test-app"); + ClientRepresentation testApp = RealmRepUtil.findClientByClientId(testRealm, "test-app"); testApp.setClientAuthenticatorType(PassThroughClientAuthenticator.PROVIDER_ID); testApp.setDirectAccessGrantsEnabled(true); } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/LoginHotpTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/LoginHotpTest.java index 8964040e8e..43c6153c91 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/LoginHotpTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/LoginHotpTest.java @@ -36,6 +36,7 @@ import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.representations.idm.UserRepresentation; import org.keycloak.testsuite.TestRealmKeycloakTest; import org.keycloak.testsuite.util.GreenMailRule; +import org.keycloak.testsuite.util.RealmRepUtil; import org.keycloak.testsuite.util.UserBuilder; /** @@ -48,7 +49,7 @@ public class LoginHotpTest extends TestRealmKeycloakTest { @Override public void configureTestRealm(RealmRepresentation testRealm) { - UserRepresentation user = findUserInRealmRep(testRealm, "test-user@localhost"); + UserRepresentation user = RealmRepUtil.findUser(testRealm, "test-user@localhost"); UserBuilder.edit(user) .hotpSecret("hotpSecret") .otpEnabled(); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/LoginTotpTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/LoginTotpTest.java index 1c048474de..66e6badbae 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/LoginTotpTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/LoginTotpTest.java @@ -34,6 +34,7 @@ import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.representations.idm.UserRepresentation; import org.keycloak.testsuite.TestRealmKeycloakTest; import org.keycloak.testsuite.util.GreenMailRule; +import org.keycloak.testsuite.util.RealmRepUtil; import org.keycloak.testsuite.util.UserBuilder; /** @@ -44,7 +45,7 @@ public class LoginTotpTest extends TestRealmKeycloakTest { @Override public void configureTestRealm(RealmRepresentation testRealm) { - UserRepresentation user = findUserInRealmRep(testRealm, "test-user@localhost"); + UserRepresentation user = RealmRepUtil.findUser(testRealm, "test-user@localhost"); UserBuilder.edit(user) .totpSecret("totpSecret") .otpEnabled(); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/RealmRepUtil.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/RealmRepUtil.java new file mode 100644 index 0000000000..7d5b0c0a2b --- /dev/null +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/RealmRepUtil.java @@ -0,0 +1,103 @@ +/* + * Copyright 2016 Red Hat Inc. and/or its affiliates and other contributors + * as indicated by the @author tags. All rights reserved. + * + * 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.util; + +import java.util.HashSet; +import java.util.Set; +import org.keycloak.representations.idm.ClientRepresentation; +import org.keycloak.representations.idm.RealmRepresentation; +import org.keycloak.representations.idm.RoleRepresentation; +import org.keycloak.representations.idm.UserRepresentation; + +/** + * + * @author Stan Silvert ssilvert@redhat.com (C) 2016 Red Hat Inc. + */ +public class RealmRepUtil { + + // don't allow instance + private RealmRepUtil() { + } + + public static UserRepresentation findUser(RealmRepresentation testRealm, String userName) { + for (UserRepresentation user : testRealm.getUsers()) { + if (user.getUsername().equals(userName)) return user; + } + + return null; + } + + public static ClientRepresentation findClientByClientId(RealmRepresentation testRealm, String clientId) { + for (ClientRepresentation client : testRealm.getClients()) { + if (client.getClientId().equals(clientId)) return client; + } + + return null; + } + + public static ClientRepresentation findClientById(RealmRepresentation testRealm, String id) { + for (ClientRepresentation client : testRealm.getClients()) { + if (client.getId().equals(id)) return client; + } + return null; + } + + public static RoleRepresentation findRealmRole(RealmRepresentation realm, String roleName) { + if (realm.getRoles() == null) return null; + if (realm.getRoles().getRealm() == null) return null; + for (RoleRepresentation role : realm.getRoles().getRealm()) { + if (role.getName().equals(roleName)) return role; + } + + return null; + } + + public static RoleRepresentation findClientRole(RealmRepresentation realm, String clientId, String roleName) { + if (realm.getRoles() == null) return null; + if (realm.getRoles().getClient() == null) return null; + if (realm.getRoles().getClient().get(clientId) == null) return null; + for (RoleRepresentation role : realm.getRoles().getClient().get(clientId)) { + if (roleName.equals(role.getName())) return role; + } + + return null; + } + + public static String findDefaultRole(RealmRepresentation realm, String roleName) { + if (realm.getDefaultRoles() == null) return null; + for (String role : realm.getDefaultRoles()) { + if (role.equals(roleName)) return role; + } + + return null; + } + + public static Set allRoles(RealmRepresentation realm, UserRepresentation user) { + Set allRoles = new HashSet<>(); + for (String roleName : user.getRealmRoles()) { + allRoles.add(findRealmRole(realm, roleName)); + } + + for (String clientId : user.getClientRoles().keySet()) { + for (String roleName : user.getClientRoles().get(clientId)) { + allRoles.add(findClientRole(realm, clientId, roleName)); + } + } + + return allRoles; + } +} diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/model/testcomposites.json b/testsuite/integration-arquillian/tests/base/src/test/resources/model/testcomposites.json new file mode 100755 index 0000000000..740a4e198e --- /dev/null +++ b/testsuite/integration-arquillian/tests/base/src/test/resources/model/testcomposites.json @@ -0,0 +1,191 @@ +{ + "id": "TestComposites", + "realm": "TestComposites", + "enabled": true, + "accessTokenLifespan": 600, + "accessCodeLifespan": 600, + "accessCodeLifespanUserAction": 600, + "sslRequired": "external", + "registrationAllowed": true, + "resetPasswordAllowed": true, + "requiredCredentials": [ "password" ], + "smtpServer": { + "from": "auto@keycloak.org", + "host": "localhost", + "port":"3025" + }, + "users" : [ + { + "username" : "REALM_COMPOSITE_1_USER", + "enabled": true, + "email" : "test-user1@localhost", + "credentials" : [ + { "type" : "password", + "value" : "password" } + ], + "realmRoles": [ "REALM_COMPOSITE_1" ] + }, + { + "username" : "REALM_ROLE_1_USER", + "enabled": true, + "email" : "test-user2@localhost", + "credentials" : [ + { "type" : "password", + "value" : "password" } + ], + "realmRoles": [ "REALM_ROLE_1"] + }, + { + "username" : "REALM_APP_COMPOSITE_USER", + "enabled": true, + "email" : "test-user3@localhost", + "credentials" : [ + { "type" : "password", + "value" : "password" } + ], + "realmRoles": [ "REALM_APP_COMPOSITE_ROLE" ] + }, + { + "username" : "REALM_APP_ROLE_USER", + "enabled": true, + "email" : "test-user4@localhost", + "credentials" : [ + { "type" : "password", + "value" : "password" } + ], + "applicationRoles": { + "APP_ROLE_APPLICATION": [ "APP_ROLE_2" ] + } + }, + { + "username" : "APP_COMPOSITE_USER", + "enabled": true, + "email" : "test-user5@localhost", + "credentials" : [ + { "type" : "password", + "value" : "password" } + ], + "realmRoles": ["REALM_APP_COMPOSITE_ROLE", "REALM_COMPOSITE_1"] + } + ], + "oauthClients" : [ + { + "name" : "third-party", + "enabled": true, + "secret": "password" + } + ], + "scopeMappings": [ + { + "client": "REALM_COMPOSITE_1_APPLICATION", + "roles": ["REALM_COMPOSITE_1"] + }, + { + "client": "REALM_ROLE_1_APPLICATION", + "roles": ["REALM_ROLE_1"] + } + ], + "applications": [ + { + "name": "REALM_COMPOSITE_1_APPLICATION", + "fullScopeAllowed": false, + "enabled": true, + "baseUrl": "http://localhost:8081/app", + "adminUrl": "http://localhost:8081/app/logout", + "secret": "password" + }, + { + "name": "REALM_ROLE_1_APPLICATION", + "fullScopeAllowed": false, + "enabled": true, + "baseUrl": "http://localhost:8081/app", + "adminUrl": "http://localhost:8081/app/logout", + "secret": "password" + }, + { + "name": "APP_ROLE_APPLICATION", + "fullScopeAllowed": false, + "enabled": true, + "baseUrl": "http://localhost:8081/app", + "adminUrl": "http://localhost:8081/app/logout", + "secret": "password" + }, + { + "name": "APP_COMPOSITE_APPLICATION", + "fullScopeAllowed": false, + "enabled": true, + "baseUrl": "http://localhost:8081/app", + "adminUrl": "http://localhost:8081/app/logout", + "secret": "password" + } + ], + "roles" : { + "realm" : [ + { + "name": "REALM_ROLE_1" + }, + { + "name": "REALM_ROLE_2" + }, + { + "name": "REALM_ROLE_3" + }, + { + "name": "REALM_COMPOSITE_1", + "composites": { + "realm": ["REALM_ROLE_1"] + } + }, + { + "name": "REALM_APP_COMPOSITE_ROLE", + "composites": { + "application": { + "APP_ROLE_APPLICATION" :[ + "APP_ROLE_1" + ] + } + } + } + ], + "application" : { + "APP_ROLE_APPLICATION" : [ + { + "name": "APP_ROLE_1" + }, + { + "name": "APP_ROLE_2" + } + ], + "APP_COMPOSITE_APPLICATION" : [ + { + "name": "APP_COMPOSITE_ROLE", + "composites": { + "realm" : [ + "REALM_ROLE_1", + "REALM_ROLE_2", + "REALM_ROLE_3" + ], + "application": { + "APP_ROLE_APPLICATION" :[ + "APP_ROLE_1" + ] + } + } + }, + { + "name": "APP_ROLE_2" + } + ] + } + + }, + + "applicationScopeMappings": { + "APP_ROLE_APPLICATION": [ + { + "client": "APP_COMPOSITE_APPLICATION", + "roles": ["APP_ROLE_2"] + } + ] + } +} diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/model/testrealm-demo.json b/testsuite/integration-arquillian/tests/base/src/test/resources/model/testrealm-demo.json new file mode 100755 index 0000000000..c98bbf7f47 --- /dev/null +++ b/testsuite/integration-arquillian/tests/base/src/test/resources/model/testrealm-demo.json @@ -0,0 +1,63 @@ +{ + "realm": "demo", + "enabled": true, + "accessTokenLifespan": 300, + "accessCodeLifespan": 10, + "accessCodeLifespanUserAction": 600, + "sslRequired": "external", + "privateKey": "MIICXAIBAAKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQABAoGAfmO8gVhyBxdqlxmIuglbz8bcjQbhXJLR2EoS8ngTXmN1bo2L90M0mUKSdc7qF10LgETBzqL8jYlQIbt+e6TH8fcEpKCjUlyq0Mf/vVbfZSNaVycY13nTzo27iPyWQHK5NLuJzn1xvxxrUeXI6A2WFpGEBLbHjwpx5WQG9A+2scECQQDvdn9NE75HPTVPxBqsEd2z10TKkl9CZxu10Qby3iQQmWLEJ9LNmy3acvKrE3gMiYNWb6xHPKiIqOR1as7L24aTAkEAtyvQOlCvr5kAjVqrEKXalj0Tzewjweuxc0pskvArTI2Oo070h65GpoIKLc9jf+UA69cRtquwP93aZKtW06U8dQJAF2Y44ks/mK5+eyDqik3koCI08qaC8HYq2wVl7G2QkJ6sbAaILtcvD92ToOvyGyeE0flvmDZxMYlvaZnaQ0lcSQJBAKZU6umJi3/xeEbkJqMfeLclD27XGEFoPeNrmdx0q10Azp4NfJAY+Z8KRyQCR2BEG+oNitBOZ+YXF9KCpH3cdmECQHEigJhYg+ykOvr1aiZUMFT72HU0jnmQe2FVekuG+LJUt2Tm7GtMjTFoGpf0JwrVuZN39fOYAlo+nTixgeW7X8Y=", + "publicKey": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB", + "requiredCredentials": [ "password" ], + "users" : [ + { + "username" : "bburke@redhat.com", + "enabled": true, + "email" : "bburke@redhat.com", + "credentials" : [ + { "type" : "Password", + "value" : "password" } + ], + "realmRoles": [ "user" ] + } + ], + "oauthClients" : [ + { + "name" : "third-party", + "enabled": true, + "secret": "password" + } + ], + "roles" : { + "realm" : [ + { + "name": "user", + "description": "Have User privileges" + }, + { + "name": "admin", + "description": "Have Administrator privileges" + } + ] + }, + + "scopeMappings": [ + { + "client": "third-party", + "roles": ["user"] + } + ], + "applications": [ + { + "name": "customer-portal", + "enabled": true, + "adminUrl": "http://localhost:8080/customer-portal/j_admin_request", + "secret": "password" + }, + { + "name": "product-portal", + "enabled": true, + "adminUrl": "http://localhost:8080/product-portal/j_admin_request", + "secret": "password" + } + ] +} diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/model/testrealm-noclient-id.json b/testsuite/integration-arquillian/tests/base/src/test/resources/model/testrealm-noclient-id.json new file mode 100755 index 0000000000..4751c7f255 --- /dev/null +++ b/testsuite/integration-arquillian/tests/base/src/test/resources/model/testrealm-noclient-id.json @@ -0,0 +1,57 @@ + +{ + "realm": "demo-no-client-id", + "enabled": true, + "accessTokenLifespan": 300, + "accessCodeLifespan": 10, + "accessCodeLifespanUserAction": 600, + "sslRequired": "external", + "privateKey": "MIICXAIBAAKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQABAoGAfmO8gVhyBxdqlxmIuglbz8bcjQbhXJLR2EoS8ngTXmN1bo2L90M0mUKSdc7qF10LgETBzqL8jYlQIbt+e6TH8fcEpKCjUlyq0Mf/vVbfZSNaVycY13nTzo27iPyWQHK5NLuJzn1xvxxrUeXI6A2WFpGEBLbHjwpx5WQG9A+2scECQQDvdn9NE75HPTVPxBqsEd2z10TKkl9CZxu10Qby3iQQmWLEJ9LNmy3acvKrE3gMiYNWb6xHPKiIqOR1as7L24aTAkEAtyvQOlCvr5kAjVqrEKXalj0Tzewjweuxc0pskvArTI2Oo070h65GpoIKLc9jf+UA69cRtquwP93aZKtW06U8dQJAF2Y44ks/mK5+eyDqik3koCI08qaC8HYq2wVl7G2QkJ6sbAaILtcvD92ToOvyGyeE0flvmDZxMYlvaZnaQ0lcSQJBAKZU6umJi3/xeEbkJqMfeLclD27XGEFoPeNrmdx0q10Azp4NfJAY+Z8KRyQCR2BEG+oNitBOZ+YXF9KCpH3cdmECQHEigJhYg+ykOvr1aiZUMFT72HU0jnmQe2FVekuG+LJUt2Tm7GtMjTFoGpf0JwrVuZN39fOYAlo+nTixgeW7X8Y=", + "publicKey": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB", + "requiredCredentials": [ "password" ], + "users" : [ + { + "username" : "bburke@redhat.com", + "enabled": true, + "email" : "bburke@redhat.com", + "credentials" : [ + { "type" : "Password", + "value" : "password" } + ], + "realmRoles": [ "user" ] + } + ], + "roles" : { + "realm" : [ + { + "name": "user", + "description": "Have User privileges" + }, + { + "name": "admin", + "description": "Have Administrator privileges" + } + ] + }, + "scopeMappings": [ + { + "client": "third-party", + "roles": ["user"] + } + ], + "clients": [ + { + "name": "third-party", + "enabled": true, + "bearerOnly": true + } + ], + "clientScopeMappings": { + "realm-management": [ + { + "client": "some-client", + "roles": ["create-client"] + } + ] + } +} \ No newline at end of file diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/model/testrealm.json b/testsuite/integration-arquillian/tests/base/src/test/resources/model/testrealm.json new file mode 100755 index 0000000000..23be71982d --- /dev/null +++ b/testsuite/integration-arquillian/tests/base/src/test/resources/model/testrealm.json @@ -0,0 +1,290 @@ +{ + "realm": "test-realm", + "enabled": true, + "accessTokenLifespan": 6000, + "accessTokenLifespanForImplicitFlow": 1500, + "accessCodeLifespan": 30, + "accessCodeLifespanUserAction": 600, + "offlineSessionIdleTimeout": 3600000, + "requiredCredentials": [ "password" ], + "defaultRoles": [ "foo", "bar" ], + "verifyEmail" : "true", + "smtpServer": { + "from": "auto@keycloak.org", + "host": "localhost", + "port":"3025" + }, + "identityProviders" : [ + { + "providerId" : "google", + "alias" : "google1", + "enabled": true, + "config": { + "clientId": "googleId", + "clientSecret": "googleSecret" + } + }, + { + "providerId" : "facebook", + "alias" : "facebook1", + "enabled": true, + "config": { + "clientId": "facebookId", + "clientSecret": "facebookSecret" + } + }, + { + "providerId" : "twitter", + "alias" : "twitter1", + "enabled": true, + "config": { + "clientId": "twitterId", + "clientSecret": "twitterSecret" + } + } + ], + "userFederationProviders": [ + { + "displayName": "MyLDAPProvider1", + "providerName": "ldap", + "priority": 1, + "config": { + "connectionUrl": "ldap://foo" + } + }, + { + "displayName": "MyLDAPProvider2", + "providerName": "ldap", + "priority": 2, + "config": { + "connectionUrl": "ldap://bar" + } + } + ], + "userFederationMappers": [ + { + "name": "FullNameMapper", + "federationProviderDisplayName": "MyLDAPProvider1", + "federationMapperType": "full-name-ldap-mapper", + "config": { + "ldap.full.name.attribute": "cn" + } + } + ], + "users": [ + { + "username": "wburke", + "enabled": true, + "createdTimestamp" : 123654, + "attributes": { + "email": "bburke@redhat.com" + }, + "credentials": [ + { + "type": "password", + "value": "userpassword" + } + ], + "applicationRoles": { + "Application": [ "app-user" ], + "OtherApp": [ "otherapp-user" ] + } + }, + { + "username": "loginclient", + "createdTimestamp" : "123655", + "enabled": true, + "credentials": [ + { + "type": "password", + "value": "clientpassword" + } + ] + }, + { + "username": "admin", + "enabled": true, + "attributes": { + "key1": [ + "val1" + ], + "key2": [ + "val21", + "val22" + ] + }, + "credentials": [ + { + "type": "password", + "value": "adminpassword" + } + ], + "realmRoles": [ "admin" ], + "applicationRoles": { + "Application": [ "app-admin" ], + "OtherApp": [ "otherapp-admin" ] + }, + "clientConsents": [ + { + "clientId": "Application", + "grantedRealmRoles": [ "admin" ], + "grantedClientRoles": { + "Application": [ "app-admin" ] + } + }, + { + "clientId": "OtherApp", + "grantedRealmRoles": [ "admin" ], + "grantedProtocolMappers": { + "openid-connect": [ "gss delegation credential" ] + } + } + ] + }, + { + "username": "mySocialUser", + "enabled": true, + "federatedIdentities": [ + { + "identityProvider": "facebook1", + "userId": "facebook1", + "userName": "fbuser1" + }, + { + "identityProvider": "twitter1", + "userId": "twitter1", + "userName": "twuser1" + }, + { + "identityProvider": "google1", + "userId": "google1", + "userName": "mySocialUser@gmail.com" + } + ] + }, + { + "username": "my-service-user", + "enabled": true, + "serviceAccountClientId": "OtherApp" + } + ], + "clients": [ + { + "clientId": "Application", + "name": "Applicationn", + "enabled": true, + "implicitFlowEnabled": true, + "directAccessGrantsEnabled": true, + "nodeReRegistrationTimeout": 50, + "registeredNodes": { + "node1": 10, + "172.10.15.20": 20 + } + }, + { + "clientId": "OtherApp", + "name": "Other Application", + "enabled": true, + "standardFlowEnabled": false, + "directAccessGrantsEnabled": false, + "serviceAccountsEnabled": true, + "clientAuthenticatorType": "client-jwt", + "protocolMappers" : [ + { + "name" : "gss delegation credential", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usersessionmodel-note-mapper", + "consentRequired" : true, + "consentText" : "gss delegation credential", + "config" : { + "user.session.note" : "gss_delegation_credential", + "access.token.claim" : "true", + "claim.name" : "gss_delegation_credential", + "Claim JSON Type" : "String" + } + } + ] + } + ], + "oauthClients" : [ + { + "name" : "oauthclient", + "enabled": true, + "secret": "clientpassword" + } + ], + "clientTemplates" : [ + { + "name" : "foo-template", + "description" : "foo-template-desc", + "protocol" : "openid-connect", + "protocolMappers" : [ + { + "name" : "gss delegation credential", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usersessionmodel-note-mapper", + "consentRequired" : true, + "consentText" : "gss delegation credential", + "config" : { + "user.session.note" : "gss_delegation_credential", + "access.token.claim" : "true", + "claim.name" : "gss_delegation_credential", + "Claim JSON Type" : "String" + } + } + ] + } + ], + "roles" : { + "realm" : [ + { + "name": "admin" + } + ], + "application" : { + "Application" : [ + { + "name": "app-admin", + "scopeParamRequired": true + }, + { + "name": "app-user" + } + ], + "OtherApp" : [ + { + "name": "otherapp-admin", + "scopeParamRequired": false + }, + { + "name": "otherapp-user" + } + ] + } + }, + "scopeMappings": [ + { + "client": "oauthclient", + "roles": ["admin"] + }, + { + "clientTemplate": "foo-template", + "roles": ["admin"] + } + ], + "applicationScopeMappings": { + "Application": [ + { + "client": "oauthclient", + "roles": ["app-user"] + }, + { + "clientTemplate": "foo-template", + "roles": ["app-user", "app-admin" ] + } + ] + + } + + +} \ No newline at end of file diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/model/testrealm2.json b/testsuite/integration-arquillian/tests/base/src/test/resources/model/testrealm2.json new file mode 100755 index 0000000000..4e3d9fb65f --- /dev/null +++ b/testsuite/integration-arquillian/tests/base/src/test/resources/model/testrealm2.json @@ -0,0 +1,89 @@ +{ + "realm": "demo-delete", + "enabled": true, + "accessTokenLifespan": 3000, + "accessCodeLifespan": 10, + "accessCodeLifespanUserAction": 6000, + "sslRequired": "external", + "registrationAllowed": false, + "privateKey": "MIICXAIBAAKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQABAoGAfmO8gVhyBxdqlxmIuglbz8bcjQbhXJLR2EoS8ngTXmN1bo2L90M0mUKSdc7qF10LgETBzqL8jYlQIbt+e6TH8fcEpKCjUlyq0Mf/vVbfZSNaVycY13nTzo27iPyWQHK5NLuJzn1xvxxrUeXI6A2WFpGEBLbHjwpx5WQG9A+2scECQQDvdn9NE75HPTVPxBqsEd2z10TKkl9CZxu10Qby3iQQmWLEJ9LNmy3acvKrE3gMiYNWb6xHPKiIqOR1as7L24aTAkEAtyvQOlCvr5kAjVqrEKXalj0Tzewjweuxc0pskvArTI2Oo070h65GpoIKLc9jf+UA69cRtquwP93aZKtW06U8dQJAF2Y44ks/mK5+eyDqik3koCI08qaC8HYq2wVl7G2QkJ6sbAaILtcvD92ToOvyGyeE0flvmDZxMYlvaZnaQ0lcSQJBAKZU6umJi3/xeEbkJqMfeLclD27XGEFoPeNrmdx0q10Azp4NfJAY+Z8KRyQCR2BEG+oNitBOZ+YXF9KCpH3cdmECQHEigJhYg+ykOvr1aiZUMFT72HU0jnmQe2FVekuG+LJUt2Tm7GtMjTFoGpf0JwrVuZN39fOYAlo+nTixgeW7X8Y=", + "publicKey": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB", + "requiredCredentials": [ "password" ], + "users" : [ + { + "username" : "bburke@redhat.com", + "enabled": true, + "email" : "bburke@redhat.com", + "firstName": "Bill", + "lastName": "Burke", + "credentials" : [ + { "type" : "password", + "value" : "password" } + ], + "realmRoles": ["user"], + "applicationRoles": { + "account": [ "manage-account" ] + } + + } + ], + "roles" : { + "realm" : [ + { + "name": "user", + "description": "User privileges" + }, + { + "name": "admin", + "description": "Administrator privileges" + } + ] + }, + "scopeMappings": [ + { + "client": "third-party", + "roles": ["user"] + }, + { + "client": "customer-portal", + "roles": ["user"] + }, + { + "client": "product-portal", + "roles": ["user"] + } + + ], + "applications": [ + { + "name": "customer-portal", + "enabled": true, + "adminUrl": "http://localhost:8080/customer-portal", + "redirectUris": [ + "http://localhost:8080/customer-portal/*" + ], + "secret": "password" + }, + { + "name": "product-portal", + "enabled": true, + "adminUrl": "http://localhost:8080/product-portal", + "redirectUris": [ + "http://localhost:8080/product-portal/*" + ], + "secret": "password" + } + ], + "oauthClients": [ + { + "name": "third-party", + "enabled": true, + "redirectUris": [ + "http://localhost:8080/oauth-client/*", + "http://localhost:8080/oauth-client-cdi/*" + ], + "secret": "password" + } + ] + +} diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/exportimport/ExportImportTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/exportimport/ExportImportTest.java deleted file mode 100755 index 1fb4403ff8..0000000000 --- a/testsuite/integration/src/test/java/org/keycloak/testsuite/exportimport/ExportImportTest.java +++ /dev/null @@ -1,402 +0,0 @@ -/* - * 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.exportimport; - -import org.junit.Assert; -import org.junit.ClassRule; -import org.junit.Test; -import org.junit.rules.ExternalResource; -import org.junit.rules.RuleChain; -import org.junit.rules.TestRule; -import org.keycloak.exportimport.ExportImportConfig; -import org.keycloak.exportimport.dir.DirExportProvider; -import org.keycloak.exportimport.dir.DirExportProviderFactory; -import org.keycloak.exportimport.singlefile.SingleFileExportProviderFactory; -import org.keycloak.models.KeycloakSession; -import org.keycloak.models.RealmModel; -import org.keycloak.models.RealmProvider; -import org.keycloak.models.UserCredentialModel; -import org.keycloak.models.UserModel; -import org.keycloak.models.UserProvider; -import org.keycloak.representations.idm.CredentialRepresentation; -import org.keycloak.representations.idm.RealmRepresentation; -import org.keycloak.services.managers.RealmManager; -import org.keycloak.testsuite.model.AbstractModelTest; -import org.keycloak.testsuite.model.ImportTest; -import org.keycloak.testsuite.rule.KeycloakRule; - -import java.io.File; -import java.io.IOException; -import java.net.URL; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Properties; -import java.util.Set; -import java.util.regex.Matcher; - -/** - * TODO: Move to integration-arquillian and make subclass of AbstractExportImportTest - * - * @author Marek Posolda - */ -public class ExportImportTest { - - private static SystemPropertiesHelper propsHelper = new SystemPropertiesHelper(); - - private static final String JPA_CONNECTION_URL = "keycloak.connectionsJpa.url"; - - // We want data to be persisted among server restarts - private static ExternalResource persistenceSetupRule = new ExternalResource() { - - @Override - protected void before() throws Throwable { - if (System.getProperty(JPA_CONNECTION_URL) == null) { - String baseExportImportDir = getExportImportTestDirectory(); - - File oldDBFile = new File(baseExportImportDir, "keycloakDB.h2.db"); - if (oldDBFile.exists()) { - oldDBFile.delete(); - } - - String dbDir = baseExportImportDir + "/keycloakDB"; - propsHelper.pushProperty(JPA_CONNECTION_URL, "jdbc:h2:file:" + dbDir + ";DB_CLOSE_DELAY=-1"); - } - } - - @Override - protected void after() { - propsHelper.pullProperty(JPA_CONNECTION_URL); - } - }; - - private static KeycloakRule keycloakRule = new KeycloakRule( new KeycloakRule.KeycloakSetup() { - - @Override - public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) { - // Create some users in "test" and "master" realms - addUser(manager.getSession().users(), appRealm, "user1", "password"); - addUser(manager.getSession().users(), appRealm, "user2", "password"); - addUser(manager.getSession().users(), appRealm, "user3", "password"); - - // Import "test-realm" realm - try { - RealmRepresentation rep = AbstractModelTest.loadJson("model/testrealm.json"); - rep.setId("test-realm"); - RealmModel demoRealm = manager.importRealm(rep); - } catch (IOException ioe) { - throw new RuntimeException(ioe); - } - } - - }) { - @Override - protected void after() { - super.after(); - - // TODO: Make this subclass of AbstractExportImportTest and use AbstractExportImportTest.clearExportImportProperties - - // Clear export/import properties after test - Properties systemProps = System.getProperties(); - Set propsToRemove = new HashSet(); - - for (Object key : systemProps.keySet()) { - if (key.toString().startsWith(ExportImportConfig.PREFIX)) { - propsToRemove.add(key.toString()); - } - } - - for (String propToRemove : propsToRemove) { - systemProps.remove(propToRemove); - } - } - - protected String[] getTestRealms() { - return new String[]{"test", "demo", "test-realm"}; - } - }; - - @ClassRule - public static TestRule chain = RuleChain - .outerRule(persistenceSetupRule) - .around(keycloakRule); - - @Test - public void testDirFullExportImport() throws Throwable { - ExportImportConfig.setProvider(DirExportProviderFactory.PROVIDER_ID); - String targetDirPath = getExportImportTestDirectory() + File.separator + "dirExport"; - DirExportProvider.recursiveDeleteDir(new File(targetDirPath)); - ExportImportConfig.setDir(targetDirPath); - ExportImportConfig.setUsersPerFile(ExportImportConfig.DEFAULT_USERS_PER_FILE); - - testFullExportImport(); - - // There should be 6 files in target directory (3 realm, 3 user) - Assert.assertEquals(6, new File(targetDirPath).listFiles().length); - } - - @Test - public void testDirRealmExportImport() throws Throwable { - ExportImportConfig.setProvider(DirExportProviderFactory.PROVIDER_ID); - String targetDirPath = getExportImportTestDirectory() + File.separator + "dirRealmExport"; - DirExportProvider.recursiveDeleteDir(new File(targetDirPath)); - ExportImportConfig.setDir(targetDirPath); - ExportImportConfig.setUsersPerFile(3); - - testRealmExportImport(); - - // There should be 3 files in target directory (1 realm, 3 user) - File[] files = new File(targetDirPath).listFiles(); - Assert.assertEquals(4, files.length); - } - - @Test - public void testSingleFileFullExportImport() throws Throwable { - ExportImportConfig.setProvider(SingleFileExportProviderFactory.PROVIDER_ID); - String targetFilePath = getExportImportTestDirectory() + File.separator + "singleFile-full.json"; - ExportImportConfig.setFile(targetFilePath); - - testFullExportImport(); - } - - @Test - public void testSingleFileRealmExportImport() throws Throwable { - ExportImportConfig.setProvider(SingleFileExportProviderFactory.PROVIDER_ID); - String targetFilePath = getExportImportTestDirectory() + File.separator + "singleFile-realm.json"; - ExportImportConfig.setFile(targetFilePath); - - testRealmExportImport(); - } - - @Test - public void testSingleFileRealmWithoutBuiltinsImport() throws Throwable { - // Remove test realm - KeycloakSession session = keycloakRule.startSession(); - try { - new RealmManager(session).removeRealm(session.realms().getRealmByName("test-realm")); - } finally { - keycloakRule.stopSession(session, true); - } - - // Set the realm, which doesn't have builtin clients/roles inside JSON - ExportImportConfig.setProvider(SingleFileExportProviderFactory.PROVIDER_ID); - URL url = ExportImportTest.class.getResource("/model/testrealm.json"); - String targetFilePath = new File(url.getFile()).getAbsolutePath(); - ExportImportConfig.setFile(targetFilePath); - - ExportImportConfig.setAction(ExportImportConfig.ACTION_IMPORT); - - // Restart server to trigger import - keycloakRule.restartServer(); - - // Ensure realm imported - session = keycloakRule.startSession(); - try { - RealmModel testRealmRealm = session.realms().getRealmByName("test-realm"); - ImportTest.assertDataImportedInRealm(session, testRealmRealm); - } finally { - keycloakRule.stopSession(session, true); - } - } - - private void testFullExportImport() { - ExportImportConfig.setAction(ExportImportConfig.ACTION_EXPORT); - ExportImportConfig.setRealmName(null); - - // Restart server, which triggers export - keycloakRule.restartServer(); - - // Delete some realm (and some data in admin realm) - KeycloakSession session = keycloakRule.startSession(); - try { - RealmProvider realmProvider = session.realms(); - UserProvider userProvider = session.users(); - new RealmManager(session).removeRealm(realmProvider.getRealmByName("test")); - new RealmManager(session).removeRealm(realmProvider.getRealmByName("test-realm")); - Assert.assertEquals(1, realmProvider.getRealms().size()); - - assertNotAuthenticated(userProvider, realmProvider, "test", "test-user@localhost", "password"); - assertNotAuthenticated(userProvider, realmProvider, "test", "user1", "password"); - assertNotAuthenticated(userProvider, realmProvider, "test", "user2", "password"); - assertNotAuthenticated(userProvider, realmProvider, "test", "user3", "password"); - } finally { - keycloakRule.stopSession(session, true); - } - - // Configure import - ExportImportConfig.setAction(ExportImportConfig.ACTION_IMPORT); - - // Restart server, which triggers import - keycloakRule.restartServer(); - - // Ensure data are imported back - session = keycloakRule.startSession(); - try { - RealmProvider model = session.realms(); - UserProvider userProvider = session.users(); - Assert.assertEquals(3, model.getRealms().size()); - - assertAuthenticated(userProvider, model, "test", "test-user@localhost", "password"); - assertAuthenticated(userProvider, model, "test", "user1", "password"); - assertAuthenticated(userProvider, model, "test", "user2", "password"); - assertAuthenticated(userProvider, model, "test", "user3", "password"); - - RealmModel testRealmRealm = model.getRealmByName("test-realm"); - ImportTest.assertDataImportedInRealm(session, testRealmRealm); - } finally { - keycloakRule.stopSession(session, true); - } - } - - private void testRealmExportImport() { - ExportImportConfig.setAction(ExportImportConfig.ACTION_EXPORT); - ExportImportConfig.setRealmName("test"); - - // Restart server, which triggers export - keycloakRule.restartServer(); - - // Delete some realm (and some data in admin realm) - KeycloakSession session = keycloakRule.startSession(); - try { - RealmProvider realmProvider = session.realms(); - UserProvider userProvider = session.users(); - new RealmManager(session).removeRealm(realmProvider.getRealmByName("test")); - Assert.assertEquals(2, realmProvider.getRealms().size()); - - assertNotAuthenticated(userProvider, realmProvider, "test", "test-user@localhost", "password"); - assertNotAuthenticated(userProvider, realmProvider, "test", "user1", "password"); - assertNotAuthenticated(userProvider, realmProvider, "test", "user2", "password"); - assertNotAuthenticated(userProvider, realmProvider, "test", "user3", "password"); - } finally { - keycloakRule.stopSession(session, true); - } - - // Configure import - ExportImportConfig.setAction(ExportImportConfig.ACTION_IMPORT); - - // Restart server, which triggers import - keycloakRule.restartServer(); - - // Ensure data are imported back, but just for "test" realm - session = keycloakRule.startSession(); - try { - RealmProvider realmProvider = session.realms(); - UserProvider userProvider = session.users(); - Assert.assertEquals(3, realmProvider.getRealms().size()); - - assertAuthenticated(userProvider, realmProvider, "test", "test-user@localhost", "password"); - assertAuthenticated(userProvider, realmProvider, "test", "user1", "password"); - assertAuthenticated(userProvider, realmProvider, "test", "user2", "password"); - assertAuthenticated(userProvider, realmProvider, "test", "user3", "password"); - } finally { - keycloakRule.stopSession(session, true); - } - } - - private void assertAuthenticated(UserProvider userProvider, RealmProvider realmProvider, String realmName, String username, String password) { - RealmModel realm = realmProvider.getRealmByName(realmName); - if (realm == null) { - Assert.fail("realm " + realmName + " not found"); - } - - UserModel user = userProvider.getUserByUsername(username, realm); - if (user == null) { - Assert.fail("user " + username + " not found"); - } - - KeycloakSession session = keycloakRule.startSession(); - try { - Assert.assertTrue(userProvider.validCredentials(session, realm, user, UserCredentialModel.password(password))); - } finally { - keycloakRule.stopSession(session, true); - } - } - - private void assertNotAuthenticated(UserProvider userProvider, RealmProvider realmProvider, String realmName, String username, String password) { - RealmModel realm = realmProvider.getRealmByName(realmName); - if (realm == null) { - return; - } - - UserModel user = userProvider.getUserByUsername(username, realm); - if (user == null) { - return; - } - - KeycloakSession session = keycloakRule.startSession(); - try { - Assert.assertFalse(userProvider.validCredentials(session, realm, user, UserCredentialModel.password(password))); - } finally { - keycloakRule.stopSession(session, true); - } - } - - private static void addUser(UserProvider userProvider, RealmModel appRealm, String username, String password) { - UserModel user = userProvider.addUser(appRealm, username); - user.setEmail(username + "@test.com"); - user.setEnabled(true); - - UserCredentialModel creds = new UserCredentialModel(); - creds.setType(CredentialRepresentation.PASSWORD); - creds.setValue(password); - user.updateCredential(creds); - } - - private static String getExportImportTestDirectory() { - String dirPath = null; - String relativeDirExportImportPath = "testsuite" + File.separator + "integration" + File.separator + "target" + File.separator + "export-import"; - - if (System.getProperties().containsKey("maven.home")) { - dirPath = System.getProperty("user.dir").replaceFirst("testsuite.integration.*", Matcher.quoteReplacement(relativeDirExportImportPath)); - } else { - for (String c : System.getProperty("java.class.path").split(File.pathSeparator)) { - if (c.contains(File.separator + "testsuite" + File.separator + "integration")) { - dirPath = c.replaceFirst("testsuite.integration.*", Matcher.quoteReplacement(relativeDirExportImportPath)); - } - } - } - - String absolutePath = new File(dirPath).getAbsolutePath(); - return absolutePath; - } - - private static class SystemPropertiesHelper { - - private Map previousValues = new HashMap(); - - private void pushProperty(String name, String value) { - String currentValue = System.getProperty(name); - previousValues.put(name, currentValue); - System.setProperty(name, value); - } - - private void pullProperty(String name) { - if (previousValues.containsKey(name)) { - String prevValue = previousValues.get(name); - - if (prevValue == null) { - System.getProperties().remove(name); - } else { - System.setProperty(name, prevValue); - } - } - } - - } - -} diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/model/ImportTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/model/ImportTest.java index 547b58356b..8beaffb6cd 100755 --- a/testsuite/integration/src/test/java/org/keycloak/testsuite/model/ImportTest.java +++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/model/ImportTest.java @@ -90,6 +90,12 @@ public class ImportTest extends AbstractModelTest { } // Moved to static method, so it's possible to test this from other places too (for example export-import tests) + /* + BIG HELPFUL HINT!!!! + WHEN YOU MIGRATE THIS CLASS YOU DO NOT NEED TO MIGRATE THIS METHOD. + IT HAS ALREADY BEEN IMPLEMENTED IN THE NEW ARQUILLIAN TESTSUTE. + SEE org.keycloak.testsuite.exportimport.ExportImportUtil + */ public static void assertDataImportedInRealm(KeycloakSession session, RealmModel realm) { Assert.assertTrue(realm.isVerifyEmail()); Assert.assertEquals(3600000, realm.getOfflineSessionIdleTimeout());