/*
* 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());
}
}