tempauth: Send back url-encoded account names

Taking user_tést_tester and sending back a link to http://saio:8080/v1/AUTH_tést
may work, but it would be better as http://saio:8080/v1/AUTH_t%C3%A9st

This is particularly important if you define something like user_test%ff_tester.

Change-Id: I19d21af94c21fccb4fb835acae231dec424790bb
Related-Bug: 1774238
This commit is contained in:
Tim Burke 2018-05-30 15:57:12 -07:00
parent 9ef2a82816
commit 7cec5a8fdb
2 changed files with 19 additions and 4 deletions

View File

@ -190,7 +190,7 @@ from swift.common.middleware.acl import (
clean_acl, parse_acl, referrer_allowed, acls_from_account_info) clean_acl, parse_acl, referrer_allowed, acls_from_account_info)
from swift.common.utils import cache_from_env, get_logger, \ from swift.common.utils import cache_from_env, get_logger, \
split_path, config_true_value, register_swift_info split_path, config_true_value, register_swift_info
from swift.common.utils import config_read_reseller_options from swift.common.utils import config_read_reseller_options, quote
from swift.proxy.controllers.base import get_account_info from swift.proxy.controllers.base import get_account_info
@ -229,7 +229,7 @@ class TempAuth(object):
self.storage_url_scheme = conf.get('storage_url_scheme', 'default') self.storage_url_scheme = conf.get('storage_url_scheme', 'default')
self.users = {} self.users = {}
for conf_key in conf: for conf_key in conf:
if conf_key.startswith('user_') or conf_key.startswith('user64_'): if conf_key.startswith(('user_', 'user64_')):
account, username = conf_key.split('_', 1)[1].split('_') account, username = conf_key.split('_', 1)[1].split('_')
if conf_key.startswith('user64_'): if conf_key.startswith('user64_'):
# Because trailing equal signs would screw up config file # Because trailing equal signs would screw up config file
@ -245,7 +245,8 @@ class TempAuth(object):
if values and ('://' in values[-1] or '$HOST' in values[-1]): if values and ('://' in values[-1] or '$HOST' in values[-1]):
url = values.pop() url = values.pop()
else: else:
url = '$HOST/v1/%s%s' % (self.reseller_prefix, account) url = '$HOST/v1/%s%s' % (
self.reseller_prefix, quote(account))
self.users[account + ':' + username] = { self.users[account + ':' + username] = {
'key': key, 'url': url, 'groups': values} 'key': key, 'url': url, 'groups': values}

View File

@ -20,6 +20,7 @@ from contextlib import contextmanager
from base64 import b64encode from base64 import b64encode
from time import time from time import time
from six.moves.urllib.parse import quote, urlparse
from swift.common.middleware import tempauth as auth from swift.common.middleware import tempauth as auth
from swift.common.middleware.acl import format_acl from swift.common.middleware.acl import format_acl
from swift.common.swob import Request, Response from swift.common.swob import Request, Response
@ -917,10 +918,11 @@ class TestAuth(unittest.TestCase):
'Swift realm="BLAH_account"') 'Swift realm="BLAH_account"')
def test_successful_token_unicode_user(self): def test_successful_token_unicode_user(self):
app = FakeApp(iter(NO_CONTENT_RESP)) app = FakeApp(iter(NO_CONTENT_RESP * 2))
ath = auth.filter_factory( ath = auth.filter_factory(
{u'user_t\u00e9st_t\u00e9ster'.encode('utf8'): {u'user_t\u00e9st_t\u00e9ster'.encode('utf8'):
u'p\u00e1ss .admin'.encode('utf8')})(app) u'p\u00e1ss .admin'.encode('utf8')})(app)
quoted_acct = quote(u'/v1/AUTH_t\u00e9st'.encode('utf8'))
memcache = FakeMemcache() memcache = FakeMemcache()
req = self._make_request( req = self._make_request(
@ -931,6 +933,8 @@ class TestAuth(unittest.TestCase):
resp = req.get_response(ath) resp = req.get_response(ath)
self.assertEqual(resp.status_int, 200) self.assertEqual(resp.status_int, 200)
auth_token = resp.headers['X-Auth-Token'] auth_token = resp.headers['X-Auth-Token']
self.assertEqual(quoted_acct,
urlparse(resp.headers['X-Storage-Url']).path)
req = self._make_request( req = self._make_request(
'/auth/v1.0', '/auth/v1.0',
@ -940,7 +944,17 @@ class TestAuth(unittest.TestCase):
resp = req.get_response(ath) resp = req.get_response(ath)
self.assertEqual(resp.status_int, 200) self.assertEqual(resp.status_int, 200)
self.assertEqual(auth_token, resp.headers['X-Auth-Token']) self.assertEqual(auth_token, resp.headers['X-Auth-Token'])
self.assertEqual(quoted_acct,
urlparse(resp.headers['X-Storage-Url']).path)
# storage urls should be url-encoded...
req = self._make_request(
quoted_acct, headers={'X-Auth-Token': auth_token})
req.environ['swift.cache'] = memcache
resp = req.get_response(ath)
self.assertEqual(204, resp.status_int)
# ...but it also works if you send the account raw
req = self._make_request( req = self._make_request(
u'/v1/AUTH_t\u00e9st', headers={'X-Auth-Token': auth_token}) u'/v1/AUTH_t\u00e9st', headers={'X-Auth-Token': auth_token})
req.environ['swift.cache'] = memcache req.environ['swift.cache'] = memcache