Make sure audit can handle API requests which does not require a token

Some service APIs such as Swift list public containers does not require
a token. Therefore, there will be no identity or service catalog information
available. In these cases, audit should fill in the default
(i.e. taxonomy.UNKNOWN) for both initiator and target instead of raising an
exception.

Change-Id: I3f3c12d5e8c0fa176fb7f0218c368971e0a9d0b5
Closes-Bug: 1583699
This commit is contained in:
Guang Yee 2016-05-24 17:24:47 -07:00 committed by Samuel de Medeiros Queiroz
parent 619dbf3786
commit d8cb5a3e93
3 changed files with 65 additions and 9 deletions

View File

@ -51,7 +51,7 @@ from six.moves import configparser
from six.moves.urllib import parse as urlparse
import webob.dec
from keystonemiddleware.i18n import _LE, _LI
from keystonemiddleware.i18n import _LE, _LI, _LW
_LOG = None
@ -286,13 +286,19 @@ class OpenStackAuditApi(object):
service_info = Service(type=taxonomy.UNKNOWN, name=taxonomy.UNKNOWN,
id=taxonomy.UNKNOWN, admin_endp=None,
private_endp=None, public_endp=None)
catalog = {}
try:
catalog = ast.literal_eval(
req.environ['HTTP_X_SERVICE_CATALOG'])
except KeyError:
raise PycadfAuditApiConfigError(
'Service catalog is missing. '
'Cannot discover target information')
_LOG.warning(_LW('Unable to discover target information because '
'service catalog is missing. Either the incoming '
'request does not contain an auth token or auth '
'token does not contain a service catalog. For '
'the latter, please make sure the '
'"include_service_catalog" property in '
'auth_token middleware is set to "True"'))
default_endpoint = None
for endp in catalog:
@ -431,13 +437,14 @@ class AuditMiddleware(object):
initiator = ClientResource(
typeURI=taxonomy.ACCOUNT_USER,
id=req.environ['HTTP_X_USER_ID'],
name=req.environ['HTTP_X_USER_NAME'],
id=req.environ.get('HTTP_X_USER_ID', taxonomy.UNKNOWN),
name=req.environ.get('HTTP_X_USER_NAME', taxonomy.UNKNOWN),
host=host.Host(address=req.client_addr, agent=req.user_agent),
credential=KeystoneCredential(
token=req.environ['HTTP_X_AUTH_TOKEN'],
identity_status=req.environ['HTTP_X_IDENTITY_STATUS']),
project_id=req.environ['HTTP_X_PROJECT_ID'])
token=req.environ.get('HTTP_X_AUTH_TOKEN', ''),
identity_status=req.environ.get('HTTP_X_IDENTITY_STATUS',
taxonomy.UNKNOWN)),
project_id=req.environ.get('HTTP_X_PROJECT_ID', taxonomy.UNKNOWN))
target = self._cadf_audit.get_target_resource(req)
event = factory.EventFactory().new_event(

View File

@ -703,3 +703,43 @@ class AuditApiLogicTest(BaseAuditMiddlewareTest):
self.middleware._process_request(req)
payload = req.environ['cadf_event'].as_dict()
self.assertEqual((payload['target']['addresses'][0]['url']), "unknown")
def test_no_auth_token(self):
# Test cases where API requests such as Swift list public containers
# which does not require an auth token. In these cases, CADF event
# should have the defaults (i.e taxonomy.UNKNOWN) instead of raising
# an exception.
env_headers = {'HTTP_X_IDENTITY_STATUS': 'Invalid',
'REQUEST_METHOD': 'GET'}
req = webob.Request.blank('https://23.253.72.207/v1/'
+ str(uuid.uuid4()),
environ=env_headers,
remote_addr='192.168.0.1')
req.context = {}
self.middleware._process_request(req)
payload = req.environ['cadf_event'].as_dict()
self.assertEqual(payload['action'], 'read')
self.assertEqual(payload['typeURI'],
'http://schemas.dmtf.org/cloud/audit/1.0/event')
self.assertEqual(payload['outcome'], 'pending')
self.assertEqual(payload['eventType'], 'activity')
self.assertEqual(payload['target']['name'], taxonomy.UNKNOWN)
self.assertEqual(payload['target']['id'], taxonomy.UNKNOWN)
self.assertEqual(payload['target']['typeURI'], taxonomy.UNKNOWN)
self.assertNotIn('addresses', payload['target'])
self.assertEqual(payload['initiator']['id'], taxonomy.UNKNOWN)
self.assertEqual(payload['initiator']['name'], taxonomy.UNKNOWN)
self.assertEqual(payload['initiator']['project_id'],
taxonomy.UNKNOWN)
self.assertEqual(payload['initiator']['host']['address'],
'192.168.0.1')
self.assertEqual(payload['initiator']['typeURI'],
'service/security/account/user')
self.assertNotEqual(payload['initiator']['credential']['token'],
None)
self.assertEqual(payload['initiator']['credential']['identity_status'],
'Invalid')
self.assertNotIn('reason', payload)
self.assertNotIn('reporterchain', payload)
self.assertEqual(payload['observer']['id'], 'target')
self.assertEqual(req.path, payload['requestPath'])

View File

@ -0,0 +1,9 @@
---
fixes:
- >
[`bug 1583699 <https://bugs.launchpad.net/keystonemiddleware/+bug/1583699>`_]
Some service APIs (such as Swift list public containers) do not require
a token. Therefore, there will be no identity or service catalog
information available. In these cases, audit now fills in the default
(i.e. taxonomy.UNKNOWN) for both initiator and target instead of raising
an exception.