Fix the response of GET Service to get only buckets owner are request user
Add check owner process of each buckets in the bucket list for GET service, when s3_acl and check_bucket_owner are true. Current Swift3 returns all bucket, but it should return only buckets owner are request user. Change-Id: I77886e59d02aaa86659a8e15da35b23e2cbf402b
This commit is contained in:
parent
17452b88ec
commit
ff12a24b2a
|
@ -88,6 +88,14 @@ use = egg:swift3#swift3
|
|||
# middleware.(specification of S3: 10000)
|
||||
# max_upload_part_num = 1000
|
||||
#
|
||||
# Enable returning only buckets which owner are the user who requested
|
||||
# GET Service operation. (default: false)
|
||||
# If you want to enable the above feature, set this and s3_acl to true.
|
||||
# That might cause significant performance degradation. So, only if your
|
||||
# service absolutely need this feature, set this setting to true.
|
||||
# If you set this to false, Swift3 returns all buckets.
|
||||
# check_bucket_owner = false
|
||||
#
|
||||
|
||||
[filter:catch_errors]
|
||||
use = egg:swift#catch_errors
|
||||
|
|
|
@ -60,4 +60,5 @@ CONF = Config({
|
|||
'storage_domain': '',
|
||||
'auth_pipeline_check': True,
|
||||
'max_upload_part_num': 1000,
|
||||
'check_bucket_owner': False,
|
||||
})
|
||||
|
|
|
@ -17,8 +17,9 @@ from simplejson import loads
|
|||
|
||||
from swift3.controllers.base import Controller
|
||||
from swift3.etree import Element, SubElement, tostring
|
||||
from swift3.response import HTTPOk
|
||||
from swift3.response import HTTPOk, AccessDenied, NoSuchBucket
|
||||
from swift3.utils import validate_bucket_name
|
||||
from swift3.cfg import CONF
|
||||
|
||||
|
||||
class ServiceController(Controller):
|
||||
|
@ -46,6 +47,14 @@ class ServiceController(Controller):
|
|||
|
||||
buckets = SubElement(elem, 'Buckets')
|
||||
for c in containers:
|
||||
if CONF.s3_acl and CONF.check_bucket_owner:
|
||||
try:
|
||||
req.get_response(self.app, 'HEAD', c['name'])
|
||||
except AccessDenied:
|
||||
continue
|
||||
except NoSuchBucket:
|
||||
continue
|
||||
|
||||
bucket = SubElement(buckets, 'Bucket')
|
||||
SubElement(bucket, 'Name').text = c['name']
|
||||
SubElement(bucket, 'CreationDate').text = \
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
|
||||
import unittest
|
||||
import simplejson
|
||||
from mock import patch
|
||||
|
||||
from swift.common import swob
|
||||
from swift.common.swob import Request
|
||||
|
@ -22,6 +23,7 @@ from swift.common.swob import Request
|
|||
from swift3.test.unit.test_s3_acl import s3acl
|
||||
from swift3.test.unit import Swift3TestCase
|
||||
from swift3.etree import fromstring
|
||||
from swift3.subresource import ACL, Owner, encode_acl
|
||||
|
||||
|
||||
class TestSwift3Service(Swift3TestCase):
|
||||
|
@ -136,6 +138,109 @@ class TestSwift3Service(Swift3TestCase):
|
|||
for i in expected:
|
||||
self.assertTrue(i[0] in names)
|
||||
|
||||
@patch('swift3.cfg.CONF.check_bucket_owner', True)
|
||||
def _test_service_GET_for_check_bucket_owner(self, buckets):
|
||||
json_pattern = ['"name":%s', '"count":%s', '"bytes":%s']
|
||||
json_pattern = '{' + ','.join(json_pattern) + '}'
|
||||
json_out = []
|
||||
|
||||
for b in buckets:
|
||||
name = simplejson.dumps(b[0])
|
||||
json_out.append(json_pattern %
|
||||
(name, b[1], b[2]))
|
||||
|
||||
bucket_list = '[' + ','.join(json_out) + ']'
|
||||
self.swift.register('GET', '/v1/AUTH_test', swob.HTTPOk, {},
|
||||
bucket_list)
|
||||
|
||||
req = Request.blank('/',
|
||||
environ={'REQUEST_METHOD': 'GET'},
|
||||
headers={'Authorization': 'AWS test:tester:hmac'})
|
||||
return self.call_swift3(req)
|
||||
|
||||
@s3acl(s3acl_only=True)
|
||||
def test_service_GET_without_bucket(self):
|
||||
bucket_list = []
|
||||
for var in range(0, 10):
|
||||
bucket = 'bucket%s' % var
|
||||
self.swift.register('HEAD', '/v1/AUTH_test/%s' % bucket,
|
||||
swob.HTTPNotFound, {}, None)
|
||||
bucket_list.append((bucket, var, 300 + var))
|
||||
|
||||
status, headers, body = \
|
||||
self._test_service_GET_for_check_bucket_owner(bucket_list)
|
||||
self.assertEquals(status.split()[0], '200')
|
||||
|
||||
elem = fromstring(body, 'ListAllMyBucketsResult')
|
||||
|
||||
resp_buckets = elem.find('./Buckets')
|
||||
buckets = resp_buckets.iterchildren('Bucket')
|
||||
self.assertEquals(len(list(buckets)), 0)
|
||||
|
||||
@s3acl(s3acl_only=True)
|
||||
def test_service_GET_without_owner_bucket(self):
|
||||
bucket_list = []
|
||||
for var in range(0, 10):
|
||||
user_id = 'test:other'
|
||||
bucket = 'bucket%s' % var
|
||||
owner = Owner(user_id, user_id)
|
||||
headers = encode_acl('container', ACL(owner, []))
|
||||
self.swift.register('HEAD', '/v1/AUTH_test/%s' % bucket,
|
||||
swob.HTTPNoContent, headers, None)
|
||||
bucket_list.append((bucket, var, 300 + var))
|
||||
|
||||
status, headers, body = \
|
||||
self._test_service_GET_for_check_bucket_owner(bucket_list)
|
||||
self.assertEquals(status.split()[0], '200')
|
||||
|
||||
elem = fromstring(body, 'ListAllMyBucketsResult')
|
||||
|
||||
resp_buckets = elem.find('./Buckets')
|
||||
buckets = resp_buckets.iterchildren('Bucket')
|
||||
self.assertEquals(len(list(buckets)), 0)
|
||||
|
||||
@s3acl(s3acl_only=True)
|
||||
def test_service_GET_bucekt_list(self):
|
||||
bucket_list = []
|
||||
for var in range(0, 10):
|
||||
if var % 3 == 0:
|
||||
user_id = 'test:tester'
|
||||
else:
|
||||
user_id = 'test:other'
|
||||
bucket = 'bucket%s' % var
|
||||
owner = Owner(user_id, user_id)
|
||||
headers = encode_acl('container', ACL(owner, []))
|
||||
# set register to get owner of buckets
|
||||
if var % 3 == 2:
|
||||
self.swift.register('HEAD', '/v1/AUTH_test/%s' % bucket,
|
||||
swob.HTTPNotFound, {}, None)
|
||||
else:
|
||||
self.swift.register('HEAD', '/v1/AUTH_test/%s' % bucket,
|
||||
swob.HTTPNoContent, headers, None)
|
||||
bucket_list.append((bucket, var, 300 + var))
|
||||
|
||||
status, headers, body = \
|
||||
self._test_service_GET_for_check_bucket_owner(bucket_list)
|
||||
self.assertEquals(status.split()[0], '200')
|
||||
|
||||
elem = fromstring(body, 'ListAllMyBucketsResult')
|
||||
resp_buckets = elem.find('./Buckets')
|
||||
buckets = resp_buckets.iterchildren('Bucket')
|
||||
listing = list(list(buckets)[0])
|
||||
self.assertEquals(len(listing), 2)
|
||||
|
||||
names = []
|
||||
for b in resp_buckets.iterchildren('Bucket'):
|
||||
names.append(b.find('./Name').text)
|
||||
|
||||
# Check whether getting bucket only locate in multiples of 3 in
|
||||
# bucket_list which mean requested user is owner.
|
||||
expected_buckets = [b for i, b in enumerate(bucket_list)
|
||||
if i % 3 == 0]
|
||||
self.assertEquals(len(names), len(expected_buckets))
|
||||
for i in expected_buckets:
|
||||
self.assertTrue(i[0] in names)
|
||||
self.assertEquals(len(self.swift.calls_with_headers), 11)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
|
Loading…
Reference in New Issue