summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJenkins <jenkins@review.openstack.org>2015-11-13 23:56:52 +0000
committerGerrit Code Review <review@openstack.org>2015-11-13 23:56:52 +0000
commit830fcbdf719df5edce69d427b5797d23d62f5204 (patch)
tree303123475f02c648a9005e3125feca14525a8ee2
parent348130e6612afce9342ecb95093724dc16bb7206 (diff)
parenta8d94f3795cf3ac2b55fa61adf31cbfab40ca82d (diff)
downloadkeystone-830fcbdf719df5edce69d427b5797d23d62f5204.tar.gz
Merge "add initiator to v2 calls for additional auditing" into stable/kilo
-rw-r--r--keystone/assignment/controllers.py6
-rw-r--r--keystone/catalog/controllers.py9
-rw-r--r--keystone/identity/controllers.py9
-rw-r--r--keystone/resource/controllers.py11
-rw-r--r--keystone/tests/unit/common/test_notifications.py163
5 files changed, 181 insertions, 17 deletions
diff --git a/keystone/assignment/controllers.py b/keystone/assignment/controllers.py
index 0b5d4f7a1..85c4acede 100644
--- a/keystone/assignment/controllers.py
+++ b/keystone/assignment/controllers.py
@@ -116,13 +116,15 @@ class Role(controller.V2Controller):
role_id = uuid.uuid4().hex
role['id'] = role_id
- role_ref = self.role_api.create_role(role_id, role)
+ initiator = notifications._get_request_audit_info(context)
+ role_ref = self.role_api.create_role(role_id, role, initiator)
return {'role': role_ref}
@controller.v2_deprecated
def delete_role(self, context, role_id):
self.assert_admin(context)
- self.role_api.delete_role(role_id)
+ initiator = notifications._get_request_audit_info(context)
+ self.role_api.delete_role(role_id, initiator)
@controller.v2_deprecated
def get_roles(self, context):
diff --git a/keystone/catalog/controllers.py b/keystone/catalog/controllers.py
index 3518c4bfe..57faccdfc 100644
--- a/keystone/catalog/controllers.py
+++ b/keystone/catalog/controllers.py
@@ -48,7 +48,8 @@ class Service(controller.V2Controller):
@controller.v2_deprecated
def delete_service(self, context, service_id):
self.assert_admin(context)
- self.catalog_api.delete_service(service_id)
+ initiator = notifications._get_request_audit_info(context)
+ self.catalog_api.delete_service(service_id, initiator)
@controller.v2_deprecated
def create_service(self, context, OS_KSADM_service):
@@ -56,8 +57,9 @@ class Service(controller.V2Controller):
service_id = uuid.uuid4().hex
service_ref = OS_KSADM_service.copy()
service_ref['id'] = service_id
+ initiator = notifications._get_request_audit_info(context)
new_service_ref = self.catalog_api.create_service(
- service_id, service_ref)
+ service_id, service_ref, initiator)
return {'OS-KSADM:service': new_service_ref}
@@ -141,11 +143,12 @@ class Endpoint(controller.V2Controller):
def delete_endpoint(self, context, endpoint_id):
"""Delete up to three v3 endpoint refs based on a legacy ref ID."""
self.assert_admin(context)
+ initiator = notifications._get_request_audit_info(context)
deleted_at_least_one = False
for endpoint in self.catalog_api.list_endpoints():
if endpoint['legacy_endpoint_id'] == endpoint_id:
- self.catalog_api.delete_endpoint(endpoint['id'])
+ self.catalog_api.delete_endpoint(endpoint['id'], initiator)
deleted_at_least_one = True
if not deleted_at_least_one:
diff --git a/keystone/identity/controllers.py b/keystone/identity/controllers.py
index a2676c417..87ea8aa7b 100644
--- a/keystone/identity/controllers.py
+++ b/keystone/identity/controllers.py
@@ -80,8 +80,9 @@ class User(controller.V2Controller):
# The manager layer will generate the unique ID for users
user_ref = self._normalize_domain_id(context, user.copy())
+ initiator = notifications._get_request_audit_info(context)
new_user_ref = self.v3_to_v2_user(
- self.identity_api.create_user(user_ref))
+ self.identity_api.create_user(user_ref, initiator))
if default_project_id is not None:
self.assignment_api.add_user_to_project(default_project_id,
@@ -118,8 +119,9 @@ class User(controller.V2Controller):
# user update.
self.resource_api.get_project(default_project_id)
+ initiator = notifications._get_request_audit_info(context)
user_ref = self.v3_to_v2_user(
- self.identity_api.update_user(user_id, user))
+ self.identity_api.update_user(user_id, user, initiator))
# If 'tenantId' is in either ref, we might need to add or remove the
# user from a project.
@@ -164,7 +166,8 @@ class User(controller.V2Controller):
@controller.v2_deprecated
def delete_user(self, context, user_id):
self.assert_admin(context)
- self.identity_api.delete_user(user_id)
+ initiator = notifications._get_request_audit_info(context)
+ self.identity_api.delete_user(user_id, initiator)
@controller.v2_deprecated
def set_user_enabled(self, context, user_id, user):
diff --git a/keystone/resource/controllers.py b/keystone/resource/controllers.py
index 570aa6fc7..bddbaf7e0 100644
--- a/keystone/resource/controllers.py
+++ b/keystone/resource/controllers.py
@@ -80,9 +80,11 @@ class Tenant(controller.V2Controller):
self.assert_admin(context)
tenant_ref['id'] = tenant_ref.get('id', uuid.uuid4().hex)
+ initiator = notifications._get_request_audit_info(context)
tenant = self.resource_api.create_project(
tenant_ref['id'],
- self._normalize_domain_id(context, tenant_ref))
+ self._normalize_domain_id(context, tenant_ref),
+ initiator)
return {'tenant': self.v3_to_v2_project(tenant)}
@controller.v2_deprecated
@@ -92,15 +94,16 @@ class Tenant(controller.V2Controller):
# be specifying that
clean_tenant = tenant.copy()
clean_tenant.pop('domain_id', None)
-
+ initiator = notifications._get_request_audit_info(context)
tenant_ref = self.resource_api.update_project(
- tenant_id, clean_tenant)
+ tenant_id, clean_tenant, initiator)
return {'tenant': self.v3_to_v2_project(tenant_ref)}
@controller.v2_deprecated
def delete_project(self, context, tenant_id):
self.assert_admin(context)
- self.resource_api.delete_project(tenant_id)
+ initiator = notifications._get_request_audit_info(context)
+ self.resource_api.delete_project(tenant_id, initiator)
@dependency.requires('resource_api')
diff --git a/keystone/tests/unit/common/test_notifications.py b/keystone/tests/unit/common/test_notifications.py
index ce1696f5d..71c916fe0 100644
--- a/keystone/tests/unit/common/test_notifications.py
+++ b/keystone/tests/unit/common/test_notifications.py
@@ -287,6 +287,16 @@ class BaseNotificationTest(test_v3.RestfulTestCase):
self.assertEqual(event_type, audit['event_type'])
self.assertTrue(audit['send_notification_called'])
+ def _assert_initiator_data_is_set(self, operation, resource_type, typeURI):
+ self.assertTrue(len(self._audits) > 0)
+ audit = self._audits[-1]
+ payload = audit['payload']
+ self.assertEqual(self.user_id, payload['initiator']['id'])
+ self.assertEqual(self.project_id, payload['initiator']['project_id'])
+ self.assertEqual(typeURI, payload['target']['typeURI'])
+ action = '%s.%s' % (operation, resource_type)
+ self.assertEqual(action, payload['action'])
+
def _assert_notify_not_sent(self, resource_id, operation, resource_type,
public=True):
unexpected = {
@@ -641,11 +651,154 @@ class CADFNotificationsForEntities(NotificationsForEntities):
resource_id = resp.result.get('domain').get('id')
self._assert_last_audit(resource_id, CREATED_OPERATION, 'domain',
cadftaxonomy.SECURITY_DOMAIN)
- self.assertTrue(len(self._audits) > 0)
- audit = self._audits[-1]
- payload = audit['payload']
- self.assertEqual(self.user_id, payload['initiator']['id'])
- self.assertEqual(self.project_id, payload['initiator']['project_id'])
+ self._assert_initiator_data_is_set(CREATED_OPERATION,
+ 'domain',
+ cadftaxonomy.SECURITY_DOMAIN)
+
+
+class V2Notifications(BaseNotificationTest):
+
+ def setUp(self):
+ super(V2Notifications, self).setUp()
+ self.config_fixture.config(notification_format='cadf')
+
+ def test_user(self):
+ token = self.get_scoped_token()
+ resp = self.admin_request(
+ method='POST',
+ path='/v2.0/users',
+ body={
+ 'user': {
+ 'name': uuid.uuid4().hex,
+ 'password': uuid.uuid4().hex,
+ 'enabled': True,
+ },
+ },
+ token=token,
+ )
+ user_id = resp.result.get('user').get('id')
+ self._assert_initiator_data_is_set(CREATED_OPERATION,
+ 'user',
+ cadftaxonomy.SECURITY_ACCOUNT_USER)
+ # test for delete user
+ self.admin_request(
+ method='DELETE',
+ path='/v2.0/users/%s' % user_id,
+ token=token,
+ )
+ self._assert_initiator_data_is_set(DELETED_OPERATION,
+ 'user',
+ cadftaxonomy.SECURITY_ACCOUNT_USER)
+
+ def test_role(self):
+ token = self.get_scoped_token()
+ resp = self.admin_request(
+ method='POST',
+ path='/v2.0/OS-KSADM/roles',
+ body={
+ 'role': {
+ 'name': uuid.uuid4().hex,
+ 'description': uuid.uuid4().hex,
+ },
+ },
+ token=token,
+ )
+ role_id = resp.result.get('role').get('id')
+ self._assert_initiator_data_is_set(CREATED_OPERATION,
+ 'role',
+ cadftaxonomy.SECURITY_ROLE)
+ # test for delete role
+ self.admin_request(
+ method='DELETE',
+ path='/v2.0/OS-KSADM/roles/%s' % role_id,
+ token=token,
+ )
+ self._assert_initiator_data_is_set(DELETED_OPERATION,
+ 'role',
+ cadftaxonomy.SECURITY_ROLE)
+
+ def test_service_and_endpoint(self):
+ token = self.get_scoped_token()
+ resp = self.admin_request(
+ method='POST',
+ path='/v2.0/OS-KSADM/services',
+ body={
+ 'OS-KSADM:service': {
+ 'name': uuid.uuid4().hex,
+ 'type': uuid.uuid4().hex,
+ 'description': uuid.uuid4().hex,
+ },
+ },
+ token=token,
+ )
+ service_id = resp.result.get('OS-KSADM:service').get('id')
+ self._assert_initiator_data_is_set(CREATED_OPERATION,
+ 'service',
+ cadftaxonomy.SECURITY_SERVICE)
+ resp = self.admin_request(
+ method='POST',
+ path='/v2.0/endpoints',
+ body={
+ 'endpoint': {
+ 'region': uuid.uuid4().hex,
+ 'service_id': service_id,
+ 'publicurl': uuid.uuid4().hex,
+ 'adminurl': uuid.uuid4().hex,
+ 'internalurl': uuid.uuid4().hex,
+ },
+ },
+ token=token,
+ )
+ endpoint_id = resp.result.get('endpoint').get('id')
+ self._assert_initiator_data_is_set(CREATED_OPERATION,
+ 'endpoint',
+ cadftaxonomy.SECURITY_ENDPOINT)
+ # test for delete endpoint
+ self.admin_request(
+ method='DELETE',
+ path='/v2.0/endpoints/%s' % endpoint_id,
+ token=token,
+ )
+ self._assert_initiator_data_is_set(DELETED_OPERATION,
+ 'endpoint',
+ cadftaxonomy.SECURITY_ENDPOINT)
+ # test for delete service
+ self.admin_request(
+ method='DELETE',
+ path='/v2.0/OS-KSADM/services/%s' % service_id,
+ token=token,
+ )
+ self._assert_initiator_data_is_set(DELETED_OPERATION,
+ 'service',
+ cadftaxonomy.SECURITY_SERVICE)
+
+ def test_project(self):
+ token = self.get_scoped_token()
+ resp = self.admin_request(
+ method='POST',
+ path='/v2.0/tenants',
+ body={
+ 'tenant': {
+ 'name': uuid.uuid4().hex,
+ 'description': uuid.uuid4().hex,
+ 'enabled': True
+ },
+ },
+ token=token,
+ )
+ project_id = resp.result.get('tenant').get('id')
+ self._assert_initiator_data_is_set(CREATED_OPERATION,
+ 'project',
+ cadftaxonomy.SECURITY_PROJECT)
+ # test for delete project
+ self.admin_request(
+ method='DELETE',
+ path='/v2.0/tenants/%s' % project_id,
+ token=token,
+ )
+ self._assert_initiator_data_is_set(DELETED_OPERATION,
+ 'project',
+ cadftaxonomy.SECURITY_PROJECT)
class TestEventCallbacks(test_v3.RestfulTestCase):