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 = (
|
unique_id, display_name = (
|
||||||
get_user_unique_id_and_display_name(request, mapped_properties)
|
get_user_unique_id_and_display_name(request, mapped_properties)
|
||||||
)
|
)
|
||||||
|
email = mapped_properties['user'].get('email')
|
||||||
user = identity_api.shadow_federated_user(identity_provider,
|
user = identity_api.shadow_federated_user(identity_provider,
|
||||||
protocol, unique_id,
|
protocol, unique_id,
|
||||||
display_name)
|
display_name,
|
||||||
|
email)
|
||||||
|
|
||||||
if 'projects' in mapped_properties:
|
if 'projects' in mapped_properties:
|
||||||
idp_domain_id = federation_api.get_idp(
|
idp_domain_id = federation_api.get_idp(
|
||||||
|
|
|
@ -1412,13 +1412,14 @@ class Manager(manager.Manager):
|
||||||
|
|
||||||
@MEMOIZE
|
@MEMOIZE
|
||||||
def shadow_federated_user(self, idp_id, protocol_id, unique_id,
|
def shadow_federated_user(self, idp_id, protocol_id, unique_id,
|
||||||
display_name):
|
display_name, email=None):
|
||||||
"""Map a federated user to a user.
|
"""Map a federated user to a user.
|
||||||
|
|
||||||
:param idp_id: identity provider id
|
:param idp_id: identity provider id
|
||||||
:param protocol_id: protocol id
|
:param protocol_id: protocol id
|
||||||
:param unique_id: unique id for the user within the IdP
|
:param unique_id: unique id for the user within the IdP
|
||||||
:param display_name: user's display name
|
:param display_name: user's display name
|
||||||
|
:param email: user's email
|
||||||
|
|
||||||
:returns: dictionary of the mapped User entity
|
:returns: dictionary of the mapped User entity
|
||||||
"""
|
"""
|
||||||
|
@ -1428,6 +1429,10 @@ class Manager(manager.Manager):
|
||||||
idp_id, protocol_id, unique_id, display_name)
|
idp_id, protocol_id, unique_id, display_name)
|
||||||
user_dict = PROVIDERS.shadow_users_api.get_federated_user(
|
user_dict = PROVIDERS.shadow_users_api.get_federated_user(
|
||||||
idp_id, protocol_id, unique_id)
|
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:
|
except exception.UserNotFound:
|
||||||
idp = PROVIDERS.federation_api.get_idp(idp_id)
|
idp = PROVIDERS.federation_api.get_idp(idp_id)
|
||||||
federated_dict = {
|
federated_dict = {
|
||||||
|
@ -1438,7 +1443,7 @@ class Manager(manager.Manager):
|
||||||
}
|
}
|
||||||
user_dict = (
|
user_dict = (
|
||||||
PROVIDERS.shadow_users_api.create_federated_user(
|
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'])
|
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."""
|
"""Interface description for an Shadow Users driver."""
|
||||||
|
|
||||||
@abc.abstractmethod
|
@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.
|
"""Create a new user with the federated identity.
|
||||||
|
|
||||||
:param domain_id: The domain ID of the IdP used for the federated user
|
:param domain_id: The domain ID of the IdP used for the federated user
|
||||||
:param dict federated_dict: Reference to the federated user
|
:param dict federated_dict: Reference to the federated user
|
||||||
|
:param email: Federated user's email
|
||||||
:returns dict: Containing the user reference
|
:returns dict: Containing the user reference
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -29,12 +29,14 @@ CONF = cfg.CONF
|
||||||
|
|
||||||
class ShadowUsers(base.ShadowUsersDriverBase):
|
class ShadowUsers(base.ShadowUsersDriverBase):
|
||||||
@sql.handle_conflicts(conflict_type='federated_user')
|
@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 = {
|
user = {
|
||||||
'id': uuid.uuid4().hex,
|
'id': uuid.uuid4().hex,
|
||||||
'domain_id': domain_id,
|
'domain_id': domain_id,
|
||||||
'enabled': True
|
'enabled': True
|
||||||
}
|
}
|
||||||
|
if email:
|
||||||
|
user['email'] = email
|
||||||
with sql.session_for_write() as session:
|
with sql.session_for_write() as session:
|
||||||
federated_ref = model.FederatedUser.from_dict(federated_dict)
|
federated_ref = model.FederatedUser.from_dict(federated_dict)
|
||||||
user_ref = model.User.from_dict(user)
|
user_ref = model.User.from_dict(user)
|
||||||
|
|
|
@ -83,6 +83,11 @@ class ShadowUsersBackendTests(object):
|
||||||
self.domain_id, self.federated_user)
|
self.domain_id, self.federated_user)
|
||||||
self.assertEqual(user['domain_id'], self.domain_id)
|
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):
|
def test_get_federated_user(self):
|
||||||
user_dict_create = PROVIDERS.shadow_users_api.create_federated_user(
|
user_dict_create = PROVIDERS.shadow_users_api.create_federated_user(
|
||||||
self.domain_id, self.federated_user)
|
self.domain_id, self.federated_user)
|
||||||
|
|
|
@ -23,9 +23,10 @@ class ShadowUsersCoreTests(object):
|
||||||
self.federated_user['idp_id'],
|
self.federated_user['idp_id'],
|
||||||
self.federated_user['protocol_id'],
|
self.federated_user['protocol_id'],
|
||||||
self.federated_user['unique_id'],
|
self.federated_user['unique_id'],
|
||||||
self.federated_user['display_name'])
|
self.federated_user['display_name'],
|
||||||
|
self.email)
|
||||||
self.assertIsNotNone(user['id'])
|
self.assertIsNotNone(user['id'])
|
||||||
self.assertEqual(6, len(user.keys()))
|
self.assertEqual(7, len(user.keys()))
|
||||||
self.assertIsNotNone(user['name'])
|
self.assertIsNotNone(user['name'])
|
||||||
self.assertIsNone(user['password_expires_at'])
|
self.assertIsNone(user['password_expires_at'])
|
||||||
self.assertIsNotNone(user['domain_id'])
|
self.assertIsNotNone(user['domain_id'])
|
||||||
|
@ -33,6 +34,7 @@ class ShadowUsersCoreTests(object):
|
||||||
# equal True. assertTrue should not be used, because it converts
|
# equal True. assertTrue should not be used, because it converts
|
||||||
# the passed value to bool().
|
# the passed value to bool().
|
||||||
self.assertEqual(True, user['enabled'])
|
self.assertEqual(True, user['enabled'])
|
||||||
|
self.assertIsNotNone(user['email'])
|
||||||
|
|
||||||
def test_shadow_existing_federated_user(self):
|
def test_shadow_existing_federated_user(self):
|
||||||
|
|
||||||
|
|
|
@ -47,6 +47,7 @@ class ShadowUsersTests(unit.TestCase,
|
||||||
'unique_id': uuid.uuid4().hex,
|
'unique_id': uuid.uuid4().hex,
|
||||||
'display_name': 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_idp(self.idp['id'], self.idp)
|
||||||
PROVIDERS.federation_api.create_mapping(
|
PROVIDERS.federation_api.create_mapping(
|
||||||
self.mapping['id'], self.mapping
|
self.mapping['id'], self.mapping
|
||||||
|
|
|
@ -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…
Reference in New Issue