Merge "s3api: Fix handling of non-ascii access keys"
This commit is contained in:
commit
0e5aeb5045
@ -1142,7 +1142,7 @@ class S3Request(swob.Request):
|
||||
Create a Swift request based on this request's environment.
|
||||
"""
|
||||
if self.account is None:
|
||||
account = self.access_key
|
||||
account = swob.str_to_wsgi(self.access_key)
|
||||
else:
|
||||
account = self.account
|
||||
|
||||
|
@ -65,7 +65,7 @@ import six
|
||||
from six.moves import urllib
|
||||
|
||||
from swift.common.swob import Request, HTTPBadRequest, HTTPUnauthorized, \
|
||||
HTTPException
|
||||
HTTPException, str_to_wsgi
|
||||
from swift.common.utils import config_true_value, split_path, get_logger, \
|
||||
cache_from_env, append_underscore
|
||||
from swift.common.wsgi import ConfigFileError
|
||||
@ -404,7 +404,7 @@ class S3Token(object):
|
||||
self._logger.debug('Connecting with tenant: %s', tenant_to_connect)
|
||||
new_tenant_name = '%s%s' % (self._reseller_prefix, tenant_to_connect)
|
||||
environ['PATH_INFO'] = environ['PATH_INFO'].replace(
|
||||
account, new_tenant_name, 1)
|
||||
str_to_wsgi(account), str_to_wsgi(new_tenant_name), 1)
|
||||
return self._app(environ, start_response)
|
||||
|
||||
|
||||
|
@ -184,9 +184,11 @@ import base64
|
||||
from eventlet import Timeout
|
||||
import six
|
||||
from swift.common.memcached import MemcacheConnectionError
|
||||
from swift.common.swob import Response, Request, wsgi_to_str
|
||||
from swift.common.swob import HTTPBadRequest, HTTPForbidden, HTTPNotFound, \
|
||||
HTTPUnauthorized, HTTPMethodNotAllowed, HTTPServiceUnavailable
|
||||
from swift.common.swob import (
|
||||
Response, Request, wsgi_to_str, str_to_wsgi, wsgi_unquote,
|
||||
HTTPBadRequest, HTTPForbidden, HTTPNotFound,
|
||||
HTTPUnauthorized, HTTPMethodNotAllowed, HTTPServiceUnavailable,
|
||||
)
|
||||
|
||||
from swift.common.request_helpers import get_sys_meta_prefix
|
||||
from swift.common.middleware.acl import (
|
||||
@ -469,7 +471,7 @@ class TempAuth(object):
|
||||
if not s3_auth_details['check_signature'](user['key']):
|
||||
return None
|
||||
env['PATH_INFO'] = env['PATH_INFO'].replace(
|
||||
account_user, account_id, 1)
|
||||
str_to_wsgi(account_user), wsgi_unquote(account_id), 1)
|
||||
groups = self._get_user_groups(account, account_user, account_id)
|
||||
|
||||
return groups
|
||||
|
@ -46,10 +46,12 @@ class FakeAuthApp(object):
|
||||
E.g. '/v1/test:tester/bucket/object' will become
|
||||
'/v1/AUTH_test/bucket/object'. This method emulates the behavior.
|
||||
"""
|
||||
tenant_user = env['s3api.auth_details']['access_key']
|
||||
tenant_user = swob.str_to_wsgi(env['s3api.auth_details']['access_key'])
|
||||
tenant, user = tenant_user.rsplit(':', 1)
|
||||
|
||||
path = env['PATH_INFO']
|
||||
# Make sure it's valid WSGI
|
||||
swob.wsgi_to_str(path)
|
||||
env['PATH_INFO'] = path.replace(tenant_user, 'AUTH_' + tenant)
|
||||
|
||||
@staticmethod
|
||||
|
@ -199,7 +199,8 @@ class S3TokenMiddlewareTestGood(S3TokenMiddlewareTestBase):
|
||||
self.middleware(req.environ, self.start_fake_response)
|
||||
self.assertEqual(self.response_status, 200)
|
||||
|
||||
def _assert_authorized(self, req, account_path='/v1/AUTH_TENANT_ID/'):
|
||||
def _assert_authorized(self, req, account_path='/v1/AUTH_TENANT_ID/',
|
||||
access_key='access'):
|
||||
self.assertTrue(
|
||||
req.path.startswith(account_path),
|
||||
'%r does not start with %r' % (req.path, account_path))
|
||||
@ -224,7 +225,7 @@ class S3TokenMiddlewareTestGood(S3TokenMiddlewareTestBase):
|
||||
self.assertEqual(1, self.requests_mock.call_count)
|
||||
request_call = self.requests_mock.request_history[0]
|
||||
self.assertEqual(json.loads(request_call.body), {'credentials': {
|
||||
'access': 'access',
|
||||
'access': access_key,
|
||||
'signature': 'signature',
|
||||
'token': base64.urlsafe_b64encode(b'token').decode('ascii')}})
|
||||
|
||||
@ -501,6 +502,18 @@ class S3TokenMiddlewareTestGood(S3TokenMiddlewareTestBase):
|
||||
self._assert_authorized(req, account_path='/v1/')
|
||||
self.assertEqual(req.environ['PATH_INFO'], '/v1/AUTH_TENANT_ID/c/o')
|
||||
|
||||
def test_authorize_with_unicode_access_key(self):
|
||||
req = Request.blank('/v1/acc\xc3\xa9sskey/c/o')
|
||||
req.environ['s3api.auth_details'] = {
|
||||
'access_key': u'acc\u00e9ss',
|
||||
'signature': u'signature',
|
||||
'string_to_sign': u'token',
|
||||
}
|
||||
req.get_response(self.middleware)
|
||||
self._assert_authorized(req, account_path='/v1/',
|
||||
access_key=u'acc\u00e9ss')
|
||||
self.assertEqual(req.environ['PATH_INFO'], '/v1/AUTH_TENANT_ID/c/o')
|
||||
|
||||
def test_authorize_with_access_key_and_unquote_chars(self):
|
||||
req = Request.blank('/v1/access%key=/c/o')
|
||||
req.environ['s3api.auth_details'] = {
|
||||
|
@ -308,6 +308,29 @@ class TestAuth(unittest.TestCase):
|
||||
self.assertEqual(req.environ['swift.authorize'],
|
||||
local_auth.authorize)
|
||||
|
||||
def test_auth_with_s3api_unicode_authorization_good(self):
|
||||
local_app = FakeApp()
|
||||
conf = {u'user_t\u00e9st_t\u00e9ster': u'p\u00e1ss .admin'}
|
||||
access_key = u't\u00e9st:t\u00e9ster'
|
||||
if six.PY2:
|
||||
conf = {k.encode('utf8'): v.encode('utf8')
|
||||
for k, v in conf.items()}
|
||||
access_key = access_key.encode('utf8')
|
||||
local_auth = auth.filter_factory(conf)(local_app)
|
||||
req = self._make_request('/v1/t\xc3\xa9st:t\xc3\xa9ster', environ={
|
||||
's3api.auth_details': {
|
||||
'access_key': access_key,
|
||||
'signature': b64encode('sig'),
|
||||
'string_to_sign': 't',
|
||||
'check_signature': lambda secret: True}})
|
||||
resp = req.get_response(local_auth)
|
||||
|
||||
self.assertEqual(resp.status_int, 404)
|
||||
self.assertEqual(local_app.calls, 1)
|
||||
self.assertEqual(req.environ['PATH_INFO'], '/v1/AUTH_t\xc3\xa9st')
|
||||
self.assertEqual(req.environ['swift.authorize'],
|
||||
local_auth.authorize)
|
||||
|
||||
def test_auth_with_swift3_authorization_invalid(self):
|
||||
local_app = FakeApp()
|
||||
local_auth = auth.filter_factory(
|
||||
|
Loading…
Reference in New Issue
Block a user