Correctly interpret url encoded users and keys. Fixes #1

This commit is contained in:
gholt 2011-06-01 00:21:17 +00:00
parent d72693cdac
commit 3ef9425dec
2 changed files with 57 additions and 8 deletions

View File

@ -862,9 +862,10 @@ class Swauth(object):
Handles the PUT v2/<account>/<user> call for adding a user to an
account.
X-Auth-User-Key represents the user's key, X-Auth-User-Admin may be set
to `true` to create an account .admin, and X-Auth-User-Reseller-Admin
may be set to `true` to create a .reseller_admin.
X-Auth-User-Key represents the user's key (url encoded),
X-Auth-User-Admin may be set to `true` to create an account .admin, and
X-Auth-User-Reseller-Admin may be set to `true` to create a
.reseller_admin.
Can only be called by an account .admin unless the user is to be a
.reseller_admin, in which case the request must be by .super_admin.
@ -875,7 +876,7 @@ class Swauth(object):
# Validate path info
account = req.path_info_pop()
user = req.path_info_pop()
key = req.headers.get('x-auth-user-key')
key = unquote(req.headers.get('x-auth-user-key', ''))
admin = req.headers.get('x-auth-user-admin') == 'true'
reseller_admin = \
req.headers.get('x-auth-user-reseller-admin') == 'true'
@ -978,6 +979,10 @@ class Swauth(object):
X-Auth-User: <act>:<usr> or X-Storage-User: <act>:<usr>
X-Auth-Key: <key> or X-Storage-Pass: <key>
Values should be url encoded, "act%3Ausr" instead of "act:usr" for
example; however, for backwards compatibility the colon may be included
unencoded.
On successful authentication, the response will have X-Auth-Token and
X-Storage-Token set to the token to use with Swift and X-Storage-URL
set to the URL to the default Swift cluster to use.
@ -1017,7 +1022,7 @@ class Swauth(object):
account = pathsegs[1]
user = req.headers.get('x-storage-user')
if not user:
user = req.headers.get('x-auth-user')
user = unquote(req.headers.get('x-auth-user', ''))
if not user or ':' not in user:
return HTTPUnauthorized(request=req)
account2, user = user.split(':', 1)
@ -1025,15 +1030,15 @@ class Swauth(object):
return HTTPUnauthorized(request=req)
key = req.headers.get('x-storage-pass')
if not key:
key = req.headers.get('x-auth-key')
key = unquote(req.headers.get('x-auth-key', ''))
elif pathsegs[0] in ('auth', 'v1.0'):
user = req.headers.get('x-auth-user')
user = unquote(req.headers.get('x-auth-user', ''))
if not user:
user = req.headers.get('x-storage-user')
if not user or ':' not in user:
return HTTPUnauthorized(request=req)
account, user = user.split(':', 1)
key = req.headers.get('x-auth-key')
key = unquote(req.headers.get('x-auth-key', ''))
if not key:
key = req.headers.get('x-storage-pass')
else:

View File

@ -3216,6 +3216,50 @@ class TestAuth(unittest.TestCase):
resp = self.test_auth.authorize(req)
self.assertEquals(resp.status_int, 403)
def _get_token_success_v1_0_encoded(self, saved_user, saved_key, sent_user,
sent_key):
self.test_auth.app = FakeApp(iter([
# GET of user object
('200 Ok', {},
json.dumps({"auth": "plaintext:%s" % saved_key,
"groups": [{'name': saved_user}, {'name': "act"},
{'name': ".admin"}]})),
# GET of account
('204 Ok', {'X-Container-Meta-Account-Id': 'AUTH_cfa'}, ''),
# PUT of new token
('201 Created', {}, ''),
# POST of token to user object
('204 No Content', {}, ''),
# GET of services object
('200 Ok', {}, json.dumps({"storage": {"default": "local",
"local": "http://127.0.0.1:8080/v1/AUTH_cfa"}}))]))
resp = Request.blank('/auth/v1.0',
headers={'X-Auth-User': sent_user,
'X-Auth-Key': sent_key}).get_response(self.test_auth)
self.assertEquals(resp.status_int, 200)
self.assert_(resp.headers.get('x-auth-token',
'').startswith('AUTH_tk'), resp.headers.get('x-auth-token'))
self.assertEquals(resp.headers.get('x-auth-token'),
resp.headers.get('x-storage-token'))
self.assertEquals(resp.headers.get('x-storage-url'),
'http://127.0.0.1:8080/v1/AUTH_cfa')
self.assertEquals(json.loads(resp.body),
{"storage": {"default": "local",
"local": "http://127.0.0.1:8080/v1/AUTH_cfa"}})
self.assertEquals(self.test_auth.app.calls, 5)
def test_get_token_success_v1_0_encoded1(self):
self._get_token_success_v1_0_encoded(
'act:usr', 'key', 'act%3ausr', 'key')
def test_get_token_success_v1_0_encoded2(self):
self._get_token_success_v1_0_encoded(
'act:u s r', 'key', 'act%3au%20s%20r', 'key')
def test_get_token_success_v1_0_encoded3(self):
self._get_token_success_v1_0_encoded(
'act:u s r', 'k:e:y', 'act%3au%20s%20r', 'k%3Ae%3ay')
if __name__ == '__main__':
unittest.main()