keycloak-uncached

Merge pull request #1349 from mposolda/master KEYCLOAK-1416

6/9/2015 6:39:49 PM

Details

diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java b/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java
index 7db1b47..8cd0678 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java
@@ -804,18 +804,23 @@ public class RealmAdapter implements RealmModel {
             if (entity.getId().equals(provider.getId())) {
 
                 session.users().preRemove(this, provider);
+                removeFederationMappersForProvider(provider.getId());
 
-                Set<UserFederationMapperEntity> mappers = getUserFederationMapperEntitiesByFederationProvider(provider.getId());
-                for (UserFederationMapperEntity mapper : mappers) {
-                    realm.getUserFederationMappers().remove(mapper);
-                    em.remove(mapper);
-                }
                 it.remove();
                 em.remove(entity);
                 return;
             }
         }
     }
+
+    private void removeFederationMappersForProvider(String federationProviderId) {
+        Set<UserFederationMapperEntity> mappers = getUserFederationMapperEntitiesByFederationProvider(federationProviderId);
+        for (UserFederationMapperEntity mapper : mappers) {
+            realm.getUserFederationMappers().remove(mapper);
+            em.remove(mapper);
+        }
+    }
+
     @Override
     public void updateUserFederationProvider(UserFederationProviderModel model) {
         KeycloakModelUtils.ensureUniqueDisplayName(model.getDisplayName(), model, getUserFederationProviders());
@@ -855,10 +860,9 @@ public class RealmAdapter implements RealmModel {
                     entity.setConfig(model.getConfig());
                     entity.setPriority(model.getPriority());
                     entity.setProviderName(model.getProviderName());
-                    entity.setPriority(model.getPriority());
                     String displayName = model.getDisplayName();
                     if (displayName != null) {
-                        entity.setDisplayName(model.getDisplayName());
+                        entity.setDisplayName(displayName);
                     }
                     entity.setFullSyncPeriod(model.getFullSyncPeriod());
                     entity.setChangedSyncPeriod(model.getChangedSyncPeriod());
@@ -871,6 +875,8 @@ public class RealmAdapter implements RealmModel {
             if (found) continue;
             session.users().preRemove(this, new UserFederationProviderModel(entity.getId(), entity.getProviderName(), entity.getConfig(), entity.getPriority(), entity.getDisplayName(),
                     entity.getFullSyncPeriod(), entity.getChangedSyncPeriod(), entity.getLastSync()));
+            removeFederationMappersForProvider(entity.getId());
+
             it.remove();
             em.remove(entity);
         }
diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RealmAdapter.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RealmAdapter.java
index aa25be7..2b8c397 100755
--- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RealmAdapter.java
+++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RealmAdapter.java
@@ -877,11 +877,7 @@ public class RealmAdapter extends AbstractMongoAdapter<MongoRealmEntity> impleme
             if (entity.getId().equals(provider.getId())) {
                 session.users().preRemove(this, new UserFederationProviderModel(entity.getId(), entity.getProviderName(), entity.getConfig(), entity.getPriority(), entity.getDisplayName(),
                         entity.getFullSyncPeriod(), entity.getChangedSyncPeriod(), entity.getLastSync()));
-
-                Set<UserFederationMapperEntity> mappers = getUserFederationMapperEntitiesByFederationProvider(provider.getId());
-                for (UserFederationMapperEntity mapper : mappers) {
-                    getMongoEntity().getUserFederationMappers().remove(mapper);
-                }
+                removeFederationMappersForProvider(provider.getId());
 
                 it.remove();
             }
@@ -889,6 +885,13 @@ public class RealmAdapter extends AbstractMongoAdapter<MongoRealmEntity> impleme
         updateRealm();
     }
 
+    private void removeFederationMappersForProvider(String federationProviderId) {
+        Set<UserFederationMapperEntity> mappers = getUserFederationMapperEntitiesByFederationProvider(federationProviderId);
+        for (UserFederationMapperEntity mapper : mappers) {
+            getMongoEntity().getUserFederationMappers().remove(mapper);
+        }
+    }
+
     @Override
     public void updateUserFederationProvider(UserFederationProviderModel model) {
         KeycloakModelUtils.ensureUniqueDisplayName(model.getDisplayName(), model, getUserFederationProviders());
@@ -943,8 +946,52 @@ public class RealmAdapter extends AbstractMongoAdapter<MongoRealmEntity> impleme
             KeycloakModelUtils.ensureUniqueDisplayName(currentProvider.getDisplayName(), currentProvider, providers);
         }
 
-        List<UserFederationProviderEntity> entities = new LinkedList<UserFederationProviderEntity>();
+        List<UserFederationProviderEntity> existingProviders = realm.getUserFederationProviders();
+        List<UserFederationProviderEntity> toRemove = new LinkedList<>();
+        for (UserFederationProviderEntity entity : existingProviders) {
+            boolean found = false;
+            for (UserFederationProviderModel model : providers) {
+                if (entity.getId().equals(model.getId())) {
+                    entity.setConfig(model.getConfig());
+                    entity.setPriority(model.getPriority());
+                    entity.setProviderName(model.getProviderName());
+                    String displayName = model.getDisplayName();
+                    if (displayName != null) {
+                        entity.setDisplayName(displayName);
+                    }
+                    entity.setFullSyncPeriod(model.getFullSyncPeriod());
+                    entity.setChangedSyncPeriod(model.getChangedSyncPeriod());
+                    entity.setLastSync(model.getLastSync());
+                    found = true;
+                    break;
+                }
+
+            }
+            if (found) continue;
+            session.users().preRemove(this, new UserFederationProviderModel(entity.getId(), entity.getProviderName(), entity.getConfig(), entity.getPriority(), entity.getDisplayName(),
+                    entity.getFullSyncPeriod(), entity.getChangedSyncPeriod(), entity.getLastSync()));
+            removeFederationMappersForProvider(entity.getId());
+
+            toRemove.add(entity);
+        }
+
+        for (UserFederationProviderEntity entity : toRemove) {
+            realm.getUserFederationProviders().remove(entity);
+        }
+
+        List<UserFederationProviderModel> add = new LinkedList<UserFederationProviderModel>();
         for (UserFederationProviderModel model : providers) {
+            boolean found = false;
+            for (UserFederationProviderEntity entity : realm.getUserFederationProviders()) {
+                if (entity.getId().equals(model.getId())) {
+                    found = true;
+                    break;
+                }
+            }
+            if (!found) add.add(model);
+        }
+
+        for (UserFederationProviderModel model : add) {
             UserFederationProviderEntity entity = new UserFederationProviderEntity();
             if (model.getId() != null) {
                 entity.setId(model.getId());
@@ -964,12 +1011,11 @@ public class RealmAdapter extends AbstractMongoAdapter<MongoRealmEntity> impleme
             entity.setFullSyncPeriod(model.getFullSyncPeriod());
             entity.setChangedSyncPeriod(model.getChangedSyncPeriod());
             entity.setLastSync(model.getLastSync());
-            entities.add(entity);
+            realm.getUserFederationProviders().add(entity);
 
             session.getKeycloakSessionFactory().publish(new UserFederationProviderCreationEventImpl(this, model));
         }
 
-        realm.setUserFederationProviders(entities);
         updateRealm();
     }
 
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/RealmAdminResource.java b/services/src/main/java/org/keycloak/services/resources/admin/RealmAdminResource.java
index b27ce49..c94fa6e 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/RealmAdminResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/RealmAdminResource.java
@@ -193,8 +193,9 @@ public class RealmAdminResource {
         } catch (PatternSyntaxException e) {
             return ErrorResponse.error("Specified regex pattern(s) is invalid.", Response.Status.BAD_REQUEST);
         } catch (ModelDuplicateException e) {
-            return ErrorResponse.exists("Realm " + rep.getRealm() + " already exists.");
-        }  catch (Exception e) {
+            throw e;
+        } catch (Exception e) {
+            logger.error(e);
             return ErrorResponse.error("Failed to update " + rep.getRealm() + " Realm.", Response.Status.INTERNAL_SERVER_ERROR);
         }
     }
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/model/UserFederationModelTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/model/UserFederationModelTest.java
index 51fc446..17e0e31 100644
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/model/UserFederationModelTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/model/UserFederationModelTest.java
@@ -1,5 +1,9 @@
 package org.keycloak.testsuite.model;
 
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.TreeMap;
@@ -97,6 +101,43 @@ public class UserFederationModelTest extends AbstractModelTest {
         commit();
     }
 
+    @Test
+    public void federationProvidersSetTest() {
+        RealmModel realm = realmManager.createRealm("test-realm");
+        UserFederationProviderModel ldapProvider = new UserFederationProviderModel(null, "ldap", new TreeMap<String, String>(), 1, "my-cool-provider", -1, -1, 0);
+        realm.setUserFederationProviders(Arrays.asList(ldapProvider));
+
+        commit();
+
+        realm = realmManager.getRealmByName("test-realm");
+        List<UserFederationProviderModel> fedProviders = realm.getUserFederationProviders();
+        Assert.assertEquals(1, fedProviders.size());
+        ldapProvider = fedProviders.get(0);
+        Set<UserFederationMapperModel> fedMappers = realmManager.getRealmByName("test-realm").getUserFederationMappersByFederationProvider(ldapProvider.getId());
+
+        UserFederationProviderModel dummyProvider = new UserFederationProviderModel(null, "dummy", new TreeMap<String, String>(), 1, "my-cool-provider", -1, -1, 0);
+        try {
+            realm.setUserFederationProviders(Arrays.asList(ldapProvider, dummyProvider));
+            commit();
+            Assert.fail("Don't expect to end here");
+        } catch (ModelDuplicateException expected) {
+        }
+
+        dummyProvider.setDisplayName("my-cool-provider2");
+        realm.setUserFederationProviders(Arrays.asList(ldapProvider, dummyProvider));
+
+        commit();
+
+        realm = realmManager.getRealmByName("test-realm");
+        Assert.assertEquals(fedMappers.size(), realm.getUserFederationMappersByFederationProvider(ldapProvider.getId()).size());
+        realm.setUserFederationProviders(new ArrayList<UserFederationProviderModel>());
+
+        commit();
+
+        realm = realmManager.getRealmByName("test-realm");
+        Assert.assertTrue(realm.getUserFederationMappersByFederationProvider(ldapProvider.getId()).isEmpty());
+    }
+
     private UserFederationMapperModel createMapper(String name, String fedProviderId, String... config) {
         UserFederationMapperModel mapperModel = new UserFederationMapperModel();
         mapperModel.setName(name);