diff --git a/keystone/auth/controllers.py b/keystone/auth/controllers.py index dcbc94bc00..7080161950 100644 --- a/keystone/auth/controllers.py +++ b/keystone/auth/controllers.py @@ -19,11 +19,11 @@ from oslo_config import cfg from oslo_log import log from oslo_serialization import jsonutils from oslo_utils import importutils -from oslo_utils import timeutils import six from keystone.common import controller from keystone.common import dependency +from keystone.common import utils from keystone.common import wsgi from keystone import config from keystone.contrib import federation @@ -526,7 +526,7 @@ class Auth(controller.V3Controller): for t in tokens: expires = t['expires'] if not (expires and isinstance(expires, six.text_type)): - t['expires'] = timeutils.isotime(expires) + t['expires'] = utils.isotime(expires) data = {'revoked': tokens} json_data = jsonutils.dumps(data) signed_text = cms.cms_sign_text(json_data, diff --git a/keystone/common/utils.py b/keystone/common/utils.py index ebe8bc8a17..76ca745d9d 100644 --- a/keystone/common/utils.py +++ b/keystone/common/utils.py @@ -27,6 +27,7 @@ from oslo_config import cfg from oslo_log import log from oslo_serialization import jsonutils from oslo_utils import strutils +from oslo_utils import timeutils import passlib.hash import six from six import moves @@ -469,3 +470,32 @@ class WhiteListedItemFilter(object): if name not in self._whitelist: raise KeyError return self._data[name] + + +_ISO8601_TIME_FORMAT_SUBSECOND = '%Y-%m-%dT%H:%M:%S.%f' +_ISO8601_TIME_FORMAT = '%Y-%m-%dT%H:%M:%S' + + +def isotime(at=None, subsecond=False): + """Stringify time in ISO 8601 format.""" + + # Python provides a similar instance method for datetime.datetime objects + # called isoformat(). The format of the strings generated by isoformat() + # have a couple of problems: + # 1) The strings generated by isotime are used in tokens and other public + # APIs that we can't change without a deprecation period. The strings + # generated by isoformat are not the same format, so we can't just + # change to it. + # 2) The strings generated by isoformat do not include the microseconds if + # the value happens to be 0. This will likely show up as random failures + # as parsers may be written to always expect microseconds, and it will + # parse correctly most of the time. + + if not at: + at = timeutils.utcnow() + st = at.strftime(_ISO8601_TIME_FORMAT + if not subsecond + else _ISO8601_TIME_FORMAT_SUBSECOND) + tz = at.tzinfo.tzname(None) if at.tzinfo else 'UTC' + st += ('Z' if tz == 'UTC' else tz) + return st diff --git a/keystone/contrib/federation/idp.py b/keystone/contrib/federation/idp.py index aefd97582f..6ea193d30d 100644 --- a/keystone/contrib/federation/idp.py +++ b/keystone/contrib/federation/idp.py @@ -31,6 +31,7 @@ xmldsig = importutils.try_import("saml2.xmldsig") if not xmldsig: xmldsig = importutils.try_import("xmldsig") +from keystone.common import utils from keystone import exception from keystone.i18n import _, _LE from keystone.openstack.common import fileutils @@ -94,7 +95,7 @@ class SAMLGenerator(object): expires_in = CONF.saml.assertion_expiration_time now = timeutils.utcnow() future = now + datetime.timedelta(seconds=expires_in) - return timeutils.isotime(future, subsecond=True) + return utils.isotime(future, subsecond=True) def _create_status(self): """Create an object that represents a SAML Status. @@ -240,7 +241,7 @@ class SAMLGenerator(object): """ authn_statement = saml.AuthnStatement() - authn_statement.authn_instant = timeutils.isotime() + authn_statement.authn_instant = utils.isotime() authn_statement.session_index = uuid.uuid4().hex authn_statement.session_not_on_or_after = expiration_time @@ -277,7 +278,7 @@ class SAMLGenerator(object): """ assertion = saml.Assertion() assertion.id = self.assertion_id - assertion.issue_instant = timeutils.isotime() + assertion.issue_instant = utils.isotime() assertion.version = '2.0' assertion.issuer = issuer assertion.signature = signature @@ -305,7 +306,7 @@ class SAMLGenerator(object): response = samlp.Response() response.id = uuid.uuid4().hex response.destination = recipient - response.issue_instant = timeutils.isotime() + response.issue_instant = utils.isotime() response.version = '2.0' response.issuer = issuer response.status = status diff --git a/keystone/contrib/oauth1/backends/sql.py b/keystone/contrib/oauth1/backends/sql.py index c6ab6e5a2a..36dfc64e3d 100644 --- a/keystone/contrib/oauth1/backends/sql.py +++ b/keystone/contrib/oauth1/backends/sql.py @@ -21,6 +21,7 @@ from oslo_utils import timeutils import six from keystone.common import sql +from keystone.common import utils from keystone.contrib.oauth1 import core from keystone import exception from keystone.i18n import _ @@ -163,7 +164,7 @@ class OAuth1(object): if token_duration: now = timeutils.utcnow() future = now + datetime.timedelta(seconds=token_duration) - expiry_date = timeutils.isotime(future, subsecond=True) + expiry_date = utils.isotime(future, subsecond=True) ref = {} ref['id'] = request_token_id @@ -225,7 +226,7 @@ class OAuth1(object): if token_duration: now = timeutils.utcnow() future = now + datetime.timedelta(seconds=token_duration) - expiry_date = timeutils.isotime(future, subsecond=True) + expiry_date = utils.isotime(future, subsecond=True) # add Access Token ref = {} diff --git a/keystone/contrib/revoke/model.py b/keystone/contrib/revoke/model.py index b13f9ed147..1df660485e 100644 --- a/keystone/contrib/revoke/model.py +++ b/keystone/contrib/revoke/model.py @@ -13,6 +13,8 @@ from oslo_utils import timeutils from six.moves import map +from keystone.common import utils + # The set of attributes common between the RevokeEvent # and the dictionaries created from the token Data. @@ -101,10 +103,10 @@ class RevokeEvent(object): if self.consumer_id is not None: event['OS-OAUTH1:access_token_id'] = self.access_token_id if self.expires_at is not None: - event['expires_at'] = timeutils.isotime(self.expires_at) + event['expires_at'] = utils.isotime(self.expires_at) if self.issued_before is not None: - event['issued_before'] = timeutils.isotime(self.issued_before, - subsecond=True) + event['issued_before'] = utils.isotime(self.issued_before, + subsecond=True) return event def key_for_name(self, name): diff --git a/keystone/tests/unit/test_backend_kvs.py b/keystone/tests/unit/test_backend_kvs.py index 5337135b4c..a22faa5952 100644 --- a/keystone/tests/unit/test_backend_kvs.py +++ b/keystone/tests/unit/test_backend_kvs.py @@ -18,6 +18,7 @@ from oslo_config import cfg from oslo_utils import timeutils import six +from keystone.common import utils from keystone import exception from keystone.tests import unit as tests from keystone.tests.unit import test_backend @@ -67,13 +68,13 @@ class KvsToken(tests.TestCase, test_backend.TokenTests): valid_token_ref = token_persistence.get_token(valid_token_id) expired_token_ref = token_persistence.get_token(expired_token_id) expected_user_token_list = [ - (valid_token_id, timeutils.isotime(valid_token_ref['expires'], - subsecond=True)), - (expired_token_id, timeutils.isotime(expired_token_ref['expires'], - subsecond=True))] + (valid_token_id, utils.isotime(valid_token_ref['expires'], + subsecond=True)), + (expired_token_id, utils.isotime(expired_token_ref['expires'], + subsecond=True))] self.assertEqual(expected_user_token_list, user_token_list) new_expired_data = (expired_token_id, - timeutils.isotime( + utils.isotime( (timeutils.utcnow() - expire_delta), subsecond=True)) self._update_user_token_index_direct(user_key, expired_token_id, @@ -82,10 +83,10 @@ class KvsToken(tests.TestCase, test_backend.TokenTests): user_id=user_id) valid_token_ref_2 = token_persistence.get_token(valid_token_id_2) expected_user_token_list = [ - (valid_token_id, timeutils.isotime(valid_token_ref['expires'], - subsecond=True)), - (valid_token_id_2, timeutils.isotime(valid_token_ref_2['expires'], - subsecond=True))] + (valid_token_id, utils.isotime(valid_token_ref['expires'], + subsecond=True)), + (valid_token_id_2, utils.isotime(valid_token_ref_2['expires'], + subsecond=True))] user_token_list = token_persistence.driver._store.get(user_key) self.assertEqual(expected_user_token_list, user_token_list) @@ -94,10 +95,10 @@ class KvsToken(tests.TestCase, test_backend.TokenTests): new_token_id, data = self.create_token_sample_data(user_id=user_id) new_token_ref = token_persistence.get_token(new_token_id) expected_user_token_list = [ - (valid_token_id, timeutils.isotime(valid_token_ref['expires'], - subsecond=True)), - (new_token_id, timeutils.isotime(new_token_ref['expires'], - subsecond=True))] + (valid_token_id, utils.isotime(valid_token_ref['expires'], + subsecond=True)), + (new_token_id, utils.isotime(new_token_ref['expires'], + subsecond=True))] user_token_list = token_persistence.driver._store.get(user_key) self.assertEqual(expected_user_token_list, user_token_list) diff --git a/keystone/tests/unit/test_revoke.py b/keystone/tests/unit/test_revoke.py index 3f6c20cbec..e07733daeb 100644 --- a/keystone/tests/unit/test_revoke.py +++ b/keystone/tests/unit/test_revoke.py @@ -19,6 +19,7 @@ from oslo_utils import timeutils from six.moves import range from testtools import matchers +from keystone.common import utils from keystone.contrib import revoke from keystone.contrib.revoke import model from keystone import exception @@ -147,8 +148,8 @@ class RevokeTests(object): def test_expired_events_removed_validate_token_success(self, mock_utcnow): def _sample_token_values(): token = _sample_blank_token() - token['expires_at'] = timeutils.isotime(_future_time(), - subsecond=True) + token['expires_at'] = utils.isotime(_future_time(), + subsecond=True) return token now = datetime.datetime.utcnow() @@ -175,7 +176,7 @@ class RevokeTests(object): def test_revoke_by_expiration_project_and_domain_fails(self): user_id = _new_id() - expires_at = timeutils.isotime(_future_time(), subsecond=True) + expires_at = utils.isotime(_future_time(), subsecond=True) domain_id = _new_id() project_id = _new_id() self.assertThat( diff --git a/keystone/tests/unit/test_token_provider.py b/keystone/tests/unit/test_token_provider.py index da57587ce1..3ebb0187b7 100644 --- a/keystone/tests/unit/test_token_provider.py +++ b/keystone/tests/unit/test_token_provider.py @@ -18,6 +18,7 @@ from oslo_config import cfg from oslo_utils import timeutils from keystone.common import dependency +from keystone.common import utils from keystone import exception from keystone.tests import unit as tests from keystone.tests.unit.ksfixtures import database @@ -657,8 +658,8 @@ def create_v2_token(): return { "access": { "token": { - "expires": timeutils.isotime(timeutils.utcnow() + - FUTURE_DELTA), + "expires": utils.isotime(timeutils.utcnow() + + FUTURE_DELTA), "issued_at": "2013-05-21T00:02:43.941473Z", "tenant": { "enabled": True, @@ -673,7 +674,7 @@ def create_v2_token(): SAMPLE_V2_TOKEN_EXPIRED = { "access": { "token": { - "expires": timeutils.isotime(CURRENT_DATE), + "expires": utils.isotime(CURRENT_DATE), "issued_at": "2013-05-21T00:02:43.941473Z", "tenant": { "enabled": True, @@ -689,7 +690,7 @@ def create_v3_token(): return { "token": { 'methods': [], - "expires_at": timeutils.isotime(timeutils.utcnow() + FUTURE_DELTA), + "expires_at": utils.isotime(timeutils.utcnow() + FUTURE_DELTA), "issued_at": "2013-05-21T00:02:43.941473Z", } } @@ -697,7 +698,7 @@ def create_v3_token(): SAMPLE_V3_TOKEN_EXPIRED = { "token": { - "expires_at": timeutils.isotime(CURRENT_DATE), + "expires_at": utils.isotime(CURRENT_DATE), "issued_at": "2013-05-21T00:02:43.941473Z", } } diff --git a/keystone/tests/unit/test_v3_auth.py b/keystone/tests/unit/test_v3_auth.py index 280cbc0b48..6465d3ad93 100644 --- a/keystone/tests/unit/test_v3_auth.py +++ b/keystone/tests/unit/test_v3_auth.py @@ -28,6 +28,7 @@ from testtools import matchers from testtools import testcase from keystone import auth +from keystone.common import utils from keystone import exception from keystone.policy.backends import rules from keystone.tests import unit as tests @@ -1560,8 +1561,8 @@ class TestTokenRevokeApi(TestTokenRevokeById): expected_status=200).json_body['events'] self.assertEqual(2, len(events)) - future = timeutils.isotime(timeutils.utcnow() + - datetime.timedelta(seconds=1000)) + future = utils.isotime(timeutils.utcnow() + + datetime.timedelta(seconds=1000)) events = self.get('/OS-REVOKE/events?since=%s' % (future), expected_status=200).json_body['events'] @@ -3921,9 +3922,9 @@ class TestAuthContext(tests.TestCase): self.auth_context = auth.controllers.AuthContext() def test_pick_lowest_expires_at(self): - expires_at_1 = timeutils.isotime(timeutils.utcnow()) - expires_at_2 = timeutils.isotime(timeutils.utcnow() + - datetime.timedelta(seconds=10)) + expires_at_1 = utils.isotime(timeutils.utcnow()) + expires_at_2 = utils.isotime(timeutils.utcnow() + + datetime.timedelta(seconds=10)) # make sure auth_context picks the lowest value self.auth_context['expires_at'] = expires_at_1 self.auth_context['expires_at'] = expires_at_2 diff --git a/keystone/tests/unit/test_v3_os_revoke.py b/keystone/tests/unit/test_v3_os_revoke.py index 5710d973c9..48226cd41e 100644 --- a/keystone/tests/unit/test_v3_os_revoke.py +++ b/keystone/tests/unit/test_v3_os_revoke.py @@ -17,6 +17,7 @@ from oslo_utils import timeutils import six from testtools import matchers +from keystone.common import utils from keystone.contrib.revoke import model from keystone.tests.unit import test_v3 from keystone.token import provider @@ -25,7 +26,7 @@ from keystone.token import provider def _future_time_string(): expire_delta = datetime.timedelta(seconds=1000) future_time = timeutils.utcnow() + expire_delta - return timeutils.isotime(future_time) + return utils.isotime(future_time) class OSRevokeTests(test_v3.RestfulTestCase, test_v3.JsonHomeTestMixin): @@ -55,13 +56,13 @@ class OSRevokeTests(test_v3.RestfulTestCase, test_v3.JsonHomeTestMixin): self.assertTrue( before_time <= event_issued_before, 'invalid event issued_before time; %s is not later than %s.' % ( - timeutils.isotime(event_issued_before, subsecond=True), - timeutils.isotime(before_time, subsecond=True))) + utils.isotime(event_issued_before, subsecond=True), + utils.isotime(before_time, subsecond=True))) self.assertTrue( event_issued_before <= after_time, 'invalid event issued_before time; %s is not earlier than %s.' % ( - timeutils.isotime(event_issued_before, subsecond=True), - timeutils.isotime(after_time, subsecond=True))) + utils.isotime(event_issued_before, subsecond=True), + utils.isotime(after_time, subsecond=True))) del (event['issued_before']) self.assertEqual(sample, event) @@ -76,7 +77,7 @@ class OSRevokeTests(test_v3.RestfulTestCase, test_v3.JsonHomeTestMixin): expires_at = provider.default_expire_time() sample = self._blank_event() sample['user_id'] = six.text_type(user_id) - sample['expires_at'] = six.text_type(timeutils.isotime(expires_at)) + sample['expires_at'] = six.text_type(utils.isotime(expires_at)) before_time = timeutils.utcnow() self.revoke_api.revoke_by_expiration(user_id, expires_at) resp = self.get('/OS-REVOKE/events') diff --git a/keystone/tests/unit/token/test_fernet_provider.py b/keystone/tests/unit/token/test_fernet_provider.py index 3c2d32d0bd..0c98753464 100644 --- a/keystone/tests/unit/token/test_fernet_provider.py +++ b/keystone/tests/unit/token/test_fernet_provider.py @@ -16,6 +16,7 @@ import uuid from oslo_utils import timeutils from keystone.common import config +from keystone.common import utils from keystone import exception from keystone.tests import unit as tests from keystone.tests.unit import ksfixtures @@ -69,7 +70,7 @@ class TestPayloads(tests.TestCase): def test_time_string_to_int_conversions(self): payload_cls = token_formatters.BasePayload - expected_time_str = timeutils.isotime() + expected_time_str = utils.isotime() time_obj = timeutils.parse_isotime(expected_time_str) expected_time_int = ( (timeutils.normalize_time(time_obj) - @@ -86,7 +87,7 @@ class TestPayloads(tests.TestCase): def test_unscoped_payload(self): exp_user_id = uuid.uuid4().hex exp_methods = ['password'] - exp_expires_at = timeutils.isotime(timeutils.utcnow()) + exp_expires_at = utils.isotime(timeutils.utcnow()) exp_audit_ids = [provider.random_urlsafe_str()] payload = token_formatters.UnscopedPayload.assemble( @@ -104,7 +105,7 @@ class TestPayloads(tests.TestCase): exp_user_id = uuid.uuid4().hex exp_methods = ['password'] exp_project_id = uuid.uuid4().hex - exp_expires_at = timeutils.isotime(timeutils.utcnow()) + exp_expires_at = utils.isotime(timeutils.utcnow()) exp_audit_ids = [provider.random_urlsafe_str()] payload = token_formatters.ProjectScopedPayload.assemble( @@ -124,7 +125,7 @@ class TestPayloads(tests.TestCase): exp_user_id = uuid.uuid4().hex exp_methods = ['password'] exp_domain_id = uuid.uuid4().hex - exp_expires_at = timeutils.isotime(timeutils.utcnow()) + exp_expires_at = utils.isotime(timeutils.utcnow()) exp_audit_ids = [provider.random_urlsafe_str()] payload = token_formatters.DomainScopedPayload.assemble( @@ -144,7 +145,7 @@ class TestPayloads(tests.TestCase): exp_user_id = uuid.uuid4().hex exp_methods = ['password'] exp_domain_id = CONF.identity.default_domain_id - exp_expires_at = timeutils.isotime(timeutils.utcnow()) + exp_expires_at = utils.isotime(timeutils.utcnow()) exp_audit_ids = [provider.random_urlsafe_str()] payload = token_formatters.DomainScopedPayload.assemble( @@ -164,7 +165,7 @@ class TestPayloads(tests.TestCase): exp_user_id = uuid.uuid4().hex exp_methods = ['password'] exp_project_id = uuid.uuid4().hex - exp_expires_at = timeutils.isotime(timeutils.utcnow()) + exp_expires_at = utils.isotime(timeutils.utcnow()) exp_audit_ids = [provider.random_urlsafe_str()] exp_trust_id = uuid.uuid4().hex @@ -185,7 +186,7 @@ class TestPayloads(tests.TestCase): def test_unscoped_payload_with_non_uuid_user_id(self): exp_user_id = 'someNonUuidUserId' exp_methods = ['password'] - exp_expires_at = timeutils.isotime(timeutils.utcnow()) + exp_expires_at = utils.isotime(timeutils.utcnow()) exp_audit_ids = [provider.random_urlsafe_str()] payload = token_formatters.UnscopedPayload.assemble( @@ -203,7 +204,7 @@ class TestPayloads(tests.TestCase): exp_user_id = 'someNonUuidUserId' exp_methods = ['password'] exp_project_id = uuid.uuid4().hex - exp_expires_at = timeutils.isotime(timeutils.utcnow()) + exp_expires_at = utils.isotime(timeutils.utcnow()) exp_audit_ids = [provider.random_urlsafe_str()] payload = token_formatters.ProjectScopedPayload.assemble( @@ -223,7 +224,7 @@ class TestPayloads(tests.TestCase): exp_user_id = uuid.uuid4().hex exp_methods = ['password'] exp_project_id = 'someNonUuidProjectId' - exp_expires_at = timeutils.isotime(timeutils.utcnow()) + exp_expires_at = utils.isotime(timeutils.utcnow()) exp_audit_ids = [provider.random_urlsafe_str()] payload = token_formatters.ProjectScopedPayload.assemble( @@ -243,7 +244,7 @@ class TestPayloads(tests.TestCase): exp_user_id = 'someNonUuidUserId' exp_methods = ['password'] exp_domain_id = uuid.uuid4().hex - exp_expires_at = timeutils.isotime(timeutils.utcnow()) + exp_expires_at = utils.isotime(timeutils.utcnow()) exp_audit_ids = [provider.random_urlsafe_str()] payload = token_formatters.DomainScopedPayload.assemble( @@ -263,7 +264,7 @@ class TestPayloads(tests.TestCase): exp_user_id = 'someNonUuidUserId' exp_methods = ['password'] exp_project_id = uuid.uuid4().hex - exp_expires_at = timeutils.isotime(timeutils.utcnow()) + exp_expires_at = utils.isotime(timeutils.utcnow()) exp_audit_ids = [provider.random_urlsafe_str()] exp_trust_id = uuid.uuid4().hex @@ -285,7 +286,7 @@ class TestPayloads(tests.TestCase): exp_user_id = uuid.uuid4().hex exp_methods = ['password'] exp_project_id = 'someNonUuidProjectId' - exp_expires_at = timeutils.isotime(timeutils.utcnow()) + exp_expires_at = utils.isotime(timeutils.utcnow()) exp_audit_ids = [provider.random_urlsafe_str()] exp_trust_id = uuid.uuid4().hex @@ -306,7 +307,7 @@ class TestPayloads(tests.TestCase): def test_federated_payload_with_non_uuid_ids(self): exp_user_id = 'someNonUuidUserId' exp_methods = ['password'] - exp_expires_at = timeutils.isotime(timeutils.utcnow()) + exp_expires_at = utils.isotime(timeutils.utcnow()) exp_audit_ids = [provider.random_urlsafe_str()] exp_federated_info = {'group_ids': [{'id': 'someNonUuidGroupId'}], 'idp_id': uuid.uuid4().hex, diff --git a/keystone/token/controllers.py b/keystone/token/controllers.py index c0fdbfe153..80a94e0ae5 100644 --- a/keystone/token/controllers.py +++ b/keystone/token/controllers.py @@ -15,6 +15,7 @@ import datetime import sys +from keystone.common import utils from keystoneclient.common import cms from oslo_config import cfg from oslo_log import log @@ -205,7 +206,7 @@ class Auth(controller.V2Controller): raise exception.Forbidden() if ('expires' in trust_ref) and (trust_ref['expires']): expiry = trust_ref['expires'] - if expiry < timeutils.parse_isotime(timeutils.isotime()): + if expiry < timeutils.parse_isotime(utils.isotime()): raise exception.Forbidden() user_id = trust_ref['trustor_user_id'] trustor_user_ref = self.identity_api.get_user( @@ -463,7 +464,7 @@ class Auth(controller.V2Controller): for t in tokens: expires = t['expires'] if expires and isinstance(expires, datetime.datetime): - t['expires'] = timeutils.isotime(expires) + t['expires'] = utils.isotime(expires) data = {'revoked': tokens} json_data = jsonutils.dumps(data) signed_text = cms.cms_sign_text(json_data, diff --git a/keystone/token/persistence/backends/kvs.py b/keystone/token/persistence/backends/kvs.py index 9caf09a4a9..1bd08a3153 100644 --- a/keystone/token/persistence/backends/kvs.py +++ b/keystone/token/persistence/backends/kvs.py @@ -22,6 +22,7 @@ from oslo_utils import timeutils import six from keystone.common import kvs +from keystone.common import utils from keystone import exception from keystone.i18n import _, _LE, _LW from keystone import token @@ -106,7 +107,7 @@ class Token(token.persistence.Driver): # concern about the backend, always store the value(s) in the # index as the isotime (string) version so this is where the string is # built. - expires_str = timeutils.isotime(data_copy['expires'], subsecond=True) + expires_str = utils.isotime(data_copy['expires'], subsecond=True) self._set_key(ptk, data_copy) user_id = data['user']['id'] @@ -205,8 +206,8 @@ class Token(token.persistence.Driver): 'revocation list.'), data['id']) return - revoked_token_data['expires'] = timeutils.isotime(expires, - subsecond=True) + revoked_token_data['expires'] = utils.isotime(expires, + subsecond=True) revoked_token_data['id'] = data['id'] token_list = self._get_key_or_default(self.revocation_key, default=[]) diff --git a/keystone/token/providers/common.py b/keystone/token/providers/common.py index c0f0cfb39b..4152190796 100644 --- a/keystone/token/providers/common.py +++ b/keystone/token/providers/common.py @@ -21,6 +21,7 @@ from six.moves.urllib import parse from keystone.common import controller as common_controller from keystone.common import dependency +from keystone.common import utils from keystone.contrib import federation from keystone import exception from keystone.i18n import _, _LE @@ -99,7 +100,7 @@ class V2TokenDataHelper(object): expires = token_ref.get('expires', provider.default_expire_time()) if expires is not None: if not isinstance(expires, six.text_type): - expires = timeutils.isotime(expires) + expires = utils.isotime(expires) token_data = token_ref.get('token_data') if token_data: @@ -393,10 +394,10 @@ class V3TokenDataHelper(object): if not expires: expires = provider.default_expire_time() if not isinstance(expires, six.string_types): - expires = timeutils.isotime(expires, subsecond=True) + expires = utils.isotime(expires, subsecond=True) token_data['expires_at'] = expires token_data['issued_at'] = (issued_at or - timeutils.isotime(subsecond=True)) + utils.isotime(subsecond=True)) def _populate_audit_info(self, token_data, audit_info=None): if audit_info is None or isinstance(audit_info, six.string_types): diff --git a/keystone/token/providers/fernet/token_formatters.py b/keystone/token/providers/fernet/token_formatters.py index e953e9f8de..a4dba3f861 100644 --- a/keystone/token/providers/fernet/token_formatters.py +++ b/keystone/token/providers/fernet/token_formatters.py @@ -24,6 +24,7 @@ import six from six.moves import map, urllib from keystone.auth import plugins as auth_plugins +from keystone.common import utils as ks_utils from keystone import exception from keystone.i18n import _, _LI from keystone.token import provider @@ -204,9 +205,9 @@ class TokenFormatter(object): # rather than appearing in the payload, the creation time is encoded # into the token format itself created_at = TokenFormatter.creation_time(token) - created_at = timeutils.isotime(at=created_at, subsecond=True) + created_at = ks_utils.isotime(at=created_at, subsecond=True) expires_at = timeutils.parse_isotime(expires_at) - expires_at = timeutils.isotime(at=expires_at, subsecond=True) + expires_at = ks_utils.isotime(at=expires_at, subsecond=True) return (user_id, methods, audit_ids, domain_id, project_id, trust_id, federated_info, created_at, expires_at) @@ -285,7 +286,7 @@ class BasePayload(object): """ time_object = datetime.datetime.utcfromtimestamp(int(time_int)) - return timeutils.isotime(time_object) + return ks_utils.isotime(time_object) @classmethod def attempt_convert_uuid_hex_to_bytes(cls, value): diff --git a/keystone/trust/controllers.py b/keystone/trust/controllers.py index 05382056d9..605a1faee7 100644 --- a/keystone/trust/controllers.py +++ b/keystone/trust/controllers.py @@ -22,6 +22,7 @@ import six from keystone import assignment from keystone.common import controller from keystone.common import dependency +from keystone.common import utils from keystone.common import validation from keystone import exception from keystone.i18n import _ @@ -81,7 +82,7 @@ class TrustV3(controller.V3Controller): def _fill_in_roles(self, context, trust, all_roles): if trust.get('expires_at') is not None: - trust['expires_at'] = (timeutils.isotime + trust['expires_at'] = (utils.isotime (trust['expires_at'], subsecond=True)) @@ -243,7 +244,7 @@ class TrustV3(controller.V3Controller): if 'roles' in trust: del trust['roles'] if trust.get('expires_at') is not None: - trust['expires_at'] = (timeutils.isotime + trust['expires_at'] = (utils.isotime (trust['expires_at'], subsecond=True)) return TrustV3.wrap_collection(context, trusts)