/* * 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.security.encryption; import static org.easymock.EasyMock.createNiceMock; import java.io.File; import java.util.Map; import java.util.Properties; import java.util.concurrent.TimeUnit; import org.apache.ambari.server.AmbariException; import org.apache.ambari.server.configuration.Configuration; import org.apache.ambari.server.security.SecurePasswordHelper; import org.apache.ambari.server.security.credential.PrincipalKeyCredential; import org.apache.ambari.server.state.stack.OsFamily; import org.junit.After; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; import com.google.inject.AbstractModule; import com.google.inject.Guice; import com.google.inject.Injector; import junit.framework.Assert; public class CredentialStoreServiceImplTest { @Rule public TemporaryFolder tmpFolder = new TemporaryFolder(); private CredentialStoreServiceImpl credentialStoreService; private static final String CLUSTER_NAME = "C1"; @Before public void setUp() throws Exception { tmpFolder.create(); final File masterKeyFile = tmpFolder.newFile(Configuration.MASTER_KEY_FILENAME_DEFAULT); Assert.assertTrue(MasterKeyServiceImpl.initializeMasterKeyFile(masterKeyFile, "secret")); Injector injector = Guice.createInjector(new AbstractModule() { @Override protected void configure() { Properties properties = new Properties(); properties.setProperty(Configuration.MASTER_KEY_LOCATION.getKey(), tmpFolder.getRoot().getAbsolutePath()); properties.setProperty(Configuration.MASTER_KEYSTORE_LOCATION.getKey(), tmpFolder.getRoot().getAbsolutePath()); bind(OsFamily.class).toInstance(createNiceMock(OsFamily.class)); bind(SecurePasswordHelper.class).toInstance(new SecurePasswordHelper()); bind(Configuration.class).toInstance(new Configuration(properties)); } }); // Test to make sure the MasterKey file is ok... MasterKeyService masterKeyService = new MasterKeyServiceImpl(masterKeyFile); Assert.assertTrue(masterKeyService.isMasterKeyInitialized()); credentialStoreService = injector.getInstance(CredentialStoreServiceImpl.class); } @After public void tearDown() throws Exception { credentialStoreService = null; tmpFolder.delete(); } @Test public void testSetAndGetCredential_Temporary() throws Exception { PrincipalKeyCredential credential = new PrincipalKeyCredential("username", "password"); credentialStoreService.setCredential(CLUSTER_NAME, "test1", credential, CredentialStoreType.TEMPORARY); Assert.assertEquals(credential, credentialStoreService.getCredential(CLUSTER_NAME, "test1", CredentialStoreType.TEMPORARY)); Assert.assertEquals(credential, credentialStoreService.getCredential(CLUSTER_NAME, "test1")); Assert.assertNull(credentialStoreService.getCredential(CLUSTER_NAME, "test1", CredentialStoreType.PERSISTED)); } @Test public void testSetAndGetCredential_Persisted() throws Exception { PrincipalKeyCredential credential = new PrincipalKeyCredential("username", "password"); credentialStoreService.setCredential(CLUSTER_NAME, "test1", credential, CredentialStoreType.PERSISTED); Assert.assertEquals(credential, credentialStoreService.getCredential(CLUSTER_NAME, "test1", CredentialStoreType.PERSISTED)); Assert.assertEquals(credential, credentialStoreService.getCredential(CLUSTER_NAME, "test1")); Assert.assertNull(credentialStoreService.getCredential(CLUSTER_NAME, "test1", CredentialStoreType.TEMPORARY)); } @Test public void testRemoveCredential_Temporary() throws Exception { PrincipalKeyCredential credential1 = new PrincipalKeyCredential("username1", "password1"); PrincipalKeyCredential credential2 = new PrincipalKeyCredential("username2", "password2"); credentialStoreService.setCredential(CLUSTER_NAME, "test1", credential1, CredentialStoreType.TEMPORARY); credentialStoreService.setCredential(CLUSTER_NAME, "test2", credential2, CredentialStoreType.TEMPORARY); // Nothing should happen if forcing remove from persistent CredentialStore credentialStoreService.removeCredential(CLUSTER_NAME, "test1", CredentialStoreType.PERSISTED); Assert.assertEquals(credential1, credentialStoreService.getCredential(CLUSTER_NAME, "test1", CredentialStoreType.TEMPORARY)); Assert.assertEquals(credential1, credentialStoreService.getCredential(CLUSTER_NAME, "test1")); // Remove should happen if forcing remove from temporary CredentialStore credentialStoreService.removeCredential(CLUSTER_NAME, "test1", CredentialStoreType.TEMPORARY); Assert.assertNull(credentialStoreService.getCredential(CLUSTER_NAME, "test1", CredentialStoreType.TEMPORARY)); Assert.assertNull(credentialStoreService.getCredential(CLUSTER_NAME, "test1")); // The other credentials should remain untouched Assert.assertEquals(credential2, credentialStoreService.getCredential(CLUSTER_NAME, "test2")); } @Test public void testRemoveCredential_Persisted() throws Exception { PrincipalKeyCredential credential1 = new PrincipalKeyCredential("username1", "password1"); PrincipalKeyCredential credential2 = new PrincipalKeyCredential("username2", "password2"); credentialStoreService.setCredential(CLUSTER_NAME, "test1", credential1, CredentialStoreType.PERSISTED); credentialStoreService.setCredential(CLUSTER_NAME, "test2", credential2, CredentialStoreType.PERSISTED); // Nothing should happen if forcing remove from temporary CredentialStore credentialStoreService.removeCredential(CLUSTER_NAME, "test1", CredentialStoreType.TEMPORARY); Assert.assertEquals(credential1, credentialStoreService.getCredential(CLUSTER_NAME, "test1", CredentialStoreType.PERSISTED)); Assert.assertEquals(credential1, credentialStoreService.getCredential(CLUSTER_NAME, "test1")); // Remove should happen if forcing remove from persistent CredentialStore credentialStoreService.removeCredential(CLUSTER_NAME, "test1", CredentialStoreType.PERSISTED); Assert.assertNull(credentialStoreService.getCredential(CLUSTER_NAME, "test1", CredentialStoreType.PERSISTED)); Assert.assertNull(credentialStoreService.getCredential(CLUSTER_NAME, "test1")); // The other credentials should remain untouched Assert.assertEquals(credential2, credentialStoreService.getCredential(CLUSTER_NAME, "test2")); } @Test public void testRemoveCredential_Either() throws Exception { PrincipalKeyCredential credential1 = new PrincipalKeyCredential("username1", "password1"); PrincipalKeyCredential credential2 = new PrincipalKeyCredential("username2", "password2"); PrincipalKeyCredential credential3 = new PrincipalKeyCredential("username3", "password3"); PrincipalKeyCredential credential4 = new PrincipalKeyCredential("username4", "password4"); credentialStoreService.setCredential(CLUSTER_NAME, "test1", credential1, CredentialStoreType.PERSISTED); credentialStoreService.setCredential(CLUSTER_NAME, "test2", credential2, CredentialStoreType.PERSISTED); credentialStoreService.setCredential(CLUSTER_NAME, "test3", credential3, CredentialStoreType.TEMPORARY); credentialStoreService.setCredential(CLUSTER_NAME, "test4", credential4, CredentialStoreType.TEMPORARY); credentialStoreService.removeCredential(CLUSTER_NAME, "test1"); Assert.assertNull(credentialStoreService.getCredential(CLUSTER_NAME, "test1", CredentialStoreType.PERSISTED)); Assert.assertNull(credentialStoreService.getCredential(CLUSTER_NAME, "test1")); Assert.assertEquals(credential2, credentialStoreService.getCredential(CLUSTER_NAME, "test2")); Assert.assertEquals(credential3, credentialStoreService.getCredential(CLUSTER_NAME, "test3")); Assert.assertEquals(credential4, credentialStoreService.getCredential(CLUSTER_NAME, "test4")); credentialStoreService.removeCredential(CLUSTER_NAME, "test3"); Assert.assertNull(credentialStoreService.getCredential(CLUSTER_NAME, "test1")); Assert.assertEquals(credential2, credentialStoreService.getCredential(CLUSTER_NAME, "test2")); Assert.assertNull(credentialStoreService.getCredential(CLUSTER_NAME, "test3")); Assert.assertEquals(credential4, credentialStoreService.getCredential(CLUSTER_NAME, "test4")); } @Test public void testUpdateCredential() throws Exception { PrincipalKeyCredential credential1 = new PrincipalKeyCredential("username1", "password1"); PrincipalKeyCredential credential2 = new PrincipalKeyCredential("username2", "password2"); credentialStoreService.setCredential(CLUSTER_NAME, "test1", credential1, CredentialStoreType.PERSISTED); Assert.assertEquals(credential1, credentialStoreService.getCredential(CLUSTER_NAME, "test1", CredentialStoreType.PERSISTED)); Assert.assertNull(credentialStoreService.getCredential(CLUSTER_NAME, "test1", CredentialStoreType.TEMPORARY)); Assert.assertEquals(credential1, credentialStoreService.getCredential(CLUSTER_NAME, "test1")); credentialStoreService.setCredential(CLUSTER_NAME, "test1", credential1, CredentialStoreType.TEMPORARY); Assert.assertEquals(credential1, credentialStoreService.getCredential(CLUSTER_NAME, "test1", CredentialStoreType.TEMPORARY)); Assert.assertNull(credentialStoreService.getCredential(CLUSTER_NAME, "test1", CredentialStoreType.PERSISTED)); Assert.assertEquals(credential1, credentialStoreService.getCredential(CLUSTER_NAME, "test1")); credentialStoreService.setCredential(CLUSTER_NAME, "test1", credential2, CredentialStoreType.PERSISTED); Assert.assertEquals(credential2, credentialStoreService.getCredential(CLUSTER_NAME, "test1", CredentialStoreType.PERSISTED)); Assert.assertNull(credentialStoreService.getCredential(CLUSTER_NAME, "test1", CredentialStoreType.TEMPORARY)); Assert.assertEquals(credential2, credentialStoreService.getCredential(CLUSTER_NAME, "test1")); } @Test public void testContainsCredential() throws Exception { PrincipalKeyCredential credential1 = new PrincipalKeyCredential("username1", "password1"); PrincipalKeyCredential credential2 = new PrincipalKeyCredential("username2", "password2"); PrincipalKeyCredential credential3 = new PrincipalKeyCredential("username3", "password3"); PrincipalKeyCredential credential4 = new PrincipalKeyCredential("username4", "password4"); credentialStoreService.setCredential(CLUSTER_NAME, "test1", credential1, CredentialStoreType.PERSISTED); credentialStoreService.setCredential(CLUSTER_NAME, "test2", credential2, CredentialStoreType.PERSISTED); credentialStoreService.setCredential(CLUSTER_NAME, "test3", credential3, CredentialStoreType.TEMPORARY); credentialStoreService.setCredential(CLUSTER_NAME, "test4", credential4, CredentialStoreType.TEMPORARY); Assert.assertTrue(credentialStoreService.containsCredential(CLUSTER_NAME, "test1", CredentialStoreType.PERSISTED)); Assert.assertFalse(credentialStoreService.containsCredential(CLUSTER_NAME, "test1", CredentialStoreType.TEMPORARY)); Assert.assertFalse(credentialStoreService.containsCredential(CLUSTER_NAME, "test3", CredentialStoreType.PERSISTED)); Assert.assertFalse(credentialStoreService.containsCredential(CLUSTER_NAME, "test1", CredentialStoreType.TEMPORARY)); Assert.assertFalse(credentialStoreService.containsCredential(CLUSTER_NAME, "test3", CredentialStoreType.PERSISTED)); Assert.assertTrue(credentialStoreService.containsCredential(CLUSTER_NAME, "test3", CredentialStoreType.TEMPORARY)); Assert.assertTrue(credentialStoreService.containsCredential(CLUSTER_NAME, "test1")); Assert.assertTrue(credentialStoreService.containsCredential(CLUSTER_NAME, "test3")); } @Test public void testIsCredentialPersisted() throws Exception { PrincipalKeyCredential credential1 = new PrincipalKeyCredential("username1", "password1"); PrincipalKeyCredential credential2 = new PrincipalKeyCredential("username2", "password2"); PrincipalKeyCredential credential3 = new PrincipalKeyCredential("username3", "password3"); PrincipalKeyCredential credential4 = new PrincipalKeyCredential("username4", "password4"); credentialStoreService.setCredential(CLUSTER_NAME, "test1", credential1, CredentialStoreType.PERSISTED); credentialStoreService.setCredential(CLUSTER_NAME, "test2", credential2, CredentialStoreType.PERSISTED); credentialStoreService.setCredential(CLUSTER_NAME, "test3", credential3, CredentialStoreType.TEMPORARY); credentialStoreService.setCredential(CLUSTER_NAME, "test4", credential4, CredentialStoreType.TEMPORARY); Assert.assertEquals(CredentialStoreType.PERSISTED, credentialStoreService.getCredentialStoreType(CLUSTER_NAME, "test1")); Assert.assertEquals(CredentialStoreType.PERSISTED, credentialStoreService.getCredentialStoreType(CLUSTER_NAME, "test2")); Assert.assertEquals(CredentialStoreType.TEMPORARY, credentialStoreService.getCredentialStoreType(CLUSTER_NAME, "test3")); Assert.assertEquals(CredentialStoreType.TEMPORARY, credentialStoreService.getCredentialStoreType(CLUSTER_NAME, "test4")); try { credentialStoreService.getCredentialStoreType(CLUSTER_NAME, "test5"); Assert.fail("Expected AmbariException to be thrown"); } catch (AmbariException e) { // expected } } @Test public void testListCredentials() throws Exception { PrincipalKeyCredential credential1 = new PrincipalKeyCredential("username1", "password1"); PrincipalKeyCredential credential2 = new PrincipalKeyCredential("username2", "password2"); PrincipalKeyCredential credential3 = new PrincipalKeyCredential("username3", "password3"); PrincipalKeyCredential credential4 = new PrincipalKeyCredential("username4", "password4"); credentialStoreService.setCredential(CLUSTER_NAME, "test1", credential1, CredentialStoreType.PERSISTED); credentialStoreService.setCredential(CLUSTER_NAME, "test2", credential2, CredentialStoreType.PERSISTED); credentialStoreService.setCredential(CLUSTER_NAME, "test3", credential3, CredentialStoreType.TEMPORARY); credentialStoreService.setCredential(CLUSTER_NAME, "test4", credential4, CredentialStoreType.TEMPORARY); Map<String, CredentialStoreType> credentials = credentialStoreService.listCredentials(CLUSTER_NAME); Assert.assertNotNull(credentials); Assert.assertEquals(4, credentials.size()); Assert.assertEquals(CredentialStoreType.PERSISTED, credentials.get("test1")); Assert.assertEquals(CredentialStoreType.PERSISTED, credentials.get("test2")); Assert.assertEquals(CredentialStoreType.TEMPORARY, credentials.get("test3")); Assert.assertEquals(CredentialStoreType.TEMPORARY, credentials.get("test4")); } @Test(expected = AmbariException.class) public void testFailToReinitialize_Persisted() throws Exception { // This should throw an exception not matter what the arguments are.... credentialStoreService.initializePersistedCredentialStore(null, null); } @Test(expected = AmbariException.class) public void testFailToReinitialize_Temporary() throws Exception { // This should throw an exception not matter what the arguments are.... credentialStoreService.initializeTemporaryCredentialStore(1, TimeUnit.MINUTES, false); } @Test public void testFailNotInitialized() throws Exception { Configuration configuration = new Configuration(new Properties()); CredentialStoreService uninitializedCredentialStoreService = new CredentialStoreServiceImpl(configuration, new SecurePasswordHelper()); PrincipalKeyCredential credential1 = new PrincipalKeyCredential("username1", "password1"); // The temporary store should always be initialized.... this should succeed. uninitializedCredentialStoreService.setCredential(CLUSTER_NAME, "test1", credential1, CredentialStoreType.TEMPORARY); try { uninitializedCredentialStoreService.setCredential(CLUSTER_NAME, "test1", credential1, CredentialStoreType.PERSISTED); Assert.fail("AmbariException should have been thrown"); } catch (AmbariException e) { // This is expected... } } }