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
This commit is contained in:
parent
6167850d12
commit
d0ad287df3
@ -15,6 +15,7 @@
|
|||||||
"""Main entry point into the Identity service."""
|
"""Main entry point into the Identity service."""
|
||||||
|
|
||||||
import functools
|
import functools
|
||||||
|
import itertools
|
||||||
import operator
|
import operator
|
||||||
import os
|
import os
|
||||||
import threading
|
import threading
|
||||||
@ -530,15 +531,19 @@ class Manager(manager.Manager):
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
project_id = payload['resource_info']
|
project_id = payload['resource_info']
|
||||||
try:
|
drivers = itertools.chain(
|
||||||
self.driver.unset_default_project_id(project_id)
|
self.domain_configs.values(), [{'driver': self.driver}]
|
||||||
except exception.Forbidden:
|
)
|
||||||
# NOTE(lbragstad): If the driver throws a Forbidden, it's because
|
for d in drivers:
|
||||||
# the driver doesn't support writes. This is the case with the
|
try:
|
||||||
# in-tree LDAP implementation since it is read-only. This also
|
d['driver'].unset_default_project_id(project_id)
|
||||||
# ensures consistency for out-of-tree backends that might be
|
except exception.Forbidden:
|
||||||
# read-only.
|
# NOTE(lbragstad): If the driver throws a Forbidden, it's
|
||||||
pass
|
# 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
|
# Domain ID normalization methods
|
||||||
def _set_domain_id_and_mapping(self, ref, domain_id, driver,
|
def _set_domain_id_and_mapping(self, ref, domain_id, driver,
|
||||||
|
@ -33,6 +33,7 @@ from keystone import exception
|
|||||||
from keystone import identity
|
from keystone import identity
|
||||||
from keystone.identity.backends import ldap as ldap_identity
|
from keystone.identity.backends import ldap as ldap_identity
|
||||||
from keystone.identity.backends.ldap import common as common_ldap
|
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.identity.mapping_backends import mapping as map
|
||||||
from keystone.tests import unit
|
from keystone.tests import unit
|
||||||
from keystone.tests.unit.assignment import test_backends as assignment_tests
|
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 = super(BaseLDAPIdentity, self)
|
||||||
base.test_remove_foreign_assignments_when_deleting_a_domain()
|
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 MultiLDAPandSQLIdentityDomainConfigsInSQL(MultiLDAPandSQLIdentity):
|
||||||
"""Class to test the use of domain configs stored in the database.
|
"""Class to test the use of domain configs stored in the database.
|
||||||
|
Loading…
Reference in New Issue
Block a user