diff --git a/rhodecode/apps/admin/__init__.py b/rhodecode/apps/admin/__init__.py --- a/rhodecode/apps/admin/__init__.py +++ b/rhodecode/apps/admin/__init__.py @@ -72,10 +72,36 @@ def admin_routes(config): pattern='/settings/process_management/signal') # global permissions + + config.add_route( + name='admin_permissions_application', + pattern='/permissions/application') + config.add_route( + name='admin_permissions_application_update', + pattern='/permissions/application/update') + + config.add_route( + name='admin_permissions_global', + pattern='/permissions/global') + config.add_route( + name='admin_permissions_global_update', + pattern='/permissions/global/update') + + config.add_route( + name='admin_permissions_object', + pattern='/permissions/object') + config.add_route( + name='admin_permissions_object_update', + pattern='/permissions/object/update') + config.add_route( name='admin_permissions_ips', pattern='/permissions/ips') + config.add_route( + name='admin_permissions_overview', + pattern='/permissions/overview') + # users admin config.add_route( name='users', diff --git a/rhodecode/tests/functional/test_admin_permissions.py b/rhodecode/apps/admin/tests/test_admin_permissions.py rename from rhodecode/tests/functional/test_admin_permissions.py rename to rhodecode/apps/admin/tests/test_admin_permissions.py --- a/rhodecode/tests/functional/test_admin_permissions.py +++ b/rhodecode/apps/admin/tests/test_admin_permissions.py @@ -22,7 +22,7 @@ import pytest from rhodecode.model.db import User, UserIpMap from rhodecode.model.permission import PermissionModel from rhodecode.tests import ( - TestController, url, clear_all_caches, assert_session_flash) + TestController, clear_all_caches, assert_session_flash) def route_path(name, params=None, **kwargs): @@ -36,6 +36,27 @@ def route_path(name, params=None, **kwar ADMIN_PREFIX + '/users/{user_id}/edit/ips/new', 'edit_user_ips_delete': ADMIN_PREFIX + '/users/{user_id}/edit/ips/delete', + + 'admin_permissions_application': + ADMIN_PREFIX + '/permissions/application', + 'admin_permissions_application_update': + ADMIN_PREFIX + '/permissions/application/update', + + 'admin_permissions_global': + ADMIN_PREFIX + '/permissions/global', + 'admin_permissions_global_update': + ADMIN_PREFIX + '/permissions/global/update', + + 'admin_permissions_object': + ADMIN_PREFIX + '/permissions/object', + 'admin_permissions_object_update': + ADMIN_PREFIX + '/permissions/object/update', + + 'admin_permissions_ips': + ADMIN_PREFIX + '/permissions/ips', + 'admin_permissions_overview': + ADMIN_PREFIX + '/permissions/overview' + }[name].format(**kwargs) if params: @@ -55,7 +76,7 @@ class TestAdminPermissionsController(Tes def test_index_application(self): self.log_user() - self.app.get(url('admin_permissions_application')) + self.app.get(route_path('admin_permissions_application')) @pytest.mark.parametrize( 'anonymous, default_register, default_register_message, default_password_reset,' @@ -87,7 +108,7 @@ class TestAdminPermissionsController(Tes 'default_password_reset': default_password_reset, 'default_extern_activate': default_extern_activate, } - response = self.app.post(url('admin_permissions_application'), + response = self.app.post(route_path('admin_permissions_application_update'), params=params) if expect_form_error: assert response.status_int == 200 @@ -101,7 +122,7 @@ class TestAdminPermissionsController(Tes def test_index_object(self): self.log_user() - self.app.get(url('admin_permissions_object')) + self.app.get(route_path('admin_permissions_object')) @pytest.mark.parametrize( 'repo, repo_group, user_group, expect_error, expect_form_error', [ @@ -127,7 +148,7 @@ class TestAdminPermissionsController(Tes 'default_user_group_perm': user_group, 'overwrite_default_user_group': False, } - response = self.app.post(url('admin_permissions_object'), + response = self.app.post(route_path('admin_permissions_object_update'), params=params) if expect_form_error: assert response.status_int == 200 @@ -141,7 +162,7 @@ class TestAdminPermissionsController(Tes def test_index_global(self): self.log_user() - self.app.get(url('admin_permissions_global')) + self.app.get(route_path('admin_permissions_global')) @pytest.mark.parametrize( 'repo_create, repo_create_write, user_group_create, repo_group_create,' @@ -175,7 +196,7 @@ class TestAdminPermissionsController(Tes 'default_fork_create': fork_create, 'default_inherit_default_permissions': inherit_default_permissions } - response = self.app.post(url('admin_permissions_global'), + response = self.app.post(route_path('admin_permissions_global_update'), params=params) if expect_form_error: assert response.status_int == 200 @@ -189,7 +210,7 @@ class TestAdminPermissionsController(Tes def test_index_ips(self): self.log_user() - response = self.app.get(url('admin_permissions_ips')) + response = self.app.get(route_path('admin_permissions_ips')) # TODO: Test response... response.mustcontain('All IP addresses are allowed') @@ -203,7 +224,7 @@ class TestAdminPermissionsController(Tes route_path('edit_user_ips_add', user_id=default_user_id), params={'new_ip': '127.0.0.0/24', 'csrf_token': self.csrf_token}) - response = self.app.get(url('admin_permissions_ips')) + response = self.app.get(route_path('admin_permissions_ips')) response.mustcontain('127.0.0.0/24') response.mustcontain('127.0.0.0 - 127.0.0.255') @@ -219,11 +240,11 @@ class TestAdminPermissionsController(Tes assert_session_flash(response, 'Removed ip address from user whitelist') clear_all_caches() - response = self.app.get(url('admin_permissions_ips')) + response = self.app.get(route_path('admin_permissions_ips')) response.mustcontain('All IP addresses are allowed') response.mustcontain(no=['127.0.0.0/24']) response.mustcontain(no=['127.0.0.0 - 127.0.0.255']) def test_index_overview(self): self.log_user() - self.app.get(url('admin_permissions_overview')) + self.app.get(route_path('admin_permissions_overview')) diff --git a/rhodecode/apps/admin/views/permissions.py b/rhodecode/apps/admin/views/permissions.py new file mode 100644 --- /dev/null +++ b/rhodecode/apps/admin/views/permissions.py @@ -0,0 +1,310 @@ +# -*- 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 . +# +# 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 +import formencode + +from pyramid.view import view_config +from pyramid.httpexceptions import HTTPFound +from pyramid.renderers import render +from pyramid.response import Response + +from rhodecode.apps._base import BaseAppView + +from rhodecode.lib import helpers as h +from rhodecode.lib.auth import ( + LoginRequired, HasPermissionAllDecorator, CSRFRequired) +from rhodecode.model.db import User, UserIpMap +from rhodecode.model.forms import ( + ApplicationPermissionsForm, ObjectPermissionsForm, UserPermissionsForm) +from rhodecode.model.meta import Session +from rhodecode.model.permission import PermissionModel +from rhodecode.model.settings import SettingsModel + + +log = logging.getLogger(__name__) + + +class AdminPermissionsView(BaseAppView): + def load_default_context(self): + c = self._get_local_tmpl_context() + + self._register_global_c(c) + PermissionModel().set_global_permission_choices( + c, gettext_translator=self.request.translate) + return c + + @LoginRequired() + @HasPermissionAllDecorator('hg.admin') + @view_config( + route_name='admin_permissions_application', request_method='GET', + renderer='rhodecode:templates/admin/permissions/permissions.mako') + def permissions_application(self): + c = self.load_default_context() + c.active = 'application' + + c.user = User.get_default_user(refresh=True) + + app_settings = SettingsModel().get_all_settings() + defaults = { + 'anonymous': c.user.active, + 'default_register_message': app_settings.get( + 'rhodecode_register_message') + } + defaults.update(c.user.get_default_perms()) + + data = render('rhodecode:templates/admin/permissions/permissions.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') + @CSRFRequired() + @view_config( + route_name='admin_permissions_application_update', request_method='POST', + renderer='rhodecode:templates/admin/permissions/permissions.mako') + def permissions_application_update(self): + _ = self.request.translate + c = self.load_default_context() + c.active = 'application' + + _form = ApplicationPermissionsForm( + [x[0] for x in c.register_choices], + [x[0] for x in c.password_reset_choices], + [x[0] for x in c.extern_activate_choices])() + + try: + form_result = _form.to_python(dict(self.request.POST)) + form_result.update({'perm_user_name': User.DEFAULT_USER}) + PermissionModel().update_application_permissions(form_result) + + settings = [ + ('register_message', 'default_register_message'), + ] + for setting, form_key in settings: + sett = SettingsModel().create_or_update_setting( + setting, form_result[form_key]) + Session().add(sett) + + Session().commit() + h.flash(_('Application permissions updated successfully'), + category='success') + + except formencode.Invalid as errors: + defaults = errors.value + + data = render( + 'rhodecode:templates/admin/permissions/permissions.mako', + self._get_template_context(c), self.request) + html = formencode.htmlfill.render( + data, + defaults=defaults, + errors=errors.error_dict or {}, + prefix_error=False, + encoding="UTF-8", + force_defaults=False + ) + return Response(html) + + except Exception: + log.exception("Exception during update of permissions") + h.flash(_('Error occurred during update of permissions'), + category='error') + + raise HTTPFound(h.route_path('admin_permissions_application')) + + @LoginRequired() + @HasPermissionAllDecorator('hg.admin') + @view_config( + route_name='admin_permissions_object', request_method='GET', + renderer='rhodecode:templates/admin/permissions/permissions.mako') + def permissions_objects(self): + c = self.load_default_context() + c.active = 'objects' + + c.user = User.get_default_user(refresh=True) + defaults = {} + defaults.update(c.user.get_default_perms()) + + data = render( + 'rhodecode:templates/admin/permissions/permissions.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') + @CSRFRequired() + @view_config( + route_name='admin_permissions_object_update', request_method='POST', + renderer='rhodecode:templates/admin/permissions/permissions.mako') + def permissions_objects_update(self): + _ = self.request.translate + c = self.load_default_context() + c.active = 'objects' + + _form = ObjectPermissionsForm( + [x[0] for x in c.repo_perms_choices], + [x[0] for x in c.group_perms_choices], + [x[0] for x in c.user_group_perms_choices])() + + try: + form_result = _form.to_python(dict(self.request.POST)) + form_result.update({'perm_user_name': User.DEFAULT_USER}) + PermissionModel().update_object_permissions(form_result) + + Session().commit() + h.flash(_('Object permissions updated successfully'), + category='success') + + except formencode.Invalid as errors: + defaults = errors.value + + data = render( + 'rhodecode:templates/admin/permissions/permissions.mako', + self._get_template_context(c), self.request) + html = formencode.htmlfill.render( + data, + defaults=defaults, + errors=errors.error_dict or {}, + prefix_error=False, + encoding="UTF-8", + force_defaults=False + ) + return Response(html) + except Exception: + log.exception("Exception during update of permissions") + h.flash(_('Error occurred during update of permissions'), + category='error') + + raise HTTPFound(h.route_path('admin_permissions_object')) + + @LoginRequired() + @HasPermissionAllDecorator('hg.admin') + @view_config( + route_name='admin_permissions_global', request_method='GET', + renderer='rhodecode:templates/admin/permissions/permissions.mako') + def permissions_global(self): + c = self.load_default_context() + c.active = 'global' + + c.user = User.get_default_user(refresh=True) + defaults = {} + defaults.update(c.user.get_default_perms()) + + data = render( + 'rhodecode:templates/admin/permissions/permissions.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') + @CSRFRequired() + @view_config( + route_name='admin_permissions_global_update', request_method='POST', + renderer='rhodecode:templates/admin/permissions/permissions.mako') + def permissions_global_update(self): + _ = self.request.translate + c = self.load_default_context() + c.active = 'global' + + _form = UserPermissionsForm( + [x[0] for x in c.repo_create_choices], + [x[0] for x in c.repo_create_on_write_choices], + [x[0] for x in c.repo_group_create_choices], + [x[0] for x in c.user_group_create_choices], + [x[0] for x in c.fork_choices], + [x[0] for x in c.inherit_default_permission_choices])() + + try: + form_result = _form.to_python(dict(self.request.POST)) + form_result.update({'perm_user_name': User.DEFAULT_USER}) + PermissionModel().update_user_permissions(form_result) + + Session().commit() + h.flash(_('Global permissions updated successfully'), + category='success') + + except formencode.Invalid as errors: + defaults = errors.value + + data = render( + 'rhodecode:templates/admin/permissions/permissions.mako', + self._get_template_context(c), self.request) + html = formencode.htmlfill.render( + data, + defaults=defaults, + errors=errors.error_dict or {}, + prefix_error=False, + encoding="UTF-8", + force_defaults=False + ) + return Response(html) + except Exception: + log.exception("Exception during update of permissions") + h.flash(_('Error occurred during update of permissions'), + category='error') + + raise HTTPFound(h.route_path('admin_permissions_global')) + + @LoginRequired() + @HasPermissionAllDecorator('hg.admin') + @view_config( + route_name='admin_permissions_ips', request_method='GET', + renderer='rhodecode:templates/admin/permissions/permissions.mako') + def permissions_ips(self): + c = self.load_default_context() + c.active = 'ips' + + c.user = User.get_default_user(refresh=True) + c.user_ip_map = ( + UserIpMap.query().filter(UserIpMap.user == c.user).all()) + + return self._get_template_context(c) + + @LoginRequired() + @HasPermissionAllDecorator('hg.admin') + @view_config( + route_name='admin_permissions_overview', request_method='GET', + renderer='rhodecode:templates/admin/permissions/permissions.mako') + def permissions_overview(self): + c = self.load_default_context() + c.active = 'perms' + + c.user = User.get_default_user(refresh=True) + c.perm_user = c.user.AuthUser + return self._get_template_context(c) diff --git a/rhodecode/tests/functional/test_login.py b/rhodecode/apps/login/tests/test_login.py rename from rhodecode/tests/functional/test_login.py rename to rhodecode/apps/login/tests/test_login.py --- a/rhodecode/tests/functional/test_login.py +++ b/rhodecode/apps/login/tests/test_login.py @@ -23,9 +23,8 @@ import urlparse import mock import pytest -from rhodecode.config.routing import ADMIN_PREFIX from rhodecode.tests import ( - assert_session_flash, url, HG_REPO, TEST_USER_ADMIN_LOGIN, + assert_session_flash, HG_REPO, TEST_USER_ADMIN_LOGIN, no_newline_id_generator) from rhodecode.tests.fixture import Fixture from rhodecode.lib.auth import check_password @@ -37,14 +36,32 @@ from rhodecode.model.meta import Session fixture = Fixture() -# Hardcode URLs because we don't have a request object to use -# pyramids URL generation methods. -index_url = '/' -login_url = ADMIN_PREFIX + '/login' -logut_url = ADMIN_PREFIX + '/logout' -register_url = ADMIN_PREFIX + '/register' -pwd_reset_url = ADMIN_PREFIX + '/password_reset' -pwd_reset_confirm_url = ADMIN_PREFIX + '/password_reset_confirmation' + +def route_path(name, params=None, **kwargs): + import urllib + from rhodecode.apps._base import ADMIN_PREFIX + + base_url = { + 'login': ADMIN_PREFIX + '/login', + 'logout': ADMIN_PREFIX + '/logout', + 'register': ADMIN_PREFIX + '/register', + 'reset_password': + ADMIN_PREFIX + '/password_reset', + 'reset_password_confirmation': + ADMIN_PREFIX + '/password_reset_confirmation', + + 'admin_permissions_application': + ADMIN_PREFIX + '/permissions/application', + 'admin_permissions_application_update': + ADMIN_PREFIX + '/permissions/application/update', + + 'repo_commit_raw': '/{repo_name}/raw-changeset/{commit_id}' + + }[name].format(**kwargs) + + if params: + base_url = '{}?{}'.format(base_url, urllib.urlencode(params)) + return base_url @pytest.mark.usefixtures('app') @@ -63,12 +80,12 @@ class TestLoginController(object): assert Notification.query().all() == [] def test_index(self): - response = self.app.get(login_url) + response = self.app.get(route_path('login')) assert response.status == '200 OK' # Test response... def test_login_admin_ok(self): - response = self.app.post(login_url, + response = self.app.post(route_path('login'), {'username': 'test_admin', 'password': 'test12'}) assert response.status == '302 Found' @@ -79,7 +96,7 @@ class TestLoginController(object): response.mustcontain('/%s' % HG_REPO) def test_login_regular_ok(self): - response = self.app.post(login_url, + response = self.app.post(route_path('login'), {'username': 'test_regular', 'password': 'test12'}) @@ -92,7 +109,7 @@ class TestLoginController(object): def test_login_ok_came_from(self): test_came_from = '/_admin/users?branch=stable' - _url = '{}?came_from={}'.format(login_url, test_came_from) + _url = '{}?came_from={}'.format(route_path('login'), test_came_from) response = self.app.post( _url, {'username': 'test_admin', 'password': 'test12'}) assert response.status == '302 Found' @@ -113,7 +130,7 @@ class TestLoginController(object): assert 'branch=stable' in response_query[0][1] def test_login_form_with_get_args(self): - _url = '{}?came_from=/_admin/users,branch=stable'.format(login_url) + _url = '{}?came_from=/_admin/users,branch=stable'.format(route_path('login')) response = self.app.get(_url) assert 'branch%3Dstable' in response.form.action @@ -126,7 +143,7 @@ class TestLoginController(object): '/\r\nX-Forwarded-Host: http://example.org', ], ids=no_newline_id_generator) def test_login_bad_came_froms(self, url_came_from): - _url = '{}?came_from={}'.format(login_url, url_came_from) + _url = '{}?came_from={}'.format(route_path('login'), url_came_from) response = self.app.post( _url, {'username': 'test_admin', 'password': 'test12'}) @@ -136,7 +153,7 @@ class TestLoginController(object): assert response.request.path == '/' def test_login_short_password(self): - response = self.app.post(login_url, + response = self.app.post(route_path('login'), {'username': 'test_admin', 'password': 'as'}) assert response.status == '200 OK' @@ -145,7 +162,7 @@ class TestLoginController(object): def test_login_wrong_non_ascii_password(self, user_regular): response = self.app.post( - login_url, + route_path('login'), {'username': user_regular.username, 'password': u'invalid-non-asci\xe4'.encode('utf8')}) @@ -156,13 +173,13 @@ class TestLoginController(object): password = u'valid-non-ascii\xe4' user = user_util.create_user(password=password) response = self.app.post( - login_url, + route_path('login'), {'username': user.username, 'password': password.encode('utf-8')}) assert response.status_code == 302 def test_login_wrong_username_password(self): - response = self.app.post(login_url, + response = self.app.post(route_path('login'), {'username': 'error', 'password': 'test12'}) @@ -180,7 +197,7 @@ class TestLoginController(object): Session().add(user) Session().commit() self.destroy_users.add(temp_user) - response = self.app.post(login_url, + response = self.app.post(route_path('login'), {'username': temp_user, 'password': 'test123'}) @@ -197,13 +214,13 @@ class TestLoginController(object): # REGISTRATIONS def test_register(self): - response = self.app.get(register_url) + response = self.app.get(route_path('register')) response.mustcontain('Create an Account') def test_register_err_same_username(self): uname = 'test_admin' response = self.app.post( - register_url, + route_path('register'), { 'username': uname, 'password': 'test12', @@ -221,7 +238,7 @@ class TestLoginController(object): def test_register_err_same_email(self): response = self.app.post( - register_url, + route_path('register'), { 'username': 'test_admin_0', 'password': 'test12', @@ -238,7 +255,7 @@ class TestLoginController(object): def test_register_err_same_email_case_sensitive(self): response = self.app.post( - register_url, + route_path('register'), { 'username': 'test_admin_1', 'password': 'test12', @@ -254,7 +271,7 @@ class TestLoginController(object): def test_register_err_wrong_data(self): response = self.app.post( - register_url, + route_path('register'), { 'username': 'xs', 'password': 'test', @@ -270,7 +287,7 @@ class TestLoginController(object): def test_register_err_username(self): response = self.app.post( - register_url, + route_path('register'), { 'username': 'error user', 'password': 'test12', @@ -291,7 +308,7 @@ class TestLoginController(object): def test_register_err_case_sensitive(self): usr = 'Test_Admin' response = self.app.post( - register_url, + route_path('register'), { 'username': usr, 'password': 'test12', @@ -309,7 +326,7 @@ class TestLoginController(object): def test_register_special_chars(self): response = self.app.post( - register_url, + route_path('register'), { 'username': 'xxxaxn', 'password': 'ąćźżąśśśś', @@ -325,7 +342,7 @@ class TestLoginController(object): def test_register_password_mismatch(self): response = self.app.post( - register_url, + route_path('register'), { 'username': 'xs', 'password': '123qwe', @@ -346,7 +363,7 @@ class TestLoginController(object): lastname = 'testlastname' response = self.app.post( - register_url, + route_path('register'), { 'username': username, 'password': password, @@ -374,29 +391,29 @@ class TestLoginController(object): def test_forgot_password_wrong_mail(self): bad_email = 'marcin@wrongmail.org' response = self.app.post( - pwd_reset_url, {'email': bad_email, } + route_path('reset_password'), {'email': bad_email, } ) assert_session_flash(response, 'If such email exists, a password reset link was sent to it.') def test_forgot_password(self, user_util): - response = self.app.get(pwd_reset_url) + response = self.app.get(route_path('reset_password')) assert response.status == '200 OK' user = user_util.create_user() user_id = user.user_id email = user.email - response = self.app.post(pwd_reset_url, {'email': email, }) + response = self.app.post(route_path('reset_password'), {'email': email, }) assert_session_flash(response, 'If such email exists, a password reset link was sent to it.') # BAD KEY - confirm_url = '{}?key={}'.format(pwd_reset_confirm_url, 'badkey') + confirm_url = '{}?key={}'.format(route_path('reset_password_confirmation'), 'badkey') response = self.app.get(confirm_url) assert response.status == '302 Found' - assert response.location.endswith(pwd_reset_url) + assert response.location.endswith(route_path('reset_password')) assert_session_flash(response, 'Given reset token is invalid') response.follow() # cleanup flash @@ -409,10 +426,10 @@ class TestLoginController(object): assert key - confirm_url = '{}?key={}'.format(pwd_reset_confirm_url, key.api_key) + confirm_url = '{}?key={}'.format(route_path('reset_password_confirmation'), key.api_key) response = self.app.get(confirm_url) assert response.status == '302 Found' - assert response.location.endswith(login_url) + assert response.location.endswith(route_path('login')) assert_session_flash( response, @@ -442,11 +459,11 @@ class TestLoginController(object): auth_token = user_admin.api_key with fixture.anon_access(False): - self.app.get(url(controller='changeset', - action='changeset_raw', - repo_name=HG_REPO, revision='tip', - api_key=auth_token), - status=302) + self.app.get( + route_path('repo_commit_raw', + repo_name=HG_REPO, commit_id='tip', + params=dict(api_key=auth_token)), + status=302) @pytest.mark.parametrize("test_name, auth_token, code", [ ('none', None, 302), @@ -468,11 +485,11 @@ class TestLoginController(object): assert auth_token with fixture.anon_access(False): - self.app.get(url(controller='changeset', - action='changeset_raw', - repo_name=HG_REPO, revision='tip', - api_key=auth_token), - status=code) + self.app.get( + route_path('repo_commit_raw', + repo_name=HG_REPO, commit_id='tip', + params=dict(api_key=auth_token)), + status=code) def test_access_page_via_extra_auth_token(self): whitelist = self._get_api_whitelist( @@ -485,11 +502,11 @@ class TestLoginController(object): TEST_USER_ADMIN_LOGIN, 'test') Session().commit() with fixture.anon_access(False): - self.app.get(url(controller='changeset', - action='changeset_raw', - repo_name=HG_REPO, revision='tip', - api_key=new_auth_token.api_key), - status=200) + self.app.get( + route_path('repo_commit_raw', + repo_name=HG_REPO, commit_id='tip', + params=dict(api_key=new_auth_token.api_key)), + status=200) def test_access_page_via_expired_auth_token(self): whitelist = self._get_api_whitelist( @@ -506,8 +523,8 @@ class TestLoginController(object): Session().add(new_auth_token) Session().commit() with fixture.anon_access(False): - self.app.get(url(controller='changeset', - action='changeset_raw', - repo_name=HG_REPO, revision='tip', - api_key=new_auth_token.api_key), - status=302) + self.app.get( + route_path('repo_commit_raw', + repo_name=HG_REPO, commit_id='tip', + params=dict(api_key=new_auth_token.api_key)), + status=302) diff --git a/rhodecode/tests/functional/test_password_reset.py b/rhodecode/apps/login/tests/test_password_reset.py rename from rhodecode/tests/functional/test_password_reset.py rename to rhodecode/apps/login/tests/test_password_reset.py --- a/rhodecode/tests/functional/test_password_reset.py +++ b/rhodecode/apps/login/tests/test_password_reset.py @@ -20,23 +20,38 @@ import pytest -from rhodecode.config.routing import ADMIN_PREFIX +from rhodecode.lib import helpers as h from rhodecode.tests import ( - TestController, clear_all_caches, url, + TestController, clear_all_caches, TEST_USER_ADMIN_LOGIN, TEST_USER_ADMIN_PASS) from rhodecode.tests.fixture import Fixture from rhodecode.tests.utils import AssertResponse fixture = Fixture() -# Hardcode URLs because we don't have a request object to use -# pyramids URL generation methods. -index_url = '/' -login_url = ADMIN_PREFIX + '/login' -logut_url = ADMIN_PREFIX + '/logout' -register_url = ADMIN_PREFIX + '/register' -pwd_reset_url = ADMIN_PREFIX + '/password_reset' -pwd_reset_confirm_url = ADMIN_PREFIX + '/password_reset_confirmation' + +def route_path(name, params=None, **kwargs): + import urllib + from rhodecode.apps._base import ADMIN_PREFIX + + base_url = { + 'login': ADMIN_PREFIX + '/login', + 'logout': ADMIN_PREFIX + '/logout', + 'register': ADMIN_PREFIX + '/register', + 'reset_password': + ADMIN_PREFIX + '/password_reset', + 'reset_password_confirmation': + ADMIN_PREFIX + '/password_reset_confirmation', + + 'admin_permissions_application': + ADMIN_PREFIX + '/permissions/application', + 'admin_permissions_application_update': + ADMIN_PREFIX + '/permissions/application/update', + }[name].format(**kwargs) + + if params: + base_url = '{}?{}'.format(base_url, urllib.urlencode(params)) + return base_url class TestPasswordReset(TestController): @@ -59,12 +74,12 @@ class TestPasswordReset(TestController): 'default_password_reset': pwd_reset_setting, 'default_extern_activate': 'hg.extern_activate.auto', } - resp = self.app.post(url('admin_permissions_application'), params=params) + resp = self.app.post(route_path('admin_permissions_application_update'), params=params) self.logout_user() - login_page = self.app.get(login_url) + login_page = self.app.get(route_path('login')) asr_login = AssertResponse(login_page) - index_page = self.app.get(index_url) + index_page = self.app.get(h.route_path('home')) asr_index = AssertResponse(index_page) if show_link: @@ -74,7 +89,7 @@ class TestPasswordReset(TestController): asr_login.no_element_exists('a.pwd_reset') asr_index.no_element_exists('a.pwd_reset') - response = self.app.get(pwd_reset_url) + response = self.app.get(route_path('reset_password')) assert_response = AssertResponse(response) if show_reset: @@ -96,11 +111,11 @@ class TestPasswordReset(TestController): 'default_password_reset': 'hg.password_reset.disabled', 'default_extern_activate': 'hg.extern_activate.auto', } - self.app.post(url('admin_permissions_application'), params=params) + self.app.post(route_path('admin_permissions_application_update'), params=params) self.logout_user() response = self.app.post( - pwd_reset_url, {'email': 'lisa@rhodecode.com',} + route_path('reset_password'), {'email': 'lisa@rhodecode.com',} ) response = response.follow() response.mustcontain('Password reset is disabled.') diff --git a/rhodecode/config/routing.py b/rhodecode/config/routing.py --- a/rhodecode/config/routing.py +++ b/rhodecode/config/routing.py @@ -321,32 +321,6 @@ def make_map(config): '/user_groups/{user_group_id}/edit/members', jsroute=True, action='user_group_members', conditions={'method': ['GET']}) - # ADMIN PERMISSIONS ROUTES - with rmap.submapper(path_prefix=ADMIN_PREFIX, - controller='admin/permissions') as m: - m.connect('admin_permissions_application', '/permissions/application', - action='permission_application_update', conditions={'method': ['POST']}) - m.connect('admin_permissions_application', '/permissions/application', - action='permission_application', conditions={'method': ['GET']}) - - m.connect('admin_permissions_global', '/permissions/global', - action='permission_global_update', conditions={'method': ['POST']}) - m.connect('admin_permissions_global', '/permissions/global', - action='permission_global', conditions={'method': ['GET']}) - - m.connect('admin_permissions_object', '/permissions/object', - action='permission_objects_update', conditions={'method': ['POST']}) - m.connect('admin_permissions_object', '/permissions/object', - action='permission_objects', conditions={'method': ['GET']}) - - m.connect('admin_permissions_ips', '/permissions/ips', - action='permission_ips', conditions={'method': ['POST']}) - m.connect('admin_permissions_ips', '/permissions/ips', - action='permission_ips', conditions={'method': ['GET']}) - - m.connect('admin_permissions_overview', '/permissions/overview', - action='permission_perms', conditions={'method': ['GET']}) - # ADMIN DEFAULTS REST ROUTES with rmap.submapper(path_prefix=ADMIN_PREFIX, controller='admin/defaults') as m: diff --git a/rhodecode/controllers/admin/permissions.py b/rhodecode/controllers/admin/permissions.py deleted file mode 100644 --- a/rhodecode/controllers/admin/permissions.py +++ /dev/null @@ -1,244 +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 . -# -# 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/ - - -""" -permissions controller for RhodeCode Enterprise -""" - - -import logging - -import formencode -from formencode import htmlfill -from pylons import request, tmpl_context as c, url -from pylons.controllers.util import redirect -from pylons.i18n.translation import _ - -from rhodecode.lib import helpers as h -from rhodecode.lib import auth -from rhodecode.lib.auth import (LoginRequired, HasPermissionAllDecorator) -from rhodecode.lib.base import BaseController, render -from rhodecode.model.db import User, UserIpMap -from rhodecode.model.forms import ( - ApplicationPermissionsForm, ObjectPermissionsForm, UserPermissionsForm) -from rhodecode.model.meta import Session -from rhodecode.model.permission import PermissionModel -from rhodecode.model.settings import SettingsModel - -log = logging.getLogger(__name__) - - -class PermissionsController(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('permission', 'permissions') - - @LoginRequired() - def __before__(self): - super(PermissionsController, self).__before__() - - def __load_data(self): - PermissionModel().set_global_permission_choices(c, gettext_translator=_) - - @HasPermissionAllDecorator('hg.admin') - def permission_application(self): - c.active = 'application' - self.__load_data() - - c.user = User.get_default_user(refresh=True) - - app_settings = SettingsModel().get_all_settings() - defaults = { - 'anonymous': c.user.active, - 'default_register_message': app_settings.get( - 'rhodecode_register_message') - } - defaults.update(c.user.get_default_perms()) - - return htmlfill.render( - render('admin/permissions/permissions.mako'), - defaults=defaults, - encoding="UTF-8", - force_defaults=False) - - @HasPermissionAllDecorator('hg.admin') - @auth.CSRFRequired() - def permission_application_update(self): - c.active = 'application' - self.__load_data() - _form = ApplicationPermissionsForm( - [x[0] for x in c.register_choices], - [x[0] for x in c.password_reset_choices], - [x[0] for x in c.extern_activate_choices])() - - try: - form_result = _form.to_python(dict(request.POST)) - form_result.update({'perm_user_name': User.DEFAULT_USER}) - PermissionModel().update_application_permissions(form_result) - - settings = [ - ('register_message', 'default_register_message'), - ] - for setting, form_key in settings: - sett = SettingsModel().create_or_update_setting( - setting, form_result[form_key]) - Session().add(sett) - - Session().commit() - h.flash(_('Application permissions updated successfully'), - category='success') - - except formencode.Invalid as errors: - defaults = errors.value - - return htmlfill.render( - render('admin/permissions/permissions.mako'), - defaults=defaults, - errors=errors.error_dict or {}, - prefix_error=False, - encoding="UTF-8", - force_defaults=False) - except Exception: - log.exception("Exception during update of permissions") - h.flash(_('Error occurred during update of permissions'), - category='error') - - return redirect(url('admin_permissions_application')) - - @HasPermissionAllDecorator('hg.admin') - def permission_objects(self): - c.active = 'objects' - self.__load_data() - c.user = User.get_default_user() - defaults = {} - defaults.update(c.user.get_default_perms()) - return htmlfill.render( - render('admin/permissions/permissions.mako'), - defaults=defaults, - encoding="UTF-8", - force_defaults=False) - - @HasPermissionAllDecorator('hg.admin') - @auth.CSRFRequired() - def permission_objects_update(self): - c.active = 'objects' - self.__load_data() - _form = ObjectPermissionsForm( - [x[0] for x in c.repo_perms_choices], - [x[0] for x in c.group_perms_choices], - [x[0] for x in c.user_group_perms_choices])() - - try: - form_result = _form.to_python(dict(request.POST)) - form_result.update({'perm_user_name': User.DEFAULT_USER}) - PermissionModel().update_object_permissions(form_result) - - Session().commit() - h.flash(_('Object permissions updated successfully'), - category='success') - - except formencode.Invalid as errors: - defaults = errors.value - - return htmlfill.render( - render('admin/permissions/permissions.mako'), - defaults=defaults, - errors=errors.error_dict or {}, - prefix_error=False, - encoding="UTF-8", - force_defaults=False) - except Exception: - log.exception("Exception during update of permissions") - h.flash(_('Error occurred during update of permissions'), - category='error') - - return redirect(url('admin_permissions_object')) - - @HasPermissionAllDecorator('hg.admin') - def permission_global(self): - c.active = 'global' - self.__load_data() - - c.user = User.get_default_user() - defaults = {} - defaults.update(c.user.get_default_perms()) - - return htmlfill.render( - render('admin/permissions/permissions.mako'), - defaults=defaults, - encoding="UTF-8", - force_defaults=False) - - @HasPermissionAllDecorator('hg.admin') - @auth.CSRFRequired() - def permission_global_update(self): - c.active = 'global' - self.__load_data() - _form = UserPermissionsForm( - [x[0] for x in c.repo_create_choices], - [x[0] for x in c.repo_create_on_write_choices], - [x[0] for x in c.repo_group_create_choices], - [x[0] for x in c.user_group_create_choices], - [x[0] for x in c.fork_choices], - [x[0] for x in c.inherit_default_permission_choices])() - - try: - form_result = _form.to_python(dict(request.POST)) - form_result.update({'perm_user_name': User.DEFAULT_USER}) - PermissionModel().update_user_permissions(form_result) - - Session().commit() - h.flash(_('Global permissions updated successfully'), - category='success') - - except formencode.Invalid as errors: - defaults = errors.value - - return htmlfill.render( - render('admin/permissions/permissions.mako'), - defaults=defaults, - errors=errors.error_dict or {}, - prefix_error=False, - encoding="UTF-8", - force_defaults=False) - except Exception: - log.exception("Exception during update of permissions") - h.flash(_('Error occurred during update of permissions'), - category='error') - - return redirect(url('admin_permissions_global')) - - @HasPermissionAllDecorator('hg.admin') - def permission_ips(self): - c.active = 'ips' - c.user = User.get_default_user() - c.user_ip_map = ( - UserIpMap.query().filter(UserIpMap.user == c.user).all()) - - return render('admin/permissions/permissions.mako') - - @HasPermissionAllDecorator('hg.admin') - def permission_perms(self): - c.active = 'perms' - c.user = User.get_default_user() - c.perm_user = c.user.AuthUser - return render('admin/permissions/permissions.mako') diff --git a/rhodecode/model/permission.py b/rhodecode/model/permission.py --- a/rhodecode/model/permission.py +++ b/rhodecode/model/permission.py @@ -62,62 +62,63 @@ class PermissionModel(BaseModel): } def set_global_permission_choices(self, c_obj, gettext_translator): + _ = gettext_translator c_obj.repo_perms_choices = [ - ('repository.none', gettext_translator('None'),), - ('repository.read', gettext_translator('Read'),), - ('repository.write', gettext_translator('Write'),), - ('repository.admin', gettext_translator('Admin'),)] + ('repository.none', _('None'),), + ('repository.read', _('Read'),), + ('repository.write', _('Write'),), + ('repository.admin', _('Admin'),)] c_obj.group_perms_choices = [ - ('group.none', gettext_translator('None'),), - ('group.read', gettext_translator('Read'),), - ('group.write', gettext_translator('Write'),), - ('group.admin', gettext_translator('Admin'),)] + ('group.none', _('None'),), + ('group.read', _('Read'),), + ('group.write', _('Write'),), + ('group.admin', _('Admin'),)] c_obj.user_group_perms_choices = [ - ('usergroup.none', gettext_translator('None'),), - ('usergroup.read', gettext_translator('Read'),), - ('usergroup.write', gettext_translator('Write'),), - ('usergroup.admin', gettext_translator('Admin'),)] + ('usergroup.none', _('None'),), + ('usergroup.read', _('Read'),), + ('usergroup.write', _('Write'),), + ('usergroup.admin', _('Admin'),)] c_obj.register_choices = [ - ('hg.register.none', gettext_translator('Disabled')), - ('hg.register.manual_activate', gettext_translator('Allowed with manual account activation')), - ('hg.register.auto_activate', gettext_translator('Allowed with automatic account activation')),] + ('hg.register.none', _('Disabled')), + ('hg.register.manual_activate', _('Allowed with manual account activation')), + ('hg.register.auto_activate', _('Allowed with automatic account activation')),] c_obj.password_reset_choices = [ - ('hg.password_reset.enabled', gettext_translator('Allow password recovery')), - ('hg.password_reset.hidden', gettext_translator('Hide password recovery link')), - ('hg.password_reset.disabled', gettext_translator('Disable password recovery')),] + ('hg.password_reset.enabled', _('Allow password recovery')), + ('hg.password_reset.hidden', _('Hide password recovery link')), + ('hg.password_reset.disabled', _('Disable password recovery')),] c_obj.extern_activate_choices = [ - ('hg.extern_activate.manual', gettext_translator('Manual activation of external account')), - ('hg.extern_activate.auto', gettext_translator('Automatic activation of external account')),] + ('hg.extern_activate.manual', _('Manual activation of external account')), + ('hg.extern_activate.auto', _('Automatic activation of external account')),] c_obj.repo_create_choices = [ - ('hg.create.none', gettext_translator('Disabled')), - ('hg.create.repository', gettext_translator('Enabled'))] + ('hg.create.none', _('Disabled')), + ('hg.create.repository', _('Enabled'))] c_obj.repo_create_on_write_choices = [ - ('hg.create.write_on_repogroup.false', gettext_translator('Disabled')), - ('hg.create.write_on_repogroup.true', gettext_translator('Enabled'))] + ('hg.create.write_on_repogroup.false', _('Disabled')), + ('hg.create.write_on_repogroup.true', _('Enabled'))] c_obj.user_group_create_choices = [ - ('hg.usergroup.create.false', gettext_translator('Disabled')), - ('hg.usergroup.create.true', gettext_translator('Enabled'))] + ('hg.usergroup.create.false', _('Disabled')), + ('hg.usergroup.create.true', _('Enabled'))] c_obj.repo_group_create_choices = [ - ('hg.repogroup.create.false', gettext_translator('Disabled')), - ('hg.repogroup.create.true', gettext_translator('Enabled'))] + ('hg.repogroup.create.false', _('Disabled')), + ('hg.repogroup.create.true', _('Enabled'))] c_obj.fork_choices = [ - ('hg.fork.none', gettext_translator('Disabled')), - ('hg.fork.repository', gettext_translator('Enabled'))] + ('hg.fork.none', _('Disabled')), + ('hg.fork.repository', _('Enabled'))] c_obj.inherit_default_permission_choices = [ - ('hg.inherit_default_perms.false', gettext_translator('Disabled')), - ('hg.inherit_default_perms.true', gettext_translator('Enabled'))] + ('hg.inherit_default_perms.false', _('Disabled')), + ('hg.inherit_default_perms.true', _('Enabled'))] def get_default_perms(self, object_perms, suffix): defaults = {} diff --git a/rhodecode/public/js/rhodecode/routes.js b/rhodecode/public/js/rhodecode/routes.js --- a/rhodecode/public/js/rhodecode/routes.js +++ b/rhodecode/public/js/rhodecode/routes.js @@ -63,7 +63,14 @@ function registerRCRoutes() { pyroutes.register('admin_settings_sessions_cleanup', '/_admin/settings/sessions/cleanup', []); pyroutes.register('admin_settings_process_management', '/_admin/settings/process_management', []); pyroutes.register('admin_settings_process_management_signal', '/_admin/settings/process_management/signal', []); + 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', []); + pyroutes.register('admin_permissions_global_update', '/_admin/permissions/global/update', []); + pyroutes.register('admin_permissions_object', '/_admin/permissions/object', []); + pyroutes.register('admin_permissions_object_update', '/_admin/permissions/object/update', []); pyroutes.register('admin_permissions_ips', '/_admin/permissions/ips', []); + pyroutes.register('admin_permissions_overview', '/_admin/permissions/overview', []); pyroutes.register('users', '/_admin/users', []); pyroutes.register('users_data', '/_admin/users_data', []); pyroutes.register('edit_user_auth_tokens', '/_admin/users/%(user_id)s/edit/auth_tokens', ['user_id']); diff --git a/rhodecode/templates/admin/permissions/permissions.mako b/rhodecode/templates/admin/permissions/permissions.mako --- a/rhodecode/templates/admin/permissions/permissions.mako +++ b/rhodecode/templates/admin/permissions/permissions.mako @@ -30,19 +30,19 @@ diff --git a/rhodecode/templates/admin/permissions/permissions_application.mako b/rhodecode/templates/admin/permissions/permissions_application.mako --- a/rhodecode/templates/admin/permissions/permissions_application.mako +++ b/rhodecode/templates/admin/permissions/permissions_application.mako @@ -3,7 +3,7 @@

${_('System Wide Application Permissions')}

- ${h.secure_form(h.url('admin_permissions_application'), method='post')} + ${h.secure_form(h.route_path('admin_permissions_application_update'), method='POST', request=request)}
@@ -15,7 +15,7 @@
${h.checkbox('anonymous',True)} Allow Anonymous Access
- ${h.literal(_('Allow access to RhodeCode Enterprise without requiring users to login. Anonymous users get the %s permission settings.' % (h.link_to('"default user"',h.url('admin_permissions_object')))))} + ${h.literal(_('Allow access to RhodeCode Enterprise without requiring users to login. Anonymous users get the %s permission settings.' % (h.link_to('"default user"',h.route_path('admin_permissions_object')))))}
diff --git a/rhodecode/templates/admin/permissions/permissions_global.mako b/rhodecode/templates/admin/permissions/permissions_global.mako --- a/rhodecode/templates/admin/permissions/permissions_global.mako +++ b/rhodecode/templates/admin/permissions/permissions_global.mako @@ -1,5 +1,5 @@ -${h.secure_form(h.url('admin_permissions_global'), method='post')} +${h.secure_form(h.route_path('admin_permissions_global_update'), method='POST', request=request)}
diff --git a/rhodecode/templates/admin/permissions/permissions_ips.mako b/rhodecode/templates/admin/permissions/permissions_ips.mako --- a/rhodecode/templates/admin/permissions/permissions_ips.mako +++ b/rhodecode/templates/admin/permissions/permissions_ips.mako @@ -6,6 +6,9 @@
+
${_('Current IP address')}: ${c.rhodecode_user.ip_addr}
+ + diff --git a/rhodecode/templates/admin/permissions/permissions_objects.mako b/rhodecode/templates/admin/permissions/permissions_objects.mako --- a/rhodecode/templates/admin/permissions/permissions_objects.mako +++ b/rhodecode/templates/admin/permissions/permissions_objects.mako @@ -5,7 +5,7 @@

${_('Default system permissions. Each permissions management entity will be created with the following default settings. Check the overwrite checkbox to force any permission changes on already existing settings.')}

- ${h.secure_form(h.url('admin_permissions_object'), method='post')} + ${h.secure_form(h.route_path('admin_permissions_object_update'), method='POST', request=request)}
diff --git a/rhodecode/templates/admin/users/user_edit_ips.mako b/rhodecode/templates/admin/users/user_edit_ips.mako --- a/rhodecode/templates/admin/users/user_edit_ips.mako +++ b/rhodecode/templates/admin/users/user_edit_ips.mako @@ -17,7 +17,7 @@
- + %endfor diff --git a/rhodecode/templates/base/base.mako b/rhodecode/templates/base/base.mako --- a/rhodecode/templates/base/base.mako +++ b/rhodecode/templates/base/base.mako @@ -77,7 +77,7 @@
  • ${_('Repository groups')}
  • ${_('Users')}
  • ${_('User groups')}
  • -
  • ${_('Permissions')}
  • +
  • ${_('Permissions')}
  • ${_('Authentication')}
  • ${_('Integrations')}
  • ${_('Defaults')}
  • diff --git a/rhodecode/templates/base/default_perms_box.mako b/rhodecode/templates/base/default_perms_box.mako --- a/rhodecode/templates/base/default_perms_box.mako +++ b/rhodecode/templates/base/default_perms_box.mako @@ -106,7 +106,7 @@ ${h.literal(_('Select to inherit permissions from %s permissions settings, ' 'including default IP address whitelist and inheritance of \npermission by members of user groups.') - % h.link_to('default user', h.url('admin_permissions_global')))} + % h.link_to('default user', h.route_path('admin_permissions_global')))} diff --git a/rhodecode/templates/base/perms_summary.mako b/rhodecode/templates/base/perms_summary.mako --- a/rhodecode/templates/base/perms_summary.mako +++ b/rhodecode/templates/base/perms_summary.mako @@ -76,7 +76,7 @@ %if actions: %endif @@ -84,14 +84,14 @@ ${glob(_('Super admin'), get_section_perms('hg.admin', permissions[section]))} - ${glob(_('Repository default permission'), get_section_perms('repository.', permissions[section]), 'repository', h.url('admin_permissions_object'))} - ${glob(_('Repository group default permission'), get_section_perms('group.', permissions[section]), 'group', h.url('admin_permissions_object'))} - ${glob(_('User group default permission'), get_section_perms('usergroup.', permissions[section]), 'usergroup', h.url('admin_permissions_object'))} + ${glob(_('Repository default permission'), get_section_perms('repository.', permissions[section]), 'repository', h.route_path('admin_permissions_object'))} + ${glob(_('Repository group default permission'), get_section_perms('group.', permissions[section]), 'group', h.route_path('admin_permissions_object'))} + ${glob(_('User group default permission'), get_section_perms('usergroup.', permissions[section]), 'usergroup', h.route_path('admin_permissions_object'))} - ${glob(_('Create repositories'), get_section_perms('hg.create.', permissions[section]), custom_url=h.url('admin_permissions_global'))} - ${glob(_('Fork repositories'), get_section_perms('hg.fork.', permissions[section]), custom_url=h.url('admin_permissions_global'))} - ${glob(_('Create repository groups'), get_section_perms('hg.repogroup.create.', permissions[section]), custom_url=h.url('admin_permissions_global'))} - ${glob(_('Create user groups'), get_section_perms('hg.usergroup.create.', permissions[section]), custom_url=h.url('admin_permissions_global'))} + ${glob(_('Create repositories'), get_section_perms('hg.create.', permissions[section]), custom_url=h.route_path('admin_permissions_global'))} + ${glob(_('Fork repositories'), get_section_perms('hg.fork.', permissions[section]), custom_url=h.route_path('admin_permissions_global'))} + ${glob(_('Create repository groups'), get_section_perms('hg.repogroup.create.', permissions[section]), custom_url=h.route_path('admin_permissions_global'))} + ${glob(_('Create user groups'), get_section_perms('hg.usergroup.create.', permissions[section]), custom_url=h.route_path('admin_permissions_global'))} diff --git a/rhodecode/tests/__init__.py b/rhodecode/tests/__init__.py --- a/rhodecode/tests/__init__.py +++ b/rhodecode/tests/__init__.py @@ -46,6 +46,7 @@ from rhodecode.config.routing import ADM from rhodecode.model.meta import Session from rhodecode.model.db import User from rhodecode.lib import auth +from rhodecode.lib import helpers as h from rhodecode.lib.helpers import flash, link_to from rhodecode.lib.utils2 import safe_unicode, safe_str @@ -166,9 +167,9 @@ class TestController(object): def login_user_session( app, username=TEST_USER_ADMIN_LOGIN, password=TEST_USER_ADMIN_PASS): - from rhodecode.tests.functional.test_login import login_url + response = app.post( - login_url, + h.route_path('login'), {'username': username, 'password': password}) if 'invalid user name' in response.body: pytest.fail('could not login using %s %s' % (username, password)) @@ -187,8 +188,7 @@ def login_user_session( def logout_user_session(app, csrf_token): - from rhodecode.tests.functional.test_login import logut_url - app.post(logut_url, {'csrf_token': csrf_token}, status=302) + app.post(h.route_path('logout'), {'csrf_token': csrf_token}, status=302) def login_user(app, username=TEST_USER_ADMIN_LOGIN, diff --git a/rhodecode/tests/functional/test_pullrequests.py b/rhodecode/tests/functional/test_pullrequests.py --- a/rhodecode/tests/functional/test_pullrequests.py +++ b/rhodecode/tests/functional/test_pullrequests.py @@ -99,13 +99,12 @@ class TestPullrequestsController(object) in response) != pr_merge_enabled def test_close_status_visibility(self, pr_util, user_util, csrf_token): - from rhodecode.tests.functional.test_login import login_url, logut_url # Logout response = self.app.post( - logut_url, + h.route_path('logout'), params={'csrf_token': csrf_token}) # Login as regular user - response = self.app.post(login_url, + response = self.app.post(h.route_path('login'), {'username': TEST_USER_REGULAR_LOGIN, 'password': 'test12'}) diff --git a/rhodecode/tests/utils.py b/rhodecode/tests/utils.py --- a/rhodecode/tests/utils.py +++ b/rhodecode/tests/utils.py @@ -410,7 +410,12 @@ def add_test_routes(config): """ Adds test routing that can be used in different functional tests """ + from rhodecode.apps._base import ADMIN_PREFIX + config.add_route(name='home', pattern='/') + + config.add_route(name='login', pattern=ADMIN_PREFIX + '/login') + config.add_route(name='logout', pattern=ADMIN_PREFIX + '/logout') config.add_route(name='repo_summary', pattern='/{repo_name}') config.add_route(name='repo_summary_explicit', pattern='/{repo_name}/summary') config.add_route(name='repo_group_home', pattern='/{repo_group_name}')
    IP Address
    ${ip.ip_addr}
    ${h.ip_range(ip.ip_addr)}
    ${h.literal(_('Inherited from %s') % h.link_to('*default*',h.url('admin_permissions_ips')))}${h.literal(_('Inherited from %s') % h.link_to('*default*',h.route_path('admin_permissions_ips')))}
    - ${_('edit')} + ${_('edit')}