Ensure tokens are added to both Trustor and Trustee indexes
Tokens are now added to both the Trustor and Trustee user-token-index so that bulk token revocations (e.g. password change) of the trustee will work as expected. This is a backport of the basic code that was used in the Icehouse-vintage Dogpile Token KVS backend that resolves this issue by merging the handling of memcache and KVS backends into the same logic. Change-Id: I3e19e4a8fc1e11cef6db51d364e80061e97befa7 Closes-Bug: #1260080
This commit is contained in:
parent
8fcc18c42b
commit
a411c944af
|
@ -62,6 +62,15 @@ class Token(token.Driver):
|
|||
return token_ref
|
||||
|
||||
def create_token(self, token_id, data):
|
||||
|
||||
def update_index(user_id, token_data):
|
||||
user_key = self._prefix_user_id(user_id)
|
||||
if not self.client.append(user_key, ',%s' % token_data):
|
||||
if not self.client.add(user_key, token_data):
|
||||
if not self.client.append(user_key, ',%s' % token_data):
|
||||
msg = _('Unable to add token user list.')
|
||||
raise exception.UnexpectedError(msg)
|
||||
|
||||
data_copy = copy.deepcopy(data)
|
||||
ptk = self._prefix_token_id(token.unique_id(token_id))
|
||||
if not data_copy.get('expires'):
|
||||
|
@ -73,15 +82,19 @@ class Token(token.Driver):
|
|||
expires_ts = utils.unixtime(data_copy['expires'])
|
||||
kwargs['time'] = expires_ts
|
||||
self.client.set(ptk, data_copy, **kwargs)
|
||||
if 'id' in data['user']:
|
||||
token_data = jsonutils.dumps(token_id)
|
||||
if 'id' in data['user']:
|
||||
user_id = data['user']['id']
|
||||
user_key = self._prefix_user_id(user_id)
|
||||
if not self.client.append(user_key, ',%s' % token_data):
|
||||
if not self.client.add(user_key, token_data):
|
||||
if not self.client.append(user_key, ',%s' % token_data):
|
||||
msg = _('Unable to add token user list.')
|
||||
raise exception.UnexpectedError(msg)
|
||||
update_index(user_id, token_data)
|
||||
|
||||
if CONF.trust.enabled and data.get('trust_id'):
|
||||
if 'access' in data_copy:
|
||||
trustee_user_id = data_copy['access']['trust'][
|
||||
'trustee_user_id']
|
||||
else:
|
||||
trustee_user_id = data_copy['OS-TRUST:trust'][
|
||||
'trustee_user_id']
|
||||
update_index(trustee_user_id, token_data)
|
||||
return copy.deepcopy(data_copy)
|
||||
|
||||
def _add_to_revocation_list(self, token_id, token_data):
|
||||
|
|
|
@ -2096,7 +2096,8 @@ class TokenTests(object):
|
|||
self.token_api.delete_token, token_id)
|
||||
|
||||
def create_token_sample_data(self, tenant_id=None, trust_id=None,
|
||||
user_id="testuserid"):
|
||||
user_id='testuserid',
|
||||
trustee_user_id='testuserid2'):
|
||||
token_id = self._create_token_id()
|
||||
data = {'id': token_id, 'a': 'b',
|
||||
'user': {'id': user_id}}
|
||||
|
@ -2104,6 +2105,11 @@ class TokenTests(object):
|
|||
data['tenant'] = {'id': tenant_id, 'name': tenant_id}
|
||||
if trust_id is not None:
|
||||
data['trust_id'] = trust_id
|
||||
data.setdefault('access', {}).setdefault('trust', {})
|
||||
# Testuserid2 is used here since a trustee will be different in
|
||||
# the cases of impersonation and therefore should not match the
|
||||
# token's user_id.
|
||||
data['access']['trust']['trustee_user_id'] = trustee_user_id
|
||||
self.token_api.create_token(token_id, data)
|
||||
return token_id
|
||||
|
||||
|
@ -2290,6 +2296,39 @@ class TokenTests(object):
|
|||
for t in self.token_api.list_revoked_tokens():
|
||||
self.assertIn('expires', t)
|
||||
|
||||
def test_token_in_trustee_and_trustor_token_list(self):
|
||||
self.opt_in_group('trust',
|
||||
enabled=True)
|
||||
trustor = self.user_foo
|
||||
trustee = self.user_two
|
||||
trust_id = uuid.uuid4().hex
|
||||
trust_info = {'trustor_user_id': trustor['id'],
|
||||
'trustee_user_id': trustee['id'],
|
||||
'project_id': self.tenant_bar['id'],
|
||||
'expires_at': timeutils.
|
||||
parse_isotime('2031-02-18T18:10:00Z'),
|
||||
'impersonation': True}
|
||||
self.trust_api.create_trust(trust_id, trust_info,
|
||||
roles=[{'id': 'member'},
|
||||
{'id': 'other'},
|
||||
{'id': 'browser'}])
|
||||
|
||||
token_id = self.create_token_sample_data(
|
||||
tenant_id=self.tenant_bar['id'],
|
||||
trust_id=trust_id,
|
||||
user_id=trustor['id'],
|
||||
trustee_user_id=trustee['id'])
|
||||
|
||||
# Ensure the token id exists in both the trustor and trustee token
|
||||
# lists
|
||||
|
||||
self.assertIn(token_id,
|
||||
self.token_api.list_tokens(self.user_two['id'],
|
||||
trust_id=trust_id))
|
||||
self.assertIn(token_id,
|
||||
self.token_api.list_tokens(self.user_foo['id'],
|
||||
trust_id=trust_id))
|
||||
|
||||
|
||||
class TrustTests(object):
|
||||
def create_sample_trust(self, new_id):
|
||||
|
|
|
@ -73,6 +73,8 @@ class KvsToken(test.TestCase, test_backend.TokenTests):
|
|||
def setUp(self):
|
||||
super(KvsToken, self).setUp()
|
||||
self.token_api = token_kvs.Token(db={})
|
||||
self.load_backends()
|
||||
self.load_fixtures(default_fixtures)
|
||||
|
||||
|
||||
class KvsTrust(test.TestCase, test_backend.TrustTests):
|
||||
|
|
|
@ -18,6 +18,7 @@ import uuid
|
|||
|
||||
import memcache
|
||||
|
||||
import default_fixtures
|
||||
from keystone.common import utils
|
||||
from keystone.openstack.common import timeutils
|
||||
from keystone import test
|
||||
|
@ -75,8 +76,10 @@ class MemcacheClient(object):
|
|||
class MemcacheToken(test.TestCase, test_backend.TokenTests):
|
||||
def setUp(self):
|
||||
super(MemcacheToken, self).setUp()
|
||||
self.load_backends()
|
||||
fake_client = MemcacheClient()
|
||||
self.token_api = token_memcache.Token(client=fake_client)
|
||||
self.load_fixtures(default_fixtures)
|
||||
|
||||
def test_create_unicode_token_id(self):
|
||||
token_id = unicode(self._create_token_id())
|
||||
|
|
Loading…
Reference in New Issue