Merge lp:~robru/bileto/unify-audit-logging into lp:bileto

Proposed by Robert Bruce Park
Status: Merged
Merged at revision: 517
Proposed branch: lp:~robru/bileto/unify-audit-logging
Merge into: lp:bileto
Diff against target: 146 lines (+44/-53)
2 files modified
bileto/models.py (+41/-15)
bileto/v1.py (+3/-38)
To merge this branch: bzr merge lp:~robru/bileto/unify-audit-logging
Reviewer Review Type Date Requested Status
CU2D maintainers Pending
Review via email: mp+297112@code.launchpad.net
To post a comment you must log in.
lp:~robru/bileto/unify-audit-logging updated
517. By Robert Bruce Park

Fix tests.

518. By Robert Bruce Park

Simplify.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'bileto/models.py'
2--- bileto/models.py 2016-06-08 16:11:29 +0000
3+++ bileto/models.py 2016-06-10 21:49:56 +0000
4@@ -16,7 +16,7 @@
5 from sqlalchemy.inspection import inspect
6 from sqlalchemy.orm import relationship
7 from sqlalchemy.dialects import sqlite
8-from flask import session
9+from flask import request, session
10
11 from bileto.app import db
12
13@@ -331,9 +331,41 @@
14 """Allow requests to be sorted."""
15 return self.request_id < other.request_id
16
17- def update(self, *args, **kwargs):
18- """Cache computed values in the db."""
19- super().update(*args, **kwargs)
20+ def _audit(self, status, job_log, author='bileto-bot', **kwargs):
21+ """Create a Comment object which records a change in the ticket."""
22+ db.session.add(Comment(
23+ log_url=job_log,
24+ published_versions=kwargs.get('published_versions', EMPTY),
25+ siloname=kwargs.get('siloname', self.siloname),
26+ request_id=self.request_id,
27+ author=author,
28+ text=status,
29+ ))
30+
31+ def audit(self, **kwargs):
32+ """Create audit log messages as appropriate."""
33+ no_audit = self.verboten | {'author', 'job_log'}
34+ nick = environ.get('BLAME') or session.get('nickname')
35+ kwargs['author'] = nick or kwargs.get('author') or 'bileto-bot'
36+ status = kwargs.get('status')
37+ if status and status != self.status:
38+ self._audit(**kwargs)
39+ else:
40+ comment = dict(kwargs)
41+ comment.setdefault('job_log', self.path)
42+ for key, val in comment.items():
43+ if key not in no_audit and hasattr(self, key):
44+ if self[key] != val:
45+ explicit = '{}: {}'.format(key, val)
46+ brief = 'Updated {}.'.format(key)
47+ self._audit(
48+ status=explicit if len(explicit) < 100 else brief,
49+ **comment)
50+
51+ def update(self, **kwargs):
52+ """Ensure changes are logged & compute computed values."""
53+ self.audit(**kwargs)
54+ super().update(**kwargs)
55 tokens = set(WORD.split((self.status or EMPTY).lower()))
56 keys = sorted(set(super().keys()) - self.verboten)
57 self.search = N.join([str(self[key] or EMPTY) for key in keys])
58@@ -348,17 +380,11 @@
59
60 def set_status(self, message):
61 """Update status immediately."""
62- request_path = environ.get('LOG_PATH') or environ['REQUEST_PATH']
63- self.job_log = request_path
64- self.update(status=message)
65- # Add audit log comment.
66- db.session.add(Comment(
67- log_url=request_path,
68- published_versions=EMPTY, # TODO
69- siloname=self.siloname,
70- request_id=self.request_id,
71- author=environ['BLAME'],
72- text=message))
73+ self.update(
74+ status=message,
75+ job_log=environ.get('LOG_PATH') or
76+ environ.get('REQUEST_PATH') or
77+ request.path)
78 self.commit()
79 return message
80
81
82=== modified file 'bileto/v1.py'
83--- bileto/v1.py 2016-06-01 01:08:28 +0000
84+++ bileto/v1.py 2016-06-10 21:49:56 +0000
85@@ -52,29 +52,6 @@
86 return 0
87
88
89-def diff_dicts(alpha, beta):
90- """Identify which keys differ between dicts.
91-
92- Only considers keys from the first dict.
93- """
94- fields = {key for key, val in alpha.items() if beta.get(key) != val}
95- fields -= set(Request.verboten)
96- fields -= {'author', 'job_log'}
97- return fields
98-
99-
100-def audit(status, request_id, job_log, author='bileto-bot', **kwargs):
101- """Create an audit record of something that happened."""
102- comment = Comment(
103- log_url=job_log,
104- published_versions=kwargs.get('published_versions', ''),
105- siloname=kwargs.get('siloname', ''),
106- request_id=request_id,
107- author=author,
108- text=status)
109- db.session.add(comment)
110-
111-
112 def do_pagination(args, pages, page, limit):
113 """Calculate some pagination magic."""
114 remaining = max(pages.total - (page * limit), 0)
115@@ -126,9 +103,9 @@
116 requestid = request.json.get('request_id')
117 success = 200 if requestid else 201
118 if not requestid:
119- req = Request()
120+ request.json['creator'] = session['nickname']
121+ req = Request(**request.json)
122 db.session.add(req)
123- request.json['creator'] = session['nickname']
124 else:
125 try:
126 req = Request.query.get(requestid)
127@@ -136,20 +113,8 @@
128 except Exception:
129 db.session.rollback()
130 abort(400)
131- nick = session.get('nickname')
132- diff = diff_dicts(request.json, dict(req))
133- if 'status' in diff:
134- audit(**request.json)
135- else:
136- kwargs = dict(request.json)
137- kwargs.setdefault('job_log', req.path)
138- kwargs['author'] = nick or kwargs.get('author') or 'bileto-bot'
139- for key in diff:
140- msg = '{}: {}'.format(key, request.json[key])
141- kwargs['status'] = msg if len(msg) < 100 else 'Updated ' + key
142- audit(**kwargs)
143 req.update(**request.json)
144- db.session.commit()
145+ req.commit()
146 return jsonify(dict(request_id=req.request_id)), success
147
148

Subscribers

People subscribed via source and target branches