/* * Copyright 2012-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"). * You may not use this file except in compliance with the License. * A copy of the License is located at * * http://aws.amazon.com/apache2.0 * * or in the "license" file accompanying this file. This file 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 com.amazonaws.auth.profile; import com.amazonaws.AmazonClientException; import com.amazonaws.auth.AWSCredentials; import com.amazonaws.auth.AWSSessionCredentials; import com.amazonaws.auth.BasicAWSCredentials; import com.amazonaws.auth.profile.internal.Profile; import org.junit.Test; import java.io.File; import java.io.IOException; import java.net.URISyntaxException; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; public class CredentialProfilesTest { /** * Name of the default profile used in the configuration file. */ private static final String DEFAULT_PROFILE_NAME = "default"; /** * Name of the sample test profile used during testing. */ private static final String PROFILE_NAME_TEST = "test"; @Test(expected = IllegalArgumentException.class) public void loadProfileFromNonExistentFile() { new ProfilesConfigFile(new File("/some/invalid/file/location.txt")); } /** * Tests two profiles having same name. The second profile overrides the first profile. Also * checks if the AWS Access Key ID and AWS Secret Access Key are mapped properly under the * profile. */ @Test public void testTwoProfileWithSameName() throws URISyntaxException { ProfilesConfigFile profile = new ProfilesConfigFile( ProfileResourceLoader.profilesWithSameProfileName().asFile()); AWSCredentials defaultCred = profile.getCredentials(DEFAULT_PROFILE_NAME); assertNotNull(defaultCred); assertTrue(defaultCred instanceof BasicAWSCredentials); AWSCredentials testCred = profile.getCredentials(PROFILE_NAME_TEST); assertNotNull(testCred); assertTrue(testCred instanceof AWSSessionCredentials); AWSSessionCredentials testSessionCred = (AWSSessionCredentials) testCred; assertEquals(testSessionCred.getAWSAccessKeyId(), "testProfile2"); assertEquals(testSessionCred.getAWSSecretKey(), "testProfile2"); assertEquals(testSessionCred.getSessionToken(), "testProfile2"); } /** * Tests loading profile with a profile name having only spaces. An exception should be thrown * in this case. */ @Test public void testProfileNameWithJustSpaces() { checkExpectedException(ProfileResourceLoader.profileNameWithSpaces(), AmazonClientException.class, "Should throw an exception as there is a profile mentioned with no profile name."); } /** * Tests loading profile with a profile name not mentioned. An exception should be thrown in * this case. */ @Test public void testProfileWithNoProfileNameGiven() { checkExpectedException(ProfileResourceLoader.profilesWithNoProfileName(), AmazonClientException.class, "Should throw an exception as there is a profile mentioned with only spaces."); } /** * Tests loading profile with a profile name not having opening or closing braces. An exception * should be thrown in this case. */ @Test public void testProfileWithProfileNameNotHavingOpeningOrClosingBraces() { checkExpectedException(ProfileResourceLoader.profileNameWithNoClosingBraces(), IllegalArgumentException.class, "Should throw an exception as there is a profile name mentioned with no closing braces."); checkExpectedException(ProfileResourceLoader.profileNameWithNoOpeningBraces(), IllegalArgumentException.class, "Should throw an exception as there is a profile name mentioned with no opening braces."); checkExpectedException(ProfileResourceLoader.profileNameWithNoBraces(), IllegalArgumentException.class, "Should throw an exception as there is a profile name mentioned with no braces."); } /** * Tests loading profile with AWS Access Key not specified for a profile. An exception should be * thrown in this case. */ @Test public void testProfileWithAccessKeyNotSpecified() throws URISyntaxException { checkDeferredException(ProfileResourceLoader.accessKeyNotSpecified(), AmazonClientException.class, "test2", "Should throw an exception as there is a profile with AWS Access Key ID not specified."); } @Test public void testProfileWithEmptyAccessKey() throws URISyntaxException { checkDeferredException(ProfileResourceLoader.profileWithEmptyAccessKey(), AmazonClientException.class, "test", "Should throw an exception as there is a profile with an empty AWS Access Key ID"); } /** * Tests loading profile with AWS Secret Access Key not specified for a profile. An exception * should be thrown in this case. */ @Test public void testProfileWithSecretAccessKeyNotSpecified() throws Exception { checkDeferredException(ProfileResourceLoader.profilesWithSecretAccessKeyNotSpecified(), AmazonClientException.class, "profile test2", "Should throw an exception as there is a profile with AWS Secret Access Key not specified."); } @Test public void testProfileWithEmptySecretAccessKey() throws URISyntaxException { checkDeferredException(ProfileResourceLoader.profileWithEmptySecretKey(), AmazonClientException.class, "test", "Should throw an exception as there is a profile with an empty AWS Secret Access Key."); } /** * Tests loading profile with a profile having multiple AWS Access Key ID's. An exception should * be thrown in this case. */ @Test public void testProfileWithMultipleAccessOrSecretKeysUnderSameProfile() { checkExpectedException(ProfileResourceLoader.profilesWithTwoAccessKeyUnderSameProfile(), IllegalArgumentException.class, "Should throw an exception as there is a profile with two AWS Access Key ID's."); } /** * Tests loading profile with a file that contains other configuration informations like region, * output format etc., The file should be parsed correctly and the profiles must be loaded. */ @Test public void testProfileWithOtherConfigurations() throws URISyntaxException { ProfilesConfigFile profile = new ProfilesConfigFile( ProfileResourceLoader.profilesContainingOtherConfiguration().asFile()); assertNotNull(profile.getCredentials(DEFAULT_PROFILE_NAME)); assertNotNull(profile.getCredentials(PROFILE_NAME_TEST)); assertEquals(profile.getCredentials(PROFILE_NAME_TEST).getAWSAccessKeyId(), "test"); assertEquals(profile.getCredentials(PROFILE_NAME_TEST).getAWSSecretKey(), "test key"); } /** * Test verifying we pick up a change to a file. */ @Test public void testReadUpdatedProfile() throws URISyntaxException, IOException { ProfilesConfigFile fixture = new ProfilesConfigFile( ProfileResourceLoader.basicProfile().asFile()); File modifiable = File.createTempFile("UpdatableProfile", ".tst"); ProfilesConfigFileWriter.dumpToFile(modifiable, true, fixture.getAllProfiles().values() .toArray(new Profile[1])); ProfilesConfigFile test = new ProfilesConfigFile(modifiable); AWSCredentials orig = test.getCredentials(DEFAULT_PROFILE_NAME); assertEquals("defaultAccessKey", orig.getAWSAccessKeyId()); assertEquals("defaultSecretAccessKey", orig.getAWSSecretKey()); //Sleep to ensure that the timestamp on the file (when we modify it) is //distinguishably later from the original write. try { Thread.sleep(2000); } catch (Exception e) { } Profile newProfile = new Profile(DEFAULT_PROFILE_NAME, new BasicAWSCredentials("newAccessKey", "newSecretKey")); ProfilesConfigFileWriter.modifyOneProfile(modifiable, DEFAULT_PROFILE_NAME, newProfile); test.refresh(); AWSCredentials updated = test.getCredentials(DEFAULT_PROFILE_NAME); assertEquals("newAccessKey", updated.getAWSAccessKeyId()); assertEquals("newSecretKey", updated.getAWSSecretKey()); } /** * Tests loading a profile that assumes a role, but the source profile does not exist. */ @Test public void testRoleProfileWithNoSourceName() throws URISyntaxException { checkDeferredException(ProfileResourceLoader.roleProfileWithNoSourceName(), AmazonClientException.class, "test", "Should throw an exception as there is a role profile with a missing source role"); } /** * Tests loading a profile that assumes a role, but the source profile does not exist. */ @Test public void testRoleProfileWithEmptySourceName() throws URISyntaxException { checkDeferredException(ProfileResourceLoader.roleProfileWithEmptySourceName(), AmazonClientException.class, "test", "Should throw an exception as there is a role profile with an empty source role"); } /** * Tests loading a profile that assumes a role, but the source profile does not exist. */ @Test public void testRoleProfileMissingSource() throws URISyntaxException { checkDeferredException(ProfileResourceLoader.roleProfileMissingSource(), AmazonClientException.class, "test", "Should throw an exception as there is a role profile without a source specified"); } /** * Tests loading a profile that assumes a role, but the source profile does not exist. */ @Test public void testRoleProfileWithRoleSource() throws URISyntaxException { checkDeferredException(ProfileResourceLoader.roleProfileWithRoleSource(), AmazonClientException.class, "test", "Should throw an exception as a role profile can not use a role profile as its source"); } /** * Configures the Profile with the data returned from the file. Throws an error if the * configuration is success as the file contains data not in the correct format. * * @param resource Resource object to source profiles from. * @param failureMessage failure message to be displayed if the file configuration is success */ private void checkExpectedException(ProfileResourceLoader resource, Class<? extends Exception> expectedExceptionClass, String failureMessage) { try { new ProfilesConfigFile(resource.asFile()); fail(failureMessage); } catch (Exception e) { if (!expectedExceptionClass.isInstance(e)) { throw new RuntimeException(e); } } } private void checkDeferredException(ProfileResourceLoader resource, Class<? extends Exception> expectedExceptionClass, String profileName, String failureMessage) throws URISyntaxException { ProfilesConfigFile configFile = new ProfilesConfigFile(resource.asFile()); try { configFile.getCredentials(profileName); fail(failureMessage); } catch (Exception e) { if (!expectedExceptionClass.isInstance(e)) { throw new RuntimeException(e); } } } }