Return-Path: X-Original-To: archive-asf-public-internal@cust-asf2.ponee.io Delivered-To: archive-asf-public-internal@cust-asf2.ponee.io Received: from cust-asf.ponee.io (cust-asf.ponee.io [163.172.22.183]) by cust-asf2.ponee.io (Postfix) with ESMTP id 13871200B96 for ; Thu, 6 Oct 2016 20:46:08 +0200 (CEST) Received: by cust-asf.ponee.io (Postfix) id 12133160ADB; Thu, 6 Oct 2016 18:46:08 +0000 (UTC) Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by cust-asf.ponee.io (Postfix) with SMTP id 0911B160AC5 for ; Thu, 6 Oct 2016 20:46:06 +0200 (CEST) Received: (qmail 39932 invoked by uid 500); 6 Oct 2016 18:46:06 -0000 Mailing-List: contact commits-help@ambari.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: ambari-dev@ambari.apache.org Delivered-To: mailing list commits@ambari.apache.org Received: (qmail 39923 invoked by uid 99); 6 Oct 2016 18:46:06 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 06 Oct 2016 18:46:06 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id F0BCADFF55; Thu, 6 Oct 2016 18:46:05 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: smnaha@apache.org To: commits@ambari.apache.org Message-Id: X-Mailer: ASF-Git Admin Mailer Subject: ambari git commit: AMBARI-18540: Unit test cases required for verifying Ambari username case sensitivity Date: Thu, 6 Oct 2016 18:46:05 +0000 (UTC) archived-at: Thu, 06 Oct 2016 18:46:08 -0000 Repository: ambari Updated Branches: refs/heads/branch-2.4 ffa1bbf63 -> f51fdcc19 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/f51fdcc1 Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/f51fdcc1 Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/f51fdcc1 Branch: refs/heads/branch-2.4 Commit: f51fdcc192d71f879cbe557aa5a3974853096213 Parents: ffa1bbf Author: Nahappan Somasundaram Authored: Wed Oct 5 17:25:20 2016 -0700 Committer: Nahappan Somasundaram Committed: Thu Oct 6 11:44:08 2016 -0700 ---------------------------------------------------------------------- .../internal/UserResourceProviderDBTest.java | 280 +++++++++++++++++++ 1 file changed, 280 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/f51fdcc1/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..f3445d7 --- /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_KEY, JDBC_IN_MEMORY_URL_CREATE); + properties.setProperty(Configuration.SERVER_JDBC_DRIVER_KEY, Configuration.JDBC_IN_MEMROY_DRIVER); + injector = Guice.createInjector(testModule); + + injector.getInstance(PersistService.class).start(); + + amc = injector.getInstance(AmbariManagementController.class); + + Set propertyIds = PropertyHelper.getPropertyIds(userType); + Map 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 requestProperties = new HashMap(); + 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(Arrays.asList("Users"))); + Predicate predicate = new PredicateBuilder() + .property(UserResourceProvider.USER_USERNAME_PROPERTY_ID).equals("viewUser").toPredicate(); + Set 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 requestProperties = new HashMap(); + 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(Arrays.asList("Users"))); + Set 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 requestProperties = new HashMap(); + 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(Arrays.asList("Users"))); + Predicate predicate = new PredicateBuilder() + .property(UserResourceProvider.USER_USERNAME_PROPERTY_ID).equals("viewuser").toPredicate(); + Set 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 userNames = Arrays.asList("user1", "uSer2", "User3", "useR4"); + + for (String userName : userNames) { + Map requestProperties = new HashMap(); + 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(Arrays.asList("Users"))); + Set 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); + } +}