Fix response of DELETE Multiple Objects without bucket write permission

S3 returns 200 status code and following xml body, even if it does not have
bucket write permission.

<?xml version="1.0" encoding="UTF-8"?>
<DeleteResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
  <Error>
    <Key>sample1</Key>
    <Code>AccessDenied</Code>
    <Message>Access Denied</Message>
  </Error>
  <Error>
    <Key>sample2</Key>
    <Code>AccessDenied</Code>
    <Message>Access Denied</Message>
  </Error>
</DeleteResult>

Change-Id: I75d5543ee35d108c9b3d037c8dfb3a96fc65b634
This commit is contained in:
Naoto Nishizono
2014-12-22 17:42:51 +09:00
parent 7e44c62781
commit 650fa98679
2 changed files with 39 additions and 12 deletions

View File

@@ -17,7 +17,7 @@ from swift3.controllers.base import Controller, bucket_operation
from swift3.etree import Element, SubElement, fromstring, tostring, \
XMLSyntaxError, DocumentInvalid
from swift3.response import HTTPOk, S3NotImplemented, NoSuchKey, \
ErrorResponse, MalformedXML, UserKeyMustBeSpecified
ErrorResponse, MalformedXML, UserKeyMustBeSpecified, AccessDenied
from swift3.cfg import CONF
from swift3.utils import LOGGER
@@ -29,6 +29,19 @@ class MultiObjectDeleteController(Controller):
Handles Delete Multiple Objects, which is logged as a MULTI_OBJECT_DELETE
operation in the S3 server log.
"""
def _gen_error_body(self, error, elem, delete_list):
for key, version in delete_list:
if version is not None:
# TODO: delete the specific version of the object
raise S3NotImplemented()
error_elem = SubElement(elem, 'Error')
SubElement(error_elem, 'Key').text = key
SubElement(error_elem, 'Code').text = error.__class__.__name__
SubElement(error_elem, 'Message').text = error._msg
return tostring(elem)
@bucket_operation
def POST(self, req):
"""
@@ -45,9 +58,6 @@ class MultiObjectDeleteController(Controller):
yield key, version
# check bucket existence
req.get_response(self.app, 'HEAD')
try:
xml = req.xml(MAX_MULTI_DELETE_BODY_SIZE, check_md5=True)
elem = fromstring(xml, 'Delete')
@@ -71,6 +81,13 @@ class MultiObjectDeleteController(Controller):
elem = Element('DeleteResult')
# check bucket existence
try:
req.get_response(self.app, 'HEAD')
except AccessDenied as error:
body = self._gen_error_body(error, elem, delete_list)
return HTTPOk(body=body)
for key, version in delete_list:
if version is not None:
# TODO: delete the specific version of the object