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
|
# Token caching via memcache
|
||||||
self._cache = None
|
self._cache = None
|
||||||
|
self._iso8601 = None
|
||||||
memcache_servers = conf.get('memcache_servers')
|
memcache_servers = conf.get('memcache_servers')
|
||||||
# By default the token will be cached for 5 minutes
|
# By default the token will be cached for 5 minutes
|
||||||
self.token_cache_time = conf.get('token_cache_time', 300)
|
self.token_cache_time = conf.get('token_cache_time', 300)
|
||||||
@ -155,6 +156,7 @@ class AuthProtocol(object):
|
|||||||
import iso8601
|
import iso8601
|
||||||
logger.info('Using memcache for caching token')
|
logger.info('Using memcache for caching token')
|
||||||
self._cache = memcache.Client(memcache_servers.split(','))
|
self._cache = memcache.Client(memcache_servers.split(','))
|
||||||
|
self._iso8601 = iso8601
|
||||||
except NameError as e:
|
except NameError as e:
|
||||||
logger.warn('disabled caching due to missing libraries %s', e)
|
logger.warn('disabled caching due to missing libraries %s', e)
|
||||||
|
|
||||||
@ -459,7 +461,7 @@ class AuthProtocol(object):
|
|||||||
raise InvalidUserToken('Token authorization failed')
|
raise InvalidUserToken('Token authorization failed')
|
||||||
if cached:
|
if cached:
|
||||||
data, expires = cached
|
data, expires = cached
|
||||||
if time.time() < expires:
|
if time.time() < float(expires):
|
||||||
logger.debug('Returning cached token %s', token)
|
logger.debug('Returning cached token %s', token)
|
||||||
return data
|
return data
|
||||||
else:
|
else:
|
||||||
@ -475,7 +477,7 @@ class AuthProtocol(object):
|
|||||||
key = 'tokens/%s' % token
|
key = 'tokens/%s' % token
|
||||||
if 'token' in data.get('access', {}):
|
if 'token' in data.get('access', {}):
|
||||||
timestamp = data['access']['token']['expires']
|
timestamp = data['access']['token']['expires']
|
||||||
expires = iso8601.parse_date(timestamp)
|
expires = self._iso8601.parse_date(timestamp).strftime('%s')
|
||||||
else:
|
else:
|
||||||
logger.error('invalid token format')
|
logger.error('invalid token format')
|
||||||
return
|
return
|
||||||
|
@ -17,10 +17,55 @@
|
|||||||
import json
|
import json
|
||||||
|
|
||||||
import webob
|
import webob
|
||||||
|
import datetime
|
||||||
|
import iso8601
|
||||||
|
|
||||||
from keystone.middleware import auth_token
|
from keystone.middleware import auth_token
|
||||||
from keystone import test
|
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):
|
class FakeHTTPResponse(object):
|
||||||
def __init__(self, status, body):
|
def __init__(self, status, body):
|
||||||
@ -59,25 +104,7 @@ class FakeHTTPConnection(object):
|
|||||||
token_id = path.rsplit('/', 1)[1]
|
token_id = path.rsplit('/', 1)[1]
|
||||||
if token_id == 'token1':
|
if token_id == 'token1':
|
||||||
status = 200
|
status = 200
|
||||||
body = json.dumps({
|
body = json.dumps(DATA)
|
||||||
'access': {
|
|
||||||
'token': {
|
|
||||||
'id': token_id,
|
|
||||||
'tenant': {
|
|
||||||
'id': 'tenant_id1',
|
|
||||||
'name': 'tenant_name1',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
'user': {
|
|
||||||
'id': 'user_id1',
|
|
||||||
'username': 'user_name1',
|
|
||||||
'roles': [
|
|
||||||
{'name': 'role1'},
|
|
||||||
{'name': 'role2'},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
else:
|
else:
|
||||||
status = 404
|
status = 404
|
||||||
body = ''
|
body = ''
|
||||||
@ -123,6 +150,7 @@ class AuthTokenMiddlewareTest(test.TestCase):
|
|||||||
|
|
||||||
self.middleware = auth_token.AuthProtocol(fake_app, conf)
|
self.middleware = auth_token.AuthProtocol(fake_app, conf)
|
||||||
self.middleware.http_client_class = FakeHTTPConnection
|
self.middleware.http_client_class = FakeHTTPConnection
|
||||||
|
self.middleware._iso8601 = iso8601
|
||||||
|
|
||||||
self.response_status = None
|
self.response_status = None
|
||||||
self.response_headers = None
|
self.response_headers = None
|
||||||
@ -160,3 +188,30 @@ class AuthTokenMiddlewareTest(test.TestCase):
|
|||||||
self.assertEqual(self.response_status, 401)
|
self.assertEqual(self.response_status, 401)
|
||||||
self.assertEqual(self.response_headers['WWW-Authenticate'],
|
self.assertEqual(self.response_headers['WWW-Authenticate'],
|
||||||
'Keystone uri=\'https://keystone.example.com:1234\'')
|
'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
|
# for python-novaclient
|
||||||
prettytable
|
prettytable
|
||||||
|
iso8601>=0.1.4
|
||||||
|
Loading…
Reference in New Issue
Block a user