##// END OF EJS Templates
audit-logs: expose download user audit logs as JSON file....
ergo -
r3970:36c4e038 default
parent child Browse files
Show More
@@ -378,6 +378,10 b' def admin_routes(config):'
378 name='edit_user_audit_logs',
378 name='edit_user_audit_logs',
379 pattern='/users/{user_id:\d+}/edit/audit', user_route=True)
379 pattern='/users/{user_id:\d+}/edit/audit', user_route=True)
380
380
381 config.add_route(
382 name='edit_user_audit_logs_download',
383 pattern='/users/{user_id:\d+}/edit/audit/download', user_route=True)
384
381 # user caches
385 # user caches
382 config.add_route(
386 config.add_route(
383 name='edit_user_caches',
387 name='edit_user_caches',
@@ -91,6 +91,9 b' def route_path(name, params=None, **kwar'
91 'edit_user_audit_logs':
91 'edit_user_audit_logs':
92 ADMIN_PREFIX + '/users/{user_id}/edit/audit',
92 ADMIN_PREFIX + '/users/{user_id}/edit/audit',
93
93
94 'edit_user_audit_logs_download':
95 ADMIN_PREFIX + '/users/{user_id}/edit/audit/download',
96
94 }[name].format(**kwargs)
97 }[name].format(**kwargs)
95
98
96 if params:
99 if params:
@@ -318,7 +321,6 b' class TestAdminUsersView(TestController)'
318 route_path('edit_user_emails', user_id=user_id))
321 route_path('edit_user_emails', user_id=user_id))
319 response.mustcontain(no=['example@rhodecode.com'])
322 response.mustcontain(no=['example@rhodecode.com'])
320
323
321
322 def test_create(self, request, xhr_header):
324 def test_create(self, request, xhr_header):
323 self.log_user()
325 self.log_user()
324 username = 'newtestuser'
326 username = 'newtestuser'
@@ -531,8 +533,7 b' class TestAdminUsersView(TestController)'
531 params={'csrf_token': self.csrf_token})
533 params={'csrf_token': self.csrf_token})
532
534
533 msg = 'user "%s" still owns 1 repositories and cannot be removed. ' \
535 msg = 'user "%s" still owns 1 repositories and cannot be removed. ' \
534 'Switch owners or remove those repositories:%s' % (username,
536 'Switch owners or remove those repositories:%s' % (username, obj_name)
535 obj_name)
536 assert_session_flash(response, msg)
537 assert_session_flash(response, msg)
537 fixture.destroy_repo(obj_name)
538 fixture.destroy_repo(obj_name)
538
539
@@ -583,8 +584,7 b' class TestAdminUsersView(TestController)'
583 params={'csrf_token': self.csrf_token})
584 params={'csrf_token': self.csrf_token})
584
585
585 msg = 'user "%s" still owns 1 repository groups and cannot be removed. ' \
586 msg = 'user "%s" still owns 1 repository groups and cannot be removed. ' \
586 'Switch owners or remove those repository groups:%s' % (username,
587 'Switch owners or remove those repository groups:%s' % (username, obj_name)
587 obj_name)
588 assert_session_flash(response, msg)
588 assert_session_flash(response, msg)
589 fixture.destroy_repo_group(obj_name)
589 fixture.destroy_repo_group(obj_name)
590
590
@@ -635,8 +635,7 b' class TestAdminUsersView(TestController)'
635 params={'csrf_token': self.csrf_token})
635 params={'csrf_token': self.csrf_token})
636
636
637 msg = 'user "%s" still owns 1 user groups and cannot be removed. ' \
637 msg = 'user "%s" still owns 1 user groups and cannot be removed. ' \
638 'Switch owners or remove those user groups:%s' % (username,
638 'Switch owners or remove those user groups:%s' % (username, obj_name)
639 obj_name)
640 assert_session_flash(response, msg)
639 assert_session_flash(response, msg)
641 fixture.destroy_user_group(obj_name)
640 fixture.destroy_user_group(obj_name)
642
641
@@ -779,3 +778,13 b' class TestAdminUsersView(TestController)'
779 user = self.log_user()
778 user = self.log_user()
780 self.app.get(
779 self.app.get(
781 route_path('edit_user_audit_logs', user_id=user['user_id']))
780 route_path('edit_user_audit_logs', user_id=user['user_id']))
781
782 def test_audit_log_page_download(self):
783 user = self.log_user()
784 user_id = user['user_id']
785 response = self.app.get(
786 route_path('edit_user_audit_logs_download', user_id=user_id))
787
788 assert response.content_disposition == \
789 'attachment; filename=user_{}_audit_logs.json'.format(user_id)
790 assert response.content_type == "application/json"
@@ -1200,6 +1200,29 b' class UsersView(UserAppView):'
1200 @LoginRequired()
1200 @LoginRequired()
1201 @HasPermissionAllDecorator('hg.admin')
1201 @HasPermissionAllDecorator('hg.admin')
1202 @view_config(
1202 @view_config(
1203 route_name='edit_user_audit_logs_download', request_method='GET',
1204 renderer='string')
1205 def user_audit_logs_download(self):
1206 _ = self.request.translate
1207 c = self.load_default_context()
1208 c.user = self.db_user
1209
1210 user_log = UserModel().get_user_log(c.user, filter_term=None)
1211
1212 audit_log_data = {}
1213 for entry in user_log:
1214 audit_log_data[entry.user_log_id] = entry.get_dict()
1215
1216 response = Response(json.dumps(audit_log_data, indent=4))
1217 response.content_disposition = str(
1218 'attachment; filename=%s' % 'user_{}_audit_logs.json'.format(c.user.user_id))
1219 response.content_type = 'application/json'
1220
1221 return response
1222
1223 @LoginRequired()
1224 @HasPermissionAllDecorator('hg.admin')
1225 @view_config(
1203 route_name='edit_user_perms_summary', request_method='GET',
1226 route_name='edit_user_perms_summary', request_method='GET',
1204 renderer='rhodecode:templates/admin/users/user_edit.mako')
1227 renderer='rhodecode:templates/admin/users/user_edit.mako')
1205 def user_perms_summary(self):
1228 def user_perms_summary(self):
@@ -121,6 +121,7 b' function registerRCRoutes() {'
121 pyroutes.register('edit_user_groups_management', '/_admin/users/%(user_id)s/edit/groups_management', ['user_id']);
121 pyroutes.register('edit_user_groups_management', '/_admin/users/%(user_id)s/edit/groups_management', ['user_id']);
122 pyroutes.register('edit_user_groups_management_updates', '/_admin/users/%(user_id)s/edit/edit_user_groups_management/updates', ['user_id']);
122 pyroutes.register('edit_user_groups_management_updates', '/_admin/users/%(user_id)s/edit/edit_user_groups_management/updates', ['user_id']);
123 pyroutes.register('edit_user_audit_logs', '/_admin/users/%(user_id)s/edit/audit', ['user_id']);
123 pyroutes.register('edit_user_audit_logs', '/_admin/users/%(user_id)s/edit/audit', ['user_id']);
124 pyroutes.register('edit_user_audit_logs_download', '/_admin/users/%(user_id)s/edit/audit/download', ['user_id']);
124 pyroutes.register('edit_user_caches', '/_admin/users/%(user_id)s/edit/caches', ['user_id']);
125 pyroutes.register('edit_user_caches', '/_admin/users/%(user_id)s/edit/caches', ['user_id']);
125 pyroutes.register('edit_user_caches_update', '/_admin/users/%(user_id)s/edit/caches/update', ['user_id']);
126 pyroutes.register('edit_user_caches_update', '/_admin/users/%(user_id)s/edit/caches/update', ['user_id']);
126 pyroutes.register('user_groups', '/_admin/user_groups', []);
127 pyroutes.register('user_groups', '/_admin/user_groups', []);
@@ -7,6 +7,7 b''
7 <h3 class="panel-title">${_('User Audit Logs')} -
7 <h3 class="panel-title">${_('User Audit Logs')} -
8 ${_ungettext('%s entry', '%s entries', c.audit_logs.item_count) % (c.audit_logs.item_count)}
8 ${_ungettext('%s entry', '%s entries', c.audit_logs.item_count) % (c.audit_logs.item_count)}
9 </h3>
9 </h3>
10 <a href="${h.route_path('edit_user_audit_logs_download', user_id=c.user.user_id)}" class="panel-edit">${_('Download as JSON')}</a>
10 </div>
11 </div>
11 <div class="panel-body">
12 <div class="panel-body">
12
13
General Comments 0
You need to be logged in to leave comments. Login now