Add more auth details to the audit message

Generate proper user resource id in case of keystone authentication.

Change-Id: Ic5042db62d4db9032866cf8f00e0f03c8f0aeaea
This commit is contained in:
Stanisław Pitucha 2015-12-03 15:06:38 +11:00
parent d7d6db29c7
commit ebfaa3c929
5 changed files with 50 additions and 17 deletions

View File

@ -12,6 +12,7 @@
# under the License.
import logging
import uuid
from anchor import jsonloader
@ -27,6 +28,8 @@ logger = logging.getLogger(__name__)
target = None
notifier = None
ANCHOR_UUID_NS = uuid.UUID('0ff9c8c5-f57e-47aa-bd3d-5407eb907c74')
def _emit_event(event_type, payload):
if not payload.is_valid():
@ -45,13 +48,25 @@ def _event_defaults(result):
}
def _user_resource(username):
def _user_resource(username, result):
if result:
res_id = uuid.uuid5(ANCHOR_UUID_NS, result.username)
user = result.username
else:
if username:
res_id = uuid.uuid5(ANCHOR_UUID_NS, username.encode('utf-8',
'replace'))
user = username
else:
# Authentication was a failure, but there was no username
# provided either. This can happen with failed token authentication
# for example.
res_id = uuid.uuid4()
user = None
return resource.Resource(
# TODO(stan): generate id from username if it's known
# this should also get username from keystone tokens to work correctly
id=identifier.generate_uuid(),
id=str(res_id),
typeURI=cadftaxonomy.ACCOUNT_USER,
name=username)
name=user)
def _auth_resource(ra_name):
@ -80,9 +95,10 @@ def _certificate_resource(fingerprint):
def emit_auth_event(ra_name, username, result):
params = _event_defaults(result)
success = result is not None
params = _event_defaults(success)
params['action'] = 'authenticate'
params['initiator'] = _user_resource(username)
params['initiator'] = _user_resource(username, result)
auth_res = _auth_resource(ra_name)
params['observer'] = auth_res
params['target'] = auth_res
@ -92,7 +108,7 @@ def emit_auth_event(ra_name, username, result):
def emit_signing_event(ra_name, username, result, fingerprint=None):
params = _event_defaults(result)
params['action'] = 'evaluate'
params['initiator'] = _user_resource(username)
params['initiator'] = _user_resource(username, result)
params['observer'] = _policy_resource(ra_name)
params['target'] = _certificate_resource(fingerprint)
# add when pycadf merges event names

View File

@ -41,11 +41,15 @@ def login(_, token):
try:
res = req.json()
user = res['token']['user']['name']
user = res['token']['user']
user_name = user['name']
user_id = user['id']
project_id = res['token']['project']['id']
roles = [role['name'] for role in res['token']['roles']]
except Exception:
logger.exception("Keystone response was not in the expected format")
return None
return results.AuthDetails(username=user, groups=roles)
return results.AuthDetails(username=user_name, groups=roles,
user_id=user_id, project_id=project_id)

View File

@ -13,7 +13,17 @@
from __future__ import absolute_import
import collections
class AuthDetails(object):
def __init__(self, username=None, groups=None, user_id=None,
project_id=None):
self.username = username
self.groups = groups or []
self.user_id = user_id
self.project_id = project_id
AuthDetails = collections.namedtuple('AuthDetails', ['username', 'groups'])
def __eq__(self, other):
return (self.username == other.username and
self.groups == other.groups and
self.user_id == other.user_id and
self.project_id == other.project_id)

View File

@ -53,10 +53,10 @@ class SignInstanceController(GenericInstanceController):
pecan.request.POST.get('user'),
pecan.request.POST.get('secret'))
audit.emit_auth_event(ra_name, pecan.request.POST.get('user'),
True)
auth_result)
except http_status.HTTPUnauthorized:
audit.emit_auth_event(ra_name, pecan.request.POST.get('user'),
False)
None)
raise
try:
@ -68,10 +68,10 @@ class SignInstanceController(GenericInstanceController):
cert, fingerprint = certificate_ops.dispatch_sign(ra_name, csr)
audit.emit_signing_event(ra_name, pecan.request.POST.get('user'),
True, fingerprint=fingerprint)
auth_result, fingerprint=fingerprint)
except Exception:
audit.emit_signing_event(ra_name, pecan.request.POST.get('user'),
False)
auth_result)
raise
return cert

View File

@ -104,8 +104,11 @@ class AuthKeystoneTests(unittest.TestCase):
self.user = self.json_response['token']['user']['name']
self.roles = [role['name']
for role in self.json_response['token']['roles']]
self.user_id = self.json_response['token']['user']['id']
self.project_id = self.json_response['token']['project']['id']
self.expected = results.AuthDetails(
username=self.user, groups=self.roles)
username=self.user, groups=self.roles,
user_id=self.user_id, project_id=self.project_id)
self.keystone_url = self.data['auth'][
'keystone']['url'] + '/v3/auth/tokens'