diff options
author | Jenkins <jenkins@review.openstack.org> | 2015-11-13 23:56:52 +0000 |
---|---|---|
committer | Gerrit Code Review <review@openstack.org> | 2015-11-13 23:56:52 +0000 |
commit | 830fcbdf719df5edce69d427b5797d23d62f5204 (patch) | |
tree | 303123475f02c648a9005e3125feca14525a8ee2 | |
parent | 348130e6612afce9342ecb95093724dc16bb7206 (diff) | |
parent | a8d94f3795cf3ac2b55fa61adf31cbfab40ca82d (diff) | |
download | keystone-830fcbdf719df5edce69d427b5797d23d62f5204.tar.gz |
Merge "add initiator to v2 calls for additional auditing" into stable/kilo
-rw-r--r-- | keystone/assignment/controllers.py | 6 | ||||
-rw-r--r-- | keystone/catalog/controllers.py | 9 | ||||
-rw-r--r-- | keystone/identity/controllers.py | 9 | ||||
-rw-r--r-- | keystone/resource/controllers.py | 11 | ||||
-rw-r--r-- | keystone/tests/unit/common/test_notifications.py | 163 |
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): |