Skip to content

Commit

Permalink
Implement Token Flush via keystone-manage.
Browse files Browse the repository at this point in the history
Creates a cli entry 'token_flush' which removes all expired tokens.

Fixes: bug 1032633
Implements: blueprint keystone-manage-token-flush
Change-Id: I47eab99b577ff9e9ee74fee08e18fd07c4af5aad
  • Loading branch information
Jamie Lennox committed May 21, 2013
1 parent 8d2b8e6 commit ff76a1b
Show file tree
Hide file tree
Showing 8 changed files with 78 additions and 0 deletions.
13 changes: 13 additions & 0 deletions doc/source/configuration.rst
Expand Up @@ -975,6 +975,19 @@ example::
$ keystone service-delete 08741d8ed88242ca88d1f61484a0fe3b



Removing Expired Tokens
===========================================================

In the SQL and KVS token stores expired tokens are not automatically
removed. These tokens can be removed with::

$ keystone-manage token_flush

The memcache backend automatically discards expired tokens and so flushing
is unnecessary and if attempted will fail with a NotImplemented error.


Configuring the LDAP Identity Provider
===========================================================

Expand Down
1 change: 1 addition & 0 deletions doc/source/man/keystone-manage.rst
Expand Up @@ -49,6 +49,7 @@ Available commands:
* ``import_nova_auth``: Import a dump of nova auth data into keystone.
* ``pki_setup``: Initialize the certificates used to sign tokens.
* ``ssl_setup``: Generate certificates for SSL.
* ``token_flush``: Purge expired tokens.


OPTIONS
Expand Down
13 changes: 13 additions & 0 deletions keystone/cli.py
Expand Up @@ -26,6 +26,7 @@
from keystone.openstack.common import importutils
from keystone.openstack.common import jsonutils
from keystone.openstack.common import version
from keystone import token

CONF = config.CONF

Expand Down Expand Up @@ -111,6 +112,17 @@ def main(cls):
conf_ssl.run()


class TokenFlush(BaseApp):
"""Flush expired tokens from the backend."""

name = 'token_flush'

@classmethod
def main(cls):
token_manager = token.Manager()
token_manager.driver.flush_expired_tokens()


class ImportLegacy(BaseApp):
"""Import a legacy database."""

Expand Down Expand Up @@ -173,6 +185,7 @@ def main():
ImportNovaAuth,
PKISetup,
SSLSetup,
TokenFlush,
]


Expand Down
6 changes: 6 additions & 0 deletions keystone/token/backends/kvs.py
Expand Up @@ -116,3 +116,9 @@ def list_revoked_tokens(self):
record['expires'] = token_ref['expires']
tokens.append(record)
return tokens

def flush_expired_tokens(self):
now = timeutils.utcnow()
for token, token_ref in self.db.items():
if self.is_expired(now, token_ref):
self.db.delete(token)
9 changes: 9 additions & 0 deletions keystone/token/backends/sql.py
Expand Up @@ -131,3 +131,12 @@ def list_revoked_tokens(self):
}
tokens.append(record)
return tokens

def flush_expired_tokens(self):
session = self.get_session()

query = session.query(TokenModel)
query = query.filter(TokenModel.expires < timeutils.utcnow())
query.delete(synchronize_session=False)

session.flush()
5 changes: 5 additions & 0 deletions keystone/token/core.py
Expand Up @@ -187,3 +187,8 @@ def list_revoked_tokens(self):
"""
raise exception.NotImplemented()

def flush_expired_tokens(self):
"""Archive or delete tokens that have expired.
"""
raise exception.NotImplemented()
26 changes: 26 additions & 0 deletions tests/test_backend.py
Expand Up @@ -2188,6 +2188,32 @@ def test_list_revoked_tokens_for_multiple_tokens(self):
self.check_list_revoked_tokens([self.delete_token()
for x in xrange(2)])

def test_flush_expired_token(self):
token_id = uuid.uuid4().hex
expire_time = timeutils.utcnow() - datetime.timedelta(minutes=1)
data = {'id_hash': token_id, 'id': token_id, 'a': 'b',
'expires': expire_time,
'trust_id': None,
'user': {'id': 'testuserid'}}
data_ref = self.token_api.create_token(token_id, data)
data_ref.pop('user_id')
self.assertDictEqual(data_ref, data)

token_id = uuid.uuid4().hex
expire_time = timeutils.utcnow() + datetime.timedelta(minutes=1)
data = {'id_hash': token_id, 'id': token_id, 'a': 'b',
'expires': expire_time,
'trust_id': None,
'user': {'id': 'testuserid'}}
data_ref = self.token_api.create_token(token_id, data)
data_ref.pop('user_id')
self.assertDictEqual(data_ref, data)

self.token_api.flush_expired_tokens()
tokens = self.token_api.list_tokens('testuserid')
self.assertEqual(len(tokens), 1)
self.assertIn(token_id, tokens)


class TrustTests(object):
def create_sample_trust(self, new_id):
Expand Down
5 changes: 5 additions & 0 deletions tests/test_backend_memcache.py
Expand Up @@ -19,6 +19,7 @@
import memcache

from keystone.common import utils
from keystone import exception
from keystone.openstack.common import timeutils
from keystone import test
from keystone.token.backends import memcache as token_memcache
Expand Down Expand Up @@ -96,3 +97,7 @@ def test_create_unicode_user_id(self):
def test_list_tokens_unicode_user_id(self):
user_id = unicode(uuid.uuid4().hex)
self.token_api.list_tokens(user_id)

def test_flush_expired_token(self):
with self.assertRaises(exception.NotImplemented):
self.token_api.flush_expired_tokens()

0 comments on commit ff76a1b

Please sign in to comment.