From b1a75f065e05c68a1e03cd9f9a15cb8833e6e34b Mon Sep 17 00:00:00 2001 From: GERey Date: Thu, 16 Apr 2015 15:57:45 -0700 Subject: [PATCH 1/7] Removed older keyspaces mentions and then added in the two new ones --- .../persistence/cassandra/CassandraService.java | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/stack/core/src/main/java/org/apache/usergrid/persistence/cassandra/CassandraService.java b/stack/core/src/main/java/org/apache/usergrid/persistence/cassandra/CassandraService.java index 854c0ff2d1..cd819124cc 100644 --- a/stack/core/src/main/java/org/apache/usergrid/persistence/cassandra/CassandraService.java +++ b/stack/core/src/main/java/org/apache/usergrid/persistence/cassandra/CassandraService.java @@ -94,9 +94,12 @@ public class CassandraService { - public static String SYSTEM_KEYSPACE = "Usergrid"; +// public static String SYSTEM_KEYSPACE = "Usergrid"; +// +// public static String STATIC_APPLICATION_KEYSPACE = "Usergrid_Applications"; - public static String STATIC_APPLICATION_KEYSPACE = "Usergrid_Applications"; + public static String SYSTEM_KEYSPACE = System.getProperty( "cassandra.system.keyspace" ); + public static String STATIC_APPLICATION_KEYSPACE = System.getProperty( "cassandra.application.keyspace" ); public static final boolean USE_VIRTUAL_KEYSPACES = true; @@ -162,6 +165,12 @@ public void init() throws Exception { .setDefaultReadConsistencyLevel( HConsistencyLevel.ONE ); } accessMap = new HashMap( 2 ); + if ( SYSTEM_KEYSPACE == null ) { + SYSTEM_KEYSPACE = "Usergrid"; + } + if ( STATIC_APPLICATION_KEYSPACE == null) { + STATIC_APPLICATION_KEYSPACE = "Usergrid_Applications"; + } accessMap.put( "username", properties.getProperty( "cassandra.username" ) ); accessMap.put( "password", properties.getProperty( "cassandra.password" ) ); systemKeyspace = From f512fed8d5067ee038c7e7eb1947d44d4d17b3d2 Mon Sep 17 00:00:00 2001 From: GERey Date: Fri, 17 Apr 2015 09:14:02 -0700 Subject: [PATCH 2/7] Adding ability to customize keyspaces but if they aren't set then set them to default values. . --- .../cassandra/CassandraService.java | 20 +++++++------------ 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/stack/core/src/main/java/org/apache/usergrid/persistence/cassandra/CassandraService.java b/stack/core/src/main/java/org/apache/usergrid/persistence/cassandra/CassandraService.java index cd819124cc..43bfd2d1fb 100644 --- a/stack/core/src/main/java/org/apache/usergrid/persistence/cassandra/CassandraService.java +++ b/stack/core/src/main/java/org/apache/usergrid/persistence/cassandra/CassandraService.java @@ -94,13 +94,6 @@ public class CassandraService { -// public static String SYSTEM_KEYSPACE = "Usergrid"; -// -// public static String STATIC_APPLICATION_KEYSPACE = "Usergrid_Applications"; - - public static String SYSTEM_KEYSPACE = System.getProperty( "cassandra.system.keyspace" ); - public static String STATIC_APPLICATION_KEYSPACE = System.getProperty( "cassandra.application.keyspace" ); - public static final boolean USE_VIRTUAL_KEYSPACES = true; public static final String APPLICATIONS_CF = "Applications"; @@ -134,6 +127,9 @@ public class CassandraService { ConsistencyLevelPolicy consistencyLevelPolicy; + public static String SYSTEM_KEYSPACE; + public static String STATIC_APPLICATION_KEYSPACE; + private Keyspace systemKeyspace; private Map accessMap; @@ -159,18 +155,16 @@ public CassandraService( Properties properties, Cluster cluster, public void init() throws Exception { + SYSTEM_KEYSPACE = properties.getProperty( "cassandra.system.keyspace" ,"Usergrid"); + STATIC_APPLICATION_KEYSPACE = properties.getProperty( "cassandra.application.keyspace","Usergrid_Applications" ); + if ( consistencyLevelPolicy == null ) { consistencyLevelPolicy = new ConfigurableConsistencyLevel(); ( ( ConfigurableConsistencyLevel ) consistencyLevelPolicy ) .setDefaultReadConsistencyLevel( HConsistencyLevel.ONE ); } accessMap = new HashMap( 2 ); - if ( SYSTEM_KEYSPACE == null ) { - SYSTEM_KEYSPACE = "Usergrid"; - } - if ( STATIC_APPLICATION_KEYSPACE == null) { - STATIC_APPLICATION_KEYSPACE = "Usergrid_Applications"; - } + accessMap.put( "username", properties.getProperty( "cassandra.username" ) ); accessMap.put( "password", properties.getProperty( "cassandra.password" ) ); systemKeyspace = From 11709e05cc74abcadde0f817734ef04562237b41 Mon Sep 17 00:00:00 2001 From: Dave Johnson Date: Fri, 17 Apr 2015 18:23:00 -0400 Subject: [PATCH 3/7] Ensure that when external token validation is enabled, Admin Users cannot be created, activated or confirmed; plus a test. --- .../organizations/OrganizationsResource.java | 18 +++- .../rest/management/users/UserResource.java | 42 ++++++++ .../rest/management/users/UsersResource.java | 16 ++- .../rest/management/ManagementResourceIT.java | 22 ++-- .../management/users/MUUserResourceIT.java | 102 ++++++++++++++++-- 5 files changed, 179 insertions(+), 21 deletions(-) diff --git a/stack/rest/src/main/java/org/apache/usergrid/rest/management/organizations/OrganizationsResource.java b/stack/rest/src/main/java/org/apache/usergrid/rest/management/organizations/OrganizationsResource.java index 67c273f1df..e4e9edabc7 100644 --- a/stack/rest/src/main/java/org/apache/usergrid/rest/management/organizations/OrganizationsResource.java +++ b/stack/rest/src/main/java/org/apache/usergrid/rest/management/organizations/OrganizationsResource.java @@ -33,6 +33,7 @@ import javax.ws.rs.core.UriInfo; import org.apache.usergrid.rest.RootResource; +import org.apache.usergrid.rest.management.ManagementResource; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -111,9 +112,9 @@ public JSONWithPadding newOrganization( @Context UriInfo ui, Map String name = ( String ) json.remove( "name" ); String email = ( String ) json.remove( "email" ); String password = ( String ) json.remove( "password" ); - Map properties = ( Map ) json.remove( ORGANIZATION_PROPERTIES ); + Map orgProperties = ( Map ) json.remove( ORGANIZATION_PROPERTIES ); - return newOrganization( ui, organizationName, username, name, email, password, json, properties, callback ); + return newOrganization( ui, organizationName, username, name, email, password, json, orgProperties, callback ); } @@ -146,7 +147,16 @@ public JSONWithPadding newOrganizationFromForm( @Context UriInfo ui, /** Create a new organization */ private JSONWithPadding newOrganization( @Context UriInfo ui, String organizationName, String username, String name, String email, String password, Map userProperties, - Map properties, String callback ) throws Exception { + Map orgProperties, String callback ) throws Exception { + + final boolean externalTokensEnabled = + !StringUtils.isEmpty( properties.getProperty( ManagementResource.USERGRID_CENTRAL_URL ) ); + + if ( externalTokensEnabled ) { + throw new IllegalArgumentException( "Organization / Admin Users must be created via " + + properties.getProperty( ManagementResource.USERGRID_CENTRAL_URL ) ); + } + Preconditions .checkArgument( StringUtils.isNotBlank( organizationName ), "The organization parameter was missing" ); @@ -157,7 +167,7 @@ private JSONWithPadding newOrganization( @Context UriInfo ui, String organizatio OrganizationOwnerInfo organizationOwner = management .createOwnerAndOrganization( organizationName, username, name, email, password, false, false, - userProperties, properties ); + userProperties, orgProperties ); if ( organizationOwner == null ) { logger.info( "organizationOwner is null, returning. organization: {}", organizationName ); 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 49b0037045..de3928d7b5 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 @@ -33,6 +33,8 @@ import javax.ws.rs.core.MediaType; import javax.ws.rs.core.UriInfo; +import org.apache.commons.lang.StringUtils; +import org.apache.usergrid.rest.management.ManagementResource; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.context.annotation.Scope; @@ -205,6 +207,14 @@ public JSONWithPadding getUserData( @Context UriInfo ui, @QueryParam( "ttl" ) lo @Produces( MediaType.TEXT_HTML ) public Viewable showPasswordResetForm( @Context UriInfo ui, @QueryParam( "token" ) String token ) { + final boolean externalTokensEnabled = + !StringUtils.isEmpty( properties.getProperty( ManagementResource.USERGRID_CENTRAL_URL ) ); + + if ( externalTokensEnabled ) { + throw new IllegalArgumentException( "Admin Users must reset passwords via " + + properties.getProperty( ManagementResource.USERGRID_CENTRAL_URL ) ); + } + try { this.token = token; @@ -234,6 +244,14 @@ public Viewable handlePasswordResetForm( @Context UriInfo ui, @FormParam( "token @FormParam( "recaptcha_challenge_field" ) String challenge, @FormParam( "recaptcha_response_field" ) String uresponse ) { + final boolean externalTokensEnabled = + !StringUtils.isEmpty( properties.getProperty( ManagementResource.USERGRID_CENTRAL_URL ) ); + + if ( externalTokensEnabled ) { + throw new IllegalArgumentException( "Admin Users must reset passwords via " + + properties.getProperty( ManagementResource.USERGRID_CENTRAL_URL ) ); + } + try { this.token = token; @@ -309,6 +327,14 @@ public UserInfo getUser() { @Produces( MediaType.TEXT_HTML ) public Viewable activate( @Context UriInfo ui, @QueryParam( "token" ) String token ) { + final boolean externalTokensEnabled = + !StringUtils.isEmpty( properties.getProperty( ManagementResource.USERGRID_CENTRAL_URL ) ); + + if ( externalTokensEnabled ) { + throw new IllegalArgumentException( "Admin Users must activate via " + + properties.getProperty( ManagementResource.USERGRID_CENTRAL_URL ) ); + } + try { management.handleActivationTokenForAdminUser( user.getUuid(), token ); return handleViewable( "activate", this ); @@ -330,6 +356,14 @@ public Viewable activate( @Context UriInfo ui, @QueryParam( "token" ) String tok @Produces( MediaType.TEXT_HTML ) public Viewable confirm( @Context UriInfo ui, @QueryParam( "token" ) String token ) { + final boolean externalTokensEnabled = + !StringUtils.isEmpty( properties.getProperty( ManagementResource.USERGRID_CENTRAL_URL ) ); + + if ( externalTokensEnabled ) { + throw new IllegalArgumentException( "Admin Users must confirm via " + + properties.getProperty( ManagementResource.USERGRID_CENTRAL_URL ) ); + } + try { ActivationState state = management.handleConfirmationTokenForAdminUser( user.getUuid(), token ); if ( state == ActivationState.CONFIRMED_AWAITING_ACTIVATION ) { @@ -355,6 +389,14 @@ public JSONWithPadding reactivate( @Context UriInfo ui, @QueryParam( "callback" ) @DefaultValue( "callback" ) String callback ) throws Exception { + final boolean externalTokensEnabled = + !StringUtils.isEmpty( properties.getProperty( ManagementResource.USERGRID_CENTRAL_URL ) ); + + if ( externalTokensEnabled ) { + throw new IllegalArgumentException( "Admin Users must reactiveate via " + + properties.getProperty( ManagementResource.USERGRID_CENTRAL_URL ) ); + } + logger.info( "Send activation email for user: {}" , user.getUuid() ); ApiResponse response = createApiResponse(); 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 144a6de0d5..d907632c88 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 @@ -34,8 +34,10 @@ import javax.ws.rs.core.MediaType; import javax.ws.rs.core.UriInfo; +import org.apache.commons.lang.StringUtils; import org.apache.usergrid.management.exceptions.ManagementException; import org.apache.usergrid.rest.RootResource; +import org.apache.usergrid.rest.management.ManagementResource; import org.apache.usergrid.services.exceptions.ServiceResourceNotFoundException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -78,7 +80,7 @@ public UsersResource() { @Path(RootResource.USER_ID_PATH) public UserResource getUserById( @Context UriInfo ui, @PathParam( "userId" ) String userIdStr ) throws Exception { - return getUserResource(management.getAdminUserByUuid(UUID.fromString(userIdStr)), "user id", userIdStr); + return getUserResource(management.getAdminUserByUuid( UUID.fromString( userIdStr ) ), "user id", userIdStr); } @@ -101,14 +103,14 @@ private UserResource getUserResource(UserInfo user, String type, String value) t if (user == null) { throw new ManagementException("Could not find organization for " + type + " : " + value); } - return getSubResource(UserResource.class).init(user); + return getSubResource(UserResource.class).init( user ); } @Path(RootResource.EMAIL_PATH) public UserResource getUserByEmail( @Context UriInfo ui, @PathParam( "email" ) String email ) throws Exception { - return getUserResource(management.getAdminUserByEmail(email), "email", email); + return getUserResource(management.getAdminUserByEmail( email ), "email", email); } @@ -120,6 +122,14 @@ public JSONWithPadding createUser( @Context UriInfo ui, @FormParam( "username" ) @QueryParam( "callback" ) @DefaultValue( "callback" ) String callback ) throws Exception { + final boolean externalTokensEnabled = + !StringUtils.isEmpty( properties.getProperty( ManagementResource.USERGRID_CENTRAL_URL ) ); + + if ( externalTokensEnabled ) { + throw new IllegalArgumentException( "Admin Users must signup via " + + properties.getProperty( ManagementResource.USERGRID_CENTRAL_URL ) ); + } + logger.info( "Create user: " + username ); ApiResponse response = createApiResponse(); diff --git a/stack/rest/src/test/java/org/apache/usergrid/rest/management/ManagementResourceIT.java b/stack/rest/src/test/java/org/apache/usergrid/rest/management/ManagementResourceIT.java index d6b507e712..2cec9acf8b 100644 --- a/stack/rest/src/test/java/org/apache/usergrid/rest/management/ManagementResourceIT.java +++ b/stack/rest/src/test/java/org/apache/usergrid/rest/management/ManagementResourceIT.java @@ -669,7 +669,7 @@ public void testValidateExternalToken() throws Exception { String suToken = superAdminToken(); Map props = new HashMap(); - props.put( USERGRID_CENTRAL_URL, getBaseURI().toURL().toExternalForm()); + props.put( USERGRID_CENTRAL_URL, getBaseURI().toURL().toExternalForm() ); resource().path( "/testproperties" ) .queryParam( "access_token", suToken) .accept( MediaType.APPLICATION_JSON ) @@ -722,7 +722,7 @@ public void testSuperuserOnlyWhenValidateExternalTokensEnabled() throws Exceptio // create an org and an admin user - String rand = RandomStringUtils.randomAlphanumeric(10); + String rand = RandomStringUtils.randomAlphanumeric( 10 ); final String username = "user_" + rand; OrganizationOwnerInfo orgInfo = setup.getMgmtSvc().createOwnerAndOrganization( username, username, "Test User", username + "@example.com", "password" ); @@ -743,17 +743,23 @@ public void testSuperuserOnlyWhenValidateExternalTokensEnabled() throws Exceptio try { Map loginInfo = new HashMap() {{ - put("username", username ); - put("password", "password"); - put("grant_type", "password"); - }}; + put("username", username ); + put("password", "password"); + put("grant_type", "password"); + }}; JsonNode accessInfoNode = resource().path("/management/token") .type( MediaType.APPLICATION_JSON_TYPE ) .post( JsonNode.class, loginInfo ); fail("Login as Admin User must fail when validate external tokens is enabled"); - } catch ( Exception actual ) { - logger.debug( "error", actual ); + } catch ( UniformInterfaceException actual ) { + assertEquals( 400, actual.getResponse().getStatus() ); + String errorMsg = actual.getResponse().getEntity( JsonNode.class ).get( "error_description" ).toString(); + logger.error( "ERROR: " + errorMsg ); + assertTrue( errorMsg.contains( "Admin Users must login via" )); + + } catch ( Exception e ) { + fail( "We expected a UniformInterfaceException" ); } // login as superuser must succeed diff --git a/stack/rest/src/test/java/org/apache/usergrid/rest/management/users/MUUserResourceIT.java b/stack/rest/src/test/java/org/apache/usergrid/rest/management/users/MUUserResourceIT.java index a75a401ddc..65d6d503da 100644 --- a/stack/rest/src/test/java/org/apache/usergrid/rest/management/users/MUUserResourceIT.java +++ b/stack/rest/src/test/java/org/apache/usergrid/rest/management/users/MUUserResourceIT.java @@ -25,9 +25,14 @@ import javax.mail.Message; import javax.mail.MessagingException; import javax.mail.internet.MimeMultipart; +import javax.ws.rs.DefaultValue; +import javax.ws.rs.FormParam; +import javax.ws.rs.QueryParam; import javax.ws.rs.core.MediaType; +import org.apache.commons.lang.RandomStringUtils; import org.codehaus.jackson.JsonNode; +import org.jclouds.json.Json; import org.junit.Ignore; import org.junit.Rule; import org.junit.Test; @@ -55,6 +60,7 @@ import com.sun.jersey.api.client.UniformInterfaceException; import com.sun.jersey.api.representation.Form; +import static org.apache.usergrid.rest.management.ManagementResource.USERGRID_CENTRAL_URL; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; @@ -71,7 +77,7 @@ /** @author zznate */ public class MUUserResourceIT extends AbstractRestIT { - private Logger LOG = LoggerFactory.getLogger( MUUserResourceIT.class ); + private Logger logger = LoggerFactory.getLogger( MUUserResourceIT.class ); @Rule @@ -87,7 +93,7 @@ public class MUUserResourceIT extends AbstractRestIT { @Test // @Ignore( "aok - check this please" ) public void testCaseSensitivityAdminUser() throws Exception { - LOG.info( "Starting testCaseSensitivityAdminUser()" ); + logger.info( "Starting testCaseSensitivityAdminUser()" ); UserInfo mixcaseUser = setup.getMgmtSvc() .createAdminUser( "AKarasulu", "Alex Karasulu", "AKarasulu@Apache.org", "test", true, false ); @@ -157,7 +163,7 @@ public void testUnconfirmedAdminLogin() throws Exception { assertEquals( "invalid_grant", node.get( "error" ).getTextValue() ); assertEquals( "User must be confirmed to authenticate", node.get( "error_description" ).getTextValue() ); - LOG.info( "Unconfirmed user was not authorized to authenticate!" ); + logger.info( "Unconfirmed user was not authorized to authenticate!" ); } // Confirm the getting account confirmation email for unconfirmed user @@ -174,7 +180,7 @@ public void testUnconfirmedAdminLogin() throws Exception { // Extract the token to confirm the user // ------------------------------------------- String token = getTokenFromMessage( confirmation ); - LOG.info( token ); + logger.info( token ); ActivationState state = setup.getMgmtSvc().handleConfirmationTokenForAdminUser( orgOwner.getOwner().getUuid(), token ); @@ -194,7 +200,7 @@ public void testUnconfirmedAdminLogin() throws Exception { .accept( MediaType.APPLICATION_JSON ).get( JsonNode.class ); assertNotNull( node ); - LOG.info( "Authentication succeeded after confirmation: {}.", node.toString() ); + logger.info( "Authentication succeeded after confirmation: {}.", node.toString() ); } finally { setTestProperties( originalProperties ); @@ -305,7 +311,7 @@ public void updateManagementUser() throws Exception { logNode( node ); payload = hashMap( "company", "Usergrid" ); - LOG.info( "sending PUT for company update" ); + logger.info( "sending PUT for company update" ); node = resource().path( String.format( "/management/users/%s", userId ) ).queryParam( "access_token", token ) .type( MediaType.APPLICATION_JSON_TYPE ).put( JsonNode.class, payload ); assertNotNull( node ); @@ -602,4 +608,88 @@ public void listOrgUsersByName() { assertEquals( context.getActiveUser().getEmail(), adminNode.get( "email" ).asText() ); assertEquals( context.getActiveUser().getUser(), adminNode.get( "username" ).asText() ); } + + + @Test + public void testNoAdminUserSignupWhenValidateExternalTokensEnabled() throws Exception { + + // turn on validate external tokens by setting the usergrid.central.url + + String suToken = superAdminToken(); + Map props = new HashMap(); + props.put( USERGRID_CENTRAL_URL, getBaseURI().toURL().toExternalForm()); + resource().path( "/testproperties" ) + .queryParam( "access_token", suToken) + .accept( MediaType.APPLICATION_JSON ) + .type( MediaType.APPLICATION_JSON_TYPE ) + .post( props ); + + // create an admin user must fail + + try { + + // create an admin user + + final String rand = RandomStringUtils.randomAlphanumeric( 10 ); + Map payload = new HashMap() {{ + put( "username", "user_" + rand ); + put( "name", "Joe Userperson" ); + put( "email", "joe_" + rand + "@example.com" ); + put( "password", "wigglestone" ); + }}; + JsonNode node = resource().path( "/management/users") + .accept( MediaType.APPLICATION_JSON ) + .type( MediaType.APPLICATION_JSON ) + .post( JsonNode.class, payload ); + + fail( "Create admin user should fail" ); + + } catch ( UniformInterfaceException actual ) { + assertEquals( 400, actual.getResponse().getStatus() ); + String errorMsg = actual.getResponse().getEntity( JsonNode.class ).get( "error_description" ).toString(); + assertTrue( errorMsg.startsWith( "Admin Users must signup via http://localhost:" ) ); + + } catch ( Exception e ) { + fail("We expected a UniformInterfaceException"); + } + + + try { + + // create an org and an admin user + + final String rand = RandomStringUtils.randomAlphanumeric( 10 ); + Map payload = new HashMap() {{ + put( "organization", "org_" + rand ); + put( "username", "user_" + rand ); + put( "name", "Joe Userperson" ); + put( "email", "joe_" + rand + "@example.com" ); + put( "password", "wigglestone" ); + }}; + JsonNode node = resource().path( "/management/organizations/") + .accept( MediaType.APPLICATION_JSON ) + .type( MediaType.APPLICATION_JSON ) + .post( JsonNode.class, payload ); + + fail( "Create org and admin user should fail" ); + + } catch ( UniformInterfaceException actual ) { + assertEquals( 400, actual.getResponse().getStatus() ); + assertTrue( actual.getResponse().getEntity( JsonNode.class ).get( "error_description" ) + .toString().startsWith( "Organization / Admin Users must be created via http://localhost:" )); + + } catch ( Exception e ) { + fail("We expected a UniformInterfaceException"); + } + + + // turn off validate external tokens by un-setting the usergrid.central.url + + props.put( USERGRID_CENTRAL_URL, "" ); + resource().path( "/testproperties" ) + .queryParam( "access_token", suToken) + .accept( MediaType.APPLICATION_JSON ) + .type( MediaType.APPLICATION_JSON_TYPE ) + .post( props ); + } } From c3e8782263a8b839bb1011910d72a0da9201e158 Mon Sep 17 00:00:00 2001 From: Dave Johnson Date: Mon, 20 Apr 2015 08:21:51 -0400 Subject: [PATCH 4/7] Typo --- .../org/apache/usergrid/rest/management/users/UserResource.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 de3928d7b5..3c755f8297 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 @@ -393,7 +393,7 @@ public JSONWithPadding reactivate( @Context UriInfo ui, !StringUtils.isEmpty( properties.getProperty( ManagementResource.USERGRID_CENTRAL_URL ) ); if ( externalTokensEnabled ) { - throw new IllegalArgumentException( "Admin Users must reactiveate via " + + throw new IllegalArgumentException( "Admin Users must reactivate via " + properties.getProperty( ManagementResource.USERGRID_CENTRAL_URL ) ); } From 8aff671853b7df41d2338b5617defdd99ffa08f1 Mon Sep 17 00:00:00 2001 From: Dave Johnson Date: Mon, 20 Apr 2015 09:45:11 -0400 Subject: [PATCH 5/7] Fixes to no Admin User signup when ext. tokens enabled test. --- .../management/users/MUUserResourceIT.java | 41 +++++++++---------- 1 file changed, 20 insertions(+), 21 deletions(-) diff --git a/stack/rest/src/test/java/org/apache/usergrid/rest/management/users/MUUserResourceIT.java b/stack/rest/src/test/java/org/apache/usergrid/rest/management/users/MUUserResourceIT.java index 65d6d503da..a1e31c48b4 100644 --- a/stack/rest/src/test/java/org/apache/usergrid/rest/management/users/MUUserResourceIT.java +++ b/stack/rest/src/test/java/org/apache/usergrid/rest/management/users/MUUserResourceIT.java @@ -29,7 +29,9 @@ import javax.ws.rs.FormParam; import javax.ws.rs.QueryParam; import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.MultivaluedMap; +import com.sun.jersey.core.util.MultivaluedMapImpl; import org.apache.commons.lang.RandomStringUtils; import org.codehaus.jackson.JsonNode; import org.jclouds.json.Json; @@ -631,26 +633,25 @@ public void testNoAdminUserSignupWhenValidateExternalTokensEnabled() throws Exce // create an admin user final String rand = RandomStringUtils.randomAlphanumeric( 10 ); - Map payload = new HashMap() {{ - put( "username", "user_" + rand ); - put( "name", "Joe Userperson" ); - put( "email", "joe_" + rand + "@example.com" ); - put( "password", "wigglestone" ); + MultivaluedMap payload = new MultivaluedMapImpl() {{ + putSingle( "username", "user_" + rand ); + putSingle( "name", "Joe Userperson" ); + putSingle( "email", "joe_" + rand + "@example.com" ); + putSingle( "password", "wigglestone" ); }}; JsonNode node = resource().path( "/management/users") .accept( MediaType.APPLICATION_JSON ) - .type( MediaType.APPLICATION_JSON ) + .type( MediaType.APPLICATION_FORM_URLENCODED ) .post( JsonNode.class, payload ); fail( "Create admin user should fail" ); - } catch ( UniformInterfaceException actual ) { - assertEquals( 400, actual.getResponse().getStatus() ); - String errorMsg = actual.getResponse().getEntity( JsonNode.class ).get( "error_description" ).toString(); - assertTrue( errorMsg.startsWith( "Admin Users must signup via http://localhost:" ) ); - - } catch ( Exception e ) { - fail("We expected a UniformInterfaceException"); + } catch ( Exception actual ) { + assertTrue( actual instanceof UniformInterfaceException ); + UniformInterfaceException uie = (UniformInterfaceException)actual; + assertEquals( 400, uie.getResponse().getStatus() ); + String errorMsg = uie.getResponse().getEntity( JsonNode.class ).get( "error_description" ).toString(); + assertTrue( errorMsg.contains( "Admin Users must signup via" ) ); } @@ -673,16 +674,14 @@ public void testNoAdminUserSignupWhenValidateExternalTokensEnabled() throws Exce fail( "Create org and admin user should fail" ); - } catch ( UniformInterfaceException actual ) { - assertEquals( 400, actual.getResponse().getStatus() ); - assertTrue( actual.getResponse().getEntity( JsonNode.class ).get( "error_description" ) - .toString().startsWith( "Organization / Admin Users must be created via http://localhost:" )); - - } catch ( Exception e ) { - fail("We expected a UniformInterfaceException"); + } catch ( Exception actual ) { + assertTrue( actual instanceof UniformInterfaceException ); + UniformInterfaceException uie = (UniformInterfaceException)actual; + assertEquals( 400, uie.getResponse().getStatus() ); + String errorMsg = uie.getResponse().getEntity( JsonNode.class ).get( "error_description" ).toString(); + assertTrue( errorMsg.contains( "Organization / Admin Users must be created via" ) ); } - // turn off validate external tokens by un-setting the usergrid.central.url props.put( USERGRID_CENTRAL_URL, "" ); From f96f28894e7b71d1205b95fe796650965576ef3e Mon Sep 17 00:00:00 2001 From: Dave Johnson Date: Mon, 20 Apr 2015 10:47:57 -0400 Subject: [PATCH 6/7] Add comments about new keyspace name configuration properties, plus a test fix. --- .../resources/usergrid-default.properties | 27 +++++++++++-------- .../rest/management/ManagementResourceIT.java | 7 +++-- 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/stack/config/src/main/resources/usergrid-default.properties b/stack/config/src/main/resources/usergrid-default.properties index fe7a945a59..b895310482 100644 --- a/stack/config/src/main/resources/usergrid-default.properties +++ b/stack/config/src/main/resources/usergrid-default.properties @@ -31,13 +31,16 @@ # URL for local testing Cassandra cluster cassandra.url=localhost:9160 -#The number of thrift connections to open per cassandra node. +# The number of thrift connections to open per cassandra node. cassandra.connections=50 - # Name of Cassandra cluster cassandra.cluster=Test Cluster +# Keyspace names to be used (see also the locks keyspace below) +cassandra.system.keyspace=Usergrid +cassandra.application.keyspace=Usergrid_Applications + cassandra.keyspace.strategy=org.apache.cassandra.locator.SimpleStrategy #cassandra.keyspace.strategy=org.apache.cassandra.locator.NetworkTopologyStrategy @@ -49,18 +52,19 @@ cassandra.keyspace.replication=1 cassandra.username= cassandra.password= -#Read consistency level for the cassandra cluster +# Read consistency level for the cassandra cluster cassandra.readcl=QUORUM -#Write consistency level for the cassandra cluster +# Write consistency level for the cassandra cluster cassandra.writecl=QUORUM -#The maximum number of pending mutations allowed in ram before it is flushed to cassandra +# The maximum number of pending mutations allowed in ram before it is flushed to cassandra cassandra.mutation.flushsize=2000 -#Keyspace to use for locking -#Note that if this is deployed in a production cluster, the RF on the keyspace MUST be updated to use an odd number for it's replication Factor. -#Even numbers for RF can potentially case the locks to fail, via "split brain" when read at QUORUM on lock verification +# Keyspace to use for locking - Used by Hector lock manager: +# Note that if this is deployed in a production cluster, the RF on the keyspace MUST +# be updated to use an odd number for it's replication Factor. Even numbers for RF can +# potentially case the locks to fail, via "split brain" when read at QUORUM on lock verification cassandra.lock.keyspace=Locks # false to disable test features @@ -111,9 +115,10 @@ usergrid.sysadmin.login.allowed=false usergrid.sysadmin.approve.users=false usergrid.sysadmin.approve.organizations=false -# Base URL of central Usergrid SSO server -# Setting this will enable external token validation. -# See also: https://issues.apache.org/jira/browse/USERGRID-567 +# Base URL of central Usergrid SSO server: +# Setting this will enable External Token Validation for Admin Users and will configure +# this Usergrid instance delegate all Admin User authentication to the central Usegrid SSO +# server. See also: https://issues.apache.org/jira/browse/USERGRID-567 usergrid.central.url= # Where to store temporary files diff --git a/stack/rest/src/test/java/org/apache/usergrid/rest/management/ManagementResourceIT.java b/stack/rest/src/test/java/org/apache/usergrid/rest/management/ManagementResourceIT.java index 2cec9acf8b..651fcdfb66 100644 --- a/stack/rest/src/test/java/org/apache/usergrid/rest/management/ManagementResourceIT.java +++ b/stack/rest/src/test/java/org/apache/usergrid/rest/management/ManagementResourceIT.java @@ -695,8 +695,11 @@ public void testValidateExternalToken() throws Exception { .queryParam( "ttl", "1000" ) .get( JsonNode.class ); fail("Validation should have failed"); - } catch ( Exception actual ) { - logger.debug( "error", actual ); + } catch ( UniformInterfaceException actual ) { + assertEquals( 400, actual.getResponse().getStatus() ); + String errorMsg = actual.getResponse().getEntity( JsonNode.class ).get( "error_description" ).toString(); + logger.error( "ERROR: " + errorMsg ); + assertTrue( errorMsg.contains( "Admin Users must login via" ) ); } From 23febdf9a7f961fefa6675bd166466999c0f0969 Mon Sep 17 00:00:00 2001 From: Dave Johnson Date: Mon, 20 Apr 2015 11:50:26 -0400 Subject: [PATCH 7/7] Another test fix. --- .../apache/usergrid/rest/management/ManagementResourceIT.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/stack/rest/src/test/java/org/apache/usergrid/rest/management/ManagementResourceIT.java b/stack/rest/src/test/java/org/apache/usergrid/rest/management/ManagementResourceIT.java index 651fcdfb66..cec172df17 100644 --- a/stack/rest/src/test/java/org/apache/usergrid/rest/management/ManagementResourceIT.java +++ b/stack/rest/src/test/java/org/apache/usergrid/rest/management/ManagementResourceIT.java @@ -696,10 +696,10 @@ public void testValidateExternalToken() throws Exception { .get( JsonNode.class ); fail("Validation should have failed"); } catch ( UniformInterfaceException actual ) { - assertEquals( 400, actual.getResponse().getStatus() ); + assertEquals( 404, actual.getResponse().getStatus() ); String errorMsg = actual.getResponse().getEntity( JsonNode.class ).get( "error_description" ).toString(); logger.error( "ERROR: " + errorMsg ); - assertTrue( errorMsg.contains( "Admin Users must login via" ) ); + assertTrue( errorMsg.contains( "Cannot find Admin User" ) ); }