11import json
22import re
33from datetime import datetime
4- from typing import Dict , List , Optional
4+ from typing import Dict , List
55from urllib .parse import quote
66
77from moto .iam .models import (
8- AccessKey ,
9- AWSManagedPolicy ,
108 IAMBackend ,
11- InlinePolicy ,
12- Policy ,
139 filter_items_with_path_prefix ,
1410 iam_backends ,
1511)
1612from moto .iam .models import Role as MotoRole
17- from moto .iam .policy_validation import VALID_STATEMENT_ELEMENTS
1813
19- from localstack import config
2014from localstack .aws .api import CommonServiceException , RequestContext , handler
2115from localstack .aws .api .iam import (
2216 ActionNameListType ,
6660)
6761from localstack .aws .connect import connect_to
6862from localstack .constants import INTERNAL_AWS_SECRET_ACCESS_KEY
63+ from localstack .services .iam .iam_patches import apply_iam_patches
6964from localstack .services .moto import call_moto
7065from localstack .utils .aws .request_context import extract_access_key_id_from_auth_header
7166from localstack .utils .common import short_uid
72- from localstack .utils .patch import patch
7367
7468SERVICE_LINKED_ROLE_PATH_PREFIX = "/aws-service-role"
7569
76- ADDITIONAL_MANAGED_POLICIES = {
77- "AWSLambdaExecute" : {
78- "Arn" : "arn:aws:iam::aws:policy/AWSLambdaExecute" ,
79- "Path" : "/" ,
80- "CreateDate" : "2017-10-20T17:23:10+00:00" ,
81- "DefaultVersionId" : "v4" ,
82- "Document" : {
83- "Version" : "2012-10-17" ,
84- "Statement" : [
85- {
86- "Effect" : "Allow" ,
87- "Action" : ["logs:*" ],
88- "Resource" : "arn:aws:logs:*:*:*" ,
89- },
90- {
91- "Effect" : "Allow" ,
92- "Action" : ["s3:GetObject" , "s3:PutObject" ],
93- "Resource" : "arn:aws:s3:::*" ,
94- },
95- ],
96- },
97- "UpdateDate" : "2019-05-20T18:22:18+00:00" ,
98- }
99- }
10070
10171POLICY_ARN_REGEX = re .compile (r"arn:[^:]+:iam::(?:\d{12}|aws):policy/.*" )
10272
@@ -107,7 +77,7 @@ def get_iam_backend(context: RequestContext) -> IAMBackend:
10777
10878class IamProvider (IamApi ):
10979 def __init__ (self ):
110- apply_patches ()
80+ apply_iam_patches ()
11181
11282 @handler ("CreateRole" , expand = False )
11383 def create_role (
@@ -450,106 +420,3 @@ def attach_user_policy(
450420 if not POLICY_ARN_REGEX .match (policy_arn ):
451421 raise InvalidInputException (f"ARN { policy_arn } is not valid." )
452422 return call_moto (context = context )
453-
454- # def get_user(
455- # self, context: RequestContext, user_name: existingUserNameType = None
456- # ) -> GetUserResponse:
457- # # TODO: The following migrates patch 'iam_response_get_user' as a provider function.
458- # # However, there are concerns with utilising 'aws_stack.extract_access_key_id_from_auth_header'
459- # # in place of 'moto.core.responses.get_current_user'.
460- # if not user_name:
461- # access_key_id = aws_stack.extract_access_key_id_from_auth_header(context.request.headers)
462- # moto_user = moto_iam_backend.get_user_from_access_key_id(access_key_id)
463- # if moto_user is None:
464- # moto_user = MotoUser("default_user")
465- # else:
466- # moto_user = moto_iam_backend.get_user(user_name)
467- #
468- # response_user_name = config.TEST_IAM_USER_NAME or moto_user.name
469- # response_user_id = config.TEST_IAM_USER_ID or moto_user.id
470- # moto_user = moto_iam_backend.users.get(response_user_name) or moto_user
471- # moto_tags = moto_iam_backend.tagger.list_tags_for_resource(moto_user.arn).get("Tags", [])
472- # response_tags = None
473- # if moto_tags:
474- # response_tags = [Tag(Key=t["Key"], Value=t["Value"]) for t in moto_tags]
475- #
476- # response_user = User()
477- # response_user["Path"] = moto_user.path
478- # response_user["UserName"] = response_user_name
479- # response_user["UserId"] = response_user_id
480- # response_user["Arn"] = moto_user.arn
481- # response_user["CreateDate"] = moto_user.create_date
482- # if moto_user.password_last_used:
483- # response_user["PasswordLastUsed"] = moto_user.password_last_used
484- # # response_user["PermissionsBoundary"] = # TODO
485- # if response_tags:
486- # response_user["Tags"] = response_tags
487- # return GetUserResponse(User=response_user)
488-
489-
490- def apply_patches ():
491- # support service linked roles
492-
493- @property
494- def moto_role_arn (self ):
495- return getattr (self , "service_linked_role_arn" , None ) or moto_role_og_arn_prop .__get__ (self )
496-
497- moto_role_og_arn_prop = MotoRole .arn
498- MotoRole .arn = moto_role_arn
499-
500- # Add missing managed polices
501- # TODO this might not be necessary
502- @patch (IAMBackend ._init_aws_policies )
503- def _init_aws_policies_extended (_init_aws_policies , self ):
504- loaded_policies = _init_aws_policies (self )
505- loaded_policies .extend (
506- [
507- AWSManagedPolicy .from_data (name , self .account_id , self .region_name , d )
508- for name , d in ADDITIONAL_MANAGED_POLICIES .items ()
509- ]
510- )
511- return loaded_policies
512-
513- if "Principal" not in VALID_STATEMENT_ELEMENTS :
514- VALID_STATEMENT_ELEMENTS .append ("Principal" )
515-
516- # patch policy __init__ to set document as attribute
517-
518- @patch (Policy .__init__ )
519- def policy__init__ (
520- fn ,
521- self ,
522- name ,
523- account_id ,
524- region ,
525- default_version_id = None ,
526- description = None ,
527- document = None ,
528- ** kwargs ,
529- ):
530- fn (self , name , account_id , region , default_version_id , description , document , ** kwargs )
531- self .document = document
532-
533- # patch unapply_policy
534-
535- @patch (InlinePolicy .unapply_policy )
536- def inline_policy_unapply_policy (fn , self , backend ):
537- try :
538- fn (self , backend )
539- except Exception :
540- # Actually role can be deleted before policy being deleted in cloudformation
541- pass
542-
543- @patch (AccessKey .__init__ )
544- def access_key__init__ (
545- fn ,
546- self ,
547- user_name : Optional [str ],
548- prefix : str ,
549- account_id : str ,
550- status : str = "Active" ,
551- ** kwargs ,
552- ):
553- if not config .PARITY_AWS_ACCESS_KEY_ID :
554- prefix = "L" + prefix [1 :]
555- fn (self , user_name , prefix , account_id , status , ** kwargs )
0 commit comments