@@ -267,6 +267,20 @@ def _filter_header(param: dict) -> dict:
267
267
return {k : v for k , v in param .items () if k .startswith ("x-amz" ) or k in ["content-type" ]}
268
268
269
269
270
+ def _simple_bucket_policy (s3_bucket : str ) -> dict :
271
+ return {
272
+ "Version" : "2012-10-17" ,
273
+ "Statement" : [
274
+ {
275
+ "Action" : "s3:GetObject" ,
276
+ "Effect" : "Allow" ,
277
+ "Resource" : f"arn:aws:s3:::{ s3_bucket } /*" ,
278
+ "Principal" : {"AWS" : "*" },
279
+ }
280
+ ],
281
+ }
282
+
283
+
270
284
class TestS3 :
271
285
@pytest .mark .skipif (condition = TEST_S3_IMAGE , reason = "KMS not enabled in S3 image" )
272
286
@markers .aws .validated
@@ -964,31 +978,136 @@ def test_create_bucket_via_host_name(self, s3_vhost_client, aws_client, region_n
964
978
s3_vhost_client .delete_bucket (Bucket = bucket_name )
965
979
966
980
@markers .aws .validated
967
- def test_put_and_get_bucket_policy (self , s3_bucket , snapshot , aws_client , allow_bucket_acl ):
981
+ def test_get_bucket_policy (self , s3_bucket , snapshot , aws_client , allow_bucket_acl , account_id ):
982
+ snapshot .add_transformer (snapshot .transform .key_value ("Resource" ))
983
+ snapshot .add_transformer (snapshot .transform .key_value ("BucketName" ))
984
+
985
+ with pytest .raises (ClientError ) as e :
986
+ aws_client .s3 .get_bucket_policy (Bucket = s3_bucket )
987
+ snapshot .match ("get-bucket-policy-no-such-bucket-policy" , e .value .response )
988
+
989
+ policy = _simple_bucket_policy (s3_bucket )
990
+ aws_client .s3 .put_bucket_policy (Bucket = s3_bucket , Policy = json .dumps (policy ))
991
+
992
+ # retrieve and check policy config
993
+ response = aws_client .s3 .get_bucket_policy (Bucket = s3_bucket )
994
+ snapshot .match ("get-bucket-policy" , response )
995
+ assert policy == json .loads (response ["Policy" ])
996
+
997
+ response = aws_client .s3 .get_bucket_policy (Bucket = s3_bucket , ExpectedBucketOwner = account_id )
998
+ snapshot .match ("get-bucket-policy-with-expected-bucket-owner" , response )
999
+ assert policy == json .loads (response ["Policy" ])
1000
+
1001
+ with pytest .raises (ClientError ) as e :
1002
+ aws_client .s3 .get_bucket_policy (Bucket = s3_bucket , ExpectedBucketOwner = "000000000002" )
1003
+ snapshot .match ("get-bucket-policy-with-expected-bucket-owner-error" , e .value .response )
1004
+
1005
+ @pytest .mark .parametrize (
1006
+ "invalid_account_id" , ["0000" , "0000000000020" , "abcd" , "aa000000000$" ]
1007
+ )
1008
+ @markers .aws .validated
1009
+ def test_get_bucket_policy_invalid_account_id (
1010
+ self , s3_bucket , snapshot , aws_client , invalid_account_id
1011
+ ):
1012
+ with pytest .raises (ClientError ) as e :
1013
+ aws_client .s3 .get_bucket_policy (
1014
+ Bucket = s3_bucket , ExpectedBucketOwner = invalid_account_id
1015
+ )
1016
+
1017
+ snapshot .match ("get-bucket-policy-invalid-bucket-owner" , e .value .response )
1018
+
1019
+ @markers .aws .validated
1020
+ def test_put_bucket_policy (self , s3_bucket , snapshot , aws_client , allow_bucket_acl ):
968
1021
# just for the joke: Response syntax HTTP/1.1 200
969
1022
# sample response: HTTP/1.1 204 No Content
970
1023
# https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketPolicy.html
971
1024
snapshot .add_transformer (snapshot .transform .key_value ("Resource" ))
972
1025
# put bucket policy
973
- policy = {
974
- "Version" : "2012-10-17" ,
975
- "Statement" : [
976
- {
977
- "Action" : "s3:GetObject" ,
978
- "Effect" : "Allow" ,
979
- "Resource" : f"arn:aws:s3:::{ s3_bucket } /*" ,
980
- "Principal" : {"AWS" : "*" },
981
- }
982
- ],
983
- }
1026
+ policy = _simple_bucket_policy (s3_bucket )
984
1027
response = aws_client .s3 .put_bucket_policy (Bucket = s3_bucket , Policy = json .dumps (policy ))
985
1028
snapshot .match ("put-bucket-policy" , response )
986
1029
987
- # retrieve and check policy config
988
1030
response = aws_client .s3 .get_bucket_policy (Bucket = s3_bucket )
989
1031
snapshot .match ("get-bucket-policy" , response )
990
1032
assert policy == json .loads (response ["Policy" ])
991
1033
1034
+ @markers .aws .validated
1035
+ def test_put_bucket_policy_expected_bucket_owner (
1036
+ self , s3_bucket , snapshot , aws_client , allow_bucket_acl , account_id , secondary_account_id
1037
+ ):
1038
+ snapshot .add_transformer (snapshot .transform .key_value ("Resource" ))
1039
+ policy = _simple_bucket_policy (s3_bucket )
1040
+
1041
+ with pytest .raises (ClientError ) as e :
1042
+ aws_client .s3 .put_bucket_policy (
1043
+ Bucket = s3_bucket ,
1044
+ Policy = json .dumps (policy ),
1045
+ ExpectedBucketOwner = secondary_account_id ,
1046
+ )
1047
+ snapshot .match ("put-bucket-policy-with-expected-bucket-owner-error" , e .value .response )
1048
+
1049
+ response = aws_client .s3 .put_bucket_policy (
1050
+ Bucket = s3_bucket , Policy = json .dumps (policy ), ExpectedBucketOwner = account_id
1051
+ )
1052
+ snapshot .match ("put-bucket-policy-with-expected-bucket-owner" , response )
1053
+
1054
+ @pytest .mark .parametrize (
1055
+ "invalid_account_id" , ["0000" , "0000000000020" , "abcd" , "aa000000000$" ]
1056
+ )
1057
+ @markers .aws .validated
1058
+ def test_put_bucket_policy_invalid_account_id (
1059
+ self , s3_bucket , snapshot , aws_client , invalid_account_id
1060
+ ):
1061
+ snapshot .add_transformer (snapshot .transform .key_value ("Resource" ))
1062
+ policy = _simple_bucket_policy (s3_bucket )
1063
+
1064
+ with pytest .raises (ClientError ) as e :
1065
+ aws_client .s3 .put_bucket_policy (
1066
+ Bucket = s3_bucket , Policy = json .dumps (policy ), ExpectedBucketOwner = invalid_account_id
1067
+ )
1068
+
1069
+ snapshot .match ("put-bucket-policy-invalid-bucket-owner" , e .value .response )
1070
+
1071
+ @markers .aws .validated
1072
+ def test_delete_bucket_policy (self , s3_bucket , snapshot , aws_client , allow_bucket_acl ):
1073
+ snapshot .add_transformer (snapshot .transform .key_value ("Resource" ))
1074
+ snapshot .add_transformer (snapshot .transform .key_value ("BucketName" ))
1075
+
1076
+ policy = _simple_bucket_policy (s3_bucket )
1077
+ aws_client .s3 .put_bucket_policy (Bucket = s3_bucket , Policy = json .dumps (policy ))
1078
+
1079
+ response = aws_client .s3 .delete_bucket_policy (Bucket = s3_bucket )
1080
+ snapshot .match ("delete-bucket-policy" , response )
1081
+
1082
+ with pytest .raises (ClientError ) as e :
1083
+ aws_client .s3 .get_bucket_policy (Bucket = s3_bucket )
1084
+ snapshot .match ("get-bucket-policy-no-such-bucket-policy" , e .value .response )
1085
+
1086
+ @markers .aws .validated
1087
+ def test_delete_bucket_policy_expected_bucket_owner (
1088
+ self , s3_bucket , snapshot , aws_client , allow_bucket_acl , account_id , secondary_account_id
1089
+ ):
1090
+ snapshot .add_transformer (snapshot .transform .key_value ("Resource" ))
1091
+ snapshot .add_transformer (snapshot .transform .key_value ("BucketName" ))
1092
+
1093
+ policy = _simple_bucket_policy (s3_bucket )
1094
+ aws_client .s3 .put_bucket_policy (Bucket = s3_bucket , Policy = json .dumps (policy ))
1095
+
1096
+ with pytest .raises (ClientError ) as e :
1097
+ aws_client .s3 .delete_bucket_policy (
1098
+ Bucket = s3_bucket , ExpectedBucketOwner = secondary_account_id
1099
+ )
1100
+ snapshot .match ("delete-bucket-policy-with-expected-bucket-owner-error" , e .value .response )
1101
+
1102
+ with pytest .raises (ClientError ) as e :
1103
+ aws_client .s3 .delete_bucket_policy (Bucket = s3_bucket , ExpectedBucketOwner = "invalid" )
1104
+ snapshot .match ("delete-bucket-policy-invalid-bucket-owner" , e .value .response )
1105
+
1106
+ response = aws_client .s3 .delete_bucket_policy (
1107
+ Bucket = s3_bucket , ExpectedBucketOwner = account_id
1108
+ )
1109
+ snapshot .match ("delete-bucket-policy-with-expected-bucket-owner" , response )
1110
+
992
1111
@markers .aws .validated
993
1112
def test_put_object_tagging_empty_list (self , s3_bucket , snapshot , aws_client ):
994
1113
key = "my-key"
0 commit comments