Repository: usergrid
Updated Branches:
  refs/heads/release-2.1.1 cdb92aa7e -> 7fdca3d24


Ensure that /org/app/users/me always works for logged in user, regardless of 
roles/permissions, also that it is impossible to create an app or admin user 
named 'me'


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

Branch: refs/heads/release-2.1.1
Commit: c7c7c8cd240a788b8cd3cf317590c23b9373385d
Parents: 29e940e
Author: Dave Johnson <snoopd...@apache.org>
Authored: Mon May 9 14:58:18 2016 -0400
Committer: Dave Johnson <snoopd...@apache.org>
Committed: Mon May 9 14:58:18 2016 -0400

----------------------------------------------------------------------
 .../rest/applications/users/UserResource.java   |   9 ++
 .../rest/applications/users/UsersResource.java  |   9 ++
 .../rest/management/users/UserResource.java     |   4 +
 .../rest/management/users/UsersResource.java    |   4 +
 .../security/SecuredResourceFilterFactory.java  |  14 ++-
 .../usergrid/rest/applications/SecurityIT.java  |   1 -
 .../collection/users/PermissionsResourceIT.java | 125 +++++++++++++++++--
 .../test/resource/endpoints/NamedResource.java  |   8 +-
 .../principals/ApplicationUserPrincipal.java    |  13 +-
 9 files changed, 165 insertions(+), 22 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/usergrid/blob/c7c7c8cd/stack/rest/src/main/java/org/apache/usergrid/rest/applications/users/UserResource.java
----------------------------------------------------------------------
diff --git 
a/stack/rest/src/main/java/org/apache/usergrid/rest/applications/users/UserResource.java
 
b/stack/rest/src/main/java/org/apache/usergrid/rest/applications/users/UserResource.java
index 373bf09..5435f7e 100644
--- 
a/stack/rest/src/main/java/org/apache/usergrid/rest/applications/users/UserResource.java
+++ 
b/stack/rest/src/main/java/org/apache/usergrid/rest/applications/users/UserResource.java
@@ -117,6 +117,11 @@ public class UserResource extends ServiceResource {
         Map<String, Object> json = mapper.readValue( body, mapTypeReference );
 
         if ( json != null ) {
+
+            if ( "me".equals( json.get("username") ) ) {
+                throw new IllegalArgumentException( "Username 'me' is 
reserved" );
+            }
+
             json.remove( "password" );
             json.remove( "pin" );
         }
@@ -225,6 +230,10 @@ public class UserResource extends ServiceResource {
             return null;
         }
 
+        if ( "me".equals( json.get("username") ) ) {
+            throw new IllegalArgumentException( "Username 'me' is reserved" );
+        }
+
         ApiResponse response = createApiResponse();
         response.setAction( "set user credentials" );
 

http://git-wip-us.apache.org/repos/asf/usergrid/blob/c7c7c8cd/stack/rest/src/main/java/org/apache/usergrid/rest/applications/users/UsersResource.java
----------------------------------------------------------------------
diff --git 
a/stack/rest/src/main/java/org/apache/usergrid/rest/applications/users/UsersResource.java
 
b/stack/rest/src/main/java/org/apache/usergrid/rest/applications/users/UsersResource.java
index 34c6915..247df8a 100644
--- 
a/stack/rest/src/main/java/org/apache/usergrid/rest/applications/users/UsersResource.java
+++ 
b/stack/rest/src/main/java/org/apache/usergrid/rest/applications/users/UsersResource.java
@@ -192,6 +192,10 @@ public class UsersResource extends ServiceResource {
         ObjectMapper mapper = new ObjectMapper();
         Map<String, Object> json = mapper.readValue( body, mapTypeReference );
 
+        if ( "me".equals( json.get("username") ) ) {
+            throw new IllegalArgumentException( "Username 'me' is reserved" );
+        }
+
         User user = getUser();
         if ( user == null ) {
             return executePost( ui, body, callback );
@@ -233,6 +237,11 @@ public class UsersResource extends ServiceResource {
 
         if ( json instanceof Map ) {
             @SuppressWarnings("unchecked") Map<String, Object> map = ( 
Map<String, Object> ) json;
+
+            if ( "me".equals( map.get("username") ) ) {
+                throw new IllegalArgumentException( "Username 'me' is 
reserved" );
+            }
+
             password = ( String ) map.get( "password" );
             map.remove( "password" );
             pin = ( String ) map.get( "pin" );

http://git-wip-us.apache.org/repos/asf/usergrid/blob/c7c7c8cd/stack/rest/src/main/java/org/apache/usergrid/rest/management/users/UserResource.java
----------------------------------------------------------------------
diff --git 
a/stack/rest/src/main/java/org/apache/usergrid/rest/management/users/UserResource.java
 
b/stack/rest/src/main/java/org/apache/usergrid/rest/management/users/UserResource.java
index ce79adf..28d46a6 100644
--- 
a/stack/rest/src/main/java/org/apache/usergrid/rest/management/users/UserResource.java
+++ 
b/stack/rest/src/main/java/org/apache/usergrid/rest/management/users/UserResource.java
@@ -111,6 +111,10 @@ public class UserResource extends AbstractContextResource {
         String username = string( json.remove( "username" ) );
         String name = string( json.remove( "name" ) );
 
+        if ( "me".equals( username ) ) {
+            throw new IllegalArgumentException( "Username 'me' is reserved" );
+        }
+
         management.updateAdminUser( user, username, name, email, json );
 
         ApiResponse response = createApiResponse();

http://git-wip-us.apache.org/repos/asf/usergrid/blob/c7c7c8cd/stack/rest/src/main/java/org/apache/usergrid/rest/management/users/UsersResource.java
----------------------------------------------------------------------
diff --git 
a/stack/rest/src/main/java/org/apache/usergrid/rest/management/users/UsersResource.java
 
b/stack/rest/src/main/java/org/apache/usergrid/rest/management/users/UsersResource.java
index e57e5ef..ff279ef 100644
--- 
a/stack/rest/src/main/java/org/apache/usergrid/rest/management/users/UsersResource.java
+++ 
b/stack/rest/src/main/java/org/apache/usergrid/rest/management/users/UsersResource.java
@@ -127,6 +127,10 @@ public class UsersResource extends AbstractContextResource 
{
             throw new IllegalArgumentException( "email form parameter is 
required" );
         }
 
+        if ( "me".equals( username ) ) {
+            throw new IllegalArgumentException( "Username 'me' is reserved" );
+        }
+
         // if username not provided, email will be used
         logger.info( "Create user: {}", (StringUtils.isNotBlank(username) ? 
username : email) );
 

http://git-wip-us.apache.org/repos/asf/usergrid/blob/c7c7c8cd/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 4c7d26a..67cf248 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
@@ -409,9 +409,10 @@ public class SecuredResourceFilterFactory implements 
DynamicFeature {
                 logger.debug( "PathPermissionsFilter.authorize" );
             }
 
-            final String PATH_MSG =
-                "---- Checked permissions for path 
--------------------------------------------\n" + "Requested path: {} \n"
-                    + "Requested action: {} \n" + "Requested permission: {} 
\n" + "Permitted: {} \n";
+            final String PATH_MSG = "---- Checked permissions for path 
--------------------------------------------\n"
+                + "Requested path: {} \n"
+                + "Requested action: {} \n" + "Requested permission: {} \n"
+                + "Permitted: {} \n";
 
             ApplicationInfo application = null;
 
@@ -449,6 +450,12 @@ public class SecuredResourceFilterFactory implements 
DynamicFeature {
                 String path = 
request.getUriInfo().getPath().toLowerCase().replace(applicationName, "");
                 String perm =  getPermissionFromPath( 
em.getApplicationRef().getUuid(), operation, path );
 
+                if ( "/users/me".equals( path ) ) {
+                    // shortcut the permissions checking, the "me" end-point 
is always allowed
+                    logger.debug("Allowing {} access to /users/me", 
getSubject().toString() );
+                    return;
+                }
+
                 boolean permitted = currentUser.isPermitted( perm );
                 if ( logger.isDebugEnabled() ) {
                     logger.debug( PATH_MSG, path, operation, perm, permitted );
@@ -462,7 +469,6 @@ public class SecuredResourceFilterFactory implements 
DynamicFeature {
                     
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/c7c7c8cd/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
index f64afe8..cbc8e38 100644
--- 
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
@@ -17,7 +17,6 @@
 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;

http://git-wip-us.apache.org/repos/asf/usergrid/blob/c7c7c8cd/stack/rest/src/test/java/org/apache/usergrid/rest/applications/collection/users/PermissionsResourceIT.java
----------------------------------------------------------------------
diff --git 
a/stack/rest/src/test/java/org/apache/usergrid/rest/applications/collection/users/PermissionsResourceIT.java
 
b/stack/rest/src/test/java/org/apache/usergrid/rest/applications/collection/users/PermissionsResourceIT.java
index 9f6c4e4..b0b3791 100644
--- 
a/stack/rest/src/test/java/org/apache/usergrid/rest/applications/collection/users/PermissionsResourceIT.java
+++ 
b/stack/rest/src/test/java/org/apache/usergrid/rest/applications/collection/users/PermissionsResourceIT.java
@@ -17,21 +17,25 @@
 package org.apache.usergrid.rest.applications.collection.users;
 
 
-import java.util.List;
-import java.util.UUID;
-
 import net.jcip.annotations.NotThreadSafe;
+import org.apache.commons.lang.RandomStringUtils;
 import org.apache.usergrid.rest.test.resource.AbstractRestIT;
 import org.apache.usergrid.rest.test.resource.model.*;
-import 
org.apache.usergrid.services.exceptions.ServiceResourceNotFoundException;
 import org.apache.usergrid.utils.UUIDUtils;
-
 import org.junit.Before;
 import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
+import javax.ws.rs.BadRequestException;
 import javax.ws.rs.ClientErrorException;
+import javax.ws.rs.core.Form;
 import javax.ws.rs.core.Response;
 import java.io.IOException;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
 
 import static org.junit.Assert.*;
 
@@ -41,6 +45,7 @@ import static org.junit.Assert.*;
  */
 @NotThreadSafe
 public class PermissionsResourceIT extends AbstractRestIT {
+    private static final Logger logger = 
LoggerFactory.getLogger(PermissionsResourceIT.class);
 
     private static final String ROLE = "permtestrole";
 
@@ -562,18 +567,19 @@ public class PermissionsResourceIT extends AbstractRestIT 
{
      * @throws IOException
      */
     private void addPermission(  String rolename, String grant ) throws 
IOException {
-        //Create and post the permissions
+
+        // Create and post the permissions
         Entity props = new Entity().chainPut("permission", grant);
 
         
this.app().collection("roles").entity(rolename).collection("permissions").post(props);
 
-        //Checks that the permissions were added correctly
+        // Checks that the permissions were added correctly
         Collection node = 
this.app().collection("roles").entity(rolename).collection("permissions").get();
 
         List<Object> data =(List) node.getResponse().getData();
 
-        for(Object o : data){
-            if(grant.equals(o.toString())){
+        for ( Object o : data ) {
+            if ( grant.equals(o.toString()) ) {
                 return;
             }
         }
@@ -582,4 +588,105 @@ public class PermissionsResourceIT extends AbstractRestIT 
{
     }
 
 
+    @Test
+    public void testUsersMeAlwaysAvailable() {
+
+        // delete default roles/permissions from app
+
+        app().collection("roles").entity("default").delete();
+
+        // create an app user, get token (and switch context to that of user)
+
+        Token token = null;
+        try {
+            String password = "s3cr3t";
+            Entity newUser = app().collection( "users" ).post(
+                new User( "dave", "Dave Johnson", "d...@example.com", password 
) );
+            token = app().token().post(
+                new Token( "password", (String)newUser.get("username") , 
password ));
+
+        } catch ( Exception e ) {
+            logger.error( "Error creating user and logging in: {}", e);
+        }
+        assertNotNull( token );
+
+        // user cannot post to a collection
+
+        try {
+            Map<String, Object> catMap = new HashMap<String, Object>() {{
+                put("name", "enzo");
+                put("color", "orange");
+            }};
+            app().collection( "cats" ).post( true, token, ApiResponse.class, 
catMap, null, false );
+            fail("Post should have failed");
+        } catch ( Exception expected ) {}
+
+        // but the /users/me end-point should work
+
+        Entity me = app().collection( "users" ).entity( "me" ).get();
+        assertNotNull( me );
+
+        try {
+            app().collection( "users" ).entity( "me" ).delete();
+            fail("Delete /users/me must fail");
+        } catch ( Exception expected ) {}
+    }
+
+
+    @Test
+    public void testAppUserNamedMeNotAllowed() {
+
+        // cannot create app user named me
+        try {
+            app().collection( "users" ).post( new User( "me", "it's me", 
"m...@example.com", "me!" ) );
+            fail("Must not be able to create app user named me");
+        } catch ( BadRequestException expected ) {}
+
+        // cannot use update to rename app user to me
+        Entity user = app().collection( "users" ).post( new User( "dave", 
"Sneaky Me", "m...@example.com", "me!" ) );
+        try {
+            app().collection( "users" ).entity( user ).put( new 
Entity().chainPut( "username", "me" ));
+            fail("Must not be able to update app user to name me");
+
+        } catch ( BadRequestException expected ) {}
+
+    }
+
+
+    @Test
+    public void testAdminUserNamedMeNotAllowed() {
+
+        // cannot create admin user named me
+        try {
+            Form form = new Form();
+            form.param( "username", "me" );
+            form.param( "email", "m...@example.com");
+            form.param( "name", "me Me ME!");
+            form.param( "password", "me me 123" );
+            management().users().post( ApiResponse.class, form );
+
+            fail("Must not be able to create admin user named me");
+
+        } catch ( BadRequestException expected ) {}
+
+        // cannot use update to rename admin user to me
+        String randomString = RandomStringUtils.randomAlphanumeric( 10 );
+        String username = "user_" + randomString;
+        String password = "me me 123";
+        Form form = new Form();
+        form.param( "username", username );
+        form.param( "email", username + "@example.com");
+        form.param( "name", "Despicable me");
+        form.param( "password", password );
+        management().users().post( ApiResponse.class, form );
+        management().token().get( username, password );
+
+        try {
+            management().users().user( username ).put( true, new 
Entity().chainPut( "username", "me" ) );
+            fail("Must not be able to create admin user named me");
+
+        } catch ( BadRequestException e ) {}
+
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/usergrid/blob/c7c7c8cd/stack/rest/src/test/java/org/apache/usergrid/rest/test/resource/endpoints/NamedResource.java
----------------------------------------------------------------------
diff --git 
a/stack/rest/src/test/java/org/apache/usergrid/rest/test/resource/endpoints/NamedResource.java
 
b/stack/rest/src/test/java/org/apache/usergrid/rest/test/resource/endpoints/NamedResource.java
index a2377d4..ad014d9 100644
--- 
a/stack/rest/src/test/java/org/apache/usergrid/rest/test/resource/endpoints/NamedResource.java
+++ 
b/stack/rest/src/test/java/org/apache/usergrid/rest/test/resource/endpoints/NamedResource.java
@@ -283,7 +283,7 @@ public class NamedResource implements UrlResource {
 
         if (useBasicAuthentication) {
             HttpAuthenticationFeature feature = 
HttpAuthenticationFeature.basicBuilder()
-                                                                         
.credentials("superuser", "superpassword").build();
+                .credentials("superuser", "superpassword").build();
             return resource.register(feature).request()
                            .accept(MediaType.APPLICATION_JSON)
                            .post(javax.ws.rs.client.Entity.json(entity), gt);
@@ -343,6 +343,12 @@ public class NamedResource implements UrlResource {
             javax.ws.rs.client.Entity.entity(data, type), ApiResponse.class);
     }
 
+    public ApiResponse put(boolean useToken, 
org.apache.usergrid.rest.test.resource.model.Entity entity ) {
+        WebTarget resource = getTarget(useToken);
+        return resource.request().put(
+            javax.ws.rs.client.Entity.entity(entity, 
MediaType.APPLICATION_JSON_TYPE), ApiResponse.class);
+    }
+
     public ApiResponse put(byte[] data, MediaType type) {
         return put(true, data, type);
     }

http://git-wip-us.apache.org/repos/asf/usergrid/blob/c7c7c8cd/stack/services/src/main/java/org/apache/usergrid/security/shiro/principals/ApplicationUserPrincipal.java
----------------------------------------------------------------------
diff --git 
a/stack/services/src/main/java/org/apache/usergrid/security/shiro/principals/ApplicationUserPrincipal.java
 
b/stack/services/src/main/java/org/apache/usergrid/security/shiro/principals/ApplicationUserPrincipal.java
index 65503b4..41c84ae 100644
--- 
a/stack/services/src/main/java/org/apache/usergrid/security/shiro/principals/ApplicationUserPrincipal.java
+++ 
b/stack/services/src/main/java/org/apache/usergrid/security/shiro/principals/ApplicationUserPrincipal.java
@@ -33,12 +33,14 @@ import org.apache.usergrid.persistence.entities.User;
 import org.apache.usergrid.security.shiro.Realm;
 import org.apache.usergrid.security.shiro.UsergridAuthorizationInfo;
 import org.apache.usergrid.security.shiro.credentials.AccessTokenCredentials;
+import org.apache.usergrid.security.shiro.utils.SubjectUtils;
 import org.apache.usergrid.security.tokens.TokenInfo;
 import org.apache.usergrid.security.tokens.TokenService;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import static 
org.apache.usergrid.security.shiro.utils.SubjectUtils.getPermissionFromPath;
+import static org.apache.usergrid.security.shiro.utils.SubjectUtils.getSubject;
 
 
 public class ApplicationUserPrincipal extends UserPrincipal {
@@ -94,13 +96,10 @@ public class ApplicationUserPrincipal extends UserPrincipal 
{
 
         grant( info, getPermissionFromPath( applicationId, "access" ) );
 
-                /*
-                 * grant(info, principal, getPermissionFromPath(applicationId,
-                 * "get,put,post,delete", "/users/${user}",
-                 * "/users/${user}/feed", "/users/${user}/activities",
-                 * "/users/${user}/groups", "/users/${user}/following/*",
-                 * "/users/${user}/following/user/*"));
-                 */
+        if ( SubjectUtils.getUser() != null ) {
+            // ensure that the /org/app/users/me end-point always works for 
logged in user
+            grant( info, "applications:get:" + applicationId + ":/users/" + 
SubjectUtils.getUser().getUuid() );
+        }
 
         EntityManager em = emf.getEntityManager( applicationId );
         try {

Reply via email to