##// END OF EJS Templates
audit-logs: expose tailoed audit logs in repository view
marcink -
r2156:ea1af41c default
parent child Browse files
Show More
@@ -0,0 +1,65 b''
1 # -*- coding: utf-8 -*-
2
3 # Copyright (C) 2017-2017 RhodeCode GmbH
4 #
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU Affero General Public License, version 3
7 # (only), as published by the Free Software Foundation.
8 #
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
13 #
14 # You should have received a copy of the GNU Affero General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #
17 # This program is dual-licensed. If you wish to learn more about the
18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
21 import logging
22 from pyramid.view import view_config
23
24 from rhodecode.apps._base import RepoAppView
25 from rhodecode.lib import helpers as h
26 from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator
27 from rhodecode.lib.utils2 import safe_int
28 from rhodecode.model.repo import RepoModel
29
30 log = logging.getLogger(__name__)
31
32
33 class AuditLogsView(RepoAppView):
34 def load_default_context(self):
35 c = self._get_local_tmpl_context()
36
37 self._register_global_c(c)
38 return c
39
40 @LoginRequired()
41 @HasRepoPermissionAnyDecorator('repository.admin')
42 @view_config(
43 route_name='edit_repo_audit_logs', request_method='GET',
44 renderer='rhodecode:templates/admin/repos/repo_edit.mako')
45 def repo_audit_logs(self):
46 _ = self.request.translate
47 c = self.load_default_context()
48 c.db_repo = self.db_repo
49
50 c.active = 'audit'
51
52 p = safe_int(self.request.GET.get('page', 1), 1)
53
54 filter_term = self.request.GET.get('filter')
55 user_log = RepoModel().get_repo_log(c.db_repo, filter_term)
56
57 def url_generator(**kw):
58 if filter_term:
59 kw['filter'] = filter_term
60 return self.request.current_route_path(_query=kw)
61
62 c.audit_logs = h.Page(
63 user_log, page=p, items_per_page=10, url=url_generator)
64 c.filter_term = filter_term
65 return self._get_template_context(c)
@@ -0,0 +1,22 b''
1 ## -*- coding: utf-8 -*-
2 <%namespace name="base" file="/base/base.mako"/>
3
4
5 <div class="panel panel-default">
6 <div class="panel-heading">
7 <h3 class="panel-title">${_('Repository Audit Logs')} -
8 ${_ungettext('%s entry', '%s entries', c.audit_logs.item_count) % (c.audit_logs.item_count)}
9 </h3>
10 </div>
11 <div class="panel-body">
12
13 ${h.form(None, id_="filter_form", method="get")}
14 <input class="q_filter_box ${'' if c.filter_term else 'initial'}" id="j_filter" size="15" type="text" name="filter" value="${c.filter_term or ''}" placeholder="${_('audit filter...')}"/>
15 <input type='submit' value="${_('filter')}" class="btn" />
16 ${h.end_form()}
17 <p class="tooltip filterexample" style="position: inherit" title="${h.tooltip(h.journal_filter_help(c.pyramid_request))}">${_('Example Queries')}</p>
18
19 <%include file="/admin/admin_log_base.mako" />
20
21 </div>
22 </div>
@@ -431,6 +431,11 b' def includeme(config):'
431 431 name='strip_execute',
432 432 pattern='/{repo_name:.*?[^/]}/settings/strip_execute', repo_route=True)
433 433
434 # Audit logs
435 config.add_route(
436 name='edit_repo_audit_logs',
437 pattern='/{repo_name:.*?[^/]}/settings/audit_logs', repo_route=True)
438
434 439 # ATOM/RSS Feed
435 440 config.add_route(
436 441 name='rss_feed_home',
@@ -18,11 +18,11 b''
18 18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 20
21 import logging
22 21 import os
23 22 import re
24 23 import shutil
25 24 import time
25 import logging
26 26 import traceback
27 27 import datetime
28 28
@@ -30,21 +30,22 b' from pyramid.threadlocal import get_curr'
30 30 from zope.cachedescriptors.property import Lazy as LazyProperty
31 31
32 32 from rhodecode import events
33 from rhodecode.lib import helpers as h
34 33 from rhodecode.lib.auth import HasUserGroupPermissionAny
35 34 from rhodecode.lib.caching_query import FromCache
36 35 from rhodecode.lib.exceptions import AttachedForksError
37 36 from rhodecode.lib.hooks_base import log_delete_repository
37 from rhodecode.lib.user_log_filter import user_log_filter
38 38 from rhodecode.lib.utils import make_db_config
39 39 from rhodecode.lib.utils2 import (
40 40 safe_str, safe_unicode, remove_prefix, obfuscate_url_pw,
41 get_current_rhodecode_user, safe_int, datetime_to_time, action_logger_generic)
41 get_current_rhodecode_user, safe_int, datetime_to_time,
42 action_logger_generic)
42 43 from rhodecode.lib.vcs.backends import get_backend
43 44 from rhodecode.model import BaseModel
44 from rhodecode.model.db import (_hash_key,
45 Repository, UserRepoToPerm, UserGroupRepoToPerm, UserRepoGroupToPerm,
46 UserGroupRepoGroupToPerm, User, Permission, Statistics, UserGroup,
47 RepoGroup, RepositoryField)
45 from rhodecode.model.db import (
46 _hash_key, joinedload, or_, Repository, UserRepoToPerm, UserGroupRepoToPerm,
47 UserRepoGroupToPerm, UserGroupRepoGroupToPerm, User, Permission,
48 Statistics, UserGroup, RepoGroup, RepositoryField, UserLog)
48 49
49 50 from rhodecode.model.settings import VcsSettingsModel
50 51
@@ -182,6 +183,17 b' class RepoModel(BaseModel):'
182 183 'repo_commit', repo_name=safe_str(repo.repo_name),
183 184 commit_id=commit_id)
184 185
186 def get_repo_log(self, repo, filter_term):
187 repo_log = UserLog.query()\
188 .filter(or_(UserLog.repository_id == repo.repo_id,
189 UserLog.repository_name == repo.repo_name))\
190 .options(joinedload(UserLog.user))\
191 .options(joinedload(UserLog.repository))\
192 .order_by(UserLog.action_date.desc())
193
194 repo_log = user_log_filter(repo_log, filter_term)
195 return repo_log
196
185 197 @classmethod
186 198 def update_repoinfo(cls, repositories=None):
187 199 if not repositories:
@@ -85,6 +85,9 b''
85 85 <li class="${'active' if c.active=='strip' else ''}">
86 86 <a href="${h.route_path('edit_repo_strip', repo_name=c.repo_name)}">${_('Strip')}</a>
87 87 </li>
88 <li class="${'active' if c.active=='audit' else ''}">
89 <a href="${h.route_path('edit_repo_audit_logs', repo_name=c.repo_name)}">${_('Audit logs')}</a>
90 </li>
88 91
89 92 </ul>
90 93 </div>
@@ -44,7 +44,7 b''
44 44 <li class="${'active' if c.active=='emails' else ''}"><a href="${h.route_path('edit_user_emails', user_id=c.user.user_id)}">${_('Emails')}</a></li>
45 45 <li class="${'active' if c.active=='ips' else ''}"><a href="${h.route_path('edit_user_ips', user_id=c.user.user_id)}">${_('Ip Whitelist')}</a></li>
46 46 <li class="${'active' if c.active=='groups' else ''}"><a href="${h.route_path('edit_user_groups_management', user_id=c.user.user_id)}">${_('User Groups Management')}</a></li>
47 <li class="${'active' if c.active=='audit' else ''}"><a href="${h.route_path('edit_user_audit_logs', user_id=c.user.user_id)}">${_('User audit')}</a></li>
47 <li class="${'active' if c.active=='audit' else ''}"><a href="${h.route_path('edit_user_audit_logs', user_id=c.user.user_id)}">${_('Audit logs')}</a></li>
48 48 </ul>
49 49 </div>
50 50
General Comments 0
You need to be logged in to leave comments. Login now