2023-09-08 13:12:26 +00:00
|
|
|
import json
|
2023-11-30 15:55:51 +00:00
|
|
|
from unittest import SkipTest
|
|
|
|
from unittest.mock import patch
|
2024-03-06 23:00:19 +00:00
|
|
|
from uuid import uuid4
|
2023-09-08 13:12:26 +00:00
|
|
|
|
2023-01-16 23:36:08 +00:00
|
|
|
import boto3
|
|
|
|
import pytest
|
2023-09-08 13:12:26 +00:00
|
|
|
from botocore.client import ClientError
|
2023-01-16 23:36:08 +00:00
|
|
|
|
2024-01-07 12:03:33 +00:00
|
|
|
from moto import mock_aws, settings
|
2023-09-08 13:12:26 +00:00
|
|
|
from moto.core import DEFAULT_ACCOUNT_ID
|
|
|
|
from moto.s3 import s3_backends
|
|
|
|
from moto.s3.models import FakeBucket
|
2023-08-07 16:48:48 +00:00
|
|
|
from moto.s3.responses import DEFAULT_REGION_NAME
|
2024-03-06 23:00:19 +00:00
|
|
|
from tests.test_s3 import empty_bucket, s3_aws_verified
|
2023-01-16 23:36:08 +00:00
|
|
|
|
|
|
|
|
2024-01-07 12:03:33 +00:00
|
|
|
@mock_aws
|
2023-01-16 23:36:08 +00:00
|
|
|
def test_put_bucket_logging():
|
2023-08-07 16:48:48 +00:00
|
|
|
s3_client = boto3.client("s3", region_name=DEFAULT_REGION_NAME)
|
2023-01-16 23:36:08 +00:00
|
|
|
bucket_name = "mybucket"
|
|
|
|
log_bucket = "logbucket"
|
|
|
|
wrong_region_bucket = "wrongregionlogbucket"
|
2023-08-07 16:48:48 +00:00
|
|
|
s3_client.create_bucket(Bucket=bucket_name)
|
|
|
|
# Adding the ACL for log-delivery later...
|
|
|
|
s3_client.create_bucket(Bucket=log_bucket)
|
|
|
|
s3_client.create_bucket(
|
2023-01-16 23:36:08 +00:00
|
|
|
Bucket=wrong_region_bucket,
|
|
|
|
CreateBucketConfiguration={"LocationConstraint": "us-west-2"},
|
|
|
|
)
|
|
|
|
|
|
|
|
# No logging config:
|
2023-08-07 16:48:48 +00:00
|
|
|
result = s3_client.get_bucket_logging(Bucket=bucket_name)
|
2023-01-16 23:36:08 +00:00
|
|
|
assert not result.get("LoggingEnabled")
|
|
|
|
|
|
|
|
# A log-bucket that doesn't exist:
|
|
|
|
with pytest.raises(ClientError) as err:
|
2023-08-07 16:48:48 +00:00
|
|
|
s3_client.put_bucket_logging(
|
2023-01-16 23:36:08 +00:00
|
|
|
Bucket=bucket_name,
|
|
|
|
BucketLoggingStatus={
|
|
|
|
"LoggingEnabled": {"TargetBucket": "IAMNOTREAL", "TargetPrefix": ""}
|
|
|
|
},
|
|
|
|
)
|
|
|
|
assert err.value.response["Error"]["Code"] == "InvalidTargetBucketForLogging"
|
|
|
|
|
|
|
|
# A log-bucket that's missing the proper ACLs for LogDelivery:
|
|
|
|
with pytest.raises(ClientError) as err:
|
2023-08-07 16:48:48 +00:00
|
|
|
s3_client.put_bucket_logging(
|
2023-01-16 23:36:08 +00:00
|
|
|
Bucket=bucket_name,
|
|
|
|
BucketLoggingStatus={
|
|
|
|
"LoggingEnabled": {"TargetBucket": log_bucket, "TargetPrefix": ""}
|
|
|
|
},
|
|
|
|
)
|
|
|
|
assert err.value.response["Error"]["Code"] == "InvalidTargetBucketForLogging"
|
|
|
|
assert "log-delivery" in err.value.response["Error"]["Message"]
|
|
|
|
|
|
|
|
# Add the proper "log-delivery" ACL to the log buckets:
|
2023-08-07 16:48:48 +00:00
|
|
|
bucket_owner = s3_client.get_bucket_acl(Bucket=log_bucket)["Owner"]
|
2023-01-16 23:36:08 +00:00
|
|
|
for bucket in [log_bucket, wrong_region_bucket]:
|
2023-08-07 16:48:48 +00:00
|
|
|
s3_client.put_bucket_acl(
|
2023-01-16 23:36:08 +00:00
|
|
|
Bucket=bucket,
|
|
|
|
AccessControlPolicy={
|
|
|
|
"Grants": [
|
|
|
|
{
|
|
|
|
"Grantee": {
|
|
|
|
"URI": "http://acs.amazonaws.com/groups/s3/LogDelivery",
|
|
|
|
"Type": "Group",
|
|
|
|
},
|
|
|
|
"Permission": "WRITE",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"Grantee": {
|
|
|
|
"URI": "http://acs.amazonaws.com/groups/s3/LogDelivery",
|
|
|
|
"Type": "Group",
|
|
|
|
},
|
|
|
|
"Permission": "READ_ACP",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"Grantee": {"Type": "CanonicalUser", "ID": bucket_owner["ID"]},
|
|
|
|
"Permission": "FULL_CONTROL",
|
|
|
|
},
|
|
|
|
],
|
|
|
|
"Owner": bucket_owner,
|
|
|
|
},
|
|
|
|
)
|
|
|
|
|
|
|
|
# A log-bucket that's in the wrong region:
|
|
|
|
with pytest.raises(ClientError) as err:
|
2023-08-07 16:48:48 +00:00
|
|
|
s3_client.put_bucket_logging(
|
2023-01-16 23:36:08 +00:00
|
|
|
Bucket=bucket_name,
|
|
|
|
BucketLoggingStatus={
|
|
|
|
"LoggingEnabled": {
|
|
|
|
"TargetBucket": wrong_region_bucket,
|
|
|
|
"TargetPrefix": "",
|
|
|
|
}
|
|
|
|
},
|
|
|
|
)
|
|
|
|
assert err.value.response["Error"]["Code"] == "CrossLocationLoggingProhibitted"
|
|
|
|
|
|
|
|
# Correct logging:
|
2023-08-07 16:48:48 +00:00
|
|
|
s3_client.put_bucket_logging(
|
2023-01-16 23:36:08 +00:00
|
|
|
Bucket=bucket_name,
|
|
|
|
BucketLoggingStatus={
|
|
|
|
"LoggingEnabled": {
|
|
|
|
"TargetBucket": log_bucket,
|
|
|
|
"TargetPrefix": f"{bucket_name}/",
|
|
|
|
}
|
|
|
|
},
|
|
|
|
)
|
2023-08-07 16:48:48 +00:00
|
|
|
result = s3_client.get_bucket_logging(Bucket=bucket_name)
|
2023-01-16 23:36:08 +00:00
|
|
|
assert result["LoggingEnabled"]["TargetBucket"] == log_bucket
|
|
|
|
assert result["LoggingEnabled"]["TargetPrefix"] == f"{bucket_name}/"
|
|
|
|
assert not result["LoggingEnabled"].get("TargetGrants")
|
|
|
|
|
|
|
|
# And disabling:
|
2023-08-07 16:48:48 +00:00
|
|
|
s3_client.put_bucket_logging(Bucket=bucket_name, BucketLoggingStatus={})
|
|
|
|
assert not s3_client.get_bucket_logging(Bucket=bucket_name).get("LoggingEnabled")
|
2023-01-16 23:36:08 +00:00
|
|
|
|
|
|
|
# And enabling with multiple target grants:
|
2023-08-07 16:48:48 +00:00
|
|
|
s3_client.put_bucket_logging(
|
2023-01-16 23:36:08 +00:00
|
|
|
Bucket=bucket_name,
|
|
|
|
BucketLoggingStatus={
|
|
|
|
"LoggingEnabled": {
|
|
|
|
"TargetBucket": log_bucket,
|
|
|
|
"TargetPrefix": f"{bucket_name}/",
|
|
|
|
"TargetGrants": [
|
|
|
|
{
|
|
|
|
"Grantee": {
|
|
|
|
"ID": "SOMEIDSTRINGHERE9238748923734823917498237489237409123840983274",
|
|
|
|
"Type": "CanonicalUser",
|
|
|
|
},
|
|
|
|
"Permission": "READ",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"Grantee": {
|
|
|
|
"ID": "SOMEIDSTRINGHERE9238748923734823917498237489237409123840983274",
|
|
|
|
"Type": "CanonicalUser",
|
|
|
|
},
|
|
|
|
"Permission": "WRITE",
|
|
|
|
},
|
|
|
|
],
|
|
|
|
}
|
|
|
|
},
|
|
|
|
)
|
|
|
|
|
2023-08-07 16:48:48 +00:00
|
|
|
result = s3_client.get_bucket_logging(Bucket=bucket_name)
|
2023-01-16 23:36:08 +00:00
|
|
|
assert len(result["LoggingEnabled"]["TargetGrants"]) == 2
|
|
|
|
assert (
|
|
|
|
result["LoggingEnabled"]["TargetGrants"][0]["Grantee"]["ID"]
|
|
|
|
== "SOMEIDSTRINGHERE9238748923734823917498237489237409123840983274"
|
|
|
|
)
|
|
|
|
|
|
|
|
# Test with just 1 grant:
|
2023-08-07 16:48:48 +00:00
|
|
|
s3_client.put_bucket_logging(
|
2023-01-16 23:36:08 +00:00
|
|
|
Bucket=bucket_name,
|
|
|
|
BucketLoggingStatus={
|
|
|
|
"LoggingEnabled": {
|
|
|
|
"TargetBucket": log_bucket,
|
|
|
|
"TargetPrefix": f"{bucket_name}/",
|
|
|
|
"TargetGrants": [
|
|
|
|
{
|
|
|
|
"Grantee": {
|
|
|
|
"ID": "SOMEIDSTRINGHERE9238748923734823917498237489237409123840983274",
|
|
|
|
"Type": "CanonicalUser",
|
|
|
|
},
|
|
|
|
"Permission": "READ",
|
|
|
|
}
|
|
|
|
],
|
|
|
|
}
|
|
|
|
},
|
|
|
|
)
|
2023-08-07 16:48:48 +00:00
|
|
|
result = s3_client.get_bucket_logging(Bucket=bucket_name)
|
2023-01-16 23:36:08 +00:00
|
|
|
assert len(result["LoggingEnabled"]["TargetGrants"]) == 1
|
|
|
|
|
|
|
|
# With an invalid grant:
|
|
|
|
with pytest.raises(ClientError) as err:
|
2023-08-07 16:48:48 +00:00
|
|
|
s3_client.put_bucket_logging(
|
2023-01-16 23:36:08 +00:00
|
|
|
Bucket=bucket_name,
|
|
|
|
BucketLoggingStatus={
|
|
|
|
"LoggingEnabled": {
|
|
|
|
"TargetBucket": log_bucket,
|
|
|
|
"TargetPrefix": f"{bucket_name}/",
|
|
|
|
"TargetGrants": [
|
|
|
|
{
|
|
|
|
"Grantee": {
|
2023-08-07 16:48:48 +00:00
|
|
|
"ID": (
|
|
|
|
"SOMEIDSTRINGHERE9238748923734823917498"
|
|
|
|
"237489237409123840983274"
|
|
|
|
),
|
2023-01-16 23:36:08 +00:00
|
|
|
"Type": "CanonicalUser",
|
|
|
|
},
|
|
|
|
"Permission": "NOTAREALPERM",
|
|
|
|
}
|
|
|
|
],
|
|
|
|
}
|
|
|
|
},
|
|
|
|
)
|
|
|
|
assert err.value.response["Error"]["Code"] == "MalformedXML"
|
|
|
|
|
|
|
|
|
2024-01-07 12:03:33 +00:00
|
|
|
@mock_aws
|
2023-01-16 23:36:08 +00:00
|
|
|
def test_log_file_is_created():
|
|
|
|
# Create necessary buckets
|
2023-08-07 16:48:48 +00:00
|
|
|
s3_client = boto3.client("s3", region_name=DEFAULT_REGION_NAME)
|
2023-01-16 23:36:08 +00:00
|
|
|
bucket_name = "mybucket"
|
|
|
|
log_bucket = "logbucket"
|
2023-08-07 16:48:48 +00:00
|
|
|
s3_client.create_bucket(Bucket=bucket_name)
|
|
|
|
s3_client.create_bucket(Bucket=log_bucket)
|
2023-01-16 23:36:08 +00:00
|
|
|
|
|
|
|
# Enable logging
|
2023-08-07 16:48:48 +00:00
|
|
|
bucket_owner = s3_client.get_bucket_acl(Bucket=log_bucket)["Owner"]
|
|
|
|
s3_client.put_bucket_acl(
|
2023-01-16 23:36:08 +00:00
|
|
|
Bucket=log_bucket,
|
|
|
|
AccessControlPolicy={
|
|
|
|
"Grants": [
|
|
|
|
{
|
|
|
|
"Grantee": {
|
|
|
|
"URI": "http://acs.amazonaws.com/groups/s3/LogDelivery",
|
|
|
|
"Type": "Group",
|
|
|
|
},
|
|
|
|
"Permission": "WRITE",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"Grantee": {
|
|
|
|
"URI": "http://acs.amazonaws.com/groups/s3/LogDelivery",
|
|
|
|
"Type": "Group",
|
|
|
|
},
|
|
|
|
"Permission": "READ_ACP",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"Grantee": {"Type": "CanonicalUser", "ID": bucket_owner["ID"]},
|
|
|
|
"Permission": "FULL_CONTROL",
|
|
|
|
},
|
|
|
|
],
|
|
|
|
"Owner": bucket_owner,
|
|
|
|
},
|
|
|
|
)
|
2023-08-07 16:48:48 +00:00
|
|
|
s3_client.put_bucket_logging(
|
2023-01-16 23:36:08 +00:00
|
|
|
Bucket=bucket_name,
|
|
|
|
BucketLoggingStatus={
|
|
|
|
"LoggingEnabled": {
|
|
|
|
"TargetBucket": log_bucket,
|
|
|
|
"TargetPrefix": f"{bucket_name}/",
|
|
|
|
}
|
|
|
|
},
|
|
|
|
)
|
|
|
|
|
|
|
|
# Make some requests against the source bucket
|
2023-08-07 16:48:48 +00:00
|
|
|
s3_client.put_object(Bucket=bucket_name, Key="key1", Body=b"")
|
|
|
|
s3_client.put_object(Bucket=bucket_name, Key="key2", Body=b"data")
|
2023-01-16 23:36:08 +00:00
|
|
|
|
2023-08-07 16:48:48 +00:00
|
|
|
s3_client.put_bucket_logging(
|
2023-01-16 23:36:08 +00:00
|
|
|
Bucket=bucket_name,
|
|
|
|
BucketLoggingStatus={
|
|
|
|
"LoggingEnabled": {"TargetBucket": log_bucket, "TargetPrefix": ""}
|
|
|
|
},
|
|
|
|
)
|
2023-08-07 16:48:48 +00:00
|
|
|
s3_client.list_objects_v2(Bucket=bucket_name)
|
2023-01-16 23:36:08 +00:00
|
|
|
|
|
|
|
# Verify files are created in the target (logging) bucket
|
2023-08-07 16:48:48 +00:00
|
|
|
keys = [k["Key"] for k in s3_client.list_objects_v2(Bucket=log_bucket)["Contents"]]
|
|
|
|
assert len([k for k in keys if k.startswith("mybucket/")]) == 3
|
|
|
|
assert len([k for k in keys if not k.startswith("mybucket/")]) == 1
|
2023-01-16 23:36:08 +00:00
|
|
|
|
|
|
|
# Verify (roughly) files have the correct content
|
|
|
|
contents = [
|
2023-08-07 16:48:48 +00:00
|
|
|
s3_client.get_object(Bucket=log_bucket, Key=key)["Body"].read().decode("utf-8")
|
2023-01-16 23:36:08 +00:00
|
|
|
for key in keys
|
|
|
|
]
|
2023-08-07 16:48:48 +00:00
|
|
|
assert any(c for c in contents if bucket_name in c)
|
|
|
|
assert any(c for c in contents if "REST.GET.BUCKET" in c)
|
|
|
|
assert any(c for c in contents if "REST.PUT.BUCKET" in c)
|
2023-09-08 13:12:26 +00:00
|
|
|
|
|
|
|
|
2024-01-07 12:03:33 +00:00
|
|
|
@mock_aws
|
2023-09-08 13:12:26 +00:00
|
|
|
def test_invalid_bucket_logging_when_permissions_are_false():
|
2023-09-19 19:46:20 +00:00
|
|
|
if not settings.TEST_DECORATOR_MODE:
|
2023-09-08 13:12:26 +00:00
|
|
|
raise SkipTest("Can't patch permission logic in ServerMode")
|
|
|
|
|
|
|
|
s3_client = boto3.client("s3", region_name=DEFAULT_REGION_NAME)
|
|
|
|
bucket_name = "mybucket"
|
|
|
|
log_bucket = "logbucket"
|
|
|
|
s3_client.create_bucket(Bucket=bucket_name)
|
|
|
|
s3_client.create_bucket(Bucket=log_bucket)
|
|
|
|
with patch(
|
|
|
|
"moto.s3.models.FakeBucket._log_permissions_enabled_policy", return_value=False
|
|
|
|
), patch(
|
|
|
|
"moto.s3.models.FakeBucket._log_permissions_enabled_acl", return_value=False
|
|
|
|
):
|
|
|
|
with pytest.raises(ClientError) as err:
|
|
|
|
s3_client.put_bucket_logging(
|
|
|
|
Bucket=bucket_name,
|
|
|
|
BucketLoggingStatus={
|
|
|
|
"LoggingEnabled": {"TargetBucket": log_bucket, "TargetPrefix": ""}
|
|
|
|
},
|
|
|
|
)
|
|
|
|
assert err.value.response["Error"]["Code"] == "InvalidTargetBucketForLogging"
|
|
|
|
assert "log-delivery" in err.value.response["Error"]["Message"]
|
|
|
|
|
|
|
|
|
2024-01-07 12:03:33 +00:00
|
|
|
@mock_aws
|
2023-09-08 13:12:26 +00:00
|
|
|
def test_valid_bucket_logging_when_permissions_are_true():
|
2023-09-19 19:46:20 +00:00
|
|
|
if not settings.TEST_DECORATOR_MODE:
|
2023-09-08 13:12:26 +00:00
|
|
|
raise SkipTest("Can't patch permission logic in ServerMode")
|
|
|
|
|
|
|
|
s3_client = boto3.client("s3", region_name=DEFAULT_REGION_NAME)
|
|
|
|
bucket_name = "mybucket"
|
|
|
|
log_bucket = "logbucket"
|
|
|
|
s3_client.create_bucket(Bucket=bucket_name)
|
|
|
|
s3_client.create_bucket(Bucket=log_bucket)
|
|
|
|
with patch(
|
|
|
|
"moto.s3.models.FakeBucket._log_permissions_enabled_policy", return_value=True
|
|
|
|
), patch(
|
|
|
|
"moto.s3.models.FakeBucket._log_permissions_enabled_acl", return_value=True
|
|
|
|
):
|
|
|
|
s3_client.put_bucket_logging(
|
|
|
|
Bucket=bucket_name,
|
|
|
|
BucketLoggingStatus={
|
|
|
|
"LoggingEnabled": {
|
|
|
|
"TargetBucket": log_bucket,
|
|
|
|
"TargetPrefix": f"{bucket_name}/",
|
|
|
|
}
|
|
|
|
},
|
|
|
|
)
|
|
|
|
result = s3_client.get_bucket_logging(Bucket=bucket_name)
|
|
|
|
assert result["LoggingEnabled"]["TargetBucket"] == log_bucket
|
|
|
|
assert result["LoggingEnabled"]["TargetPrefix"] == f"{bucket_name}/"
|
|
|
|
|
|
|
|
|
2024-01-07 12:03:33 +00:00
|
|
|
@mock_aws
|
2023-09-08 13:12:26 +00:00
|
|
|
def test_bucket_policy_not_set():
|
2023-09-19 19:46:20 +00:00
|
|
|
if not settings.TEST_DECORATOR_MODE:
|
2023-09-08 13:12:26 +00:00
|
|
|
raise SkipTest("Can't patch permission logic in ServerMode")
|
|
|
|
|
|
|
|
s3_client = boto3.client("s3", region_name=DEFAULT_REGION_NAME)
|
|
|
|
s3_backend = s3_backends[DEFAULT_ACCOUNT_ID]["global"]
|
|
|
|
|
|
|
|
log_bucket = "log_bucket"
|
|
|
|
s3_client.create_bucket(Bucket=log_bucket)
|
|
|
|
log_bucket_obj = s3_backend.get_bucket(log_bucket)
|
|
|
|
|
|
|
|
assert (
|
|
|
|
FakeBucket._log_permissions_enabled_policy(
|
|
|
|
target_bucket=log_bucket_obj, target_prefix=""
|
|
|
|
)
|
|
|
|
is False
|
|
|
|
)
|
|
|
|
|
|
|
|
|
2024-01-07 12:03:33 +00:00
|
|
|
@mock_aws
|
2023-09-08 13:12:26 +00:00
|
|
|
def test_bucket_policy_principal():
|
2023-09-19 19:46:20 +00:00
|
|
|
if not settings.TEST_DECORATOR_MODE:
|
2023-09-08 13:12:26 +00:00
|
|
|
raise SkipTest("Can't patch permission logic in ServerMode")
|
|
|
|
|
|
|
|
s3_client = boto3.client("s3", region_name=DEFAULT_REGION_NAME)
|
|
|
|
s3_backend = s3_backends[DEFAULT_ACCOUNT_ID]["global"]
|
|
|
|
|
|
|
|
log_bucket = "log_bucket"
|
|
|
|
s3_client.create_bucket(Bucket=log_bucket)
|
|
|
|
log_bucket_obj = s3_backend.get_bucket(log_bucket)
|
|
|
|
|
|
|
|
invalid_principal_policy = {
|
|
|
|
"Version": "2012-10-17",
|
|
|
|
"Statement": [
|
|
|
|
{
|
|
|
|
"Sid": "S3ServerAccessLogsPolicy",
|
|
|
|
"Effect": "Allow",
|
|
|
|
"Principal": {"Service": "not_logging.s3.amazonaws.com"},
|
|
|
|
"Action": ["s3:PutObject"],
|
|
|
|
"Resource": f"arn:aws:s3:::{log_bucket}/*",
|
|
|
|
}
|
|
|
|
],
|
|
|
|
}
|
|
|
|
s3_client.put_bucket_policy(
|
|
|
|
Bucket=log_bucket, Policy=json.dumps(invalid_principal_policy)
|
|
|
|
)
|
|
|
|
assert (
|
|
|
|
FakeBucket._log_permissions_enabled_policy(
|
|
|
|
target_bucket=log_bucket_obj, target_prefix=""
|
|
|
|
)
|
|
|
|
is False
|
|
|
|
)
|
|
|
|
|
|
|
|
s3_client.delete_bucket_policy(Bucket=log_bucket)
|
|
|
|
valid_principal_policy = {
|
|
|
|
"Version": "2012-10-17",
|
|
|
|
"Statement": [
|
|
|
|
{
|
|
|
|
"Sid": "S3ServerAccessLogsPolicy",
|
|
|
|
"Effect": "Allow",
|
|
|
|
"Principal": {"Service": "logging.s3.amazonaws.com"},
|
|
|
|
"Action": ["s3:PutObject"],
|
|
|
|
"Resource": f"arn:aws:s3:::{log_bucket}/*",
|
|
|
|
}
|
|
|
|
],
|
|
|
|
}
|
|
|
|
s3_client.put_bucket_policy(
|
|
|
|
Bucket=log_bucket, Policy=json.dumps(valid_principal_policy)
|
|
|
|
)
|
|
|
|
assert FakeBucket._log_permissions_enabled_policy(
|
|
|
|
target_bucket=log_bucket_obj, target_prefix=""
|
|
|
|
)
|
|
|
|
|
|
|
|
|
2024-01-07 12:03:33 +00:00
|
|
|
@mock_aws
|
2023-09-08 13:12:26 +00:00
|
|
|
def test_bucket_policy_effect():
|
2023-09-19 19:46:20 +00:00
|
|
|
if not settings.TEST_DECORATOR_MODE:
|
2023-09-08 13:12:26 +00:00
|
|
|
raise SkipTest("Can't patch permission logic in ServerMode")
|
|
|
|
|
|
|
|
s3_client = boto3.client("s3", region_name=DEFAULT_REGION_NAME)
|
|
|
|
s3_backend = s3_backends[DEFAULT_ACCOUNT_ID]["global"]
|
|
|
|
|
|
|
|
log_bucket = "log_bucket"
|
|
|
|
s3_client.create_bucket(Bucket=log_bucket)
|
|
|
|
log_bucket_obj = s3_backend.get_bucket(log_bucket)
|
|
|
|
deny_effect_policy = {
|
|
|
|
"Version": "2012-10-17",
|
|
|
|
"Statement": [
|
|
|
|
{
|
|
|
|
"Sid": "S3ServerAccessLogsPolicy",
|
|
|
|
"Effect": "Deny",
|
|
|
|
"Principal": {"Service": "logging.s3.amazonaws.com"},
|
|
|
|
"Action": ["s3:PutObject"],
|
|
|
|
"Resource": f"arn:aws:s3:::{log_bucket}/*",
|
|
|
|
}
|
|
|
|
],
|
|
|
|
}
|
|
|
|
s3_client.put_bucket_policy(
|
|
|
|
Bucket=log_bucket, Policy=json.dumps(deny_effect_policy)
|
|
|
|
)
|
|
|
|
assert (
|
|
|
|
FakeBucket._log_permissions_enabled_policy(
|
|
|
|
target_bucket=log_bucket_obj, target_prefix=""
|
|
|
|
)
|
|
|
|
is False
|
|
|
|
)
|
|
|
|
|
|
|
|
s3_client.delete_bucket_policy(Bucket=log_bucket)
|
|
|
|
allow_effect_policy = {
|
|
|
|
"Version": "2012-10-17",
|
|
|
|
"Statement": [
|
|
|
|
{
|
|
|
|
"Sid": "S3ServerAccessLogsPolicy",
|
|
|
|
"Effect": "Allow",
|
|
|
|
"Principal": {"Service": "logging.s3.amazonaws.com"},
|
|
|
|
"Action": ["s3:PutObject"],
|
|
|
|
"Resource": f"arn:aws:s3:::{log_bucket}/*",
|
|
|
|
}
|
|
|
|
],
|
|
|
|
}
|
|
|
|
s3_client.put_bucket_policy(
|
|
|
|
Bucket=log_bucket, Policy=json.dumps(allow_effect_policy)
|
|
|
|
)
|
|
|
|
assert FakeBucket._log_permissions_enabled_policy(
|
|
|
|
target_bucket=log_bucket_obj, target_prefix=""
|
|
|
|
)
|
|
|
|
|
|
|
|
|
2024-01-07 12:03:33 +00:00
|
|
|
@mock_aws
|
2023-09-08 13:12:26 +00:00
|
|
|
def test_bucket_policy_action():
|
2023-09-19 19:46:20 +00:00
|
|
|
if not settings.TEST_DECORATOR_MODE:
|
2023-09-08 13:12:26 +00:00
|
|
|
raise SkipTest("Can't patch permission logic in ServerMode")
|
|
|
|
|
|
|
|
s3_client = boto3.client("s3", region_name=DEFAULT_REGION_NAME)
|
|
|
|
s3_backend = s3_backends[DEFAULT_ACCOUNT_ID]["global"]
|
|
|
|
|
|
|
|
log_bucket = "log_bucket"
|
|
|
|
s3_client.create_bucket(Bucket=log_bucket)
|
|
|
|
log_bucket_obj = s3_backend.get_bucket(log_bucket)
|
|
|
|
non_put_object_policy = {
|
|
|
|
"Version": "2012-10-17",
|
|
|
|
"Statement": [
|
|
|
|
{
|
|
|
|
"Sid": "S3ServerAccessLogsPolicy",
|
|
|
|
"Effect": "Allow",
|
|
|
|
"Principal": {"Service": "logging.s3.amazonaws.com"},
|
|
|
|
"Action": ["s3:GetObject"],
|
|
|
|
"Resource": f"arn:aws:s3:::{log_bucket}/*",
|
|
|
|
}
|
|
|
|
],
|
|
|
|
}
|
|
|
|
s3_client.put_bucket_policy(
|
|
|
|
Bucket=log_bucket, Policy=json.dumps(non_put_object_policy)
|
|
|
|
)
|
|
|
|
assert (
|
|
|
|
FakeBucket._log_permissions_enabled_policy(
|
|
|
|
target_bucket=log_bucket_obj, target_prefix=""
|
|
|
|
)
|
|
|
|
is False
|
|
|
|
)
|
|
|
|
|
|
|
|
s3_client.delete_bucket_policy(Bucket=log_bucket)
|
|
|
|
put_object_policy = {
|
|
|
|
"Version": "2012-10-17",
|
|
|
|
"Statement": [
|
|
|
|
{
|
|
|
|
"Sid": "S3ServerAccessLogsPolicy",
|
|
|
|
"Effect": "Allow",
|
|
|
|
"Principal": {"Service": "logging.s3.amazonaws.com"},
|
|
|
|
"Action": ["s3:PutObject"],
|
|
|
|
"Resource": f"arn:aws:s3:::{log_bucket}/*",
|
|
|
|
}
|
|
|
|
],
|
|
|
|
}
|
|
|
|
s3_client.put_bucket_policy(Bucket=log_bucket, Policy=json.dumps(put_object_policy))
|
|
|
|
assert FakeBucket._log_permissions_enabled_policy(
|
|
|
|
target_bucket=log_bucket_obj, target_prefix=""
|
|
|
|
)
|
|
|
|
|
|
|
|
|
2024-01-07 12:03:33 +00:00
|
|
|
@mock_aws
|
2023-09-08 13:12:26 +00:00
|
|
|
def test_bucket_policy_resource():
|
2023-09-19 19:46:20 +00:00
|
|
|
if not settings.TEST_DECORATOR_MODE:
|
2023-09-08 13:12:26 +00:00
|
|
|
raise SkipTest("Can't patch permission logic in ServerMode")
|
|
|
|
|
|
|
|
s3_client = boto3.client("s3", region_name=DEFAULT_REGION_NAME)
|
|
|
|
s3_backend = s3_backends[DEFAULT_ACCOUNT_ID]["global"]
|
|
|
|
|
|
|
|
log_bucket = "log_bucket"
|
|
|
|
s3_client.create_bucket(Bucket=log_bucket)
|
|
|
|
log_bucket_obj = s3_backend.get_bucket(log_bucket)
|
|
|
|
entire_bucket_policy = {
|
|
|
|
"Version": "2012-10-17",
|
|
|
|
"Statement": [
|
|
|
|
{
|
|
|
|
"Sid": "S3ServerAccessLogsPolicy",
|
|
|
|
"Effect": "Allow",
|
|
|
|
"Principal": {"Service": "logging.s3.amazonaws.com"},
|
|
|
|
"Action": ["s3:PutObject"],
|
|
|
|
"Resource": f"arn:aws:s3:::{log_bucket}/*",
|
|
|
|
}
|
|
|
|
],
|
|
|
|
}
|
|
|
|
s3_client.put_bucket_policy(
|
|
|
|
Bucket=log_bucket, Policy=json.dumps(entire_bucket_policy)
|
|
|
|
)
|
|
|
|
assert FakeBucket._log_permissions_enabled_policy(
|
|
|
|
target_bucket=log_bucket_obj, target_prefix=""
|
|
|
|
)
|
|
|
|
assert FakeBucket._log_permissions_enabled_policy(
|
|
|
|
target_bucket=log_bucket_obj, target_prefix="prefix"
|
|
|
|
)
|
|
|
|
|
|
|
|
s3_client.delete_bucket_policy(Bucket=log_bucket)
|
|
|
|
bucket_level_policy = {
|
|
|
|
"Version": "2012-10-17",
|
|
|
|
"Statement": [
|
|
|
|
{
|
|
|
|
"Sid": "S3ServerAccessLogsPolicy",
|
|
|
|
"Effect": "Allow",
|
|
|
|
"Principal": {"Service": "logging.s3.amazonaws.com"},
|
|
|
|
"Action": ["s3:PutObject"],
|
|
|
|
"Resource": f"arn:aws:s3:::{log_bucket}",
|
|
|
|
}
|
|
|
|
],
|
|
|
|
}
|
|
|
|
s3_client.put_bucket_policy(
|
|
|
|
Bucket=log_bucket, Policy=json.dumps(bucket_level_policy)
|
|
|
|
)
|
|
|
|
assert FakeBucket._log_permissions_enabled_policy(
|
|
|
|
target_bucket=log_bucket_obj, target_prefix=""
|
|
|
|
)
|
|
|
|
assert FakeBucket._log_permissions_enabled_policy(
|
|
|
|
target_bucket=log_bucket_obj, target_prefix="prefix"
|
|
|
|
)
|
|
|
|
|
|
|
|
s3_client.delete_bucket_policy(Bucket=log_bucket)
|
|
|
|
specfic_prefix_policy = {
|
|
|
|
"Version": "2012-10-17",
|
|
|
|
"Statement": [
|
|
|
|
{
|
|
|
|
"Sid": "S3ServerAccessLogsPolicy",
|
|
|
|
"Effect": "Allow",
|
|
|
|
"Principal": {"Service": "logging.s3.amazonaws.com"},
|
|
|
|
"Action": ["s3:PutObject"],
|
|
|
|
"Resource": f"arn:aws:s3:::{log_bucket}/prefix*",
|
|
|
|
}
|
|
|
|
],
|
|
|
|
}
|
|
|
|
s3_client.put_bucket_policy(
|
|
|
|
Bucket=log_bucket, Policy=json.dumps(specfic_prefix_policy)
|
|
|
|
)
|
|
|
|
assert (
|
|
|
|
FakeBucket._log_permissions_enabled_policy(
|
|
|
|
target_bucket=log_bucket_obj, target_prefix=""
|
|
|
|
)
|
|
|
|
is False
|
|
|
|
)
|
|
|
|
assert FakeBucket._log_permissions_enabled_policy(
|
|
|
|
target_bucket=log_bucket_obj, target_prefix="prefix"
|
|
|
|
)
|
2024-03-06 23:00:19 +00:00
|
|
|
|
|
|
|
|
|
|
|
@s3_aws_verified
|
|
|
|
@pytest.mark.aws_verified
|
|
|
|
def test_put_logging_w_bucket_policy_no_prefix(bucket_name=None):
|
|
|
|
s3_client = boto3.client("s3", region_name=DEFAULT_REGION_NAME)
|
|
|
|
|
|
|
|
log_bucket_name = f"{uuid4()}"
|
|
|
|
s3_client.create_bucket(Bucket=log_bucket_name)
|
|
|
|
bucket_policy = {
|
|
|
|
"Version": "2012-10-17",
|
|
|
|
"Statement": [
|
|
|
|
{
|
|
|
|
"Sid": "S3ServerAccessLogsPolicy",
|
|
|
|
"Effect": "Allow",
|
|
|
|
"Principal": {"Service": "logging.s3.amazonaws.com"},
|
|
|
|
"Action": ["s3:PutObject"],
|
|
|
|
"Resource": f"arn:aws:s3:::{log_bucket_name}/*",
|
|
|
|
}
|
|
|
|
],
|
|
|
|
}
|
|
|
|
s3_client.put_bucket_policy(
|
|
|
|
Bucket=log_bucket_name, Policy=json.dumps(bucket_policy)
|
|
|
|
)
|
|
|
|
s3_client.put_bucket_logging(
|
|
|
|
Bucket=bucket_name,
|
|
|
|
BucketLoggingStatus={
|
|
|
|
"LoggingEnabled": {"TargetBucket": log_bucket_name, "TargetPrefix": ""}
|
|
|
|
},
|
|
|
|
)
|
|
|
|
result = s3_client.get_bucket_logging(Bucket=bucket_name)
|
|
|
|
assert result["LoggingEnabled"]["TargetBucket"] == log_bucket_name
|
|
|
|
assert result["LoggingEnabled"]["TargetPrefix"] == ""
|
|
|
|
|
|
|
|
empty_bucket(s3_client, log_bucket_name)
|
|
|
|
s3_client.delete_bucket(Bucket=log_bucket_name)
|
|
|
|
|
|
|
|
|
|
|
|
@s3_aws_verified
|
|
|
|
@pytest.mark.aws_verified
|
|
|
|
def test_put_logging_w_bucket_policy_w_prefix(bucket_name=None):
|
|
|
|
s3_client = boto3.client("s3", region_name=DEFAULT_REGION_NAME)
|
|
|
|
|
|
|
|
log_bucket_name = f"{uuid4()}"
|
|
|
|
s3_client.create_bucket(Bucket=log_bucket_name)
|
|
|
|
prefix = "some-prefix"
|
|
|
|
bucket_policy = {
|
|
|
|
"Version": "2012-10-17",
|
|
|
|
"Statement": [
|
|
|
|
{
|
|
|
|
"Sid": "S3ServerAccessLogsPolicy",
|
|
|
|
"Effect": "Allow",
|
|
|
|
"Principal": {"Service": "logging.s3.amazonaws.com"},
|
|
|
|
"Action": ["s3:PutObject"],
|
|
|
|
"Resource": f"arn:aws:s3:::{log_bucket_name}/{prefix}*",
|
|
|
|
}
|
|
|
|
],
|
|
|
|
}
|
|
|
|
s3_client.put_bucket_policy(
|
|
|
|
Bucket=log_bucket_name, Policy=json.dumps(bucket_policy)
|
|
|
|
)
|
|
|
|
s3_client.put_bucket_logging(
|
|
|
|
Bucket=bucket_name,
|
|
|
|
BucketLoggingStatus={
|
|
|
|
"LoggingEnabled": {"TargetBucket": log_bucket_name, "TargetPrefix": prefix}
|
|
|
|
},
|
|
|
|
)
|
|
|
|
result = s3_client.get_bucket_logging(Bucket=bucket_name)
|
|
|
|
assert result["LoggingEnabled"]["TargetBucket"] == log_bucket_name
|
|
|
|
assert result["LoggingEnabled"]["TargetPrefix"] == prefix
|
|
|
|
|
|
|
|
empty_bucket(s3_client, log_bucket_name)
|
|
|
|
s3_client.delete_bucket(Bucket=log_bucket_name)
|