From c8be9e01f8b77ddd6b2b7f050685193fa87ef459 Mon Sep 17 00:00:00 2001 From: Bill Burke Date: Thu, 26 Sep 2013 17:47:43 -0400 Subject: [PATCH] application roles --- .../src/main/webapp/saas/admin/js/app.js | 45 ++++++++++++ .../main/webapp/saas/admin/js/controllers.js | 30 ++++++-- .../src/main/webapp/saas/admin/js/loaders.js | 20 ++++++ .../src/main/webapp/saas/admin/js/services.js | 13 ++++ .../admin/partials/application-detail.html | 2 +- .../partials/application-role-detail.html | 60 ++++++++++++++++ .../admin/partials/application-role-list.html | 57 +++++++++++++++ .../services/managers/RealmManager.java | 6 +- .../resources/admin/ApplicationResource.java | 72 ++++++++++++++++--- .../resources/admin/RealmAdminResource.java | 14 ++-- 10 files changed, 294 insertions(+), 25 deletions(-) create mode 100755 examples/as7-eap-demo/server/src/main/webapp/saas/admin/partials/application-role-detail.html create mode 100755 examples/as7-eap-demo/server/src/main/webapp/saas/admin/partials/application-role-list.html diff --git a/examples/as7-eap-demo/server/src/main/webapp/saas/admin/js/app.js b/examples/as7-eap-demo/server/src/main/webapp/saas/admin/js/app.js index 114595c24c6..f1befd7ec27 100755 --- a/examples/as7-eap-demo/server/src/main/webapp/saas/admin/js/app.js +++ b/examples/as7-eap-demo/server/src/main/webapp/saas/admin/js/app.js @@ -109,6 +109,51 @@ module.config([ '$routeProvider', function($routeProvider) { controller : 'RoleListCtrl' }) + .when('/create/role/:realm/applications/:application', { + templateUrl : 'partials/application-role-detail.html', + resolve : { + realm : function(RealmLoader) { + return RealmLoader(); + }, + application : function(ApplicationLoader) { + return ApplicationLoader(); + }, + role : function() { + return {}; + } + }, + controller : 'ApplicationRoleDetailCtrl' + }).when('/realms/:realm/applications/:application/roles/:role', { + templateUrl : 'partials/application-role-detail.html', + resolve : { + realm : function(RealmLoader) { + return RealmLoader(); + }, + application : function(ApplicationLoader) { + return ApplicationLoader(); + }, + role : function(ApplicationRoleLoader) { + return ApplicationRoleLoader(); + } + }, + controller : 'ApplicationRoleDetailCtrl' + }).when('/realms/:realm/applications/:application/roles', { + templateUrl : 'partials/application-role-list.html', + resolve : { + realm : function(RealmLoader) { + return RealmLoader(); + }, + application : function(ApplicationLoader) { + return ApplicationLoader(); + }, + roles : function(ApplicationRoleListLoader) { + return ApplicationRoleListLoader(); + } + }, + controller : 'ApplicationRoleListCtrl' + }) + + .when('/create/application/:realm', { templateUrl : 'partials/application-detail.html', diff --git a/examples/as7-eap-demo/server/src/main/webapp/saas/admin/js/controllers.js b/examples/as7-eap-demo/server/src/main/webapp/saas/admin/js/controllers.js index 6c00e6a3912..5f76681c676 100755 --- a/examples/as7-eap-demo/server/src/main/webapp/saas/admin/js/controllers.js +++ b/examples/as7-eap-demo/server/src/main/webapp/saas/admin/js/controllers.js @@ -327,8 +327,23 @@ module.controller('RoleListCtrl', function($scope, $location, realm, roles) { }); }); -module.controller('RoleDetailCtrl', function($scope, realm, role, Role, $location, Dialog, Notifications) { +module.controller('ApplicationRoleListCtrl', function($scope, $location, realm, application, roles) { $scope.realm = realm; + $scope.roles = roles; + $scope.application = application; + + $scope.$watch(function() { + return $location.path(); + }, function() { + $scope.path = $location.path().substring(1).split("/"); + }); +}); + + + +module.controller('ApplicationRoleDetailCtrl', function($scope, realm, application, role, ApplicationRole, $location, Dialog, Notifications) { + $scope.realm = realm; + $scope.application = application; $scope.role = angular.copy(role); $scope.create = !role.name; @@ -348,8 +363,9 @@ module.controller('RoleDetailCtrl', function($scope, realm, role, Role, $locatio $scope.save = function() { if ($scope.create) { - Role.save({ - realm: realm.id + ApplicationRole.save({ + realm: realm.id, + application : application.id }, $scope.role, function (data, headers) { $scope.changed = false; role = angular.copy($scope.role); @@ -361,8 +377,9 @@ module.controller('RoleDetailCtrl', function($scope, realm, role, Role, $locatio }); } else { - Role.update({ + ApplicationRole.update({ realm : realm.id, + application : application.id, roleId : role.id }, $scope.role, function() { $scope.changed = false; @@ -379,16 +396,17 @@ module.controller('RoleDetailCtrl', function($scope, realm, role, Role, $locatio }; $scope.cancel = function() { - $location.url("/realms/" + realm.id + "/roles"); + $location.url("/realms/" + realm.id + "/applications/" + application.id + "/roles"); }; $scope.remove = function() { Dialog.confirmDelete($scope.role.name, 'role', function() { $scope.role.$remove({ realm : realm.id, + application : application.id, role : $scope.role.name }, function() { - $location.url("/realms/" + realm.id + "/roles"); + $location.url("/realms/" + realm.id + "/applications/" + application.id + "/roles"); Notifications.success("Deleted role"); }); }); diff --git a/examples/as7-eap-demo/server/src/main/webapp/saas/admin/js/loaders.js b/examples/as7-eap-demo/server/src/main/webapp/saas/admin/js/loaders.js index 57c7973f614..97607f4c3fd 100755 --- a/examples/as7-eap-demo/server/src/main/webapp/saas/admin/js/loaders.js +++ b/examples/as7-eap-demo/server/src/main/webapp/saas/admin/js/loaders.js @@ -77,6 +77,26 @@ module.factory('RoleListLoader', function(Loader, Role, $route, $q) { }); }); +module.factory('ApplicationRoleLoader', function(Loader, ApplicationRole, $route, $q) { + return Loader.get(ApplicationRole, function() { + return { + realm : $route.current.params.realm, + application : $route.current.params.application, + roleId : $route.current.params.role + } + }); +}); + +module.factory('ApplicationRoleListLoader', function(Loader, ApplicationRole, $route, $q) { + return Loader.query(ApplicationRole, function() { + return { + realm : $route.current.params.realm, + application : $route.current.params.application + } + }); +}); + + module.factory('ApplicationLoader', function(Loader, Application, $route, $q) { return Loader.get(Application, function() { diff --git a/examples/as7-eap-demo/server/src/main/webapp/saas/admin/js/services.js b/examples/as7-eap-demo/server/src/main/webapp/saas/admin/js/services.js index 3ee65ad5ed3..e8c352662a2 100755 --- a/examples/as7-eap-demo/server/src/main/webapp/saas/admin/js/services.js +++ b/examples/as7-eap-demo/server/src/main/webapp/saas/admin/js/services.js @@ -130,6 +130,19 @@ module.factory('Role', function($resource) { }); }); +module.factory('ApplicationRole', function($resource) { + return $resource('/auth-server/rest/saas/admin/realms/:realm/applications/:application/roles/:roleId', { + realm : '@realm', + application : "@application", + roleId : '@roleId' + }, { + update : { + method : 'PUT' + } + }); +}); + + module.factory('Application', function($resource) { return $resource('/auth-server/rest/saas/admin/realms/:realm/applications/:id', { realm : '@realm', diff --git a/examples/as7-eap-demo/server/src/main/webapp/saas/admin/partials/application-detail.html b/examples/as7-eap-demo/server/src/main/webapp/saas/admin/partials/application-detail.html index 8bd656f9ba7..1503ac136a5 100755 --- a/examples/as7-eap-demo/server/src/main/webapp/saas/admin/partials/application-detail.html +++ b/examples/as7-eap-demo/server/src/main/webapp/saas/admin/partials/application-detail.html @@ -9,7 +9,7 @@
  • Settings
  • Credentials
  • Installation
  • -
  • Roles
  • +
  • Roles
  • Scope
  • Sessions
  • diff --git a/examples/as7-eap-demo/server/src/main/webapp/saas/admin/partials/application-role-detail.html b/examples/as7-eap-demo/server/src/main/webapp/saas/admin/partials/application-role-detail.html new file mode 100755 index 00000000000..2e8a3122f1a --- /dev/null +++ b/examples/as7-eap-demo/server/src/main/webapp/saas/admin/partials/application-role-detail.html @@ -0,0 +1,60 @@ +
    +
    +
    +
    + +
    +

    New Application {{application.name}} Role

    +

    Application {{application.name}} Role {{role.name}}

    +

    * Required fields

    +
    +
    + Details +
    + * + +
    + +
    +
    +
    + + +
    + +
    +
    +
    +
    + + +
    + +
    + + + +
    + +
    +
    +
    +
    +
    +
    \ No newline at end of file diff --git a/examples/as7-eap-demo/server/src/main/webapp/saas/admin/partials/application-role-list.html b/examples/as7-eap-demo/server/src/main/webapp/saas/admin/partials/application-role-list.html new file mode 100755 index 00000000000..de4413d3219 --- /dev/null +++ b/examples/as7-eap-demo/server/src/main/webapp/saas/admin/partials/application-role-list.html @@ -0,0 +1,57 @@ +
    +
    +
    +
    + +
    +

    Application {{application.name}} Roles

    + + + + + + + + + + + + + + + + + + + + + + + +
    Table of realm rolesNo configured realm roles...
    +
    + + +
    +
    Role NameDescription
    + +
    {{role.name}}{{role.description}}
    +
    +
    +
    +
    +
    diff --git a/services/src/main/java/org/keycloak/services/managers/RealmManager.java b/services/src/main/java/org/keycloak/services/managers/RealmManager.java index f5848438d19..2b0fb20fe06 100755 --- a/services/src/main/java/org/keycloak/services/managers/RealmManager.java +++ b/services/src/main/java/org/keycloak/services/managers/RealmManager.java @@ -313,7 +313,7 @@ public class RealmManager { } } - public UserRepresentation toRepresentation(UserModel user) { + public static UserRepresentation toRepresentation(UserModel user) { UserRepresentation rep = new UserRepresentation(); rep.setUsername(user.getLoginName()); rep.setLastName(user.getLastName()); @@ -325,7 +325,7 @@ public class RealmManager { return rep; } - public RoleRepresentation toRepresentation(RoleModel role) { + public static RoleRepresentation toRepresentation(RoleModel role) { RoleRepresentation rep = new RoleRepresentation(); rep.setId(role.getId()); rep.setName(role.getName()); @@ -333,7 +333,7 @@ public class RealmManager { return rep; } - public RealmRepresentation toRepresentation(RealmModel realm) { + public static RealmRepresentation toRepresentation(RealmModel realm) { RealmRepresentation rep = new RealmRepresentation(); rep.setId(realm.getId()); rep.setRealm(realm.getName()); diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ApplicationResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ApplicationResource.java index 191fb240e60..582ebae6c51 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/ApplicationResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/ApplicationResource.java @@ -3,16 +3,18 @@ package org.keycloak.services.resources.admin; import org.jboss.resteasy.annotations.cache.NoCache; import org.jboss.resteasy.logging.Logger; import org.keycloak.representations.idm.ApplicationRepresentation; +import org.keycloak.representations.idm.RoleRepresentation; import org.keycloak.services.managers.RealmManager; import org.keycloak.services.managers.ResourceManager; -import org.keycloak.services.models.ApplicationModel; -import org.keycloak.services.models.KeycloakSession; -import org.keycloak.services.models.RealmModel; -import org.keycloak.services.models.UserModel; +import org.keycloak.services.models.*; import javax.ws.rs.*; import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.UriInfo; +import java.util.ArrayList; +import java.util.List; /** * @author Bill Burke @@ -22,7 +24,7 @@ public class ApplicationResource { protected static final Logger logger = Logger.getLogger(RealmAdminResource.class); protected UserModel admin; protected RealmModel realm; - protected ApplicationModel applicationModel; + protected ApplicationModel application; @Context protected KeycloakSession session; @@ -30,14 +32,14 @@ public class ApplicationResource { public ApplicationResource(UserModel admin, RealmModel realm, ApplicationModel applicationModel) { this.admin = admin; this.realm = realm; - this.applicationModel = applicationModel; + this.application = applicationModel; } @PUT @Consumes(MediaType.APPLICATION_JSON) public void update(final ApplicationRepresentation rep) { ResourceManager resourceManager = new ResourceManager(new RealmManager(session)); - resourceManager.updateResource(rep, applicationModel); + resourceManager.updateResource(rep, application); } @@ -46,6 +48,60 @@ public class ApplicationResource { @Produces(MediaType.APPLICATION_JSON) public ApplicationRepresentation getResource(final @PathParam("id") String id) { ResourceManager resourceManager = new ResourceManager(new RealmManager(session)); - return resourceManager.toRepresentation(applicationModel); + return resourceManager.toRepresentation(application); } + + @Path("roles") + @GET + @NoCache + @Produces("application/json") + public List getRoles() { + List roleModels = application.getRoles(); + List roles = new ArrayList(); + for (RoleModel roleModel : roleModels) { + roles.add(RealmManager.toRepresentation(roleModel)); + } + return roles; + } + + @Path("roles/{id}") + @GET + @NoCache + @Produces("application/json") + public RoleRepresentation getRole(final @PathParam("id") String id) { + RoleModel roleModel = application.getRoleById(id); + if (roleModel == null) { + throw new NotFoundException(); + } + return RealmManager.toRepresentation(roleModel); + } + + + @Path("roles/{id}") + @PUT + @Consumes("application/json") + public void updateRole(final @PathParam("id") String id, final RoleRepresentation rep) { + RoleModel role = application.getRoleById(id); + if (role == null) { + throw new NotFoundException(); + } + role.setName(rep.getName()); + role.setDescription(rep.getDescription()); + } + + @Path("roles") + @POST + @Consumes("application/json") + public Response createRole(final @Context UriInfo uriInfo, final RoleRepresentation rep) { + if (application.getRole(rep.getName()) != null) { // no duplicates + throw new InternalServerErrorException(); // todo appropriate status here. + } + RoleModel role = application.addRole(rep.getName()); + if (role == null) { + throw new NotFoundException(); + } + role.setDescription(rep.getDescription()); + return Response.created(uriInfo.getAbsolutePathBuilder().path(role.getId()).build()).build(); + } + } 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 30151691458..4c72238c13d 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 @@ -56,6 +56,13 @@ public class RealmAdminResource { } + @PUT + @Consumes("application/json") + public void updateRealm(final RealmRepresentation rep) { + logger.info("updating realm: " + rep.getRealm()); + new RealmManager(session).updateRealm(rep, realm); + } + @Path("roles") @GET @NoCache @@ -71,13 +78,6 @@ public class RealmAdminResource { return roles; } - @PUT - @Consumes("application/json") - public void updateRealm(final RealmRepresentation rep) { - logger.info("updating realm: " + rep.getRealm()); - new RealmManager(session).updateRealm(rep, realm); - } - @Path("roles/{id}") @GET @NoCache