import json
import xmltodict
from moto.core.responses import BaseResponse
from moto.core.utils import amzn_request_id
from moto.s3.exceptions import S3ClientError
from moto.s3.responses import S3_PUBLIC_ACCESS_BLOCK_CONFIGURATION
from .models import s3control_backend
class S3ControlResponse(BaseResponse):
@amzn_request_id
def public_access_block(
self, request, full_url, headers
): # pylint: disable=unused-argument
try:
if request.method == "GET":
return self.get_public_access_block(request)
elif request.method == "PUT":
return self.put_public_access_block(request)
elif request.method == "DELETE":
return self.delete_public_access_block(request)
except S3ClientError as err:
return err.code, {}, err.description
def get_public_access_block(self, request):
account_id = request.headers.get("x-amz-account-id")
public_block_config = s3control_backend.get_public_access_block(
account_id=account_id
)
template = self.response_template(S3_PUBLIC_ACCESS_BLOCK_CONFIGURATION)
return 200, {}, template.render(public_block_config=public_block_config)
def put_public_access_block(self, request):
account_id = request.headers.get("x-amz-account-id")
data = request.body if hasattr(request, "body") else request.data
pab_config = self._parse_pab_config(data)
s3control_backend.put_public_access_block(
account_id, pab_config["PublicAccessBlockConfiguration"]
)
return 201, {}, json.dumps({})
def delete_public_access_block(self, request):
account_id = request.headers.get("x-amz-account-id")
s3control_backend.delete_public_access_block(account_id=account_id)
return 204, {}, json.dumps({})
def _parse_pab_config(self, body):
parsed_xml = xmltodict.parse(body)
parsed_xml["PublicAccessBlockConfiguration"].pop("@xmlns", None)
return parsed_xml
def access_point(self, request, full_url, headers):
self.setup_class(request, full_url, headers)
if request.method == "PUT":
return self.create_access_point(full_url)
if request.method == "GET":
return self.get_access_point(full_url)
if request.method == "DELETE":
return self.delete_access_point(full_url)
def access_point_policy(self, request, full_url, headers):
self.setup_class(request, full_url, headers)
if request.method == "PUT":
return self.create_access_point_policy(full_url)
if request.method == "GET":
return self.get_access_point_policy(full_url)
if request.method == "DELETE":
return self.delete_access_point_policy(full_url)
def access_point_policy_status(self, request, full_url, headers):
self.setup_class(request, full_url, headers)
if request.method == "PUT":
return self.create_access_point(full_url)
if request.method == "GET":
return self.get_access_point_policy_status(full_url)
def create_access_point(self, full_url):
account_id, name = self._get_accountid_and_name_from_accesspoint(full_url)
params = xmltodict.parse(self.body)["CreateAccessPointRequest"]
bucket = params["Bucket"]
vpc_configuration = params.get("VpcConfiguration")
public_access_block_configuration = params.get("PublicAccessBlockConfiguration")
access_point = s3control_backend.create_access_point(
account_id=account_id,
name=name,
bucket=bucket,
vpc_configuration=vpc_configuration,
public_access_block_configuration=public_access_block_configuration,
)
template = self.response_template(CREATE_ACCESS_POINT_TEMPLATE)
return 200, {}, template.render(access_point=access_point)
def get_access_point(self, full_url):
account_id, name = self._get_accountid_and_name_from_accesspoint(full_url)
access_point = s3control_backend.get_access_point(
account_id=account_id, name=name
)
template = self.response_template(GET_ACCESS_POINT_TEMPLATE)
return 200, {}, template.render(access_point=access_point)
def delete_access_point(self, full_url):
account_id, name = self._get_accountid_and_name_from_accesspoint(full_url)
s3control_backend.delete_access_point(account_id=account_id, name=name)
return 204, {}, ""
def create_access_point_policy(self, full_url):
account_id, name = self._get_accountid_and_name_from_policy(full_url)
params = xmltodict.parse(self.body)
policy = params["PutAccessPointPolicyRequest"]["Policy"]
s3control_backend.create_access_point_policy(account_id, name, policy)
return 200, {}, ""
def get_access_point_policy(self, full_url):
account_id, name = self._get_accountid_and_name_from_policy(full_url)
policy = s3control_backend.get_access_point_policy(account_id, name)
template = self.response_template(GET_ACCESS_POINT_POLICY_TEMPLATE)
return 200, {}, template.render(policy=policy)
def delete_access_point_policy(self, full_url):
account_id, name = self._get_accountid_and_name_from_policy(full_url)
s3control_backend.delete_access_point_policy(account_id=account_id, name=name)
return 204, {}, ""
def get_access_point_policy_status(self, full_url):
account_id, name = self._get_accountid_and_name_from_policy(full_url)
s3control_backend.get_access_point_policy_status(account_id, name)
template = self.response_template(GET_ACCESS_POINT_POLICY_STATUS_TEMPLATE)
return 200, {}, template.render()
def _get_accountid_and_name_from_accesspoint(self, full_url):
url = full_url
if full_url.startswith("http"):
url = full_url.split("://")[1]
account_id = url.split(".")[0]
name = url.split("v20180820/accesspoint/")[-1]
return account_id, name
def _get_accountid_and_name_from_policy(self, full_url):
url = full_url
if full_url.startswith("http"):
url = full_url.split("://")[1]
account_id = url.split(".")[0]
name = self.path.split("/")[-2]
return account_id, name
S3ControlResponseInstance = S3ControlResponse()
CREATE_ACCESS_POINT_TEMPLATE = """
1549581b-12b7-11e3-895e-1334aEXAMPLE
{{ access_point.name }}
{{ access_point.arn }}
"""
GET_ACCESS_POINT_TEMPLATE = """
1549581b-12b7-11e3-895e-1334aEXAMPLE
{{ access_point.name }}
{{ access_point.bucket }}
{{ access_point.network_origin }}
{% if access_point.vpc_id %}
{{ access_point.vpc_id }}
{% endif %}
{{ access_point.pubc["BlockPublicAcls"] }}
{{ access_point.pubc["IgnorePublicAcls"] }}
{{ access_point.pubc["BlockPublicPolicy"] }}
{{ access_point.pubc["RestrictPublicBuckets"] }}
{{ access_point.created }}
{{ access_point.alias }}
{{ access_point.arn }}
ipv4
s3-accesspoint.us-east-1.amazonaws.com
fips
s3-accesspoint-fips.us-east-1.amazonaws.com
fips_dualstack
s3-accesspoint-fips.dualstack.us-east-1.amazonaws.com
dualstack
s3-accesspoint.dualstack.us-east-1.amazonaws.com
"""
GET_ACCESS_POINT_POLICY_TEMPLATE = """
1549581b-12b7-11e3-895e-1334aEXAMPLE
{{ policy }}
"""
GET_ACCESS_POINT_POLICY_STATUS_TEMPLATE = """
1549581b-12b7-11e3-895e-1334aEXAMPLE
true
"""