Fix list users by name
When attempting to filter users by name, it works for local users, but doesn't work for federated users. This patch fixed this error. Change-Id: I1bee51c2be81dbddd9d849731ab53728c86b2765 Closes-bug: #1738895
This commit is contained in:
parent
f4ac7b7a5f
commit
e7a4d43ece
@ -14,6 +14,7 @@
|
||||
|
||||
"""Main entry point into the Identity service."""
|
||||
|
||||
import copy
|
||||
import functools
|
||||
import itertools
|
||||
import operator
|
||||
@ -1025,12 +1026,23 @@ class Manager(manager.Manager):
|
||||
raise exception.InvalidOperatorError(op)
|
||||
return hints
|
||||
|
||||
def _handle_federated_attributes_in_hints(self, driver, hints):
|
||||
def _handle_shadow_and_local_users(self, driver, hints):
|
||||
federated_attributes = ['idp_id', 'protocol_id', 'unique_id']
|
||||
for filter_ in hints.filters:
|
||||
if filter_['name'] in federated_attributes:
|
||||
return PROVIDERS.shadow_users_api.get_federated_users(hints)
|
||||
return driver.list_users(hints)
|
||||
fed_hints = copy.deepcopy(hints)
|
||||
res = driver.list_users(hints)
|
||||
|
||||
# Note: If the filters contain 'name', we should get the user from both
|
||||
# local user and shadow user backend.
|
||||
for filter_ in fed_hints.filters:
|
||||
if filter_['name'] == 'name':
|
||||
fed_res = PROVIDERS.shadow_users_api.get_federated_users(
|
||||
fed_hints)
|
||||
res += fed_res
|
||||
break
|
||||
return res
|
||||
|
||||
@domains_configured
|
||||
@exception_translated('user')
|
||||
@ -1047,7 +1059,7 @@ class Manager(manager.Manager):
|
||||
# driver selection, so remove any such filter.
|
||||
self._mark_domain_id_filter_satisfied(hints)
|
||||
hints = self._translate_expired_password_hints(hints)
|
||||
ref_list = self._handle_federated_attributes_in_hints(driver, hints)
|
||||
ref_list = self._handle_shadow_and_local_users(driver, hints)
|
||||
return self._set_domain_id_and_mapping(
|
||||
ref_list, domain_scope, driver, mapping.EntityType.USER)
|
||||
|
||||
|
@ -67,9 +67,20 @@ class ShadowUsers(base.ShadowUsersDriverBase):
|
||||
|
||||
def get_federated_users(self, hints):
|
||||
with sql.session_for_read() as session:
|
||||
query = session.query(model.User).outerjoin(model.LocalUser)
|
||||
query = session.query(model.User).outerjoin(
|
||||
model.LocalUser).outerjoin(model.FederatedUser)
|
||||
query = query.filter(model.User.id == model.FederatedUser.user_id)
|
||||
query = self._update_query_with_federated_statements(hints, query)
|
||||
name_filter = None
|
||||
for filter_ in hints.filters:
|
||||
if filter_['name'] == 'name':
|
||||
name_filter = filter_
|
||||
query = query.filter(
|
||||
model.FederatedUser.display_name == name_filter[
|
||||
'value'])
|
||||
break
|
||||
if name_filter:
|
||||
hints.filters.remove(name_filter)
|
||||
user_refs = sql.filter_limit_query(model.User, query, hints)
|
||||
return [identity_base.filter_user(x.to_dict()) for x in user_refs]
|
||||
|
||||
|
@ -529,6 +529,29 @@ class IdentityTests(object):
|
||||
filters = ['unique_id', 'idp_id', 'protocol_id']
|
||||
self._test_list_users_with_attribute(filters, federated_dict)
|
||||
|
||||
def test_list_users_with_name(self):
|
||||
federated_dict = unit.new_federated_user_ref(
|
||||
display_name='test@federation.org')
|
||||
domain = self._get_domain_fixture()
|
||||
|
||||
hints = driver_hints.Hints()
|
||||
hints.add_filter('name', 'test@federation.org')
|
||||
users = self.identity_api.list_users(hints=hints)
|
||||
self.assertEqual(0, len(users))
|
||||
|
||||
self.shadow_users_api.create_federated_user(domain['id'],
|
||||
federated_dict)
|
||||
hints = driver_hints.Hints()
|
||||
hints.add_filter('name', 'test@federation.org')
|
||||
users = self.identity_api.list_users(hints=hints)
|
||||
self.assertEqual(1, len(users))
|
||||
|
||||
hints = driver_hints.Hints()
|
||||
hints.add_filter('name', 'test@federation.org')
|
||||
hints.add_filter('idp_id', 'ORG_IDP')
|
||||
users = self.identity_api.list_users(hints=hints)
|
||||
self.assertEqual(1, len(users))
|
||||
|
||||
def test_list_groups(self):
|
||||
group1 = unit.new_group_ref(domain_id=CONF.identity.default_domain_id)
|
||||
group2 = unit.new_group_ref(domain_id=CONF.identity.default_domain_id)
|
||||
|
7
releasenotes/notes/bug-1738895-342864cd0285bc42.yaml
Normal file
7
releasenotes/notes/bug-1738895-342864cd0285bc42.yaml
Normal file
@ -0,0 +1,7 @@
|
||||
---
|
||||
fixes:
|
||||
- |
|
||||
[`bug 1738895 <https://bugs.launchpad.net/keystone/+bug/1738895>`_]
|
||||
Fixed the bug that federated users can't be listed by `name` filter. Now
|
||||
when list users by `name`, Keystone will query both local user backend and
|
||||
shadow user backend.
|
Loading…
Reference in New Issue
Block a user