diff --git a/aws-lambda-java-events/pom.xml b/aws-lambda-java-events/pom.xml index 3d9be9bb..b88adbff 100644 --- a/aws-lambda-java-events/pom.xml +++ b/aws-lambda-java-events/pom.xml @@ -56,6 +56,19 @@ 5.7.0 test + + com.fasterxml.jackson.core + jackson-databind + 2.10.4 + test + + + net.javacrumbs.json-unit + json-unit-assertj + 2.22.0 + test + + org.projectlombok lombok diff --git a/aws-lambda-java-events/src/main/java/com/amazonaws/services/lambda/runtime/events/IamPolicyResponse.java b/aws-lambda-java-events/src/main/java/com/amazonaws/services/lambda/runtime/events/IamPolicyResponse.java new file mode 100644 index 00000000..a511836c --- /dev/null +++ b/aws-lambda-java-events/src/main/java/com/amazonaws/services/lambda/runtime/events/IamPolicyResponse.java @@ -0,0 +1,85 @@ +package com.amazonaws.services.lambda.runtime.events; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@Data +@Builder(setterPrefix = "with") +@NoArgsConstructor +@AllArgsConstructor +public class IamPolicyResponse implements Serializable, Cloneable { + + public static final String EXECUTE_API_INVOKE = "execute-api:Invoke"; + public static final String VERSION_2012_10_17 = "2012-10-17"; + public static final String ALLOW = "Allow"; + public static final String DENY = "Deny"; + + private String principalId; + private PolicyDocument policyDocument; + private Map context; + + public Map getPolicyDocument() { + Map serializablePolicy = new HashMap<>(); + serializablePolicy.put("Version", policyDocument.getVersion()); + + int numberOfStatements = policyDocument.getStatement().size(); + Map[] serializableStatementArray = new Map[numberOfStatements]; + for (int i = 0; i < numberOfStatements; i++) { + Statement statement = policyDocument.getStatement().get(i); + Map serializableStatement = new HashMap<>(); + serializableStatement.put("Effect", statement.getEffect()); + serializableStatement.put("Action", statement.getAction()); + serializableStatement.put("Resource", statement.getResource().toArray(new String[0])); + serializableStatement.put("Condition", statement.getCondition()); + serializableStatementArray[i] = serializableStatement; + } + serializablePolicy.put("Statement", serializableStatementArray); + return serializablePolicy; + } + + public static Statement allowStatement(String resource) { + return Statement.builder() + .withEffect(ALLOW) + .withResource(Collections.singletonList(resource)) + .withAction(EXECUTE_API_INVOKE) + .build(); + } + + public static Statement denyStatement(String resource) { + return Statement.builder() + .withEffect(DENY) + .withResource(Collections.singletonList(resource)) + .withAction(EXECUTE_API_INVOKE) + .build(); + } + + @Data + @Builder(setterPrefix = "with") + @NoArgsConstructor + @AllArgsConstructor + public static class PolicyDocument implements Serializable, Cloneable { + + private String version; + private List statement; + } + + @Data + @Builder(setterPrefix = "with") + @NoArgsConstructor + @AllArgsConstructor + public static class Statement implements Serializable, Cloneable { + + private String action; + private String effect; + private List resource; + private Map> condition; + } +} \ No newline at end of file diff --git a/aws-lambda-java-events/src/test/java/com/amazonaws/services/lambda/runtime/events/IamPolicyResponseTest.java b/aws-lambda-java-events/src/test/java/com/amazonaws/services/lambda/runtime/events/IamPolicyResponseTest.java new file mode 100644 index 00000000..4dbbb108 --- /dev/null +++ b/aws-lambda-java-events/src/test/java/com/amazonaws/services/lambda/runtime/events/IamPolicyResponseTest.java @@ -0,0 +1,91 @@ +package com.amazonaws.services.lambda.runtime.events; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.jupiter.api.Test; + +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.HashMap; +import java.util.Map; + +import static com.amazonaws.services.lambda.runtime.events.IamPolicyResponse.ALLOW; +import static com.amazonaws.services.lambda.runtime.events.IamPolicyResponse.EXECUTE_API_INVOKE; +import static com.amazonaws.services.lambda.runtime.events.IamPolicyResponse.VERSION_2012_10_17; +import static com.amazonaws.services.lambda.runtime.events.IamPolicyResponse.allowStatement; +import static com.amazonaws.services.lambda.runtime.events.IamPolicyResponse.denyStatement; +import static java.util.Collections.singletonList; +import static java.util.Collections.singletonMap; +import static net.javacrumbs.jsonunit.assertj.JsonAssertions.assertThatJson; + +public class IamPolicyResponseTest { + + private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); + + @Test + public void testAllowStatement() throws JsonProcessingException { + IamPolicyResponse iamPolicyResponse = IamPolicyResponse.builder() + .withPrincipalId("me") + .withPolicyDocument(IamPolicyResponse.PolicyDocument.builder() + .withVersion(VERSION_2012_10_17) + .withStatement(singletonList(allowStatement("arn:aws:execute-api:eu-west-1:123456789012:1234abc/$deafult/*/*"))) + .build()) + .build(); + + String json = OBJECT_MAPPER.writeValueAsString(iamPolicyResponse); + + assertThatJson(json).isEqualTo(readResource("iamPolicyResponses/allow.json")); + } + + @Test + public void testDenyStatement() throws JsonProcessingException { + IamPolicyResponse iamPolicyResponse = IamPolicyResponse.builder() + .withPrincipalId("me") + .withPolicyDocument(IamPolicyResponse.PolicyDocument.builder() + .withVersion(VERSION_2012_10_17) + .withStatement(singletonList(denyStatement("arn:aws:execute-api:eu-west-1:123456789012:1234abc/$deafult/*/*"))) + .build()) + .build(); + + String json = OBJECT_MAPPER.writeValueAsString(iamPolicyResponse); + + assertThatJson(json).isEqualTo(readResource("iamPolicyResponses/deny.json")); + } + + @Test + public void testStatementWithCondition() throws JsonProcessingException { + Map> conditions = new HashMap<>(); + conditions.put("DateGreaterThan", singletonMap("aws:TokenIssueTime", "2020-01-01T00:00:01Z")); + + IamPolicyResponse iamPolicyResponse = IamPolicyResponse.builder() + .withPrincipalId("me") + .withPolicyDocument(IamPolicyResponse.PolicyDocument.builder() + .withVersion(VERSION_2012_10_17) + .withStatement(singletonList(IamPolicyResponse.Statement.builder() + .withAction(EXECUTE_API_INVOKE) + .withEffect(ALLOW) + .withResource(singletonList("arn:aws:execute-api:eu-west-1:123456789012:1234abc/$deafult/*/*")) + .withCondition(conditions) + .build())) + .build()) + .build(); + + String json = OBJECT_MAPPER.writeValueAsString(iamPolicyResponse); + + assertThatJson(json).isEqualTo(readResource("iamPolicyResponses/allow-with-condition.json")); + } + + private String readResource(String name) { + Path filePath = Paths.get("src", "test", "resources", name); + byte[] bytes = new byte[0]; + try { + bytes = Files.readAllBytes(filePath); + } catch (IOException e) { + e.printStackTrace(); + } + return new String(bytes, StandardCharsets.UTF_8); + } +} \ No newline at end of file diff --git a/aws-lambda-java-events/src/test/resources/iamPolicyResponses/allow-with-condition.json b/aws-lambda-java-events/src/test/resources/iamPolicyResponses/allow-with-condition.json new file mode 100644 index 00000000..0541e410 --- /dev/null +++ b/aws-lambda-java-events/src/test/resources/iamPolicyResponses/allow-with-condition.json @@ -0,0 +1,13 @@ +{ + "principalId": "me", + "policyDocument": { + "Version": "2012-10-17", + "Statement": [{ + "Action": "execute-api:Invoke", + "Resource": ["arn:aws:execute-api:eu-west-1:123456789012:1234abc/$deafult/*/*"], + "Effect": "Allow", + "Condition": {"DateGreaterThan": {"aws:TokenIssueTime": "2020-01-01T00:00:01Z"}} + }] + }, + "context":null +} \ No newline at end of file diff --git a/aws-lambda-java-events/src/test/resources/iamPolicyResponses/allow.json b/aws-lambda-java-events/src/test/resources/iamPolicyResponses/allow.json new file mode 100644 index 00000000..7636502b --- /dev/null +++ b/aws-lambda-java-events/src/test/resources/iamPolicyResponses/allow.json @@ -0,0 +1,13 @@ +{ + "principalId": "me", + "policyDocument": { + "Version": "2012-10-17", + "Statement": [{ + "Action": "execute-api:Invoke", + "Resource": ["arn:aws:execute-api:eu-west-1:123456789012:1234abc/$deafult/*/*"], + "Effect": "Allow", + "Condition": null + }] + }, + "context":null +} \ No newline at end of file diff --git a/aws-lambda-java-events/src/test/resources/iamPolicyResponses/deny.json b/aws-lambda-java-events/src/test/resources/iamPolicyResponses/deny.json new file mode 100644 index 00000000..c5e360d3 --- /dev/null +++ b/aws-lambda-java-events/src/test/resources/iamPolicyResponses/deny.json @@ -0,0 +1,13 @@ +{ + "principalId": "me", + "policyDocument": { + "Version": "2012-10-17", + "Statement": [{ + "Action": "execute-api:Invoke", + "Resource": ["arn:aws:execute-api:eu-west-1:123456789012:1234abc/$deafult/*/*"], + "Effect": "Deny", + "Condition": null + }] + }, + "context":null +} \ No newline at end of file