Skip to content
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
18 changes: 14 additions & 4 deletions samtranslator/model/apigateway.py
Original file line number Diff line number Diff line change
Expand Up @@ -270,11 +270,19 @@ def _is_missing_identity_source(self, identity):
query_strings = identity.get("QueryStrings")
stage_variables = identity.get("StageVariables")
context = identity.get("Context")
ttl = identity.get("ReauthorizeEvery")

if not headers and not query_strings and not stage_variables and not context:
return True
required_properties_missing = not headers and not query_strings and not stage_variables and not context

try:
ttl_int = int(ttl)
# this will catch if ttl is None and not convertable to an int
except TypeError:
# previous behavior before trying to read ttl
return required_properties_missing

return False
# If we can resolve ttl, attempt to see if things are valid
return ttl_int > 0 and required_properties_missing

def generate_swagger(self):
authorizer_type = self._get_type()
Expand Down Expand Up @@ -314,7 +322,9 @@ def generate_swagger(self):
swagger[APIGATEWAY_AUTHORIZER_KEY]["authorizerCredentials"] = function_invoke_role

if self._get_function_payload_type() == "REQUEST":
swagger[APIGATEWAY_AUTHORIZER_KEY]["identitySource"] = self._get_identity_source()
identity_source = self._get_identity_source()
if identity_source:
swagger[APIGATEWAY_AUTHORIZER_KEY]["identitySource"] = self._get_identity_source()

# Authorizer Validation Expression is only allowed on COGNITO_USER_POOLS and LAMBDA_TOKEN
is_lambda_token_authorizer = authorizer_type == "LAMBDA" and self._get_function_payload_type() == "TOKEN"
Expand Down
98 changes: 96 additions & 2 deletions tests/model/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,100 @@ def test_create_oauth2_auth(self):

def test_create_authorizer_fails_with_string_authorization_scopes(self):
with pytest.raises(InvalidResourceException):
auth = ApiGatewayAuthorizer(
api_logical_id="logicalId", name="authName", authorization_scopes="invalid_scope"
ApiGatewayAuthorizer(api_logical_id="logicalId", name="authName", authorization_scopes="invalid_scope")

def test_create_authorizer_fails_with_missing_identity_values_and_not_cached(self):
with pytest.raises(InvalidResourceException):
ApiGatewayAuthorizer(
api_logical_id="logicalId",
name="authName",
identity={"ReauthorizeEvery": 10},
function_payload_type="REQUEST",
)

def test_create_authorizer_fails_with_empty_identity(self):
with pytest.raises(InvalidResourceException):
ApiGatewayAuthorizer(
api_logical_id="logicalId", name="authName", identity={}, function_payload_type="REQUEST"
)

def test_create_authorizer_doesnt_fail_with_identity_reauthorization_every_as_zero(self):
auth = ApiGatewayAuthorizer(
api_logical_id="logicalId",
name="authName",
identity={"ReauthorizeEvery": 0},
function_payload_type="REQUEST",
)

self.assertIsNotNone(auth)

def test_create_authorizer_with_non_integer_identity(self):
auth = ApiGatewayAuthorizer(
api_logical_id="logicalId",
name="authName",
identity={"ReauthorizeEvery": [], "Headers": ["Accept"]},
function_payload_type="REQUEST",
)

self.assertIsNotNone(auth)

def test_create_authorizer_with_identity_intrinsic_is_valid_with_headers(self):
auth = ApiGatewayAuthorizer(
api_logical_id="logicalId",
name="authName",
identity={"ReauthorizeEvery": {"FN:If": ["isProd", 10, 0]}, "Headers": ["Accept"]},
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: the intrinsic key is actually Fn::If

function_payload_type="REQUEST",
)

self.assertIsNotNone(auth)

def test_create_authorizer_with_identity_intrinsic_is_invalid_if_no_querystring_stagevariables_context_headers(
self,
):
with pytest.raises(InvalidResourceException):
ApiGatewayAuthorizer(
api_logical_id="logicalId",
name="authName",
identity={"ReauthorizeEvery": {"FN:If": ["isProd", 10, 0]}},
function_payload_type="REQUEST",
)

def test_create_authorizer_with_identity_intrinsic_is_valid_with_context(self):
auth = ApiGatewayAuthorizer(
api_logical_id="logicalId",
name="authName",
identity={"ReauthorizeEvery": {"FN:If": ["isProd", 10, 0]}, "Context": ["Accept"]},
function_payload_type="REQUEST",
)

self.assertIsNotNone(auth)

def test_create_authorizer_with_identity_intrinsic_is_valid_with_stage_variables(self):
auth = ApiGatewayAuthorizer(
api_logical_id="logicalId",
name="authName",
identity={"ReauthorizeEvery": {"FN:If": ["isProd", 10, 0]}, "StageVariables": ["Stage"]},
function_payload_type="REQUEST",
)

self.assertIsNotNone(auth)

def test_create_authorizer_with_identity_intrinsic_is_valid_with_query_strings(self):
auth = ApiGatewayAuthorizer(
api_logical_id="logicalId",
name="authName",
identity={"ReauthorizeEvery": {"FN:If": ["isProd", 10, 0]}, "QueryStrings": ["AQueryString"]},
function_payload_type="REQUEST",
)

self.assertIsNotNone(auth)

def test_create_authorizer_with_identity_ReauthorizeEvery_asNone_valid_with_query_strings(self):
auth = ApiGatewayAuthorizer(
api_logical_id="logicalId",
name="authName",
identity={"ReauthorizeEvery": None, "QueryStrings": ["AQueryString"]},
function_payload_type="REQUEST",
)

self.assertIsNotNone(auth)
21 changes: 21 additions & 0 deletions tests/translator/input/api_with_auth_all_minimum.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,20 @@ Resources:
Identity:
Headers:
- Authorization1

MyApiWithNotCachedLambdaRequestAuth:
Type: "AWS::Serverless::Api"
Properties:
StageName: Prod
Auth:
DefaultAuthorizer: MyLambdaRequestAuth
Authorizers:
MyLambdaRequestAuth:
FunctionPayloadType: REQUEST
FunctionArn: !GetAtt MyAuthFn.Arn
Identity:
ReauthorizeEvery: 0

MyAuthFn:
Type: AWS::Serverless::Function
Properties:
Expand Down Expand Up @@ -81,6 +95,13 @@ Resources:
RestApiId: !Ref MyApiWithLambdaRequestAuth
Method: any
Path: /any/lambda-request
LambdaNotCachedRequest:
Type: Api
Properties:
RestApiId: !Ref MyApiWithNotCachedLambdaRequestAuth
Method: get
Path: /not-cached-lambda-request

MyUserPool:
Type: AWS::Cognito::UserPool
Properties:
Expand Down
22 changes: 22 additions & 0 deletions tests/translator/input/api_with_identity_intrinsic.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
AWSTemplateFormatVersion: "2010-09-09"
Transform: AWS::Serverless-2016-10-31

Conditions:
isProd: true


Resources:
APIGateway:
Type: 'AWS::Serverless::Api'
Properties:
StageName: Prod
Auth:
DefaultAuthorizer: SomeAuthorizer
Authorizers:
SomeAuthorizer:
FunctionPayloadType: REQUEST
FunctionArn: SomeArn
Identity:
Headers:
- Accept
ReauthorizeEvery: !If [isProd, 3600, 0]
Loading