1616
1717POLICY_NAME_FORMAT = "{bucket_name}-owner-policy"
1818
19- REQUIRE_HTTPS_CONDITION = {
20- "Bool" : {
21- # Require HTTPS
22- "aws:SecureTransport" : "true"
23- },
24- "NumericGreaterThanEquals" : {
25- # Require TLS >= 1.2
26- "s3:TlsVersion" : ["1.2" ]
27- },
28- }
29-
3019
3120class BucketCreator :
3221 def __init__ (self , profile_name = None , region_name = None ):
@@ -77,11 +66,22 @@ def format_path(path):
7766 "Principal" : "*" ,
7867 "Action" : ["s3:GetObject" ],
7968 "Resource" : paths_resources ,
80- # Require HTTPS for public requests
81- "Condition" : REQUIRE_HTTPS_CONDITION ,
8269 }
8370
8471 def get_bucket_policy_statements_for_user_access (self , bucket , user ):
72+ # Deny access which isn't over HTTPS
73+ yield {
74+ "Sid" : "DenyInsecureTransport" ,
75+ "Effect" : "Deny" ,
76+ "Principal" : "*" ,
77+ "Action" : "s3:*" ,
78+ "Resource" : [
79+ f"arn:aws:s3:::{ bucket .name } " ,
80+ f"arn:aws:s3:::{ bucket .name } /*" ,
81+ ],
82+ "Condition" : {"Bool" : {"aws:SecureTransport" : "false" }},
83+ }
84+
8585 # Create policy statement giving the created user access to
8686 # non-destructive actions on the bucket.
8787 yield {
@@ -95,8 +95,6 @@ def get_bucket_policy_statements_for_user_access(self, bucket, user):
9595 "s3:ListBucketVersions" ,
9696 ],
9797 "Resource" : "arn:aws:s3:::{bucket_name}" .format (bucket_name = bucket .name ),
98- # Require HTTPS for API
99- "Condition" : REQUIRE_HTTPS_CONDITION ,
10098 }
10199 # Create policy statement giving the created user full access over the
102100 # objects.
@@ -106,14 +104,11 @@ def get_bucket_policy_statements_for_user_access(self, bucket, user):
106104 "Principal" : {"AWS" : user .arn },
107105 "Action" : "s3:*" ,
108106 "Resource" : "arn:aws:s3:::{bucket_name}/*" .format (bucket_name = bucket .name ),
109- # Require HTTPS for API
110- "Condition" : REQUIRE_HTTPS_CONDITION ,
111107 }
112108
113109 def set_bucket_policy (
114110 self , bucket , user , allow_public_acls , public_get_object_paths = None
115111 ):
116- policy_statement = []
117112 public_access = bool (public_get_object_paths )
118113
119114 # NB: This API doesn't exist on a `Bucket`
@@ -129,15 +124,16 @@ def set_bucket_policy(
129124 if public_access or allow_public_acls :
130125 print ("Configured public access to bucket." )
131126
127+ policy_statement = list (
128+ self .get_bucket_policy_statements_for_user_access (bucket , user )
129+ )
130+
132131 if public_access :
133132 policy_statement .append (
134133 self .get_bucket_policy_statement_for_get_object (
135134 bucket , public_get_object_paths
136135 )
137136 )
138- policy_statement .extend (
139- list (self .get_bucket_policy_statements_for_user_access (bucket , user ))
140- )
141137 policy = json .dumps (
142138 {
143139 "Version" : "2012-10-17" ,
@@ -148,7 +144,7 @@ def set_bucket_policy(
148144 try :
149145 bucket .Policy ().put (Policy = policy )
150146 except ClientError as e :
151- if e .response ["Error" ]["Code " ] == "MalformedPolicy " :
147+ if e .response ["Error" ]["Message " ] == "Invalid principal in policy " :
152148 print (
153149 "Waiting for the user to be available to be "
154150 "attached to the policy (wait 5s)."
0 commit comments