Show More
@@ -0,0 +1,310 b'' | |||||
|
1 | # -*- coding: utf-8 -*- | |||
|
2 | ||||
|
3 | # Copyright (C) 2016-2017 RhodeCode GmbH | |||
|
4 | # | |||
|
5 | # This program is free software: you can redistribute it and/or modify | |||
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |||
|
7 | # (only), as published by the Free Software Foundation. | |||
|
8 | # | |||
|
9 | # This program is distributed in the hope that it will be useful, | |||
|
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
|
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
|
12 | # GNU General Public License for more details. | |||
|
13 | # | |||
|
14 | # You should have received a copy of the GNU Affero General Public License | |||
|
15 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
|
16 | # | |||
|
17 | # This program is dual-licensed. If you wish to learn more about the | |||
|
18 | # RhodeCode Enterprise Edition, including its added features, Support services, | |||
|
19 | # and proprietary license terms, please see https://rhodecode.com/licenses/ | |||
|
20 | ||||
|
21 | import logging | |||
|
22 | import formencode | |||
|
23 | ||||
|
24 | from pyramid.view import view_config | |||
|
25 | from pyramid.httpexceptions import HTTPFound | |||
|
26 | from pyramid.renderers import render | |||
|
27 | from pyramid.response import Response | |||
|
28 | ||||
|
29 | from rhodecode.apps._base import BaseAppView | |||
|
30 | ||||
|
31 | from rhodecode.lib import helpers as h | |||
|
32 | from rhodecode.lib.auth import ( | |||
|
33 | LoginRequired, HasPermissionAllDecorator, CSRFRequired) | |||
|
34 | from rhodecode.model.db import User, UserIpMap | |||
|
35 | from rhodecode.model.forms import ( | |||
|
36 | ApplicationPermissionsForm, ObjectPermissionsForm, UserPermissionsForm) | |||
|
37 | from rhodecode.model.meta import Session | |||
|
38 | from rhodecode.model.permission import PermissionModel | |||
|
39 | from rhodecode.model.settings import SettingsModel | |||
|
40 | ||||
|
41 | ||||
|
42 | log = logging.getLogger(__name__) | |||
|
43 | ||||
|
44 | ||||
|
45 | class AdminPermissionsView(BaseAppView): | |||
|
46 | def load_default_context(self): | |||
|
47 | c = self._get_local_tmpl_context() | |||
|
48 | ||||
|
49 | self._register_global_c(c) | |||
|
50 | PermissionModel().set_global_permission_choices( | |||
|
51 | c, gettext_translator=self.request.translate) | |||
|
52 | return c | |||
|
53 | ||||
|
54 | @LoginRequired() | |||
|
55 | @HasPermissionAllDecorator('hg.admin') | |||
|
56 | @view_config( | |||
|
57 | route_name='admin_permissions_application', request_method='GET', | |||
|
58 | renderer='rhodecode:templates/admin/permissions/permissions.mako') | |||
|
59 | def permissions_application(self): | |||
|
60 | c = self.load_default_context() | |||
|
61 | c.active = 'application' | |||
|
62 | ||||
|
63 | c.user = User.get_default_user(refresh=True) | |||
|
64 | ||||
|
65 | app_settings = SettingsModel().get_all_settings() | |||
|
66 | defaults = { | |||
|
67 | 'anonymous': c.user.active, | |||
|
68 | 'default_register_message': app_settings.get( | |||
|
69 | 'rhodecode_register_message') | |||
|
70 | } | |||
|
71 | defaults.update(c.user.get_default_perms()) | |||
|
72 | ||||
|
73 | data = render('rhodecode:templates/admin/permissions/permissions.mako', | |||
|
74 | self._get_template_context(c), self.request) | |||
|
75 | html = formencode.htmlfill.render( | |||
|
76 | data, | |||
|
77 | defaults=defaults, | |||
|
78 | encoding="UTF-8", | |||
|
79 | force_defaults=False | |||
|
80 | ) | |||
|
81 | return Response(html) | |||
|
82 | ||||
|
83 | @LoginRequired() | |||
|
84 | @HasPermissionAllDecorator('hg.admin') | |||
|
85 | @CSRFRequired() | |||
|
86 | @view_config( | |||
|
87 | route_name='admin_permissions_application_update', request_method='POST', | |||
|
88 | renderer='rhodecode:templates/admin/permissions/permissions.mako') | |||
|
89 | def permissions_application_update(self): | |||
|
90 | _ = self.request.translate | |||
|
91 | c = self.load_default_context() | |||
|
92 | c.active = 'application' | |||
|
93 | ||||
|
94 | _form = ApplicationPermissionsForm( | |||
|
95 | [x[0] for x in c.register_choices], | |||
|
96 | [x[0] for x in c.password_reset_choices], | |||
|
97 | [x[0] for x in c.extern_activate_choices])() | |||
|
98 | ||||
|
99 | try: | |||
|
100 | form_result = _form.to_python(dict(self.request.POST)) | |||
|
101 | form_result.update({'perm_user_name': User.DEFAULT_USER}) | |||
|
102 | PermissionModel().update_application_permissions(form_result) | |||
|
103 | ||||
|
104 | settings = [ | |||
|
105 | ('register_message', 'default_register_message'), | |||
|
106 | ] | |||
|
107 | for setting, form_key in settings: | |||
|
108 | sett = SettingsModel().create_or_update_setting( | |||
|
109 | setting, form_result[form_key]) | |||
|
110 | Session().add(sett) | |||
|
111 | ||||
|
112 | Session().commit() | |||
|
113 | h.flash(_('Application permissions updated successfully'), | |||
|
114 | category='success') | |||
|
115 | ||||
|
116 | except formencode.Invalid as errors: | |||
|
117 | defaults = errors.value | |||
|
118 | ||||
|
119 | data = render( | |||
|
120 | 'rhodecode:templates/admin/permissions/permissions.mako', | |||
|
121 | self._get_template_context(c), self.request) | |||
|
122 | html = formencode.htmlfill.render( | |||
|
123 | data, | |||
|
124 | defaults=defaults, | |||
|
125 | errors=errors.error_dict or {}, | |||
|
126 | prefix_error=False, | |||
|
127 | encoding="UTF-8", | |||
|
128 | force_defaults=False | |||
|
129 | ) | |||
|
130 | return Response(html) | |||
|
131 | ||||
|
132 | except Exception: | |||
|
133 | log.exception("Exception during update of permissions") | |||
|
134 | h.flash(_('Error occurred during update of permissions'), | |||
|
135 | category='error') | |||
|
136 | ||||
|
137 | raise HTTPFound(h.route_path('admin_permissions_application')) | |||
|
138 | ||||
|
139 | @LoginRequired() | |||
|
140 | @HasPermissionAllDecorator('hg.admin') | |||
|
141 | @view_config( | |||
|
142 | route_name='admin_permissions_object', request_method='GET', | |||
|
143 | renderer='rhodecode:templates/admin/permissions/permissions.mako') | |||
|
144 | def permissions_objects(self): | |||
|
145 | c = self.load_default_context() | |||
|
146 | c.active = 'objects' | |||
|
147 | ||||
|
148 | c.user = User.get_default_user(refresh=True) | |||
|
149 | defaults = {} | |||
|
150 | defaults.update(c.user.get_default_perms()) | |||
|
151 | ||||
|
152 | data = render( | |||
|
153 | 'rhodecode:templates/admin/permissions/permissions.mako', | |||
|
154 | self._get_template_context(c), self.request) | |||
|
155 | html = formencode.htmlfill.render( | |||
|
156 | data, | |||
|
157 | defaults=defaults, | |||
|
158 | encoding="UTF-8", | |||
|
159 | force_defaults=False | |||
|
160 | ) | |||
|
161 | return Response(html) | |||
|
162 | ||||
|
163 | @LoginRequired() | |||
|
164 | @HasPermissionAllDecorator('hg.admin') | |||
|
165 | @CSRFRequired() | |||
|
166 | @view_config( | |||
|
167 | route_name='admin_permissions_object_update', request_method='POST', | |||
|
168 | renderer='rhodecode:templates/admin/permissions/permissions.mako') | |||
|
169 | def permissions_objects_update(self): | |||
|
170 | _ = self.request.translate | |||
|
171 | c = self.load_default_context() | |||
|
172 | c.active = 'objects' | |||
|
173 | ||||
|
174 | _form = ObjectPermissionsForm( | |||
|
175 | [x[0] for x in c.repo_perms_choices], | |||
|
176 | [x[0] for x in c.group_perms_choices], | |||
|
177 | [x[0] for x in c.user_group_perms_choices])() | |||
|
178 | ||||
|
179 | try: | |||
|
180 | form_result = _form.to_python(dict(self.request.POST)) | |||
|
181 | form_result.update({'perm_user_name': User.DEFAULT_USER}) | |||
|
182 | PermissionModel().update_object_permissions(form_result) | |||
|
183 | ||||
|
184 | Session().commit() | |||
|
185 | h.flash(_('Object permissions updated successfully'), | |||
|
186 | category='success') | |||
|
187 | ||||
|
188 | except formencode.Invalid as errors: | |||
|
189 | defaults = errors.value | |||
|
190 | ||||
|
191 | data = render( | |||
|
192 | 'rhodecode:templates/admin/permissions/permissions.mako', | |||
|
193 | self._get_template_context(c), self.request) | |||
|
194 | html = formencode.htmlfill.render( | |||
|
195 | data, | |||
|
196 | defaults=defaults, | |||
|
197 | errors=errors.error_dict or {}, | |||
|
198 | prefix_error=False, | |||
|
199 | encoding="UTF-8", | |||
|
200 | force_defaults=False | |||
|
201 | ) | |||
|
202 | return Response(html) | |||
|
203 | except Exception: | |||
|
204 | log.exception("Exception during update of permissions") | |||
|
205 | h.flash(_('Error occurred during update of permissions'), | |||
|
206 | category='error') | |||
|
207 | ||||
|
208 | raise HTTPFound(h.route_path('admin_permissions_object')) | |||
|
209 | ||||
|
210 | @LoginRequired() | |||
|
211 | @HasPermissionAllDecorator('hg.admin') | |||
|
212 | @view_config( | |||
|
213 | route_name='admin_permissions_global', request_method='GET', | |||
|
214 | renderer='rhodecode:templates/admin/permissions/permissions.mako') | |||
|
215 | def permissions_global(self): | |||
|
216 | c = self.load_default_context() | |||
|
217 | c.active = 'global' | |||
|
218 | ||||
|
219 | c.user = User.get_default_user(refresh=True) | |||
|
220 | defaults = {} | |||
|
221 | defaults.update(c.user.get_default_perms()) | |||
|
222 | ||||
|
223 | data = render( | |||
|
224 | 'rhodecode:templates/admin/permissions/permissions.mako', | |||
|
225 | self._get_template_context(c), self.request) | |||
|
226 | html = formencode.htmlfill.render( | |||
|
227 | data, | |||
|
228 | defaults=defaults, | |||
|
229 | encoding="UTF-8", | |||
|
230 | force_defaults=False | |||
|
231 | ) | |||
|
232 | return Response(html) | |||
|
233 | ||||
|
234 | @LoginRequired() | |||
|
235 | @HasPermissionAllDecorator('hg.admin') | |||
|
236 | @CSRFRequired() | |||
|
237 | @view_config( | |||
|
238 | route_name='admin_permissions_global_update', request_method='POST', | |||
|
239 | renderer='rhodecode:templates/admin/permissions/permissions.mako') | |||
|
240 | def permissions_global_update(self): | |||
|
241 | _ = self.request.translate | |||
|
242 | c = self.load_default_context() | |||
|
243 | c.active = 'global' | |||
|
244 | ||||
|
245 | _form = UserPermissionsForm( | |||
|
246 | [x[0] for x in c.repo_create_choices], | |||
|
247 | [x[0] for x in c.repo_create_on_write_choices], | |||
|
248 | [x[0] for x in c.repo_group_create_choices], | |||
|
249 | [x[0] for x in c.user_group_create_choices], | |||
|
250 | [x[0] for x in c.fork_choices], | |||
|
251 | [x[0] for x in c.inherit_default_permission_choices])() | |||
|
252 | ||||
|
253 | try: | |||
|
254 | form_result = _form.to_python(dict(self.request.POST)) | |||
|
255 | form_result.update({'perm_user_name': User.DEFAULT_USER}) | |||
|
256 | PermissionModel().update_user_permissions(form_result) | |||
|
257 | ||||
|
258 | Session().commit() | |||
|
259 | h.flash(_('Global permissions updated successfully'), | |||
|
260 | category='success') | |||
|
261 | ||||
|
262 | except formencode.Invalid as errors: | |||
|
263 | defaults = errors.value | |||
|
264 | ||||
|
265 | data = render( | |||
|
266 | 'rhodecode:templates/admin/permissions/permissions.mako', | |||
|
267 | self._get_template_context(c), self.request) | |||
|
268 | html = formencode.htmlfill.render( | |||
|
269 | data, | |||
|
270 | defaults=defaults, | |||
|
271 | errors=errors.error_dict or {}, | |||
|
272 | prefix_error=False, | |||
|
273 | encoding="UTF-8", | |||
|
274 | force_defaults=False | |||
|
275 | ) | |||
|
276 | return Response(html) | |||
|
277 | except Exception: | |||
|
278 | log.exception("Exception during update of permissions") | |||
|
279 | h.flash(_('Error occurred during update of permissions'), | |||
|
280 | category='error') | |||
|
281 | ||||
|
282 | raise HTTPFound(h.route_path('admin_permissions_global')) | |||
|
283 | ||||
|
284 | @LoginRequired() | |||
|
285 | @HasPermissionAllDecorator('hg.admin') | |||
|
286 | @view_config( | |||
|
287 | route_name='admin_permissions_ips', request_method='GET', | |||
|
288 | renderer='rhodecode:templates/admin/permissions/permissions.mako') | |||
|
289 | def permissions_ips(self): | |||
|
290 | c = self.load_default_context() | |||
|
291 | c.active = 'ips' | |||
|
292 | ||||
|
293 | c.user = User.get_default_user(refresh=True) | |||
|
294 | c.user_ip_map = ( | |||
|
295 | UserIpMap.query().filter(UserIpMap.user == c.user).all()) | |||
|
296 | ||||
|
297 | return self._get_template_context(c) | |||
|
298 | ||||
|
299 | @LoginRequired() | |||
|
300 | @HasPermissionAllDecorator('hg.admin') | |||
|
301 | @view_config( | |||
|
302 | route_name='admin_permissions_overview', request_method='GET', | |||
|
303 | renderer='rhodecode:templates/admin/permissions/permissions.mako') | |||
|
304 | def permissions_overview(self): | |||
|
305 | c = self.load_default_context() | |||
|
306 | c.active = 'perms' | |||
|
307 | ||||
|
308 | c.user = User.get_default_user(refresh=True) | |||
|
309 | c.perm_user = c.user.AuthUser | |||
|
310 | return self._get_template_context(c) |
@@ -72,10 +72,36 b' def admin_routes(config):' | |||||
72 | pattern='/settings/process_management/signal') |
|
72 | pattern='/settings/process_management/signal') | |
73 |
|
73 | |||
74 | # global permissions |
|
74 | # global permissions | |
|
75 | ||||
|
76 | config.add_route( | |||
|
77 | name='admin_permissions_application', | |||
|
78 | pattern='/permissions/application') | |||
|
79 | config.add_route( | |||
|
80 | name='admin_permissions_application_update', | |||
|
81 | pattern='/permissions/application/update') | |||
|
82 | ||||
|
83 | config.add_route( | |||
|
84 | name='admin_permissions_global', | |||
|
85 | pattern='/permissions/global') | |||
|
86 | config.add_route( | |||
|
87 | name='admin_permissions_global_update', | |||
|
88 | pattern='/permissions/global/update') | |||
|
89 | ||||
|
90 | config.add_route( | |||
|
91 | name='admin_permissions_object', | |||
|
92 | pattern='/permissions/object') | |||
|
93 | config.add_route( | |||
|
94 | name='admin_permissions_object_update', | |||
|
95 | pattern='/permissions/object/update') | |||
|
96 | ||||
75 | config.add_route( |
|
97 | config.add_route( | |
76 | name='admin_permissions_ips', |
|
98 | name='admin_permissions_ips', | |
77 | pattern='/permissions/ips') |
|
99 | pattern='/permissions/ips') | |
78 |
|
100 | |||
|
101 | config.add_route( | |||
|
102 | name='admin_permissions_overview', | |||
|
103 | pattern='/permissions/overview') | |||
|
104 | ||||
79 | # users admin |
|
105 | # users admin | |
80 | config.add_route( |
|
106 | config.add_route( | |
81 | name='users', |
|
107 | name='users', |
@@ -22,7 +22,7 b' import pytest' | |||||
22 | from rhodecode.model.db import User, UserIpMap |
|
22 | from rhodecode.model.db import User, UserIpMap | |
23 | from rhodecode.model.permission import PermissionModel |
|
23 | from rhodecode.model.permission import PermissionModel | |
24 | from rhodecode.tests import ( |
|
24 | from rhodecode.tests import ( | |
25 |
TestController |
|
25 | TestController, clear_all_caches, assert_session_flash) | |
26 |
|
26 | |||
27 |
|
27 | |||
28 | def route_path(name, params=None, **kwargs): |
|
28 | def route_path(name, params=None, **kwargs): | |
@@ -36,6 +36,27 b' def route_path(name, params=None, **kwar' | |||||
36 | ADMIN_PREFIX + '/users/{user_id}/edit/ips/new', |
|
36 | ADMIN_PREFIX + '/users/{user_id}/edit/ips/new', | |
37 | 'edit_user_ips_delete': |
|
37 | 'edit_user_ips_delete': | |
38 | ADMIN_PREFIX + '/users/{user_id}/edit/ips/delete', |
|
38 | ADMIN_PREFIX + '/users/{user_id}/edit/ips/delete', | |
|
39 | ||||
|
40 | 'admin_permissions_application': | |||
|
41 | ADMIN_PREFIX + '/permissions/application', | |||
|
42 | 'admin_permissions_application_update': | |||
|
43 | ADMIN_PREFIX + '/permissions/application/update', | |||
|
44 | ||||
|
45 | 'admin_permissions_global': | |||
|
46 | ADMIN_PREFIX + '/permissions/global', | |||
|
47 | 'admin_permissions_global_update': | |||
|
48 | ADMIN_PREFIX + '/permissions/global/update', | |||
|
49 | ||||
|
50 | 'admin_permissions_object': | |||
|
51 | ADMIN_PREFIX + '/permissions/object', | |||
|
52 | 'admin_permissions_object_update': | |||
|
53 | ADMIN_PREFIX + '/permissions/object/update', | |||
|
54 | ||||
|
55 | 'admin_permissions_ips': | |||
|
56 | ADMIN_PREFIX + '/permissions/ips', | |||
|
57 | 'admin_permissions_overview': | |||
|
58 | ADMIN_PREFIX + '/permissions/overview' | |||
|
59 | ||||
39 | }[name].format(**kwargs) |
|
60 | }[name].format(**kwargs) | |
40 |
|
61 | |||
41 | if params: |
|
62 | if params: | |
@@ -55,7 +76,7 b' class TestAdminPermissionsController(Tes' | |||||
55 |
|
76 | |||
56 | def test_index_application(self): |
|
77 | def test_index_application(self): | |
57 | self.log_user() |
|
78 | self.log_user() | |
58 |
self.app.get( |
|
79 | self.app.get(route_path('admin_permissions_application')) | |
59 |
|
80 | |||
60 | @pytest.mark.parametrize( |
|
81 | @pytest.mark.parametrize( | |
61 | 'anonymous, default_register, default_register_message, default_password_reset,' |
|
82 | 'anonymous, default_register, default_register_message, default_password_reset,' | |
@@ -87,7 +108,7 b' class TestAdminPermissionsController(Tes' | |||||
87 | 'default_password_reset': default_password_reset, |
|
108 | 'default_password_reset': default_password_reset, | |
88 | 'default_extern_activate': default_extern_activate, |
|
109 | 'default_extern_activate': default_extern_activate, | |
89 | } |
|
110 | } | |
90 |
response = self.app.post( |
|
111 | response = self.app.post(route_path('admin_permissions_application_update'), | |
91 | params=params) |
|
112 | params=params) | |
92 | if expect_form_error: |
|
113 | if expect_form_error: | |
93 | assert response.status_int == 200 |
|
114 | assert response.status_int == 200 | |
@@ -101,7 +122,7 b' class TestAdminPermissionsController(Tes' | |||||
101 |
|
122 | |||
102 | def test_index_object(self): |
|
123 | def test_index_object(self): | |
103 | self.log_user() |
|
124 | self.log_user() | |
104 |
self.app.get( |
|
125 | self.app.get(route_path('admin_permissions_object')) | |
105 |
|
126 | |||
106 | @pytest.mark.parametrize( |
|
127 | @pytest.mark.parametrize( | |
107 | 'repo, repo_group, user_group, expect_error, expect_form_error', [ |
|
128 | 'repo, repo_group, user_group, expect_error, expect_form_error', [ | |
@@ -127,7 +148,7 b' class TestAdminPermissionsController(Tes' | |||||
127 | 'default_user_group_perm': user_group, |
|
148 | 'default_user_group_perm': user_group, | |
128 | 'overwrite_default_user_group': False, |
|
149 | 'overwrite_default_user_group': False, | |
129 | } |
|
150 | } | |
130 |
response = self.app.post( |
|
151 | response = self.app.post(route_path('admin_permissions_object_update'), | |
131 | params=params) |
|
152 | params=params) | |
132 | if expect_form_error: |
|
153 | if expect_form_error: | |
133 | assert response.status_int == 200 |
|
154 | assert response.status_int == 200 | |
@@ -141,7 +162,7 b' class TestAdminPermissionsController(Tes' | |||||
141 |
|
162 | |||
142 | def test_index_global(self): |
|
163 | def test_index_global(self): | |
143 | self.log_user() |
|
164 | self.log_user() | |
144 |
self.app.get( |
|
165 | self.app.get(route_path('admin_permissions_global')) | |
145 |
|
166 | |||
146 | @pytest.mark.parametrize( |
|
167 | @pytest.mark.parametrize( | |
147 | 'repo_create, repo_create_write, user_group_create, repo_group_create,' |
|
168 | 'repo_create, repo_create_write, user_group_create, repo_group_create,' | |
@@ -175,7 +196,7 b' class TestAdminPermissionsController(Tes' | |||||
175 | 'default_fork_create': fork_create, |
|
196 | 'default_fork_create': fork_create, | |
176 | 'default_inherit_default_permissions': inherit_default_permissions |
|
197 | 'default_inherit_default_permissions': inherit_default_permissions | |
177 | } |
|
198 | } | |
178 |
response = self.app.post( |
|
199 | response = self.app.post(route_path('admin_permissions_global_update'), | |
179 | params=params) |
|
200 | params=params) | |
180 | if expect_form_error: |
|
201 | if expect_form_error: | |
181 | assert response.status_int == 200 |
|
202 | assert response.status_int == 200 | |
@@ -189,7 +210,7 b' class TestAdminPermissionsController(Tes' | |||||
189 |
|
210 | |||
190 | def test_index_ips(self): |
|
211 | def test_index_ips(self): | |
191 | self.log_user() |
|
212 | self.log_user() | |
192 |
response = self.app.get( |
|
213 | response = self.app.get(route_path('admin_permissions_ips')) | |
193 | # TODO: Test response... |
|
214 | # TODO: Test response... | |
194 | response.mustcontain('All IP addresses are allowed') |
|
215 | response.mustcontain('All IP addresses are allowed') | |
195 |
|
216 | |||
@@ -203,7 +224,7 b' class TestAdminPermissionsController(Tes' | |||||
203 | route_path('edit_user_ips_add', user_id=default_user_id), |
|
224 | route_path('edit_user_ips_add', user_id=default_user_id), | |
204 | params={'new_ip': '127.0.0.0/24', 'csrf_token': self.csrf_token}) |
|
225 | params={'new_ip': '127.0.0.0/24', 'csrf_token': self.csrf_token}) | |
205 |
|
226 | |||
206 |
response = self.app.get( |
|
227 | response = self.app.get(route_path('admin_permissions_ips')) | |
207 | response.mustcontain('127.0.0.0/24') |
|
228 | response.mustcontain('127.0.0.0/24') | |
208 | response.mustcontain('127.0.0.0 - 127.0.0.255') |
|
229 | response.mustcontain('127.0.0.0 - 127.0.0.255') | |
209 |
|
230 | |||
@@ -219,11 +240,11 b' class TestAdminPermissionsController(Tes' | |||||
219 | assert_session_flash(response, 'Removed ip address from user whitelist') |
|
240 | assert_session_flash(response, 'Removed ip address from user whitelist') | |
220 |
|
241 | |||
221 | clear_all_caches() |
|
242 | clear_all_caches() | |
222 |
response = self.app.get( |
|
243 | response = self.app.get(route_path('admin_permissions_ips')) | |
223 | response.mustcontain('All IP addresses are allowed') |
|
244 | response.mustcontain('All IP addresses are allowed') | |
224 | response.mustcontain(no=['127.0.0.0/24']) |
|
245 | response.mustcontain(no=['127.0.0.0/24']) | |
225 | response.mustcontain(no=['127.0.0.0 - 127.0.0.255']) |
|
246 | response.mustcontain(no=['127.0.0.0 - 127.0.0.255']) | |
226 |
|
247 | |||
227 | def test_index_overview(self): |
|
248 | def test_index_overview(self): | |
228 | self.log_user() |
|
249 | self.log_user() | |
229 |
self.app.get( |
|
250 | self.app.get(route_path('admin_permissions_overview')) |
@@ -23,9 +23,8 b' import urlparse' | |||||
23 | import mock |
|
23 | import mock | |
24 | import pytest |
|
24 | import pytest | |
25 |
|
25 | |||
26 | from rhodecode.config.routing import ADMIN_PREFIX |
|
|||
27 | from rhodecode.tests import ( |
|
26 | from rhodecode.tests import ( | |
28 |
assert_session_flash |
|
27 | assert_session_flash, HG_REPO, TEST_USER_ADMIN_LOGIN, | |
29 | no_newline_id_generator) |
|
28 | no_newline_id_generator) | |
30 | from rhodecode.tests.fixture import Fixture |
|
29 | from rhodecode.tests.fixture import Fixture | |
31 | from rhodecode.lib.auth import check_password |
|
30 | from rhodecode.lib.auth import check_password | |
@@ -37,14 +36,32 b' from rhodecode.model.meta import Session' | |||||
37 |
|
36 | |||
38 | fixture = Fixture() |
|
37 | fixture = Fixture() | |
39 |
|
38 | |||
40 | # Hardcode URLs because we don't have a request object to use |
|
39 | ||
41 | # pyramids URL generation methods. |
|
40 | def route_path(name, params=None, **kwargs): | |
42 | index_url = '/' |
|
41 | import urllib | |
43 | login_url = ADMIN_PREFIX + '/login' |
|
42 | from rhodecode.apps._base import ADMIN_PREFIX | |
44 | logut_url = ADMIN_PREFIX + '/logout' |
|
43 | ||
45 | register_url = ADMIN_PREFIX + '/register' |
|
44 | base_url = { | |
46 | pwd_reset_url = ADMIN_PREFIX + '/password_reset' |
|
45 | 'login': ADMIN_PREFIX + '/login', | |
47 | pwd_reset_confirm_url = ADMIN_PREFIX + '/password_reset_confirmation' |
|
46 | 'logout': ADMIN_PREFIX + '/logout', | |
|
47 | 'register': ADMIN_PREFIX + '/register', | |||
|
48 | 'reset_password': | |||
|
49 | ADMIN_PREFIX + '/password_reset', | |||
|
50 | 'reset_password_confirmation': | |||
|
51 | ADMIN_PREFIX + '/password_reset_confirmation', | |||
|
52 | ||||
|
53 | 'admin_permissions_application': | |||
|
54 | ADMIN_PREFIX + '/permissions/application', | |||
|
55 | 'admin_permissions_application_update': | |||
|
56 | ADMIN_PREFIX + '/permissions/application/update', | |||
|
57 | ||||
|
58 | 'repo_commit_raw': '/{repo_name}/raw-changeset/{commit_id}' | |||
|
59 | ||||
|
60 | }[name].format(**kwargs) | |||
|
61 | ||||
|
62 | if params: | |||
|
63 | base_url = '{}?{}'.format(base_url, urllib.urlencode(params)) | |||
|
64 | return base_url | |||
48 |
|
65 | |||
49 |
|
66 | |||
50 | @pytest.mark.usefixtures('app') |
|
67 | @pytest.mark.usefixtures('app') | |
@@ -63,12 +80,12 b' class TestLoginController(object):' | |||||
63 | assert Notification.query().all() == [] |
|
80 | assert Notification.query().all() == [] | |
64 |
|
81 | |||
65 | def test_index(self): |
|
82 | def test_index(self): | |
66 |
response = self.app.get( |
|
83 | response = self.app.get(route_path('login')) | |
67 | assert response.status == '200 OK' |
|
84 | assert response.status == '200 OK' | |
68 | # Test response... |
|
85 | # Test response... | |
69 |
|
86 | |||
70 | def test_login_admin_ok(self): |
|
87 | def test_login_admin_ok(self): | |
71 |
response = self.app.post( |
|
88 | response = self.app.post(route_path('login'), | |
72 | {'username': 'test_admin', |
|
89 | {'username': 'test_admin', | |
73 | 'password': 'test12'}) |
|
90 | 'password': 'test12'}) | |
74 | assert response.status == '302 Found' |
|
91 | assert response.status == '302 Found' | |
@@ -79,7 +96,7 b' class TestLoginController(object):' | |||||
79 | response.mustcontain('/%s' % HG_REPO) |
|
96 | response.mustcontain('/%s' % HG_REPO) | |
80 |
|
97 | |||
81 | def test_login_regular_ok(self): |
|
98 | def test_login_regular_ok(self): | |
82 |
response = self.app.post( |
|
99 | response = self.app.post(route_path('login'), | |
83 | {'username': 'test_regular', |
|
100 | {'username': 'test_regular', | |
84 | 'password': 'test12'}) |
|
101 | 'password': 'test12'}) | |
85 |
|
102 | |||
@@ -92,7 +109,7 b' class TestLoginController(object):' | |||||
92 |
|
109 | |||
93 | def test_login_ok_came_from(self): |
|
110 | def test_login_ok_came_from(self): | |
94 | test_came_from = '/_admin/users?branch=stable' |
|
111 | test_came_from = '/_admin/users?branch=stable' | |
95 |
_url = '{}?came_from={}'.format( |
|
112 | _url = '{}?came_from={}'.format(route_path('login'), test_came_from) | |
96 | response = self.app.post( |
|
113 | response = self.app.post( | |
97 | _url, {'username': 'test_admin', 'password': 'test12'}) |
|
114 | _url, {'username': 'test_admin', 'password': 'test12'}) | |
98 | assert response.status == '302 Found' |
|
115 | assert response.status == '302 Found' | |
@@ -113,7 +130,7 b' class TestLoginController(object):' | |||||
113 | assert 'branch=stable' in response_query[0][1] |
|
130 | assert 'branch=stable' in response_query[0][1] | |
114 |
|
131 | |||
115 | def test_login_form_with_get_args(self): |
|
132 | def test_login_form_with_get_args(self): | |
116 |
_url = '{}?came_from=/_admin/users,branch=stable'.format( |
|
133 | _url = '{}?came_from=/_admin/users,branch=stable'.format(route_path('login')) | |
117 | response = self.app.get(_url) |
|
134 | response = self.app.get(_url) | |
118 | assert 'branch%3Dstable' in response.form.action |
|
135 | assert 'branch%3Dstable' in response.form.action | |
119 |
|
136 | |||
@@ -126,7 +143,7 b' class TestLoginController(object):' | |||||
126 | '/\r\nX-Forwarded-Host: http://example.org', |
|
143 | '/\r\nX-Forwarded-Host: http://example.org', | |
127 | ], ids=no_newline_id_generator) |
|
144 | ], ids=no_newline_id_generator) | |
128 | def test_login_bad_came_froms(self, url_came_from): |
|
145 | def test_login_bad_came_froms(self, url_came_from): | |
129 |
_url = '{}?came_from={}'.format( |
|
146 | _url = '{}?came_from={}'.format(route_path('login'), url_came_from) | |
130 | response = self.app.post( |
|
147 | response = self.app.post( | |
131 | _url, |
|
148 | _url, | |
132 | {'username': 'test_admin', 'password': 'test12'}) |
|
149 | {'username': 'test_admin', 'password': 'test12'}) | |
@@ -136,7 +153,7 b' class TestLoginController(object):' | |||||
136 | assert response.request.path == '/' |
|
153 | assert response.request.path == '/' | |
137 |
|
154 | |||
138 | def test_login_short_password(self): |
|
155 | def test_login_short_password(self): | |
139 |
response = self.app.post( |
|
156 | response = self.app.post(route_path('login'), | |
140 | {'username': 'test_admin', |
|
157 | {'username': 'test_admin', | |
141 | 'password': 'as'}) |
|
158 | 'password': 'as'}) | |
142 | assert response.status == '200 OK' |
|
159 | assert response.status == '200 OK' | |
@@ -145,7 +162,7 b' class TestLoginController(object):' | |||||
145 |
|
162 | |||
146 | def test_login_wrong_non_ascii_password(self, user_regular): |
|
163 | def test_login_wrong_non_ascii_password(self, user_regular): | |
147 | response = self.app.post( |
|
164 | response = self.app.post( | |
148 |
|
|
165 | route_path('login'), | |
149 | {'username': user_regular.username, |
|
166 | {'username': user_regular.username, | |
150 | 'password': u'invalid-non-asci\xe4'.encode('utf8')}) |
|
167 | 'password': u'invalid-non-asci\xe4'.encode('utf8')}) | |
151 |
|
168 | |||
@@ -156,13 +173,13 b' class TestLoginController(object):' | |||||
156 | password = u'valid-non-ascii\xe4' |
|
173 | password = u'valid-non-ascii\xe4' | |
157 | user = user_util.create_user(password=password) |
|
174 | user = user_util.create_user(password=password) | |
158 | response = self.app.post( |
|
175 | response = self.app.post( | |
159 |
|
|
176 | route_path('login'), | |
160 | {'username': user.username, |
|
177 | {'username': user.username, | |
161 | 'password': password.encode('utf-8')}) |
|
178 | 'password': password.encode('utf-8')}) | |
162 | assert response.status_code == 302 |
|
179 | assert response.status_code == 302 | |
163 |
|
180 | |||
164 | def test_login_wrong_username_password(self): |
|
181 | def test_login_wrong_username_password(self): | |
165 |
response = self.app.post( |
|
182 | response = self.app.post(route_path('login'), | |
166 | {'username': 'error', |
|
183 | {'username': 'error', | |
167 | 'password': 'test12'}) |
|
184 | 'password': 'test12'}) | |
168 |
|
185 | |||
@@ -180,7 +197,7 b' class TestLoginController(object):' | |||||
180 | Session().add(user) |
|
197 | Session().add(user) | |
181 | Session().commit() |
|
198 | Session().commit() | |
182 | self.destroy_users.add(temp_user) |
|
199 | self.destroy_users.add(temp_user) | |
183 |
response = self.app.post( |
|
200 | response = self.app.post(route_path('login'), | |
184 | {'username': temp_user, |
|
201 | {'username': temp_user, | |
185 | 'password': 'test123'}) |
|
202 | 'password': 'test123'}) | |
186 |
|
203 | |||
@@ -197,13 +214,13 b' class TestLoginController(object):' | |||||
197 |
|
214 | |||
198 | # REGISTRATIONS |
|
215 | # REGISTRATIONS | |
199 | def test_register(self): |
|
216 | def test_register(self): | |
200 |
response = self.app.get(register |
|
217 | response = self.app.get(route_path('register')) | |
201 | response.mustcontain('Create an Account') |
|
218 | response.mustcontain('Create an Account') | |
202 |
|
219 | |||
203 | def test_register_err_same_username(self): |
|
220 | def test_register_err_same_username(self): | |
204 | uname = 'test_admin' |
|
221 | uname = 'test_admin' | |
205 | response = self.app.post( |
|
222 | response = self.app.post( | |
206 |
register |
|
223 | route_path('register'), | |
207 | { |
|
224 | { | |
208 | 'username': uname, |
|
225 | 'username': uname, | |
209 | 'password': 'test12', |
|
226 | 'password': 'test12', | |
@@ -221,7 +238,7 b' class TestLoginController(object):' | |||||
221 |
|
238 | |||
222 | def test_register_err_same_email(self): |
|
239 | def test_register_err_same_email(self): | |
223 | response = self.app.post( |
|
240 | response = self.app.post( | |
224 |
register |
|
241 | route_path('register'), | |
225 | { |
|
242 | { | |
226 | 'username': 'test_admin_0', |
|
243 | 'username': 'test_admin_0', | |
227 | 'password': 'test12', |
|
244 | 'password': 'test12', | |
@@ -238,7 +255,7 b' class TestLoginController(object):' | |||||
238 |
|
255 | |||
239 | def test_register_err_same_email_case_sensitive(self): |
|
256 | def test_register_err_same_email_case_sensitive(self): | |
240 | response = self.app.post( |
|
257 | response = self.app.post( | |
241 |
register |
|
258 | route_path('register'), | |
242 | { |
|
259 | { | |
243 | 'username': 'test_admin_1', |
|
260 | 'username': 'test_admin_1', | |
244 | 'password': 'test12', |
|
261 | 'password': 'test12', | |
@@ -254,7 +271,7 b' class TestLoginController(object):' | |||||
254 |
|
271 | |||
255 | def test_register_err_wrong_data(self): |
|
272 | def test_register_err_wrong_data(self): | |
256 | response = self.app.post( |
|
273 | response = self.app.post( | |
257 |
register |
|
274 | route_path('register'), | |
258 | { |
|
275 | { | |
259 | 'username': 'xs', |
|
276 | 'username': 'xs', | |
260 | 'password': 'test', |
|
277 | 'password': 'test', | |
@@ -270,7 +287,7 b' class TestLoginController(object):' | |||||
270 |
|
287 | |||
271 | def test_register_err_username(self): |
|
288 | def test_register_err_username(self): | |
272 | response = self.app.post( |
|
289 | response = self.app.post( | |
273 |
register |
|
290 | route_path('register'), | |
274 | { |
|
291 | { | |
275 | 'username': 'error user', |
|
292 | 'username': 'error user', | |
276 | 'password': 'test12', |
|
293 | 'password': 'test12', | |
@@ -291,7 +308,7 b' class TestLoginController(object):' | |||||
291 | def test_register_err_case_sensitive(self): |
|
308 | def test_register_err_case_sensitive(self): | |
292 | usr = 'Test_Admin' |
|
309 | usr = 'Test_Admin' | |
293 | response = self.app.post( |
|
310 | response = self.app.post( | |
294 |
register |
|
311 | route_path('register'), | |
295 | { |
|
312 | { | |
296 | 'username': usr, |
|
313 | 'username': usr, | |
297 | 'password': 'test12', |
|
314 | 'password': 'test12', | |
@@ -309,7 +326,7 b' class TestLoginController(object):' | |||||
309 |
|
326 | |||
310 | def test_register_special_chars(self): |
|
327 | def test_register_special_chars(self): | |
311 | response = self.app.post( |
|
328 | response = self.app.post( | |
312 |
register |
|
329 | route_path('register'), | |
313 | { |
|
330 | { | |
314 | 'username': 'xxxaxn', |
|
331 | 'username': 'xxxaxn', | |
315 | 'password': 'ąćźżąśśśś', |
|
332 | 'password': 'ąćźżąśśśś', | |
@@ -325,7 +342,7 b' class TestLoginController(object):' | |||||
325 |
|
342 | |||
326 | def test_register_password_mismatch(self): |
|
343 | def test_register_password_mismatch(self): | |
327 | response = self.app.post( |
|
344 | response = self.app.post( | |
328 |
register |
|
345 | route_path('register'), | |
329 | { |
|
346 | { | |
330 | 'username': 'xs', |
|
347 | 'username': 'xs', | |
331 | 'password': '123qwe', |
|
348 | 'password': '123qwe', | |
@@ -346,7 +363,7 b' class TestLoginController(object):' | |||||
346 | lastname = 'testlastname' |
|
363 | lastname = 'testlastname' | |
347 |
|
364 | |||
348 | response = self.app.post( |
|
365 | response = self.app.post( | |
349 |
register |
|
366 | route_path('register'), | |
350 | { |
|
367 | { | |
351 | 'username': username, |
|
368 | 'username': username, | |
352 | 'password': password, |
|
369 | 'password': password, | |
@@ -374,29 +391,29 b' class TestLoginController(object):' | |||||
374 | def test_forgot_password_wrong_mail(self): |
|
391 | def test_forgot_password_wrong_mail(self): | |
375 | bad_email = 'marcin@wrongmail.org' |
|
392 | bad_email = 'marcin@wrongmail.org' | |
376 | response = self.app.post( |
|
393 | response = self.app.post( | |
377 |
|
|
394 | route_path('reset_password'), {'email': bad_email, } | |
378 | ) |
|
395 | ) | |
379 | assert_session_flash(response, |
|
396 | assert_session_flash(response, | |
380 | 'If such email exists, a password reset link was sent to it.') |
|
397 | 'If such email exists, a password reset link was sent to it.') | |
381 |
|
398 | |||
382 | def test_forgot_password(self, user_util): |
|
399 | def test_forgot_password(self, user_util): | |
383 |
response = self.app.get( |
|
400 | response = self.app.get(route_path('reset_password')) | |
384 | assert response.status == '200 OK' |
|
401 | assert response.status == '200 OK' | |
385 |
|
402 | |||
386 | user = user_util.create_user() |
|
403 | user = user_util.create_user() | |
387 | user_id = user.user_id |
|
404 | user_id = user.user_id | |
388 | email = user.email |
|
405 | email = user.email | |
389 |
|
406 | |||
390 |
response = self.app.post( |
|
407 | response = self.app.post(route_path('reset_password'), {'email': email, }) | |
391 |
|
408 | |||
392 | assert_session_flash(response, |
|
409 | assert_session_flash(response, | |
393 | 'If such email exists, a password reset link was sent to it.') |
|
410 | 'If such email exists, a password reset link was sent to it.') | |
394 |
|
411 | |||
395 | # BAD KEY |
|
412 | # BAD KEY | |
396 |
confirm_url = '{}?key={}'.format( |
|
413 | confirm_url = '{}?key={}'.format(route_path('reset_password_confirmation'), 'badkey') | |
397 | response = self.app.get(confirm_url) |
|
414 | response = self.app.get(confirm_url) | |
398 | assert response.status == '302 Found' |
|
415 | assert response.status == '302 Found' | |
399 |
assert response.location.endswith( |
|
416 | assert response.location.endswith(route_path('reset_password')) | |
400 | assert_session_flash(response, 'Given reset token is invalid') |
|
417 | assert_session_flash(response, 'Given reset token is invalid') | |
401 |
|
418 | |||
402 | response.follow() # cleanup flash |
|
419 | response.follow() # cleanup flash | |
@@ -409,10 +426,10 b' class TestLoginController(object):' | |||||
409 |
|
426 | |||
410 | assert key |
|
427 | assert key | |
411 |
|
428 | |||
412 |
confirm_url = '{}?key={}'.format( |
|
429 | confirm_url = '{}?key={}'.format(route_path('reset_password_confirmation'), key.api_key) | |
413 | response = self.app.get(confirm_url) |
|
430 | response = self.app.get(confirm_url) | |
414 | assert response.status == '302 Found' |
|
431 | assert response.status == '302 Found' | |
415 |
assert response.location.endswith( |
|
432 | assert response.location.endswith(route_path('login')) | |
416 |
|
433 | |||
417 | assert_session_flash( |
|
434 | assert_session_flash( | |
418 | response, |
|
435 | response, | |
@@ -442,11 +459,11 b' class TestLoginController(object):' | |||||
442 | auth_token = user_admin.api_key |
|
459 | auth_token = user_admin.api_key | |
443 |
|
460 | |||
444 | with fixture.anon_access(False): |
|
461 | with fixture.anon_access(False): | |
445 |
self.app.get( |
|
462 | self.app.get( | |
446 | action='changeset_raw', |
|
463 | route_path('repo_commit_raw', | |
447 |
|
|
464 | repo_name=HG_REPO, commit_id='tip', | |
448 |
|
|
465 | params=dict(api_key=auth_token)), | |
449 |
|
|
466 | status=302) | |
450 |
|
467 | |||
451 | @pytest.mark.parametrize("test_name, auth_token, code", [ |
|
468 | @pytest.mark.parametrize("test_name, auth_token, code", [ | |
452 | ('none', None, 302), |
|
469 | ('none', None, 302), | |
@@ -468,11 +485,11 b' class TestLoginController(object):' | |||||
468 | assert auth_token |
|
485 | assert auth_token | |
469 |
|
486 | |||
470 | with fixture.anon_access(False): |
|
487 | with fixture.anon_access(False): | |
471 |
self.app.get( |
|
488 | self.app.get( | |
472 | action='changeset_raw', |
|
489 | route_path('repo_commit_raw', | |
473 |
|
|
490 | repo_name=HG_REPO, commit_id='tip', | |
474 |
|
|
491 | params=dict(api_key=auth_token)), | |
475 |
|
|
492 | status=code) | |
476 |
|
493 | |||
477 | def test_access_page_via_extra_auth_token(self): |
|
494 | def test_access_page_via_extra_auth_token(self): | |
478 | whitelist = self._get_api_whitelist( |
|
495 | whitelist = self._get_api_whitelist( | |
@@ -485,11 +502,11 b' class TestLoginController(object):' | |||||
485 | TEST_USER_ADMIN_LOGIN, 'test') |
|
502 | TEST_USER_ADMIN_LOGIN, 'test') | |
486 | Session().commit() |
|
503 | Session().commit() | |
487 | with fixture.anon_access(False): |
|
504 | with fixture.anon_access(False): | |
488 |
self.app.get( |
|
505 | self.app.get( | |
489 | action='changeset_raw', |
|
506 | route_path('repo_commit_raw', | |
490 |
|
|
507 | repo_name=HG_REPO, commit_id='tip', | |
491 |
|
|
508 | params=dict(api_key=new_auth_token.api_key)), | |
492 |
|
|
509 | status=200) | |
493 |
|
510 | |||
494 | def test_access_page_via_expired_auth_token(self): |
|
511 | def test_access_page_via_expired_auth_token(self): | |
495 | whitelist = self._get_api_whitelist( |
|
512 | whitelist = self._get_api_whitelist( | |
@@ -506,8 +523,8 b' class TestLoginController(object):' | |||||
506 | Session().add(new_auth_token) |
|
523 | Session().add(new_auth_token) | |
507 | Session().commit() |
|
524 | Session().commit() | |
508 | with fixture.anon_access(False): |
|
525 | with fixture.anon_access(False): | |
509 |
self.app.get( |
|
526 | self.app.get( | |
510 | action='changeset_raw', |
|
527 | route_path('repo_commit_raw', | |
511 |
|
|
528 | repo_name=HG_REPO, commit_id='tip', | |
512 |
|
|
529 | params=dict(api_key=new_auth_token.api_key)), | |
513 |
|
|
530 | status=302) |
@@ -20,23 +20,38 b'' | |||||
20 |
|
20 | |||
21 | import pytest |
|
21 | import pytest | |
22 |
|
22 | |||
23 | from rhodecode.config.routing import ADMIN_PREFIX |
|
23 | from rhodecode.lib import helpers as h | |
24 | from rhodecode.tests import ( |
|
24 | from rhodecode.tests import ( | |
25 |
TestController, clear_all_caches, |
|
25 | TestController, clear_all_caches, | |
26 | TEST_USER_ADMIN_LOGIN, TEST_USER_ADMIN_PASS) |
|
26 | TEST_USER_ADMIN_LOGIN, TEST_USER_ADMIN_PASS) | |
27 | from rhodecode.tests.fixture import Fixture |
|
27 | from rhodecode.tests.fixture import Fixture | |
28 | from rhodecode.tests.utils import AssertResponse |
|
28 | from rhodecode.tests.utils import AssertResponse | |
29 |
|
29 | |||
30 | fixture = Fixture() |
|
30 | fixture = Fixture() | |
31 |
|
31 | |||
32 | # Hardcode URLs because we don't have a request object to use |
|
32 | ||
33 | # pyramids URL generation methods. |
|
33 | def route_path(name, params=None, **kwargs): | |
34 | index_url = '/' |
|
34 | import urllib | |
35 | login_url = ADMIN_PREFIX + '/login' |
|
35 | from rhodecode.apps._base import ADMIN_PREFIX | |
36 | logut_url = ADMIN_PREFIX + '/logout' |
|
36 | ||
37 | register_url = ADMIN_PREFIX + '/register' |
|
37 | base_url = { | |
38 | pwd_reset_url = ADMIN_PREFIX + '/password_reset' |
|
38 | 'login': ADMIN_PREFIX + '/login', | |
39 | pwd_reset_confirm_url = ADMIN_PREFIX + '/password_reset_confirmation' |
|
39 | 'logout': ADMIN_PREFIX + '/logout', | |
|
40 | 'register': ADMIN_PREFIX + '/register', | |||
|
41 | 'reset_password': | |||
|
42 | ADMIN_PREFIX + '/password_reset', | |||
|
43 | 'reset_password_confirmation': | |||
|
44 | ADMIN_PREFIX + '/password_reset_confirmation', | |||
|
45 | ||||
|
46 | 'admin_permissions_application': | |||
|
47 | ADMIN_PREFIX + '/permissions/application', | |||
|
48 | 'admin_permissions_application_update': | |||
|
49 | ADMIN_PREFIX + '/permissions/application/update', | |||
|
50 | }[name].format(**kwargs) | |||
|
51 | ||||
|
52 | if params: | |||
|
53 | base_url = '{}?{}'.format(base_url, urllib.urlencode(params)) | |||
|
54 | return base_url | |||
40 |
|
55 | |||
41 |
|
56 | |||
42 | class TestPasswordReset(TestController): |
|
57 | class TestPasswordReset(TestController): | |
@@ -59,12 +74,12 b' class TestPasswordReset(TestController):' | |||||
59 | 'default_password_reset': pwd_reset_setting, |
|
74 | 'default_password_reset': pwd_reset_setting, | |
60 | 'default_extern_activate': 'hg.extern_activate.auto', |
|
75 | 'default_extern_activate': 'hg.extern_activate.auto', | |
61 | } |
|
76 | } | |
62 |
resp = self.app.post( |
|
77 | resp = self.app.post(route_path('admin_permissions_application_update'), params=params) | |
63 | self.logout_user() |
|
78 | self.logout_user() | |
64 |
|
79 | |||
65 |
login_page = self.app.get( |
|
80 | login_page = self.app.get(route_path('login')) | |
66 | asr_login = AssertResponse(login_page) |
|
81 | asr_login = AssertResponse(login_page) | |
67 |
index_page = self.app.get( |
|
82 | index_page = self.app.get(h.route_path('home')) | |
68 | asr_index = AssertResponse(index_page) |
|
83 | asr_index = AssertResponse(index_page) | |
69 |
|
84 | |||
70 | if show_link: |
|
85 | if show_link: | |
@@ -74,7 +89,7 b' class TestPasswordReset(TestController):' | |||||
74 | asr_login.no_element_exists('a.pwd_reset') |
|
89 | asr_login.no_element_exists('a.pwd_reset') | |
75 | asr_index.no_element_exists('a.pwd_reset') |
|
90 | asr_index.no_element_exists('a.pwd_reset') | |
76 |
|
91 | |||
77 |
response = self.app.get( |
|
92 | response = self.app.get(route_path('reset_password')) | |
78 |
|
93 | |||
79 | assert_response = AssertResponse(response) |
|
94 | assert_response = AssertResponse(response) | |
80 | if show_reset: |
|
95 | if show_reset: | |
@@ -96,11 +111,11 b' class TestPasswordReset(TestController):' | |||||
96 | 'default_password_reset': 'hg.password_reset.disabled', |
|
111 | 'default_password_reset': 'hg.password_reset.disabled', | |
97 | 'default_extern_activate': 'hg.extern_activate.auto', |
|
112 | 'default_extern_activate': 'hg.extern_activate.auto', | |
98 | } |
|
113 | } | |
99 |
self.app.post( |
|
114 | self.app.post(route_path('admin_permissions_application_update'), params=params) | |
100 | self.logout_user() |
|
115 | self.logout_user() | |
101 |
|
116 | |||
102 | response = self.app.post( |
|
117 | response = self.app.post( | |
103 |
|
|
118 | route_path('reset_password'), {'email': 'lisa@rhodecode.com',} | |
104 | ) |
|
119 | ) | |
105 | response = response.follow() |
|
120 | response = response.follow() | |
106 | response.mustcontain('Password reset is disabled.') |
|
121 | response.mustcontain('Password reset is disabled.') |
@@ -321,32 +321,6 b' def make_map(config):' | |||||
321 | '/user_groups/{user_group_id}/edit/members', jsroute=True, |
|
321 | '/user_groups/{user_group_id}/edit/members', jsroute=True, | |
322 | action='user_group_members', conditions={'method': ['GET']}) |
|
322 | action='user_group_members', conditions={'method': ['GET']}) | |
323 |
|
323 | |||
324 | # ADMIN PERMISSIONS ROUTES |
|
|||
325 | with rmap.submapper(path_prefix=ADMIN_PREFIX, |
|
|||
326 | controller='admin/permissions') as m: |
|
|||
327 | m.connect('admin_permissions_application', '/permissions/application', |
|
|||
328 | action='permission_application_update', conditions={'method': ['POST']}) |
|
|||
329 | m.connect('admin_permissions_application', '/permissions/application', |
|
|||
330 | action='permission_application', conditions={'method': ['GET']}) |
|
|||
331 |
|
||||
332 | m.connect('admin_permissions_global', '/permissions/global', |
|
|||
333 | action='permission_global_update', conditions={'method': ['POST']}) |
|
|||
334 | m.connect('admin_permissions_global', '/permissions/global', |
|
|||
335 | action='permission_global', conditions={'method': ['GET']}) |
|
|||
336 |
|
||||
337 | m.connect('admin_permissions_object', '/permissions/object', |
|
|||
338 | action='permission_objects_update', conditions={'method': ['POST']}) |
|
|||
339 | m.connect('admin_permissions_object', '/permissions/object', |
|
|||
340 | action='permission_objects', conditions={'method': ['GET']}) |
|
|||
341 |
|
||||
342 | m.connect('admin_permissions_ips', '/permissions/ips', |
|
|||
343 | action='permission_ips', conditions={'method': ['POST']}) |
|
|||
344 | m.connect('admin_permissions_ips', '/permissions/ips', |
|
|||
345 | action='permission_ips', conditions={'method': ['GET']}) |
|
|||
346 |
|
||||
347 | m.connect('admin_permissions_overview', '/permissions/overview', |
|
|||
348 | action='permission_perms', conditions={'method': ['GET']}) |
|
|||
349 |
|
||||
350 | # ADMIN DEFAULTS REST ROUTES |
|
324 | # ADMIN DEFAULTS REST ROUTES | |
351 | with rmap.submapper(path_prefix=ADMIN_PREFIX, |
|
325 | with rmap.submapper(path_prefix=ADMIN_PREFIX, | |
352 | controller='admin/defaults') as m: |
|
326 | controller='admin/defaults') as m: |
@@ -62,62 +62,63 b' class PermissionModel(BaseModel):' | |||||
62 | } |
|
62 | } | |
63 |
|
63 | |||
64 | def set_global_permission_choices(self, c_obj, gettext_translator): |
|
64 | def set_global_permission_choices(self, c_obj, gettext_translator): | |
|
65 | _ = gettext_translator | |||
65 |
|
66 | |||
66 | c_obj.repo_perms_choices = [ |
|
67 | c_obj.repo_perms_choices = [ | |
67 |
('repository.none', |
|
68 | ('repository.none', _('None'),), | |
68 |
('repository.read', |
|
69 | ('repository.read', _('Read'),), | |
69 |
('repository.write', |
|
70 | ('repository.write', _('Write'),), | |
70 |
('repository.admin', |
|
71 | ('repository.admin', _('Admin'),)] | |
71 |
|
72 | |||
72 | c_obj.group_perms_choices = [ |
|
73 | c_obj.group_perms_choices = [ | |
73 |
('group.none', |
|
74 | ('group.none', _('None'),), | |
74 |
('group.read', |
|
75 | ('group.read', _('Read'),), | |
75 |
('group.write', |
|
76 | ('group.write', _('Write'),), | |
76 |
('group.admin', |
|
77 | ('group.admin', _('Admin'),)] | |
77 |
|
78 | |||
78 | c_obj.user_group_perms_choices = [ |
|
79 | c_obj.user_group_perms_choices = [ | |
79 |
('usergroup.none', |
|
80 | ('usergroup.none', _('None'),), | |
80 |
('usergroup.read', |
|
81 | ('usergroup.read', _('Read'),), | |
81 |
('usergroup.write', |
|
82 | ('usergroup.write', _('Write'),), | |
82 |
('usergroup.admin', |
|
83 | ('usergroup.admin', _('Admin'),)] | |
83 |
|
84 | |||
84 | c_obj.register_choices = [ |
|
85 | c_obj.register_choices = [ | |
85 |
('hg.register.none', |
|
86 | ('hg.register.none', _('Disabled')), | |
86 |
('hg.register.manual_activate', |
|
87 | ('hg.register.manual_activate', _('Allowed with manual account activation')), | |
87 |
('hg.register.auto_activate', |
|
88 | ('hg.register.auto_activate', _('Allowed with automatic account activation')),] | |
88 |
|
89 | |||
89 | c_obj.password_reset_choices = [ |
|
90 | c_obj.password_reset_choices = [ | |
90 |
('hg.password_reset.enabled', |
|
91 | ('hg.password_reset.enabled', _('Allow password recovery')), | |
91 |
('hg.password_reset.hidden', |
|
92 | ('hg.password_reset.hidden', _('Hide password recovery link')), | |
92 |
('hg.password_reset.disabled', |
|
93 | ('hg.password_reset.disabled', _('Disable password recovery')),] | |
93 |
|
94 | |||
94 | c_obj.extern_activate_choices = [ |
|
95 | c_obj.extern_activate_choices = [ | |
95 |
('hg.extern_activate.manual', |
|
96 | ('hg.extern_activate.manual', _('Manual activation of external account')), | |
96 |
('hg.extern_activate.auto', |
|
97 | ('hg.extern_activate.auto', _('Automatic activation of external account')),] | |
97 |
|
98 | |||
98 | c_obj.repo_create_choices = [ |
|
99 | c_obj.repo_create_choices = [ | |
99 |
('hg.create.none', |
|
100 | ('hg.create.none', _('Disabled')), | |
100 |
('hg.create.repository', |
|
101 | ('hg.create.repository', _('Enabled'))] | |
101 |
|
102 | |||
102 | c_obj.repo_create_on_write_choices = [ |
|
103 | c_obj.repo_create_on_write_choices = [ | |
103 |
('hg.create.write_on_repogroup.false', |
|
104 | ('hg.create.write_on_repogroup.false', _('Disabled')), | |
104 |
('hg.create.write_on_repogroup.true', |
|
105 | ('hg.create.write_on_repogroup.true', _('Enabled'))] | |
105 |
|
106 | |||
106 | c_obj.user_group_create_choices = [ |
|
107 | c_obj.user_group_create_choices = [ | |
107 |
('hg.usergroup.create.false', |
|
108 | ('hg.usergroup.create.false', _('Disabled')), | |
108 |
('hg.usergroup.create.true', |
|
109 | ('hg.usergroup.create.true', _('Enabled'))] | |
109 |
|
110 | |||
110 | c_obj.repo_group_create_choices = [ |
|
111 | c_obj.repo_group_create_choices = [ | |
111 |
('hg.repogroup.create.false', |
|
112 | ('hg.repogroup.create.false', _('Disabled')), | |
112 |
('hg.repogroup.create.true', |
|
113 | ('hg.repogroup.create.true', _('Enabled'))] | |
113 |
|
114 | |||
114 | c_obj.fork_choices = [ |
|
115 | c_obj.fork_choices = [ | |
115 |
('hg.fork.none', |
|
116 | ('hg.fork.none', _('Disabled')), | |
116 |
('hg.fork.repository', |
|
117 | ('hg.fork.repository', _('Enabled'))] | |
117 |
|
118 | |||
118 | c_obj.inherit_default_permission_choices = [ |
|
119 | c_obj.inherit_default_permission_choices = [ | |
119 |
('hg.inherit_default_perms.false', |
|
120 | ('hg.inherit_default_perms.false', _('Disabled')), | |
120 |
('hg.inherit_default_perms.true', |
|
121 | ('hg.inherit_default_perms.true', _('Enabled'))] | |
121 |
|
122 | |||
122 | def get_default_perms(self, object_perms, suffix): |
|
123 | def get_default_perms(self, object_perms, suffix): | |
123 | defaults = {} |
|
124 | defaults = {} |
@@ -63,7 +63,14 b' function registerRCRoutes() {' | |||||
63 | pyroutes.register('admin_settings_sessions_cleanup', '/_admin/settings/sessions/cleanup', []); |
|
63 | pyroutes.register('admin_settings_sessions_cleanup', '/_admin/settings/sessions/cleanup', []); | |
64 | pyroutes.register('admin_settings_process_management', '/_admin/settings/process_management', []); |
|
64 | pyroutes.register('admin_settings_process_management', '/_admin/settings/process_management', []); | |
65 | pyroutes.register('admin_settings_process_management_signal', '/_admin/settings/process_management/signal', []); |
|
65 | pyroutes.register('admin_settings_process_management_signal', '/_admin/settings/process_management/signal', []); | |
|
66 | pyroutes.register('admin_permissions_application', '/_admin/permissions/application', []); | |||
|
67 | pyroutes.register('admin_permissions_application_update', '/_admin/permissions/application/update', []); | |||
|
68 | pyroutes.register('admin_permissions_global', '/_admin/permissions/global', []); | |||
|
69 | pyroutes.register('admin_permissions_global_update', '/_admin/permissions/global/update', []); | |||
|
70 | pyroutes.register('admin_permissions_object', '/_admin/permissions/object', []); | |||
|
71 | pyroutes.register('admin_permissions_object_update', '/_admin/permissions/object/update', []); | |||
66 | pyroutes.register('admin_permissions_ips', '/_admin/permissions/ips', []); |
|
72 | pyroutes.register('admin_permissions_ips', '/_admin/permissions/ips', []); | |
|
73 | pyroutes.register('admin_permissions_overview', '/_admin/permissions/overview', []); | |||
67 | pyroutes.register('users', '/_admin/users', []); |
|
74 | pyroutes.register('users', '/_admin/users', []); | |
68 | pyroutes.register('users_data', '/_admin/users_data', []); |
|
75 | pyroutes.register('users_data', '/_admin/users_data', []); | |
69 | pyroutes.register('edit_user_auth_tokens', '/_admin/users/%(user_id)s/edit/auth_tokens', ['user_id']); |
|
76 | pyroutes.register('edit_user_auth_tokens', '/_admin/users/%(user_id)s/edit/auth_tokens', ['user_id']); |
@@ -30,19 +30,19 b'' | |||||
30 | <div class="sidebar"> |
|
30 | <div class="sidebar"> | |
31 | <ul class="nav nav-pills nav-stacked"> |
|
31 | <ul class="nav nav-pills nav-stacked"> | |
32 | <li class="${'active' if c.active=='application' else ''}"> |
|
32 | <li class="${'active' if c.active=='application' else ''}"> | |
33 |
<a href="${h. |
|
33 | <a href="${h.route_path('admin_permissions_application')}">${_('Application')}</a> | |
34 | </li> |
|
34 | </li> | |
35 | <li class="${'active' if c.active=='global' else ''}"> |
|
35 | <li class="${'active' if c.active=='global' else ''}"> | |
36 |
<a href="${h. |
|
36 | <a href="${h.route_path('admin_permissions_global')}">${_('Global')}</a> | |
37 | </li> |
|
37 | </li> | |
38 | <li class="${'active' if c.active=='objects' else ''}"> |
|
38 | <li class="${'active' if c.active=='objects' else ''}"> | |
39 |
<a href="${h. |
|
39 | <a href="${h.route_path('admin_permissions_object')}">${_('Object')}</a> | |
40 | </li> |
|
40 | </li> | |
41 | <li class="${'active' if c.active=='ips' else ''}"> |
|
41 | <li class="${'active' if c.active=='ips' else ''}"> | |
42 |
<a href="${h. |
|
42 | <a href="${h.route_path('admin_permissions_ips')}">${_('IP Whitelist')}</a> | |
43 | </li> |
|
43 | </li> | |
44 | <li class="${'active' if c.active=='perms' else ''}"> |
|
44 | <li class="${'active' if c.active=='perms' else ''}"> | |
45 |
<a href="${h. |
|
45 | <a href="${h.route_path('admin_permissions_overview')}">${_('Overview')}</a> | |
46 | </li> |
|
46 | </li> | |
47 | </ul> |
|
47 | </ul> | |
48 | </div> |
|
48 | </div> |
@@ -3,7 +3,7 b'' | |||||
3 | <h3 class="panel-title">${_('System Wide Application Permissions')}</h3> |
|
3 | <h3 class="panel-title">${_('System Wide Application Permissions')}</h3> | |
4 | </div> |
|
4 | </div> | |
5 | <div class="panel-body"> |
|
5 | <div class="panel-body"> | |
6 |
${h.secure_form(h. |
|
6 | ${h.secure_form(h.route_path('admin_permissions_application_update'), method='POST', request=request)} | |
7 | <div class="form"> |
|
7 | <div class="form"> | |
8 | <!-- fields --> |
|
8 | <!-- fields --> | |
9 | <div class="fields"> |
|
9 | <div class="fields"> | |
@@ -15,7 +15,7 b'' | |||||
15 | <div class="checkbox"> |
|
15 | <div class="checkbox"> | |
16 | ${h.checkbox('anonymous',True)} Allow Anonymous Access |
|
16 | ${h.checkbox('anonymous',True)} Allow Anonymous Access | |
17 | </div> |
|
17 | </div> | |
18 |
<span class="help-block">${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. |
|
18 | <span class="help-block">${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')))))}</span> | |
19 | </div> |
|
19 | </div> | |
20 | </div> |
|
20 | </div> | |
21 |
|
21 |
@@ -1,5 +1,5 b'' | |||||
1 |
|
1 | |||
2 |
${h.secure_form(h. |
|
2 | ${h.secure_form(h.route_path('admin_permissions_global_update'), method='POST', request=request)} | |
3 | <div class="form permissions-global"> |
|
3 | <div class="form permissions-global"> | |
4 | <!-- fields --> |
|
4 | <!-- fields --> | |
5 | <div class="fields"> |
|
5 | <div class="fields"> |
@@ -6,6 +6,9 b'' | |||||
6 | </div> |
|
6 | </div> | |
7 | <div class="panel-body"> |
|
7 | <div class="panel-body"> | |
8 | <div class="ips_wrap"> |
|
8 | <div class="ips_wrap"> | |
|
9 | <h5>${_('Current IP address')}: <code>${c.rhodecode_user.ip_addr}</code></h5> | |||
|
10 | ||||
|
11 | ||||
9 | <table class="rctable ip-whitelist"> |
|
12 | <table class="rctable ip-whitelist"> | |
10 | <tr> |
|
13 | <tr> | |
11 | <th>IP Address</th> |
|
14 | <th>IP Address</th> |
@@ -5,7 +5,7 b'' | |||||
5 | <div class="panel-body"> |
|
5 | <div class="panel-body"> | |
6 | <p>${_('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.')} |
|
6 | <p>${_('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.')} | |
7 | </p> |
|
7 | </p> | |
8 |
${h.secure_form(h. |
|
8 | ${h.secure_form(h.route_path('admin_permissions_object_update'), method='POST', request=request)} | |
9 | <div class="form"> |
|
9 | <div class="form"> | |
10 | <div class="fields"> |
|
10 | <div class="fields"> | |
11 | <div class="field"> |
|
11 | <div class="field"> |
@@ -17,7 +17,7 b'' | |||||
17 | <tr> |
|
17 | <tr> | |
18 | <td class="td-ip"><div class="ip">${ip.ip_addr}</div></td> |
|
18 | <td class="td-ip"><div class="ip">${ip.ip_addr}</div></td> | |
19 | <td class="td-iprange"><div class="ip">${h.ip_range(ip.ip_addr)}</div></td> |
|
19 | <td class="td-iprange"><div class="ip">${h.ip_range(ip.ip_addr)}</div></td> | |
20 |
<td class="td-description">${h.literal(_('Inherited from %s') % h.link_to('*default*',h. |
|
20 | <td class="td-description">${h.literal(_('Inherited from %s') % h.link_to('*default*',h.route_path('admin_permissions_ips')))}</td> | |
21 | <td></td> |
|
21 | <td></td> | |
22 | </tr> |
|
22 | </tr> | |
23 | %endfor |
|
23 | %endfor |
@@ -77,7 +77,7 b'' | |||||
77 | <li><a href="${h.url('repo_groups')}">${_('Repository groups')}</a></li> |
|
77 | <li><a href="${h.url('repo_groups')}">${_('Repository groups')}</a></li> | |
78 | <li><a href="${h.route_path('users')}">${_('Users')}</a></li> |
|
78 | <li><a href="${h.route_path('users')}">${_('Users')}</a></li> | |
79 | <li><a href="${h.url('users_groups')}">${_('User groups')}</a></li> |
|
79 | <li><a href="${h.url('users_groups')}">${_('User groups')}</a></li> | |
80 |
<li><a href="${h. |
|
80 | <li><a href="${h.route_path('admin_permissions_application')}">${_('Permissions')}</a></li> | |
81 | <li><a href="${h.route_path('auth_home', traverse='')}">${_('Authentication')}</a></li> |
|
81 | <li><a href="${h.route_path('auth_home', traverse='')}">${_('Authentication')}</a></li> | |
82 | <li><a href="${h.route_path('global_integrations_home')}">${_('Integrations')}</a></li> |
|
82 | <li><a href="${h.route_path('global_integrations_home')}">${_('Integrations')}</a></li> | |
83 | <li><a href="${h.url('admin_defaults_repositories')}">${_('Defaults')}</a></li> |
|
83 | <li><a href="${h.url('admin_defaults_repositories')}">${_('Defaults')}</a></li> |
@@ -106,7 +106,7 b'' | |||||
106 | <span class="help-block"> |
|
106 | <span class="help-block"> | |
107 | ${h.literal(_('Select to inherit permissions from %s permissions settings, ' |
|
107 | ${h.literal(_('Select to inherit permissions from %s permissions settings, ' | |
108 | 'including default IP address whitelist and inheritance of \npermission by members of user groups.') |
|
108 | 'including default IP address whitelist and inheritance of \npermission by members of user groups.') | |
109 |
% h.link_to('default user', h. |
|
109 | % h.link_to('default user', h.route_path('admin_permissions_global')))} | |
110 | </span> |
|
110 | </span> | |
111 | </div> |
|
111 | </div> | |
112 | </div> |
|
112 | </div> |
@@ -76,7 +76,7 b'' | |||||
76 | </td> |
|
76 | </td> | |
77 | %if actions: |
|
77 | %if actions: | |
78 | <td class="td-action"> |
|
78 | <td class="td-action"> | |
79 |
<a href="${custom_url or h. |
|
79 | <a href="${custom_url or h.route_path('admin_permissions_global')}">${_('edit')}</a> | |
80 | </td> |
|
80 | </td> | |
81 | %endif |
|
81 | %endif | |
82 | </tr> |
|
82 | </tr> | |
@@ -84,14 +84,14 b'' | |||||
84 |
|
84 | |||
85 | ${glob(_('Super admin'), get_section_perms('hg.admin', permissions[section]))} |
|
85 | ${glob(_('Super admin'), get_section_perms('hg.admin', permissions[section]))} | |
86 |
|
86 | |||
87 |
${glob(_('Repository default permission'), get_section_perms('repository.', permissions[section]), 'repository', h. |
|
87 | ${glob(_('Repository default permission'), get_section_perms('repository.', permissions[section]), 'repository', h.route_path('admin_permissions_object'))} | |
88 |
${glob(_('Repository group default permission'), get_section_perms('group.', permissions[section]), 'group', h. |
|
88 | ${glob(_('Repository group default permission'), get_section_perms('group.', permissions[section]), 'group', h.route_path('admin_permissions_object'))} | |
89 |
${glob(_('User group default permission'), get_section_perms('usergroup.', permissions[section]), 'usergroup', h. |
|
89 | ${glob(_('User group default permission'), get_section_perms('usergroup.', permissions[section]), 'usergroup', h.route_path('admin_permissions_object'))} | |
90 |
|
90 | |||
91 |
${glob(_('Create repositories'), get_section_perms('hg.create.', permissions[section]), custom_url=h. |
|
91 | ${glob(_('Create repositories'), get_section_perms('hg.create.', permissions[section]), custom_url=h.route_path('admin_permissions_global'))} | |
92 |
${glob(_('Fork repositories'), get_section_perms('hg.fork.', permissions[section]), custom_url=h. |
|
92 | ${glob(_('Fork repositories'), get_section_perms('hg.fork.', permissions[section]), custom_url=h.route_path('admin_permissions_global'))} | |
93 |
${glob(_('Create repository groups'), get_section_perms('hg.repogroup.create.', permissions[section]), custom_url=h. |
|
93 | ${glob(_('Create repository groups'), get_section_perms('hg.repogroup.create.', permissions[section]), custom_url=h.route_path('admin_permissions_global'))} | |
94 |
${glob(_('Create user groups'), get_section_perms('hg.usergroup.create.', permissions[section]), custom_url=h. |
|
94 | ${glob(_('Create user groups'), get_section_perms('hg.usergroup.create.', permissions[section]), custom_url=h.route_path('admin_permissions_global'))} | |
95 |
|
95 | |||
96 |
|
96 | |||
97 | </tbody> |
|
97 | </tbody> |
@@ -46,6 +46,7 b' from rhodecode.config.routing import ADM' | |||||
46 | from rhodecode.model.meta import Session |
|
46 | from rhodecode.model.meta import Session | |
47 | from rhodecode.model.db import User |
|
47 | from rhodecode.model.db import User | |
48 | from rhodecode.lib import auth |
|
48 | from rhodecode.lib import auth | |
|
49 | from rhodecode.lib import helpers as h | |||
49 | from rhodecode.lib.helpers import flash, link_to |
|
50 | from rhodecode.lib.helpers import flash, link_to | |
50 | from rhodecode.lib.utils2 import safe_unicode, safe_str |
|
51 | from rhodecode.lib.utils2 import safe_unicode, safe_str | |
51 |
|
52 | |||
@@ -166,9 +167,9 b' class TestController(object):' | |||||
166 |
|
167 | |||
167 | def login_user_session( |
|
168 | def login_user_session( | |
168 | app, username=TEST_USER_ADMIN_LOGIN, password=TEST_USER_ADMIN_PASS): |
|
169 | app, username=TEST_USER_ADMIN_LOGIN, password=TEST_USER_ADMIN_PASS): | |
169 | from rhodecode.tests.functional.test_login import login_url |
|
170 | ||
170 | response = app.post( |
|
171 | response = app.post( | |
171 | login_url, |
|
172 | h.route_path('login'), | |
172 | {'username': username, 'password': password}) |
|
173 | {'username': username, 'password': password}) | |
173 | if 'invalid user name' in response.body: |
|
174 | if 'invalid user name' in response.body: | |
174 | pytest.fail('could not login using %s %s' % (username, password)) |
|
175 | pytest.fail('could not login using %s %s' % (username, password)) | |
@@ -187,8 +188,7 b' def login_user_session(' | |||||
187 |
|
188 | |||
188 |
|
189 | |||
189 | def logout_user_session(app, csrf_token): |
|
190 | def logout_user_session(app, csrf_token): | |
190 | from rhodecode.tests.functional.test_login import logut_url |
|
191 | app.post(h.route_path('logout'), {'csrf_token': csrf_token}, status=302) | |
191 | app.post(logut_url, {'csrf_token': csrf_token}, status=302) |
|
|||
192 |
|
192 | |||
193 |
|
193 | |||
194 | def login_user(app, username=TEST_USER_ADMIN_LOGIN, |
|
194 | def login_user(app, username=TEST_USER_ADMIN_LOGIN, |
@@ -99,13 +99,12 b' class TestPullrequestsController(object)' | |||||
99 | in response) != pr_merge_enabled |
|
99 | in response) != pr_merge_enabled | |
100 |
|
100 | |||
101 | def test_close_status_visibility(self, pr_util, user_util, csrf_token): |
|
101 | def test_close_status_visibility(self, pr_util, user_util, csrf_token): | |
102 | from rhodecode.tests.functional.test_login import login_url, logut_url |
|
|||
103 | # Logout |
|
102 | # Logout | |
104 | response = self.app.post( |
|
103 | response = self.app.post( | |
105 |
|
|
104 | h.route_path('logout'), | |
106 | params={'csrf_token': csrf_token}) |
|
105 | params={'csrf_token': csrf_token}) | |
107 | # Login as regular user |
|
106 | # Login as regular user | |
108 |
response = self.app.post( |
|
107 | response = self.app.post(h.route_path('login'), | |
109 | {'username': TEST_USER_REGULAR_LOGIN, |
|
108 | {'username': TEST_USER_REGULAR_LOGIN, | |
110 | 'password': 'test12'}) |
|
109 | 'password': 'test12'}) | |
111 |
|
110 |
@@ -410,7 +410,12 b' def add_test_routes(config):' | |||||
410 | """ |
|
410 | """ | |
411 | Adds test routing that can be used in different functional tests |
|
411 | Adds test routing that can be used in different functional tests | |
412 | """ |
|
412 | """ | |
|
413 | from rhodecode.apps._base import ADMIN_PREFIX | |||
|
414 | ||||
413 | config.add_route(name='home', pattern='/') |
|
415 | config.add_route(name='home', pattern='/') | |
|
416 | ||||
|
417 | config.add_route(name='login', pattern=ADMIN_PREFIX + '/login') | |||
|
418 | config.add_route(name='logout', pattern=ADMIN_PREFIX + '/logout') | |||
414 | config.add_route(name='repo_summary', pattern='/{repo_name}') |
|
419 | config.add_route(name='repo_summary', pattern='/{repo_name}') | |
415 | config.add_route(name='repo_summary_explicit', pattern='/{repo_name}/summary') |
|
420 | config.add_route(name='repo_summary_explicit', pattern='/{repo_name}/summary') | |
416 | config.add_route(name='repo_group_home', pattern='/{repo_group_name}') |
|
421 | config.add_route(name='repo_group_home', pattern='/{repo_group_name}') |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
General Comments 0
You need to be logged in to leave comments.
Login now