/* * Copyright 2011-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. * You may obtain a copy of the License at: * * http://aws.amazon.com/apache2.0 * * 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; import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; import static com.github.tomakehurst.wiremock.client.WireMock.get; import static com.github.tomakehurst.wiremock.client.WireMock.stubFor; import static com.github.tomakehurst.wiremock.client.WireMock.urlPathEqualTo; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.fail; import java.net.URI; import java.net.URISyntaxException; import org.joda.time.DateTime; import org.junit.Assert; import org.junit.Before; import org.junit.BeforeClass; import org.junit.ClassRule; import org.junit.Test; import com.amazonaws.AmazonClientException; import com.amazonaws.AmazonServiceException; import com.amazonaws.internal.CredentialsEndpointProvider; import com.github.tomakehurst.wiremock.junit.WireMockRule; /** * Tests for the ContainerCredentialsProvider. */ public class ContainerCredentialsProviderTest { @ClassRule public static WireMockRule mockServer = new WireMockRule(0); /** Environment variable name for the AWS ECS Container credentials path */ private static final String CREDENTIALS_PATH = "/dummy/credentials/path"; private static final String ACCESS_KEY_ID = "ACCESS_KEY_ID"; private static final String SECRET_ACCESS_KEY = "SECRET_ACCESS_KEY"; private static final String TOKEN = "TOKEN_TOKEN_TOKEN"; private static final String EXPIRATION_DATE = "3000-05-03T04:55:54Z"; private static ContainerCredentialsProvider containerCredentialsProvider; @BeforeClass public static void setup() { containerCredentialsProvider = new ContainerCredentialsProvider(new TestCredentialsEndpointProvider("http://localhost:" + mockServer.port())); } @Before public void refreshCredentials() { containerCredentialsProvider.refresh(); } /** * Tests that when "AWS_CONTAINER_CREDENTIALS_RELATIVE_URI" is not set, * throws an AmazonClientException. */ @Test (expected = AmazonClientException.class) public void testEnvVariableNotSet() { ContainerCredentialsProvider credentialsProvider = new ContainerCredentialsProvider(); credentialsProvider.getCredentials(); } /** * Tests that the getCredentials parses the response properly when * it receives a valid 200 response from endpoint. */ @Test public void testGetCredentialsReturnsValidResponseFromEcsEndpoint() { stubForSuccessResponse(); BasicSessionCredentials credentials = (BasicSessionCredentials) containerCredentialsProvider.getCredentials(); Assert.assertEquals(ACCESS_KEY_ID, credentials.getAWSAccessKeyId()); Assert.assertEquals(SECRET_ACCESS_KEY, credentials.getAWSSecretKey()); Assert.assertEquals(TOKEN, credentials.getSessionToken()); Assert.assertEquals(new DateTime(EXPIRATION_DATE).toDate(), containerCredentialsProvider.getCredentialsExpiration()); } /** * Tests when the response is 404 Not found, * then getCredentials method throws an AmazonClientException. */ @Test public void testGetCredentialsThrowsAceFor404ErrorResponse() { stubForErrorResponse(404); try { containerCredentialsProvider.getCredentials(); fail("The test should throw an exception"); } catch (AmazonClientException exception) { assertNotNull(exception.getMessage()); } } /** * Tests when the request to http endpoint returns a non-200 or non-404 response, * then getCredentials method throws an AmazonServiceException. */ @Test public void testGetCredentialsThrowsAseForNon200AndNon404ErrorResponse() { stubForErrorResponse(401); try { containerCredentialsProvider.getCredentials(); fail("The test should have thrown an exception"); } catch (AmazonServiceException exception) { assertEquals(401, exception.getStatusCode()); assertNotNull(exception.getMessage()); } } private void stubForSuccessResponse() { stubFor( get(urlPathEqualTo(CREDENTIALS_PATH)) .willReturn(aResponse() .withStatus(200) .withHeader("Content-Type", "application/json") .withHeader("charset", "utf-8") .withBody("{\"AccessKeyId\":\"ACCESS_KEY_ID\",\"SecretAccessKey\":\"SECRET_ACCESS_KEY\",\"Token\":\"TOKEN_TOKEN_TOKEN\"," + "\"Expiration\":\"3000-05-03T04:55:54Z\"}"))); } private void stubForErrorResponse(int statusCode) { stubFor( get(urlPathEqualTo(CREDENTIALS_PATH)) .willReturn(aResponse() .withStatus(statusCode) .withHeader("Content-Type", "application/json") .withHeader("charset", "utf-8") .withBody("{\"code\":\"" + statusCode + "\",\"message\":\"DetailedErrorMessage\"}"))); } /** * Dummy CredentialsPathProvider that overrides the endpoint * and connects to the WireMock server. */ private static class TestCredentialsEndpointProvider extends CredentialsEndpointProvider { private final String host; public TestCredentialsEndpointProvider(String host) { this.host = host; } @Override public URI getCredentialsEndpoint() throws URISyntaxException { return new URI(host + CREDENTIALS_PATH); } } }