Fix iso8601 import/use and date comparaison.
- Store the unix time from iso8601.parse_date to compare against time.time. - on a WSGI environement the import don't get passed to the methods from __init__ use a self. variable. - Fixes bug 951603. - Add unit tests. - Add iso8601 to test-requires. Change-Id: Ia8af8b203d1310d5ae6868c3a14dfdf68d6e5331
This commit is contained in:
parent
a036b3f77b
commit
1e07b98d77
@ -146,6 +146,7 @@ class AuthProtocol(object):
|
||||
|
||||
# Token caching via memcache
|
||||
self._cache = None
|
||||
self._iso8601 = None
|
||||
memcache_servers = conf.get('memcache_servers')
|
||||
# By default the token will be cached for 5 minutes
|
||||
self.token_cache_time = conf.get('token_cache_time', 300)
|
||||
@ -155,6 +156,7 @@ class AuthProtocol(object):
|
||||
import iso8601
|
||||
logger.info('Using memcache for caching token')
|
||||
self._cache = memcache.Client(memcache_servers.split(','))
|
||||
self._iso8601 = iso8601
|
||||
except NameError as e:
|
||||
logger.warn('disabled caching due to missing libraries %s', e)
|
||||
|
||||
@ -459,7 +461,7 @@ class AuthProtocol(object):
|
||||
raise InvalidUserToken('Token authorization failed')
|
||||
if cached:
|
||||
data, expires = cached
|
||||
if time.time() < expires:
|
||||
if time.time() < float(expires):
|
||||
logger.debug('Returning cached token %s', token)
|
||||
return data
|
||||
else:
|
||||
@ -475,7 +477,7 @@ class AuthProtocol(object):
|
||||
key = 'tokens/%s' % token
|
||||
if 'token' in data.get('access', {}):
|
||||
timestamp = data['access']['token']['expires']
|
||||
expires = iso8601.parse_date(timestamp)
|
||||
expires = self._iso8601.parse_date(timestamp).strftime('%s')
|
||||
else:
|
||||
logger.error('invalid token format')
|
||||
return
|
||||
|
@ -17,10 +17,55 @@
|
||||
import json
|
||||
|
||||
import webob
|
||||
import datetime
|
||||
import iso8601
|
||||
|
||||
from keystone.middleware import auth_token
|
||||
from keystone import test
|
||||
|
||||
DATA = {
|
||||
'access': {
|
||||
'token': {
|
||||
'id': 'token1',
|
||||
'tenant': {
|
||||
'id': 'tenant_id1',
|
||||
'name': 'tenant_name1',
|
||||
},
|
||||
},
|
||||
'user': {
|
||||
'id': 'user_id1',
|
||||
'username': 'user_name1',
|
||||
'roles': [
|
||||
{'name': 'role1'},
|
||||
{'name': 'role2'},
|
||||
],
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
class FakeMemcache(object):
|
||||
def __init__(self):
|
||||
self.set_key = None
|
||||
self.set_value = None
|
||||
self.token_expiration = None
|
||||
|
||||
def get(self, key):
|
||||
data = DATA.copy()
|
||||
if not data or key != "tokens/%s" % (data['access']['token']['id']):
|
||||
return
|
||||
if not self.token_expiration:
|
||||
dt = datetime.datetime.now() + datetime.timedelta(minutes=5)
|
||||
self.token_expiration = dt.strftime("%s")
|
||||
dt = datetime.datetime.now() + datetime.timedelta(hours=24)
|
||||
ks_expires = dt.isoformat()
|
||||
data['access']['token']['expires'] = ks_expires
|
||||
return (data, str(self.token_expiration))
|
||||
|
||||
def set(self, key, value, time=None):
|
||||
self.set_value = value
|
||||
self.set_key = key
|
||||
|
||||
|
||||
class FakeHTTPResponse(object):
|
||||
def __init__(self, status, body):
|
||||
@ -59,25 +104,7 @@ class FakeHTTPConnection(object):
|
||||
token_id = path.rsplit('/', 1)[1]
|
||||
if token_id == 'token1':
|
||||
status = 200
|
||||
body = json.dumps({
|
||||
'access': {
|
||||
'token': {
|
||||
'id': token_id,
|
||||
'tenant': {
|
||||
'id': 'tenant_id1',
|
||||
'name': 'tenant_name1',
|
||||
},
|
||||
},
|
||||
'user': {
|
||||
'id': 'user_id1',
|
||||
'username': 'user_name1',
|
||||
'roles': [
|
||||
{'name': 'role1'},
|
||||
{'name': 'role2'},
|
||||
],
|
||||
},
|
||||
},
|
||||
})
|
||||
body = json.dumps(DATA)
|
||||
else:
|
||||
status = 404
|
||||
body = ''
|
||||
@ -123,6 +150,7 @@ class AuthTokenMiddlewareTest(test.TestCase):
|
||||
|
||||
self.middleware = auth_token.AuthProtocol(fake_app, conf)
|
||||
self.middleware.http_client_class = FakeHTTPConnection
|
||||
self.middleware._iso8601 = iso8601
|
||||
|
||||
self.response_status = None
|
||||
self.response_headers = None
|
||||
@ -160,3 +188,30 @@ class AuthTokenMiddlewareTest(test.TestCase):
|
||||
self.assertEqual(self.response_status, 401)
|
||||
self.assertEqual(self.response_headers['WWW-Authenticate'],
|
||||
'Keystone uri=\'https://keystone.example.com:1234\'')
|
||||
|
||||
def test_memcache(self):
|
||||
req = webob.Request.blank('/')
|
||||
req.headers['X-Auth-Token'] = 'token1'
|
||||
self.middleware._cache = FakeMemcache()
|
||||
self.middleware(req.environ, self.start_fake_response)
|
||||
self.assertEqual(self.middleware._cache.set_value, None)
|
||||
|
||||
def test_memcache_set_invalid(self):
|
||||
req = webob.Request.blank('/')
|
||||
req.headers['X-Auth-Token'] = 'token2'
|
||||
self.middleware._cache = FakeMemcache()
|
||||
self.middleware(req.environ, self.start_fake_response)
|
||||
self.assertEqual(self.middleware._cache.set_value, "invalid")
|
||||
|
||||
def test_memcache_set_expired(self):
|
||||
req = webob.Request.blank('/')
|
||||
req.headers['X-Auth-Token'] = 'token1'
|
||||
self.middleware._cache = FakeMemcache()
|
||||
expired = datetime.datetime.now() - datetime.timedelta(minutes=1)
|
||||
self.middleware._cache.token_expiration = float(expired.strftime("%s"))
|
||||
self.middleware(req.environ, self.start_fake_response)
|
||||
self.assertEqual(len(self.middleware._cache.set_value), 2)
|
||||
|
||||
if __name__ == '__main__':
|
||||
import unittest
|
||||
unittest.main()
|
||||
|
@ -22,3 +22,4 @@ httplib2
|
||||
|
||||
# for python-novaclient
|
||||
prettytable
|
||||
iso8601>=0.1.4
|
||||
|
Loading…
Reference in New Issue
Block a user