summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJenkins <jenkins@review.openstack.org>2015-08-20 11:13:07 +0000
committerGerrit Code Review <review@openstack.org>2015-08-20 11:13:07 +0000
commitec59d49e5f4941fe1d5f08f3b4870ea601910128 (patch)
tree6a2d66daf6620edf0f509368f62fd0171009dcd4
parent4c6695b00a3ca062e060e2d52868f8bca372c54c (diff)
parentaa3354e73bda53bbe8c354b644ed37e8b100a7d8 (diff)
downloadkeystone-ec59d49e5f4941fe1d5f08f3b4870ea601910128.tar.gz
Merge "Fernet 'expires' value loses 'ms' after validation" into stable/kilo
-rw-r--r--keystone/tests/unit/test_v3_auth.py20
-rw-r--r--keystone/tests/unit/token/test_fernet_provider.py26
-rw-r--r--keystone/token/providers/fernet/core.py18
-rw-r--r--keystone/token/providers/fernet/token_formatters.py4
4 files changed, 35 insertions, 33 deletions
diff --git a/keystone/tests/unit/test_v3_auth.py b/keystone/tests/unit/test_v3_auth.py
index 3d20e0e14..dd272f5f7 100644
--- a/keystone/tests/unit/test_v3_auth.py
+++ b/keystone/tests/unit/test_v3_auth.py
@@ -267,8 +267,8 @@ class TokenAPITests(object):
# just need to make sure the non fraction part agrees
self.assertIn(v2_token['access']['token']['expires'][:-1],
token_data['token']['expires_at'])
- self.assertEqual(v2_token['access']['user']['roles'][0]['id'],
- token_data['token']['roles'][0]['id'])
+ self.assertEqual(v2_token['access']['user']['roles'][0]['name'],
+ token_data['token']['roles'][0]['name'])
def test_v2_v3_unscoped_token_intermix(self):
body = {
@@ -540,22 +540,6 @@ class TestFernetTokenAPIs(test_v3.RestfulTestCase, TokenAPITests):
super(TestFernetTokenAPIs, self).setUp()
self.doSetUp()
- @test_utils.wip('Failing due to bug 1459790.')
- def test_v3_v2_token_intermix(self):
- super(TestFernetTokenAPIs, self).test_v3_v2_token_intermix()
-
- @test_utils.wip('Failing due to bug 1459790.')
- def test_v3_v2_unscoped_token_intermix(self):
- super(TestFernetTokenAPIs, self).test_v3_v2_unscoped_token_intermix()
-
- @test_utils.wip('Failing due to bug 1459790.')
- def test_v2_v3_token_intermix(self):
- super(TestFernetTokenAPIs, self).test_v2_v3_token_intermix()
-
- @test_utils.wip('Failing due to bug 1459790.')
- def test_rescoping_token(self):
- super(TestFernetTokenAPIs, self).test_rescoping_token()
-
@test_utils.wip('Failing due to bug 1475762.')
def test_v3_v2_intermix_non_default_project_failed(self):
super(TestFernetTokenAPIs,
diff --git a/keystone/tests/unit/token/test_fernet_provider.py b/keystone/tests/unit/token/test_fernet_provider.py
index 2c62e6c53..7ab983484 100644
--- a/keystone/tests/unit/token/test_fernet_provider.py
+++ b/keystone/tests/unit/token/test_fernet_provider.py
@@ -75,7 +75,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 = timeutils.isotime(subsecond=True)
time_obj = timeutils.parse_isotime(expected_time_str)
expected_time_int = (
(timeutils.normalize_time(time_obj) -
@@ -92,7 +92,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 = timeutils.isotime(timeutils.utcnow(), subsecond=True)
exp_audit_ids = [provider.random_urlsafe_str()]
payload = token_formatters.UnscopedPayload.assemble(
@@ -110,7 +110,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 = timeutils.isotime(timeutils.utcnow(), subsecond=True)
exp_audit_ids = [provider.random_urlsafe_str()]
payload = token_formatters.ProjectScopedPayload.assemble(
@@ -130,7 +130,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 = timeutils.isotime(timeutils.utcnow(), subsecond=True)
exp_audit_ids = [provider.random_urlsafe_str()]
payload = token_formatters.DomainScopedPayload.assemble(
@@ -150,7 +150,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 = timeutils.isotime(timeutils.utcnow(), subsecond=True)
exp_audit_ids = [provider.random_urlsafe_str()]
payload = token_formatters.DomainScopedPayload.assemble(
@@ -170,7 +170,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 = timeutils.isotime(timeutils.utcnow(), subsecond=True)
exp_audit_ids = [provider.random_urlsafe_str()]
exp_trust_id = uuid.uuid4().hex
@@ -191,7 +191,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 = timeutils.isotime(timeutils.utcnow(), subsecond=True)
exp_audit_ids = [provider.random_urlsafe_str()]
payload = token_formatters.UnscopedPayload.assemble(
@@ -209,7 +209,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 = timeutils.isotime(timeutils.utcnow(), subsecond=True)
exp_audit_ids = [provider.random_urlsafe_str()]
payload = token_formatters.ProjectScopedPayload.assemble(
@@ -229,7 +229,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 = timeutils.isotime(timeutils.utcnow(), subsecond=True)
exp_audit_ids = [provider.random_urlsafe_str()]
payload = token_formatters.ProjectScopedPayload.assemble(
@@ -249,7 +249,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 = timeutils.isotime(timeutils.utcnow(), subsecond=True)
exp_audit_ids = [provider.random_urlsafe_str()]
payload = token_formatters.DomainScopedPayload.assemble(
@@ -269,7 +269,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 = timeutils.isotime(timeutils.utcnow(), subsecond=True)
exp_audit_ids = [provider.random_urlsafe_str()]
exp_trust_id = uuid.uuid4().hex
@@ -291,7 +291,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 = timeutils.isotime(timeutils.utcnow(), subsecond=True)
exp_audit_ids = [provider.random_urlsafe_str()]
exp_trust_id = uuid.uuid4().hex
@@ -312,7 +312,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 = timeutils.isotime(timeutils.utcnow(), subsecond=True)
exp_audit_ids = [provider.random_urlsafe_str()]
exp_federated_info = {'group_ids': [{'id': 'someNonUuidGroupId'}],
'idp_id': uuid.uuid4().hex,
diff --git a/keystone/token/providers/fernet/core.py b/keystone/token/providers/fernet/core.py
index 722ec606c..3f06f05a1 100644
--- a/keystone/token/providers/fernet/core.py
+++ b/keystone/token/providers/fernet/core.py
@@ -12,6 +12,7 @@
from oslo_config import cfg
from oslo_log import log
+from oslo_utils import timeutils
from keystone.common import dependency
from keystone.contrib import federation
@@ -87,12 +88,28 @@ class Provider(common.BaseProvider):
audit_ids,
methods=method_names,
project_id=project_id)
+ self._build_issued_at_info(token_id, v3_token_data)
# Convert v3 to v2 token data and build v2 catalog
token_data = self.v2_token_data_helper.v3_to_v2_token(token_id,
v3_token_data)
return token_id, token_data
+ def _build_issued_at_info(self, token_id, token_data):
+ # NOTE(roxanaghe, lbragstad): We must use the creation time that
+ # Fernet builds into it's token. The Fernet spec details that the
+ # token creation time is built into the token, outside of the payload
+ # provided by Keystone. This is the reason why we don't pass the
+ # issued_at time in the payload. This also means that we shouldn't
+ # return a token reference with a creation time that we created
+ # when Fernet uses a different creation time. We should use the
+ # creation time provided by Fernet because it's the creation time
+ # that we have to rely on when we validate the token.
+ fernet_creation_datetime_obj = self.token_formatter.creation_time(
+ token_id)
+ token_data['token']['issued_at'] = timeutils.isotime(
+ at=fernet_creation_datetime_obj, subsecond=True)
+
def _build_federated_info(self, token_data):
"""Extract everything needed for federated tokens.
@@ -195,6 +212,7 @@ class Provider(common.BaseProvider):
project_id=project_id,
trust_id=token_data['token'].get('OS-TRUST:trust', {}).get('id'),
federated_info=federated_dict)
+ self._build_issued_at_info(token, token_data)
return token, token_data
def validate_v2_token(self, token_ref):
diff --git a/keystone/token/providers/fernet/token_formatters.py b/keystone/token/providers/fernet/token_formatters.py
index f7399220a..2fbebb3ec 100644
--- a/keystone/token/providers/fernet/token_formatters.py
+++ b/keystone/token/providers/fernet/token_formatters.py
@@ -274,8 +274,8 @@ class BasePayload(object):
:returns: a time formatted strings
"""
- time_object = datetime.datetime.utcfromtimestamp(int(time_int))
- return timeutils.isotime(time_object)
+ time_object = datetime.datetime.utcfromtimestamp(time_int)
+ return timeutils.isotime(time_object, subsecond=True)
@classmethod
def attempt_convert_uuid_hex_to_bytes(cls, value):