keycloak-memoizeit

application roles

9/26/2013 6:47:43 PM

Details

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 114595c..f1befd7 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 6c00e6a..5f76681 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 57c7973..97607f4 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 3ee65ad..e8c3526 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 8bd656f..1503ac1 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 @@
                     <li class="active"><a href="#/realms/{{realm.id}}/applications/{{application.id}}">Settings</a></li>
                     <li><a href="#">Credentials</a></li>
                     <li><a href="#">Installation</a></li>
-                    <li><a href="#">Roles</a></li>
+                    <li><a href="#/realms/{{realm.id}}/applications/{{application.id}}/roles">Roles</a></li>
                     <li><a href="#">Scope</a></li>
                     <li><a href="#">Sessions</a></li>
                 </ul>
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 0000000..2e8a312
--- /dev/null
+++ b/examples/as7-eap-demo/server/src/main/webapp/saas/admin/partials/application-role-detail.html
@@ -0,0 +1,60 @@
+<div id="wrapper" class="container">
+    <div class="row">
+        <div class="bs-sidebar col-md-3 clearfix" data-ng-include data-src="'partials/realm-menu.html'"></div>
+        <div id="content-area" class="col-md-9" role="main">
+            <div class="top-nav">
+                <ul class="rcue-tabs">
+                    <li class="active"><a href="#/create/role/{{realm.id}}/applications/{{application.id}}">New {{application.name}} Role</a></li>
+                    <li><a href="#/realms/{{realm.id}}/applications/{{application.id}}/roles">{{application.name}} Roles</a></li>
+                    <li><a href="#/realms/{{realm.id}}/applications/{{application.id}}">{{application.name}} Settings</a></li>
+                </ul>
+            </div>
+            <div id="content">
+                <h2 class="pull-left" data-ng-show="create">New Application {{application.name}} Role</h2>
+                <h2 class="pull-left" data-ng-hide="create">Application {{application.name}} Role <span>{{role.name}}</span></h2>
+                <p class="subtitle" data-ng-show="create"><span class="required">*</span> Required fields</p>
+                <form name="realmForm" novalidate>
+                    <fieldset>
+                        <legend uncollapsed><span class="text">Details</span> </legend>
+                        <div class="form-group">
+                            <label for="name">Role name </label><span class="required" data-ng-show="create">*</span>
+
+                            <div class="controls">
+                                <input type="text" id="name" name="name" data-ng-model="role.name" autofocus
+                                       required data-ng-readonly="!create">
+                            </div>
+                        </div>
+                        <div class="form-group">
+                            <label for="description">Description </label>
+
+                            <div class="controls">
+                                <input type="text" id="description" name="description" data-ng-model="role.description" autofocus
+                                       required>
+                            </div>
+                        </div>
+                    </fieldset>
+                    <div class="form-actions" data-ng-show="create">
+                        <button type="submit" data-ng-click="save()" class="primary" data-ng-show="changed">Save
+                        </button>
+                        <button type="submit" data-ng-click="cancel()" data-ng-click="cancel()"
+                                data-ng-show="changed">Cancel
+                        </button>
+                    </div>
+
+                    <div class="form-actions" data-ng-show="!create">
+                        <button type="submit" data-ng-click="save()" class="primary" data-ng-show="changed">Save
+                            changes
+                        </button>
+                        <button type="submit" data-ng-click="reset()" data-ng-show="changed">Clear changes
+                        </button>
+                        <button type="submit" data-ng-click="remove()" class="danger" data-ng-hide="changed">
+                            Delete
+                        </button>
+                    </div>
+
+                </form>
+            </div>
+        </div>
+        <div id="container-right-bg"></div>
+    </div>
+</div>
\ 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 0000000..de4413d
--- /dev/null
+++ b/examples/as7-eap-demo/server/src/main/webapp/saas/admin/partials/application-role-list.html
@@ -0,0 +1,57 @@
+<div id="wrapper" class="container">
+    <div class="row">
+        <div class="bs-sidebar col-md-3 clearfix" data-ng-include data-src="'partials/realm-menu.html'"></div>
+        <div id="content-area" class="col-md-9" role="main">
+            <div class="top-nav">
+                <ul class="rcue-tabs">
+                    <li><a href="#/create/role/{{realm.id}}/applications/{{application.id}}">New {{application.name}} Role</a></li>
+                    <li class="active"><a href="#/realms/{{realm.id}}/applications/{{application.id}}/roles">{{application.name}} Roles</a></li>
+                    <li><a href="#/realms/{{realm.id}}/applications/{{application.id}}">{{application.name}} Settings</a></li>
+                </ul>
+            </div>
+            <div id="content">
+                <h2 class="pull-left">Application <span>{{application.name}}</span> Roles</h2>
+                <table>
+                    <caption data-ng-show="roles && roles.length > 0">Table of realm roles</caption>
+                    <caption data-ng-show="!roles || roles.length == 0">No configured realm roles...</caption>
+                    <thead>
+                    <tr data-ng-show="roles && roles.length > 5">
+                        <th class="rcue-table-actions" colspan="2">
+                            <div class="search-comp clearfix">
+                                <input type="text" placeholder="Search..." class="search">
+                                <button class="icon-search tooltipRightTrigger"
+                                        data-original-title="Search by role name.">
+                                    Icon: search
+                                </button>
+                            </div>
+                        </th>
+                    </tr>
+                    <tr>
+                        <th>Role Name</th>
+                        <th>Description</th>
+                    </tr>
+                    </thead>
+                    <tfoot data-ng-show="roles && roles.length > 5"> <!-- todo -->
+                    <tr>
+                        <td colspan="2">
+                            <div class="table-nav">
+                                <a href="#" class="first disabled">First page</a><a href="#" class="prev disabled">Previous
+                                page</a><span><strong>1-8</strong> of <strong>10</strong></span><a href="#"
+                                                                                                   class="next">Next
+                                page</a><a href="#" class="last">Last page</a>
+                            </div>
+                        </td>
+                    </tr>
+                    </tfoot>
+                    <tbody class="selectable-rows">
+                    <tr ng-repeat="role in roles">
+                        <td><a href="#/realms/{{realm.id}}/applications/{{application.id}}/roles/{{role.id}}">{{role.name}}</a></td>
+                        <td>{{role.description}}</td>
+                    </tr>
+                    </tbody>
+                </table>
+            </div>
+        </div>
+        <div id="container-right-bg"></div>
+    </div>
+</div>
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 f584843..2b0fb20 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 191fb24..582ebae 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 <a href="mailto:bill@burkecentral.com">Bill Burke</a>
@@ -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<RoleRepresentation> getRoles() {
+        List<RoleModel> roleModels = application.getRoles();
+        List<RoleRepresentation> roles = new ArrayList<RoleRepresentation>();
+        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 3015169..4c72238 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