1
1
import json
2
- from typing import Any , Dict , Optional
2
+ from typing import Any , Dict , Optional , cast
3
3
4
4
from samtranslator .metrics .method_decorator import cw_timer
5
5
from samtranslator .model import Property , PropertyType , ResourceMacro , Resource
@@ -27,6 +27,7 @@ class EventSource(ResourceMacro):
27
27
# line to avoid any potential behavior change.
28
28
# TODO: Make `EventSource` an abstract class and not giving `principal` initial value.
29
29
principal : str = None # type: ignore
30
+ relative_id : str # overriding the Optional[str]: for event, relative id is not None
30
31
31
32
Target : Optional [Dict [str , str ]]
32
33
@@ -272,6 +273,11 @@ class Api(EventSource):
272
273
"UnescapeMappingTemplate" : Property (False , is_type (bool )),
273
274
}
274
275
276
+ Path : str
277
+ Method : str
278
+ RestApiId : str
279
+ Stage : Optional [str ]
280
+ Auth : Optional [Dict [str , Any ]]
275
281
UnescapeMappingTemplate : Optional [bool ]
276
282
277
283
def resources_to_link (self , resources ): # type: ignore[no-untyped-def]
@@ -289,7 +295,7 @@ def resources_to_link(self, resources): # type: ignore[no-untyped-def]
289
295
permitted_stage = "*"
290
296
stage_suffix = "AllStages"
291
297
explicit_api = None
292
- rest_api_id = PushApi .get_rest_api_id_string (self .RestApiId ) # type: ignore[attr-defined]
298
+ rest_api_id = PushApi .get_rest_api_id_string (self .RestApiId )
293
299
if isinstance (rest_api_id , str ):
294
300
295
301
if (
@@ -314,7 +320,7 @@ def resources_to_link(self, resources): # type: ignore[no-untyped-def]
314
320
"RestApiId property of Api event must reference a valid resource in the same template." ,
315
321
)
316
322
317
- return {"explicit_api" : explicit_api , "explicit_api_stage" : {"suffix" : stage_suffix }}
323
+ return {"explicit_api" : explicit_api , "api_id" : rest_api_id , " explicit_api_stage" : {"suffix" : stage_suffix }}
318
324
319
325
@cw_timer (prefix = SFN_EVETSOURCE_METRIC_PREFIX )
320
326
def to_cloudformation (self , resource , ** kwargs ): # type: ignore[no-untyped-def]
@@ -336,20 +342,21 @@ def to_cloudformation(self, resource, **kwargs): # type: ignore[no-untyped-def]
336
342
intrinsics_resolver = kwargs .get ("intrinsics_resolver" )
337
343
permissions_boundary = kwargs .get ("permissions_boundary" )
338
344
339
- if self .Method is not None : # type: ignore[has-type]
345
+ if self .Method is not None :
340
346
# Convert to lower case so that user can specify either GET or get
341
- self .Method = self .Method .lower () # type: ignore[has-type]
347
+ self .Method = self .Method .lower ()
342
348
343
349
role = self ._construct_role (resource , permissions_boundary ) # type: ignore[no-untyped-call]
344
350
resources .append (role )
345
351
346
352
explicit_api = kwargs ["explicit_api" ]
353
+ api_id = kwargs ["api_id" ]
347
354
if explicit_api .get ("__MANAGE_SWAGGER" ):
348
- self ._add_swagger_integration (explicit_api , resource , role , intrinsics_resolver ) # type: ignore[no-untyped-call]
355
+ self ._add_swagger_integration (explicit_api , api_id , resource , role , intrinsics_resolver ) # type: ignore[no-untyped-call]
349
356
350
357
return resources
351
358
352
- def _add_swagger_integration (self , api , resource , role , intrinsics_resolver ): # type: ignore[no-untyped-def]
359
+ def _add_swagger_integration (self , api , api_id , resource , role , intrinsics_resolver ): # type: ignore[no-untyped-def]
353
360
"""Adds the path and method for this Api event source to the Swagger body for the provided RestApi.
354
361
355
362
:param model.apigateway.ApiGatewayRestApi rest_api: the RestApi to which the path and method should be added.
@@ -362,12 +369,12 @@ def _add_swagger_integration(self, api, resource, role, intrinsics_resolver): #
362
369
363
370
editor = SwaggerEditor (swagger_body )
364
371
365
- if editor .has_integration (self .Path , self .Method ): # type: ignore[attr-defined]
372
+ if editor .has_integration (self .Path , self .Method ):
366
373
# Cannot add the integration, if it is already present
367
374
raise InvalidEventException (
368
375
self .relative_id ,
369
376
'API method "{method}" defined multiple times for path "{path}".' .format (
370
- method = self .Method , path = self .Path # type: ignore[attr-defined]
377
+ method = self .Method , path = self .Path
371
378
),
372
379
)
373
380
@@ -382,78 +389,23 @@ def _add_swagger_integration(self, api, resource, role, intrinsics_resolver): #
382
389
)
383
390
384
391
editor .add_state_machine_integration ( # type: ignore[no-untyped-call]
385
- self .Path , # type: ignore[attr-defined]
392
+ self .Path ,
386
393
self .Method ,
387
394
integration_uri ,
388
395
role .get_runtime_attr ("arn" ),
389
396
request_template ,
390
397
condition = condition ,
391
398
)
392
399
393
- # Note: Refactor and combine the section below with the Api eventsource for functions
394
- if self .Auth : # type: ignore[attr-defined]
395
- method_authorizer = self .Auth .get ("Authorizer" ) # type: ignore[attr-defined]
396
- api_auth = api .get ("Auth" )
397
- api_auth = intrinsics_resolver .resolve_parameter_refs (api_auth )
398
-
399
- if method_authorizer :
400
- api_authorizers = api_auth and api_auth .get ("Authorizers" )
401
-
402
- if method_authorizer != "AWS_IAM" :
403
- if method_authorizer != "NONE" and not api_authorizers :
404
- raise InvalidEventException (
405
- self .relative_id ,
406
- "Unable to set Authorizer [{authorizer}] on API method [{method}] for path [{path}] "
407
- "because the related API does not define any Authorizers." .format (
408
- authorizer = method_authorizer , method = self .Method , path = self .Path # type: ignore[attr-defined]
409
- ),
410
- )
411
-
412
- if method_authorizer != "NONE" and not api_authorizers .get (method_authorizer ):
413
- raise InvalidEventException (
414
- self .relative_id ,
415
- "Unable to set Authorizer [{authorizer}] on API method [{method}] for path [{path}] "
416
- "because it wasn't defined in the API's Authorizers." .format (
417
- authorizer = method_authorizer , method = self .Method , path = self .Path # type: ignore[attr-defined]
418
- ),
419
- )
420
-
421
- if method_authorizer == "NONE" :
422
- if not api_auth or not api_auth .get ("DefaultAuthorizer" ):
423
- raise InvalidEventException (
424
- self .relative_id ,
425
- "Unable to set Authorizer on API method [{method}] for path [{path}] because 'NONE' "
426
- "is only a valid value when a DefaultAuthorizer on the API is specified." .format (
427
- method = self .Method , path = self .Path # type: ignore[attr-defined]
428
- ),
429
- )
430
-
431
- if self .Auth .get ("AuthorizationScopes" ) and not isinstance (self .Auth .get ("AuthorizationScopes" ), list ): # type: ignore[attr-defined]
432
- raise InvalidEventException (
433
- self .relative_id ,
434
- "Unable to set Authorizer on API method [{method}] for path [{path}] because "
435
- "'AuthorizationScopes' must be a list of strings." .format (method = self .Method , path = self .Path ), # type: ignore[attr-defined]
436
- )
400
+ # self.Stage is not None as it is set in _get_permissions()
401
+ # before calling this method.
402
+ # TODO: refactor to remove this cast
403
+ stage = cast (str , self .Stage )
437
404
438
- apikey_required_setting = self .Auth .get ("ApiKeyRequired" ) # type: ignore[attr-defined]
439
- apikey_required_setting_is_false = apikey_required_setting is not None and not apikey_required_setting
440
- if apikey_required_setting_is_false and (not api_auth or not api_auth .get ("ApiKeyRequired" )):
441
- raise InvalidEventException (
442
- self .relative_id ,
443
- "Unable to set ApiKeyRequired [False] on API method [{method}] for path [{path}] "
444
- "because the related API does not specify any ApiKeyRequired." .format (
445
- method = self .Method , path = self .Path # type: ignore[attr-defined]
446
- ),
447
- )
448
-
449
- if method_authorizer or apikey_required_setting is not None :
450
- editor .add_auth_to_method (api = api , path = self .Path , method_name = self .Method , auth = self .Auth ) # type: ignore[attr-defined, attr-defined, no-untyped-call]
451
-
452
- if self .Auth .get ("ResourcePolicy" ): # type: ignore[attr-defined]
453
- resource_policy = self .Auth .get ("ResourcePolicy" ) # type: ignore[attr-defined]
454
- editor .add_resource_policy (resource_policy = resource_policy , path = self .Path , stage = self .Stage ) # type: ignore[attr-defined, attr-defined, no-untyped-call]
455
- if resource_policy .get ("CustomStatements" ):
456
- editor .add_custom_statements (resource_policy .get ("CustomStatements" )) # type: ignore[no-untyped-call]
405
+ if self .Auth :
406
+ PushApi .add_auth_to_swagger (
407
+ self .Auth , api , api_id , self .relative_id , self .Method , self .Path , stage , editor , intrinsics_resolver
408
+ )
457
409
458
410
api ["DefinitionBody" ] = editor .swagger
459
411
0 commit comments