Return `revoked_at` for list revoke events

The field will help to figure out when the event is recorded, and thus
give a clue on when the revocation was done.

Change-Id: If5ba3bb9b68fff5f35be2b57af15584d69c6df8d
Closes-Bug: #1598040
This commit is contained in:
Dave Chen 2016-07-01 16:40:18 +08:00
parent a6b0552dd3
commit 25e5227d23
3 changed files with 35 additions and 0 deletions

View File

@ -118,6 +118,9 @@ class RevokeEvent(object):
if self.issued_before is not None:
event['issued_before'] = utils.isotime(self.issued_before,
subsecond=True)
if self.revoked_at is not None:
event['revoked_at'] = utils.isotime(self.revoked_at,
subsecond=True)
return event
def key_for_name(self, name):

View File

@ -3342,6 +3342,7 @@ class TestTokenRevokeApi(TestTokenRevokeById):
self.assertIsNotNone(events[0]['issued_before'])
self.assertIsNotNone(events_response['links'])
del (events_response['events'][0]['issued_before'])
del (events_response['events'][0]['revoked_at'])
del (events_response['links'])
expected_response = {'events': [{'project_id': project_id}]}
self.assertEqual(expected_response, events_response)
@ -3356,6 +3357,8 @@ class TestTokenRevokeApi(TestTokenRevokeById):
self.assertIsNotNone(events_response['links'])
del (events_response['events'][0]['issued_before'])
del (events_response['events'][1]['issued_before'])
del (events_response['events'][0]['revoked_at'])
del (events_response['events'][1]['revoked_at'])
del (events_response['links'])
expected_response = {'events': [{'project_id': domain_id},
{'domain_id': domain_id}]}
@ -3369,6 +3372,7 @@ class TestTokenRevokeApi(TestTokenRevokeById):
self.assertIsNotNone(events[0]['issued_before'])
self.assertIsNotNone(events_response['links'])
del (events_response['events'][0]['issued_before'])
del (events_response['events'][0]['revoked_at'])
del (events_response['links'])
expected_response = {'events': [kwargs]}

View File

@ -38,6 +38,20 @@ class OSRevokeTests(test_v3.RestfulTestCase, test_v3.JsonHomeTestMixin):
},
}
# TODO(davechen): This method is copied from `keystone.tests.unit.
# test_v3_auth.TokenAPITests`, move this method into utils.py to avoid
# the duplication?
def assertTimestampEqual(self, expected, value):
# Compare two timestamps but ignore the microseconds part
# of the expected timestamp. Keystone does not track microseconds and
# is working to eliminate microseconds from it's datetimes used.
expected = timeutils.parse_isotime(expected).replace(microsecond=0)
value = timeutils.parse_isotime(value).replace(microsecond=0)
self.assertEqual(
expected,
value,
"%s != %s" % (expected, value))
def test_get_empty_list(self):
resp = self.get('/OS-REVOKE/events')
self.assertEqual([], resp.json_body['events'])
@ -62,6 +76,7 @@ class OSRevokeTests(test_v3.RestfulTestCase, test_v3.JsonHomeTestMixin):
utils.isotime(event_issued_before, subsecond=True),
utils.isotime(after_time, subsecond=True)))
del (event['issued_before'])
del (event['revoked_at'])
self.assertEqual(sample, event)
def test_revoked_list_self_url(self):
@ -131,3 +146,16 @@ class OSRevokeTests(test_v3.RestfulTestCase, test_v3.JsonHomeTestMixin):
resp = self.get('/OS-REVOKE/events?since=%s' % _future_time_string())
events = resp.json_body['events']
self.assertEqual([], events)
def test_revoked_at_in_list(self):
revoked_at = timeutils.utcnow()
# Given or not, `revoked_at` will always be set in the backend.
self.revoke_api.revoke(
revoke_model.RevokeEvent(revoked_at=revoked_at))
resp = self.get('/OS-REVOKE/events')
events = resp.json_body['events']
self.assertThat(events, matchers.HasLength(1))
# Strip off the microseconds from `revoked_at`.
self.assertTimestampEqual(utils.isotime(revoked_at),
events[0]['revoked_at'])