admin: ported settings controller to pyramid.

- NavList dropped pyramid flag as it's pure pyramid now
This commit is contained in:
Marcin Kuzminski 2017-11-09 15:40:31 +01:00
parent 36d19561bc
commit 9c110539e0
20 changed files with 657 additions and 478 deletions

View file

@ -20,7 +20,6 @@
from rhodecode.apps._base import ADMIN_PREFIX
from rhodecode.lib.utils2 import str2bool
def admin_routes(config):
@ -82,6 +81,88 @@ def admin_routes(config):
name='admin_defaults_repositories_update',
pattern='/defaults/repositories/update')
# admin settings
config.add_route(
name='admin_settings',
pattern='/settings')
config.add_route(
name='admin_settings_update',
pattern='/settings/update')
config.add_route(
name='admin_settings_global',
pattern='/settings/global')
config.add_route(
name='admin_settings_global_update',
pattern='/settings/global/update')
config.add_route(
name='admin_settings_vcs',
pattern='/settings/vcs')
config.add_route(
name='admin_settings_vcs_update',
pattern='/settings/vcs/update')
config.add_route(
name='admin_settings_vcs_svn_pattern_delete',
pattern='/settings/vcs/svn_pattern_delete')
config.add_route(
name='admin_settings_mapping',
pattern='/settings/mapping')
config.add_route(
name='admin_settings_mapping_update',
pattern='/settings/mapping/update')
config.add_route(
name='admin_settings_visual',
pattern='/settings/visual')
config.add_route(
name='admin_settings_visual_update',
pattern='/settings/visual/update')
config.add_route(
name='admin_settings_issuetracker',
pattern='/settings/issue-tracker')
config.add_route(
name='admin_settings_issuetracker_update',
pattern='/settings/issue-tracker/update')
config.add_route(
name='admin_settings_issuetracker_test',
pattern='/settings/issue-tracker/test')
config.add_route(
name='admin_settings_issuetracker_delete',
pattern='/settings/issue-tracker/delete')
config.add_route(
name='admin_settings_email',
pattern='/settings/email')
config.add_route(
name='admin_settings_email_update',
pattern='/settings/email/update')
config.add_route(
name='admin_settings_hooks',
pattern='/settings/hooks')
config.add_route(
name='admin_settings_hooks_update',
pattern='/settings/hooks/update')
config.add_route(
name='admin_settings_hooks_delete',
pattern='/settings/hooks/delete')
config.add_route(
name='admin_settings_search',
pattern='/settings/search')
config.add_route(
name='admin_settings_labs',
pattern='/settings/labs')
config.add_route(
name='admin_settings_labs_update',
pattern='/settings/labs/update')
# global permissions
config.add_route(
@ -236,7 +317,7 @@ def admin_routes(config):
config.add_route(
name='edit_user_ips_delete',
pattern='/users/{user_id:\d+}/edit/ips/delete',
user_route_with_default=True) # enabled for default user too
user_route_with_default=True) # enabled for default user too
# user perms
config.add_route(

View file

@ -46,65 +46,53 @@ class NavEntry(object):
be removed as soon as we are fully migrated to pyramid.
"""
def __init__(self, key, name, view_name, pyramid=False):
def __init__(self, key, name, view_name):
self.key = key
self.name = name
self.view_name = view_name
self.pyramid = pyramid
def generate_url(self, request):
if self.pyramid:
if hasattr(request, 'route_path'):
return request.route_path(self.view_name)
else:
# TODO: johbo: Remove this after migrating to pyramid.
# We need the pyramid request here to generate URLs to pyramid
# views from within pylons views.
from pyramid.threadlocal import get_current_request
pyramid_request = get_current_request()
return pyramid_request.route_path(self.view_name)
else:
from pylons import url
return url(self.view_name)
return request.route_path(self.view_name)
def get_localized_name(self, request):
if hasattr(request, 'translate'):
return request.translate(self.name)
else:
# TODO(marcink): Remove this after migrating to pyramid
from pyramid.threadlocal import get_current_request
pyramid_request = get_current_request()
return pyramid_request.translate(self.name)
return request.translate(self.name)
@implementer(IAdminNavigationRegistry)
class NavigationRegistry(object):
_base_entries = [
NavEntry('global', _('Global'), 'admin_settings_global'),
NavEntry('vcs', _('VCS'), 'admin_settings_vcs'),
NavEntry('visual', _('Visual'), 'admin_settings_visual'),
NavEntry('mapping', _('Remap and Rescan'), 'admin_settings_mapping'),
NavEntry('global', _('Global'),
'admin_settings_global'),
NavEntry('vcs', _('VCS'),
'admin_settings_vcs'),
NavEntry('visual', _('Visual'),
'admin_settings_visual'),
NavEntry('mapping', _('Remap and Rescan'),
'admin_settings_mapping'),
NavEntry('issuetracker', _('Issue Tracker'),
'admin_settings_issuetracker'),
NavEntry('email', _('Email'), 'admin_settings_email'),
NavEntry('hooks', _('Hooks'), 'admin_settings_hooks'),
NavEntry('search', _('Full Text Search'), 'admin_settings_search'),
NavEntry('email', _('Email'),
'admin_settings_email'),
NavEntry('hooks', _('Hooks'),
'admin_settings_hooks'),
NavEntry('search', _('Full Text Search'),
'admin_settings_search'),
NavEntry('integrations', _('Integrations'),
'global_integrations_home', pyramid=True),
'global_integrations_home'),
NavEntry('system', _('System Info'),
'admin_settings_system', pyramid=True),
'admin_settings_system'),
NavEntry('process_management', _('Processes'),
'admin_settings_process_management', pyramid=True),
'admin_settings_process_management'),
NavEntry('sessions', _('User Sessions'),
'admin_settings_sessions', pyramid=True),
'admin_settings_sessions'),
NavEntry('open_source', _('Open Source Licenses'),
'admin_settings_open_source', pyramid=True),
'admin_settings_open_source'),
]
_labs_entry = NavEntry('labs', _('Labs'), 'admin_settings_labs')
_labs_entry = NavEntry('labs', _('Labs'),
'admin_settings_labs')
def __init__(self, labs_active=False):
self._registered_entries = collections.OrderedDict()

View file

@ -27,7 +27,7 @@ from rhodecode.lib.utils2 import md5
from rhodecode.model.db import RhodeCodeUi
from rhodecode.model.meta import Session
from rhodecode.model.settings import SettingsModel, IssueTrackerSettingsModel
from rhodecode.tests import url, assert_session_flash
from rhodecode.tests import assert_session_flash
from rhodecode.tests.utils import AssertResponse
@ -35,6 +35,78 @@ UPDATE_DATA_QUALNAME = (
'rhodecode.apps.admin.views.system_info.AdminSystemInfoSettingsView.get_update_data')
def route_path(name, params=None, **kwargs):
import urllib
from rhodecode.apps._base import ADMIN_PREFIX
base_url = {
'admin_settings':
ADMIN_PREFIX +'/settings',
'admin_settings_update':
ADMIN_PREFIX + '/settings/update',
'admin_settings_global':
ADMIN_PREFIX + '/settings/global',
'admin_settings_global_update':
ADMIN_PREFIX + '/settings/global/update',
'admin_settings_vcs':
ADMIN_PREFIX + '/settings/vcs',
'admin_settings_vcs_update':
ADMIN_PREFIX + '/settings/vcs/update',
'admin_settings_vcs_svn_pattern_delete':
ADMIN_PREFIX + '/settings/vcs/svn_pattern_delete',
'admin_settings_mapping':
ADMIN_PREFIX + '/settings/mapping',
'admin_settings_mapping_update':
ADMIN_PREFIX + '/settings/mapping/update',
'admin_settings_visual':
ADMIN_PREFIX + '/settings/visual',
'admin_settings_visual_update':
ADMIN_PREFIX + '/settings/visual/update',
'admin_settings_issuetracker':
ADMIN_PREFIX + '/settings/issue-tracker',
'admin_settings_issuetracker_update':
ADMIN_PREFIX + '/settings/issue-tracker/update',
'admin_settings_issuetracker_test':
ADMIN_PREFIX + '/settings/issue-tracker/test',
'admin_settings_issuetracker_delete':
ADMIN_PREFIX + '/settings/issue-tracker/delete',
'admin_settings_email':
ADMIN_PREFIX + '/settings/email',
'admin_settings_email_update':
ADMIN_PREFIX + '/settings/email/update',
'admin_settings_hooks':
ADMIN_PREFIX + '/settings/hooks',
'admin_settings_hooks_update':
ADMIN_PREFIX + '/settings/hooks/update',
'admin_settings_hooks_delete':
ADMIN_PREFIX + '/settings/hooks/delete',
'admin_settings_search':
ADMIN_PREFIX + '/settings/search',
'admin_settings_labs':
ADMIN_PREFIX + '/settings/labs',
'admin_settings_labs_update':
ADMIN_PREFIX + '/settings/labs/update',
'admin_settings_sessions':
ADMIN_PREFIX + '/settings/sessions',
'admin_settings_sessions_cleanup':
ADMIN_PREFIX + '/settings/sessions/cleanup',
'admin_settings_system':
ADMIN_PREFIX + '/settings/system',
'admin_settings_system_update':
ADMIN_PREFIX + '/settings/system/updates',
'admin_settings_open_source':
ADMIN_PREFIX + '/settings/open_source',
}[name].format(**kwargs)
if params:
base_url = '{}?{}'.format(base_url, urllib.urlencode(params))
return base_url
@pytest.mark.usefixtures('autologin_user', 'app')
class TestAdminSettingsController(object):
@ -47,12 +119,12 @@ class TestAdminSettingsController(object):
'admin_settings_hooks',
'admin_settings_search',
])
def test_simple_get(self, urlname, app):
app.get(url(urlname))
def test_simple_get(self, urlname):
self.app.get(route_path(urlname))
def test_create_custom_hook(self, csrf_token):
response = self.app.post(
url('admin_settings_hooks'),
route_path('admin_settings_hooks_update'),
params={
'new_hook_ui_key': 'test_hooks_1',
'new_hook_ui_value': 'cd /tmp',
@ -64,7 +136,7 @@ class TestAdminSettingsController(object):
def test_create_custom_hook_delete(self, csrf_token):
response = self.app.post(
url('admin_settings_hooks'),
route_path('admin_settings_hooks_update'),
params={
'new_hook_ui_key': 'test_hooks_2',
'new_hook_ui_value': 'cd /tmp2',
@ -78,9 +150,9 @@ class TestAdminSettingsController(object):
# delete
self.app.post(
url('admin_settings_hooks'),
route_path('admin_settings_hooks_delete'),
params={'hook_id': hook_id, 'csrf_token': csrf_token})
response = self.app.get(url('admin_settings_hooks'))
response = self.app.get(route_path('admin_settings_hooks'))
response.mustcontain(no=['test_hooks_2'])
response.mustcontain(no=['cd /tmp2'])
@ -135,7 +207,6 @@ class TestAdminSettingsGlobal(object):
def test_title_change(self, csrf_token):
old_title = 'RhodeCode'
new_title = old_title + '_changed'
for new_title in ['Changed', 'Żółwik', old_title]:
response = self.post_and_verify_settings({
@ -161,7 +232,8 @@ class TestAdminSettingsGlobal(object):
'rhodecode_personal_repo_group_pattern': '${username}',
}
params.update(settings)
response = self.app.post(url('admin_settings_global'), params=params)
response = self.app.post(
route_path('admin_settings_global_update'), params=params)
assert_session_flash(response, 'Updated application settings')
app_settings = SettingsModel().get_all_settings()
@ -175,8 +247,8 @@ class TestAdminSettingsGlobal(object):
@pytest.mark.usefixtures('autologin_user', 'app')
class TestAdminSettingsVcs(object):
def test_contains_svn_default_patterns(self, app):
response = app.get(url('admin_settings_vcs'))
def test_contains_svn_default_patterns(self):
response = self.app.get(route_path('admin_settings_vcs'))
expected_patterns = [
'/trunk',
'/branches/*',
@ -186,7 +258,7 @@ class TestAdminSettingsVcs(object):
response.mustcontain(pattern)
def test_add_new_svn_branch_and_tag_pattern(
self, app, backend_svn, form_defaults, disable_sql_cache,
self, backend_svn, form_defaults, disable_sql_cache,
csrf_token):
form_defaults.update({
'new_svn_branch': '/exp/branches/*',
@ -194,8 +266,9 @@ class TestAdminSettingsVcs(object):
'csrf_token': csrf_token,
})
response = app.post(
url('admin_settings_vcs'), params=form_defaults, status=302)
response = self.app.post(
route_path('admin_settings_vcs_update'),
params=form_defaults, status=302)
response = response.follow()
# Expect to find the new values on the page
@ -208,12 +281,12 @@ class TestAdminSettingsVcs(object):
assert 'important_tags/v0.5' in repo.tags
def test_add_same_svn_value_twice_shows_an_error_message(
self, app, form_defaults, csrf_token, settings_util):
self, form_defaults, csrf_token, settings_util):
settings_util.create_rhodecode_ui('vcs_svn_branch', '/test')
settings_util.create_rhodecode_ui('vcs_svn_tag', '/test')
response = app.post(
url('admin_settings_vcs'),
response = self.app.post(
route_path('admin_settings_vcs_update'),
params={
'paths_root_path': form_defaults['paths_root_path'],
'new_svn_branch': '/test',
@ -230,14 +303,13 @@ class TestAdminSettingsVcs(object):
'vcs_svn_tag',
])
def test_delete_svn_patterns(
self, section, app, csrf_token, settings_util):
self, section, csrf_token, settings_util):
setting = settings_util.create_rhodecode_ui(
section, '/test_delete', cleanup=False)
app.post(
url('admin_settings_vcs'),
self.app.post(
route_path('admin_settings_vcs_svn_pattern_delete'),
params={
'_method': 'delete',
'delete_svn_pattern': setting.ui_id,
'csrf_token': csrf_token},
headers={'X-REQUESTED-WITH': 'XMLHttpRequest'})
@ -246,25 +318,24 @@ class TestAdminSettingsVcs(object):
'vcs_svn_branch',
'vcs_svn_tag',
])
def test_delete_svn_patterns_raises_400_when_no_xhr(
self, section, app, csrf_token, settings_util):
def test_delete_svn_patterns_raises_404_when_no_xhr(
self, section, csrf_token, settings_util):
setting = settings_util.create_rhodecode_ui(section, '/test_delete')
app.post(
url('admin_settings_vcs'),
self.app.post(
route_path('admin_settings_vcs_svn_pattern_delete'),
params={
'_method': 'delete',
'delete_svn_pattern': setting.ui_id,
'csrf_token': csrf_token},
status=400)
status=404)
def test_extensions_hgsubversion(self, app, form_defaults, csrf_token):
def test_extensions_hgsubversion(self, form_defaults, csrf_token):
form_defaults.update({
'csrf_token': csrf_token,
'extensions_hgsubversion': 'True',
})
response = app.post(
url('admin_settings_vcs'),
response = self.app.post(
route_path('admin_settings_vcs_update'),
params=form_defaults,
status=302)
@ -275,13 +346,13 @@ class TestAdminSettingsVcs(object):
'value="True" checked="checked" />')
response.mustcontain(extensions_input)
def test_extensions_hgevolve(self, app, form_defaults, csrf_token):
def test_extensions_hgevolve(self, form_defaults, csrf_token):
form_defaults.update({
'csrf_token': csrf_token,
'extensions_evolve': 'True',
})
response = app.post(
url('admin_settings_vcs'),
response = self.app.post(
route_path('admin_settings_vcs_update'),
params=form_defaults,
status=302)
@ -292,20 +363,19 @@ class TestAdminSettingsVcs(object):
'value="True" checked="checked" />')
response.mustcontain(extensions_input)
def test_has_a_section_for_pull_request_settings(self, app):
response = app.get(url('admin_settings_vcs'))
def test_has_a_section_for_pull_request_settings(self):
response = self.app.get(route_path('admin_settings_vcs'))
response.mustcontain('Pull Request Settings')
def test_has_an_input_for_invalidation_of_inline_comments(
self, app):
response = app.get(url('admin_settings_vcs'))
def test_has_an_input_for_invalidation_of_inline_comments(self):
response = self.app.get(route_path('admin_settings_vcs'))
assert_response = AssertResponse(response)
assert_response.one_element_exists(
'[name=rhodecode_use_outdated_comments]')
@pytest.mark.parametrize('new_value', [True, False])
def test_allows_to_change_invalidation_of_inline_comments(
self, app, form_defaults, csrf_token, new_value):
self, form_defaults, csrf_token, new_value):
setting_key = 'use_outdated_comments'
setting = SettingsModel().create_or_update_setting(
setting_key, not new_value, 'bool')
@ -316,8 +386,8 @@ class TestAdminSettingsVcs(object):
'csrf_token': csrf_token,
'rhodecode_use_outdated_comments': str(new_value),
})
response = app.post(
url('admin_settings_vcs'),
response = self.app.post(
route_path('admin_settings_vcs_update'),
params=form_defaults,
status=302)
response = response.follow()
@ -326,7 +396,7 @@ class TestAdminSettingsVcs(object):
@pytest.mark.parametrize('new_value', [True, False])
def test_allows_to_change_hg_rebase_merge_strategy(
self, app, form_defaults, csrf_token, new_value):
self, form_defaults, csrf_token, new_value):
setting_key = 'hg_use_rebase_for_merging'
form_defaults.update({
@ -336,8 +406,8 @@ class TestAdminSettingsVcs(object):
with mock.patch.dict(
rhodecode.CONFIG, {'labs_settings_active': 'true'}):
app.post(
url('admin_settings_vcs'),
self.app.post(
route_path('admin_settings_vcs_update'),
params=form_defaults,
status=302)
@ -353,9 +423,8 @@ class TestAdminSettingsVcs(object):
@pytest.fixture
def form_defaults(self):
from rhodecode.controllers.admin.settings import SettingsController
controller = SettingsController()
return controller._form_defaults()
from rhodecode.apps.admin.views.settings import AdminSettingsView
return AdminSettingsView._form_defaults()
# TODO: johbo: What we really want is to checkpoint before a test run and
# reset the session afterwards.
@ -374,14 +443,16 @@ class TestAdminSettingsVcs(object):
@pytest.mark.usefixtures('autologin_user', 'app')
class TestLabsSettings(object):
def test_get_settings_page_disabled(self):
with mock.patch.dict(rhodecode.CONFIG,
{'labs_settings_active': 'false'}):
response = self.app.get(url('admin_settings_labs'), status=302)
with mock.patch.dict(
rhodecode.CONFIG, {'labs_settings_active': 'false'}):
assert response.location.endswith(url('admin_settings'))
response = self.app.get(
route_path('admin_settings_labs'), status=302)
assert response.location.endswith(route_path('admin_settings'))
def test_get_settings_page_enabled(self):
from rhodecode.controllers.admin import settings
from rhodecode.apps.admin.views import settings
lab_settings = [
settings.LabSetting(
key='rhodecode_bool',
@ -401,7 +472,7 @@ class TestLabsSettings(object):
with mock.patch.dict(rhodecode.CONFIG,
{'labs_settings_active': 'true'}):
with mock.patch.object(settings, '_LAB_SETTINGS', lab_settings):
response = self.app.get(url('admin_settings_labs'))
response = self.app.get(route_path('admin_settings_labs'))
assert '<label>bool group:</label>' in response
assert '<label for="rhodecode_bool">bool label</label>' in response
@ -417,9 +488,6 @@ class TestLabsSettings(object):
@pytest.mark.usefixtures('app')
class TestOpenSourceLicenses(object):
def _get_url(self):
return ADMIN_PREFIX + '/settings/open_source'
def test_records_are_displayed(self, autologin_user):
sample_licenses = {
"python2.7-pytest-2.7.1": {
@ -433,7 +501,8 @@ class TestOpenSourceLicenses(object):
'rhodecode.apps.admin.views.open_source_licenses.read_opensource_licenses',
return_value=sample_licenses)
with read_licenses_patch:
response = self.app.get(self._get_url(), status=200)
response = self.app.get(
route_path('admin_settings_open_source'), status=200)
assert_response = AssertResponse(response)
assert_response.element_contains(
@ -444,29 +513,25 @@ class TestOpenSourceLicenses(object):
assert_response.element_contains('.panel-body', license)
def test_records_can_be_read(self, autologin_user):
response = self.app.get(self._get_url(), status=200)
response = self.app.get(
route_path('admin_settings_open_source'), status=200)
assert_response = AssertResponse(response)
assert_response.element_contains(
'.panel-heading', 'Licenses of Third Party Packages')
def test_forbidden_when_normal_user(self, autologin_regular_user):
self.app.get(self._get_url(), status=404)
self.app.get(
route_path('admin_settings_open_source'), status=404)
@pytest.mark.usefixtures('app')
class TestUserSessions(object):
def _get_url(self, name='admin_settings_sessions'):
return {
'admin_settings_sessions': ADMIN_PREFIX + '/settings/sessions',
'admin_settings_sessions_cleanup': ADMIN_PREFIX + '/settings/sessions/cleanup'
}[name]
def test_forbidden_when_normal_user(self, autologin_regular_user):
self.app.get(self._get_url(), status=404)
self.app.get(route_path('admin_settings_sessions'), status=404)
def test_show_sessions_page(self, autologin_user):
response = self.app.get(self._get_url(), status=200)
response = self.app.get(route_path('admin_settings_sessions'), status=200)
response.mustcontain('file')
def test_cleanup_old_sessions(self, autologin_user, csrf_token):
@ -476,24 +541,19 @@ class TestUserSessions(object):
'expire_days': '60'
}
response = self.app.post(
self._get_url('admin_settings_sessions_cleanup'), params=post_data,
route_path('admin_settings_sessions_cleanup'), params=post_data,
status=302)
assert_session_flash(response, 'Cleaned up old sessions')
@pytest.mark.usefixtures('app')
class TestAdminSystemInfo(object):
def _get_url(self, name='admin_settings_system'):
return {
'admin_settings_system': ADMIN_PREFIX + '/settings/system',
'admin_settings_system_update': ADMIN_PREFIX + '/settings/system/updates',
}[name]
def test_forbidden_when_normal_user(self, autologin_regular_user):
self.app.get(self._get_url(), status=404)
self.app.get(route_path('admin_settings_system'), status=404)
def test_system_info_page(self, autologin_user):
response = self.app.get(self._get_url())
response = self.app.get(route_path('admin_settings_system'))
response.mustcontain('RhodeCode Community Edition, version {}'.format(
rhodecode.__version__))
@ -511,7 +571,7 @@ class TestAdminSystemInfo(object):
]
}
with mock.patch(UPDATE_DATA_QUALNAME, return_value=update_data):
response = self.app.get(self._get_url('admin_settings_system_update'))
response = self.app.get(route_path('admin_settings_system_update'))
response.mustcontain('A <b>new version</b> is available')
def test_system_update_nothing_new(self, autologin_user):
@ -524,13 +584,13 @@ class TestAdminSystemInfo(object):
]
}
with mock.patch(UPDATE_DATA_QUALNAME, return_value=update_data):
response = self.app.get(self._get_url('admin_settings_system_update'))
response = self.app.get(route_path('admin_settings_system_update'))
response.mustcontain(
'You already have the <b>latest</b> stable version.')
def test_system_update_bad_response(self, autologin_user):
with mock.patch(UPDATE_DATA_QUALNAME, side_effect=ValueError('foo')):
response = self.app.get(self._get_url('admin_settings_system_update'))
response = self.app.get(route_path('admin_settings_system_update'))
response.mustcontain(
'Bad data sent from update server')
@ -542,12 +602,12 @@ class TestAdminSettingsIssueTracker(object):
PATTERN_KEY = RC_PREFIX + SHORT_PATTERN_KEY
def test_issuetracker_index(self, autologin_user):
response = self.app.get(url('admin_settings_issuetracker'))
response = self.app.get(route_path('admin_settings_issuetracker'))
assert response.status_code == 200
def test_add_empty_issuetracker_pattern(
self, request, autologin_user, csrf_token):
post_url = url('admin_settings_issuetracker_save')
post_url = route_path('admin_settings_issuetracker_update')
post_data = {
'csrf_token': csrf_token
}
@ -557,7 +617,7 @@ class TestAdminSettingsIssueTracker(object):
self, request, autologin_user, csrf_token):
pattern = 'issuetracker_pat'
another_pattern = pattern+'1'
post_url = url('admin_settings_issuetracker_save')
post_url = route_path('admin_settings_issuetracker_update')
post_data = {
'new_pattern_pattern_0': pattern,
'new_pattern_url_0': 'url',
@ -600,7 +660,7 @@ class TestAdminSettingsIssueTracker(object):
SettingsModel().create_or_update_setting(
self.SHORT_PATTERN_KEY+old_uid, old_pattern, 'unicode')
post_url = url('admin_settings_issuetracker_save')
post_url = route_path('admin_settings_issuetracker_update')
post_data = {
'new_pattern_pattern_0': pattern,
'new_pattern_url_0': 'url',
@ -634,7 +694,7 @@ class TestAdminSettingsIssueTracker(object):
settings_util.create_rhodecode_setting(
desc_key, 'old description', 'unicode', cleanup=False)
post_url = url('admin_settings_issuetracker_save')
post_url = route_path('admin_settings_issuetracker_update')
post_data = {
'new_pattern_pattern_0': pattern,
'new_pattern_url_0': 'url',
@ -659,7 +719,7 @@ class TestAdminSettingsIssueTracker(object):
settings_util.create_rhodecode_setting(
self.SHORT_PATTERN_KEY+uid, pattern, 'unicode', cleanup=False)
post_url = url('admin_issuetracker_delete')
post_url = route_path('admin_settings_issuetracker_delete')
post_data = {
'_method': 'delete',
'uid': uid,

View file

@ -19,39 +19,34 @@
# and proprietary license terms, please see https://rhodecode.com/licenses/
"""
settings controller for rhodecode admin
"""
import collections
import logging
import collections
import datetime
import formencode
from formencode import htmlfill
from pylons import request, tmpl_context as c, url, config
from pylons.controllers.util import redirect
from pylons.i18n.translation import _
from pylons.decorators import jsonify
from pyramid.threadlocal import get_current_registry
from webob.exc import HTTPBadRequest
import formencode.htmlfill
import rhodecode
from pyramid.view import view_config
from pyramid.httpexceptions import HTTPFound, HTTPNotFound
from pyramid.renderers import render
from pyramid.response import Response
from rhodecode.apps._base import BaseAppView
from rhodecode.apps.admin.navigation import navigation_list
from rhodecode.apps.svn_support.config_keys import generate_config
from rhodecode.lib import auth
from rhodecode.lib import helpers as h
from rhodecode.lib.auth import LoginRequired, HasPermissionAllDecorator
from rhodecode.lib.base import BaseController, render
from rhodecode.lib.auth import (
LoginRequired, HasPermissionAllDecorator, CSRFRequired)
from rhodecode.lib.celerylib import tasks, run_task
from rhodecode.lib.utils import repo2db_mapper
from rhodecode.lib.utils2 import (
str2bool, safe_unicode, AttributeDict, safe_int)
from rhodecode.lib.utils2 import str2bool, safe_unicode, AttributeDict
from rhodecode.lib.index import searcher_from_config
from rhodecode.model.db import RhodeCodeUi, Repository
from rhodecode.model.forms import ApplicationSettingsForm, \
ApplicationUiSettingsForm, ApplicationVisualisationForm, \
LabsSettingsForm, IssueTrackerPatternsForm
from rhodecode.model.forms import (ApplicationSettingsForm,
ApplicationUiSettingsForm, ApplicationVisualisationForm,
LabsSettingsForm, IssueTrackerPatternsForm)
from rhodecode.model.repo_group import RepoGroupModel
from rhodecode.model.scm import ScmModel
@ -65,21 +60,18 @@ from rhodecode.model.settings import (
log = logging.getLogger(__name__)
class SettingsController(BaseController):
"""REST Controller styled on the Atom Publishing Protocol"""
# To properly map this controller, ensure your config/routing.py
# file has a resource setup:
# map.resource('setting', 'settings', controller='admin/settings',
# path_prefix='/admin', name_prefix='admin_')
class AdminSettingsView(BaseAppView):
@LoginRequired()
def __before__(self):
super(SettingsController, self).__before__()
def load_default_context(self):
c = self._get_local_tmpl_context()
c.labs_active = str2bool(
rhodecode.CONFIG.get('labs_settings_active', 'true'))
c.navlist = navigation_list(request)
c.navlist = navigation_list(self.request)
self._register_global_c(c)
return c
def _get_ui_settings(self):
@classmethod
def _get_ui_settings(cls):
ret = RhodeCodeUi.query().all()
if not ret:
@ -103,54 +95,83 @@ class SettingsController(BaseController):
settings[each.ui_section + '_' + k] = v
return settings
@HasPermissionAllDecorator('hg.admin')
@auth.CSRFRequired()
@jsonify
def delete_svn_pattern(self):
if not request.is_xhr:
raise HTTPBadRequest()
@classmethod
def _form_defaults(cls):
defaults = SettingsModel().get_all_settings()
defaults.update(cls._get_ui_settings())
delete_pattern_id = request.POST.get('delete_svn_pattern')
defaults.update({
'new_svn_branch': '',
'new_svn_tag': '',
})
return defaults
@LoginRequired()
@HasPermissionAllDecorator('hg.admin')
@view_config(
route_name='admin_settings_vcs', request_method='GET',
renderer='rhodecode:templates/admin/settings/settings.mako')
def settings_vcs(self):
c = self.load_default_context()
c.active = 'vcs'
model = VcsSettingsModel()
try:
model.delete_global_svn_pattern(delete_pattern_id)
except SettingNotFound:
raise HTTPBadRequest()
c.svn_branch_patterns = model.get_global_svn_branch_patterns()
c.svn_tag_patterns = model.get_global_svn_tag_patterns()
Session().commit()
return True
settings = self.request.registry.settings
c.svn_proxy_generate_config = settings[generate_config]
defaults = self._form_defaults()
model.create_largeobjects_dirs_if_needed(defaults['paths_root_path'])
data = render('rhodecode:templates/admin/settings/settings.mako',
self._get_template_context(c), self.request)
html = formencode.htmlfill.render(
data,
defaults=defaults,
encoding="UTF-8",
force_defaults=False
)
return Response(html)
@LoginRequired()
@HasPermissionAllDecorator('hg.admin')
@auth.CSRFRequired()
@CSRFRequired()
@view_config(
route_name='admin_settings_vcs_update', request_method='POST',
renderer='rhodecode:templates/admin/settings/settings.mako')
def settings_vcs_update(self):
"""POST /admin/settings: All items in the collection"""
# url('admin_settings_vcs')
_ = self.request.translate
c = self.load_default_context()
c.active = 'vcs'
model = VcsSettingsModel()
c.svn_branch_patterns = model.get_global_svn_branch_patterns()
c.svn_tag_patterns = model.get_global_svn_tag_patterns()
# TODO: Replace with request.registry after migrating to pyramid.
pyramid_settings = get_current_registry().settings
c.svn_proxy_generate_config = pyramid_settings[generate_config]
settings = self.request.registry.settings
c.svn_proxy_generate_config = settings[generate_config]
application_form = ApplicationUiSettingsForm()()
try:
form_result = application_form.to_python(dict(request.POST))
form_result = application_form.to_python(dict(self.request.POST))
except formencode.Invalid as errors:
h.flash(
_("Some form inputs contain invalid data."),
category='error')
return htmlfill.render(
render('admin/settings/settings.mako'),
data = render('rhodecode:templates/admin/settings/settings.mako',
self._get_template_context(c), self.request)
html = formencode.htmlfill.render(
data,
defaults=errors.value,
errors=errors.error_dict or {},
prefix_error=False,
encoding="UTF-8",
force_defaults=False
)
return Response(html)
try:
if c.visual.allow_repo_location_change:
@ -171,44 +192,68 @@ class SettingsController(BaseController):
else:
Session().commit()
h.flash(_('Updated VCS settings'), category='success')
return redirect(url('admin_settings_vcs'))
raise HTTPFound(h.route_path('admin_settings_vcs'))
return htmlfill.render(
render('admin/settings/settings.mako'),
data = render('rhodecode:templates/admin/settings/settings.mako',
self._get_template_context(c), self.request)
html = formencode.htmlfill.render(
data,
defaults=self._form_defaults(),
encoding="UTF-8",
force_defaults=False)
force_defaults=False
)
return Response(html)
@LoginRequired()
@HasPermissionAllDecorator('hg.admin')
def settings_vcs(self):
"""GET /admin/settings: All items in the collection"""
# url('admin_settings_vcs')
c.active = 'vcs'
@CSRFRequired()
@view_config(
route_name='admin_settings_vcs_svn_pattern_delete', request_method='POST',
renderer='json_ext', xhr=True)
def settings_vcs_delete_svn_pattern(self):
delete_pattern_id = self.request.POST.get('delete_svn_pattern')
model = VcsSettingsModel()
c.svn_branch_patterns = model.get_global_svn_branch_patterns()
c.svn_tag_patterns = model.get_global_svn_tag_patterns()
try:
model.delete_global_svn_pattern(delete_pattern_id)
except SettingNotFound:
log.exception(
'Failed to delete svn_pattern with id %s', delete_pattern_id)
raise HTTPNotFound()
# TODO: Replace with request.registry after migrating to pyramid.
pyramid_settings = get_current_registry().settings
c.svn_proxy_generate_config = pyramid_settings[generate_config]
defaults = self._form_defaults()
model.create_largeobjects_dirs_if_needed(defaults['paths_root_path'])
return htmlfill.render(
render('admin/settings/settings.mako'),
defaults=defaults,
encoding="UTF-8",
force_defaults=False)
Session().commit()
return True
@LoginRequired()
@HasPermissionAllDecorator('hg.admin')
@auth.CSRFRequired()
def settings_mapping_update(self):
"""POST /admin/settings/mapping: All items in the collection"""
# url('admin_settings_mapping')
@view_config(
route_name='admin_settings_mapping', request_method='GET',
renderer='rhodecode:templates/admin/settings/settings.mako')
def settings_mapping(self):
c = self.load_default_context()
c.active = 'mapping'
rm_obsolete = request.POST.get('destroy', False)
invalidate_cache = request.POST.get('invalidate', False)
data = render('rhodecode:templates/admin/settings/settings.mako',
self._get_template_context(c), self.request)
html = formencode.htmlfill.render(
data,
defaults=self._form_defaults(),
encoding="UTF-8",
force_defaults=False
)
return Response(html)
@LoginRequired()
@HasPermissionAllDecorator('hg.admin')
@CSRFRequired()
@view_config(
route_name='admin_settings_mapping_update', request_method='POST',
renderer='rhodecode:templates/admin/settings/settings.mako')
def settings_mapping_update(self):
_ = self.request.translate
c = self.load_default_context()
c.active = 'mapping'
rm_obsolete = self.request.POST.get('destroy', False)
invalidate_cache = self.request.POST.get('invalidate', False)
log.debug(
'rescanning repo location with destroy obsolete=%s', rm_obsolete)
@ -224,51 +269,74 @@ class SettingsController(BaseController):
'rescanned added: %s ; removed: %s') %
(_repr(added), _repr(removed)),
category='success')
return redirect(url('admin_settings_mapping'))
raise HTTPFound(h.route_path('admin_settings_mapping'))
@LoginRequired()
@HasPermissionAllDecorator('hg.admin')
def settings_mapping(self):
"""GET /admin/settings/mapping: All items in the collection"""
# url('admin_settings_mapping')
c.active = 'mapping'
@view_config(
route_name='admin_settings', request_method='GET',
renderer='rhodecode:templates/admin/settings/settings.mako')
@view_config(
route_name='admin_settings_global', request_method='GET',
renderer='rhodecode:templates/admin/settings/settings.mako')
def settings_global(self):
c = self.load_default_context()
c.active = 'global'
c.personal_repo_group_default_pattern = RepoGroupModel()\
.get_personal_group_name_pattern()
return htmlfill.render(
render('admin/settings/settings.mako'),
data = render('rhodecode:templates/admin/settings/settings.mako',
self._get_template_context(c), self.request)
html = formencode.htmlfill.render(
data,
defaults=self._form_defaults(),
encoding="UTF-8",
force_defaults=False)
force_defaults=False
)
return Response(html)
@LoginRequired()
@HasPermissionAllDecorator('hg.admin')
@auth.CSRFRequired()
@CSRFRequired()
@view_config(
route_name='admin_settings_update', request_method='POST',
renderer='rhodecode:templates/admin/settings/settings.mako')
@view_config(
route_name='admin_settings_global_update', request_method='POST',
renderer='rhodecode:templates/admin/settings/settings.mako')
def settings_global_update(self):
"""POST /admin/settings/global: All items in the collection"""
# url('admin_settings_global')
_ = self.request.translate
c = self.load_default_context()
c.active = 'global'
c.personal_repo_group_default_pattern = RepoGroupModel()\
.get_personal_group_name_pattern()
application_form = ApplicationSettingsForm()()
try:
form_result = application_form.to_python(dict(request.POST))
form_result = application_form.to_python(dict(self.request.POST))
except formencode.Invalid as errors:
return htmlfill.render(
render('admin/settings/settings.mako'),
data = render('rhodecode:templates/admin/settings/settings.mako',
self._get_template_context(c), self.request)
html = formencode.htmlfill.render(
data,
defaults=errors.value,
errors=errors.error_dict or {},
prefix_error=False,
encoding="UTF-8",
force_defaults=False)
force_defaults=False
)
return Response(html)
settings = [
('title', 'rhodecode_title', 'unicode'),
('realm', 'rhodecode_realm', 'unicode'),
('pre_code', 'rhodecode_pre_code', 'unicode'),
('post_code', 'rhodecode_post_code', 'unicode'),
('captcha_public_key', 'rhodecode_captcha_public_key', 'unicode'),
('captcha_private_key', 'rhodecode_captcha_private_key', 'unicode'),
('create_personal_repo_group', 'rhodecode_create_personal_repo_group', 'bool'),
('personal_repo_group_pattern', 'rhodecode_personal_repo_group_pattern', 'unicode'),
]
try:
settings = [
('title', 'rhodecode_title', 'unicode'),
('realm', 'rhodecode_realm', 'unicode'),
('pre_code', 'rhodecode_pre_code', 'unicode'),
('post_code', 'rhodecode_post_code', 'unicode'),
('captcha_public_key', 'rhodecode_captcha_public_key', 'unicode'),
('captcha_private_key', 'rhodecode_captcha_private_key', 'unicode'),
('create_personal_repo_group', 'rhodecode_create_personal_repo_group', 'bool'),
('personal_repo_group_pattern', 'rhodecode_personal_repo_group_pattern', 'unicode'),
]
for setting, form_key, type_ in settings:
sett = SettingsModel().create_or_update_setting(
setting, form_result[form_key], type_)
@ -283,40 +351,52 @@ class SettingsController(BaseController):
_('Error occurred during updating application settings'),
category='error')
return redirect(url('admin_settings_global'))
raise HTTPFound(h.route_path('admin_settings_global'))
@LoginRequired()
@HasPermissionAllDecorator('hg.admin')
def settings_global(self):
"""GET /admin/settings/global: All items in the collection"""
# url('admin_settings_global')
c.active = 'global'
c.personal_repo_group_default_pattern = RepoGroupModel()\
.get_personal_group_name_pattern()
@view_config(
route_name='admin_settings_visual', request_method='GET',
renderer='rhodecode:templates/admin/settings/settings.mako')
def settings_visual(self):
c = self.load_default_context()
c.active = 'visual'
return htmlfill.render(
render('admin/settings/settings.mako'),
data = render('rhodecode:templates/admin/settings/settings.mako',
self._get_template_context(c), self.request)
html = formencode.htmlfill.render(
data,
defaults=self._form_defaults(),
encoding="UTF-8",
force_defaults=False)
force_defaults=False
)
return Response(html)
@LoginRequired()
@HasPermissionAllDecorator('hg.admin')
@auth.CSRFRequired()
@CSRFRequired()
@view_config(
route_name='admin_settings_visual_update', request_method='POST',
renderer='rhodecode:templates/admin/settings/settings.mako')
def settings_visual_update(self):
"""POST /admin/settings/visual: All items in the collection"""
# url('admin_settings_visual')
_ = self.request.translate
c = self.load_default_context()
c.active = 'visual'
application_form = ApplicationVisualisationForm()()
try:
form_result = application_form.to_python(dict(request.POST))
form_result = application_form.to_python(dict(self.request.POST))
except formencode.Invalid as errors:
return htmlfill.render(
render('admin/settings/settings.mako'),
data = render('rhodecode:templates/admin/settings/settings.mako',
self._get_template_context(c), self.request)
html = formencode.htmlfill.render(
data,
defaults=errors.value,
errors=errors.error_dict or {},
prefix_error=False,
encoding="UTF-8",
force_defaults=False
)
return Response(html)
try:
settings = [
@ -349,42 +429,15 @@ class SettingsController(BaseController):
'visualisation settings'),
category='error')
return redirect(url('admin_settings_visual'))
@HasPermissionAllDecorator('hg.admin')
def settings_visual(self):
"""GET /admin/settings/visual: All items in the collection"""
# url('admin_settings_visual')
c.active = 'visual'
return htmlfill.render(
render('admin/settings/settings.mako'),
defaults=self._form_defaults(),
encoding="UTF-8",
force_defaults=False)
@HasPermissionAllDecorator('hg.admin')
@auth.CSRFRequired()
def settings_issuetracker_test(self):
if request.is_xhr:
return h.urlify_commit_message(
request.POST.get('test_text', ''),
'repo_group/test_repo1')
else:
raise HTTPBadRequest()
@HasPermissionAllDecorator('hg.admin')
@auth.CSRFRequired()
def settings_issuetracker_delete(self):
uid = request.POST.get('uid')
IssueTrackerSettingsModel().delete_entries(uid)
h.flash(_('Removed issue tracker entry'), category='success')
return redirect(url('admin_settings_issuetracker'))
raise HTTPFound(h.route_path('admin_settings_visual'))
@LoginRequired()
@HasPermissionAllDecorator('hg.admin')
@view_config(
route_name='admin_settings_issuetracker', request_method='GET',
renderer='rhodecode:templates/admin/settings/settings.mako')
def settings_issuetracker(self):
"""GET /admin/settings/issue-tracker: All items in the collection"""
# url('admin_settings_issuetracker')
c = self.load_default_context()
c.active = 'issuetracker'
defaults = SettingsModel().get_all_settings()
@ -404,14 +457,31 @@ class SettingsController(BaseController):
'desc': defaults.get('rhodecode_issuetracker_desc_' + uid),
})
return render('admin/settings/settings.mako')
return self._get_template_context(c)
@LoginRequired()
@HasPermissionAllDecorator('hg.admin')
@auth.CSRFRequired()
def settings_issuetracker_save(self):
@CSRFRequired()
@view_config(
route_name='admin_settings_issuetracker_test', request_method='POST',
renderer='string', xhr=True)
def settings_issuetracker_test(self):
return h.urlify_commit_message(
self.request.POST.get('test_text', ''),
'repo_group/test_repo1')
@LoginRequired()
@HasPermissionAllDecorator('hg.admin')
@CSRFRequired()
@view_config(
route_name='admin_settings_issuetracker_update', request_method='POST',
renderer='rhodecode:templates/admin/settings/settings.mako')
def settings_issuetracker_update(self):
_ = self.request.translate
self.load_default_context()
settings_model = IssueTrackerSettingsModel()
form = IssueTrackerPatternsForm()().to_python(request.POST)
form = IssueTrackerPatternsForm()().to_python(self.request.POST)
if form:
for uid in form.get('delete_patterns', []):
settings_model.delete_entries(uid)
@ -426,20 +496,62 @@ class SettingsController(BaseController):
SettingsModel().invalidate_settings_cache()
h.flash(_('Updated issue tracker entries'), category='success')
return redirect(url('admin_settings_issuetracker'))
raise HTTPFound(h.route_path('admin_settings_issuetracker'))
@LoginRequired()
@HasPermissionAllDecorator('hg.admin')
@auth.CSRFRequired()
@CSRFRequired()
@view_config(
route_name='admin_settings_issuetracker_delete', request_method='POST',
renderer='rhodecode:templates/admin/settings/settings.mako')
def settings_issuetracker_delete(self):
_ = self.request.translate
self.load_default_context()
uid = self.request.POST.get('uid')
try:
IssueTrackerSettingsModel().delete_entries(uid)
except Exception:
log.exception('Failed to delete issue tracker setting %s', uid)
raise HTTPNotFound()
h.flash(_('Removed issue tracker entry'), category='success')
raise HTTPFound(h.route_path('admin_settings_issuetracker'))
@LoginRequired()
@HasPermissionAllDecorator('hg.admin')
@view_config(
route_name='admin_settings_email', request_method='GET',
renderer='rhodecode:templates/admin/settings/settings.mako')
def settings_email(self):
c = self.load_default_context()
c.active = 'email'
c.rhodecode_ini = rhodecode.CONFIG
data = render('rhodecode:templates/admin/settings/settings.mako',
self._get_template_context(c), self.request)
html = formencode.htmlfill.render(
data,
defaults=self._form_defaults(),
encoding="UTF-8",
force_defaults=False
)
return Response(html)
@LoginRequired()
@HasPermissionAllDecorator('hg.admin')
@CSRFRequired()
@view_config(
route_name='admin_settings_email_update', request_method='POST',
renderer='rhodecode:templates/admin/settings/settings.mako')
def settings_email_update(self):
"""POST /admin/settings/email: All items in the collection"""
# url('admin_settings_email')
_ = self.request.translate
c = self.load_default_context()
c.active = 'email'
test_email = request.POST.get('test_email')
test_email = self.request.POST.get('test_email')
if not test_email:
h.flash(_('Please enter email address'), category='error')
return redirect(url('admin_settings_email'))
raise HTTPFound(h.route_path('admin_settings_email'))
email_kwargs = {
'date': datetime.datetime.now(),
@ -457,32 +569,49 @@ class SettingsController(BaseController):
email_body_plaintext, email_body)
h.flash(_('Send email task created'), category='success')
return redirect(url('admin_settings_email'))
raise HTTPFound(h.route_path('admin_settings_email'))
@LoginRequired()
@HasPermissionAllDecorator('hg.admin')
def settings_email(self):
"""GET /admin/settings/email: All items in the collection"""
# url('admin_settings_email')
c.active = 'email'
c.rhodecode_ini = rhodecode.CONFIG
@view_config(
route_name='admin_settings_hooks', request_method='GET',
renderer='rhodecode:templates/admin/settings/settings.mako')
def settings_hooks(self):
c = self.load_default_context()
c.active = 'hooks'
return htmlfill.render(
render('admin/settings/settings.mako'),
model = SettingsModel()
c.hooks = model.get_builtin_hooks()
c.custom_hooks = model.get_custom_hooks()
data = render('rhodecode:templates/admin/settings/settings.mako',
self._get_template_context(c), self.request)
html = formencode.htmlfill.render(
data,
defaults=self._form_defaults(),
encoding="UTF-8",
force_defaults=False)
force_defaults=False
)
return Response(html)
@LoginRequired()
@HasPermissionAllDecorator('hg.admin')
@auth.CSRFRequired()
@CSRFRequired()
@view_config(
route_name='admin_settings_hooks_update', request_method='POST',
renderer='rhodecode:templates/admin/settings/settings.mako')
@view_config(
route_name='admin_settings_hooks_delete', request_method='POST',
renderer='rhodecode:templates/admin/settings/settings.mako')
def settings_hooks_update(self):
"""POST or DELETE /admin/settings/hooks: All items in the collection"""
# url('admin_settings_hooks')
_ = self.request.translate
c = self.load_default_context()
c.active = 'hooks'
if c.visual.allow_custom_hooks_settings:
ui_key = request.POST.get('new_hook_ui_key')
ui_value = request.POST.get('new_hook_ui_value')
ui_key = self.request.POST.get('new_hook_ui_key')
ui_value = self.request.POST.get('new_hook_ui_value')
hook_id = request.POST.get('hook_id')
hook_id = self.request.POST.get('hook_id')
new_hook = False
model = SettingsModel()
@ -497,7 +626,7 @@ class SettingsController(BaseController):
# check for edits
update = False
_d = request.POST.dict_of_lists()
_d = self.request.POST.dict_of_lists()
for k, v in zip(_d.get('hook_ui_key', []),
_d.get('hook_ui_value_new', [])):
model.create_or_update_hook(k, v)
@ -511,58 +640,74 @@ class SettingsController(BaseController):
h.flash(_('Error occurred during hook creation'),
category='error')
return redirect(url('admin_settings_hooks'))
@HasPermissionAllDecorator('hg.admin')
def settings_hooks(self):
"""GET /admin/settings/hooks: All items in the collection"""
# url('admin_settings_hooks')
c.active = 'hooks'
model = SettingsModel()
c.hooks = model.get_builtin_hooks()
c.custom_hooks = model.get_custom_hooks()
return htmlfill.render(
render('admin/settings/settings.mako'),
defaults=self._form_defaults(),
encoding="UTF-8",
force_defaults=False)
raise HTTPFound(h.route_path('admin_settings_hooks'))
@LoginRequired()
@HasPermissionAllDecorator('hg.admin')
@view_config(
route_name='admin_settings_search', request_method='GET',
renderer='rhodecode:templates/admin/settings/settings.mako')
def settings_search(self):
"""GET /admin/settings/search: All items in the collection"""
# url('admin_settings_search')
c = self.load_default_context()
c.active = 'search'
from rhodecode.lib.index import searcher_from_config
searcher = searcher_from_config(config)
searcher = searcher_from_config(self.request.registry.settings)
c.statistics = searcher.statistics()
return render('admin/settings/settings.mako')
return self._get_template_context(c)
@LoginRequired()
@HasPermissionAllDecorator('hg.admin')
@auth.CSRFRequired()
@view_config(
route_name='admin_settings_labs', request_method='GET',
renderer='rhodecode:templates/admin/settings/settings.mako')
def settings_labs(self):
c = self.load_default_context()
if not c.labs_active:
raise HTTPFound(h.route_path('admin_settings'))
c.active = 'labs'
c.lab_settings = _LAB_SETTINGS
data = render('rhodecode:templates/admin/settings/settings.mako',
self._get_template_context(c), self.request)
html = formencode.htmlfill.render(
data,
defaults=self._form_defaults(),
encoding="UTF-8",
force_defaults=False
)
return Response(html)
@LoginRequired()
@HasPermissionAllDecorator('hg.admin')
@CSRFRequired()
@view_config(
route_name='admin_settings_labs_update', request_method='POST',
renderer='rhodecode:templates/admin/settings/settings.mako')
def settings_labs_update(self):
"""POST /admin/settings/labs: All items in the collection"""
# url('admin_settings/labs', method={'POST'})
_ = self.request.translate
c = self.load_default_context()
c.active = 'labs'
application_form = LabsSettingsForm()()
try:
form_result = application_form.to_python(dict(request.POST))
form_result = application_form.to_python(dict(self.request.POST))
except formencode.Invalid as errors:
h.flash(
_('Some form inputs contain invalid data.'),
category='error')
return htmlfill.render(
render('admin/settings/settings.mako'),
data = render('rhodecode:templates/admin/settings/settings.mako',
self._get_template_context(c), self.request)
html = formencode.htmlfill.render(
data,
defaults=errors.value,
errors=errors.error_dict or {},
prefix_error=False,
encoding='UTF-8',
encoding="UTF-8",
force_defaults=False
)
return Response(html)
try:
session = Session()
@ -580,39 +725,17 @@ class SettingsController(BaseController):
Session().commit()
SettingsModel().invalidate_settings_cache()
h.flash(_('Updated Labs settings'), category='success')
return redirect(url('admin_settings_labs'))
raise HTTPFound(h.route_path('admin_settings_labs'))
return htmlfill.render(
render('admin/settings/settings.mako'),
data = render('rhodecode:templates/admin/settings/settings.mako',
self._get_template_context(c), self.request)
html = formencode.htmlfill.render(
data,
defaults=self._form_defaults(),
encoding='UTF-8',
force_defaults=False)
@HasPermissionAllDecorator('hg.admin')
def settings_labs(self):
"""GET /admin/settings/labs: All items in the collection"""
# url('admin_settings_labs')
if not c.labs_active:
redirect(url('admin_settings'))
c.active = 'labs'
c.lab_settings = _LAB_SETTINGS
return htmlfill.render(
render('admin/settings/settings.mako'),
defaults=self._form_defaults(),
encoding='UTF-8',
force_defaults=False)
def _form_defaults(self):
defaults = SettingsModel().get_all_settings()
defaults.update(self._get_ui_settings())
defaults.update({
'new_svn_branch': '',
'new_svn_tag': '',
})
return defaults
encoding="UTF-8",
force_defaults=False
)
return Response(html)
# :param key: name of the setting including the 'rhodecode_' prefix

View file

@ -172,81 +172,6 @@ def make_map(config):
# CUSTOM ROUTES HERE
#==========================================================================
# ADMIN SETTINGS ROUTES
with rmap.submapper(path_prefix=ADMIN_PREFIX,
controller='admin/settings') as m:
# default
m.connect('admin_settings', '/settings',
action='settings_global_update',
conditions={'method': ['POST']})
m.connect('admin_settings', '/settings',
action='settings_global', conditions={'method': ['GET']})
m.connect('admin_settings_vcs', '/settings/vcs',
action='settings_vcs_update',
conditions={'method': ['POST']})
m.connect('admin_settings_vcs', '/settings/vcs',
action='settings_vcs',
conditions={'method': ['GET']})
m.connect('admin_settings_vcs', '/settings/vcs',
action='delete_svn_pattern',
conditions={'method': ['DELETE']})
m.connect('admin_settings_mapping', '/settings/mapping',
action='settings_mapping_update',
conditions={'method': ['POST']})
m.connect('admin_settings_mapping', '/settings/mapping',
action='settings_mapping', conditions={'method': ['GET']})
m.connect('admin_settings_global', '/settings/global',
action='settings_global_update',
conditions={'method': ['POST']})
m.connect('admin_settings_global', '/settings/global',
action='settings_global', conditions={'method': ['GET']})
m.connect('admin_settings_visual', '/settings/visual',
action='settings_visual_update',
conditions={'method': ['POST']})
m.connect('admin_settings_visual', '/settings/visual',
action='settings_visual', conditions={'method': ['GET']})
m.connect('admin_settings_issuetracker',
'/settings/issue-tracker', action='settings_issuetracker',
conditions={'method': ['GET']})
m.connect('admin_settings_issuetracker_save',
'/settings/issue-tracker/save',
action='settings_issuetracker_save',
conditions={'method': ['POST']})
m.connect('admin_issuetracker_test', '/settings/issue-tracker/test',
action='settings_issuetracker_test',
conditions={'method': ['POST']})
m.connect('admin_issuetracker_delete',
'/settings/issue-tracker/delete',
action='settings_issuetracker_delete',
conditions={'method': ['DELETE']})
m.connect('admin_settings_email', '/settings/email',
action='settings_email_update',
conditions={'method': ['POST']})
m.connect('admin_settings_email', '/settings/email',
action='settings_email', conditions={'method': ['GET']})
m.connect('admin_settings_hooks', '/settings/hooks',
action='settings_hooks_update',
conditions={'method': ['POST', 'DELETE']})
m.connect('admin_settings_hooks', '/settings/hooks',
action='settings_hooks', conditions={'method': ['GET']})
m.connect('admin_settings_search', '/settings/search',
action='settings_search', conditions={'method': ['GET']})
m.connect('admin_settings_labs', '/settings/labs',
action='settings_labs_update',
conditions={'method': ['POST']})
m.connect('admin_settings_labs', '/settings/labs',
action='settings_labs', conditions={'method': ['GET']})
# ADMIN MY ACCOUNT
with rmap.submapper(path_prefix=ADMIN_PREFIX,
controller='admin/my_account') as m:

View file

@ -1,19 +0,0 @@
# -*- 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/

View file

@ -51,6 +51,29 @@ function registerRCRoutes() {
pyroutes.register('admin_settings_process_management_signal', '/_admin/settings/process_management/signal', []);
pyroutes.register('admin_defaults_repositories', '/_admin/defaults/repositories', []);
pyroutes.register('admin_defaults_repositories_update', '/_admin/defaults/repositories/update', []);
pyroutes.register('admin_settings', '/_admin/settings', []);
pyroutes.register('admin_settings_update', '/_admin/settings/update', []);
pyroutes.register('admin_settings_global', '/_admin/settings/global', []);
pyroutes.register('admin_settings_global_update', '/_admin/settings/global/update', []);
pyroutes.register('admin_settings_vcs', '/_admin/settings/vcs', []);
pyroutes.register('admin_settings_vcs_update', '/_admin/settings/vcs/update', []);
pyroutes.register('admin_settings_vcs_svn_pattern_delete', '/_admin/settings/vcs/svn_pattern_delete', []);
pyroutes.register('admin_settings_mapping', '/_admin/settings/mapping', []);
pyroutes.register('admin_settings_mapping_update', '/_admin/settings/mapping/update', []);
pyroutes.register('admin_settings_visual', '/_admin/settings/visual', []);
pyroutes.register('admin_settings_visual_update', '/_admin/settings/visual/update', []);
pyroutes.register('admin_settings_issuetracker', '/_admin/settings/issue-tracker', []);
pyroutes.register('admin_settings_issuetracker_update', '/_admin/settings/issue-tracker/update', []);
pyroutes.register('admin_settings_issuetracker_test', '/_admin/settings/issue-tracker/test', []);
pyroutes.register('admin_settings_issuetracker_delete', '/_admin/settings/issue-tracker/delete', []);
pyroutes.register('admin_settings_email', '/_admin/settings/email', []);
pyroutes.register('admin_settings_email_update', '/_admin/settings/email/update', []);
pyroutes.register('admin_settings_hooks', '/_admin/settings/hooks', []);
pyroutes.register('admin_settings_hooks_update', '/_admin/settings/hooks/update', []);
pyroutes.register('admin_settings_hooks_delete', '/_admin/settings/hooks/delete', []);
pyroutes.register('admin_settings_search', '/_admin/settings/search', []);
pyroutes.register('admin_settings_labs', '/_admin/settings/labs', []);
pyroutes.register('admin_settings_labs_update', '/_admin/settings/labs/update', []);
pyroutes.register('admin_permissions_application', '/_admin/permissions/application', []);
pyroutes.register('admin_permissions_application_update', '/_admin/permissions/application/update', []);
pyroutes.register('admin_permissions_global', '/_admin/permissions/global', []);

View file

@ -27,7 +27,7 @@
%else:
${h.link_to(_('Admin'),h.route_path('admin_home'))}
&raquo;
${h.link_to(_('Settings'),h.url('admin_settings'))}
${h.link_to(_('Settings'),h.route_path('admin_settings'))}
&raquo;
${h.link_to(_('Integrations'),request.route_url(route_name='global_integrations_home'))}
&raquo;

View file

@ -13,7 +13,7 @@
%else:
${h.link_to(_('Admin'),h.route_path('admin_home'))}
&raquo;
${h.link_to(_('Settings'),h.url('admin_settings'))}
${h.link_to(_('Settings'),h.route_path('admin_settings'))}
%endif
%if c.current_IntegrationType:
&raquo;

View file

@ -18,7 +18,7 @@
%else:
${h.link_to(_('Admin'),h.route_path('admin_home'))}
&raquo;
${h.link_to(_('Settings'),h.url('admin_settings'))}
${h.link_to(_('Settings'),h.route_path('admin_settings'))}
&raquo;
${h.link_to(_('Integrations'),request.route_url(route_name='global_integrations_home'))}
%endif

View file

@ -33,7 +33,7 @@ ${h.secure_form(h.route_path('repo_create'), request=request)}
add authentication information to the URL: https://username:password@server.company.com/repo-name.
- The Git LFS/Mercurial Largefiles objects will not be imported.
- For very large repositories, it's recommended to manually copy them into the
RhodeCode <a href="${h.url('admin_settings_vcs', anchor='vcs-storage-options')}">storage location</a> and run <a href="${h.url('admin_settings_mapping')}">Remap and Rescan</a>.
RhodeCode <a href="${h.route_path('admin_settings_vcs', _anchor='vcs-storage-options')}">storage location</a> and run <a href="${h.route_path('admin_settings_mapping')}">Remap and Rescan</a>.
</pre>
</span>
</div>

View file

@ -34,7 +34,7 @@
<h3 class="panel-title">${_('Test Email')}</h3>
</div>
<div class="panel-body">
${h.secure_form(h.url('admin_settings_email'), request=request)}
${h.secure_form(h.route_path('admin_settings_email_update'), request=request)}
<div class="field input">
${h.text('test_email', size=60, placeholder=_('enter valid email'))}

View file

@ -1,4 +1,4 @@
${h.secure_form(h.url('admin_settings_global'), request=request)}
${h.secure_form(h.route_path('admin_settings_global_update'), request=request)}
<div class="panel panel-default">
<div class="panel-heading" id="branding-options">

View file

@ -28,7 +28,7 @@
</div>
<div class="panel-body">
% if c.visual.allow_custom_hooks_settings:
${h.secure_form(h.url('admin_settings_hooks'), request=request)}
${h.secure_form(h.route_path('admin_settings_hooks_update'), request=request)}
<div class="form">
<div class="fields">
@ -74,13 +74,12 @@
<script type="text/javascript">
function ajaxActionHook(hook_id,field_id) {
var sUrl = "${h.url('admin_settings_hooks')}";
var sUrl = "${h.route_path('admin_settings_hooks_delete')}";
var callback = function (o) {
var elem = $("#"+field_id);
elem.remove();
};
var postData = {
'_method': 'delete',
'hook_id': hook_id,
'csrf_token': CSRF_TOKEN
};
@ -89,5 +88,5 @@ function ajaxActionHook(hook_id,field_id) {
.fail(function (data, textStatus, errorThrown) {
alert("Error while deleting hooks.\nError code {0} ({1}). URL: {2}".format(data.status,data.statusText,$(this)[0].url));
});
};
}
</script>

View file

@ -5,11 +5,11 @@
<h3 class="panel-title">${_('Issue Tracker / Wiki Patterns')}</h3>
</div>
<div class="panel-body">
${h.secure_form(h.url('admin_settings_issuetracker_save'), request=request)}
${h.secure_form(h.route_path('admin_settings_issuetracker_update'), request=request)}
${its.issue_tracker_settings_table(
patterns=c.issuetracker_entries.items(),
form_url=h.url('admin_settings_issuetracker'),
delete_url=h.url('admin_issuetracker_delete')
form_url=h.route_path('admin_settings_issuetracker'),
delete_url=h.route_path('admin_settings_issuetracker_delete')
)}
<div class="buttons">
<button type="submit" class="btn btn-primary" id="save">${_('Save')}</button>
@ -25,7 +25,7 @@
</div>
<div class="panel-body">
${its.issue_tracker_new_row()}
${its.issue_tracker_settings_test(test_url=h.url('admin_issuetracker_test'))}
${its.issue_tracker_settings_test(test_url=h.route_path('admin_settings_issuetracker_test'))}
</div>
</div>

View file

@ -3,7 +3,7 @@
<h3 class="panel-title">${_('Labs Settings')}</h3>
</div>
<div class="panel-body">
${h.secure_form(h.url('admin_settings_labs'), request=request)}
${h.secure_form(h.route_path('admin_settings_labs_update'), request=request)}
<div class="form">
<div class="fields">
% if not c.lab_settings:

View file

@ -1,4 +1,4 @@
${h.secure_form(h.url('admin_settings_mapping'), request=request)}
${h.secure_form(h.route_path('admin_settings_mapping_update'), request=request)}
<div class="panel panel-default">
<div class="panel-heading">

View file

@ -1,6 +1,6 @@
<%namespace name="vcss" file="/base/vcs_settings.mako"/>
${h.secure_form(h.url('admin_settings_vcs'), request=request)}
${h.secure_form(h.route_path('admin_settings_vcs_update'), request=request)}
<div>
${vcss.vcs_settings_fields(
suffix='',
@ -19,13 +19,12 @@ ${h.end_form()}
<script type="text/javascript">
function ajaxDeletePattern(pattern_id, field_id) {
var sUrl = "${h.url('admin_settings_vcs')}";
var sUrl = "${h.route_path('admin_settings_vcs_svn_pattern_delete')}";
var callback = function (o) {
var elem = $("#"+field_id);
elem.remove();
};
var postData = {
'_method': 'delete',
'delete_svn_pattern': pattern_id,
'csrf_token': CSRF_TOKEN
};

View file

@ -1,4 +1,4 @@
${h.secure_form(h.url('admin_settings_visual'), request=request)}
${h.secure_form(h.route_path('admin_settings_visual_update'), request=request)}
<div class="panel panel-default">
<div class="panel-heading" id="general">

View file

@ -81,7 +81,7 @@
<li><a href="${h.route_path('auth_home', traverse='')}">${_('Authentication')}</a></li>
<li><a href="${h.route_path('global_integrations_home')}">${_('Integrations')}</a></li>
<li><a href="${h.route_path('admin_defaults_repositories')}">${_('Defaults')}</a></li>
<li class="last"><a href="${h.url('admin_settings')}">${_('Settings')}</a></li>
<li class="last"><a href="${h.route_path('admin_settings')}">${_('Settings')}</a></li>
</ul>
</%def>