def set_cors(self, rules): from moto.s3.exceptions import InvalidRequest, MalformedXML self.cors = [] if len(rules) > 100: raise MalformedXML() for rule in rules: assert isinstance(rule["AllowedMethod"], list) or isinstance( rule["AllowedMethod"], six.string_types) assert isinstance(rule["AllowedOrigin"], list) or isinstance( rule["AllowedOrigin"], six.string_types) assert isinstance(rule.get( "AllowedHeader", []), list) or isinstance( rule.get("AllowedHeader", ""), six.string_types) assert isinstance(rule.get( "ExposedHeader", []), list) or isinstance( rule.get("ExposedHeader", ""), six.string_types) assert isinstance(rule.get("MaxAgeSeconds", "0"), six.string_types) if isinstance(rule["AllowedMethod"], six.string_types): methods = [rule["AllowedMethod"]] else: methods = rule["AllowedMethod"] for method in methods: if method not in ["GET", "PUT", "HEAD", "POST", "DELETE"]: raise InvalidRequest(method) self.cors.append( CorsRule(rule["AllowedMethod"], rule["AllowedOrigin"], rule.get("AllowedHeader"), rule.get("ExposedHeader"), rule.get("MaxAgeSecond")))
def _bucket_response_put(self, request, body, region_name, bucket_name, querystring, headers): if not request.headers.get('Content-Length'): return 411, {}, "Content-Length required" if 'versioning' in querystring: ver = re.search('<Status>([A-Za-z]+)</Status>', body) if ver: self.backend.set_bucket_versioning(bucket_name, ver.group(1)) template = self.response_template(S3_BUCKET_VERSIONING) return template.render(bucket_versioning_status=ver.group(1)) else: return 404, {}, "" elif 'lifecycle' in querystring: rules = xmltodict.parse(body)['LifecycleConfiguration']['Rule'] if not isinstance(rules, list): # If there is only one rule, xmldict returns just the item rules = [rules] self.backend.set_bucket_lifecycle(bucket_name, rules) return "" elif 'policy' in querystring: self.backend.set_bucket_policy(bucket_name, body) return 'True' elif 'acl' in querystring: acl = self._acl_from_headers(request.headers) # TODO: Support the XML-based ACL format self.backend.set_bucket_acl(bucket_name, acl) return "" elif "tagging" in querystring: tagging = self._bucket_tagging_from_xml(body) self.backend.put_bucket_tagging(bucket_name, tagging) return "" elif 'website' in querystring: self.backend.set_bucket_website_configuration(bucket_name, body) return "" elif "cors" in querystring: from moto.s3.exceptions import MalformedXML try: self.backend.put_bucket_cors(bucket_name, self._cors_from_xml(body)) return "" except KeyError: raise MalformedXML() else: if body: try: region_name = xmltodict.parse(body)['CreateBucketConfiguration']['LocationConstraint'] except KeyError: pass try: new_bucket = self.backend.create_bucket( bucket_name, region_name) except BucketAlreadyExists: if region_name == DEFAULT_REGION_NAME: # us-east-1 has different behavior new_bucket = self.backend.get_bucket(bucket_name) else: raise template = self.response_template(S3_BUCKET_CREATE_RESPONSE) return 200, {}, template.render(bucket=new_bucket)
def set_cors(self, rules): from moto.s3.exceptions import InvalidRequest, MalformedXML self.cors = [] if len(rules) > 100: raise MalformedXML() # Python 2 and 3 have different string types for handling unicodes. Python 2 wants `basestring`, # whereas Python 3 is OK with str. This causes issues with the XML parser, which returns # unicode strings in Python 2. So, need to do this to make it work in both Python 2 and 3: import sys if sys.version_info >= (3, 0): str_type = str else: str_type = basestring # noqa for rule in rules: assert isinstance(rule["AllowedMethod"], list) or isinstance( rule["AllowedMethod"], str_type) assert isinstance(rule["AllowedOrigin"], list) or isinstance( rule["AllowedOrigin"], str_type) assert isinstance(rule.get("AllowedHeader", []), list) or isinstance( rule.get("AllowedHeader", ""), str_type) assert isinstance(rule.get("ExposedHeader", []), list) or isinstance( rule.get("ExposedHeader", ""), str_type) assert isinstance(rule.get("MaxAgeSeconds", "0"), str_type) if isinstance(rule["AllowedMethod"], str_type): methods = [rule["AllowedMethod"]] else: methods = rule["AllowedMethod"] for method in methods: if method not in ["GET", "PUT", "HEAD", "POST", "DELETE"]: raise InvalidRequest(method) self.cors.append( CorsRule(rule["AllowedMethod"], rule["AllowedOrigin"], rule.get("AllowedHeader"), rule.get("ExposedHeader"), rule.get("MaxAgeSecond")))
def set_lifecycle(self, rules): self.rules = [] for rule in rules: # Extract and validate actions from Lifecycle rule expiration = rule.get('Expiration') transition = rule.get('Transition') nve_noncurrent_days = None if rule.get('NoncurrentVersionExpiration') is not None: if rule["NoncurrentVersionExpiration"].get( 'NoncurrentDays') is None: raise MalformedXML() nve_noncurrent_days = rule["NoncurrentVersionExpiration"][ "NoncurrentDays"] nvt_noncurrent_days = None nvt_storage_class = None if rule.get('NoncurrentVersionTransition') is not None: if rule["NoncurrentVersionTransition"].get( 'NoncurrentDays') is None: raise MalformedXML() if rule["NoncurrentVersionTransition"].get( 'StorageClass') is None: raise MalformedXML() nvt_noncurrent_days = rule["NoncurrentVersionTransition"][ "NoncurrentDays"] nvt_storage_class = rule["NoncurrentVersionTransition"][ "StorageClass"] aimu_days = None if rule.get('AbortIncompleteMultipartUpload') is not None: if rule["AbortIncompleteMultipartUpload"].get( 'DaysAfterInitiation') is None: raise MalformedXML() aimu_days = rule["AbortIncompleteMultipartUpload"][ "DaysAfterInitiation"] eodm = None if expiration and expiration.get( "ExpiredObjectDeleteMarker") is not None: # This cannot be set if Date or Days is set: if expiration.get("Days") or expiration.get("Date"): raise MalformedXML() eodm = expiration["ExpiredObjectDeleteMarker"] # Pull out the filter: lc_filter = None if rule.get("Filter"): # Can't have both `Filter` and `Prefix` (need to check for the presence of the key): try: if rule["Prefix"] or not rule["Prefix"]: raise MalformedXML() except KeyError: pass and_filter = None if rule["Filter"].get("And"): and_tags = [] if rule["Filter"]["And"].get("Tag"): if not isinstance(rule["Filter"]["And"]["Tag"], list): rule["Filter"]["And"]["Tag"] = [ rule["Filter"]["And"]["Tag"] ] for t in rule["Filter"]["And"]["Tag"]: and_tags.append( FakeTag(t["Key"], t.get("Value", ''))) and_filter = LifecycleAndFilter( prefix=rule["Filter"]["And"]["Prefix"], tags=and_tags) filter_tag = None if rule["Filter"].get("Tag"): filter_tag = FakeTag( rule["Filter"]["Tag"]["Key"], rule["Filter"]["Tag"].get("Value", '')) lc_filter = LifecycleFilter(prefix=rule["Filter"]["Prefix"], tag=filter_tag, and_filter=and_filter) self.rules.append( LifecycleRule( id=rule.get('ID'), prefix=rule.get('Prefix'), lc_filter=lc_filter, status=rule['Status'], expiration_days=expiration.get('Days') if expiration else None, expiration_date=expiration.get('Date') if expiration else None, transition_days=transition.get('Days') if transition else None, transition_date=transition.get('Date') if transition else None, storage_class=transition.get('StorageClass') if transition else None, expired_object_delete_marker=eodm, nve_noncurrent_days=nve_noncurrent_days, nvt_noncurrent_days=nvt_noncurrent_days, nvt_storage_class=nvt_storage_class, aimu_days=aimu_days, ))
def set_lifecycle(self, rules): self.rules = [] for rule in rules: expiration = rule.get('Expiration') transition = rule.get('Transition') eodm = None if expiration and expiration.get( "ExpiredObjectDeleteMarker") is not None: # This cannot be set if Date or Days is set: if expiration.get("Days") or expiration.get("Date"): raise MalformedXML() eodm = expiration["ExpiredObjectDeleteMarker"] # Pull out the filter: lc_filter = None if rule.get("Filter"): # Can't have both `Filter` and `Prefix` (need to check for the presence of the key): try: if rule["Prefix"] or not rule["Prefix"]: raise MalformedXML() except KeyError: pass and_filter = None if rule["Filter"].get("And"): and_tags = [] if rule["Filter"]["And"].get("Tag"): if not isinstance(rule["Filter"]["And"]["Tag"], list): rule["Filter"]["And"]["Tag"] = [ rule["Filter"]["And"]["Tag"] ] for t in rule["Filter"]["And"]["Tag"]: and_tags.append( FakeTag(t["Key"], t.get("Value", ''))) and_filter = LifecycleAndFilter( prefix=rule["Filter"]["And"]["Prefix"], tags=and_tags) filter_tag = None if rule["Filter"].get("Tag"): filter_tag = FakeTag( rule["Filter"]["Tag"]["Key"], rule["Filter"]["Tag"].get("Value", '')) lc_filter = LifecycleFilter(prefix=rule["Filter"]["Prefix"], tag=filter_tag, and_filter=and_filter) self.rules.append( LifecycleRule( id=rule.get('ID'), prefix=rule.get('Prefix'), lc_filter=lc_filter, status=rule['Status'], expiration_days=expiration.get('Days') if expiration else None, expiration_date=expiration.get('Date') if expiration else None, expired_object_delete_marker=eodm, transition_days=transition.get('Days') if transition else None, transition_date=transition.get('Date') if transition else None, storage_class=transition['StorageClass'] if transition else None, ))