keycloak-memoizeit

composite role mapping listing

5/14/2014 11:37:50 AM

Details

diff --git a/forms/common-themes/src/main/resources/theme/admin/base/resources/js/app.js b/forms/common-themes/src/main/resources/theme/admin/base/resources/js/app.js
index 33c2048..00fbe0e 100755
--- a/forms/common-themes/src/main/resources/theme/admin/base/resources/js/app.js
+++ b/forms/common-themes/src/main/resources/theme/admin/base/resources/js/app.js
@@ -277,9 +277,6 @@ module.config([ '$routeProvider', function($routeProvider) {
                 },
                 applications : function(ApplicationListLoader) {
                     return ApplicationListLoader();
-                },
-                roles : function(RoleListLoader) {
-                    return RoleListLoader();
                 }
             },
             controller : 'UserRoleMappingCtrl'
diff --git a/forms/common-themes/src/main/resources/theme/admin/base/resources/js/controllers/users.js b/forms/common-themes/src/main/resources/theme/admin/base/resources/js/controllers/users.js
index 19aecb8..ac886e1 100755
--- a/forms/common-themes/src/main/resources/theme/admin/base/resources/js/controllers/users.js
+++ b/forms/common-themes/src/main/resources/theme/admin/base/resources/js/controllers/users.js
@@ -1,117 +1,96 @@
-module.controller('UserRoleMappingCtrl', function($scope, $http, realm, user, roles, applications, RealmRoleMapping, ApplicationRoleMapping, ApplicationRole) {
+module.controller('UserRoleMappingCtrl', function($scope, $http, realm, user, applications, RealmRoleMapping,
+                                                  ApplicationRoleMapping, AvailableRealmRoleMapping, AvailableApplicationRoleMapping,
+                                                  CompositeRealmRoleMapping, CompositeApplicationRoleMapping) {
     $scope.realm = realm;
     $scope.user = user;
-    $scope.realmRoles = angular.copy(roles);
     $scope.selectedRealmRoles = [];
     $scope.selectedRealmMappings = [];
     $scope.realmMappings = [];
     $scope.applications = applications;
     $scope.applicationRoles = [];
+    $scope.applicationComposite = [];
     $scope.selectedApplicationRoles = [];
     $scope.selectedApplicationMappings = [];
     $scope.applicationMappings = [];
+    $scope.dummymodel = [];
 
-    $scope.realmMappings = RealmRoleMapping.query({realm : realm.realm, userId : user.username}, function(){
-        for (var i = 0; i < $scope.realmMappings.length; i++) {
-            var role = $scope.realmMappings[i];
-            for (var j = 0; j < $scope.realmRoles.length; j++) {
-                var realmRole = $scope.realmRoles[j];
-                if (realmRole.id == role.id) {
-                    var idx = $scope.realmRoles.indexOf(realmRole);
-                    if (idx != -1) {
-                        $scope.realmRoles.splice(idx, 1);
-                        break;
-                    }
-                }
-            }
-        }
-    });
+    $scope.realmMappings = RealmRoleMapping.query({realm : realm.realm, userId : user.username});
+    $scope.realmRoles = AvailableRealmRoleMapping.query({realm : realm.realm, userId : user.username});
+    $scope.realmComposite = CompositeRealmRoleMapping.query({realm : realm.realm, userId : user.username});
 
     $scope.addRealmRole = function() {
         $http.post(authUrl + '/admin/realms/' + realm.realm + '/users/' + user.username + '/role-mappings/realm',
                 $scope.selectedRealmRoles).success(function() {
-                for (var i = 0; i < $scope.selectedRealmRoles.length; i++) {
-                    var role = $scope.selectedRealmRoles[i];
-                    var idx = $scope.realmRoles.indexOf($scope.selectedRealmRoles[i]);
-                    if (idx != -1) {
-                        $scope.realmRoles.splice(idx, 1);
-                        $scope.realmMappings.push(role);
-                    }
-                }
+                $scope.realmMappings = RealmRoleMapping.query({realm : realm.realm, userId : user.username});
+                $scope.realmRoles = AvailableRealmRoleMapping.query({realm : realm.realm, userId : user.username});
+                $scope.realmComposite = CompositeRealmRoleMapping.query({realm : realm.realm, userId : user.username});
+                $scope.selectedRealmMappings = [];
                 $scope.selectRealmRoles = [];
+                if ($scope.application) {
+                    console.log('load available');
+                    $scope.applicationComposite = CompositeApplicationRoleMapping.query({realm : realm.realm, userId : user.username, application : $scope.application.name});
+                    $scope.applicationRoles = AvailableApplicationRoleMapping.query({realm : realm.realm, userId : user.username, application : $scope.application.name});
+                    $scope.applicationMappings = ApplicationRoleMapping.query({realm : realm.realm, userId : user.username, application : $scope.application.name});
+                    $scope.selectedApplicationRoles = [];
+                    $scope.selectedApplicationMappings = [];
+                }
             });
     };
 
     $scope.deleteRealmRole = function() {
         $http.delete(authUrl + '/admin/realms/' + realm.realm + '/users/' + user.username + '/role-mappings/realm',
             {data : $scope.selectedRealmMappings, headers : {"content-type" : "application/json"}}).success(function() {
-                for (var i = 0; i < $scope.selectedRealmMappings.length; i++) {
-                    var role = $scope.selectedRealmMappings[i];
-                    var idx = $scope.realmMappings.indexOf($scope.selectedRealmMappings[i]);
-                    if (idx != -1) {
-                        $scope.realmMappings.splice(idx, 1);
-                        $scope.realmRoles.push(role);
-                    }
-                }
+                $scope.realmMappings = RealmRoleMapping.query({realm : realm.realm, userId : user.username});
+                $scope.realmRoles = AvailableRealmRoleMapping.query({realm : realm.realm, userId : user.username});
+                $scope.realmComposite = CompositeRealmRoleMapping.query({realm : realm.realm, userId : user.username});
                 $scope.selectedRealmMappings = [];
+                $scope.selectRealmRoles = [];
+                if ($scope.application) {
+                    console.log('load available');
+                    $scope.applicationComposite = CompositeApplicationRoleMapping.query({realm : realm.realm, userId : user.username, application : $scope.application.name});
+                    $scope.applicationRoles = AvailableApplicationRoleMapping.query({realm : realm.realm, userId : user.username, application : $scope.application.name});
+                    $scope.applicationMappings = ApplicationRoleMapping.query({realm : realm.realm, userId : user.username, application : $scope.application.name});
+                    $scope.selectedApplicationRoles = [];
+                    $scope.selectedApplicationMappings = [];
+                }
             });
     };
 
     $scope.addApplicationRole = function() {
         $http.post(authUrl + '/admin/realms/' + realm.realm + '/users/' + user.username + '/role-mappings/applications/' + $scope.application.name,
                 $scope.selectedApplicationRoles).success(function() {
-                for (var i = 0; i < $scope.selectedApplicationRoles.length; i++) {
-                    var role = $scope.selectedApplicationRoles[i];
-                    var idx = $scope.applicationRoles.indexOf($scope.selectedApplicationRoles[i]);
-                    if (idx != -1) {
-                        $scope.applicationRoles.splice(idx, 1);
-                        $scope.applicationMappings.push(role);
-                    }
-                }
+                $scope.applicationMappings = ApplicationRoleMapping.query({realm : realm.realm, userId : user.username, application : $scope.application.name});
+                $scope.applicationRoles = AvailableApplicationRoleMapping.query({realm : realm.realm, userId : user.username, application : $scope.application.name});
+                $scope.applicationComposite = CompositeApplicationRoleMapping.query({realm : realm.realm, userId : user.username, application : $scope.application.name});
                 $scope.selectedApplicationRoles = [];
+                $scope.selectedApplicationMappings = [];
             });
     };
 
     $scope.deleteApplicationRole = function() {
         $http.delete(authUrl + '/admin/realms/' + realm.realm + '/users/' + user.username + '/role-mappings/applications/' + $scope.application.name,
             {data : $scope.selectedApplicationMappings, headers : {"content-type" : "application/json"}}).success(function() {
-                for (var i = 0; i < $scope.selectedApplicationMappings.length; i++) {
-                    var role = $scope.selectedApplicationMappings[i];
-                    var idx = $scope.applicationMappings.indexOf($scope.selectedApplicationMappings[i]);
-                    if (idx != -1) {
-                        $scope.applicationMappings.splice(idx, 1);
-                        $scope.applicationRoles.push(role);
-                    }
-                }
+                $scope.applicationMappings = ApplicationRoleMapping.query({realm : realm.realm, userId : user.username, application : $scope.application.name});
+                $scope.applicationRoles = AvailableApplicationRoleMapping.query({realm : realm.realm, userId : user.username, application : $scope.application.name});
+                $scope.applicationComposite = CompositeApplicationRoleMapping.query({realm : realm.realm, userId : user.username, application : $scope.application.name});
+                $scope.selectedApplicationRoles = [];
                 $scope.selectedApplicationMappings = [];
             });
     };
 
 
     $scope.changeApplication = function() {
+        console.log('changeApplication');
         if ($scope.application) {
-            $scope.applicationRoles = ApplicationRole.query({realm : realm.realm, userId : user.username, application : $scope.application.name}, function() {
-                    $scope.applicationMappings = ApplicationRoleMapping.query({realm : realm.realm, userId : user.username, application : $scope.application.name}, function(){
-                        for (var i = 0; i < $scope.applicationMappings.length; i++) {
-                            var role = $scope.applicationMappings[i];
-                            for (var j = 0; j < $scope.applicationRoles.length; j++) {
-                                var realmRole = $scope.applicationRoles[j];
-                                if (realmRole.id == role.id) {
-                                    var idx = $scope.applicationRoles.indexOf(realmRole);
-                                    if (idx != -1) {
-                                        $scope.applicationRoles.splice(idx, 1);
-                                        break;
-                                    }
-                                }
-                            }
-                        }
-                    });
-
-                }
-            );
+            console.log('load available');
+            $scope.applicationComposite = CompositeApplicationRoleMapping.query({realm : realm.realm, userId : user.username, application : $scope.application.name});
+            $scope.applicationRoles = AvailableApplicationRoleMapping.query({realm : realm.realm, userId : user.username, application : $scope.application.name});
+            $scope.applicationMappings = ApplicationRoleMapping.query({realm : realm.realm, userId : user.username, application : $scope.application.name});
         } else {
             $scope.applicationRoles = null;
         }
+        $scope.selectedApplicationRoles = [];
+        $scope.selectedApplicationMappings = [];
     };
 
 
@@ -329,54 +308,3 @@ module.controller('UserCredentialsCtrl', function($scope, realm, user, User, Use
         $scope.userChange = false;
     };
 });
-
-module.controller('RoleMappingCtrl', function($scope, realm, User, users, role, RoleMapping, Notifications) {
-    $scope.realm = realm;
-    $scope.realmId = realm.realm || realm.realm;
-    $scope.allUsers = User.query({ realm : $scope.realmId });
-    $scope.users = users;
-    $scope.role = role;
-
-    $scope.addUser = function() {
-        var user = $scope.newUser;
-        $scope.newUser = null;
-
-        for ( var i = 0; i < $scope.allUsers.length; i++) {
-            if ($scope.allUsers[i].userId == user) {
-                user = $scope.allUsers[i];
-                RoleMapping.save({
-                    realm : $scope.realmId,
-                    role : role
-                }, user, function() {
-                    $scope.users = RoleMapping.query({
-                        realm : $scope.realmId,
-                        role : role
-                    });
-                    Notifications.success("The role mapping has been added for the user.");
-                });
-            }
-        }
-    }
-
-    $scope.removeUser = function(userId) {
-        for (var i = 0; i < $scope.users.length; i++) {
-            var user = $scope.users[i];
-            if ($scope.users[i].userId == userId) {
-                RoleMapping.delete({
-                    realm : $scope.realmId,
-                    role : role
-                }, user, function() {
-                    $scope.users = RoleMapping.query({
-                        realm : $scope.realmId,
-                        role : role
-                    });
-
-                    Notifications.success("The role mapping has been removed for the user.");
-                });
-            }
-        }
-    }
-});
-
-
-
diff --git a/forms/common-themes/src/main/resources/theme/admin/base/resources/js/services.js b/forms/common-themes/src/main/resources/theme/admin/base/resources/js/services.js
index f8515a2..eaa77bb 100755
--- a/forms/common-themes/src/main/resources/theme/admin/base/resources/js/services.js
+++ b/forms/common-themes/src/main/resources/theme/admin/base/resources/js/services.js
@@ -236,6 +236,21 @@ module.factory('RealmRoleMapping', function($resource) {
     });
 });
 
+module.factory('CompositeRealmRoleMapping', function($resource) {
+    return $resource(authUrl + '/admin/realms/:realm/users/:userId/role-mappings/realm/composite', {
+        realm : '@realm',
+        userId : '@userId'
+    });
+});
+
+module.factory('AvailableRealmRoleMapping', function($resource) {
+    return $resource(authUrl + '/admin/realms/:realm/users/:userId/role-mappings/realm/available', {
+        realm : '@realm',
+        userId : '@userId'
+    });
+});
+
+
 module.factory('ApplicationRoleMapping', function($resource) {
     return $resource(authUrl + '/admin/realms/:realm/users/:userId/role-mappings/applications/:application', {
         realm : '@realm',
@@ -244,6 +259,22 @@ module.factory('ApplicationRoleMapping', function($resource) {
     });
 });
 
+module.factory('AvailableApplicationRoleMapping', function($resource) {
+    return $resource(authUrl + '/admin/realms/:realm/users/:userId/role-mappings/applications/:application/available', {
+        realm : '@realm',
+        userId : '@userId',
+        application : "@application"
+    });
+});
+
+module.factory('CompositeApplicationRoleMapping', function($resource) {
+    return $resource(authUrl + '/admin/realms/:realm/users/:userId/role-mappings/applications/:application/composite', {
+        realm : '@realm',
+        userId : '@userId',
+        application : "@application"
+    });
+});
+
 module.factory('ApplicationRealmScopeMapping', function($resource) {
     return $resource(authUrl + '/admin/realms/:realm/applications/:application/scope-mappings/realm', {
         realm : '@realm',
diff --git a/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/role-mappings.html b/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/role-mappings.html
index 09dd60d..18dab11 100755
--- a/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/role-mappings.html
+++ b/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/role-mappings.html
@@ -45,6 +45,17 @@
                                     ng-options="r.name for r in realmMappings">
                             </select>
                         </div>
+                        <div class="middle-buttons">
+                            -
+                        </div>
+                        <div class="select-title">
+                            <label class="control-label" for="realm-composite">Composite Role Mappings</label>
+                            <select id="realm-composite" class="form-control" multiple size=5
+                                    ng-disabled="true"
+                                    ng-model="dummymodel"
+                                    ng-options="r.name for r in realmComposite">
+                            </select>
+                        </div>
                     </div>
                 </div>
             </fieldset>
@@ -89,6 +100,17 @@
                                     ng-options="r.name for r in applicationMappings">
                             </select>
                         </div>
+                        <div class="middle-buttons">
+                            -
+                        </div>
+                        <div class="select-title">
+                            <label class="control-label" for="app-composite">Composite Role Mappings</label>
+                            <select id="app-composite" class="form-control" multiple size=5
+                                    ng-disabled="true"
+                                    ng-model="dummymodel"
+                                    ng-options="r.name for r in applicationComposite">
+                            </select>
+                        </div>
                     </div>
                 </div>
             </fieldset>
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/UsersResource.java b/services/src/main/java/org/keycloak/services/resources/admin/UsersResource.java
index 56f5e3b..1002fc2 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/UsersResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/UsersResource.java
@@ -325,13 +325,50 @@ public class UsersResource {
 
         Set<RoleModel> realmMappings = realm.getRealmRoleMappings(user);
         List<RoleRepresentation> realmMappingsRep = new ArrayList<RoleRepresentation>();
-        RealmManager manager = new RealmManager(session);
         for (RoleModel roleModel : realmMappings) {
             realmMappingsRep.add(ModelToRepresentation.toRepresentation(roleModel));
         }
         return realmMappingsRep;
     }
 
+    @Path("{username}/role-mappings/realm/composite")
+    @GET
+    @Produces("application/json")
+    @NoCache
+    public List<RoleRepresentation> getCompositeRealmRoleMappings(@PathParam("username") String username) {
+        auth.requireView();
+
+        UserModel user = realm.getUser(username);
+        if (user == null) {
+            throw new NotFoundException("User not found");
+        }
+
+        Set<RoleModel> roles = realm.getRoles();
+        List<RoleRepresentation> realmMappingsRep = new ArrayList<RoleRepresentation>();
+        for (RoleModel roleModel : roles) {
+            if (realm.hasRole(user, roleModel)) {
+               realmMappingsRep.add(ModelToRepresentation.toRepresentation(roleModel));
+            }
+        }
+        return realmMappingsRep;
+    }
+
+    @Path("{username}/role-mappings/realm/available")
+    @GET
+    @Produces("application/json")
+    @NoCache
+    public List<RoleRepresentation> getAvailableRealmRoleMappings(@PathParam("username") String username) {
+        auth.requireView();
+
+        UserModel user = realm.getUser(username);
+        if (user == null) {
+            throw new NotFoundException("User not found");
+        }
+
+        Set<RoleModel> available = realm.getRoles();
+        return getAvailableRoles(user, available);
+    }
+
     @Path("{username}/role-mappings/realm")
     @POST
     @Consumes("application/json")
@@ -413,6 +450,72 @@ public class UsersResource {
         return mapRep;
     }
 
+    @Path("{username}/role-mappings/applications/{app}/composite")
+    @GET
+    @Produces("application/json")
+    @NoCache
+    public List<RoleRepresentation> getCompositeApplicationRoleMappings(@PathParam("username") String username, @PathParam("app") String appName) {
+        auth.requireView();
+
+        logger.debug("getCompositeApplicationRoleMappings");
+
+        UserModel user = realm.getUser(username);
+        if (user == null) {
+            throw new NotFoundException("User not found");
+        }
+
+        ApplicationModel application = realm.getApplicationByName(appName);
+
+        if (application == null) {
+            throw new NotFoundException("Application not found");
+        }
+
+        Set<RoleModel> roles = application.getRoles();
+        List<RoleRepresentation> mapRep = new ArrayList<RoleRepresentation>();
+        for (RoleModel roleModel : roles) {
+            if (realm.hasRole(user, roleModel)) mapRep.add(ModelToRepresentation.toRepresentation(roleModel));
+        }
+        logger.debugv("getCompositeApplicationRoleMappings.size() = {0}", mapRep.size());
+        return mapRep;
+    }
+
+    @Path("{username}/role-mappings/applications/{app}/available")
+    @GET
+    @Produces("application/json")
+    @NoCache
+    public List<RoleRepresentation> getAvailableApplicationRoleMappings(@PathParam("username") String username, @PathParam("app") String appName) {
+        auth.requireView();
+
+        logger.debug("getApplicationRoleMappings");
+
+        UserModel user = realm.getUser(username);
+        if (user == null) {
+            throw new NotFoundException("User not found");
+        }
+
+        ApplicationModel application = realm.getApplicationByName(appName);
+
+        if (application == null) {
+            throw new NotFoundException("Application not found");
+        }
+        Set<RoleModel> available = application.getRoles();
+        return getAvailableRoles(user, available);
+    }
+
+    protected List<RoleRepresentation> getAvailableRoles(UserModel user, Set<RoleModel> available) {
+        Set<RoleModel> roles = new HashSet<RoleModel>();
+        for (RoleModel roleModel : available) {
+            if (realm.hasRole(user, roleModel)) continue;
+            roles.add(roleModel);
+        }
+
+        List<RoleRepresentation> mappings = new ArrayList<RoleRepresentation>();
+        for (RoleModel roleModel : roles) {
+            mappings.add(ModelToRepresentation.toRepresentation(roleModel));
+        }
+        return mappings;
+    }
+
     @Path("{username}/role-mappings/applications/{app}")
     @POST
     @Consumes("application/json")
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/account/AccountTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/account/AccountTest.java
index 167ca7e..8290d3f 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/account/AccountTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/account/AccountTest.java
@@ -161,6 +161,13 @@ public class AccountTest {
         });
     }
 
+    /*
+    @Test
+    public void forever() throws Exception{
+        while (true) Thread.sleep(5000);
+    }
+    */
+
     @Test
     public void returnToAppFromQueryParam() {
         driver.navigate().to(AccountUpdateProfilePage.PATH + "?referrer=test-app");