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/04 18:52:32 UTC

[1/2] usergrid git commit: Add additional functionality in REST layer for checking permissions.

Repository: usergrid
Updated Branches:
  refs/heads/rest-fixes [created] b1e11e38a


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

Branch: refs/heads/rest-fixes
Commit: 7ddf0f46e0b33951bd2fa534f2cb100b6b93b48e
Parents: 65ed997
Author: Michael Russo <mi...@gmail.com>
Authored: Fri Dec 4 00:42:17 2015 -0800
Committer: Michael Russo <mi...@gmail.com>
Committed: Fri Dec 4 00:42:17 2015 -0800

----------------------------------------------------------------------
 .../cassandra/EntityManagerImpl.java            | 107 ++++++++++---------
 .../rest/applications/ApplicationResource.java  |   2 +
 .../rest/applications/AuthResource.java         |  11 +-
 .../applications/assets/AssetsResource.java     |   8 +-
 .../rest/applications/queues/QueueResource.java |  12 ++-
 .../queues/QueueSubscriberResource.java         |   5 +
 .../queues/QueueSubscriptionResource.java       |   5 +
 .../queues/QueueTransactionsResource.java       |   3 +
 .../security/SecuredResourceFilterFactory.java  |  74 +++++++++++--
 .../annotations/CheckPermissionsForPath.java    |  32 ++++++
 10 files changed, 190 insertions(+), 69 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/usergrid/blob/7ddf0f46/stack/core/src/main/java/org/apache/usergrid/persistence/cassandra/EntityManagerImpl.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/persistence/cassandra/EntityManagerImpl.java b/stack/core/src/main/java/org/apache/usergrid/persistence/cassandra/EntityManagerImpl.java
index ec99d53..0dd1b93 100644
--- a/stack/core/src/main/java/org/apache/usergrid/persistence/cassandra/EntityManagerImpl.java
+++ b/stack/core/src/main/java/org/apache/usergrid/persistence/cassandra/EntityManagerImpl.java
@@ -546,19 +546,20 @@ public class EntityManagerImpl implements EntityManager {
                 cass.getColumns( cass.getApplicationKeyspace( applicationId ), ENTITY_UNIQUE, key, null, null, 2,
                         false );
 
+// TEMPORARY REMOVAL OF READ REPAIR
 
         //check to see if the single value is valid. If it is not valid then it will be zero and go through
         //the code below.
-        if(cols.size() == 1){
-            logger.debug("Verifying that column is still valid, if not will be removed");
-            UUID indexCorruptionUuid = ue.fromByteBuffer( cols.get( 0 ).getName());
-
-            if (get(indexCorruptionUuid) == null ) {
-                logger.debug( "Deleting the following uuid: {} from the application: {}",indexCorruptionUuid,applicationId );
-                deleteUniqueColumn( ownerEntityId, key, indexCorruptionUuid );
-                cols.remove( 0 );
-            }
-        }
+//        if(cols.size() == 1){
+//            logger.debug("Verifying that column is still valid, if not will be removed");
+//            UUID indexCorruptionUuid = ue.fromByteBuffer( cols.get( 0 ).getName());
+//
+//            if (get(indexCorruptionUuid) == null ) {
+//                logger.debug( "Deleting the following uuid: {} from the application: {}",indexCorruptionUuid,applicationId );
+//                deleteUniqueColumn( ownerEntityId, key, indexCorruptionUuid );
+//                cols.remove( 0 );
+//            }
+//        }
 
         //No columns at all, it's unique
         if ( cols.size() == 0 ) {
@@ -572,48 +573,50 @@ public class EntityManagerImpl implements EntityManager {
                     + "property {} with value {}",
                     new Object[] { ownerEntityId, collectionNameInternal, propertyName, propertyValue } );
 
-            //retrieve ALL DA columns.
-            List<HColumn<ByteBuffer, ByteBuffer>> indexingColumns = cass.getAllColumns( cass.getApplicationKeyspace( applicationId ),ENTITY_UNIQUE,key,be,be );
-
-
-            //Contains entities that weren't deleted but are still in index.
-            //maybe use a set or list so you don't have to keep track of an index.
-            Entity[] entities = new Entity[indexingColumns.size()];
-            int index = 0;
-
-            for ( HColumn<ByteBuffer, ByteBuffer> col : indexingColumns ) {
-                UUID indexCorruptionUuid = ue.fromByteBuffer( col.getName());
-
-                entities[index] = get(indexCorruptionUuid);
-
-                if (entities[index] == null ) {
-                    logger.debug("deleting uuid: {} from {} because it no longer exists.",indexCorruptionUuid,ownerEntityId);
-                    deleteUniqueColumn( ownerEntityId, key, indexCorruptionUuid );
-                }
-                else{
-                    index++;
-                }
-            }
-            //this means that the same unique rowkey has two values associated with it
-            if(index>1){
-                Entity mostRecentEntity = entities[0];
-                for(Entity entity: entities){
-                    if(mostRecentEntity.getModified() > entity.getModified()){
-                        deleteEntity( entity.getUuid() );
-                        logger.info( "Deleting " + entity.getUuid().toString()
-                                + " because it shares older unique value with: " + propertyValue );
-                    }
-                    else if (mostRecentEntity.getModified() < entity.getModified()){
-                        logger.info("Deleting "+mostRecentEntity.getUuid().toString()+" because it shares older unique value with: "+propertyValue);
-                        deleteEntity( mostRecentEntity.getUuid() );
-                        mostRecentEntity = entity;
-                    }
-                    else if (mostRecentEntity.getModified() == entity.getModified() && !mostRecentEntity.getUuid().equals( entity.getUuid() )){
-                        logger.error("Entities with unique value: "+propertyValue+" has two or more entities with the same modified time."
-                                + "Please manually resolve by query or changing names. ");
-                    }
-                }
-            }
+// TEMPORARY REMOVAL OF READ REPAIR
+
+//            //retrieve ALL DA columns.
+//            List<HColumn<ByteBuffer, ByteBuffer>> indexingColumns = cass.getAllColumns( cass.getApplicationKeyspace( applicationId ),ENTITY_UNIQUE,key,be,be );
+//
+//
+//            //Contains entities that weren't deleted but are still in index.
+//            //maybe use a set or list so you don't have to keep track of an index.
+//            Entity[] entities = new Entity[indexingColumns.size()];
+//            int index = 0;
+//
+//            for ( HColumn<ByteBuffer, ByteBuffer> col : indexingColumns ) {
+//                UUID indexCorruptionUuid = ue.fromByteBuffer( col.getName());
+//
+//                entities[index] = get(indexCorruptionUuid);
+//
+//                if (entities[index] == null ) {
+//                    logger.debug("deleting uuid: {} from {} because it no longer exists.",indexCorruptionUuid,ownerEntityId);
+//                    deleteUniqueColumn( ownerEntityId, key, indexCorruptionUuid );
+//                }
+//                else{
+//                    index++;
+//                }
+//            }
+//            //this means that the same unique rowkey has two values associated with it
+//            if(index>1){
+//                Entity mostRecentEntity = entities[0];
+//                for(Entity entity: entities){
+//                    if(mostRecentEntity.getModified() > entity.getModified()){
+//                        deleteEntity( entity.getUuid() );
+//                        logger.info( "Deleting " + entity.getUuid().toString()
+//                                + " because it shares older unique value with: " + propertyValue );
+//                    }
+//                    else if (mostRecentEntity.getModified() < entity.getModified()){
+//                        logger.info("Deleting "+mostRecentEntity.getUuid().toString()+" because it shares older unique value with: "+propertyValue);
+//                        deleteEntity( mostRecentEntity.getUuid() );
+//                        mostRecentEntity = entity;
+//                    }
+//                    else if (mostRecentEntity.getModified() == entity.getModified() && !mostRecentEntity.getUuid().equals( entity.getUuid() )){
+//                        logger.error("Entities with unique value: "+propertyValue+" has two or more entities with the same modified time."
+//                                + "Please manually resolve by query or changing names. ");
+//                    }
+//                }
+//            }
         }
 
         cols = cass.getColumns( cass.getApplicationKeyspace( applicationId ), ENTITY_UNIQUE, key, null, null, 2,

http://git-wip-us.apache.org/repos/asf/usergrid/blob/7ddf0f46/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 a1c8d11..0ebe6b8 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
@@ -38,6 +38,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.context.annotation.Scope;
@@ -126,6 +127,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/7ddf0f46/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..2ea5b36 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,
@@ -203,7 +205,7 @@ public class AuthResource extends AbstractContextResource {
         }
     }
 
-
+    @CheckPermissionsForPath
     @POST
     @Path("foursquare")
     @Consumes(APPLICATION_FORM_URLENCODED)
@@ -217,6 +219,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/7ddf0f46/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 9370d7f..55bcd80 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
@@ -38,6 +38,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;
@@ -104,8 +105,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,
@@ -126,8 +127,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 )
@@ -136,8 +137,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 )
@@ -155,6 +156,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/7ddf0f46/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..4aca745 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;
@@ -85,7 +86,7 @@ public class QueueResource extends AbstractContextResource {
         return getSubResource( QueueResource.class ).init( mq, queuePath + "/" + subPath );
     }
 
-
+    @CheckPermissionsForPath
     @Path("subscribers")
     public QueueSubscriberResource getSubscribers( @Context UriInfo ui ) throws Exception {
 
@@ -95,6 +96,7 @@ public class QueueResource extends AbstractContextResource {
     }
 
 
+    @CheckPermissionsForPath
     @Path("subscriptions")
     public QueueSubscriptionResource getSubscriptions( @Context UriInfo ui ) throws Exception {
 
@@ -104,6 +106,7 @@ public class QueueResource extends AbstractContextResource {
     }
 
 
+    @CheckPermissionsForPath
     @Path("properties")
     @GET
     public JSONWithPadding getProperties( @Context UriInfo ui,
@@ -116,6 +119,7 @@ public class QueueResource extends AbstractContextResource {
     }
 
 
+    @CheckPermissionsForPath
     @Path("properties")
     @PUT
     @Consumes(MediaType.APPLICATION_JSON)
@@ -129,6 +133,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 +154,7 @@ public class QueueResource extends AbstractContextResource {
     }
 
 
+    @CheckPermissionsForPath
     @SuppressWarnings("unchecked")
     @POST
     @Consumes(MediaType.APPLICATION_JSON)
@@ -173,6 +179,7 @@ public class QueueResource extends AbstractContextResource {
     }
 
 
+    @CheckPermissionsForPath
     @PUT
     @Consumes(MediaType.APPLICATION_JSON)
     public JSONWithPadding executePut( @Context UriInfo ui, Map<String, Object> json,
@@ -187,6 +194,7 @@ public class QueueResource extends AbstractContextResource {
     }
 
 
+    @CheckPermissionsForPath
     @DELETE
     public JSONWithPadding executeDelete( @Context UriInfo ui,
                                           @QueryParam("callback") @DefaultValue("callback") String callback )
@@ -194,7 +202,7 @@ public class QueueResource extends AbstractContextResource {
         throw new NotImplementedException( "Queue delete is not implemented yet" );
     }
 
-
+    @CheckPermissionsForPath
     @Path("transactions")
     public QueueTransactionsResource getTransactions( @Context UriInfo ui ) throws Exception {
 

http://git-wip-us.apache.org/repos/asf/usergrid/blob/7ddf0f46/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/7ddf0f46/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/7ddf0f46/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/7ddf0f46/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 e0cb10d..428973f 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;
@@ -36,10 +38,6 @@ import org.apache.usergrid.persistence.EntityManager;
 import org.apache.usergrid.persistence.EntityManagerFactory;
 import org.apache.usergrid.persistence.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;
@@ -53,10 +51,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
@@ -129,6 +124,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;
     }
 
@@ -323,4 +321,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/7ddf0f46/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 {
+
+}


[2/2] usergrid git commit: Add additional tests for checking permissions.

Posted by mr...@apache.org.
Add additional tests 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/b1e11e38
Tree: http://git-wip-us.apache.org/repos/asf/usergrid/tree/b1e11e38
Diff: http://git-wip-us.apache.org/repos/asf/usergrid/diff/b1e11e38

Branch: refs/heads/rest-fixes
Commit: b1e11e38af16d21ac77139aacd697a3a159a793a
Parents: 7ddf0f4
Author: Michael Russo <mi...@gmail.com>
Authored: Fri Dec 4 09:52:28 2015 -0800
Committer: Michael Russo <mi...@gmail.com>
Committed: Fri Dec 4 09:52:28 2015 -0800

----------------------------------------------------------------------
 .../usergrid/rest/applications/SecurityIT.java  | 124 +++++++++++++++++++
 .../usergrid/services/ServiceRequestIT.java     |   5 +-
 2 files changed, 128 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/usergrid/blob/b1e11e38/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..825e30f
--- /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);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/usergrid/blob/b1e11e38/stack/services/src/test/java/org/apache/usergrid/services/ServiceRequestIT.java
----------------------------------------------------------------------
diff --git a/stack/services/src/test/java/org/apache/usergrid/services/ServiceRequestIT.java b/stack/services/src/test/java/org/apache/usergrid/services/ServiceRequestIT.java
index 846c58e..94be312 100644
--- a/stack/services/src/test/java/org/apache/usergrid/services/ServiceRequestIT.java
+++ b/stack/services/src/test/java/org/apache/usergrid/services/ServiceRequestIT.java
@@ -25,6 +25,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.UUID;
 
+import org.junit.Ignore;
 import org.junit.Rule;
 import org.junit.Test;
 import org.slf4j.Logger;
@@ -107,6 +108,7 @@ public class ServiceRequestIT {
     }
 
     //Verify that entity read repair is functioning as intended.
+    @Ignore("Temporarily disabled as read repair is disabled temporarily in EntityManagerImpl.")
     @Test
     public void testRepairOfSingleEntity() throws Exception{
         String rand = RandomStringUtils.randomAlphanumeric( 10 );
@@ -165,7 +167,7 @@ public class ServiceRequestIT {
 
     }
 
-
+    @Ignore("Temporarily disabled as read repair is disabled temporarily in EntityManagerImpl.")
     @Test
     public void testRepairOfOnlyOneOfTwoColumns() throws Exception{
         String rand = RandomStringUtils.randomAlphanumeric( 10 );
@@ -235,6 +237,7 @@ public class ServiceRequestIT {
     //For this test you need to insert a dummy key with a dummy column that leads to nowhere
     //then run the unique index cleanup.
     //checks for bug when only column doesn't exist make sure to delete the row as well.
+    @Ignore("Temporarily disabled as read repair is disabled temporarily in EntityManagerImpl.")
     @Test
     public void testRepairOfMultipleEntitiesAndRemainingEntities() throws Exception{
         String rand = RandomStringUtils.randomAlphanumeric( 10 );