From 0e0dfb60e06e6dee227204f56da9daba94236c7d Mon Sep 17 00:00:00 2001 From: Bill Burke Date: Wed, 14 May 2014 10:37:50 -0400 Subject: [PATCH 1/2] 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"); From 7ba8e09aef74033bb2f9d35a211f533d549ca033 Mon Sep 17 00:00:00 2001 From: Bill Burke Date: Wed, 14 May 2014 14:50:11 -0400 Subject: [PATCH 2/2] improved scope screen --- .../resources/js/controllers/applications.js | 90 ++++++++++++++++++- .../base/resources/js/controllers/users.js | 2 + .../theme/admin/base/resources/js/services.js | 30 +++++++ .../partials/application-scope-mappings.html | 22 +++++ .../resources/admin/ScopeMappedResource.java | 75 +++++++++++++++- 5 files changed, 215 insertions(+), 4 deletions(-) diff --git a/forms/common-themes/src/main/resources/theme/admin/base/resources/js/controllers/applications.js b/forms/common-themes/src/main/resources/theme/admin/base/resources/js/controllers/applications.js index 323c06788d..9f7615d9c1 100755 --- a/forms/common-themes/src/main/resources/theme/admin/base/resources/js/controllers/applications.js +++ b/forms/common-themes/src/main/resources/theme/admin/base/resources/js/controllers/applications.js @@ -329,18 +329,22 @@ module.controller('ApplicationDetailCtrl', function($scope, realm, application, }); -module.controller('ApplicationScopeMappingCtrl', function($scope, $http, realm, application, roles, applications, ApplicationRealmScopeMapping, ApplicationApplicationScopeMapping, ApplicationRole) { +module.controller('ApplicationScopeMappingCtrl', function($scope, $http, realm, application, applications, + ApplicationRealmScopeMapping, ApplicationApplicationScopeMapping, ApplicationRole, + ApplicationAvailableRealmScopeMapping, ApplicationAvailableApplicationScopeMapping, + ApplicationCompositeRealmScopeMapping, ApplicationCompositeApplicationScopeMapping) { $scope.realm = realm; $scope.application = application; - $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 = []; @@ -447,6 +451,88 @@ module.controller('ApplicationScopeMappingCtrl', function($scope, $http, realm, } }; + $scope.realmMappings = ApplicationRealmScopeMapping.query({realm : realm.realm, application : application.name}); + $scope.realmRoles = ApplicationAvailableRealmScopeMapping.query({realm : realm.realm, application : application.name}); + $scope.realmComposite = ApplicationCompositeRealmScopeMapping.query({realm : realm.realm, application : application.name}); + + $scope.addRealmRole = function() { + $http.post(authUrl + '/admin/realms/' + realm.realm + '/applications/' + application.name + '/scope-mappings/realm', + $scope.selectedRealmRoles).success(function() { + $scope.realmMappings = ApplicationRealmScopeMapping.query({realm : realm.realm, application : application.name}); + $scope.realmRoles = ApplicationAvailableRealmScopeMapping.query({realm : realm.realm, application : application.name}); + $scope.realmComposite = ApplicationCompositeRealmScopeMapping.query({realm : realm.realm, application : application.name}); + $scope.selectedRealmMappings = []; + $scope.selectRealmRoles = []; + if ($scope.targetApp) { + console.log('load available'); + $scope.applicationMappings = ApplicationApplicationScopeMapping.query({realm : realm.realm, application : application.name, targetApp : $scope.targetApp.name}); + $scope.applicationRoles = ApplicationAvailableApplicationScopeMapping.query({realm : realm.realm, application : application.name, targetApp : $scope.targetApp.name}); + $scope.applicationComposite = ApplicationCompositeApplicationScopeMapping.query({realm : realm.realm, application : application.name, targetApp : $scope.targetApp.name}); + $scope.selectedApplicationRoles = []; + $scope.selectedApplicationMappings = []; + } + }); + }; + + $scope.deleteRealmRole = function() { + $http.delete(authUrl + '/admin/realms/' + realm.realm + '/applications/' + application.name + '/scope-mappings/realm', + {data : $scope.selectedRealmMappings, headers : {"content-type" : "application/json"}}).success(function() { + $scope.realmMappings = ApplicationRealmScopeMapping.query({realm : realm.realm, application : application.name}); + $scope.realmRoles = ApplicationAvailableRealmScopeMapping.query({realm : realm.realm, application : application.name}); + $scope.realmComposite = ApplicationCompositeRealmScopeMapping.query({realm : realm.realm, application : application.name}); + $scope.selectedRealmMappings = []; + $scope.selectRealmRoles = []; + if ($scope.targetApp) { + console.log('load available'); + $scope.applicationMappings = ApplicationApplicationScopeMapping.query({realm : realm.realm, application : application.name, targetApp : $scope.targetApp.name}); + $scope.applicationRoles = ApplicationAvailableApplicationScopeMapping.query({realm : realm.realm, application : application.name, targetApp : $scope.targetApp.name}); + $scope.applicationComposite = ApplicationCompositeApplicationScopeMapping.query({realm : realm.realm, application : application.name, targetApp : $scope.targetApp.name}); + $scope.selectedApplicationRoles = []; + $scope.selectedApplicationMappings = []; + } + }); + }; + + $scope.addApplicationRole = function() { + $http.post(authUrl + '/admin/realms/' + realm.realm + '/applications/' + application.name + '/scope-mappings/applications/' + $scope.targetApp.name, + $scope.selectedApplicationRoles).success(function() { + $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 + '/applications/' + application.name + '/scope-mappings/applications/' + $scope.targetApp.name, + {data : $scope.selectedApplicationMappings, headers : {"content-type" : "application/json"}}).success(function() { + $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.targetApp) { + console.log('load available'); + $scope.applicationMappings = ApplicationApplicationScopeMapping.query({realm : realm.realm, application : application.name, targetApp : $scope.targetApp.name}); + $scope.applicationRoles = ApplicationAvailableApplicationScopeMapping.query({realm : realm.realm, application : application.name, targetApp : $scope.targetApp.name}); + $scope.applicationComposite = ApplicationCompositeApplicationScopeMapping.query({realm : realm.realm, application : application.name, targetApp : $scope.targetApp.name}); + } else { + $scope.applicationRoles = null; + $scope.applicationMappings = null; + $scope.applicationComposite = null; + } + $scope.selectedApplicationRoles = []; + $scope.selectedApplicationMappings = []; + }; + + }); 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 ac886e1192..ee05261fe5 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 @@ -88,6 +88,8 @@ module.controller('UserRoleMappingCtrl', function($scope, $http, realm, user, ap $scope.applicationMappings = ApplicationRoleMapping.query({realm : realm.realm, userId : user.username, application : $scope.application.name}); } else { $scope.applicationRoles = null; + $scope.applicationMappings = null; + $scope.applicationComposite = null; } $scope.selectedApplicationRoles = []; $scope.selectedApplicationMappings = []; 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 eaa77bb295..6d33070147 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 @@ -282,6 +282,20 @@ module.factory('ApplicationRealmScopeMapping', function($resource) { }); }); +module.factory('ApplicationAvailableRealmScopeMapping', function($resource) { + return $resource(authUrl + '/admin/realms/:realm/applications/:application/scope-mappings/realm/available', { + realm : '@realm', + application : '@application' + }); +}); + +module.factory('ApplicationCompositeRealmScopeMapping', function($resource) { + return $resource(authUrl + '/admin/realms/:realm/applications/:application/scope-mappings/realm/composite', { + realm : '@realm', + application : '@application' + }); +}); + module.factory('ApplicationApplicationScopeMapping', function($resource) { return $resource(authUrl + '/admin/realms/:realm/applications/:application/scope-mappings/applications/:targetApp', { realm : '@realm', @@ -290,6 +304,22 @@ module.factory('ApplicationApplicationScopeMapping', function($resource) { }); }); +module.factory('ApplicationAvailableApplicationScopeMapping', function($resource) { + return $resource(authUrl + '/admin/realms/:realm/applications/:application/scope-mappings/applications/:targetApp/available', { + realm : '@realm', + application : '@application', + targetApp : '@targetApp' + }); +}); + +module.factory('ApplicationCompositeApplicationScopeMapping', function($resource) { + return $resource(authUrl + '/admin/realms/:realm/applications/:application/scope-mappings/applications/:targetApp/composite', { + realm : '@realm', + application : '@application', + targetApp : '@targetApp' + }); +}); + module.factory('RealmRoles', function($resource) { diff --git a/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/application-scope-mappings.html b/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/application-scope-mappings.html index d8f3f5f554..de2e30d2db 100755 --- a/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/application-scope-mappings.html +++ b/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/application-scope-mappings.html @@ -49,6 +49,17 @@ ng-model="selectedRealmMappings" ng-options="r.name for r in realmMappings"> +
+ - +
+ +
+ +
@@ -94,6 +105,17 @@ ng-options="r.name for r in applicationMappings"> +
+ - +
+
+ + +
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ScopeMappedResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ScopeMappedResource.java index 549f1546ad..38d627635b 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/ScopeMappedResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/ScopeMappedResource.java @@ -52,7 +52,6 @@ public class ScopeMappedResource { MappingsRepresentation all = new MappingsRepresentation(); Set realmMappings = realm.getRealmScopeMappings(client); - RealmManager manager = new RealmManager(session); if (realmMappings.size() > 0) { List realmRep = new ArrayList(); for (RoleModel roleModel : realmMappings) { @@ -92,13 +91,51 @@ public class ScopeMappedResource { Set realmMappings = realm.getRealmScopeMappings(client); List realmMappingsRep = new ArrayList(); - RealmManager manager = new RealmManager(session); for (RoleModel roleModel : realmMappings) { realmMappingsRep.add(ModelToRepresentation.toRepresentation(roleModel)); } return realmMappingsRep; } + @Path("realm/available") + @GET + @Produces("application/json") + @NoCache + public List getAvailableRealmScopeMappings() { + auth.requireView(); + + Set roles = realm.getRoles(); + return getAvailable(roles); + } + + private List getAvailable(Set roles) { + List available = new ArrayList(); + for (RoleModel roleModel : roles) { + if (realm.hasScope(client, roleModel)) continue; + available.add(ModelToRepresentation.toRepresentation(roleModel)); + } + return available; + } + + @Path("realm/composite") + @GET + @Produces("application/json") + @NoCache + public List getCompositeRealmScopeMappings() { + auth.requireView(); + + Set roles = realm.getRoles(); + return getComposite(roles); + } + + private List getComposite(Set roles) { + List composite = new ArrayList(); + for (RoleModel roleModel : roles) { + if (realm.hasScope(client, roleModel)) composite.add(ModelToRepresentation.toRepresentation(roleModel)); + } + return composite; + } + @Path("realm") @POST @Consumes("application/json") @@ -160,6 +197,40 @@ public class ScopeMappedResource { return mapRep; } + @Path("applications/{app}/available") + @GET + @Produces("application/json") + @NoCache + public List getAvailableApplicationScopeMappings(@PathParam("app") String appName) { + auth.requireView(); + + ApplicationModel app = realm.getApplicationByName(appName); + + if (app == null) { + throw new NotFoundException("Role not found"); + } + + Set roles = app.getRoles(); + return getAvailable(roles); + } + + @Path("applications/{app}/composite") + @GET + @Produces("application/json") + @NoCache + public List getCompositeApplicationScopeMappings(@PathParam("app") String appName) { + auth.requireView(); + + ApplicationModel app = realm.getApplicationByName(appName); + + if (app == null) { + throw new NotFoundException("Role not found"); + } + + Set roles = app.getRoles(); + return getComposite(roles); + } + @Path("applications/{app}") @POST @Consumes("application/json")