/* * 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.management; import net.jcip.annotations.NotThreadSafe; import org.apache.commons.lang.RandomStringUtils; import org.apache.usergrid.management.MockImapClient; import org.apache.usergrid.persistence.core.util.StringUtils; import org.apache.usergrid.persistence.index.utils.UUIDUtils; import org.apache.usergrid.rest.test.resource.AbstractRestIT; import org.apache.usergrid.rest.test.resource.endpoints.mgmt.ManagementResource; import org.apache.usergrid.rest.test.resource.model.*; import org.junit.Before; import org.junit.Test; import org.jvnet.mock_javamail.Mailbox; import javax.mail.Message; import javax.mail.MessagingException; import javax.mail.internet.MimeMultipart; import javax.ws.rs.BadRequestException; import javax.ws.rs.ClientErrorException; import javax.ws.rs.InternalServerErrorException; import javax.ws.rs.NotAuthorizedException; import javax.ws.rs.core.Form; import javax.ws.rs.core.Response; import java.io.IOException; import java.util.*; import static org.apache.usergrid.management.AccountCreationProps.*; import static org.apache.usergrid.security.PasswordPolicy.ERROR_POLICY_VIOLIATION; import static org.junit.Assert.*; /** * Contains all tests relating to Admin Users */ @NotThreadSafe public class AdminUsersIT extends AbstractRestIT { ManagementResource management; @Before public void setup() { management= clientSetup.getRestClient().management(); } /** * Test if we can reset an admin's password by using that same admins credentials. */ @Test public void setSelfAdminPasswordAsAdmin() throws IOException { String username = clientSetup.getUsername(); String password = clientSetup.getPassword(); Map<String, Object> passwordPayload = new HashMap<String, Object>(); passwordPayload.put( "newpassword", "testPassword" ); passwordPayload.put( "oldpassword", password ); // change the password as admin. The old password isn't required management.users().user( username ).password().post(Entity.class,passwordPayload); this.waitForQueueDrainAndRefreshIndex(); //Get the token using the new password Token adminToken = management.token().post( false, Token.class, new Token( username, "testPassword" ) ,null ); management.token().setToken( adminToken ); //Check that we cannot get the token using the old password try { management.token().post(false, Token.class, new Token( username, password ),null); fail( "We shouldn't be able to get a token using the old password" ); }catch(ClientErrorException uie) { errorParse( 400,"invalid_grant",uie ); } } /** * Test that creating user with password that violates policy results in informative error message. */ @Test public void createUserWithInvalidPassword() throws IOException { String rando = RandomStringUtils.randomAlphanumeric(10); Form userForm = new Form(); userForm.param( "username", "user_" + rando ); userForm.param( "name", rando); userForm.param( "email", "user_" + rando + "@example.com" ); userForm.param( "password", "abc" ); try { management().users().post( User.class, userForm ); fail("Invalid password should have caused error"); } catch( ClientErrorException uie ) { errorParse( 400, ERROR_POLICY_VIOLIATION, uie ); } } /** * Test that setting a password that violates policy results in informative error message. */ @Test public void resetPasswordWithInvalidNewPassword() throws IOException { String username = clientSetup.getUsername(); String password = clientSetup.getPassword(); Map<String, Object> passwordPayload = new HashMap<String, Object>(); // Default password policy is lenient, only requires length of 4 passwordPayload.put( "newpassword", "abc" ); passwordPayload.put( "oldpassword", password ); try { management.users().user( username ).password().post( Entity.class, passwordPayload ); fail("Invalid password should have caused error"); } catch( ClientErrorException uie ) { errorParse( 400, ERROR_POLICY_VIOLIATION, uie ); } } /** * Check that we cannot change the password by using an older password */ @Test public void passwordMismatchErrorAdmin() { String username = clientSetup.getUsername(); String password = clientSetup.getPassword(); Map<String, Object> passwordPayload = new HashMap<String, Object>(); passwordPayload.put( "newpassword", "testPassword" ); passwordPayload.put( "oldpassword", password ); // change the password as admin. The old password isn't required management.users().user( username ).password().post(Entity.class, passwordPayload ); this.waitForQueueDrainAndRefreshIndex(); //Get the token using the new password Token adminToken = management.token().post( Token.class, new Token( username, "testPassword" ) ); management.token().setToken( adminToken ); // Check that we can't change the password using the old password. try { management.users().user( username ).password().post( Entity.class ,passwordPayload ); fail("We shouldn't be able to change the password with the same payload"); } catch ( ClientErrorException uie ) { errorParse( Response.Status.BAD_REQUEST.getStatusCode(),"auth_invalid_username_or_password",uie ); } } /** * Checks that as a superuser (i.e with a superuser token ) we can change the password of a admin. * @throws IOException */ @Test public void setAdminPasswordAsSysAdmin() throws IOException { String username = clientSetup.getUsername(); String password = clientSetup.getPassword(); // change the password as admin. The old password isn't required Map<String, Object> passwordPayload = new HashMap<String, Object>(); passwordPayload.put( "newpassword", "testPassword" ); management.token().setToken( clientSetup.getSuperuserToken()); management.users().user( username ).password().post( passwordPayload ); this.waitForQueueDrainAndRefreshIndex(); assertNotNull( management.token().post( false, Token.class, new Token(username, "testPassword"), null )); // Check that we cannot get the token using the old password try { management.token().post( false,Token.class, new Token( username, password) ,null); fail( "We shouldn't be able to get a token using the old password" ); } catch(ClientErrorException uie) { errorParse( 400,"invalid_grant",uie ); } } /** * Get the management user feed and check that it has the correct title. * @throws Exception */ @Test public void mgmtUserFeed() throws Exception { //TODO: fix or establish what the user feed should do management.token().setToken( this.getAdminToken() ); ApiResponse mgmtUserFeedEntity = management.users().user( clientSetup.getUsername() ).feed().get(); String correctValue= "<a href=mailto:"+clientSetup.getUsername(); //user_org.apache.usergrid.rest.management.AdminUsersIT.mgmtUserFeed4c3e53e0-acc7-11e4-b527-0b8af3c5813f@usergrid.com">user_org.apache.usergrid.rest.management.AdminUsersIT.mgmtUserFeed4c3e53e0-acc7-11e4-b527-0b8af3c5813f (user_org.apache.usergrid.rest.management.AdminUsersIT.mgmtUserFeed4c3e53e0-acc7-11e4-b527-0b8af3c5813f@usergrid.com)</a> created a new organization account named org_org.apache.usergrid.rest.management.AdminUsersIT.mgmtUserFeed4c3ec910-acc7-11e4-94c8-33f0d48a5559 assertNotNull( mgmtUserFeedEntity ); List<Entity> feedEntityMap = mgmtUserFeedEntity.getEntities(); assertNotNull( feedEntityMap ); assertNotEquals( 0,feedEntityMap.size() ); assertNotNull( feedEntityMap.get( 0 ).get( "title" ) ); assertTrue("Needs to contain the feed of the specific management user", ((String)(feedEntityMap.get( 0 ).get( "title" ))).contains(clientSetup.getUsername() )); } /** * Test that a unconfirmed admin cannot log in. * TODO:test for parallel test that changing the properties here won't affect other tests * @throws Exception */ @Test public void testUnconfirmedAdminLogin() throws Exception{ ApiResponse originalTestPropertiesResponse = clientSetup.getRestClient().testPropertiesResource().get(); Entity originalTestProperties = new Entity( originalTestPropertiesResponse ); try { //Set runtime enviroment to the following settings //TODO: make properties verification its own test. Map<String, Object> testPropertiesMap = new HashMap<>(); testPropertiesMap.put( PROPERTIES_SYSADMIN_APPROVES_ADMIN_USERS, "false" ); testPropertiesMap.put( PROPERTIES_SYSADMIN_APPROVES_ORGANIZATIONS, "false" ); //Requires admins to do email confirmation before they can log in. testPropertiesMap.put( PROPERTIES_ADMIN_USERS_REQUIRE_CONFIRMATION, "true" ); testPropertiesMap.put( PROPERTIES_DEFAULT_SYSADMIN_EMAIL, "sysadmin-1@mockserver.com" ); Entity testPropertiesPayload = new Entity( testPropertiesMap ); //Send rest call to the /testProperties endpoint to persist property changes clientSetup.getRestClient().testPropertiesResource().post( testPropertiesPayload ); waitForQueueDrainAndRefreshIndex(); //Create organization for the admin user to be confirmed Organization organization = createOrgPayload( "testUnconfirmedAdminLogin", null ); Organization organizationResponse = clientSetup.getRestClient().management().orgs().post( organization ); assertNotNull( organizationResponse ); //Ensure that adminUser has the correct properties set. User adminUser = organizationResponse.getOwner(); assertNotNull( adminUser ); assertFalse( "adminUser should not be activated yet", adminUser.getActivated() ); assertFalse( "adminUser should not be confirmed yet", adminUser.getConfirmed() ); //Get token grant for new admin user. QueryParameters queryParameters = new QueryParameters(); queryParameters.addParam( "grant_type", "password" ).addParam( "username", adminUser.getUsername() ) .addParam( "password", organization.getPassword() ); //Check that the adminUser cannot log in and fails with a 403 due to not being confirmed. try { management().token().get( queryParameters ); fail( "Admin user should not be able to log in." ); } catch ( ClientErrorException uie ) { assertEquals( "Admin user should have failed with 403", 403, uie.getResponse().getStatus() ); } //Create mocked inbox List<Message> inbox = Mailbox.get( organization.getEmail() ); assertFalse( inbox.isEmpty() ); MockImapClient client = new MockImapClient( "mockserver.com", "test-user-46", "somepassword" ); client.processMail(); //Get email with confirmation token and extract token Message confirmation = inbox.get( 0 ); assertEquals( "User Account Confirmation: " + organization.getEmail(), confirmation.getSubject() ); String token = getTokenFromMessage( confirmation ); //Make rest call with extracted token to confirm the admin user. management().users().user( adminUser.getUuid().toString() ).confirm() .get( new QueryParameters().addParam( "token", token ) ); //Try the previous call and verify that the admin user can retrieve login token Token retToken = management().token().get( queryParameters ); assertNotNull( retToken ); assertNotNull( retToken.getAccessToken() ); }finally { clientSetup.getRestClient().testPropertiesResource().post( originalTestProperties ); } } /** * Test that the system admin doesn't need a confirmation email * @throws Exception */ @Test public void testSystemAdminNeedsNoConfirmation() throws Exception{ //Save original properties to return them to normal at the end of the test ApiResponse originalTestPropertiesResponse = clientSetup.getRestClient().testPropertiesResource().get(); Entity originalTestProperties = new Entity( originalTestPropertiesResponse ); try { //Set runtime enviroment to the following settings Map<String, Object> testPropertiesMap = new HashMap<>(); testPropertiesMap.put( PROPERTIES_SYSADMIN_APPROVES_ADMIN_USERS, "false" ); testPropertiesMap.put( PROPERTIES_SYSADMIN_APPROVES_ORGANIZATIONS, "false" ); //Requires admins to do email confirmation before they can log in. testPropertiesMap.put( PROPERTIES_ADMIN_USERS_REQUIRE_CONFIRMATION, "true" ); Entity testPropertiesPayload = new Entity( testPropertiesMap ); //Send rest call to the /testProperties endpoint to persist property changes clientSetup.getRestClient().testPropertiesResource().post( testPropertiesPayload ); waitForQueueDrainAndRefreshIndex(); Token superuserToken = management.token().post( Token.class, new Token( clientSetup.getSuperuserName(), clientSetup.getSuperuserPassword() ) ); assertNotNull( "We should have gotten a valid token back" ,superuserToken ); }finally{ clientSetup.getRestClient().testPropertiesResource().post( originalTestProperties ); } } /** * Test that the test account doesn't need confirmation and is created automatically. * @throws Exception */ @Test public void testTestUserNeedsNoConfirmation() throws Exception{ //Save original properties to return them to normal at the end of the test ApiResponse originalTestPropertiesResponse = clientSetup.getRestClient().testPropertiesResource().get(); Entity originalTestProperties = new Entity( originalTestPropertiesResponse ); try { //Set runtime enviroment to the following settings Map<String, Object> testPropertiesMap = new HashMap<>(); testPropertiesMap.put( PROPERTIES_SYSADMIN_APPROVES_ADMIN_USERS, "false" ); testPropertiesMap.put( PROPERTIES_SYSADMIN_APPROVES_ORGANIZATIONS, "false" ); //Requires admins to do email confirmation before they can log in. testPropertiesMap.put( PROPERTIES_ADMIN_USERS_REQUIRE_CONFIRMATION, "true" ); Entity testPropertiesPayload = new Entity( testPropertiesMap ); //Send rest call to the /testProperties endpoint to persist property changes clientSetup.getRestClient().testPropertiesResource().post( testPropertiesPayload ); waitForQueueDrainAndRefreshIndex(); Token testToken = management().token().post(Token.class, new Token( originalTestProperties.getAsString( PROPERTIES_TEST_ACCOUNT_ADMIN_USER_EMAIL ), originalTestProperties.getAsString( PROPERTIES_TEST_ACCOUNT_ADMIN_USER_PASSWORD ) )); assertNotNull( "We should have gotten a valid token back" ,testToken ); }finally{ clientSetup.getRestClient().testPropertiesResource().post( originalTestProperties ); } } @Test public void updateManagementUserNoToken() throws Exception { Organization newOrg = createOrgPayload( "updateManagementUserNoToken", null ); Organization orgReturned = clientSetup.getRestClient().management().orgs().post( newOrg ); assertNotNull( orgReturned.getOwner() ); //Add a property to management user Entity userProperty = new Entity( ).chainPut( "company","usergrid" ); try{ management().users().user( newOrg.getUsername() ).put( userProperty ); } catch( NotAuthorizedException e ){ int status = e.getResponse().getStatus(); assertEquals(401, status); } } @Test public void updateManagementUserSuperuserToken() throws Exception { Organization newOrg = createOrgPayload( "updateManagementUserSuperuserToken", null ); Organization orgReturned = clientSetup.getRestClient().management().orgs().post( newOrg ); assertNotNull( orgReturned.getOwner() ); //Add a property to management user Entity userProperty = new Entity( ).chainPut( "company","usergrid" ); management.token().setToken( clientSetup.getSuperuserToken()); management().users().user( newOrg.getUsername() ).put( userProperty ); } @Test public void updateManagementUserAdminToken() throws Exception { Organization newOrg = createOrgPayload( "updateManagementUserAdminToken", null ); Organization orgReturned = clientSetup.getRestClient().management().orgs().post( newOrg ); assertNotNull( orgReturned.getOwner() ); String orgName = orgReturned.getName(); //Add a property to management user Entity userProperty = new Entity( ).chainPut( "company","usergrid" ); User adminUser = orgReturned.getOwner(); Token adminToken = management.token().get(adminUser.getUsername(), orgName); assertNotNull(adminToken); management.token().setToken( adminToken ); management().users().user( newOrg.getUsername() ).put( userProperty ); } @Test public void updateManagementUserWrongAdminToken() throws Exception { Organization newOrg = createOrgPayload( "updateManagementUserWrongAdminToken", null ); Organization orgReturned = clientSetup.getRestClient().management().orgs().post( newOrg ); assertNotNull( orgReturned.getOwner() ); // add a new management user to the org for the purpose of a 'wrong' user trying update others Entity adminUserPayload = new Entity(); String wrongAdminUsername = "wrongAdminUser"+UUIDUtils.newTimeUUID(); adminUserPayload.put( "username", wrongAdminUsername ); adminUserPayload.put( "name", wrongAdminUsername ); adminUserPayload.put( "email", wrongAdminUsername+"@usergrid.com" ); adminUserPayload.put( "password", wrongAdminUsername ); management().orgs().org( clientSetup.getOrganizationName() ).users().post(User.class ,adminUserPayload ); // get token of the newly added wrongAdminUser Token wrongAdminToken = management.token().get(wrongAdminUsername, wrongAdminUsername); assertNotNull(wrongAdminToken); management.token().setToken( wrongAdminToken ); try{ //Add a property to management user Entity userProperty = new Entity( ).chainPut( "company","usergrid" ); management().users().user( newOrg.getUsername() ).put( userProperty ); fail("Should not have been allowed"); } catch( NotAuthorizedException e ){ int status = e.getResponse().getStatus(); assertEquals(401, status); } } @Test public void testAdminRemovalFromOrg() throws Exception { Organization newOrg = createOrgPayload( "testAdminRemovalFromOrg", null ); Organization orgReturned = clientSetup.getRestClient().management().orgs().post(newOrg); User owner = orgReturned.getOwner(); assertNotNull(owner); String orgName = orgReturned.getName(); Token ownerToken = management.token().get(owner.getUsername(), orgName); // add a new admin user to the org Entity adminUserPayload = new Entity(); String newAdminUserName = "newAdminUser"+UUIDUtils.newTimeUUID(); adminUserPayload.put( "username", newAdminUserName ); adminUserPayload.put( "name", newAdminUserName ); adminUserPayload.put( "email", newAdminUserName+"@usergrid.com" ); adminUserPayload.put( "password", newAdminUserName ); management.token().setToken(ownerToken); management.orgs().org(orgName).users().post(User.class, adminUserPayload); // get token of the new admin user Token adminToken = management.token().get(newAdminUserName, newAdminUserName); assertNotNull(adminToken); // get org info try { management.token().setToken(adminToken); management.orgs().org(orgName).get(); } catch (Exception e) { // should have been allowed fail("Should have worked: " + e.getMessage()); } // remove access try { management.token().setToken(ownerToken); management.orgs().org(orgName).users().user(newAdminUserName).delete(); } catch (Exception e) { // should have been allowed fail("Should have worked: " + e.getMessage()); } // get org info (should be unsuccessful) try { management.token().setToken(adminToken); management.orgs().org(orgName).get(); fail("Should not have allowed org access"); } catch (NotAuthorizedException nae) { // this is the right return } catch (Exception e) { fail("Should have been unauthorized: " + e.getMessage()); } // restore access try { management.token().setToken(ownerToken); management.orgs().org(orgName).users().user(newAdminUserName).put(new Entity()); } catch (Exception e) { // should have been allowed fail("Should have worked: " + e.getMessage()); } // get org info try { management.token().setToken(adminToken); management.orgs().org(orgName).get(); } catch (Exception e) { // should have been allowed fail("Should have worked: " + e.getMessage()); } } /** * Check that we send the reactivate email to the user after calling the reactivate endpoint. * @throws Exception */ @Test public void reactivateTest() throws Exception { //call reactivate endpoint on default user clientSetup.getRestClient().management().users().user( clientSetup.getUsername() ).reactivate().get(); waitForQueueDrainAndRefreshIndex(); //Create mocked inbox and check to see if you recieved an email in the users inbox. List<Message> inbox = Mailbox.get( clientSetup.getEmail()); assertFalse( inbox.isEmpty() ); } @Test public void checkFormPasswordReset() throws Exception { // initiate password reset management().users().user( clientSetup.getUsername() ).resetpw().post(new Form()); waitForQueueDrainAndRefreshIndex(); // create mocked inbox, get password reset email and extract token List<Message> inbox = Mailbox.get( clientSetup.getEmail() ); assertFalse( inbox.isEmpty() ); MockImapClient client = new MockImapClient( "mockserver.com", "test-user-46", "somepassword" ); client.processMail(); // Get email with confirmation token and extract token String token = null; Iterator<Message> msgIterator = inbox.iterator(); while ( token == null && msgIterator.hasNext() ) { Message msg = msgIterator.next(); if ( msg.getSubject().equals("Password Reset") ) { token = getTokenFromMessage( msg ); } } assertNotNull( token ); Form formData = new Form(); formData.param( "token", token ); formData.param( "password1", "sesame" ); formData.param( "password2", "sesame" ); String html = management().users().user( clientSetup.getUsername() ).resetpw().getTarget().request() .post( javax.ws.rs.client.Entity.form(formData), String.class ); assertTrue( html.contains( "password set" ) ); waitForQueueDrainAndRefreshIndex(); html = management().users().user( clientSetup.getUsername() ).resetpw().post( formData ); assertTrue( html.contains( "invalid token" ) ); } @Test public void passwordResetIncorrectUserName() throws Exception { // initiate password reset management().users().user( clientSetup.getUsername() ).resetpw().post(new Form()); waitForQueueDrainAndRefreshIndex(); // create mocked inbox, get password reset email and extract token List<Message> inbox = Mailbox.get( clientSetup.getEmail() ); assertFalse( inbox.isEmpty() ); MockImapClient client = new MockImapClient( "mockserver.com", "test-user-47", "somepassword" ); client.processMail(); // Get email with confirmation token and extract token String token = null; Iterator<Message> msgIterator = inbox.iterator(); while ( token == null && msgIterator.hasNext() ) { Message msg = msgIterator.next(); if ( msg.getSubject().equals("Password Reset") ) { token = getTokenFromMessage( msg ); } } assertNotNull( token ); Form formData = new Form(); formData.param( "token", token ); formData.param( "password1", "sesame" ); formData.param( "password2", "sesame" ); try { String html = management().users().user( "mr_fatfinger" ).resetpw().getTarget().request() .post( javax.ws.rs.client.Entity.form( formData ), String.class ); fail("Password reset request should have failed"); } catch ( BadRequestException expected ) { String body = expected.getResponse().readEntity( String.class ); assertTrue( body.contains( "Could not find" ) ); } String html = management().users().user( clientSetup.getUsername() ).resetpw().getTarget().request() .post( javax.ws.rs.client.Entity.form(formData), String.class ); assertTrue( html.contains( "password set" ) ); } /** * Checks that the passwords are stored in the history and that older ones are overwritten. * @throws Exception */ @Test public void checkPasswordHistoryConflict() throws Exception { String[] passwords = new String[] { clientSetup.getPassword(), "password2" }; //set the number of old passwords stored to 1 Map<String, Object> props = new HashMap<String, Object>(); props.put( "passwordHistorySize", 1 ); Organization orgPropertiesPayload = new Organization( ); orgPropertiesPayload.put("properties", props); management().orgs().org( clientSetup.getOrganizationName() ).put( orgPropertiesPayload ); //Creates a payload with the same password to verify we cannot change the password to itself. Map<String, Object> payload = new HashMap<>( ); payload.put("oldpassword",passwords[0]); payload.put("newpassword",passwords[0]); //hashMap( "oldpassword", passwords[0] ).map( "newpassword", passwords[0] ); // fail //Makes sure we can't replace a password with itself ( as it is the only one in the history ) try { management().users().user( clientSetup.getUsername() ).password().post(Entity.class ,payload ); fail( "should fail with conflict" ); } catch ( ClientErrorException e ) { assertEquals( 409, e.getResponse().getStatus() ); } //Change the password payload.put( "newpassword", passwords[1] ); management().users().user( clientSetup.getUsername() ).password().post( Entity.class,payload ); waitForQueueDrainAndRefreshIndex(); payload.put( "newpassword", passwords[0] ); payload.put( "oldpassword", passwords[1] ); //Make sure that we can't change the password with itself using a different entry in the history. try { management().users().user( clientSetup.getUsername() ).password().post( Entity.class,payload ); fail( "should fail with conflict" ); } catch ( ClientErrorException e ) { assertEquals( 409, e.getResponse().getStatus() ); } } @Test public void checkPasswordChangeTime() throws Exception { // request password reset management().users().user( clientSetup.getUsername() ).resetpw().post(new Form()); waitForQueueDrainAndRefreshIndex(); // get resetpw token from email List<Message> inbox = Mailbox.get( clientSetup.getEmail() ); assertFalse( inbox.isEmpty() ); MockImapClient client = new MockImapClient( "mockserver.com", "test-user-46", "somepassword" ); client.processMail(); String token = null; Iterator<Message> msgIterator = inbox.iterator(); while ( token == null && msgIterator.hasNext() ) { Message msg = msgIterator.next(); if ( msg.getSubject().equals("Password Reset") ) { token = getTokenFromMessage( msg ); } } assertNotNull( token ); // reset the password to sesame Form formData = new Form(); formData.param( "token", token ); formData.param( "password1", "sesame" ); formData.param( "password2", "sesame" ); String html = management().users().user( clientSetup.getUsername() ).resetpw().getTarget().request() .post( javax.ws.rs.client.Entity.form(formData), String.class ); assertTrue( html.contains( "password set" ) ); waitForQueueDrainAndRefreshIndex(); // login with new password and get token Map<String, Object> payload = new HashMap<String, Object>() {{ put("grant_type", "password"); put("username", clientSetup.getUsername() ); put("password", "sesame"); }}; ApiResponse response = management().token().post( false, payload, null ); // check password changed time Long changeTime = Long.parseLong( response.getProperties().get( "passwordChanged" ).toString() ); assertTrue( System.currentTimeMillis() - changeTime < 2000 ); // change password again by posting JSON payload = new HashMap<String, Object>() {{ put("oldpassword", "sesame"); put("newpassword", "test"); }}; management().users().user( clientSetup.getUsername() ).password().post( false, payload, null ); waitForQueueDrainAndRefreshIndex(); // get password and check password change time again payload = new HashMap<String, Object>() {{ put("grant_type", "password"); put("username", clientSetup.getUsername() ); put("password", "test"); }}; response = management().token().post( false, payload, null ); Long changeTime2 = Long.parseLong( response.getProperties().get( "passwordChanged" ).toString() ); assertTrue( changeTime < changeTime2 ); assertTrue( System.currentTimeMillis() - changeTime2 < 2000 ); // login via /me end-point and check password change time again response = management().me().get( ApiResponse.class, new QueryParameters() .addParam( "grant_type", "password" ) .addParam( "username", clientSetup.getUsername() ) .addParam( "password", "test" ) ); Long changeTime3 = Long.parseLong( response.getProperties().get( "passwordChanged" ).toString() ); assertEquals( changeTime2, changeTime3 ); } /** * Make sure we can list the org admin users by name. */ @Test public void listOrgUsersByName() { Entity adminUserPayload = new Entity(); String username = "listOrgUsersByName"+UUIDUtils.newTimeUUID(); Credentials orgCredentials = clientSetup.getClientCredentials(); adminUserPayload.put( "username", username ); adminUserPayload.put( "name", username ); adminUserPayload.put( "email", username+"@usergrid.com" ); adminUserPayload.put( "password", username ); // //If we comment this out it works, shouldn't using an organization Token for an endpoint //with organization access work? //TODO:investigate above comment // Token organizationToken = // management().token().post( Token.class, // new Token( "client_credentials", orgCredentials.getClientId(), orgCredentials.getClientSecret() ) ); // management().token().setToken( organizationToken ); //Create admin user management().orgs().org( clientSetup.getOrganizationName() ).users().post(ApiResponse.class ,adminUserPayload ); waitForQueueDrainAndRefreshIndex(); //Retrieves the admin users ApiResponse adminUsers = management().orgs().org( clientSetup.getOrganizationName() ).users().get(ApiResponse.class); assertEquals("There need to be 2 admin users",2,( ( ArrayList ) adminUsers.getData() ).size()); } /** * Makes sure you can't create a already existing organization from a user connection. * @throws Exception */ // TODO: figure out what is the expected behavior from this test. // While it fails it is not sure what it should return @Test public void createOrgFromUserConnectionFail() throws Exception { Token token = management().token() .post( Token.class, new Token( clientSetup.getUsername(), clientSetup.getPassword() ) ); management().token().setToken( token ); // try to create the same org again off the connection try { management().users().user( clientSetup.getUsername() ).organizations() .post( clientSetup.getOrganization(), token ); fail( "Should have thrown unique exception on org name" ); } catch ( InternalServerErrorException ise ) { assertEquals(500, ise.getResponse().getStatus()); } } @Test public void testProperties(){ ApiResponse originalTestPropertiesResponse = clientSetup.getRestClient().testPropertiesResource().get(); Entity originalTestProperties = new Entity( originalTestPropertiesResponse ); try { //Set runtime enviroment to the following settings Map<String, Object> testPropertiesMap = new HashMap<>(); testPropertiesMap.put( PROPERTIES_SYSADMIN_APPROVES_ADMIN_USERS, "false" ); testPropertiesMap.put( PROPERTIES_SYSADMIN_APPROVES_ORGANIZATIONS, "false" ); //Requires admins to do email confirmation before they can log in. testPropertiesMap.put( PROPERTIES_ADMIN_USERS_REQUIRE_CONFIRMATION, "true" ); testPropertiesMap.put( PROPERTIES_DEFAULT_SYSADMIN_EMAIL, "sysadmin-1@mockserver.com" ); Entity testPropertiesPayload = new Entity( testPropertiesMap ); //Send rest call to the /testProperties endpoint to persist property changes clientSetup.getRestClient().testPropertiesResource().post( testPropertiesPayload ); waitForQueueDrainAndRefreshIndex(); //Retrieve properties and ensure that they are set correctly. ApiResponse apiResponse = clientSetup.getRestClient().testPropertiesResource().get(); assertEquals( "sysadmin-1@mockserver.com", apiResponse.getProperties().get( PROPERTIES_DEFAULT_SYSADMIN_EMAIL ) ); assertEquals( "true", apiResponse.getProperties().get( PROPERTIES_ADMIN_USERS_REQUIRE_CONFIRMATION ) ); assertEquals( "false", apiResponse.getProperties().get( PROPERTIES_SYSADMIN_APPROVES_ORGANIZATIONS ) ); assertEquals( "false", apiResponse.getProperties().get( PROPERTIES_SYSADMIN_APPROVES_ADMIN_USERS ) ); }finally{ clientSetup.getRestClient().testPropertiesResource().post( originalTestProperties); } } /** * Create an organization payload with almost the same value for every field. * @param baseName * @param properties * @return */ public Organization createOrgPayload(String baseName,Map properties){ String orgName = baseName + org.apache.usergrid.persistence.index.utils.UUIDUtils.newTimeUUID(); return new Organization( orgName, orgName,orgName+"@usergrid",orgName,orgName, properties); } /** * Extract token from mocked inbox message. * @param msg * @return * @throws IOException * @throws MessagingException */ private String getTokenFromMessage( Message msg ) throws IOException, MessagingException { String body = ( ( MimeMultipart ) msg.getContent() ).getBodyPart( 0 ).getContent().toString(); return StringUtils.substringAfterLast( body, "token=" ); } }