Invalidate token cache on domain disablement

This will invalidate the token cache when a domain is disabled. As a result,
trust-scoped tokens that have a trustor or a trustee in a disabled domain will
have to rebuild the authorization context instead of just retrieving it from
the cache.

Change-Id: I3f6b528c64a07980422d82c8ab5b5d4f9b01485c
Closes-Bug: 1532280
This commit is contained in:
Lance Bragstad 2016-07-07 20:53:48 +00:00
parent abdc723a82
commit 81c9ddcd50
2 changed files with 10 additions and 54 deletions

View File

@ -29,6 +29,7 @@ from keystone.i18n import _, _LE, _LW
from keystone import notifications
from keystone.resource.backends import base
from keystone.resource.config_backends import base as config_base
from keystone.token import provider as token_provider
CONF = keystone.conf.CONF
LOG = log.getLogger(__name__)
@ -415,6 +416,15 @@ class Manager(manager.Manager):
# If the domain is being disabled, issue the disable
# notification as well
if original_project_enabled and not project_enabled:
# NOTE(lbragstad): When a domain is disabled, we have to
# invalidate the entire token cache. With persistent
# tokens, we did something similar where all tokens for a
# specific domain were deleted when that domain was
# disabled. This effectively offers the same behavior for
# non-persistent tokens by removing them from the cache and
# requiring the authorization context to be rebuilt the
# next time they're validated.
token_provider.TOKENS_REGION.invalidate()
notifications.Audit.disabled(self._DOMAIN, project_id,
public=False)

View File

@ -2479,60 +2479,6 @@ class TestFernetTokenAPIs(test_v3.RestfulTestCase, TokenAPITests,
self.v3_create_token(auth_data,
expected_status=http_client.NOT_IMPLEMENTED)
# FIXME(lbragstad): Remove this test from this class and inherit the
# version in TokenAPITest once bug 1532280 is fixed.
def test_trust_token_is_invalid_when_trustee_domain_disabled(self):
# Remove this once revocation for domains is handled properly
self.config_fixture.config(
group='cache',
enabled=False)
# create a new domain with new user in that domain
new_domain_ref = unit.new_domain_ref()
self.resource_api.create_domain(new_domain_ref['id'], new_domain_ref)
trustee_ref = unit.create_user(self.identity_api,
domain_id=new_domain_ref['id'])
new_project_ref = unit.new_project_ref(domain_id=self.domain_id)
self.resource_api.create_project(new_project_ref['id'],
new_project_ref)
# grant the trustor access to the new project
self.assignment_api.create_grant(
self.role['id'],
user_id=self.user_id,
project_id=new_project_ref['id'])
trust_ref = unit.new_trust_ref(trustor_user_id=self.user_id,
trustee_user_id=trustee_ref['id'],
expires=dict(minutes=1),
project_id=new_project_ref['id'],
impersonation=True,
role_ids=[self.role['id']])
resp = self.post('/OS-TRUST/trusts', body={'trust': trust_ref})
self.assertValidTrustResponse(resp, trust_ref)
trust_id = resp.json_body['trust']['id']
# get a project-scoped token using the trust
trust_auth_data = self.build_authentication_request(
user_id=trustee_ref['id'],
password=trustee_ref['password'],
trust_id=trust_id)
trust_scoped_token = self.get_requested_token(trust_auth_data)
# ensure the project-scoped token from the trust is valid
self._validate_token(trust_scoped_token)
disable_body = {'domain': {'enabled': False}}
self.patch(
'/domains/%(domain_id)s' % {'domain_id': new_domain_ref['id']},
body=disable_body)
# ensure the project-scoped token from the trust is invalid
self._validate_token(trust_scoped_token,
expected_status=http_client.NOT_FOUND)
class TestTokenRevokeSelfAndAdmin(test_v3.RestfulTestCase):
"""Test token revoke using v3 Identity API by token owner and admin."""