Author: ivol37 at gmail.com
Date: Fri Nov 12 10:26:20 2010
New Revision: 417

Log:
Added authorization checks to all REST methods for CRUD operations on users and 
groups.
The REST service returns a 401 when the user invoking the service is not logged 
in with role "Administrators"

Modified:
   
branches/197-secure/platform-bundles/useradmin-cassandra-store/src/main/java/org/amdatu/platform/useradmin/store/cassandra/rest/GroupsResource.java
   
branches/197-secure/platform-bundles/useradmin-cassandra-store/src/main/java/org/amdatu/platform/useradmin/store/cassandra/rest/UsersResource.java

Modified: 
branches/197-secure/platform-bundles/useradmin-cassandra-store/src/main/java/org/amdatu/platform/useradmin/store/cassandra/rest/GroupsResource.java
==============================================================================
--- 
branches/197-secure/platform-bundles/useradmin-cassandra-store/src/main/java/org/amdatu/platform/useradmin/store/cassandra/rest/GroupsResource.java
 (original)
+++ 
branches/197-secure/platform-bundles/useradmin-cassandra-store/src/main/java/org/amdatu/platform/useradmin/store/cassandra/rest/GroupsResource.java
 Fri Nov 12 10:26:20 2010
@@ -16,6 +16,7 @@
  */
 package org.amdatu.platform.useradmin.store.cassandra.rest;
 
+import javax.servlet.http.HttpServletRequest;
 import javax.ws.rs.DELETE;
 import javax.ws.rs.DefaultValue;
 import javax.ws.rs.GET;
@@ -24,10 +25,13 @@
 import javax.ws.rs.PathParam;
 import javax.ws.rs.Produces;
 import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.Context;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
 
+import org.amdatu.platform.httpcontext.BasicHttpSession;
 import org.amdatu.platform.useradmin.store.cassandra.DummyResourceInterface;
+import org.osgi.service.useradmin.Authorization;
 import org.osgi.service.useradmin.Group;
 import org.osgi.service.useradmin.Role;
 
@@ -46,6 +50,8 @@
  */
 @Path("groups")
 public class GroupsResource extends ResourceBase implements 
DummyResourceInterface {
+       static final String DEFAULT_ADMIN_GROUP = "Administrators";
+       
     /**
      * Returns all groups that match the specified filter options. This method 
can be invoked by making the following
      * REST call:<code><pre>
@@ -81,7 +87,10 @@
     public Response getGroups(@QueryParam("filter") final String filter,
             @QueryParam("sortOrder") final String sortOrder,
             @DefaultValue("1") @QueryParam("startIndex") final int startIndex,
-            @DefaultValue("50") @QueryParam("maxResults") final int 
maxResults) {
+            @DefaultValue("50") @QueryParam("maxResults") final int 
maxResults, @Context final HttpServletRequest request) {
+               if (!isAuthorized(request)) {
+                       return 
Response.status(Response.Status.UNAUTHORIZED).build();
+               }
         return super.getRoles(filter, sortOrder, startIndex, maxResults, 
Role.GROUP);
     }
 
@@ -104,7 +113,10 @@
     @GET
     @Path("{name}")
     @Produces({MediaType.APPLICATION_JSON})
-    public Response getGroup(@PathParam("name") final String name) {
+    public Response getGroup(@PathParam("name") final String name, @Context 
final HttpServletRequest request) {
+               if (!isAuthorized(request)) {
+                       return 
Response.status(Response.Status.UNAUTHORIZED).build();
+               }
         return super.getRole(name, Role.GROUP);
     }
 
@@ -121,7 +133,10 @@
     @PUT
     @Path("{name}")
     @Produces({MediaType.APPLICATION_JSON})
-    public Response createGroup(@PathParam("name") final String name) {
+    public Response createGroup(@PathParam("name") final String name, @Context 
final HttpServletRequest request) {
+               if (!isAuthorized(request)) {
+                       return 
Response.status(Response.Status.UNAUTHORIZED).build();
+               }
         return super.createRole(name, Role.GROUP);
     }
     
@@ -140,7 +155,10 @@
     @Path("{name}/credentials/{key}")
     @Produces({MediaType.APPLICATION_JSON})
     public Response setCredential(@PathParam("name") final String name,
-            @PathParam("key") final String key, @QueryParam("value") final 
String value) {
+            @PathParam("key") final String key, @QueryParam("value") final 
String value, @Context final HttpServletRequest request) {
+               if (!isAuthorized(request)) {
+                       return 
Response.status(Response.Status.UNAUTHORIZED).build();
+               }
         return setCredential(name, key, value, Role.GROUP);
     }  
     
@@ -159,7 +177,10 @@
     @Path("{name}/properties/{key}")
     @Produces({MediaType.APPLICATION_JSON})
     public Response setProperty(@PathParam("name") final String name,
-            @PathParam("key") final String key, @QueryParam("value") final 
String value) {
+            @PathParam("key") final String key, @QueryParam("value") final 
String value, @Context final HttpServletRequest request) {
+               if (!isAuthorized(request)) {
+                       return 
Response.status(Response.Status.UNAUTHORIZED).build();
+               }
         return setProperty(name, key, value, Role.USER);
     }    
 
@@ -178,8 +199,11 @@
     @Path("{name}/basicmembers/{memberName}")
     @Produces({MediaType.APPLICATION_JSON})
     public Response addBasicMember(@PathParam("name") final String name,
-            @PathParam("memberName") final String memberName) {
-        return addMember(name, memberName, false);
+            @PathParam("memberName") final String memberName, @Context final 
HttpServletRequest request) {
+               if (!isAuthorized(request)) {
+                       return 
Response.status(Response.Status.UNAUTHORIZED).build();
+               }
+        return addMember(name, memberName, false, request);
     }
 
     /**
@@ -197,8 +221,11 @@
     @Path("{name}/requiredmembers/{memberName}")
     @Produces({MediaType.APPLICATION_JSON})
     public Response addRequiredMember(@PathParam("name") final String name,
-            @PathParam("memberName") final String memberName) {
-        return addMember(name, memberName, true);
+            @PathParam("memberName") final String memberName, @Context final 
HttpServletRequest request) {
+               if (!isAuthorized(request)) {
+                       return 
Response.status(Response.Status.UNAUTHORIZED).build();
+               }
+        return addMember(name, memberName, true, request);
     }
 
     /**
@@ -213,7 +240,10 @@
     @DELETE
     @Path("{name}")
     @Produces({MediaType.APPLICATION_JSON})
-    public Response removeGroup(@PathParam("name") final String name) {
+    public Response removeGroup(@PathParam("name") final String name, @Context 
final HttpServletRequest request) {
+               if (!isAuthorized(request)) {
+                       return 
Response.status(Response.Status.UNAUTHORIZED).build();
+               }
         return super.removeRole(name, Role.GROUP);
     }
 
@@ -230,7 +260,10 @@
     @DELETE
     @Path("{name}/members/{memberName}")
     @Produces({MediaType.APPLICATION_JSON})
-    public Response removeMember(@PathParam("name") final String name, 
@PathParam("memberName") final String memberName) {
+    public Response removeMember(@PathParam("name") final String name, 
@PathParam("memberName") final String memberName, @Context final 
HttpServletRequest request) {
+               if (!isAuthorized(request)) {
+                       return 
Response.status(Response.Status.UNAUTHORIZED).build();
+               }
         Role role = m_userAdmin.getRole(name);
         Role member = m_userAdmin.getRole(memberName);
         if (role != null && role.getType() == Role.GROUP && member != null) {
@@ -244,7 +277,10 @@
         }
     }
 
-    private Response addMember(String name, String memberName, boolean 
required) {
+    private Response addMember(String name, String memberName, boolean 
required, @Context final HttpServletRequest request) {
+               if (!isAuthorized(request)) {
+                       return 
Response.status(Response.Status.UNAUTHORIZED).build();
+               }
         Role role = m_userAdmin.getRole(name);
         Role member = m_userAdmin.getRole(memberName);
         if (role != null && role.getType() == Role.GROUP && member != null) {
@@ -259,4 +295,18 @@
             return Response.status(Response.Status.NOT_FOUND).build();
         }
     }
+    
+       private boolean isAuthorized(HttpServletRequest request) {
+               BasicHttpSession session = BasicHttpSession.getSession(request);
+               if (session != null) {
+                       Authorization auth = (Authorization) 
session.getValue("authorization");
+                       if (auth != null) {
+                               String adminRole = 
GroupsResource.DEFAULT_ADMIN_GROUP;
+                               if (auth.hasRole(adminRole)) {
+                                       return true;
+                               }
+                       }
+               }
+               return false;
+       }
 }

Modified: 
branches/197-secure/platform-bundles/useradmin-cassandra-store/src/main/java/org/amdatu/platform/useradmin/store/cassandra/rest/UsersResource.java
==============================================================================
--- 
branches/197-secure/platform-bundles/useradmin-cassandra-store/src/main/java/org/amdatu/platform/useradmin/store/cassandra/rest/UsersResource.java
  (original)
+++ 
branches/197-secure/platform-bundles/useradmin-cassandra-store/src/main/java/org/amdatu/platform/useradmin/store/cassandra/rest/UsersResource.java
  Fri Nov 12 10:26:20 2010
@@ -16,6 +16,7 @@
  */
 package org.amdatu.platform.useradmin.store.cassandra.rest;
 
+import javax.servlet.http.HttpServletRequest;
 import javax.ws.rs.DELETE;
 import javax.ws.rs.DefaultValue;
 import javax.ws.rs.FormParam;
@@ -25,10 +26,13 @@
 import javax.ws.rs.PathParam;
 import javax.ws.rs.Produces;
 import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.Context;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
 
+import org.amdatu.platform.httpcontext.BasicHttpSession;
 import org.amdatu.platform.useradmin.store.cassandra.DummyResourceInterface;
+import org.osgi.service.useradmin.Authorization;
 import org.osgi.service.useradmin.Role;
 
 /**
@@ -43,133 +47,166 @@
  */
 @Path("users")
 public class UsersResource extends ResourceBase implements 
DummyResourceInterface  {
-    /**
-     * Returns all users that match the specified filter options. This method 
can be invoked by making the following
-     * REST call:<code><pre>
-     * GET 
/rest/services/users/users?filter={filter}&sortOrder={sortOrder}&startIndex={startIndex}&maxResults={maxResults}
-     * </pre></code> For available path and query parameters, see below.
-     * @param filter Filter that the name of the user must match. A user name 
is considered to match the specified
-     *            filter if the filter equals the user name or the filter is a 
substring of the user name.
-     * @param sortOrder 'ascending' to return results in ascending order or 
'descending' to return results in descending
-     *            order.
-     * @param startIndex The index of the first result to return (default is 
1).
-     * @param maxResults The maximum amount of results to return (default is 
50).
-     * @return a 400 response with this JSON string containing the results in 
case the call was successful: <code><pre>
-     * {
-     *   "totalCount":1,             => Total amount of available results for 
this query, independent of the values of startIndex and maxResults
-     *   "resultCount":1,            => Amount of results returned, depending 
on startIndex and maxResults
-     *   "maxResults":50             => The maximum amount of results returned 
in the result (if provided as request parameter, this value is the same)
-     *   "startIndex":1,             => Index of the first search result 
returned (if provided as request parameter, this value is the same)
-     *   "endIndex":1,               => Index of the last search result 
returned
-     *   "firstStartIndex":1,        => Index of the first available result 
for this query
-     *   "lastStartIndex":1,         => Last index of available results for 
this query (i.e. if there are 243 results available and maxResults is 50, this 
value equals 201)
-     *   "entry":[                   => Result entries
-     *    {
-     *      "name":"Administrator",  => Name of the user
-     *      "properties":{}          => Properties of the user
-     *    }]
-     * }
-     * </pre></code> a 500 response in case any exception occurred.
-     */    
-    @GET
-    @Produces({MediaType.APPLICATION_JSON})
-    public Response getUsers(
-            @QueryParam("filter") final String filter,
-            @QueryParam("sortOrder") final String sortOrder,
-            @DefaultValue("1") @QueryParam("startIndex") final int startIndex,
-            @DefaultValue("50") @QueryParam("maxResults") final int 
maxResults) {
-        return super.getRoles(filter, sortOrder, startIndex, maxResults, 
Role.USER);
-    }
-    
-    /**
-     * Returns the user with the specified name. This method can be invoked by 
making the following REST call:
-     * <code><pre>
-     * GET /rest/services/users/users/{name}
-     * </pre></code> For available path and query parameters, see below.
-     * @param name Name of the user to retrieve
-     * @return a 400 response in case the user was found and returned. It 
returns this JSON string: <code><pre>
-     *   {
-     *     "name":"Administrator",  => Name of the user
-     *     "properties":{}          => Properties of the user
-     *   }
-     * </pre></code>a 404 response if the requested user does not exist.<br/>
-     *         a 500 response in case any exception occurred.
-     */
-    @GET
-    @Path("{name}")
-    @Produces({MediaType.APPLICATION_JSON})
-    public Response getUser(@PathParam("name") final String name) {
-        return super.getRole(name, Role.USER);
-    }
-    
-    /**
-     * Creates the user with the specified name. This method can be invoked by 
making the following REST call:
-     * <code><pre>
-     * PUT /rest/services/users/users/{name}
-     * </pre></code> For available path and query parameters, see below.
-     * @param name Name of the user to create
-     * @return a 400 response in case the user was created.<br/>
-     *         a 304 response in case for whatever reason the user could not 
be created (i.e. a group or user with the
-     *         specified name already exists).
-     */
-    @PUT
-    @Path("{name}")
-    @Produces({MediaType.APPLICATION_JSON})
-    public Response createUser(@PathParam("name") final String name) {
-        return super.createRole(name, Role.USER);
-    }
-    
-    /**
-     * Sets a credential for the user with the specified name. This method can 
be invoked by making the following REST
-     * call: <code><pre>
-     * PUT /rest/services/users/users/{name}/credentials/{key}
-     * </pre></code> For available path and query parameters, see below.
-     * @param name Name of the user to set the credential for
-     * @param key The key of the credential to set
-     * @param value The value of the credential to set (this should be a 
posted form field named 'value')
-     * @return a 400 response in case the credential was updated.<br/>
-     *         a 404 response in case the user with the specified name does 
not exist.
-     */
-    @PUT
-    @Path("{name}/credentials/{key}")
-    @Produces({MediaType.APPLICATION_JSON})
-    public Response setCredential(@PathParam("name") final String name,
-            @PathParam("key") final String key, @FormParam("value") final 
String value) {
-        return setCredential(name, key, value, Role.USER);
-    }  
-    
-    /**
-     * Sets a property for the user with the specified name. This method can 
be invoked by making the following REST
-     * call: <code><pre>
-     * PUT /rest/services/users/users/{name}/properties/{key}
-     * </pre></code> For available path and query parameters, see below.
-     * @param name Name of the user to set the property for
-     * @param key The key of the property to set
-     * @param value The value of the property to set (this should be a posted 
form field named 'value')
-     * @return a 400 response in case the property was updated.<br/>
-     *         a 404 response in case the user with the specified name does 
not exist.
-     */
-    @PUT
-    @Path("{name}/properties/{key}")
-    @Produces({MediaType.APPLICATION_JSON})
-    public Response setProperty(@PathParam("name") final String name,
-            @PathParam("key") final String key, @FormParam("value") final 
String value) {
-        return setProperty(name, key, value, Role.USER);
-    }    
-        
-    /**
-     * Removes the user with the specified name. This method can be invoked by 
making the following REST call:
-     * <code><pre>
-     * DELETE /rest/services/users/users/{name}
-     * </pre></code> For available path and query parameters, see below.
-     * @param name Name of the user to delete
-     * @return a 400 response in case the user was deleted.<br/>
-     *         a 404 response in case a user with the specified name does not 
exist.
-     */
-    @DELETE
-    @Path("{name}")
-    @Produces({MediaType.APPLICATION_JSON})
-    public Response removeUser(@PathParam("name") final String name) {
-        return super.removeRole(name, Role.USER);
-    }
+       /**
+        * Returns all users that match the specified filter options. This 
method can be invoked by making the following
+        * REST call:<code><pre>
+        * GET 
/rest/services/users/users?filter={filter}&sortOrder={sortOrder}&startIndex={startIndex}&maxResults={maxResults}
+        * </pre></code> For available path and query parameters, see below.
+        * @param filter Filter that the name of the user must match. A user 
name is considered to match the specified
+        *            filter if the filter equals the user name or the filter 
is a substring of the user name.
+        * @param sortOrder 'ascending' to return results in ascending order or 
'descending' to return results in descending
+        *            order.
+        * @param startIndex The index of the first result to return (default 
is 1).
+        * @param maxResults The maximum amount of results to return (default 
is 50).
+        * @return a 400 response with this JSON string containing the results 
in case the call was successful: <code><pre>
+        * {
+        *   "totalCount":1,             => Total amount of available results 
for this query, independent of the values of startIndex and maxResults
+        *   "resultCount":1,            => Amount of results returned, 
depending on startIndex and maxResults
+        *   "maxResults":50             => The maximum amount of results 
returned in the result (if provided as request parameter, this value is the 
same)
+        *   "startIndex":1,             => Index of the first search result 
returned (if provided as request parameter, this value is the same)
+        *   "endIndex":1,               => Index of the last search result 
returned
+        *   "firstStartIndex":1,        => Index of the first available result 
for this query
+        *   "lastStartIndex":1,         => Last index of available results for 
this query (i.e. if there are 243 results available and maxResults is 50, this 
value equals 201)
+        *   "entry":[                   => Result entries
+        *    {
+        *      "name":"Administrator",  => Name of the user
+        *      "properties":{}          => Properties of the user
+        *    }]
+        * }
+        * </pre></code> a 500 response in case any exception occurred.
+        */    
+       @GET
+       @Produces({MediaType.APPLICATION_JSON})
+       public Response getUsers(
+                       @QueryParam("filter") final String filter,
+                       @QueryParam("sortOrder") final String sortOrder,
+                       @DefaultValue("1") @QueryParam("startIndex") final int 
startIndex,
+                       @DefaultValue("50") @QueryParam("maxResults") final int 
maxResults,
+                       @Context final HttpServletRequest request) {
+               if (!isAuthorized(request)) {
+                       return 
Response.status(Response.Status.UNAUTHORIZED).build();
+               }
+               return super.getRoles(filter, sortOrder, startIndex, 
maxResults, Role.USER);
+       }
+
+       /**
+        * Returns the user with the specified name. This method can be invoked 
by making the following REST call:
+        * <code><pre>
+        * GET /rest/services/users/users/{name}
+        * </pre></code> For available path and query parameters, see below.
+        * @param name Name of the user to retrieve
+        * @return a 400 response in case the user was found and returned. It 
returns this JSON string: <code><pre>
+        *   {
+        *     "name":"Administrator",  => Name of the user
+        *     "properties":{}          => Properties of the user
+        *   }
+        * </pre></code>a 404 response if the requested user does not 
exist.<br/>
+        *         a 500 response in case any exception occurred.
+        */
+       @GET
+       @Path("{name}")
+       @Produces({MediaType.APPLICATION_JSON})
+       public Response getUser(@PathParam("name") final String name, @Context 
final HttpServletRequest request) {
+               if (!isAuthorized(request)) {
+                       return 
Response.status(Response.Status.UNAUTHORIZED).build();
+               }
+               return super.getRole(name, Role.USER);
+       }
+
+       /**
+        * Creates the user with the specified name. This method can be invoked 
by making the following REST call:
+        * <code><pre>
+        * PUT /rest/services/users/users/{name}
+        * </pre></code> For available path and query parameters, see below.
+        * @param name Name of the user to create
+        * @return a 400 response in case the user was created.<br/>
+        *         a 304 response in case for whatever reason the user could 
not be created (i.e. a group or user with the
+        *         specified name already exists).
+        */
+       @PUT
+       @Path("{name}")
+       @Produces({MediaType.APPLICATION_JSON})
+       public Response createUser(@PathParam("name") final String name, 
@Context final HttpServletRequest request) {
+               if (!isAuthorized(request)) {
+                       return 
Response.status(Response.Status.UNAUTHORIZED).build();
+               }
+               return super.createRole(name, Role.USER);
+       }
+
+       /**
+        * Sets a credential for the user with the specified name. This method 
can be invoked by making the following REST
+        * call: <code><pre>
+        * PUT /rest/services/users/users/{name}/credentials/{key}
+        * </pre></code> For available path and query parameters, see below.
+        * @param name Name of the user to set the credential for
+        * @param key The key of the credential to set
+        * @param value The value of the credential to set (this should be a 
posted form field named 'value')
+        * @return a 400 response in case the credential was updated.<br/>
+        *         a 404 response in case the user with the specified name does 
not exist.
+        */
+       @PUT
+       @Path("{name}/credentials/{key}")
+       @Produces({MediaType.APPLICATION_JSON})
+       public Response setCredential(@PathParam("name") final String name,
+                       @PathParam("key") final String key, @FormParam("value") 
final String value, @Context final HttpServletRequest request) {
+               if (!isAuthorized(request)) {
+                       return 
Response.status(Response.Status.UNAUTHORIZED).build();
+               }
+               return setCredential(name, key, value, Role.USER);
+       }  
+
+       /**
+        * Sets a property for the user with the specified name. This method 
can be invoked by making the following REST
+        * call: <code><pre>
+        * PUT /rest/services/users/users/{name}/properties/{key}
+        * </pre></code> For available path and query parameters, see below.
+        * @param name Name of the user to set the property for
+        * @param key The key of the property to set
+        * @param value The value of the property to set (this should be a 
posted form field named 'value')
+        * @return a 400 response in case the property was updated.<br/>
+        *         a 404 response in case the user with the specified name does 
not exist.
+        */
+       @PUT
+       @Path("{name}/properties/{key}")
+       @Produces({MediaType.APPLICATION_JSON})
+       public Response setProperty(@PathParam("name") final String name,
+                       @PathParam("key") final String key, @FormParam("value") 
final String value, @Context final HttpServletRequest request) {
+               if (!isAuthorized(request)) {
+                       return 
Response.status(Response.Status.UNAUTHORIZED).build();
+               }
+               return setProperty(name, key, value, Role.USER);
+       }    
+
+       /**
+        * Removes the user with the specified name. This method can be invoked 
by making the following REST call:
+        * <code><pre>
+        * DELETE /rest/services/users/users/{name}
+        * </pre></code> For available path and query parameters, see below.
+        * @param name Name of the user to delete
+        * @return a 400 response in case the user was deleted.<br/>
+        *         a 404 response in case a user with the specified name does 
not exist.
+        */
+       @DELETE
+       @Path("{name}")
+       @Produces({MediaType.APPLICATION_JSON})
+       public Response removeUser(@PathParam("name") final String name, 
@Context final HttpServletRequest request) {
+               if (!isAuthorized(request)) {
+                       return 
Response.status(Response.Status.UNAUTHORIZED).build();
+               }
+               return super.removeRole(name, Role.USER);
+       }
+
+       private boolean isAuthorized(HttpServletRequest request) {
+               BasicHttpSession session = BasicHttpSession.getSession(request);
+               if (session != null) {
+                       Authorization auth = (Authorization) 
session.getValue("authorization");
+                       if (auth != null) {
+                               String adminRole = 
GroupsResource.DEFAULT_ADMIN_GROUP;
+                               if (auth.hasRole(adminRole)) {
+                                       return true;
+                               }
+                       }
+               }
+               return false;
+       }
 }

Reply via email to