Update to better support no-reseller-prefix and multiple auth middleware

This commit is contained in:
gholt 2010-09-16 11:14:09 -07:00
parent 73ee6708df
commit 01059884b3
2 changed files with 61 additions and 4 deletions

View File

@ -63,7 +63,15 @@ class DevAuth(object):
resp.read()
conn.close()
if resp.status // 100 != 2:
if self.reseller_prefix:
return HTTPUnauthorized()(env, start_response)
else:
# If we have no reseller prefix, we can't deny the
# request just yet because another auth middleware
# might be able to approve.
if 'swift.authorize' not in env:
env['swift.authorize'] = self.denied_response
return self.app(env, start_response)
expiration = float(resp.getheader('x-auth-ttl'))
groups = resp.getheader('x-auth-groups')
memcache_client.set(key, (time(), expiration, groups),
@ -78,6 +86,12 @@ class DevAuth(object):
else:
version, rest = split_path(env.get('PATH_INFO', ''), 1, 2, True)
if rest and rest.startswith(self.reseller_prefix):
# If we don't have a reseller prefix we have no way of knowing
# if we should be handling the request, so we only set
# swift.authorize if it isn't set already (or we have a
# reseller prefix that matches so we know we should handle the
# request).
if self.reseller_prefix or 'swift.authorize' not in env:
env['swift.authorize'] = self.authorize
env['swift.clean_acl'] = clean_acl
elif 'swift.authorize' not in env:

View File

@ -90,10 +90,15 @@ class Logger(object):
_, exc, _ = sys.exc_info()
self.exception_value = (msg,
'%s %s' % (exc.__class__.__name__, str(exc)), args, kwargs)
# tests
class FakeApp(object):
def __init__(self):
self.i_was_called = False
def __call__(self, env, start_response):
self.i_was_called = True
req = Request(env)
if 'swift.authorize' in env:
resp = env['swift.authorize'](req)
@ -101,6 +106,7 @@ class FakeApp(object):
return resp(env, start_response)
return ['204 No Content']
def start_response(*args):
pass
@ -138,6 +144,43 @@ class TestAuth(unittest.TestCase):
finally:
auth.http_connect = old_http_connect
def test_auth_no_reseller_prefix_deny(self):
# Ensures that when we have no reseller prefix, we don't deny a request
# outright but set up a denial swift.authorize and pass the request on
# down the chain.
old_http_connect = auth.http_connect
try:
local_app = FakeApp()
local_auth = \
auth.filter_factory({'reseller_prefix': ''})(local_app)
auth.http_connect = mock_http_connect(404)
reqenv = {'REQUEST_METHOD': 'GET', 'PATH_INFO': '/v1/account',
'HTTP_X_AUTH_TOKEN': 't', 'swift.cache': FakeMemcache()}
result = ''.join(local_auth(reqenv, lambda x, y: None))
self.assert_(result.startswith('401'), result)
self.assert_(local_app.i_was_called)
self.assertEquals(reqenv['swift.authorize'],
local_auth.denied_response)
finally:
auth.http_connect = old_http_connect
def test_auth_no_reseller_prefix_no_token(self):
# Check that normally we set up a call back to our authorize.
local_auth = \
auth.filter_factory({'reseller_prefix': ''})(FakeApp())
reqenv = {'REQUEST_METHOD': 'GET', 'PATH_INFO': '/v1/account',
'swift.cache': FakeMemcache()}
result = ''.join(local_auth(reqenv, lambda x, y: None))
self.assert_(result.startswith('401'), result)
self.assertEquals(reqenv['swift.authorize'], local_auth.authorize)
# Now make sure we don't override an existing swift.authorize when we
# have no reseller prefix.
local_authorize = lambda req: None
reqenv['swift.authorize'] = local_authorize
result = ''.join(local_auth(reqenv, lambda x, y: None))
self.assert_(result.startswith('204'), result)
self.assertEquals(reqenv['swift.authorize'], local_authorize)
def test_auth_fail(self):
old_http_connect = auth.http_connect
try: