Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release/v1.28.0 #1754

Merged
merged 2 commits into from
Oct 27, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion samtranslator/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = "1.27.0"
__version__ = "1.28.0"
5 changes: 5 additions & 0 deletions samtranslator/model/api/http_api_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -436,6 +436,11 @@ def _get_authorizers(self, authorizers_config, default_authorizer=None):
authorization_scopes=authorizer.get("AuthorizationScopes"),
jwt_configuration=authorizer.get("JwtConfiguration"),
id_source=authorizer.get("IdentitySource"),
function_arn=authorizer.get("FunctionArn"),
function_invoke_role=authorizer.get("FunctionInvokeRole"),
identity=authorizer.get("Identity"),
authorizer_payload_format_version=authorizer.get("AuthorizerPayloadFormatVersion"),
enable_simple_responses=authorizer.get("EnableSimpleResponses"),
)
return authorizers

Expand Down
211 changes: 192 additions & 19 deletions samtranslator/model/apigatewayv2.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
from samtranslator.model import PropertyType, Resource
from samtranslator.model.types import is_type, one_of, is_str, list_of
from samtranslator.model.intrinsics import ref
from samtranslator.model.intrinsics import ref, fnSub
from samtranslator.model.exceptions import InvalidResourceException
from samtranslator.translator.arn_generator import ArnGenerator

APIGATEWAY_AUTHORIZER_KEY = "x-amazon-apigateway-authorizer"


class ApiGatewayV2HttpApi(Resource):
Expand Down Expand Up @@ -57,39 +60,209 @@ class ApiGatewayV2ApiMapping(Resource):

class ApiGatewayV2Authorizer(object):
def __init__(
self, api_logical_id=None, name=None, authorization_scopes=[], jwt_configuration={}, id_source=None,
self,
api_logical_id=None,
name=None,
authorization_scopes=None,
jwt_configuration=None,
id_source=None,
function_arn=None,
function_invoke_role=None,
identity=None,
authorizer_payload_format_version=None,
enable_simple_responses=None,
):
"""
Creates an authorizer for use in V2 Http Apis
"""
if authorization_scopes is not None and not isinstance(authorization_scopes, list):
raise InvalidResourceException(api_logical_id, "AuthorizationScopes must be a list.")

# Currently only one type of auth
self.auth_type = "oauth2"

self.api_logical_id = api_logical_id
self.name = name
self.authorization_scopes = authorization_scopes

# Validate necessary parameters exist
if not jwt_configuration:
raise InvalidResourceException(api_logical_id, name + " Authorizer must define 'JwtConfiguration'.")
self.jwt_configuration = jwt_configuration
if not id_source:
raise InvalidResourceException(api_logical_id, name + " Authorizer must define 'IdentitySource'.")
self.id_source = id_source
self.function_arn = function_arn
self.function_invoke_role = function_invoke_role
self.identity = identity
self.authorizer_payload_format_version = authorizer_payload_format_version
self.enable_simple_responses = enable_simple_responses

self._validate_input_parameters()

authorizer_type = self._get_auth_type()

# Validate necessary parameters exist
if authorizer_type == "JWT":
self._validate_jwt_authorizer()

if authorizer_type == "REQUEST":
self._validate_lambda_authorizer()

def _get_auth_type(self):
if self.jwt_configuration:
return "JWT"
return "REQUEST"

def _validate_input_parameters(self):
authorizer_type = self._get_auth_type()

if self.authorization_scopes is not None and not isinstance(self.authorization_scopes, list):
raise InvalidResourceException(self.api_logical_id, "AuthorizationScopes must be a list.")

if self.authorization_scopes is not None and not authorizer_type == "JWT":
raise InvalidResourceException(
self.api_logical_id, "AuthorizationScopes must be defined only for OAuth2 Authorizer."
)

if self.jwt_configuration is not None and not authorizer_type == "JWT":
raise InvalidResourceException(
self.api_logical_id, "JwtConfiguration must be defined only for OAuth2 Authorizer."
)

if self.id_source is not None and not authorizer_type == "JWT":
raise InvalidResourceException(
self.api_logical_id, "IdentitySource must be defined only for OAuth2 Authorizer."
)

if self.function_arn is not None and not authorizer_type == "REQUEST":
raise InvalidResourceException(
self.api_logical_id, "FunctionArn must be defined only for Lambda Authorizer."
)

if self.function_invoke_role is not None and not authorizer_type == "REQUEST":
raise InvalidResourceException(
self.api_logical_id, "FunctionInvokeRole must be defined only for Lambda Authorizer."
)

if self.identity is not None and not authorizer_type == "REQUEST":
raise InvalidResourceException(self.api_logical_id, "Identity must be defined only for Lambda Authorizer.")

if self.authorizer_payload_format_version is not None and not authorizer_type == "REQUEST":
raise InvalidResourceException(
self.api_logical_id, "AuthorizerPayloadFormatVersion must be defined only for Lambda Authorizer."
)

if self.enable_simple_responses is not None and not authorizer_type == "REQUEST":
raise InvalidResourceException(
self.api_logical_id, "EnableSimpleResponses must be defined only for Lambda Authorizer."
)

def _validate_jwt_authorizer(self):
if not self.jwt_configuration:
raise InvalidResourceException(
self.api_logical_id, self.name + " OAuth2 Authorizer must define 'JwtConfiguration'."
)
if not self.id_source:
raise InvalidResourceException(
self.api_logical_id, self.name + " OAuth2 Authorizer must define 'IdentitySource'."
)

def _validate_lambda_authorizer(self):
if not self.function_arn:
raise InvalidResourceException(
self.api_logical_id, self.name + " Lambda Authorizer must define 'FunctionArn'."
)
if not self.authorizer_payload_format_version:
raise InvalidResourceException(
self.api_logical_id, self.name + " Lambda Authorizer must define 'AuthorizerPayloadFormatVersion'."
)

def generate_openapi(self):
"""
Generates OAS for the securitySchemes section
"""
openapi = {
"type": self.auth_type,
"x-amazon-apigateway-authorizer": {
authorizer_type = self._get_auth_type()

if authorizer_type == "JWT":
openapi = {"type": "oauth2"}
openapi[APIGATEWAY_AUTHORIZER_KEY] = {
"jwtConfiguration": self.jwt_configuration,
"identitySource": self.id_source,
"type": "jwt",
},
}
}

if authorizer_type == "REQUEST":
openapi = {
"type": "apiKey",
"name": "Unused",
"in": "header",
}
openapi[APIGATEWAY_AUTHORIZER_KEY] = {"type": "request"}

# Generate the lambda arn
partition = ArnGenerator.get_partition_name()
resource = "lambda:path/2015-03-31/functions/${__FunctionArn__}/invocations"
authorizer_uri = fnSub(
ArnGenerator.generate_arn(
partition=partition, service="apigateway", resource=resource, include_account_id=False
),
{"__FunctionArn__": self.function_arn},
)
openapi[APIGATEWAY_AUTHORIZER_KEY]["authorizerUri"] = authorizer_uri

# Set authorizerCredentials if present
function_invoke_role = self._get_function_invoke_role()
if function_invoke_role:
openapi[APIGATEWAY_AUTHORIZER_KEY]["authorizerCredentials"] = function_invoke_role

# Set authorizerResultTtlInSeconds if present
reauthorize_every = self._get_reauthorize_every()
if reauthorize_every is not None:
openapi[APIGATEWAY_AUTHORIZER_KEY]["authorizerResultTtlInSeconds"] = reauthorize_every

# Set identitySource if present
if self.identity:
openapi[APIGATEWAY_AUTHORIZER_KEY]["identitySource"] = self._get_identity_source()

# Set authorizerPayloadFormatVersion. It's a required parameter
openapi[APIGATEWAY_AUTHORIZER_KEY][
"authorizerPayloadFormatVersion"
] = self.authorizer_payload_format_version

# Set authorizerPayloadFormatVersion. It's a required parameter
if self.enable_simple_responses:
openapi[APIGATEWAY_AUTHORIZER_KEY]["enableSimpleResponses"] = self.enable_simple_responses

return openapi

def _get_function_invoke_role(self):
if not self.function_invoke_role or self.function_invoke_role == "NONE":
return None

return self.function_invoke_role

def _get_identity_source(self):
identity_source_headers = []
identity_source_query_strings = []
identity_source_stage_variables = []
identity_source_context = []

if self.identity.get("Headers"):
identity_source_headers = list(map(lambda h: "$request.header." + h, self.identity.get("Headers")))

if self.identity.get("QueryStrings"):
identity_source_query_strings = list(
map(lambda qs: "$request.querystring." + qs, self.identity.get("QueryStrings"))
)

if self.identity.get("StageVariables"):
identity_source_stage_variables = list(
map(lambda sv: "$stageVariables." + sv, self.identity.get("StageVariables"))
)

if self.identity.get("Context"):
identity_source_context = list(map(lambda c: "$context." + c, self.identity.get("Context")))

identity_source = (
identity_source_headers
+ identity_source_query_strings
+ identity_source_stage_variables
+ identity_source_context
)

return identity_source

def _get_reauthorize_every(self):
if not self.identity:
return None

return self.identity.get("ReauthorizeEvery")
8 changes: 4 additions & 4 deletions samtranslator/model/stepfunctions/events.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ def _generate_logical_id(self, prefix, suffix, resource_type):
return logical_id

def _construct_role(self, resource, prefix=None, suffix=""):
"""Constructs the IAM Role resource allowing the event service to invoke
"""Constructs the IAM Role resource allowing the event service to invoke
the StartExecution API of the state machine resource it is associated with.

:param model.stepfunctions.StepFunctionsStateMachine resource: The state machine resource associated with the event
Expand Down Expand Up @@ -135,7 +135,7 @@ class CloudWatchEvent(EventSource):
}

def to_cloudformation(self, resource, **kwargs):
"""Returns the CloudWatch Events/EventBridge Rule and IAM Role to which this
"""Returns the CloudWatch Events/EventBridge Rule and IAM Role to which this
CloudWatch Events/EventBridge event source corresponds.

:param dict kwargs: no existing resources need to be modified
Expand Down Expand Up @@ -379,10 +379,10 @@ def _add_swagger_integration(self, api, resource, role, intrinsics_resolver):
api["DefinitionBody"] = editor.swagger

def _generate_request_template(self, resource):
"""Generates the Body mapping request template for the Api. This allows for the input
"""Generates the Body mapping request template for the Api. This allows for the input
request to the Api to be passed as the execution input to the associated state machine resource.

:param model.stepfunctions.resources.StepFunctionsStateMachine resource; the state machine
:param model.stepfunctions.resources.StepFunctionsStateMachine resource; the state machine
resource to which the Api event source must be associated

:returns: a body mapping request which passes the Api input to the state machine execution
Expand Down
2 changes: 1 addition & 1 deletion samtranslator/model/stepfunctions/generators.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ def __init__(
:param logical_id: Logical id of the SAM State Machine Resource
:param depends_on: Any resources that need to be depended on
:param managed_policy_map: Map of managed policy names to the ARNs
:param intrinsics_resolver: Instance of the resolver that knows how to resolve parameter references
:param intrinsics_resolver: Instance of the resolver that knows how to resolve parameter references
:param definition: State Machine definition
:param definition_uri: URI to State Machine definition
:param logging: Logging configuration for the State Machine
Expand Down
4 changes: 2 additions & 2 deletions samtranslator/open_api/open_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ def iter_on_path(self):
def add_timeout_to_method(self, api, path, method_name, timeout):
"""
Adds a timeout to this path/method.

:param dict api: Reference to the related Api's properties as defined in the template.
:param string path: Path name
:param string method_name: Method name
Expand All @@ -260,7 +260,7 @@ def add_timeout_to_method(self, api, path, method_name, timeout):
def add_path_parameters_to_method(self, api, path, method_name, path_parameters):
"""
Adds path parameters to this path + method

:param dict api: Reference to the related Api's properties as defined in the template.
:param string path: Path name
:param string method_name: Method name
Expand Down
Loading