keycloak-uncached

Merge pull request #3518 from mposolda/master KEYCLOAK-3930

11/18/2016 6:27:58 PM

Details

diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/MongoUserProvider.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/MongoUserProvider.java
index 7b46c0c..9eb3fd6 100755
--- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/MongoUserProvider.java
+++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/MongoUserProvider.java
@@ -50,6 +50,7 @@ import org.keycloak.models.mongo.keycloak.entities.MongoUserConsentEntity;
 import org.keycloak.models.mongo.keycloak.entities.MongoUserEntity;
 import org.keycloak.models.mongo.keycloak.entities.UserConsentEntity;
 import org.keycloak.models.utils.KeycloakModelUtils;
+import org.keycloak.models.utils.UserModelDelegate;
 
 import java.util.ArrayList;
 import java.util.Collections;
@@ -661,16 +662,18 @@ public class MongoUserProvider implements UserProvider, UserCredentialStore {
     }
 
     public MongoUserEntity getMongoUserEntity(UserModel user) {
-        UserAdapter adapter = null;
-        if (user instanceof CachedUserModel) {
-            adapter = (UserAdapter)((CachedUserModel)user).getDelegateForUpdate();
-        } else if (user instanceof UserAdapter ){
-            adapter = (UserAdapter)user;
+        if (user instanceof UserAdapter) {
+            UserAdapter adapter = (UserAdapter)user;
+            return adapter.getMongoEntity();
+        } else if (user instanceof CachedUserModel) {
+            UserModel delegate = ((CachedUserModel)user).getDelegateForUpdate();
+            return getMongoUserEntity(delegate);
+        } else if (user instanceof UserModelDelegate){
+            UserModel delegate = ((UserModelDelegate) user).getDelegate();
+            return getMongoUserEntity(delegate);
         } else {
             return getMongoStore().loadEntity(MongoUserEntity.class, user.getId(), invocationContext);
-
         }
-        return adapter.getMongoEntity();
     }
 
     @Override
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 bd00f9d..119c7df 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
@@ -1988,28 +1988,39 @@ public class RealmAdapter extends AbstractMongoAdapter<MongoRealmEntity> impleme
     @Override
     public void removeComponent(ComponentModel component) {
         Iterator<ComponentEntity> it = realm.getComponentEntities().iterator();
+        ComponentEntity found = null;
         while(it.hasNext()) {
-            if (it.next().getId().equals(component.getId())) {
-                session.users().preRemove(this, component);
-                removeComponents(component.getId());
-                it.remove();
+            ComponentEntity next = it.next();
+            if (next.getId().equals(component.getId())) {
+                found = next;
                 break;
             }
         }
-        updateRealm();
 
+        if (found != null) {
+            session.users().preRemove(this, component);
+            removeComponents(component.getId());
+            realm.getComponentEntities().remove(found);
+            updateRealm();
+        }
     }
 
     @Override
     public void removeComponents(String parentId) {
         Iterator<ComponentEntity> it = realm.getComponentEntities().iterator();
+        Set<ComponentEntity> toRemove = new HashSet<>();
         while(it.hasNext()) {
             ComponentEntity next = it.next();
             if (next.getParentId().equals(parentId)) {
-                session.users().preRemove(this, entityToModel(next));
-                it.remove();
+                toRemove.add(next);
             }
         }
+
+        for (ComponentEntity toRem : toRemove) {
+            session.users().preRemove(this, entityToModel(toRem));
+            realm.getComponentEntities().remove(toRem);
+        }
+
         updateRealm();
 
     }
diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/UserAdapter.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/UserAdapter.java
index 9d5ad7c..e5440cc 100755
--- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/UserAdapter.java
+++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/UserAdapter.java
@@ -261,6 +261,7 @@ public class UserAdapter extends AbstractMongoAdapter<MongoUserEntity> implement
 
     @Override
     public boolean isMemberOf(GroupModel group) {
+        if (user.getGroupIds() == null) return false;
         if (user.getGroupIds().contains(group.getId())) return true;
         Set<GroupModel> groups = getGroups();
         return RoleUtils.isMember(groups, group);
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/UserFederationProvidersResource.java b/services/src/main/java/org/keycloak/services/resources/admin/UserFederationProvidersResource.java
index 8854a7b..fa1e139 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/UserFederationProvidersResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/UserFederationProvidersResource.java
@@ -21,6 +21,7 @@ import org.jboss.resteasy.annotations.cache.NoCache;
 import org.jboss.resteasy.spi.NotFoundException;
 import org.jboss.resteasy.spi.ResteasyProviderFactory;
 import org.keycloak.common.constants.KerberosConstants;
+import org.keycloak.component.ComponentModel;
 import org.keycloak.events.admin.OperationType;
 import org.keycloak.events.admin.ResourceType;
 import org.keycloak.mappers.FederationConfigValidationException;
@@ -60,8 +61,10 @@ import javax.ws.rs.core.Response;
 import javax.ws.rs.core.UriInfo;
 import java.text.MessageFormat;
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.LinkedList;
 import java.util.List;
+import java.util.Map;
 import java.util.Properties;
 
 /**
@@ -263,6 +266,33 @@ public class UserFederationProvidersResource {
         return instanceResource;
     }
 
+    // TODO: This endpoint exists, so that admin console can lookup userFederation provider OR userStorage provider by federationLink.
+    // TODO: Endpoint should be removed once UserFederation SPI is removed as fallback is not needed anymore than
+    @GET
+    @Path("instances-with-fallback/{id}")
+    @Produces(MediaType.APPLICATION_JSON)
+    @NoCache
+    public Map<String, String> getUserFederationInstanceWithFallback(@PathParam("id") String id) {
+        this.auth.requireView();
+
+        Map<String, String> result = new HashMap<>();
+        UserFederationProviderModel model = KeycloakModelUtils.findUserFederationProviderById(id, realm);
+        if (model != null) {
+            result.put("federationLinkName", model.getDisplayName());
+            result.put("federationLink", "#/realms/" + realm.getName() + "/user-federation/providers/" + model.getProviderName() + "/" + model.getId());
+            return result;
+        } else {
+            ComponentModel userStorage = KeycloakModelUtils.findUserStorageProviderById(id, realm);
+            if (userStorage != null) {
+                result.put("federationLinkName", userStorage.getName());
+                result.put("federationLink", "#/realms/" + realm.getName() + "/user-storage/providers/" + userStorage.getProviderId() + "/" + userStorage.getId());
+                return result;
+            } else {
+                throw new NotFoundException("Could not find federation provider or userStorage provider");
+            }
+        }
+    }
+
 
     private ConfigPropertyRepresentation toConfigPropertyRepresentation(ProviderConfigProperty prop) {
         return ModelToRepresentation.toRepresentation(prop);
diff --git a/themes/src/main/resources/theme/base/admin/resources/js/controllers/users.js b/themes/src/main/resources/theme/base/admin/resources/js/controllers/users.js
index 984a717..8725539 100755
--- a/themes/src/main/resources/theme/base/admin/resources/js/controllers/users.js
+++ b/themes/src/main/resources/theme/base/admin/resources/js/controllers/users.js
@@ -337,7 +337,7 @@ module.controller('UserTabCtrl', function($scope, $location, Dialog, Notificatio
 module.controller('UserDetailCtrl', function($scope, realm, user, BruteForceUser, User,
                                              Components,
                                              UserFederationInstances, UserImpersonation, RequiredActions,
-                                             $location, Dialog, Notifications) {
+                                             $location, $http, Dialog, Notifications) {
     $scope.realm = realm;
     $scope.create = !user.id;
     $scope.editUsername = $scope.create || $scope.realm.editUsernameAllowed;
@@ -362,7 +362,16 @@ module.controller('UserDetailCtrl', function($scope, realm, user, BruteForceUser
             });
         };
         if(user.federationLink) {
-            console.log("federationLink is not null");
+            console.log("federationLink is not null. It is " + user.federationLink);
+
+            // TODO: This is temporary and should be removed once we remove userFederation SPI. It can be replaced with Components.get below
+            var fedUrl = authUrl + '/admin/realms/' + realm.realm + '/user-federation/instances-with-fallback/' + user.federationLink;
+            $http.get(fedUrl).success(function(data, status, headers, config) {
+                $scope.federationLinkName = data.federationLinkName;
+                $scope.federationLink = data.federationLink;
+            });
+
+            /*
             if (user.federationLink.startsWith('f:')) {
                  Components.get({realm: realm.realm, componentId: user.federationLink}, function (link) {
                     $scope.federationLinkName = link.name;
@@ -373,7 +382,7 @@ module.controller('UserDetailCtrl', function($scope, realm, user, BruteForceUser
                     $scope.federationLinkName = link.displayName;
                     $scope.federationLink = "#/realms/" + realm.realm + "/user-federation/providers/" + link.providerName + "/" + link.id;
                 });
-            }
+            }*/
 
         } else {
             console.log("federationLink is null");
diff --git a/themes/src/main/resources/theme/base/admin/resources/templates/kc-tabs-ldap.html b/themes/src/main/resources/theme/base/admin/resources/templates/kc-tabs-ldap.html
index 089a65f..a4f17a8 100644
--- a/themes/src/main/resources/theme/base/admin/resources/templates/kc-tabs-ldap.html
+++ b/themes/src/main/resources/theme/base/admin/resources/templates/kc-tabs-ldap.html
@@ -1,6 +1,6 @@
 <div data-ng-controller="LDAPTabCtrl">
     <h1 data-ng-hide="create">
-        {{instance.displayName|capitalize}}
+        {{instance.name|capitalize}}
         <i class="pficon pficon-delete clickable" data-ng-show="!create && access.manageUsers" data-ng-click="removeUserFederation()"></i>
     </h1>
     <h1 data-ng-show="create">{{:: 'add-user-federation-provider' | translate}}</h1>