/* * Copyright 2010-2015 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.policy; import static org.junit.Assert.assertEquals; import com.amazonaws.auth.policy.Principal.Services; import com.amazonaws.auth.policy.Statement.Effect; import com.amazonaws.auth.policy.conditions.ConditionFactory; import com.amazonaws.auth.policy.conditions.IpAddressCondition; import com.amazonaws.auth.policy.conditions.IpAddressCondition.IpAddressComparisonType; import com.amazonaws.auth.policy.conditions.StringCondition; import com.amazonaws.auth.policy.conditions.StringCondition.StringComparisonType; import org.junit.Test; import java.io.IOException; import java.util.LinkedList; import java.util.List; /** * Unit tests for generating AWS policy object from JSON string. */ public class PolicyReaderTest { final String POLICY_VERSION = "2012-10-17"; @Test public void testPrincipals() throws IOException { Policy policy = new Policy(); policy.withStatements(new Statement(Effect.Allow) .withResources(new Resource("resource")) .withPrincipals(new Principal("accountId1"), new Principal("accountId2")) .withActions(new TestAction("action"))); policy = Policy.fromJson(policy.toJson()); assertEquals(1, policy.getStatements().size()); List<Statement> statements = new LinkedList<Statement>(policy.getStatements()); assertEquals(Effect.Allow, statements.get(0).getEffect()); assertEquals("action", statements.get(0).getActions().get(0).getActionName()); assertEquals("resource", statements.get(0).getResources().get(0).getId()); assertEquals(2, statements.get(0).getPrincipals().size()); assertEquals("AWS", statements.get(0).getPrincipals().get(0).getProvider()); assertEquals("accountId1", statements.get(0).getPrincipals().get(0).getId()); assertEquals("AWS", statements.get(0).getPrincipals().get(1).getProvider()); assertEquals("accountId2", statements.get(0).getPrincipals().get(1).getId()); policy = new Policy(); policy.withStatements(new Statement(Effect.Allow) .withResources(new Resource("resource")) .withPrincipals(new Principal(Services.AmazonEC2), new Principal(Services.AmazonElasticTranscoder)) .withActions(new TestAction("action"))); policy = Policy.fromJson(policy.toJson()); assertEquals(1, policy.getStatements().size()); statements = new LinkedList<Statement>(policy.getStatements()); assertEquals(Effect.Allow, statements.get(0).getEffect()); assertEquals(1, statements.get(0).getActions().size()); assertEquals("action", statements.get(0).getActions().get(0).getActionName()); assertEquals(2, statements.get(0).getPrincipals().size()); assertEquals("Service", statements.get(0).getPrincipals().get(0).getProvider()); assertEquals(Services.AmazonEC2.getServiceId(), statements.get(0).getPrincipals().get(0) .getId()); assertEquals("Service", statements.get(0).getPrincipals().get(1).getProvider()); assertEquals(Services.AmazonElasticTranscoder.getServiceId(), statements.get(0) .getPrincipals().get(1).getId()); policy = new Policy(); policy.withStatements(new Statement(Effect.Allow).withResources(new Resource("resource")) .withPrincipals(Principal.All) .withActions(new TestAction("action"))); policy = Policy.fromJson(policy.toJson()); assertEquals(1, policy.getStatements().size()); statements = new LinkedList<Statement>(policy.getStatements()); assertEquals(Effect.Allow, statements.get(0).getEffect()); assertEquals(1, statements.get(0).getActions().size()); assertEquals("action", statements.get(0).getActions().get(0).getActionName()); assertEquals(1, statements.get(0).getPrincipals().size()); assertEquals(Principal.All, statements.get(0).getPrincipals().get(0)); policy = new Policy(); policy.withStatements(new Statement(Effect.Allow) .withResources(new Resource("resource")) .withPrincipals(Principal.AllUsers, Principal.AllServices, Principal.AllWebProviders) .withActions(new TestAction("action"))); policy = Policy.fromJson(policy.toJson()); assertEquals(1, policy.getStatements().size()); statements = new LinkedList<Statement>(policy.getStatements()); assertEquals(Effect.Allow, statements.get(0).getEffect()); assertEquals(1, statements.get(0).getActions().size()); assertEquals("action", statements.get(0).getActions().get(0).getActionName()); assertEquals(3, statements.get(0).getPrincipals().size()); assertEquals(Principal.AllServices, statements.get(0).getPrincipals().get(0)); assertEquals(Principal.AllUsers, statements.get(0).getPrincipals().get(1)); assertEquals(Principal.AllWebProviders, statements.get(0).getPrincipals().get(2)); } @Test public void testMultipleConditionKeysForConditionType() throws Exception { Policy policy = new Policy(); policy.withStatements(new Statement(Effect.Allow) .withResources(new Resource("arn:aws:sqs:us-east-1:987654321000:MyQueue")) .withPrincipals(Principal.AllUsers) .withActions(new TestAction("foo")) .withConditions( new StringCondition(StringComparisonType.StringNotLike, "key1", "foo"), new StringCondition(StringComparisonType.StringNotLike, "key1", "bar"))); policy = Policy.fromJson(policy.toJson()); assertEquals(1, policy.getStatements().size()); List<Statement> statements = new LinkedList<Statement>(policy.getStatements()); assertEquals(Effect.Allow, statements.get(0).getEffect()); assertEquals(1, statements.get(0).getActions().size()); assertEquals("foo", statements.get(0).getActions().get(0).getActionName()); assertEquals(1, statements.get(0).getConditions().size()); assertEquals("StringNotLike", statements.get(0).getConditions().get(0).getType()); assertEquals("key1", statements.get(0).getConditions().get(0).getConditionKey()); assertEquals(2, statements.get(0).getConditions().get(0).getValues().size()); assertEquals("foo", statements.get(0).getConditions().get(0).getValues().get(0)); assertEquals("bar", statements.get(0).getConditions().get(0).getValues().get(1)); } @Test public void testMultipleStatements() throws Exception { Policy policy = new Policy("S3PolicyId1"); policy.withStatements( new Statement(Effect.Allow) .withId("0") .withPrincipals(Principal.AllUsers) .withActions(new TestAction("action1")) .withResources(new Resource("resource")) .withConditions( new IpAddressCondition("192.168.143.0/24")), new Statement(Effect.Deny) .withId("1") .withPrincipals(Principal.AllUsers) .withActions(new TestAction("action2")) .withResources(new Resource("resource")) .withConditions(new IpAddressCondition("10.1.2.0/24")), new Statement(Effect.Allow) .withId("2") .withPrincipals(Principal.AllUsers) .withActions(new TestAction("action3")) .withResources(new Resource("resource")) .withConditions(new IpAddressCondition(IpAddressComparisonType.NotIpAddress, "192.168.143.188/32"))); policy = Policy.fromJson(policy.toJson()); assertEquals(3, policy.getStatements().size()); assertEquals("S3PolicyId1", policy.getId()); List<Statement> statements = new LinkedList<Statement>(policy.getStatements()); assertEquals(Effect.Allow, statements.get(0).getEffect()); assertEquals("0", statements.get(0).getId()); assertEquals(1, statements.get(0).getPrincipals().size()); assertEquals("*", statements.get(0).getPrincipals().get(0).getId()); assertEquals("AWS", statements.get(0).getPrincipals().get(0).getProvider()); assertEquals(1, statements.get(0).getResources().size()); assertEquals("resource", statements.get(0).getResources().get(0).getId()); assertEquals(1, statements.get(0).getActions().size()); assertEquals("action1", statements.get(0).getActions().get(0).getActionName()); assertEquals(1, statements.get(0).getConditions().size()); assertEquals("IpAddress", statements.get(0).getConditions().get(0).getType()); assertEquals(ConditionFactory.SOURCE_IP_CONDITION_KEY, statements.get(0).getConditions() .get(0).getConditionKey()); assertEquals(1, statements.get(0).getConditions().get(0).getValues().size()); assertEquals("192.168.143.0/24", statements.get(0).getConditions().get(0).getValues() .get(0)); assertEquals(Effect.Deny, statements.get(1).getEffect()); assertEquals("1", statements.get(1).getId()); assertEquals(1, statements.get(1).getPrincipals().size()); assertEquals("*", statements.get(1).getPrincipals().get(0).getId()); assertEquals("AWS", statements.get(1).getPrincipals().get(0).getProvider()); assertEquals(1, statements.get(1).getResources().size()); assertEquals("resource", statements.get(1).getResources().get(0).getId()); assertEquals(1, statements.get(1).getActions().size()); assertEquals("action2", statements.get(1).getActions().get(0).getActionName()); assertEquals(1, statements.get(1).getConditions().size()); assertEquals("IpAddress", statements.get(1).getConditions().get(0).getType()); assertEquals(ConditionFactory.SOURCE_IP_CONDITION_KEY, statements.get(0).getConditions() .get(0).getConditionKey()); assertEquals(1, statements.get(0).getConditions().get(0).getValues().size()); assertEquals("10.1.2.0/24", statements.get(1).getConditions().get(0).getValues().get(0)); assertEquals(Effect.Allow, statements.get(2).getEffect()); assertEquals("2", statements.get(2).getId()); assertEquals(1, statements.get(2).getPrincipals().size()); assertEquals("*", statements.get(2).getPrincipals().get(0).getId()); assertEquals("AWS", statements.get(2).getPrincipals().get(0).getProvider()); assertEquals(1, statements.get(2).getResources().size()); assertEquals("resource", statements.get(2).getResources().get(0).getId()); assertEquals(1, statements.get(2).getActions().size()); assertEquals("action3", statements.get(2).getActions().get(0).getActionName()); assertEquals(1, statements.get(2).getConditions().size()); assertEquals("NotIpAddress", statements.get(2).getConditions().get(0).getType()); assertEquals("192.168.143.188/32", statements.get(2).getConditions().get(0).getValues().get(0)); } @Test public void testNoJsonArray() { String jsonString = "{" + "\"Version\": \"2012-10-17\"," + "\"Statement\": [" + "{" + "\"Effect\": \"Allow\"," + "\"Principal\": {" + "\"AWS\": \"*\"" + "}," + "\"Action\": \"sts:AssumeRole\"," + "\"Condition\": {" + "\"IpAddress\": {" + " \"aws:SourceIp\": \"10.10.10.10/32\"" + "}" + "}" + "}" + "]" + "}"; Policy policy = Policy.fromJson(jsonString); assertEquals(POLICY_VERSION, policy.getVersion()); List<Statement> statements = new LinkedList<Statement>(policy.getStatements()); assertEquals(1, statements.size()); assertEquals(1, statements.get(0).getActions().size()); assertEquals(Effect.Allow, statements.get(0).getEffect()); assertEquals("sts:AssumeRole", statements.get(0).getActions().get(0).getActionName()); assertEquals(1, statements.get(0).getConditions().size()); assertEquals("IpAddress", statements.get(0).getConditions().get(0).getType()); assertEquals("aws:SourceIp", statements.get(0).getConditions().get(0).getConditionKey()); assertEquals(1, statements.get(0).getConditions().get(0).getValues().size()); assertEquals("10.10.10.10/32", statements.get(0).getConditions().get(0).getValues().get(0)); assertEquals(1, statements.get(0).getPrincipals().size()); assertEquals("*", statements.get(0).getPrincipals().get(0).getId()); assertEquals("AWS", statements.get(0).getPrincipals().get(0).getProvider()); } /** * Tests that SAML-based federated user is supported as principal. */ @Test public void testFederatedUserBySAMLProvider() { String jsonString = "{" + "\"Version\":\"2012-10-17\"," + "\"Statement\":[" + "{" + "\"Sid\":\"\"," + "\"Effect\":\"Allow\"," + "\"Principal\":{" + "\"Federated\":\"arn:aws:iam::862954416975:saml-provider/myprovider\"" + "}," + "\"Action\":\"sts:AssumeRoleWithSAML\"," + "\"Condition\":{" + "\"StringEquals\":{" + "\"SAML:aud\":\"https://signin.aws.amazon.com/saml\"" + "}" + "}" + "}" + "]" + "}"; Policy policy = Policy.fromJson(jsonString); assertEquals(POLICY_VERSION, policy.getVersion()); List<Statement> statements = new LinkedList<Statement>(policy.getStatements()); assertEquals(1, statements.size()); assertEquals(1, statements.get(0).getActions().size()); assertEquals(Effect.Allow, statements.get(0).getEffect()); assertEquals("sts:AssumeRoleWithSAML", statements.get(0).getActions().get(0) .getActionName()); assertEquals(1, statements.get(0).getConditions().size()); assertEquals("StringEquals", statements.get(0).getConditions().get(0).getType()); assertEquals("SAML:aud", statements.get(0).getConditions().get(0).getConditionKey()); assertEquals(1, statements.get(0).getConditions().get(0).getValues().size()); assertEquals("https://signin.aws.amazon.com/saml", statements.get(0).getConditions().get(0) .getValues().get(0)); assertEquals(1, statements.get(0).getPrincipals().size()); assertEquals("arn:aws:iam::862954416975:saml-provider/myprovider", statements.get(0) .getPrincipals().get(0).getId()); assertEquals("Federated", statements.get(0).getPrincipals().get(0).getProvider()); } @Test public void testCloudHSMServicePrincipal() { String jsonString = "{" + "\"Version\":\"2008-10-17\"," + "\"Statement\":[" + "{\"Sid\":\"\"," + "\"Effect\":\"Allow\"," + "\"Principal\":{\"Service\":\"cloudhsm.amazonaws.com\"}," + "\"Action\":\"sts:AssumeRole\"}" + "]" + "}"; Policy policy = Policy.fromJson(jsonString); assertEquals(POLICY_VERSION, policy.getVersion()); List<Statement> statements = new LinkedList<Statement>(policy.getStatements()); assertEquals(1, statements.size()); assertEquals(1, statements.get(0).getActions().size()); assertEquals(Effect.Allow, statements.get(0).getEffect()); assertEquals("sts:AssumeRole", statements.get(0).getActions().get(0).getActionName()); assertEquals(0, statements.get(0).getConditions().size()); assertEquals(1, statements.get(0).getPrincipals().size()); assertEquals(Services.AWSCloudHSM.getServiceId(), statements.get(0).getPrincipals().get(0) .getId()); assertEquals("Service", statements.get(0).getPrincipals().get(0).getProvider()); } private class TestAction implements Action { private final String name; public TestAction(String name) { this.name = name; } @Override public String getActionName() { return name; } } /** * This test case was written as result of the following tt * * @see https://tt.amazon.com/0030871921 When a service is mentioned in the * principal, we always try to figure out the service from * <code>com.amazonaws.auth.policy.Principal.Services</code> enum. For * new services introduced, if the enum is not updated, then the * parsing fails. */ @Test public void testPrincipalWithServiceNotInServicesEnum() { String jsonString = "{" + "\"Version\":\"2008-10-17\"," + "\"Statement\":[" + "{" + "\"Sid\":\"\"," + "\"Effect\":\"Allow\"," + "\"Principal\":{" + "\"Service\":\"workspaces.amazonaws.com\" " + "}," + "\"Action\":\"sts:AssumeRole\"" + "}" + "]" + "}"; Policy policy = Policy.fromJson(jsonString); assertEquals(POLICY_VERSION, policy.getVersion()); List<Statement> statements = new LinkedList<Statement>( policy.getStatements()); assertEquals(1, statements.size()); assertEquals(1, statements.get(0).getActions().size()); assertEquals(Effect.Allow, statements.get(0).getEffect()); assertEquals("sts:AssumeRole", statements.get(0).getActions().get(0) .getActionName()); assertEquals(0, statements.get(0).getConditions().size()); assertEquals(1, statements.get(0).getPrincipals().size()); assertEquals("workspaces.amazonaws.com", statements.get(0) .getPrincipals().get(0).getId()); assertEquals("Service", statements.get(0).getPrincipals().get(0) .getProvider()); } }