usergrid-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mru...@apache.org
Subject [5/8] usergrid git commit: Add additional functionality in REST layer for checking permissions.
Date Tue, 29 Mar 2016 20:11:46 GMT
Add additional functionality in REST layer for checking permissions.


Project: http://git-wip-us.apache.org/repos/asf/usergrid/repo
Commit: http://git-wip-us.apache.org/repos/asf/usergrid/commit/8dddc0eb
Tree: http://git-wip-us.apache.org/repos/asf/usergrid/tree/8dddc0eb
Diff: http://git-wip-us.apache.org/repos/asf/usergrid/diff/8dddc0eb

Branch: refs/heads/hotfix-2.0.0
Commit: 8dddc0eb7a615d4f6b5110f3dd772218e8bb2d3c
Parents: 5732dee
Author: Michael Russo <michaelarusso@gmail.com>
Authored: Fri Dec 4 21:05:41 2015 -0800
Committer: Michael Russo <michaelarusso@gmail.com>
Committed: Fri Dec 4 21:05:41 2015 -0800

----------------------------------------------------------------------
 .../rest/applications/ApplicationResource.java  |   1 +
 .../rest/applications/AuthResource.java         |   7 ++
 .../applications/assets/AssetsResource.java     |   8 +-
 .../rest/applications/queues/QueueResource.java |  10 ++
 .../queues/QueueSubscriberResource.java         |   5 +
 .../queues/QueueSubscriptionResource.java       |   5 +
 .../queues/QueueTransactionsResource.java       |   3 +
 .../security/SecuredResourceFilterFactory.java  |  74 +++++++++--
 .../annotations/CheckPermissionsForPath.java    |  32 +++++
 .../usergrid/rest/applications/SecurityIT.java  | 124 +++++++++++++++++++
 10 files changed, 258 insertions(+), 11 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/usergrid/blob/8dddc0eb/stack/rest/src/main/java/org/apache/usergrid/rest/applications/ApplicationResource.java
----------------------------------------------------------------------
diff --git a/stack/rest/src/main/java/org/apache/usergrid/rest/applications/ApplicationResource.java
b/stack/rest/src/main/java/org/apache/usergrid/rest/applications/ApplicationResource.java
index 2c252e7..5b3a9af 100644
--- a/stack/rest/src/main/java/org/apache/usergrid/rest/applications/ApplicationResource.java
+++ b/stack/rest/src/main/java/org/apache/usergrid/rest/applications/ApplicationResource.java
@@ -125,6 +125,7 @@ public class ApplicationResource extends ServiceResource {
     }
 
 
+    @RequireApplicationAccess
     @Path("auth")
     public AuthResource getAuthResource() throws Exception {
         return getSubResource( AuthResource.class );

http://git-wip-us.apache.org/repos/asf/usergrid/blob/8dddc0eb/stack/rest/src/main/java/org/apache/usergrid/rest/applications/AuthResource.java
----------------------------------------------------------------------
diff --git a/stack/rest/src/main/java/org/apache/usergrid/rest/applications/AuthResource.java
b/stack/rest/src/main/java/org/apache/usergrid/rest/applications/AuthResource.java
index 46e97c7..a8549d1 100644
--- a/stack/rest/src/main/java/org/apache/usergrid/rest/applications/AuthResource.java
+++ b/stack/rest/src/main/java/org/apache/usergrid/rest/applications/AuthResource.java
@@ -30,6 +30,7 @@ import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
 import javax.ws.rs.core.UriInfo;
 
+import org.apache.usergrid.rest.security.annotations.CheckPermissionsForPath;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -87,6 +88,7 @@ public class AuthResource extends AbstractContextResource {
     // TODO add auth for Ping Identity
 
 
+    @CheckPermissionsForPath
     @POST
     @Path("facebook")
     @Consumes(APPLICATION_FORM_URLENCODED)
@@ -100,6 +102,7 @@ public class AuthResource extends AbstractContextResource {
     }
 
 
+    @CheckPermissionsForPath
     @GET
     @Path("pingident")
     public Response authPingIdent( @Context UriInfo ui, @QueryParam("ping_access_token")
String pingToken,
@@ -132,6 +135,7 @@ public class AuthResource extends AbstractContextResource {
     }
 
 
+    @CheckPermissionsForPath
     @POST
     @Path("pingident")
     public Response authPingIdentPost( @Context UriInfo ui, @QueryParam("ping_access_token")
String pingToken,
@@ -170,6 +174,7 @@ public class AuthResource extends AbstractContextResource {
     }
 
 
+    @CheckPermissionsForPath
     @GET
     @Path("facebook")
     public Response authFB( @Context UriInfo ui, @QueryParam("fb_access_token") String fb_access_token,
@@ -204,6 +209,7 @@ public class AuthResource extends AbstractContextResource {
     }
 
 
+    @CheckPermissionsForPath
     @POST
     @Path("foursquare")
     @Consumes(APPLICATION_FORM_URLENCODED)
@@ -217,6 +223,7 @@ public class AuthResource extends AbstractContextResource {
     }
 
 
+    @CheckPermissionsForPath
     @GET
     @Path("foursquare")
     public Response authFQ( @Context UriInfo ui, @QueryParam("fq_access_token") String fq_access_token,

http://git-wip-us.apache.org/repos/asf/usergrid/blob/8dddc0eb/stack/rest/src/main/java/org/apache/usergrid/rest/applications/assets/AssetsResource.java
----------------------------------------------------------------------
diff --git a/stack/rest/src/main/java/org/apache/usergrid/rest/applications/assets/AssetsResource.java
b/stack/rest/src/main/java/org/apache/usergrid/rest/applications/assets/AssetsResource.java
index b43827b..aeffe3b 100644
--- a/stack/rest/src/main/java/org/apache/usergrid/rest/applications/assets/AssetsResource.java
+++ b/stack/rest/src/main/java/org/apache/usergrid/rest/applications/assets/AssetsResource.java
@@ -39,6 +39,7 @@ import javax.ws.rs.core.PathSegment;
 import javax.ws.rs.core.Response;
 import javax.ws.rs.core.UriInfo;
 
+import org.apache.usergrid.rest.security.annotations.CheckPermissionsForPath;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -107,8 +108,8 @@ public class AssetsResource extends ServiceResource {
     }
 
 
+    @CheckPermissionsForPath
     @POST
-    @RequireApplicationAccess
     @Consumes(MediaType.MULTIPART_FORM_DATA)
     @Path("{entityId: [A-Fa-f0-9]{8}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{12}}/data")
     public Response uploadData( @FormDataParam("file") InputStream uploadedInputStream,
@@ -129,8 +130,8 @@ public class AssetsResource extends ServiceResource {
     }
 
 
+    @CheckPermissionsForPath
     @PUT
-    @RequireApplicationAccess
     @Consumes(MediaType.APPLICATION_OCTET_STREAM)
     @Path("{entityId: [A-Fa-f0-9]{8}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{12}}/data")
     public Response uploadDataStreamPut( @PathParam("entityId") PathSegment entityId, InputStream
uploadedInputStream )
@@ -139,8 +140,8 @@ public class AssetsResource extends ServiceResource {
     }
 
 
+    @CheckPermissionsForPath
     @POST
-    @RequireApplicationAccess
     @Consumes(MediaType.APPLICATION_OCTET_STREAM)
     @Path("{entityId: [A-Fa-f0-9]{8}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{12}}/data")
     public Response uploadDataStream( @PathParam("entityId") PathSegment entityId, InputStream
uploadedInputStream )
@@ -158,6 +159,7 @@ public class AssetsResource extends ServiceResource {
     }
 
 
+    @CheckPermissionsForPath
     @GET
     @Path("{entityId: [A-Fa-f0-9]{8}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{12}}/data")
     public Response findAsset( @Context UriInfo ui, @QueryParam("callback") @DefaultValue("callback")
String callback,

http://git-wip-us.apache.org/repos/asf/usergrid/blob/8dddc0eb/stack/rest/src/main/java/org/apache/usergrid/rest/applications/queues/QueueResource.java
----------------------------------------------------------------------
diff --git a/stack/rest/src/main/java/org/apache/usergrid/rest/applications/queues/QueueResource.java
b/stack/rest/src/main/java/org/apache/usergrid/rest/applications/queues/QueueResource.java
index 67498cd..de71073 100644
--- a/stack/rest/src/main/java/org/apache/usergrid/rest/applications/queues/QueueResource.java
+++ b/stack/rest/src/main/java/org/apache/usergrid/rest/applications/queues/QueueResource.java
@@ -35,6 +35,7 @@ import javax.ws.rs.core.Context;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.UriInfo;
 
+import org.apache.usergrid.rest.security.annotations.CheckPermissionsForPath;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.context.annotation.Scope;
@@ -86,6 +87,7 @@ public class QueueResource extends AbstractContextResource {
     }
 
 
+    @CheckPermissionsForPath
     @Path("subscribers")
     public QueueSubscriberResource getSubscribers( @Context UriInfo ui ) throws Exception
{
 
@@ -95,6 +97,7 @@ public class QueueResource extends AbstractContextResource {
     }
 
 
+    @CheckPermissionsForPath
     @Path("subscriptions")
     public QueueSubscriptionResource getSubscriptions( @Context UriInfo ui ) throws Exception
{
 
@@ -104,6 +107,7 @@ public class QueueResource extends AbstractContextResource {
     }
 
 
+    @CheckPermissionsForPath
     @Path("properties")
     @GET
     public JSONWithPadding getProperties( @Context UriInfo ui,
@@ -116,6 +120,7 @@ public class QueueResource extends AbstractContextResource {
     }
 
 
+    @CheckPermissionsForPath
     @Path("properties")
     @PUT
     @Consumes(MediaType.APPLICATION_JSON)
@@ -129,6 +134,7 @@ public class QueueResource extends AbstractContextResource {
     }
 
 
+    @CheckPermissionsForPath
     @GET
     public JSONWithPadding executeGet( @Context UriInfo ui, @QueryParam("start") String firstQueuePath,
                                        @QueryParam("limit") @DefaultValue("10") int limit,
@@ -149,6 +155,7 @@ public class QueueResource extends AbstractContextResource {
     }
 
 
+    @CheckPermissionsForPath
     @SuppressWarnings("unchecked")
     @POST
     @Consumes(MediaType.APPLICATION_JSON)
@@ -173,6 +180,7 @@ public class QueueResource extends AbstractContextResource {
     }
 
 
+    @CheckPermissionsForPath
     @PUT
     @Consumes(MediaType.APPLICATION_JSON)
     public JSONWithPadding executePut( @Context UriInfo ui, Map<String, Object> json,
@@ -187,6 +195,7 @@ public class QueueResource extends AbstractContextResource {
     }
 
 
+    @CheckPermissionsForPath
     @DELETE
     public JSONWithPadding executeDelete( @Context UriInfo ui,
                                           @QueryParam("callback") @DefaultValue("callback")
String callback )
@@ -195,6 +204,7 @@ public class QueueResource extends AbstractContextResource {
     }
 
 
+    @CheckPermissionsForPath
     @Path("transactions")
     public QueueTransactionsResource getTransactions( @Context UriInfo ui ) throws Exception
{
 

http://git-wip-us.apache.org/repos/asf/usergrid/blob/8dddc0eb/stack/rest/src/main/java/org/apache/usergrid/rest/applications/queues/QueueSubscriberResource.java
----------------------------------------------------------------------
diff --git a/stack/rest/src/main/java/org/apache/usergrid/rest/applications/queues/QueueSubscriberResource.java
b/stack/rest/src/main/java/org/apache/usergrid/rest/applications/queues/QueueSubscriberResource.java
index 12db937..7f32be0 100644
--- a/stack/rest/src/main/java/org/apache/usergrid/rest/applications/queues/QueueSubscriberResource.java
+++ b/stack/rest/src/main/java/org/apache/usergrid/rest/applications/queues/QueueSubscriberResource.java
@@ -34,6 +34,7 @@ import javax.ws.rs.core.Context;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.UriInfo;
 
+import org.apache.usergrid.rest.security.annotations.CheckPermissionsForPath;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.context.annotation.Scope;
@@ -92,6 +93,7 @@ public class QueueSubscriberResource extends AbstractContextResource {
     }
 
 
+    @CheckPermissionsForPath
     @GET
     public JSONWithPadding executeGet( @Context UriInfo ui, @QueryParam("start") String firstSubscriberQueuePath,
                                        @QueryParam("limit") @DefaultValue("10") int limit,
@@ -106,6 +108,7 @@ public class QueueSubscriberResource extends AbstractContextResource {
     }
 
 
+    @CheckPermissionsForPath
     @POST
     @Consumes(MediaType.APPLICATION_JSON)
     public JSONWithPadding executePost( @Context UriInfo ui, EntityHolder<Map<String,
Object>> body,
@@ -118,6 +121,7 @@ public class QueueSubscriberResource extends AbstractContextResource {
     }
 
 
+    @CheckPermissionsForPath
     @PUT
     @Consumes(MediaType.APPLICATION_JSON)
     public JSONWithPadding executePut( @Context UriInfo ui, EntityHolder<Map<String,
Object>> body,
@@ -143,6 +147,7 @@ public class QueueSubscriberResource extends AbstractContextResource {
     }
 
 
+    @CheckPermissionsForPath
     @DELETE
     public JSONWithPadding executeDelete( @Context UriInfo ui,
                                           @QueryParam("callback") @DefaultValue("callback")
String callback )

http://git-wip-us.apache.org/repos/asf/usergrid/blob/8dddc0eb/stack/rest/src/main/java/org/apache/usergrid/rest/applications/queues/QueueSubscriptionResource.java
----------------------------------------------------------------------
diff --git a/stack/rest/src/main/java/org/apache/usergrid/rest/applications/queues/QueueSubscriptionResource.java
b/stack/rest/src/main/java/org/apache/usergrid/rest/applications/queues/QueueSubscriptionResource.java
index a822b1e..c488095 100644
--- a/stack/rest/src/main/java/org/apache/usergrid/rest/applications/queues/QueueSubscriptionResource.java
+++ b/stack/rest/src/main/java/org/apache/usergrid/rest/applications/queues/QueueSubscriptionResource.java
@@ -34,6 +34,7 @@ import javax.ws.rs.core.Context;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.UriInfo;
 
+import org.apache.usergrid.rest.security.annotations.CheckPermissionsForPath;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.context.annotation.Scope;
@@ -94,6 +95,7 @@ public class QueueSubscriptionResource extends AbstractContextResource {
     }
 
 
+    @CheckPermissionsForPath
     @GET
     public JSONWithPadding executeGet( @Context UriInfo ui, @QueryParam("start") String firstSubscriptionQueuePath,
                                        @QueryParam("limit") @DefaultValue("10") int limit,
@@ -108,6 +110,7 @@ public class QueueSubscriptionResource extends AbstractContextResource
{
     }
 
 
+    @CheckPermissionsForPath
     @POST
     @Consumes(MediaType.APPLICATION_JSON)
     public JSONWithPadding executePost( @Context UriInfo ui, EntityHolder<Map<String,
Object>> body,
@@ -120,6 +123,7 @@ public class QueueSubscriptionResource extends AbstractContextResource
{
     }
 
 
+    @CheckPermissionsForPath
     @PUT
     @Consumes(MediaType.APPLICATION_JSON)
     public JSONWithPadding executePut( @Context UriInfo ui, EntityHolder<Map<String,
Object>> body,
@@ -145,6 +149,7 @@ public class QueueSubscriptionResource extends AbstractContextResource
{
     }
 
 
+    @CheckPermissionsForPath
     @DELETE
     public JSONWithPadding executeDelete( @Context UriInfo ui,
                                           @QueryParam("callback") @DefaultValue("callback")
String callback )

http://git-wip-us.apache.org/repos/asf/usergrid/blob/8dddc0eb/stack/rest/src/main/java/org/apache/usergrid/rest/applications/queues/QueueTransactionsResource.java
----------------------------------------------------------------------
diff --git a/stack/rest/src/main/java/org/apache/usergrid/rest/applications/queues/QueueTransactionsResource.java
b/stack/rest/src/main/java/org/apache/usergrid/rest/applications/queues/QueueTransactionsResource.java
index 2f9819d..56cca2c 100644
--- a/stack/rest/src/main/java/org/apache/usergrid/rest/applications/queues/QueueTransactionsResource.java
+++ b/stack/rest/src/main/java/org/apache/usergrid/rest/applications/queues/QueueTransactionsResource.java
@@ -30,6 +30,7 @@ import javax.ws.rs.core.Context;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.UriInfo;
 
+import org.apache.usergrid.rest.security.annotations.CheckPermissionsForPath;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.context.annotation.Scope;
@@ -70,6 +71,7 @@ public class QueueTransactionsResource extends AbstractContextResource {
     }
 
 
+    @CheckPermissionsForPath
     @Path("{id}")
     @PUT
     public JSONWithPadding updateTransaction( @Context UriInfo ui, @PathParam("id") UUID
transactionId,
@@ -84,6 +86,7 @@ public class QueueTransactionsResource extends AbstractContextResource {
     }
 
 
+    @CheckPermissionsForPath
     @Path("{id}")
     @DELETE
     public JSONWithPadding removeTransaction( @Context UriInfo ui, @PathParam("id") UUID
transactionId,

http://git-wip-us.apache.org/repos/asf/usergrid/blob/8dddc0eb/stack/rest/src/main/java/org/apache/usergrid/rest/security/SecuredResourceFilterFactory.java
----------------------------------------------------------------------
diff --git a/stack/rest/src/main/java/org/apache/usergrid/rest/security/SecuredResourceFilterFactory.java
b/stack/rest/src/main/java/org/apache/usergrid/rest/security/SecuredResourceFilterFactory.java
index 202eb31..2699938 100644
--- a/stack/rest/src/main/java/org/apache/usergrid/rest/security/SecuredResourceFilterFactory.java
+++ b/stack/rest/src/main/java/org/apache/usergrid/rest/security/SecuredResourceFilterFactory.java
@@ -26,6 +26,8 @@ import javax.ws.rs.core.Context;
 import javax.ws.rs.core.MultivaluedMap;
 import javax.ws.rs.core.UriInfo;
 
+import org.apache.shiro.subject.Subject;
+import org.apache.usergrid.rest.security.annotations.*;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -37,10 +39,6 @@ import org.apache.usergrid.persistence.EntityManager;
 import org.apache.usergrid.persistence.EntityManagerFactory;
 import org.apache.usergrid.persistence.index.query.Identifier;
 import org.apache.usergrid.rest.exceptions.SecurityException;
-import org.apache.usergrid.rest.security.annotations.RequireAdminUserAccess;
-import org.apache.usergrid.rest.security.annotations.RequireApplicationAccess;
-import org.apache.usergrid.rest.security.annotations.RequireOrganizationAccess;
-import org.apache.usergrid.rest.security.annotations.RequireSystemAccess;
 import org.apache.usergrid.rest.utils.PathingUtils;
 import org.apache.usergrid.security.shiro.utils.SubjectUtils;
 import org.apache.usergrid.services.ServiceManagerFactory;
@@ -54,10 +52,7 @@ import com.sun.jersey.spi.container.ResourceFilterFactory;
 
 import static org.apache.commons.lang.StringUtils.isNotEmpty;
 import static org.apache.usergrid.rest.exceptions.SecurityException.mappableSecurityException;
-import static org.apache.usergrid.security.shiro.utils.SubjectUtils.isPermittedAccessToApplication;
-import static org.apache.usergrid.security.shiro.utils.SubjectUtils.isPermittedAccessToOrganization;
-import static org.apache.usergrid.security.shiro.utils.SubjectUtils.isUser;
-import static org.apache.usergrid.security.shiro.utils.SubjectUtils.loginApplicationGuest;
+import static org.apache.usergrid.security.shiro.utils.SubjectUtils.*;
 
 
 @Component
@@ -131,6 +126,9 @@ public class SecuredResourceFilterFactory implements ResourceFilterFactory
{
         else if ( am.isAnnotationPresent( RequireAdminUserAccess.class ) ) {
             return Collections.<ResourceFilter>singletonList( new AdminUserFilter()
);
         }
+        else if ( am.isAnnotationPresent( CheckPermissionsForPath.class ) ) {
+            return Collections.<ResourceFilter>singletonList( new PathPermissionsFilter()
);
+        }
         return null;
     }
 
@@ -328,4 +326,64 @@ public class SecuredResourceFilterFactory implements ResourceFilterFactory
{
             }
         }
     }
+
+    // This filter is created in REST from logic in org.apache.usergrid.services.AbstractService.checkPermissionsForPath
+    public class PathPermissionsFilter extends AbstractFilter {
+
+        public PathPermissionsFilter() {}
+
+
+        @Override
+        public void authorize( ContainerRequest request ) {
+            if(logger.isDebugEnabled()){
+                logger.debug( "PathPermissionsFilter.authorize" );
+            }
+
+            final String PATH_MSG =
+                "---- Checked permissions for path --------------------------------------------\n"
+ "Requested path: {} \n"
+                    + "Requested action: {} \n" + "Requested permission: {} \n" + "Permitted:
{} \n";
+
+            ApplicationInfo application;
+
+            try {
+
+                application = management.getApplicationInfo( getApplicationIdentifier() );
+                EntityManager em = emf.getEntityManager( application.getId() );
+                Subject currentUser = SubjectUtils.getSubject();
+
+                if ( currentUser == null ) {
+                    return;
+                }
+                String applicationName = application.getName().toLowerCase();
+                String operation = request.getMethod().toLowerCase();
+                String path = request.getPath().toLowerCase().replace(applicationName, "");
+                String perm =  getPermissionFromPath( em.getApplicationRef().getUuid(), operation,
path );
+
+                boolean permitted = currentUser.isPermitted( perm );
+                if ( logger.isDebugEnabled() ) {
+                    logger.debug( PATH_MSG, new Object[] { path, operation, perm, permitted
} );
+                }
+
+                if(!permitted){
+                    // throwing this so we can raise a proper mapped REST exception
+                    throw new Exception("Subject not permitted");
+                }
+
+
+                SubjectUtils.checkPermission( perm );
+                Subject subject = SubjectUtils.getSubject();
+
+                if ( logger.isDebugEnabled() ) {
+                    logger.debug("Checked subject {} for perm {}", subject != null ? subject.toString()
: "", perm);
+                    logger.debug("------------------------------------------------------------------------------");
+                }
+
+
+            } catch (Exception e){
+                throw mappableSecurityException( "unauthorized",
+                    "Subject does not have permission to access this resource" );
+            }
+
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/usergrid/blob/8dddc0eb/stack/rest/src/main/java/org/apache/usergrid/rest/security/annotations/CheckPermissionsForPath.java
----------------------------------------------------------------------
diff --git a/stack/rest/src/main/java/org/apache/usergrid/rest/security/annotations/CheckPermissionsForPath.java
b/stack/rest/src/main/java/org/apache/usergrid/rest/security/annotations/CheckPermissionsForPath.java
new file mode 100644
index 0000000..5f0e00d
--- /dev/null
+++ b/stack/rest/src/main/java/org/apache/usergrid/rest/security/annotations/CheckPermissionsForPath.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.usergrid.rest.security.annotations;
+
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+
+/** Requires that the current Shiro security subject be the user specified in the current
REST request path. */
+@Retention(value = RUNTIME)
+@Target(value = { METHOD })
+public @interface CheckPermissionsForPath {
+
+}

http://git-wip-us.apache.org/repos/asf/usergrid/blob/8dddc0eb/stack/rest/src/test/java/org/apache/usergrid/rest/applications/SecurityIT.java
----------------------------------------------------------------------
diff --git a/stack/rest/src/test/java/org/apache/usergrid/rest/applications/SecurityIT.java
b/stack/rest/src/test/java/org/apache/usergrid/rest/applications/SecurityIT.java
new file mode 100644
index 0000000..9542511
--- /dev/null
+++ b/stack/rest/src/test/java/org/apache/usergrid/rest/applications/SecurityIT.java
@@ -0,0 +1,124 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.usergrid.rest.applications;
+
+
+import com.sun.jersey.api.client.UniformInterfaceException;
+import org.apache.usergrid.rest.AbstractRestIT;
+import org.apache.usergrid.utils.UUIDUtils;
+import org.codehaus.jackson.JsonNode;
+import org.junit.Test;
+import javax.ws.rs.core.MediaType;
+import java.util.UUID;
+import static org.junit.Assert.assertEquals;
+
+/**
+ * These tests will execute requests against certain paths (with or without credentials)
to ensure access is being
+ * allowed according to the REST and Services permissions defined for the resource.
+ */
+public class SecurityIT extends AbstractRestIT {
+
+    final String BASE_PATH = "/test-organization/test-app";
+    final int UNAUTHORIZED_STATUS = 401;
+
+    @Test
+    public void testAssetsNoCredentials(){
+
+        final UUID uuid = UUIDUtils.newTimeUUID();
+        int responseStatus = 0;
+
+        try {
+            // intentionally do not add access_token
+            resource().path(BASE_PATH + "/assets/" + uuid + "/data")
+                .accept(MediaType.APPLICATION_JSON_TYPE)
+                .get(JsonNode.class);
+        }
+        catch (UniformInterfaceException uie ) {
+            responseStatus = uie.getResponse().getStatus();
+        }
+        assertEquals(UNAUTHORIZED_STATUS, responseStatus);
+    }
+
+    @Test
+    public void testFacebookAuthNoCredentials(){
+
+        int responseStatus = 0;
+
+        try {
+            // intentionally do not add access_token
+            resource().path(BASE_PATH + "/auth/facebook")
+                .accept(MediaType.APPLICATION_JSON_TYPE)
+                .get(JsonNode.class);
+        }
+        catch (UniformInterfaceException uie ) {
+            responseStatus = uie.getResponse().getStatus();
+        }
+        assertEquals(UNAUTHORIZED_STATUS, responseStatus);
+    }
+
+    @Test
+    public void testPingIdentityAuthNoCredentials(){
+
+        int responseStatus = 0;
+
+        try {
+            // intentionally do not add access_token
+            resource().path(BASE_PATH + "/auth/pingident")
+                .accept(MediaType.APPLICATION_JSON_TYPE)
+                .get(JsonNode.class);
+        }
+        catch (UniformInterfaceException uie ) {
+            responseStatus = uie.getResponse().getStatus();
+        }
+        assertEquals(UNAUTHORIZED_STATUS, responseStatus);
+    }
+
+    @Test
+    public void testFoursquareAuthNoCredentials(){
+
+        int responseStatus = 0;
+
+        try {
+            // intentionally do not add access_token
+            resource().path(BASE_PATH + "/auth/foursquare")
+                .accept(MediaType.APPLICATION_JSON_TYPE)
+                .get(JsonNode.class);
+        }
+        catch (UniformInterfaceException uie ) {
+            responseStatus = uie.getResponse().getStatus();
+        }
+        assertEquals(UNAUTHORIZED_STATUS, responseStatus);
+    }
+
+    @Test
+    public void testQueuesNoCredentials(){
+
+        int responseStatus = 0;
+
+        try {
+            // intentionally do not add access_token
+            resource().path(BASE_PATH + "/queues")
+                .accept(MediaType.APPLICATION_JSON_TYPE)
+                .get(JsonNode.class);
+        }
+        catch (UniformInterfaceException uie ) {
+            responseStatus = uie.getResponse().getStatus();
+        }
+        assertEquals(UNAUTHORIZED_STATUS, responseStatus);
+    }
+
+}


Mime
View raw message