summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGage Hugo <gagehugo@gmail.com>2019-12-13 14:25:28 -0600
committerKristi Nikolla <knikolla@icloud.com>2020-02-20 01:42:35 +0000
commit615fe2138de409356c34f17312e618b8c9b5cce3 (patch)
treef7724a4fb446c98c3201d2a9cba68b74b9381e07
parentf2f79a9a643a550c07b3eaee54074822e2d2eece (diff)
downloadkeystone-615fe2138de409356c34f17312e618b8c9b5cce3.tar.gz
Always have username in CADF initiator
The current initiator object for CADF notifications does not include the username of the user who initiated the action, which leads to issues when using an LDAP backend and not having a direct way to map a username to a user id. This change makes it so that the initiator object for CADF notifications always contains the username for a user as well as the user id. This follows along with the CADF standard for OpenStack[0]. [0] https://www.dmtf.org/sites/default/files/standards/documents/DSP2038_1.1.0.pdf#page=12 Closes-Bug: #1856904 Change-Id: I833e6e0d7792acf49f816050ad7a63e8ea4f702f (cherry picked from commit 95edaaab06c6da761411ef97bc2545d86d579215)
-rw-r--r--keystone/notifications.py18
-rw-r--r--keystone/tests/unit/common/test_notifications.py13
-rw-r--r--releasenotes/notes/bug-1856904-101af15bb48eb3ca.yaml9
3 files changed, 39 insertions, 1 deletions
diff --git a/keystone/notifications.py b/keystone/notifications.py
index 3f59d151e..a4312b44f 100644
--- a/keystone/notifications.py
+++ b/keystone/notifications.py
@@ -73,6 +73,7 @@ SAML_AUDIT_TYPE = 'http://docs.oasis-open.org/security/saml/v2.0'
_SUBSCRIBERS = {}
_notifier = None
SERVICE = 'identity'
+PROVIDERS = provider_api.ProviderAPIs
ROOT_DOMAIN = '<<keystone.domain.root>>'
@@ -528,6 +529,7 @@ def _get_request_audit_info(context, user_id=None):
if user_id:
initiator.user_id = user_id
initiator.id = utils.resource_uuid(user_id)
+ initiator = _add_username_to_initiator(initiator)
if project_id:
initiator.project_id = project_id
@@ -564,6 +566,7 @@ class CadfNotificationWrapper(object):
target = resource.Resource(typeURI=taxonomy.ACCOUNT_USER)
initiator = build_audit_initiator()
initiator.user_id = user_id
+ initiator = _add_username_to_initiator(initiator)
initiator.id = utils.resource_uuid(user_id)
try:
result = f(wrapped_self, user_id, *args, **kwargs)
@@ -762,6 +765,8 @@ def _send_audit_notification(action, initiator, outcome, target,
service_id = i['id']
break
+ initiator = _add_username_to_initiator(initiator)
+
event = eventfactory.EventFactory().new_event(
eventType=cadftype.EVENTTYPE_ACTIVITY,
outcome=outcome,
@@ -819,6 +824,19 @@ def _check_notification_opt_out(event_type, outcome):
return False
+def _add_username_to_initiator(initiator):
+ """Add the username to the initiator if missing."""
+ if hasattr(initiator, 'username'):
+ return initiator
+ try:
+ user_ref = PROVIDERS.identity_api.get_user(initiator.user_id)
+ initiator.username = user_ref['name']
+ except (exception.UserNotFound, AttributeError):
+ # Either user not found or no user_id, move along
+ pass
+
+ return initiator
+
emit_event = CadfNotificationWrapper
diff --git a/keystone/tests/unit/common/test_notifications.py b/keystone/tests/unit/common/test_notifications.py
index ec3ba54cd..636abfa3b 100644
--- a/keystone/tests/unit/common/test_notifications.py
+++ b/keystone/tests/unit/common/test_notifications.py
@@ -1156,7 +1156,7 @@ class CadfNotificationsWrapperTestCase(test_v3.RestfulTestCase):
'typeURI': 'service/security/account/user',
'host': {'address': 'localhost'},
'id': 'openstack:0a90d95d-582c-4efb-9cbc-e2ca7ca9c341',
- 'name': u'bccc2d9bfc2a46fd9e33bcf82f0b5c21'
+ 'username': u'admin'
},
'target': {
'typeURI': 'service/security/account/user',
@@ -1202,6 +1202,17 @@ class CadfNotificationsWrapperTestCase(test_v3.RestfulTestCase):
self.assertEqual(self.user_id, initiator.id)
self.assertEqual(self.user_id, initiator.user_id)
+ def test_initiator_always_contains_username(self):
+ # Clear notifications
+ while self._notifications:
+ self._notifications.pop()
+
+ self.get_scoped_token()
+ self.assertEqual(len(self._notifications), 1)
+ note = self._notifications.pop()
+ initiator = note['initiator']
+ self.assertEqual(self.user['name'], initiator.username)
+
def test_v3_authenticate_user_name_and_domain_id(self):
user_id = self.user_id
user_name = self.user['name']
diff --git a/releasenotes/notes/bug-1856904-101af15bb48eb3ca.yaml b/releasenotes/notes/bug-1856904-101af15bb48eb3ca.yaml
new file mode 100644
index 000000000..634b86a03
--- /dev/null
+++ b/releasenotes/notes/bug-1856904-101af15bb48eb3ca.yaml
@@ -0,0 +1,9 @@
+---
+fixes:
+ - |
+ [`Bug 1856904 <https://bugs.launchpad.net/keystone/+bug/1856904>`_]
+ The initiator object for CADF notifications now will always contain the
+ username for the user who initated the action. Previously, the initator
+ object only contained the user_id, which lead to issues mapping to users
+ when using LDAP-backed identity providers. This also helps the initiator
+ object better conform to the OpenStack standard for CADF.