keycloak-aplcache

Merge pull request #3791 from mposolda/master KEYCLOAK-4282

1/25/2017 9:21:21 AM

Details

diff --git a/server-spi-private/src/main/java/org/keycloak/models/utils/RepresentationToModel.java b/server-spi-private/src/main/java/org/keycloak/models/utils/RepresentationToModel.java
index a21d545..e3e3557 100755
--- a/server-spi-private/src/main/java/org/keycloak/models/utils/RepresentationToModel.java
+++ b/server-spi-private/src/main/java/org/keycloak/models/utils/RepresentationToModel.java
@@ -129,7 +129,7 @@ public class RepresentationToModel {
         return policy;
 
     }
-    public static void importRealm(KeycloakSession session, RealmRepresentation rep, RealmModel newRealm) {
+    public static void importRealm(KeycloakSession session, RealmRepresentation rep, RealmModel newRealm, boolean skipUserDependent) {
         convertDeprecatedSocialProviders(rep);
         convertDeprecatedApplications(session, rep);
 
@@ -279,13 +279,6 @@ public class RepresentationToModel {
             }
         }
 
-        if (rep.getClients() != null) {
-            rep.getClients().forEach(clientRepresentation -> {
-                ClientModel client = newRealm.getClientByClientId(clientRepresentation.getClientId());
-                importAuthorizationSettings(clientRepresentation, client, session);
-            });
-        }
-
         if (rep.getSmtpServer() != null) {
             newRealm.setSmtpConfig(new HashMap(rep.getSmtpServer()));
         }
@@ -331,6 +324,10 @@ public class RepresentationToModel {
             }
         }
 
+        if (!skipUserDependent) {
+            importRealmAuthorizationSettings(rep, newRealm, session);
+        }
+
         if(rep.isInternationalizationEnabled() != null){
             newRealm.setInternationalizationEnabled(rep.isInternationalizationEnabled());
         }
@@ -1813,6 +1810,15 @@ public class RepresentationToModel {
         }
     }
 
+    public static void importRealmAuthorizationSettings(RealmRepresentation rep, RealmModel newRealm, KeycloakSession session) {
+        if (rep.getClients() != null) {
+            rep.getClients().forEach(clientRepresentation -> {
+                ClientModel client = newRealm.getClientByClientId(clientRepresentation.getClientId());
+                importAuthorizationSettings(clientRepresentation, client, session);
+            });
+        }
+    }
+
     public static void importAuthorizationSettings(ClientRepresentation clientRepresentation, ClientModel client, KeycloakSession session) {
         if (Boolean.TRUE.equals(clientRepresentation.getAuthorizationServicesEnabled())) {
             AuthorizationProviderFactory authorizationFactory = (AuthorizationProviderFactory) session.getKeycloakSessionFactory().getProviderFactory(AuthorizationProvider.class);
diff --git a/services/src/main/java/org/keycloak/exportimport/dir/DirImportProvider.java b/services/src/main/java/org/keycloak/exportimport/dir/DirImportProvider.java
index e31cb8e..a2a0699 100755
--- a/services/src/main/java/org/keycloak/exportimport/dir/DirImportProvider.java
+++ b/services/src/main/java/org/keycloak/exportimport/dir/DirImportProvider.java
@@ -25,7 +25,9 @@ import org.keycloak.exportimport.util.ExportImportSessionTask;
 import org.keycloak.exportimport.util.ImportUtils;
 import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.KeycloakSessionFactory;
+import org.keycloak.models.RealmModel;
 import org.keycloak.models.utils.KeycloakModelUtils;
+import org.keycloak.models.utils.RepresentationToModel;
 import org.keycloak.representations.idm.RealmRepresentation;
 import org.keycloak.util.JsonSerialization;
 
@@ -136,7 +138,7 @@ public class DirImportProvider implements ImportProvider {
 
             @Override
             public void runExportImportTask(KeycloakSession session) throws IOException {
-                boolean imported = ImportUtils.importRealm(session, realmRep, strategy);
+                boolean imported = ImportUtils.importRealm(session, realmRep, strategy, true);
                 realmImported.set(imported);
             }
 
@@ -165,6 +167,17 @@ public class DirImportProvider implements ImportProvider {
                 });
             }
         }
+
+        // Import authorization last, as authzPolicies can require users already in DB
+        KeycloakModelUtils.runJobInTransaction(factory, new ExportImportSessionTask() {
+
+            @Override
+            public void runExportImportTask(KeycloakSession session) throws IOException {
+                RealmModel realm = session.realms().getRealmByName(realmName);
+                RepresentationToModel.importRealmAuthorizationSettings(realmRep, realm, session);
+            }
+
+        });
     }
 
     @Override
diff --git a/services/src/main/java/org/keycloak/exportimport/singlefile/SingleFileImportProviderFactory.java b/services/src/main/java/org/keycloak/exportimport/singlefile/SingleFileImportProviderFactory.java
index 5b486c9..a54af3f 100755
--- a/services/src/main/java/org/keycloak/exportimport/singlefile/SingleFileImportProviderFactory.java
+++ b/services/src/main/java/org/keycloak/exportimport/singlefile/SingleFileImportProviderFactory.java
@@ -34,6 +34,9 @@ public class SingleFileImportProviderFactory implements ImportProviderFactory {
     @Override
     public ImportProvider create(KeycloakSession session) {
         String fileName = ExportImportConfig.getFile();
+        if (fileName == null) {
+            throw new IllegalArgumentException("Property " + ExportImportConfig.FILE + " needs to be provided!");
+        }
         return new SingleFileImportProvider(new File(fileName));
     }
 
diff --git a/services/src/main/java/org/keycloak/exportimport/util/ImportUtils.java b/services/src/main/java/org/keycloak/exportimport/util/ImportUtils.java
index 2357a65..0996c9c 100755
--- a/services/src/main/java/org/keycloak/exportimport/util/ImportUtils.java
+++ b/services/src/main/java/org/keycloak/exportimport/util/ImportUtils.java
@@ -28,7 +28,6 @@ import org.keycloak.exportimport.Strategy;
 import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.RealmProvider;
-import org.keycloak.models.utils.RealmImporter;
 import org.keycloak.models.utils.RepresentationToModel;
 import org.keycloak.representations.idm.RealmRepresentation;
 import org.keycloak.representations.idm.UserRepresentation;
@@ -55,7 +54,7 @@ public class ImportUtils {
         // Import admin realm first
         for (RealmRepresentation realm : realms) {
             if (Config.getAdminRealm().equals(realm.getRealm())) {
-                if (importRealm(session, realm, strategy)) {
+                if (importRealm(session, realm, strategy, false)) {
                     masterImported = true;
                 }
             }
@@ -63,7 +62,7 @@ public class ImportUtils {
 
         for (RealmRepresentation realm : realms) {
             if (!Config.getAdminRealm().equals(realm.getRealm())) {
-                importRealm(session, realm, strategy);
+                importRealm(session, realm, strategy, false);
             }
         }
 
@@ -84,9 +83,10 @@ public class ImportUtils {
      * @param session
      * @param rep
      * @param strategy specifies whether to overwrite or ignore existing realm or user entries
+     * @param skipUserDependent If true, then import of any models, which needs users already imported in DB, will be skipped. For example authorization
      * @return newly imported realm (or existing realm if ignoreExisting is true and realm of this name already exists)
      */
-    public static boolean importRealm(KeycloakSession session, RealmRepresentation rep, Strategy strategy) {
+    public static boolean importRealm(KeycloakSession session, RealmRepresentation rep, Strategy strategy, boolean skipUserDependent) {
         String realmName = rep.getRealm();
         RealmProvider model = session.realms();
         RealmModel realm = model.getRealmByName(realmName);
@@ -110,7 +110,7 @@ public class ImportUtils {
 
         RealmManager realmManager = new RealmManager(session);
         realmManager.setContextPath(session.getContext().getContextPath());
-        realmManager.importRealm(rep);
+        realmManager.importRealm(rep, skipUserDependent);
 
         if (System.getProperty(ExportImportConfig.ACTION) != null) {
             logger.infof("Realm '%s' imported", realmName);
diff --git a/services/src/main/java/org/keycloak/services/DefaultKeycloakContext.java b/services/src/main/java/org/keycloak/services/DefaultKeycloakContext.java
index 07313d8..e1e0880 100755
--- a/services/src/main/java/org/keycloak/services/DefaultKeycloakContext.java
+++ b/services/src/main/java/org/keycloak/services/DefaultKeycloakContext.java
@@ -24,8 +24,6 @@ import org.keycloak.models.KeycloakContext;
 import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.UserModel;
-import org.keycloak.models.utils.RealmImporter;
-import org.keycloak.services.managers.RealmManager;
 import org.keycloak.services.resources.KeycloakApplication;
 import org.keycloak.services.util.LocaleHelper;
 
diff --git a/services/src/main/java/org/keycloak/services/managers/RealmManager.java b/services/src/main/java/org/keycloak/services/managers/RealmManager.java
index c647623..cb80590 100755
--- a/services/src/main/java/org/keycloak/services/managers/RealmManager.java
+++ b/services/src/main/java/org/keycloak/services/managers/RealmManager.java
@@ -37,7 +37,6 @@ import org.keycloak.models.session.UserSessionPersisterProvider;
 import org.keycloak.models.utils.DefaultAuthenticationFlows;
 import org.keycloak.models.utils.DefaultRequiredActions;
 import org.keycloak.models.utils.KeycloakModelUtils;
-import org.keycloak.models.utils.RealmImporter;
 import org.keycloak.models.utils.RepresentationToModel;
 import org.keycloak.protocol.ProtocolMapperUtils;
 import org.keycloak.protocol.oidc.OIDCLoginProtocol;
@@ -61,7 +60,7 @@ import java.util.List;
  * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
  * @version $Revision: 1 $
  */
-public class RealmManager implements RealmImporter {
+public class RealmManager {
 
     protected KeycloakSession session;
     protected RealmProvider model;
@@ -420,8 +419,15 @@ public class RealmManager implements RealmImporter {
         }
     }
 
-    @Override
     public RealmModel importRealm(RealmRepresentation rep) {
+        return importRealm(rep, false);
+    }
+
+
+    /**
+     * if "skipUserDependent" is true, then import of any models, which needs users already imported in DB, will be skipped. For example authorization
+     */
+    public RealmModel importRealm(RealmRepresentation rep, boolean skipUserDependent) {
         String id = rep.getId();
         if (id == null) {
             id = KeycloakModelUtils.generateId();
@@ -463,7 +469,7 @@ public class RealmManager implements RealmImporter {
 
         if (!hasRealmRole(rep, Constants.OFFLINE_ACCESS_ROLE)) setupOfflineTokens(realm);
 
-        RepresentationToModel.importRealm(session, rep, realm);
+        RepresentationToModel.importRealm(session, rep, realm, skipUserDependent);
 
         setupAdminConsoleLocaleMapper(realm);
 
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/exportimport/ExportImportUtil.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/exportimport/ExportImportUtil.java
index 3c296a1..f923cf4 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/exportimport/ExportImportUtil.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/exportimport/ExportImportUtil.java
@@ -627,11 +627,12 @@ public class ExportImportUtil {
         assertPredicate(scopes, scopePredicates);
 
         List<PolicyRepresentation> policies = authzResource.policies().policies();
-        Assert.assertEquals(10, policies.size());
+        Assert.assertEquals(11, policies.size());
         List<Predicate<PolicyRepresentation>> policyPredicates = new ArrayList<>();
         policyPredicates.add(policyRepresentation -> "Any Admin Policy".equals(policyRepresentation.getName()));
         policyPredicates.add(policyRepresentation -> "Any User Policy".equals(policyRepresentation.getName()));
         policyPredicates.add(policyRepresentation -> "Only Premium User Policy".equals(policyRepresentation.getName()));
+        policyPredicates.add(policyRepresentation -> "wburke policy".equals(policyRepresentation.getName()));
         policyPredicates.add(policyRepresentation -> "All Users Policy".equals(policyRepresentation.getName()));
         policyPredicates.add(policyRepresentation -> "Premium Resource Permission".equals(policyRepresentation.getName()));
         policyPredicates.add(policyRepresentation -> "Administrative Resource Permission".equals(policyRepresentation.getName()));
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
index 6cd3ef6..b540ab1 100755
--- a/testsuite/integration-arquillian/tests/base/src/test/resources/model/testrealm.json
+++ b/testsuite/integration-arquillian/tests/base/src/test/resources/model/testrealm.json
@@ -292,6 +292,15 @@
                         }
                     },
                     {
+                        "name": "wburke policy",
+                        "description": "Defines that only wburke can do something",
+                        "type": "user",
+                        "logic": "POSITIVE",
+                        "config": {
+                            "users" : "[\"wburke\"]"
+                        }
+                    },
+                    {
                         "name": "All Users Policy",
                         "description": "Defines that all users can do something",
                         "type": "aggregate",