Fix user email in federated shadow users
When the federated rule contains 'email' in user and we should set email for the federated user. Also, if the federated user changes the email info, it should be chenged too. Change-Id: Ib17172c34bd65d5236cbfc192b3a3f2b221411ef Closes-Bug: #1746599
This commit is contained in:
parent
e05e2b5a60
commit
475ea454ee
@ -237,9 +237,11 @@ def handle_unscoped_token(request, auth_payload, resource_api, federation_api,
|
||||
unique_id, display_name = (
|
||||
get_user_unique_id_and_display_name(request, mapped_properties)
|
||||
)
|
||||
email = mapped_properties['user'].get('email')
|
||||
user = identity_api.shadow_federated_user(identity_provider,
|
||||
protocol, unique_id,
|
||||
display_name)
|
||||
display_name,
|
||||
email)
|
||||
|
||||
if 'projects' in mapped_properties:
|
||||
idp_domain_id = federation_api.get_idp(
|
||||
|
@ -1412,13 +1412,14 @@ class Manager(manager.Manager):
|
||||
|
||||
@MEMOIZE
|
||||
def shadow_federated_user(self, idp_id, protocol_id, unique_id,
|
||||
display_name):
|
||||
display_name, email=None):
|
||||
"""Map a federated user to a user.
|
||||
|
||||
:param idp_id: identity provider id
|
||||
:param protocol_id: protocol id
|
||||
:param unique_id: unique id for the user within the IdP
|
||||
:param display_name: user's display name
|
||||
:param email: user's email
|
||||
|
||||
:returns: dictionary of the mapped User entity
|
||||
"""
|
||||
@ -1428,6 +1429,10 @@ class Manager(manager.Manager):
|
||||
idp_id, protocol_id, unique_id, display_name)
|
||||
user_dict = PROVIDERS.shadow_users_api.get_federated_user(
|
||||
idp_id, protocol_id, unique_id)
|
||||
if email:
|
||||
user_ref = {"email": email}
|
||||
self.update_user(user_dict['id'], user_ref)
|
||||
user_dict.update({"email": email})
|
||||
except exception.UserNotFound:
|
||||
idp = PROVIDERS.federation_api.get_idp(idp_id)
|
||||
federated_dict = {
|
||||
@ -1438,7 +1443,7 @@ class Manager(manager.Manager):
|
||||
}
|
||||
user_dict = (
|
||||
PROVIDERS.shadow_users_api.create_federated_user(
|
||||
idp['domain_id'], federated_dict
|
||||
idp['domain_id'], federated_dict, email=email
|
||||
)
|
||||
)
|
||||
PROVIDERS.shadow_users_api.set_last_active_at(user_dict['id'])
|
||||
|
@ -24,11 +24,12 @@ class ShadowUsersDriverBase(object):
|
||||
"""Interface description for an Shadow Users driver."""
|
||||
|
||||
@abc.abstractmethod
|
||||
def create_federated_user(self, domain_id, federated_dict):
|
||||
def create_federated_user(self, domain_id, federated_dict, email=None):
|
||||
"""Create a new user with the federated identity.
|
||||
|
||||
:param domain_id: The domain ID of the IdP used for the federated user
|
||||
:param dict federated_dict: Reference to the federated user
|
||||
:param email: Federated user's email
|
||||
:returns dict: Containing the user reference
|
||||
|
||||
"""
|
||||
|
@ -29,12 +29,14 @@ CONF = cfg.CONF
|
||||
|
||||
class ShadowUsers(base.ShadowUsersDriverBase):
|
||||
@sql.handle_conflicts(conflict_type='federated_user')
|
||||
def create_federated_user(self, domain_id, federated_dict):
|
||||
def create_federated_user(self, domain_id, federated_dict, email=None):
|
||||
user = {
|
||||
'id': uuid.uuid4().hex,
|
||||
'domain_id': domain_id,
|
||||
'enabled': True
|
||||
}
|
||||
if email:
|
||||
user['email'] = email
|
||||
with sql.session_for_write() as session:
|
||||
federated_ref = model.FederatedUser.from_dict(federated_dict)
|
||||
user_ref = model.User.from_dict(user)
|
||||
|
@ -83,6 +83,11 @@ class ShadowUsersBackendTests(object):
|
||||
self.domain_id, self.federated_user)
|
||||
self.assertEqual(user['domain_id'], self.domain_id)
|
||||
|
||||
def test_create_federated_user_email(self):
|
||||
user = PROVIDERS.shadow_users_api.create_federated_user(
|
||||
self.domain_id, self.federated_user, self.email)
|
||||
self.assertEqual(user['email'], self.email)
|
||||
|
||||
def test_get_federated_user(self):
|
||||
user_dict_create = PROVIDERS.shadow_users_api.create_federated_user(
|
||||
self.domain_id, self.federated_user)
|
||||
|
@ -23,9 +23,10 @@ class ShadowUsersCoreTests(object):
|
||||
self.federated_user['idp_id'],
|
||||
self.federated_user['protocol_id'],
|
||||
self.federated_user['unique_id'],
|
||||
self.federated_user['display_name'])
|
||||
self.federated_user['display_name'],
|
||||
self.email)
|
||||
self.assertIsNotNone(user['id'])
|
||||
self.assertEqual(6, len(user.keys()))
|
||||
self.assertEqual(7, len(user.keys()))
|
||||
self.assertIsNotNone(user['name'])
|
||||
self.assertIsNone(user['password_expires_at'])
|
||||
self.assertIsNotNone(user['domain_id'])
|
||||
@ -33,6 +34,7 @@ class ShadowUsersCoreTests(object):
|
||||
# equal True. assertTrue should not be used, because it converts
|
||||
# the passed value to bool().
|
||||
self.assertEqual(True, user['enabled'])
|
||||
self.assertIsNotNone(user['email'])
|
||||
|
||||
def test_shadow_existing_federated_user(self):
|
||||
|
||||
|
@ -47,6 +47,7 @@ class ShadowUsersTests(unit.TestCase,
|
||||
'unique_id': uuid.uuid4().hex,
|
||||
'display_name': uuid.uuid4().hex
|
||||
}
|
||||
self.email = uuid.uuid4().hex
|
||||
PROVIDERS.federation_api.create_idp(self.idp['id'], self.idp)
|
||||
PROVIDERS.federation_api.create_mapping(
|
||||
self.mapping['id'], self.mapping
|
||||
|
6
releasenotes/notes/bug-1746599-848a1163e52ac0a6.yaml
Normal file
6
releasenotes/notes/bug-1746599-848a1163e52ac0a6.yaml
Normal file
@ -0,0 +1,6 @@
|
||||
---
|
||||
fixes:
|
||||
- |
|
||||
[`bug 1746599 <https://bugs.launchpad.net/keystone/+bug/1746599>`_]
|
||||
Fixes user email being set for federated shadow users, when the rule
|
||||
contains email in user.
|
Loading…
x
Reference in New Issue
Block a user