AMBARI-18540: Unit test cases required for verifying Ambari username case sensitivity
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/569020ca Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/569020ca Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/569020ca Branch: refs/heads/branch-dev-patch-upgrade Commit: 569020caf1c6f39765d7da9efb8c57b66293844e Parents: 8813b1f Author: Nahappan Somasundaram <[email protected]> Authored: Wed Oct 5 17:25:20 2016 -0700 Committer: Nahappan Somasundaram <[email protected]> Committed: Fri Oct 7 14:22:27 2016 -0700 ---------------------------------------------------------------------- .../internal/UserResourceProviderDBTest.java | 280 +++++++++++++++++++ 1 file changed, 280 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/569020ca/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/UserResourceProviderDBTest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/UserResourceProviderDBTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/UserResourceProviderDBTest.java new file mode 100644 index 0000000..1629b49 --- /dev/null +++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/UserResourceProviderDBTest.java @@ -0,0 +1,280 @@ +/** + * 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.ambari.server.controller.internal; + +import com.google.inject.Guice; +import com.google.inject.Injector; +import com.google.inject.persist.PersistService; +import org.apache.ambari.server.configuration.Configuration; +import org.apache.ambari.server.controller.AmbariManagementController; +import org.apache.ambari.server.controller.spi.Predicate; +import org.apache.ambari.server.controller.spi.Request; +import org.apache.ambari.server.controller.spi.RequestStatus; +import org.apache.ambari.server.controller.spi.Resource; +import org.apache.ambari.server.controller.utilities.PredicateBuilder; +import org.apache.ambari.server.controller.utilities.PropertyHelper; +import org.apache.ambari.server.orm.InMemoryDefaultTestModule; +import org.apache.ambari.server.security.TestAuthenticationFactory; +import org.apache.ambari.server.security.authorization.AuthorizationHelper; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; + +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.Set; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.assertEquals; + +/** + * Tests creation, retrieval and deletion of users using an in-memory database. + * Also tests user creation and retrieval using usernames that differ only by case. + * Verifies that usernames are stored as provided. + */ +@PrepareForTest({AuthorizationHelper.class}) +public class UserResourceProviderDBTest { + private static Injector injector; + private static AmbariManagementController amc; + private static Resource.Type userType = Resource.Type.User; + private static UserResourceProvider userResourceProvider; + private static String JDBC_IN_MEMORY_URL_CREATE = + String.format("jdbc:derby:memory:myDB/%s;create=true", Configuration.DEFAULT_DERBY_SCHEMA); + private static String JDBC_IN_MEMORY_URL_DROP = + String.format("jdbc:derby:memory:myDB/%s;drop=true", Configuration.DEFAULT_DERBY_SCHEMA); + + /** + * Sets up the in-memory database for the test suite. + */ + @BeforeClass + public static void setupInMemoryDB() { + InMemoryDefaultTestModule testModule = new InMemoryDefaultTestModule(); + + Properties properties = testModule.getProperties(); + properties.setProperty(Configuration.SERVER_JDBC_URL.getKey(), JDBC_IN_MEMORY_URL_CREATE); + properties.setProperty(Configuration.SERVER_JDBC_DRIVER.getKey(), Configuration.JDBC_IN_MEMORY_DRIVER); + injector = Guice.createInjector(testModule); + + injector.getInstance(PersistService.class).start(); + + amc = injector.getInstance(AmbariManagementController.class); + + Set<String> propertyIds = PropertyHelper.getPropertyIds(userType); + Map<Resource.Type,String> keyPropertyIds = PropertyHelper.getKeyPropertyIds(userType); + + userResourceProvider = new UserResourceProvider(propertyIds, keyPropertyIds, amc); + } + + /** + * Closes the JPA connection after executing the test suite. + */ + @AfterClass + public static void teardownInMemoryDB() { + if (injector != null) { + injector.getInstance(PersistService.class).stop(); + } + } + + /** + * Creates a user, retrieves it and verifies that the username matches the one that was + * created. Deletes the created user and verifies that the username was deleted. + * + * @throws Exception + */ + @Test + public void createUserTest() throws Exception { + Authentication authentication = TestAuthenticationFactory.createAdministrator(); + SecurityContextHolder.getContext().setAuthentication(authentication); + + // create a new user viewUser + Map<String, Object> requestProperties = new HashMap<String, Object>(); + requestProperties.put(UserResourceProvider.USER_USERNAME_PROPERTY_ID, "viewUser"); + requestProperties.put(UserResourceProvider.USER_PASSWORD_PROPERTY_ID, "password"); + requestProperties.put(UserResourceProvider.USER_ADMIN_PROPERTY_ID, false); + requestProperties.put(UserResourceProvider.USER_ACTIVE_PROPERTY_ID, true); + + Request request = PropertyHelper.getCreateRequest(Collections.singleton(requestProperties), null); + RequestStatus requestStatus = userResourceProvider.createResources(request); + assertNotNull(requestStatus); + + // verify the created username + Request getRequest = PropertyHelper.getReadRequest(new HashSet<String>(Arrays.asList("Users"))); + Predicate predicate = new PredicateBuilder() + .property(UserResourceProvider.USER_USERNAME_PROPERTY_ID).equals("viewUser").toPredicate(); + Set<Resource> resources = userResourceProvider.getResources(getRequest, predicate); + assertEquals(resources.size(), 1); + Resource resource = resources.iterator().next(); + + String userName = resource.getPropertyValue(UserResourceProvider.USER_USERNAME_PROPERTY_ID).toString(); + assertEquals(userName, "viewUser"); + + // delete the created username + requestStatus = userResourceProvider.deleteResources(request, predicate); + assertNotNull(requestStatus); + + // verify that the username was deleted + resources = userResourceProvider.getResources(getRequest, null); + assertEquals(resources.size(), 0); + } + + /** + * Creates a username in all lowercase. Attempt to add another user whose username differs only + * by case to the previously added user. Verifies that the user cannot be added. + * + * @throws Exception + */ + @Test + public void createExistingUserTest() throws Exception { + Authentication authentication = TestAuthenticationFactory.createAdministrator(); + SecurityContextHolder.getContext().setAuthentication(authentication); + + /* add a new user */ + Map<String, Object> requestProperties = new HashMap<String, Object>(); + requestProperties.put(UserResourceProvider.USER_USERNAME_PROPERTY_ID, "abcd"); + requestProperties.put(UserResourceProvider.USER_PASSWORD_PROPERTY_ID, "password"); + requestProperties.put(UserResourceProvider.USER_ADMIN_PROPERTY_ID, false); + requestProperties.put(UserResourceProvider.USER_ACTIVE_PROPERTY_ID, true); + + Request request = PropertyHelper.getCreateRequest(Collections.singleton(requestProperties), null); + RequestStatus requestStatus = userResourceProvider.createResources(request); + assertNotNull(requestStatus); + + /* try with uppercase version of an existing user */ + requestProperties.put(UserResourceProvider.USER_USERNAME_PROPERTY_ID, "ABCD"); + request = PropertyHelper.getCreateRequest(Collections.singleton(requestProperties), null); + try { + requestStatus = userResourceProvider.createResources(request); + assertTrue("Should fail with user exists", false); + } + catch(Exception ex) { + assertTrue(ex.getMessage().contains("User abcd already exists")); + } + + // delete the created username + Predicate predicate = new PredicateBuilder() + .property(UserResourceProvider.USER_USERNAME_PROPERTY_ID).equals("abcd").toPredicate(); + requestStatus = userResourceProvider.deleteResources(request, predicate); + assertNotNull(requestStatus); + + // verify that the username was deleted + Request getRequest = PropertyHelper.getReadRequest(new HashSet<String>(Arrays.asList("Users"))); + Set<Resource> resources = userResourceProvider.getResources(getRequest, null); + assertEquals(resources.size(), 0); + } + + /** + * Creates a user and retrieves the user using the same username but in lowercase. Verifies + * that the retrieval is successful and that the retrieved username is the same as the one + * that was used during creation. + * + * @throws Exception + */ + @Test + public void getExistingUserCaseInsensitiveTest() throws Exception { + Authentication authentication = TestAuthenticationFactory.createAdministrator(); + SecurityContextHolder.getContext().setAuthentication(authentication); + + // create a new user viewUser + Map<String, Object> requestProperties = new HashMap<String, Object>(); + requestProperties.put(UserResourceProvider.USER_USERNAME_PROPERTY_ID, "viewUser"); + requestProperties.put(UserResourceProvider.USER_PASSWORD_PROPERTY_ID, "password"); + requestProperties.put(UserResourceProvider.USER_ADMIN_PROPERTY_ID, false); + requestProperties.put(UserResourceProvider.USER_ACTIVE_PROPERTY_ID, true); + + Request request = PropertyHelper.getCreateRequest(Collections.singleton(requestProperties), null); + RequestStatus requestStatus = userResourceProvider.createResources(request); + assertNotNull(requestStatus); + + // verify the created username + Request getRequest = PropertyHelper.getReadRequest(new HashSet<String>(Arrays.asList("Users"))); + Predicate predicate = new PredicateBuilder() + .property(UserResourceProvider.USER_USERNAME_PROPERTY_ID).equals("viewuser").toPredicate(); + Set<Resource> resources = userResourceProvider.getResources(getRequest, predicate); + assertEquals(resources.size(), 1); + Resource resource = resources.iterator().next(); + + String userName = resource.getPropertyValue(UserResourceProvider.USER_USERNAME_PROPERTY_ID).toString(); + assertEquals(userName, "viewUser"); + + // delete the created username + requestStatus = userResourceProvider.deleteResources(request, predicate); + assertNotNull(requestStatus); + + // verify that the username was deleted + resources = userResourceProvider.getResources(getRequest, null); + assertEquals(resources.size(), 0); + } + + /** + * Adds an array of users, retrieves the users and verifies that the usernames do not differ + * from the ones that were used during creation. + * + * @throws Exception + */ + @Test + public void getAllUserTest() throws Exception { + Authentication authentication = TestAuthenticationFactory.createAdministrator(); + SecurityContextHolder.getContext().setAuthentication(authentication); + + List<String> userNames = Arrays.asList("user1", "uSer2", "User3", "useR4"); + + for (String userName : userNames) { + Map<String, Object> requestProperties = new HashMap<String, Object>(); + requestProperties.put(UserResourceProvider.USER_USERNAME_PROPERTY_ID, userName); + requestProperties.put(UserResourceProvider.USER_PASSWORD_PROPERTY_ID, "password"); + requestProperties.put(UserResourceProvider.USER_ADMIN_PROPERTY_ID, false); + requestProperties.put(UserResourceProvider.USER_ACTIVE_PROPERTY_ID, true); + + Request request = PropertyHelper.getCreateRequest(Collections.singleton(requestProperties), null); + RequestStatus requestStatus = userResourceProvider.createResources(request); + assertNotNull(requestStatus); + } + + // verify the created username + Request getRequest = PropertyHelper.getReadRequest(new HashSet<String>(Arrays.asList("Users"))); + Set<Resource> resources = userResourceProvider.getResources(getRequest, null); + assertEquals(resources.size(), userNames.size()); + for (Resource resource : resources) { + String userName = resource.getPropertyValue(UserResourceProvider.USER_USERNAME_PROPERTY_ID).toString(); + assertTrue(userNames.contains(userName)); + } + + // delete the users + for (String userName : userNames) { + Predicate predicate = new PredicateBuilder() + .property(UserResourceProvider.USER_USERNAME_PROPERTY_ID).equals(userName).toPredicate(); + RequestStatus requestStatus = userResourceProvider.deleteResources(null /* not used */, predicate); + assertNotNull(requestStatus); + } + + // verify that the username was deleted + resources = userResourceProvider.getResources(getRequest, null); + assertEquals(resources.size(), 0); + } +}
