summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLance Bragstad <lbragstad@gmail.com>2017-08-08 20:31:26 +0000
committerLance Bragstad <lbragstad@gmail.com>2017-08-10 19:35:51 +0000
commitd0ad287df397513dd7cb8dd4da0cae383c6b49b0 (patch)
tree7968cdfeb3da213f08066ff36a820b68b691a80b
parent6167850d12f93c030bc3b53b2ca74d9975ff303e (diff)
downloadkeystone-d0ad287df397513dd7cb8dd4da0cae383c6b49b0.tar.gz
Unset project ids for all identity backends
Previously, the default behavior for the callback that unset default project ids was to only call the method for the default domain's identity driver. This meant that when a project was deleted, only the default identity backend would have references to that project removed. This means it would be possible for other identity backends to still have references to a project that doesn't exist because the callback wasn't invoked for that specific backend. This commit ensures each backend clears project id from a user's default_project_id attribute when a project is deleted. Change-Id: Ibb5396f20101a3956fa91d6ff68155d4c00ab0f9 Closes-Bug: 1705072
-rw-r--r--keystone/identity/core.py23
-rw-r--r--keystone/tests/unit/test_backend_ldap.py14
2 files changed, 28 insertions, 9 deletions
diff --git a/keystone/identity/core.py b/keystone/identity/core.py
index afa397ba2..b53d269aa 100644
--- a/keystone/identity/core.py
+++ b/keystone/identity/core.py
@@ -15,6 +15,7 @@
"""Main entry point into the Identity service."""
import functools
+import itertools
import operator
import os
import threading
@@ -530,15 +531,19 @@ class Manager(manager.Manager):
"""
project_id = payload['resource_info']
- try:
- self.driver.unset_default_project_id(project_id)
- except exception.Forbidden:
- # NOTE(lbragstad): If the driver throws a Forbidden, it's because
- # the driver doesn't support writes. This is the case with the
- # in-tree LDAP implementation since it is read-only. This also
- # ensures consistency for out-of-tree backends that might be
- # read-only.
- pass
+ drivers = itertools.chain(
+ self.domain_configs.values(), [{'driver': self.driver}]
+ )
+ for d in drivers:
+ try:
+ d['driver'].unset_default_project_id(project_id)
+ except exception.Forbidden:
+ # NOTE(lbragstad): If the driver throws a Forbidden, it's
+ # because the driver doesn't support writes. This is the case
+ # with the in-tree LDAP implementation since it is read-only.
+ # This also ensures consistency for out-of-tree backends that
+ # might be read-only.
+ pass
# Domain ID normalization methods
def _set_domain_id_and_mapping(self, ref, domain_id, driver,
diff --git a/keystone/tests/unit/test_backend_ldap.py b/keystone/tests/unit/test_backend_ldap.py
index a553504c7..ddf8852a5 100644
--- a/keystone/tests/unit/test_backend_ldap.py
+++ b/keystone/tests/unit/test_backend_ldap.py
@@ -33,6 +33,7 @@ from keystone import exception
from keystone import identity
from keystone.identity.backends import ldap as ldap_identity
from keystone.identity.backends.ldap import common as common_ldap
+from keystone.identity.backends import sql as sql_identity
from keystone.identity.mapping_backends import mapping as map
from keystone.tests import unit
from keystone.tests.unit.assignment import test_backends as assignment_tests
@@ -2500,6 +2501,19 @@ class MultiLDAPandSQLIdentity(BaseLDAPIdentity, unit.SQLDriverOverrides,
base = super(BaseLDAPIdentity, self)
base.test_remove_foreign_assignments_when_deleting_a_domain()
+ @mock.patch.object(ldap_identity.Identity, 'unset_default_project_id')
+ @mock.patch.object(sql_identity.Identity, 'unset_default_project_id')
+ def test_delete_project_unset_project_ids_for_all_backends(self, sql_mock,
+ ldap_mock):
+ ldap_mock.side_effect = exception.Forbidden
+ project = unit.new_project_ref(
+ domain_id=CONF.identity.default_domain_id
+ )
+ project = self.resource_api.create_project(project['id'], project)
+ self.resource_api.delete_project(project['id'])
+ ldap_mock.assert_called_with(project['id'])
+ sql_mock.assert_called_with(project['id'])
+
class MultiLDAPandSQLIdentityDomainConfigsInSQL(MultiLDAPandSQLIdentity):
"""Class to test the use of domain configs stored in the database.