audit-logs: introduced new view to replace admin journal.
- audit logs will represent the all important actions made inside the system - raw view visible for super-admins
This commit is contained in:
parent
1e57ca4444
commit
7216dd64ff
33 changed files with 272 additions and 146 deletions
|
|
@ -29,6 +29,20 @@ def admin_routes(config):
|
|||
Admin prefixed routes
|
||||
"""
|
||||
|
||||
config.add_route(
|
||||
name='admin_audit_logs',
|
||||
pattern='/audit_logs')
|
||||
|
||||
config.add_route(
|
||||
name='pull_requests_global_0', # backward compat
|
||||
pattern='/pull_requests/{pull_request_id:[0-9]+}')
|
||||
config.add_route(
|
||||
name='pull_requests_global_1', # backward compat
|
||||
pattern='/pull-requests/{pull_request_id:[0-9]+}')
|
||||
config.add_route(
|
||||
name='pull_requests_global',
|
||||
pattern='/pull-request/{pull_request_id:[0-9]+}')
|
||||
|
||||
config.add_route(
|
||||
name='admin_settings_open_source',
|
||||
pattern='/settings/open_source')
|
||||
|
|
@ -93,6 +107,8 @@ def includeme(config):
|
|||
navigation_registry = NavigationRegistry(labs_active=labs_active)
|
||||
config.registry.registerUtility(navigation_registry)
|
||||
|
||||
# main admin routes
|
||||
config.add_route(name='admin_home', pattern=ADMIN_PREFIX)
|
||||
config.include(admin_routes, route_prefix=ADMIN_PREFIX)
|
||||
|
||||
# Scan module for configuration decorators.
|
||||
|
|
|
|||
|
|
@ -25,12 +25,25 @@ import datetime
|
|||
import pytest
|
||||
|
||||
from rhodecode.tests import *
|
||||
from rhodecode.tests.fixture import FIXTURES
|
||||
from rhodecode.model.db import UserLog
|
||||
from rhodecode.model.meta import Session
|
||||
from rhodecode.lib.utils2 import safe_unicode
|
||||
|
||||
dn = os.path.dirname
|
||||
FIXTURES = os.path.join(dn(dn(os.path.abspath(__file__))), 'fixtures')
|
||||
|
||||
def route_path(name, params=None, **kwargs):
|
||||
import urllib
|
||||
from rhodecode.apps._base import ADMIN_PREFIX
|
||||
|
||||
base_url = {
|
||||
'admin_home': ADMIN_PREFIX,
|
||||
'admin_audit_logs': ADMIN_PREFIX + '/audit_logs',
|
||||
|
||||
}[name].format(**kwargs)
|
||||
|
||||
if params:
|
||||
base_url = '{}?{}'.format(base_url, urllib.urlencode(params))
|
||||
return base_url
|
||||
|
||||
|
||||
class TestAdminController(TestController):
|
||||
|
|
@ -73,102 +86,102 @@ class TestAdminController(TestController):
|
|||
|
||||
def test_index(self):
|
||||
self.log_user()
|
||||
response = self.app.get(url(controller='admin/admin', action='index'))
|
||||
response.mustcontain('Admin journal')
|
||||
response = self.app.get(route_path('admin_audit_logs'))
|
||||
response.mustcontain('Admin audit logs')
|
||||
|
||||
def test_filter_all_entries(self):
|
||||
self.log_user()
|
||||
response = self.app.get(url(controller='admin/admin', action='index',))
|
||||
response = self.app.get(route_path('admin_audit_logs'))
|
||||
all_count = UserLog.query().count()
|
||||
response.mustcontain('%s entries' % all_count)
|
||||
|
||||
def test_filter_journal_filter_exact_match_on_repository(self):
|
||||
self.log_user()
|
||||
response = self.app.get(url(controller='admin/admin', action='index',
|
||||
filter='repository:rhodecode'))
|
||||
response = self.app.get(route_path('admin_audit_logs',
|
||||
params=dict(filter='repository:rhodecode')))
|
||||
response.mustcontain('3 entries')
|
||||
|
||||
def test_filter_journal_filter_exact_match_on_repository_CamelCase(self):
|
||||
self.log_user()
|
||||
response = self.app.get(url(controller='admin/admin', action='index',
|
||||
filter='repository:RhodeCode'))
|
||||
response = self.app.get(route_path('admin_audit_logs',
|
||||
params=dict(filter='repository:RhodeCode')))
|
||||
response.mustcontain('3 entries')
|
||||
|
||||
def test_filter_journal_filter_wildcard_on_repository(self):
|
||||
self.log_user()
|
||||
response = self.app.get(url(controller='admin/admin', action='index',
|
||||
filter='repository:*test*'))
|
||||
response = self.app.get(route_path('admin_audit_logs',
|
||||
params=dict(filter='repository:*test*')))
|
||||
response.mustcontain('862 entries')
|
||||
|
||||
def test_filter_journal_filter_prefix_on_repository(self):
|
||||
self.log_user()
|
||||
response = self.app.get(url(controller='admin/admin', action='index',
|
||||
filter='repository:test*'))
|
||||
response = self.app.get(route_path('admin_audit_logs',
|
||||
params=dict(filter='repository:test*')))
|
||||
response.mustcontain('257 entries')
|
||||
|
||||
def test_filter_journal_filter_prefix_on_repository_CamelCase(self):
|
||||
self.log_user()
|
||||
response = self.app.get(url(controller='admin/admin', action='index',
|
||||
filter='repository:Test*'))
|
||||
response = self.app.get(route_path('admin_audit_logs',
|
||||
params=dict(filter='repository:Test*')))
|
||||
response.mustcontain('257 entries')
|
||||
|
||||
def test_filter_journal_filter_prefix_on_repository_and_user(self):
|
||||
self.log_user()
|
||||
response = self.app.get(url(controller='admin/admin', action='index',
|
||||
filter='repository:test* AND username:demo'))
|
||||
response = self.app.get(route_path('admin_audit_logs',
|
||||
params=dict(filter='repository:test* AND username:demo')))
|
||||
response.mustcontain('130 entries')
|
||||
|
||||
def test_filter_journal_filter_prefix_on_repository_or_target_repo(self):
|
||||
self.log_user()
|
||||
response = self.app.get(url(controller='admin/admin', action='index',
|
||||
filter='repository:test* OR repository:rhodecode'))
|
||||
response = self.app.get(route_path('admin_audit_logs',
|
||||
params=dict(filter='repository:test* OR repository:rhodecode')))
|
||||
response.mustcontain('260 entries') # 257 + 3
|
||||
|
||||
def test_filter_journal_filter_exact_match_on_username(self):
|
||||
self.log_user()
|
||||
response = self.app.get(url(controller='admin/admin', action='index',
|
||||
filter='username:demo'))
|
||||
response = self.app.get(route_path('admin_audit_logs',
|
||||
params=dict(filter='username:demo')))
|
||||
response.mustcontain('1087 entries')
|
||||
|
||||
def test_filter_journal_filter_exact_match_on_username_camelCase(self):
|
||||
self.log_user()
|
||||
response = self.app.get(url(controller='admin/admin', action='index',
|
||||
filter='username:DemO'))
|
||||
response = self.app.get(route_path('admin_audit_logs',
|
||||
params=dict(filter='username:DemO')))
|
||||
response.mustcontain('1087 entries')
|
||||
|
||||
def test_filter_journal_filter_wildcard_on_username(self):
|
||||
self.log_user()
|
||||
response = self.app.get(url(controller='admin/admin', action='index',
|
||||
filter='username:*test*'))
|
||||
response = self.app.get(route_path('admin_audit_logs',
|
||||
params=dict(filter='username:*test*')))
|
||||
entries_count = UserLog.query().filter(UserLog.username.ilike('%test%')).count()
|
||||
response.mustcontain('{} entries'.format(entries_count))
|
||||
|
||||
def test_filter_journal_filter_prefix_on_username(self):
|
||||
self.log_user()
|
||||
response = self.app.get(url(controller='admin/admin', action='index',
|
||||
filter='username:demo*'))
|
||||
response = self.app.get(route_path('admin_audit_logs',
|
||||
params=dict(filter='username:demo*')))
|
||||
response.mustcontain('1101 entries')
|
||||
|
||||
def test_filter_journal_filter_prefix_on_user_or_other_user(self):
|
||||
self.log_user()
|
||||
response = self.app.get(url(controller='admin/admin', action='index',
|
||||
filter='username:demo OR username:volcan'))
|
||||
response = self.app.get(route_path('admin_audit_logs',
|
||||
params=dict(filter='username:demo OR username:volcan')))
|
||||
response.mustcontain('1095 entries') # 1087 + 8
|
||||
|
||||
def test_filter_journal_filter_wildcard_on_action(self):
|
||||
self.log_user()
|
||||
response = self.app.get(url(controller='admin/admin', action='index',
|
||||
filter='action:*pull_request*'))
|
||||
response = self.app.get(route_path('admin_audit_logs',
|
||||
params=dict(filter='action:*pull_request*')))
|
||||
response.mustcontain('187 entries')
|
||||
|
||||
def test_filter_journal_filter_on_date(self):
|
||||
self.log_user()
|
||||
response = self.app.get(url(controller='admin/admin', action='index',
|
||||
filter='date:20121010'))
|
||||
response = self.app.get(route_path('admin_audit_logs',
|
||||
params=dict(filter='date:20121010')))
|
||||
response.mustcontain('47 entries')
|
||||
|
||||
def test_filter_journal_filter_on_date_2(self):
|
||||
self.log_user()
|
||||
response = self.app.get(url(controller='admin/admin', action='index',
|
||||
filter='date:20121020'))
|
||||
response = self.app.get(route_path('admin_audit_logs',
|
||||
params=dict(filter='date:20121020')))
|
||||
response.mustcontain('17 entries')
|
||||
82
rhodecode/apps/admin/tests/test_admin_main_views.py
Normal file
82
rhodecode/apps/admin/tests/test_admin_main_views.py
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright (C) 2010-2017 RhodeCode GmbH
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License, version 3
|
||||
# (only), as published by the Free Software Foundation.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
# This program is dual-licensed. If you wish to learn more about the
|
||||
# RhodeCode Enterprise Edition, including its added features, Support services,
|
||||
# and proprietary license terms, please see https://rhodecode.com/licenses/
|
||||
|
||||
import pytest
|
||||
|
||||
from rhodecode.tests import TestController
|
||||
from rhodecode.tests.fixture import Fixture
|
||||
|
||||
fixture = Fixture()
|
||||
|
||||
|
||||
def route_path(name, params=None, **kwargs):
|
||||
import urllib
|
||||
from rhodecode.apps._base import ADMIN_PREFIX
|
||||
|
||||
base_url = {
|
||||
'admin_home': ADMIN_PREFIX,
|
||||
'pullrequest_show': '/{repo_name}/pull-request/{pull_request_id}',
|
||||
'pull_requests_global': ADMIN_PREFIX + '/pull-request/{pull_request_id}',
|
||||
'pull_requests_global_0': ADMIN_PREFIX + '/pull_requests/{pull_request_id}',
|
||||
'pull_requests_global_1': ADMIN_PREFIX + '/pull-requests/{pull_request_id}',
|
||||
|
||||
}[name].format(**kwargs)
|
||||
|
||||
if params:
|
||||
base_url = '{}?{}'.format(base_url, urllib.urlencode(params))
|
||||
return base_url
|
||||
|
||||
|
||||
class TestAdminMainView(TestController):
|
||||
|
||||
def test_redirect_admin_home(self):
|
||||
self.log_user()
|
||||
response = self.app.get(route_path('admin_home'), status=302)
|
||||
assert response.location.endswith('/audit_logs')
|
||||
|
||||
def test_redirect_pull_request_view(self, view):
|
||||
self.log_user()
|
||||
self.app.get(
|
||||
route_path(view, pull_request_id='xxxx'),
|
||||
status=404)
|
||||
|
||||
@pytest.mark.backends("git", "hg")
|
||||
@pytest.mark.parametrize('view', [
|
||||
'pull_requests_global',
|
||||
'pull_requests_global_0',
|
||||
'pull_requests_global_1',
|
||||
])
|
||||
def test_redirect_pull_request_view(self, view, pr_util):
|
||||
self.log_user()
|
||||
pull_request = pr_util.create_pull_request()
|
||||
pull_request_id = pull_request.pull_request_id
|
||||
|
||||
response = self.app.get(
|
||||
route_path(view, pull_request_id=pull_request_id),
|
||||
status=302)
|
||||
assert response.location.endswith(
|
||||
'pull-request/{}'.format(pull_request_id))
|
||||
|
||||
repo_name = pull_request.target_repo.repo_name
|
||||
redirect_url = route_path(
|
||||
'pullrequest_show', repo_name=repo_name,
|
||||
pull_request_id=pull_request.pull_request_id)
|
||||
|
||||
assert redirect_url in response.location
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright (C) 2010-2017 RhodeCode GmbH
|
||||
# Copyright (C) 2016-2017 RhodeCode GmbH
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License, version 3
|
||||
|
|
@ -18,42 +18,41 @@
|
|||
# RhodeCode Enterprise Edition, including its added features, Support services,
|
||||
# and proprietary license terms, please see https://rhodecode.com/licenses/
|
||||
|
||||
"""
|
||||
Controller for Admin panel of RhodeCode Enterprise
|
||||
"""
|
||||
|
||||
|
||||
import logging
|
||||
|
||||
from pylons import request, tmpl_context as c, url
|
||||
from pylons.controllers.util import redirect
|
||||
from pyramid.view import view_config
|
||||
from sqlalchemy.orm import joinedload
|
||||
|
||||
from rhodecode.model.db import UserLog, PullRequest
|
||||
from rhodecode.apps._base import BaseAppView
|
||||
from rhodecode.model.db import UserLog
|
||||
from rhodecode.lib.user_log_filter import user_log_filter
|
||||
from rhodecode.lib.auth import LoginRequired, HasPermissionAllDecorator
|
||||
from rhodecode.lib.base import BaseController, render
|
||||
from rhodecode.lib.utils2 import safe_int
|
||||
from rhodecode.lib.helpers import Page
|
||||
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class AdminController(BaseController):
|
||||
class AdminAuditLogsView(BaseAppView):
|
||||
def load_default_context(self):
|
||||
c = self._get_local_tmpl_context()
|
||||
self._register_global_c(c)
|
||||
return c
|
||||
|
||||
@LoginRequired()
|
||||
def __before__(self):
|
||||
super(AdminController, self).__before__()
|
||||
|
||||
@HasPermissionAllDecorator('hg.admin')
|
||||
def index(self):
|
||||
@view_config(
|
||||
route_name='admin_audit_logs', request_method='GET',
|
||||
renderer='rhodecode:templates/admin/admin_audit_logs.mako')
|
||||
def admin_audit_logs(self):
|
||||
c = self.load_default_context()
|
||||
|
||||
users_log = UserLog.query()\
|
||||
.options(joinedload(UserLog.user))\
|
||||
.options(joinedload(UserLog.repository))
|
||||
|
||||
# FILTERING
|
||||
c.search_term = request.GET.get('filter')
|
||||
c.search_term = self.request.GET.get('filter')
|
||||
try:
|
||||
users_log = user_log_filter(users_log, c.search_term)
|
||||
except Exception:
|
||||
|
|
@ -62,28 +61,13 @@ class AdminController(BaseController):
|
|||
|
||||
users_log = users_log.order_by(UserLog.action_date.desc())
|
||||
|
||||
p = safe_int(request.GET.get('page', 1), 1)
|
||||
p = safe_int(self.request.GET.get('page', 1), 1)
|
||||
|
||||
def url_generator(**kw):
|
||||
return url.current(filter=c.search_term, **kw)
|
||||
if c.search_term:
|
||||
kw['filter'] = c.search_term
|
||||
return self.request.current_route_path(_query=kw)
|
||||
|
||||
c.audit_logs = Page(users_log, page=p, items_per_page=10,
|
||||
url=url_generator)
|
||||
c.log_data = render('admin/admin_log.mako')
|
||||
|
||||
if request.is_xhr:
|
||||
return c.log_data
|
||||
return render('admin/admin.mako')
|
||||
|
||||
# global redirect doesn't need permissions
|
||||
def pull_requests(self, pull_request_id):
|
||||
"""
|
||||
Global redirect for Pull Requests
|
||||
|
||||
:param pull_request_id: id of pull requests in the system
|
||||
"""
|
||||
pull_request = PullRequest.get_or_404(pull_request_id)
|
||||
repo_name = pull_request.target_repo.repo_name
|
||||
return redirect(url(
|
||||
'pullrequest_show', repo_name=repo_name,
|
||||
pull_request_id=pull_request_id))
|
||||
url=url_generator)
|
||||
return self._get_template_context(c)
|
||||
63
rhodecode/apps/admin/views/main_views.py
Normal file
63
rhodecode/apps/admin/views/main_views.py
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright (C) 2016-2017 RhodeCode GmbH
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License, version 3
|
||||
# (only), as published by the Free Software Foundation.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
# This program is dual-licensed. If you wish to learn more about the
|
||||
# RhodeCode Enterprise Edition, including its added features, Support services,
|
||||
# and proprietary license terms, please see https://rhodecode.com/licenses/
|
||||
|
||||
import logging
|
||||
|
||||
|
||||
from pyramid.httpexceptions import HTTPFound
|
||||
from pyramid.view import view_config
|
||||
|
||||
from rhodecode.apps._base import BaseAppView
|
||||
from rhodecode.lib import helpers as h
|
||||
from rhodecode.lib.auth import (LoginRequired, HasPermissionAllDecorator)
|
||||
from rhodecode.model.db import PullRequest
|
||||
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class AdminMainView(BaseAppView):
|
||||
|
||||
@LoginRequired()
|
||||
@HasPermissionAllDecorator('hg.admin')
|
||||
@view_config(
|
||||
route_name='admin_home', request_method='GET')
|
||||
def admin_main(self):
|
||||
# redirect _admin to audit logs...
|
||||
raise HTTPFound(h.route_path('admin_audit_logs'))
|
||||
|
||||
@LoginRequired()
|
||||
@view_config(route_name='pull_requests_global_0', request_method='GET')
|
||||
@view_config(route_name='pull_requests_global_1', request_method='GET')
|
||||
@view_config(route_name='pull_requests_global', request_method='GET')
|
||||
def pull_requests(self):
|
||||
"""
|
||||
Global redirect for Pull Requests
|
||||
|
||||
:param pull_request_id: id of pull requests in the system
|
||||
"""
|
||||
|
||||
pull_request_id = self.request.matchdict.get('pull_request_id')
|
||||
pull_request = PullRequest.get_or_404(pull_request_id, pyramid_exc=True)
|
||||
repo_name = pull_request.target_repo.repo_name
|
||||
|
||||
raise HTTPFound(
|
||||
h.route_path('pullrequest_show', repo_name=repo_name,
|
||||
pull_request_id=pull_request_id))
|
||||
|
|
@ -41,6 +41,12 @@ def includeme(config):
|
|||
name='bookmarks_home',
|
||||
pattern='/{repo_name:.*?[^/]}/bookmarks', repo_route=True)
|
||||
|
||||
# Pull Requests
|
||||
config.add_route(
|
||||
name='pullrequest_show',
|
||||
pattern='/{repo_name:.*?[^/]}/pull-request/{pull_request_id}',
|
||||
repo_route=True)
|
||||
|
||||
# Settings
|
||||
config.add_route(
|
||||
name='edit_repo',
|
||||
|
|
|
|||
|
|
@ -561,22 +561,6 @@ def make_map(config):
|
|||
action='show', conditions={'method': ['GET']},
|
||||
requirements=URL_NAME_REQUIREMENTS)
|
||||
|
||||
# ADMIN MAIN PAGES
|
||||
with rmap.submapper(path_prefix=ADMIN_PREFIX,
|
||||
controller='admin/admin') as m:
|
||||
m.connect('admin_home', '', action='index')
|
||||
m.connect('admin_add_repo', '/add_repo/{new_repo:[a-z0-9\. _-]*}',
|
||||
action='add_repo')
|
||||
m.connect(
|
||||
'pull_requests_global_0', '/pull_requests/{pull_request_id:[0-9]+}',
|
||||
action='pull_requests')
|
||||
m.connect(
|
||||
'pull_requests_global_1', '/pull-requests/{pull_request_id:[0-9]+}',
|
||||
action='pull_requests')
|
||||
m.connect(
|
||||
'pull_requests_global', '/pull-request/{pull_request_id:[0-9]+}',
|
||||
action='pull_requests')
|
||||
|
||||
# USER JOURNAL
|
||||
rmap.connect('journal', '%s/journal' % (ADMIN_PREFIX,),
|
||||
controller='journal', action='index')
|
||||
|
|
|
|||
|
|
@ -34,11 +34,11 @@ from webob.exc import HTTPBadRequest
|
|||
from pylons import request, tmpl_context as c, response, url
|
||||
from pylons.i18n.translation import _
|
||||
|
||||
from rhodecode.controllers.admin.admin import user_log_filter
|
||||
from rhodecode.model.db import UserLog, UserFollowing, User, UserApiKeys
|
||||
from rhodecode.model.meta import Session
|
||||
import rhodecode.lib.helpers as h
|
||||
from rhodecode.lib.helpers import Page
|
||||
from rhodecode.lib.user_log_filter import user_log_filter
|
||||
from rhodecode.lib.auth import LoginRequired, NotAnonymous, CSRFRequired
|
||||
from rhodecode.lib.base import BaseController, render
|
||||
from rhodecode.lib.utils2 import safe_int, AttributeDict
|
||||
|
|
|
|||
|
|
@ -69,6 +69,11 @@ function registerRCRoutes() {
|
|||
pyroutes.register('repo_integrations_create', '%(repo_name)s/settings/integrations/%(integration)s/new', ['repo_name', 'integration']);
|
||||
pyroutes.register('repo_integrations_edit', '%(repo_name)s/settings/integrations/%(integration)s/%(integration_id)s', ['repo_name', 'integration', 'integration_id']);
|
||||
pyroutes.register('ops_ping', '_admin/ops/ping', []);
|
||||
pyroutes.register('admin_home', '/_admin', []);
|
||||
pyroutes.register('admin_audit_logs', '_admin/audit_logs', []);
|
||||
pyroutes.register('pull_requests_global_0', '_admin/pull_requests/%(pull_request_id)s', ['pull_request_id']);
|
||||
pyroutes.register('pull_requests_global_1', '_admin/pull-requests/%(pull_request_id)s', ['pull_request_id']);
|
||||
pyroutes.register('pull_requests_global', '_admin/pull-request/%(pull_request_id)s', ['pull_request_id']);
|
||||
pyroutes.register('admin_settings_open_source', '_admin/settings/open_source', []);
|
||||
pyroutes.register('admin_settings_vcs_svn_generate_cfg', '_admin/settings/vcs/svn_generate_cfg', []);
|
||||
pyroutes.register('admin_settings_system', '_admin/settings/system', []);
|
||||
|
|
@ -100,6 +105,7 @@ function registerRCRoutes() {
|
|||
pyroutes.register('tags_home', '/%(repo_name)s/tags', ['repo_name']);
|
||||
pyroutes.register('branches_home', '/%(repo_name)s/branches', ['repo_name']);
|
||||
pyroutes.register('bookmarks_home', '/%(repo_name)s/bookmarks', ['repo_name']);
|
||||
pyroutes.register('pullrequest_show', '/%(repo_name)s/pull-request/%(pull_request_id)s', ['repo_name', 'pull_request_id']);
|
||||
pyroutes.register('edit_repo', '/%(repo_name)s/settings', ['repo_name']);
|
||||
pyroutes.register('edit_repo_advanced', '/%(repo_name)s/settings/advanced', ['repo_name']);
|
||||
pyroutes.register('edit_repo_advanced_delete', '/%(repo_name)s/settings/advanced/delete', ['repo_name']);
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
<%inherit file="/base/base.mako"/>
|
||||
|
||||
<%def name="title()">
|
||||
${_('Admin journal')}
|
||||
${_('Admin audit logs')}
|
||||
%if c.rhodecode_name:
|
||||
· ${h.branding(c.rhodecode_name)}
|
||||
%endif
|
||||
|
|
@ -10,9 +10,9 @@
|
|||
|
||||
<%def name="breadcrumbs_links()">
|
||||
${h.form(None, id_="filter_form", method="get")}
|
||||
<input class="q_filter_box ${'' if c.search_term else 'initial'}" id="j_filter" size="15" type="text" name="filter" value="${c.search_term or ''}" placeholder="${_('journal filter...')}"/>
|
||||
<input class="q_filter_box ${'' if c.search_term else 'initial'}" id="j_filter" size="15" type="text" name="filter" value="${c.search_term or ''}" placeholder="${_('filter...')}"/>
|
||||
<input type='submit' value="${_('filter')}" class="btn" />
|
||||
${_('Admin journal')} - ${ungettext('%s entry', '%s entries', c.audit_logs.item_count) % (c.audit_logs.item_count)}
|
||||
${_('Audit logs')} - ${_ungettext('%s entry', '%s entries', c.audit_logs.item_count) % (c.audit_logs.item_count)}
|
||||
${h.end_form()}
|
||||
<p class="tooltip filterexample" title="${h.tooltip(h.journal_filter_help())}">${_('Example Queries')}</p>
|
||||
</%def>
|
||||
|
|
@ -29,7 +29,7 @@
|
|||
<!-- end box / title -->
|
||||
<div class="table">
|
||||
<div id="user_log">
|
||||
${c.log_data}
|
||||
<%include file="/admin/admin_log_base.mako" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
## -*- coding: utf-8 -*-
|
||||
<%include file="/admin/admin_log_base.mako" />
|
||||
|
||||
<script type="text/javascript">
|
||||
$(function(){
|
||||
//because this is loaded on every pjax request, it must run only once
|
||||
//therefore the .one method
|
||||
$(document).on('pjax:complete',function(){
|
||||
show_more_event();
|
||||
});
|
||||
|
||||
$(document).pjax('#user_log .pager_link', '#user_log');
|
||||
});
|
||||
</script>
|
||||
|
||||
|
|
@ -9,7 +9,7 @@
|
|||
</%def>
|
||||
|
||||
<%def name="breadcrumbs_links()">
|
||||
${h.link_to(_('Admin'),h.url('admin_home'))}
|
||||
${h.link_to(_('Admin'),h.route_path('admin_home'))}
|
||||
»
|
||||
${_('Authentication Plugins')}
|
||||
</%def>
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
</%def>
|
||||
|
||||
<%def name="breadcrumbs_links()">
|
||||
${h.link_to(_('Admin'),h.url('admin_home'))}
|
||||
${h.link_to(_('Admin'),h.route_path('admin_home'))}
|
||||
»
|
||||
${h.link_to(_('Authentication Plugins'),request.resource_path(resource.__parent__, route_name='auth_home'))}
|
||||
»
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
</%def>
|
||||
|
||||
<%def name="breadcrumbs_links()">
|
||||
${h.link_to(_('Admin'),h.url('admin_home'))}
|
||||
${h.link_to(_('Admin'),h.route_path('admin_home'))}
|
||||
»
|
||||
${_('Repositories defaults')}
|
||||
</%def>
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
</%def>
|
||||
|
||||
<%def name="breadcrumbs_links()">
|
||||
${h.link_to(_('Admin'),h.url('admin_home'))}
|
||||
${h.link_to(_('Admin'),h.route_path('admin_home'))}
|
||||
»
|
||||
${_('Integrations')}
|
||||
</%def>
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
repo_name=c.repo.repo_name,
|
||||
integration=current_IntegrationType.key))}
|
||||
%elif c.repo_group:
|
||||
${h.link_to(_('Admin'),h.url('admin_home'))}
|
||||
${h.link_to(_('Admin'),h.route_path('admin_home'))}
|
||||
»
|
||||
${h.link_to(_('Repository Groups'),h.url('repo_groups'))}
|
||||
»
|
||||
|
|
@ -25,7 +25,7 @@
|
|||
repo_group_name=c.repo_group.group_name,
|
||||
integration=current_IntegrationType.key))}
|
||||
%else:
|
||||
${h.link_to(_('Admin'),h.url('admin_home'))}
|
||||
${h.link_to(_('Admin'),h.route_path('admin_home'))}
|
||||
»
|
||||
${h.link_to(_('Settings'),h.url('admin_settings'))}
|
||||
»
|
||||
|
|
|
|||
|
|
@ -5,13 +5,13 @@
|
|||
%if c.repo:
|
||||
${h.link_to('Settings',h.route_path('edit_repo', repo_name=c.repo.repo_name))}
|
||||
%elif c.repo_group:
|
||||
${h.link_to(_('Admin'),h.url('admin_home'))}
|
||||
${h.link_to(_('Admin'),h.route_path('admin_home'))}
|
||||
»
|
||||
${h.link_to(_('Repository Groups'),h.url('repo_groups'))}
|
||||
»
|
||||
${h.link_to(c.repo_group.group_name,h.url('edit_repo_group', group_name=c.repo_group.group_name))}
|
||||
%else:
|
||||
${h.link_to(_('Admin'),h.url('admin_home'))}
|
||||
${h.link_to(_('Admin'),h.route_path('admin_home'))}
|
||||
»
|
||||
${h.link_to(_('Settings'),h.url('admin_settings'))}
|
||||
%endif
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
»
|
||||
${h.link_to(_('Integrations'),request.route_url(route_name='repo_integrations_home', repo_name=c.repo.repo_name))}
|
||||
%elif c.repo_group:
|
||||
${h.link_to(_('Admin'),h.url('admin_home'))}
|
||||
${h.link_to(_('Admin'),h.route_path('admin_home'))}
|
||||
»
|
||||
${h.link_to(_('Repository Groups'),h.url('repo_groups'))}
|
||||
»
|
||||
|
|
@ -16,7 +16,7 @@
|
|||
»
|
||||
${h.link_to(_('Integrations'),request.route_url(route_name='repo_group_integrations_home', repo_group_name=c.repo_group.group_name))}
|
||||
%else:
|
||||
${h.link_to(_('Admin'),h.url('admin_home'))}
|
||||
${h.link_to(_('Admin'),h.route_path('admin_home'))}
|
||||
»
|
||||
${h.link_to(_('Settings'),h.url('admin_settings'))}
|
||||
»
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
</%def>
|
||||
|
||||
<%def name="breadcrumbs_links()">
|
||||
${h.link_to(_('Admin'),h.url('admin_home'))}
|
||||
${h.link_to(_('Admin'),h.route_path('admin_home'))}
|
||||
»
|
||||
${_('Permissions')}
|
||||
</%def>
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
</%def>
|
||||
|
||||
<%def name="breadcrumbs_links()">
|
||||
${h.link_to(_('Admin'),h.url('admin_home'))}
|
||||
${h.link_to(_('Admin'),h.route_path('admin_home'))}
|
||||
»
|
||||
${h.link_to(_('Repository groups'),h.url('repo_groups'))}
|
||||
»
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
</%def>
|
||||
|
||||
<%def name="breadcrumbs_links()">
|
||||
${h.link_to(_('Admin'),h.url('admin_home'))}
|
||||
${h.link_to(_('Admin'),h.route_path('admin_home'))}
|
||||
»
|
||||
${h.link_to(_('Repository Groups'),h.url('repo_groups'))}
|
||||
%if c.repo_group.parent_group:
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
<%def name="breadcrumbs_links()">
|
||||
<input class="q_filter_box" id="q_filter" size="15" type="text" name="filter" placeholder="${_('quick filter...')}" value=""/>
|
||||
${h.link_to(_('Admin'),h.url('admin_home'))} » <span id="repo_group_count">0</span> ${_('repository groups')}
|
||||
${h.link_to(_('Admin'),h.route_path('admin_home'))} » <span id="repo_group_count">0</span> ${_('repository groups')}
|
||||
</%def>
|
||||
|
||||
<%def name="menu_bar_nav()">
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
<%def name="breadcrumbs_links()">
|
||||
%if c.rhodecode_user.is_admin:
|
||||
${h.link_to(_('Admin'),h.url('admin_home'))}
|
||||
${h.link_to(_('Admin'),h.route_path('admin_home'))}
|
||||
»
|
||||
${h.link_to(_('Repositories'),h.url('repos'))}
|
||||
%else:
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
<%def name="breadcrumbs_links()">
|
||||
<input class="q_filter_box" id="q_filter" size="15" type="text" name="filter" placeholder="${_('quick filter...')}" value=""/>
|
||||
${h.link_to(_('Admin'),h.url('admin_home'))} » <span id="repo_count">0</span> ${_('repositories')}
|
||||
${h.link_to(_('Admin'),h.route_path('admin_home'))} » <span id="repo_count">0</span> ${_('repositories')}
|
||||
</%def>
|
||||
|
||||
<%def name="menu_bar_nav()">
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
</%def>
|
||||
|
||||
<%def name="breadcrumbs_links()">
|
||||
${h.link_to(_('Admin'),h.url('admin_home'))}
|
||||
${h.link_to(_('Admin'),h.route_path('admin_home'))}
|
||||
»
|
||||
${_('Settings')}
|
||||
</%def>
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
%endif
|
||||
</%def>
|
||||
<%def name="breadcrumbs_links()">
|
||||
${h.link_to(_('Admin'),h.url('admin_home'))}
|
||||
${h.link_to(_('Admin'),h.route_path('admin_home'))}
|
||||
»
|
||||
${h.link_to(_('User groups'),h.url('users_groups'))}
|
||||
»
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
</%def>
|
||||
|
||||
<%def name="breadcrumbs_links()">
|
||||
${h.link_to(_('Admin'),h.url('admin_home'))}
|
||||
${h.link_to(_('Admin'),h.route_path('admin_home'))}
|
||||
»
|
||||
${h.link_to(_('User Groups'),h.url('users_groups'))}
|
||||
»
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
<%def name="breadcrumbs_links()">
|
||||
<input class="q_filter_box" id="q_filter" size="15" type="text" name="filter" placeholder="${_('quick filter...')}" value=""/>
|
||||
${h.link_to(_('Admin'),h.url('admin_home'))} » <span id="user_group_count">0</span> ${_('user groups')}
|
||||
${h.link_to(_('Admin'),h.route_path('admin_home'))} » <span id="user_group_count">0</span> ${_('user groups')}
|
||||
</%def>
|
||||
|
||||
<%def name="menu_bar_nav()">
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
%endif
|
||||
</%def>
|
||||
<%def name="breadcrumbs_links()">
|
||||
${h.link_to(_('Admin'),h.url('admin_home'))}
|
||||
${h.link_to(_('Admin'),h.route_path('admin_home'))}
|
||||
»
|
||||
${h.link_to(_('Users'),h.route_path('users'))}
|
||||
»
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
</%def>
|
||||
|
||||
<%def name="breadcrumbs_links()">
|
||||
${h.link_to(_('Admin'),h.url('admin_home'))}
|
||||
${h.link_to(_('Admin'),h.route_path('admin_home'))}
|
||||
»
|
||||
${h.link_to(_('Users'),h.route_path('users'))}
|
||||
»
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
<%def name="breadcrumbs_links()">
|
||||
<input class="q_filter_box" id="q_filter" size="15" type="text" name="filter" placeholder="${_('quick filter...')}" value=""/>
|
||||
${h.link_to(_('Admin'),h.url('admin_home'))} » <span id="user_count">0</span>
|
||||
${h.link_to(_('Admin'),h.route_path('admin_home'))} » <span id="user_count">0</span>
|
||||
</%def>
|
||||
|
||||
<%def name="menu_bar_nav()">
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@
|
|||
|
||||
<%def name="admin_menu()">
|
||||
<ul class="admin_menu submenu">
|
||||
<li><a href="${h.url('admin_home')}">${_('Admin journal')}</a></li>
|
||||
<li><a href="${h.route_path('admin_audit_logs')}">${_('Admin audit logs')}</a></li>
|
||||
<li><a href="${h.url('repos')}">${_('Repositories')}</a></li>
|
||||
<li><a href="${h.url('repo_groups')}">${_('Repository groups')}</a></li>
|
||||
<li><a href="${h.route_path('users')}">${_('Users')}</a></li>
|
||||
|
|
|
|||
|
|
@ -53,19 +53,6 @@ class TestPullrequestsController:
|
|||
'pullrequest', repo_name=repo_name)
|
||||
response.mustcontain(create_pr_link)
|
||||
|
||||
def test_global_redirect_of_pr(self, backend, pr_util):
|
||||
pull_request = pr_util.create_pull_request()
|
||||
|
||||
response = self.app.get(
|
||||
url('pull_requests_global',
|
||||
pull_request_id=pull_request.pull_request_id))
|
||||
|
||||
repo_name = pull_request.target_repo.repo_name
|
||||
redirect_url = url('pullrequest_show', repo_name=repo_name,
|
||||
pull_request_id=pull_request.pull_request_id)
|
||||
assert response.status == '302 Found'
|
||||
assert redirect_url in response.location
|
||||
|
||||
def test_create_pr_form_with_raw_commit_id(self, backend):
|
||||
repo = backend.repo
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue