/*
* Copyright 2016 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.eclipse.lambda;
import java.net.URLDecoder;
import java.util.LinkedList;
import java.util.List;
import com.amazonaws.auth.policy.Action;
import com.amazonaws.auth.policy.Policy;
import com.amazonaws.auth.policy.Principal;
import com.amazonaws.auth.policy.Statement;
import com.amazonaws.auth.policy.Statement.Effect;
import com.amazonaws.auth.policy.actions.SecurityTokenServiceActions;
import com.amazonaws.services.identitymanagement.AmazonIdentityManagement;
import com.amazonaws.services.identitymanagement.model.ListRolesRequest;
import com.amazonaws.services.identitymanagement.model.ListRolesResult;
import com.amazonaws.services.identitymanagement.model.Role;
import com.amazonaws.services.lambda.AWSLambda;
import com.amazonaws.services.lambda.model.FunctionConfiguration;
import com.amazonaws.services.lambda.model.ListFunctionsRequest;
import com.amazonaws.services.lambda.model.ListFunctionsResult;
public class ServiceApiUtils {
public static final String JAVA_8 = "java8";
private static final String LAMBDA_DOT_AMAZONAWS_DOT_COM = "lambda.amazonaws.com";
public static List<FunctionConfiguration> getAllJavaFunctions(AWSLambda lambda) {
List<FunctionConfiguration> allJavaFunctions = new LinkedList<FunctionConfiguration>();
String nextMarker = null;
do {
ListFunctionsResult result = lambda.listFunctions
(new ListFunctionsRequest()
.withMarker(nextMarker));
List<FunctionConfiguration> functions = result.getFunctions();
if (functions != null) {
for (FunctionConfiguration function : functions) {
if (isJavaFunction(function)) {
allJavaFunctions.add(function);
}
}
}
nextMarker = result.getNextMarker();
} while (nextMarker != null);
return allJavaFunctions;
}
/**
* @return all the roles that are allowed to be assumed by AWS Lambda service
*/
public static List<Role> getAllLambdaRoles(AmazonIdentityManagement iam) {
List<Role> allRoles = new LinkedList<Role>();
String nextMarker = null;
do {
ListRolesResult result = iam.listRoles(
new ListRolesRequest()
.withMarker(nextMarker));
List<Role> roles = result.getRoles();
if (roles != null) {
for (Role role : roles) {
if (canBeAssumedByLambda(role)) {
allRoles.add(role);
}
}
}
nextMarker = result.getMarker();
} while (nextMarker != null);
return allRoles;
}
private static boolean isJavaFunction(FunctionConfiguration function) {
return JAVA_8.equals(function.getRuntime());
}
private static boolean canBeAssumedByLambda(Role role) {
if (role.getAssumeRolePolicyDocument() == null) {
return false;
}
Policy assumeRolePolicy;
try {
String policyJson = URLDecoder.decode(role.getAssumeRolePolicyDocument(), "UTF-8");
assumeRolePolicy = Policy.fromJson(policyJson);
} catch (Exception e) {
LambdaPlugin.getDefault().logWarning(
"Failed to parse assume role policy for ["
+ role.getRoleName() + "]. "
+ role.getAssumeRolePolicyDocument(), e);
return false;
}
for (Statement statement : assumeRolePolicy.getStatements()) {
if (statement.getEffect() == Effect.Allow
&& hasStsAssumeRoleAction(statement.getActions())
&& hasLambdaServicePrincipal(statement.getPrincipals())) {
return true;
}
}
return false;
}
private static boolean hasStsAssumeRoleAction(List<Action> actions) {
if (actions == null) {
return false;
}
for (Action action : actions) {
if (action.getActionName().equalsIgnoreCase(
SecurityTokenServiceActions.AllSecurityTokenServiceActions
.getActionName())) {
return true;
}
if (action.getActionName().equalsIgnoreCase(
SecurityTokenServiceActions.AssumeRole.getActionName())) {
return true;
}
}
return false;
}
private static boolean hasLambdaServicePrincipal(List<Principal> principals) {
if (principals == null) {
return false;
}
for (Principal principal : principals) {
if (principal.equals(Principal.All)) {
return true;
}
if (principal.equals(Principal.AllServices)) {
return true;
}
if (principal.getProvider().equalsIgnoreCase("Service")
&& principal.getId().equalsIgnoreCase(LAMBDA_DOT_AMAZONAWS_DOT_COM)) {
return true;
}
}
return false;
}
}