Merge "Implements token expiration handling"

This commit is contained in:
Jenkins
2013-02-19 18:34:47 +00:00
committed by Gerrit Code Review
3 changed files with 73 additions and 7 deletions

View File

@@ -67,7 +67,6 @@ class HTTPClient(object):
self.tenant_id = None
self.tenant_name = None
self.auth_url = None
self.auth_token = None
self.management_url = None
if timeout is not None:
self.timeout = float(timeout)
@@ -82,7 +81,6 @@ class HTTPClient(object):
self.tenant_name = self.auth_ref.tenant_name
self.auth_url = self.auth_ref.auth_url[0]
self.management_url = self.auth_ref.management_url[0]
self.auth_token = self.auth_ref.auth_token
# allow override of the auth_ref defaults from explicit
# values provided to the client
if username:
@@ -94,7 +92,9 @@ class HTTPClient(object):
if auth_url:
self.auth_url = auth_url.rstrip('/')
if token:
self.auth_token = token
self.auth_token_from_user = token
else:
self.auth_token_from_user = None
if endpoint:
self.management_url = endpoint.rstrip('/')
self.password = password
@@ -126,6 +126,23 @@ class HTTPClient(object):
self.stale_duration = stale_duration or access.STALE_TOKEN_DURATION
self.stale_duration = int(self.stale_duration)
@property
def auth_token(self):
if self.auth_token_from_user:
return self.auth_token_from_user
if self.auth_ref:
if self.auth_ref.will_expire_soon(self.stale_duration):
self.authenticate()
return self.auth_ref.auth_token
@auth_token.setter
def auth_token(self, value):
self.auth_token_from_user = value
@auth_token.deleter
def auth_token(selef):
del self.auth_token_from_user
def authenticate(self, username=None, password=None, tenant_name=None,
tenant_id=None, auth_url=None, token=None):
""" Authenticate user.
@@ -165,7 +182,12 @@ class HTTPClient(object):
password = password or self.password
tenant_name = tenant_name or self.tenant_name
tenant_id = tenant_id or self.tenant_id
token = token or self.auth_token
if not token:
token = self.auth_token_from_user
if (not token and self.auth_ref
and not self.auth_ref.will_expire_soon(self.stale_duration)):
token = self.auth_ref.auth_token
(keyring_key, auth_ref) = self.get_auth_ref_from_keyring(auth_url,
username,
@@ -224,7 +246,7 @@ class HTTPClient(object):
keyring_key)
if auth_ref:
auth_ref = pickle.loads(auth_ref)
if auth_ref.will_expire_soon(self.stale_duration):
if self.auth_ref.will_expire_soon(self.stale_duration):
# token has expired, don't use it
auth_ref = None
except Exception as e:

View File

@@ -146,7 +146,6 @@ class Client(client.HTTPClient):
# if we got a response without a service catalog, set the local
# list of tenants for introspection, and leave to client user
# to determine what to do. Otherwise, load up the service catalog
self.auth_token = self.auth_ref.auth_token
if self.auth_ref.scoped:
if self.management_url is None and self.auth_ref.management_url:
self.management_url = self.auth_ref.management_url[0]

View File

@@ -1,10 +1,12 @@
import copy
from datetime import timedelta
import json
import requests
from keystoneclient.v2_0 import client
from keystoneclient import exceptions
from keystoneclient.openstack.common import timeutils
from tests import utils
@@ -14,7 +16,7 @@ class AuthenticateAgainstKeystoneTests(utils.TestCase):
self.TEST_RESPONSE_DICT = {
"access": {
"token": {
"expires": "12345",
"expires": "2999-01-01T00:00:10Z",
"id": self.TEST_TOKEN,
"tenant": {
"id": self.TEST_TENANT_ID
@@ -40,6 +42,49 @@ class AuthenticateAgainstKeystoneTests(utils.TestCase):
'User-Agent': 'python-keystoneclient',
}
def test_authenticate_success_expired(self):
# Build an expired token
self.TEST_RESPONSE_DICT['access']['token']['expires'] = \
(timeutils.utcnow() - timedelta(1)).isoformat()
resp = utils.TestResponse({
"status_code": 200,
"text": json.dumps(self.TEST_RESPONSE_DICT),
})
kwargs = copy.copy(self.TEST_REQUEST_BASE)
kwargs['headers'] = self.TEST_REQUEST_HEADERS
kwargs['data'] = json.dumps(self.TEST_REQUEST_BODY)
requests.request('POST',
self.TEST_URL + "/tokens",
**kwargs).AndReturn((resp))
self.mox.ReplayAll()
cs = client.Client(tenant_id=self.TEST_TENANT_ID,
auth_url=self.TEST_URL,
username=self.TEST_USER,
password=self.TEST_TOKEN)
self.assertEqual(cs.management_url,
self.TEST_RESPONSE_DICT["access"]["serviceCatalog"][3]
['endpoints'][0]["adminURL"])
# Build a new response
self.mox.ResetAll()
TEST_TOKEN = "abcdef"
self.TEST_RESPONSE_DICT['access']['token']['expires'] = \
"2999-01-01T00:00:10Z"
self.TEST_RESPONSE_DICT['access']['token']['id'] = TEST_TOKEN
resp = utils.TestResponse({
"status_code": 200,
"text": json.dumps(self.TEST_RESPONSE_DICT),
})
requests.request('POST',
self.TEST_URL + "/tokens",
**kwargs).AndReturn((resp))
self.mox.ReplayAll()
self.assertEqual(cs.auth_token, TEST_TOKEN)
def test_authenticate_failure(self):
_auth = 'auth'
_cred = 'passwordCredentials'