You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@usergrid.apache.org by mr...@apache.org on 2015/12/05 02:43:56 UTC

usergrid git commit: Add additional functionality in REST layer for checking permissions.

Repository: usergrid
Updated Branches:
  refs/heads/release 29bba2433 -> fdc0d8081


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/fdc0d808
Tree: http://git-wip-us.apache.org/repos/asf/usergrid/tree/fdc0d808
Diff: http://git-wip-us.apache.org/repos/asf/usergrid/diff/fdc0d808

Branch: refs/heads/release
Commit: fdc0d80814c7a69615964c5c85429ede003b6dbf
Parents: 29bba24
Author: Michael Russo <mi...@gmail.com>
Authored: Fri Dec 4 17:43:19 2015 -0800
Committer: Michael Russo <mi...@gmail.com>
Committed: Fri Dec 4 17:43:19 2015 -0800

----------------------------------------------------------------------
 .../shard/impl/NodeShardAllocationImpl.java     |   2 +-
 .../rest/applications/ApplicationResource.java  |   1 +
 .../rest/applications/AuthResource.java         |  10 +-
 .../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  |  75 ++++++++++--
 .../annotations/CheckPermissionsForPath.java    |  32 ++++++
 .../usergrid/rest/applications/SecurityIT.java  | 113 +++++++++++++++++++
 11 files changed, 249 insertions(+), 15 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/usergrid/blob/fdc0d808/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/serialization/impl/shard/impl/NodeShardAllocationImpl.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/serialization/impl/shard/impl/NodeShardAllocationImpl.java b/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/serialization/impl/shard/impl/NodeShardAllocationImpl.java
index d52f807..62274ec 100644
--- a/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/serialization/impl/shard/impl/NodeShardAllocationImpl.java
+++ b/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/serialization/impl/shard/impl/NodeShardAllocationImpl.java
@@ -199,7 +199,7 @@ public class NodeShardAllocationImpl implements NodeShardAllocation {
 
 
         if ( !edges.hasNext() ) {
-            LOG.warn(
+            LOG.trace(
                 "Tried to allocate a new shard for edge meta data {}, " + "but no max value could be found in that row",
                 directedEdgeMeta );
             return false;

http://git-wip-us.apache.org/repos/asf/usergrid/blob/fdc0d808/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 162565f..cfcc9b6 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
@@ -113,6 +113,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/fdc0d808/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..d90a44c 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;
@@ -84,9 +85,8 @@ public class AuthResource extends AbstractContextResource {
         }
     }
 
-    // TODO add auth for Ping Identity
-
 
+    @CheckPermissionsForPath
     @POST
     @Path("facebook")
     @Consumes(APPLICATION_FORM_URLENCODED)
@@ -100,6 +100,7 @@ public class AuthResource extends AbstractContextResource {
     }
 
 
+    @CheckPermissionsForPath
     @GET
     @Path("pingident")
     public Response authPingIdent( @Context UriInfo ui, @QueryParam("ping_access_token") String pingToken,
@@ -132,6 +133,7 @@ public class AuthResource extends AbstractContextResource {
     }
 
 
+    @CheckPermissionsForPath
     @POST
     @Path("pingident")
     public Response authPingIdentPost( @Context UriInfo ui, @QueryParam("ping_access_token") String pingToken,
@@ -169,7 +171,7 @@ public class AuthResource extends AbstractContextResource {
                        .entity( wrapJSONPResponse( callback, response.getBody() ) ).build();
     }
 
-
+    @CheckPermissionsForPath
     @GET
     @Path("facebook")
     public Response authFB( @Context UriInfo ui, @QueryParam("fb_access_token") String fb_access_token,
@@ -204,6 +206,7 @@ public class AuthResource extends AbstractContextResource {
     }
 
 
+    @CheckPermissionsForPath
     @POST
     @Path("foursquare")
     @Consumes(APPLICATION_FORM_URLENCODED)
@@ -217,6 +220,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/fdc0d808/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 fedffc4..f748ee9 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
@@ -24,6 +24,7 @@ import org.apache.usergrid.persistence.EntityManager;
 import org.apache.usergrid.persistence.entities.Asset;
 import org.apache.usergrid.rest.AbstractContextResource;
 import org.apache.usergrid.rest.applications.ServiceResource;
+import org.apache.usergrid.rest.security.annotations.CheckPermissionsForPath;
 import org.apache.usergrid.rest.security.annotations.RequireApplicationAccess;
 import org.apache.usergrid.services.assets.data.AssetUtils;
 import org.apache.usergrid.services.assets.data.AwsSdkS3BinaryStore;
@@ -103,8 +104,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,
@@ -133,8 +134,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 )
@@ -143,8 +144,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 )
@@ -169,6 +170,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/fdc0d808/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/fdc0d808/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/fdc0d808/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/fdc0d808/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/fdc0d808/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 6f7d698..d867e1b 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,11 +52,8 @@ 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.Realm.ROLE_SERVICE_ADMIN;
+import static org.apache.usergrid.security.shiro.utils.SubjectUtils.*;
 
 
 @Component
@@ -132,6 +127,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;
     }
 
@@ -331,4 +329,65 @@ 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/fdc0d808/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/fdc0d808/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..c5b06b5
--- /dev/null
+++ b/stack/rest/src/test/java/org/apache/usergrid/rest/applications/SecurityIT.java
@@ -0,0 +1,113 @@
+/*
+ * 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.test.resource.AbstractRestIT;
+import org.apache.usergrid.rest.test.resource.model.ApiResponse;
+import org.apache.usergrid.utils.UUIDUtils;
+import org.junit.Test;
+
+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 {
+
+    public SecurityIT() throws Exception {}
+
+    @Test
+    public void testAssetsNoCredentials(){
+
+        final UUID uuid = UUIDUtils.newTimeUUID();
+        try {
+            //use false in get() for no token
+            this.pathResource(getOrgAppPath("assets/" + uuid + "/data")).get(ApiResponse.class, false);
+
+        } catch (UniformInterfaceException ui){
+            assertEquals(401, ui.getResponse().getStatus());
+        }
+    }
+
+
+    @Test
+    public void testFacebookAuthNoCredentials(){
+
+        int responseStatus = 0;
+        try {
+            //use false in get() for no token
+            this.pathResource(getOrgAppPath("auth/facebook")).get(ApiResponse.class, false);
+
+        } catch (UniformInterfaceException ui){
+            responseStatus = ui.getResponse().getStatus();
+
+        }
+        assertEquals(401, responseStatus);
+    }
+
+    @Test
+    public void testPingIdentityAuthNoCredentials(){
+
+        int responseStatus = 0;
+        try {
+            //use false in get() for no token
+            this.pathResource(getOrgAppPath("auth/pingident")).get(ApiResponse.class, false);
+
+        } catch (UniformInterfaceException ui){
+            responseStatus = ui.getResponse().getStatus();
+        }
+        assertEquals(401, responseStatus);
+
+    }
+
+    @Test
+    public void testFoursquareAuthNoCredentials(){
+
+        int responseStatus = 0;
+        try {
+            //use false in get() for no token
+            this.pathResource(getOrgAppPath("auth/foursquare")).get(ApiResponse.class, false);
+
+        } catch (UniformInterfaceException ui){
+            responseStatus = ui.getResponse().getStatus();
+        }
+        assertEquals(401, responseStatus);
+
+    }
+
+    @Test
+    public void testQueuesNoCredentials(){
+
+        int responseStatus = 0;
+        try {
+            //use false in get() for no token
+            this.pathResource(getOrgAppPath("queues")).get(ApiResponse.class, false);
+
+        } catch (UniformInterfaceException ui){
+            responseStatus = ui.getResponse().getStatus();
+        }
+        assertEquals(401, responseStatus);
+
+    }
+
+
+}