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 """