/* * 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 java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; import org.apache.usergrid.rest.test.resource.model.*; import org.junit.Test; import org.apache.usergrid.persistence.index.utils.UUIDUtils; import org.apache.usergrid.rest.test.resource.AbstractRestIT; import org.apache.usergrid.rest.test.resource.RestClient; import javax.ws.rs.ClientErrorException; import javax.ws.rs.ServerErrorException; import javax.ws.rs.core.Form; import javax.ws.rs.core.Response; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; /** * Handles all management organization endpoint tests. Any tests that work with organizations specifically can be found here */ public class OrganizationsIT extends AbstractRestIT { String duplicateUniquePropertyExistsErrorMessage = "duplicate_unique_property_exists"; String invalidGrantErrorMessage = "invalid_grant"; /** * Tests that a Organization and Owner can be created and that they persist properties and default permissions. */ @Test public void createOrgAndOwner() throws Exception { //User property to see if owner properties exist when created. Map<String, Object> userProperties = new HashMap<String, Object>(); userProperties.put( "company", "Apigee" ); //Create organization Organization organization = createOrgPayload( "createOrgAndOwner", userProperties ); //Get back organization response Organization organizationResponse = clientSetup.getRestClient().management().orgs().post( organization ); assertNotNull( organizationResponse ); // Thread.sleep( 1000 ); // this.waitForQueueDrainAndRefreshIndex(); //Creates token Token token = clientSetup.getRestClient().management().token().post(false,Token.class, new Token( "password", organization.getUsername(), organization.getPassword() ) ,null); this.management().token().setToken(token); assertNotNull( token ); //this.waitForQueueDrainAndRefreshIndex(); //Assert that the get returns the correct org and owner. Organization returnedOrg = clientSetup.getRestClient().management().orgs().org( organization.getOrganization() ).get(); assertTrue( returnedOrg != null && returnedOrg.getName().equals( organization.getOrganization() ) ); User returnedUser = returnedOrg.getOwner(); //Assert that the property was retained in the owner of the organization. assertNotNull( returnedUser ); assertEquals( "Apigee", returnedUser.getProperties().get( "company" ) ); } // Admin users are allowed to be created with an email address only, in which a password reset flow is invoked @Test public void createNewOrgUserNoPassword() throws Exception { //User property to see if owner properties exist when created. Map<String, Object> userProperties = new HashMap<String, Object>(); userProperties.put( "company", "Usergrid" ); //Create organization Organization organization = createOrgPayload( "createNewOrgUserNoPassword", userProperties ); //Get back organization response Organization organizationResponse = clientSetup.getRestClient().management().orgs().post( organization ); assertNotNull( organizationResponse ); //Creates token Token token = clientSetup.getRestClient().management().token().post(false,Token.class, new Token( "password", organization.getUsername(), organization.getPassword() ) ,null); this.management().token().setToken(token); assertNotNull( token ); Map<String, Object> newUser = new HashMap<String, Object>(){{put("email", "ed@usergrid.com");}}; clientSetup.getRestClient().management().orgs().org( organization.getOrganization() ).users().post(newUser); // the test will fail if any exception is thrown } /** * Creates a organization with an owner, then attempts to create an organization with the same name ( making sure it * fails) When it fails it verifies that the original is still intact. * @throws Exception */ @Test public void testCreateDuplicateOrgName() throws Exception { // Create organization Organization organization = createOrgPayload( "testCreateDuplicateOrgName", null ); Organization orgCreatedResponse = clientSetup.getRestClient().management().orgs().post( organization ); this.waitForQueueDrainAndRefreshIndex(); assertNotNull( orgCreatedResponse ); // Ensure that the token from the newly created organization works. Token tokenPayload = new Token( "password", organization.getUsername(), organization.getPassword() ); Token tokenReturned = clientSetup.getRestClient().management().token() .post( false, Token.class, tokenPayload, null ); this.management().token().setToken(tokenReturned); assertNotNull( tokenReturned ); // Try to create a organization with the same name as an organization that already exists, ensure that it fails Organization orgTestDuplicatePayload = new Organization( organization.getOrganization(), organization.getUsername() + "test", organization.getEmail() + "test", organization.getName() + "test", organization.getPassword(), null ); try { clientSetup.getRestClient().management().orgs().post( orgTestDuplicatePayload ); fail("Should not have been able to create duplicate organization"); } catch ( ClientErrorException ex ) { errorParse( 400,duplicateUniquePropertyExistsErrorMessage, ex ); } // Post to get token of what should be a non existent user due to the failure of creation above tokenPayload = new Token( "password", organization.getName() + "test", organization.getPassword() ); Token tokenError = null; try { tokenError = clientSetup.getRestClient().management().token().post(false,Token.class, tokenPayload,null ); fail( "Should not have created user" ); } catch ( ClientErrorException ex ) { errorParse( 400,invalidGrantErrorMessage, ex ); } assertNull( tokenError ); } /** * Tests creation of an organization with a duplicate email. Then checks to make sure correct * error message is thrown. Also makes sure that the owner of the duplicate org isn't created * while the original is still intact. * @throws Exception */ @Test public void testCreateDuplicateOrgEmail() throws Exception { Organization organization = createOrgPayload( "testCreateDuplicateOrgEmail", null ); //create the org/owner Organization orgCreatedResponse = clientSetup.getRestClient().management().orgs().post( organization ); this.waitForQueueDrainAndRefreshIndex(); assertNotNull( orgCreatedResponse ); //get token from organization that was created to verify it exists. Token tokenPayload = new Token( "password", organization.getUsername(), organization.getPassword() ); Token tokenReturned = clientSetup.getRestClient().management().token() .post( Token.class, tokenPayload ); assertNotNull( tokenReturned ); //recreate a new payload using a duplicate email Organization orgDuplicatePayload = new Organization( organization.getOrganization()+"test", organization.getUsername()+"test", organization.getEmail(), organization.getName()+"test", organization.getPassword()+"test", null ); //verify that we cannot create an organization that shares a email with another preexisting organization. try { clientSetup.getRestClient().management().orgs().post( orgDuplicatePayload ); fail( "Should not have created organization" ); } catch ( ClientErrorException ex ) { errorParse( 400,duplicateUniquePropertyExistsErrorMessage,ex); } //try to get the token from the organization that failed to be created to verify it was not made. tokenPayload = new Token( "password", organization.getUsername()+"test", organization.getPassword()+"test" ); Token tokenError = null; try { tokenError = clientSetup.getRestClient().management().token().post(false,Token.class, tokenPayload,null ); fail( "Should not have created organization" ); } catch ( ClientErrorException ex ) { errorParse( 400,invalidGrantErrorMessage,ex ); } assertNull( tokenError ); } /** * Creates a organization by setting the information as part of the queryParameters * @throws IOException */ @Test public void testOrgPOSTParams() throws IOException { //Create organization defaults Organization organization = createOrgPayload( "testOrgPOSTParams",null ); //Append them to the end as query parameters QueryParameters queryParameters = new QueryParameters(); queryParameters.setKeyValue( "organization",organization.getOrganization()); queryParameters.setKeyValue( "username",organization.getUsername() ); queryParameters.setKeyValue( "grant_type","password" ); queryParameters.setKeyValue( "email",organization.getEmail() ); queryParameters.setKeyValue( "name",organization.getName() ); queryParameters.setKeyValue( "password",organization.getPassword() ); //Post the organization and verify it worked --> old behavior now we get a bad request try{ Organization organizationReturned = clientSetup.getRestClient().management().orgs().post(queryParameters); fail(); }catch (ClientErrorException e){ assertEquals("ensure bad request",e.getResponse().getStatus(), 400); } // assertNotNull( organizationReturned ); // assertEquals( organization.getOrganization(), organizationReturned.getName()); // // //get token from organization that was created to verify it exists. also sets the current context. // Token tokenPayload = new Token( "password", organization.getName(), organization.getPassword() ); // Token tokenReturned = clientSetup.getRestClient().management().token().post(Token.class, tokenPayload ); // // assertNotNull( tokenReturned ); // // //Assert that the get returns the correct org and owner. // Organization returnedOrg = clientSetup.getRestClient().management().orgs().organization( organization.getOrganization() ).get(); // // assertTrue( returnedOrg != null && returnedOrg.getName().equals(organization.getOrganization()) ); } /** * Creates a organization by posting a form with the organization data. * @throws IOException */ @Test public void testOrgPOSTForm() throws IOException { Organization organization = createOrgPayload( "testOrgPOSTForm",null ); //create the form to hold the organization Form form = new Form(); form.param( "organization", organization.getOrganization() ); form.param( "username", organization.getUsername() ); form.param( "grant_type", "password" ); form.param( "email", organization.getEmail() ); form.param( "name", organization.getName() ); form.param( "password", organization.getPassword() ); //Post the organization and verify it worked. Organization organizationReturned = clientSetup.getRestClient().management().orgs().post( form ); assertNotNull( organizationReturned ); assertEquals(organization.getOrganization(), organizationReturned.getName()); //get token from organization that was created to verify it exists. also sets the current context. Token tokenPayload = new Token( "password", organization.getName(), organization.getPassword() ); Token tokenReturned = clientSetup.getRestClient().management().token().post(false,Token.class, tokenPayload,null); assertNotNull( tokenReturned ); this.management().token().setToken(tokenReturned); //Assert that the get returns the correct org and owner. Organization returnedOrg = clientSetup.getRestClient().management().orgs().org( organization.getOrganization() ).get(); assertTrue(returnedOrg != null && returnedOrg.getName().equals(organization.getOrganization())); } /** * Returns error from unimplemented delete method by trying to call the delete organization endpoint */ @Test public void noOrgDelete() throws IOException { try { // attempt to delete default organization clientSetup.getRestClient().management().orgs().org( clientSetup.getOrganizationName() ).delete(); fail( "Delete is not implemented yet" ); } catch( ServerErrorException see ){ assertEquals( Response.Status.NOT_IMPLEMENTED.getStatusCode(), see.getResponse().getStatus()); } } /** * Creates a regular organization user and then does a get to check the correct username is returned. * @throws Exception */ @Test public void testCreateOrgUserAndReturnCorrectUsername() throws Exception { RestClient restClient = clientSetup.getRestClient(); //Create adminUser values Entity adminUserPayload = new Entity(); String username = "testCreateOrgUserAndReturnCorrectUsername"+UUIDUtils.newTimeUUID(); adminUserPayload.put( "username", username ); adminUserPayload.put( "name", username ); adminUserPayload.put("email", username + "@usergrid.com"); adminUserPayload.put("password", username); //create adminUser ApiResponse adminUserEntityResponse = management().orgs().org( clientSetup.getOrganizationName() ).users().post(ApiResponse.class, adminUserPayload); Entity adminUserResponse = new Entity(adminUserEntityResponse); //verify that the response contains the correct data assertNotNull( adminUserResponse ); assertEquals(username, adminUserResponse.get("username")); //fetch the stored response adminUserResponse = management().users().entity( username ).get(this.getAdminToken(username,username)); // user = ((LinkedHashMap)((LinkedHashMap)adminUserResponse.get("data")).get("user")); //verify that values match stored response assertNotNull( adminUserResponse ); assertEquals( username , adminUserResponse.get( "username" ) ); assertEquals( username, adminUserResponse.get( "name" ) ); assertEquals(username + "@usergrid.com", adminUserResponse.get("email")); } /** * Inserts a value into the default organization then update that value and see if the value persists. * @throws Exception */ @Test public void testOrganizationUpdate() throws Exception { RestClient restClient = clientSetup.getRestClient(); //Setup what will be interested into the organization Map<String, Object> properties = new HashMap<String, Object>(); properties.put( "puppies", 5 ); Organization orgPayload = clientSetup.getOrganization(); orgPayload.put( "properties", properties ); //update the organization. management().orgs().org( clientSetup.getOrganizationName() ).put(orgPayload); this.waitForQueueDrainAndRefreshIndex(); //retrieve the organization Organization orgResponse = management().orgs().org( clientSetup.getOrganizationName() ).get(); assertEquals(5, orgResponse.getProperties().get("puppies" )); //update the value added to the organization properties.put( "puppies", 6 ); orgPayload.put("properties", properties ); //update the organization. management().orgs().org( clientSetup.getOrganizationName() ).put(orgPayload); this.waitForQueueDrainAndRefreshIndex(); orgResponse = management().orgs().org( clientSetup.getOrganizationName() ).get(); assertEquals( 6, orgResponse.getProperties().get( "puppies" )); } @Test public void testOrganizationNoDuplicateConnectionsPUT() throws Exception { RestClient restClient = clientSetup.getRestClient(); //Setup what will be interested into the organization Map<String, Object> properties = new HashMap<String, Object>(); Entity entity = new Entity( properties ); Organization orgPayload = clientSetup.getOrganization(); orgPayload.put( "properties", properties ); //retrieve the organization Organization orgResponse = management().orgs().org( clientSetup.getOrganizationName() ).get(); this.waitForQueueDrainAndRefreshIndex(); //attempt to post duplicate connection Entity userPostResponse = management().orgs().org( clientSetup.getOrganizationName() ).users().user( clientSetup.getEmail() ).put( entity ); Entity duplicateConnectionAdmins = management().orgs().org( clientSetup.getOrganizationName() ).users().get( Entity.class ); ArrayList organizationAdminUsers = ( ArrayList ) duplicateConnectionAdmins.get( "data" ); assertEquals(1,organizationAdminUsers.size() ); } @Test public void testOrganizationNoDuplicateConnectionsPOST() throws Exception { RestClient restClient = clientSetup.getRestClient(); //Setup what will be interested into the organization Map<String, Object> properties = new HashMap<String, Object>(); properties.put( "email",clientSetup.getEmail() ); Entity entity = new Entity( properties ); Organization orgPayload = clientSetup.getOrganization(); orgPayload.put( "properties", properties ); //retrieve the organization Organization orgResponse = management().orgs().org( clientSetup.getOrganizationName() ).get(); this.waitForQueueDrainAndRefreshIndex(); //attempt to post duplicate connection try { Entity userPostResponse = management().orgs().org( clientSetup.getOrganizationName() ).users().post( Entity.class, entity ); }catch(Exception e){ //nom nom nom } Entity duplicateConnectionAdmins = management().orgs().org( clientSetup.getOrganizationName() ).users().get( Entity.class ); ArrayList organizationAdminUsers = ( ArrayList ) duplicateConnectionAdmins.get( "data" ); assertEquals(1,organizationAdminUsers.size() ); } /** * Create an organization payload with almost the same value for everyfield. * @param baseName * @param properties * @return */ public Organization createOrgPayload(String baseName,Map properties){ String orgName = baseName + UUIDUtils.newTimeUUID(); return new Organization( orgName+ UUIDUtils.newTimeUUID(),orgName,orgName+"@usergrid",orgName,orgName, properties); } }