From 0e0dfb60e06e6dee227204f56da9daba94236c7d Mon Sep 17 00:00:00 2001 From: Bill Burke Date: Wed, 14 May 2014 10:37:50 -0400 Subject: [PATCH] composite role mapping listing --- .../theme/admin/base/resources/js/app.js | 3 - .../base/resources/js/controllers/users.js | 166 +++++------------- .../theme/admin/base/resources/js/services.js | 31 ++++ .../resources/partials/role-mappings.html | 22 +++ .../resources/admin/UsersResource.java | 105 ++++++++++- .../testsuite/account/AccountTest.java | 7 + 6 files changed, 211 insertions(+), 123 deletions(-) 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 33c204803f..00fbe0e48b 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 19aecb899a..ac886e1192 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 f8515a29cd..eaa77bb295 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 09dd60d052..18dab11c74 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"> +
+ - +
+
+ + +
@@ -89,6 +100,17 @@ ng-options="r.name for r in applicationMappings"> +
+ - +
+
+ + +
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 56f5e3b7ce..1002fc2244 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 realmMappings = realm.getRealmRoleMappings(user); List realmMappingsRep = new ArrayList(); - 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 getCompositeRealmRoleMappings(@PathParam("username") String username) { + auth.requireView(); + + UserModel user = realm.getUser(username); + if (user == null) { + throw new NotFoundException("User not found"); + } + + Set roles = realm.getRoles(); + List realmMappingsRep = new ArrayList(); + 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 getAvailableRealmRoleMappings(@PathParam("username") String username) { + auth.requireView(); + + UserModel user = realm.getUser(username); + if (user == null) { + throw new NotFoundException("User not found"); + } + + Set 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 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 roles = application.getRoles(); + List mapRep = new ArrayList(); + 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 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 available = application.getRoles(); + return getAvailableRoles(user, available); + } + + protected List getAvailableRoles(UserModel user, Set available) { + Set roles = new HashSet(); + for (RoleModel roleModel : available) { + if (realm.hasRole(user, roleModel)) continue; + roles.add(roleModel); + } + + List mappings = new ArrayList(); + 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 167ca7ee19..8290d3f7ce 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");