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 | 72 | pattern='/settings/process_management/signal') |
|
73 | 73 | |
|
74 | 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 | 97 | config.add_route( |
|
76 | 98 | name='admin_permissions_ips', |
|
77 | 99 | pattern='/permissions/ips') |
|
78 | 100 | |
|
101 | config.add_route( | |
|
102 | name='admin_permissions_overview', | |
|
103 | pattern='/permissions/overview') | |
|
104 | ||
|
79 | 105 | # users admin |
|
80 | 106 | config.add_route( |
|
81 | 107 | name='users', |
@@ -22,7 +22,7 b' import pytest' | |||
|
22 | 22 | from rhodecode.model.db import User, UserIpMap |
|
23 | 23 | from rhodecode.model.permission import PermissionModel |
|
24 | 24 | from rhodecode.tests import ( |
|
25 |
TestController |
|
|
25 | TestController, clear_all_caches, assert_session_flash) | |
|
26 | 26 | |
|
27 | 27 | |
|
28 | 28 | def route_path(name, params=None, **kwargs): |
@@ -36,6 +36,27 b' def route_path(name, params=None, **kwar' | |||
|
36 | 36 | ADMIN_PREFIX + '/users/{user_id}/edit/ips/new', |
|
37 | 37 | 'edit_user_ips_delete': |
|
38 | 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 | 60 | }[name].format(**kwargs) |
|
40 | 61 | |
|
41 | 62 | if params: |
@@ -55,7 +76,7 b' class TestAdminPermissionsController(Tes' | |||
|
55 | 76 | |
|
56 | 77 | def test_index_application(self): |
|
57 | 78 | self.log_user() |
|
58 |
self.app.get( |
|
|
79 | self.app.get(route_path('admin_permissions_application')) | |
|
59 | 80 | |
|
60 | 81 | @pytest.mark.parametrize( |
|
61 | 82 | 'anonymous, default_register, default_register_message, default_password_reset,' |
@@ -87,7 +108,7 b' class TestAdminPermissionsController(Tes' | |||
|
87 | 108 | 'default_password_reset': default_password_reset, |
|
88 | 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 | 112 | params=params) |
|
92 | 113 | if expect_form_error: |
|
93 | 114 | assert response.status_int == 200 |
@@ -101,7 +122,7 b' class TestAdminPermissionsController(Tes' | |||
|
101 | 122 | |
|
102 | 123 | def test_index_object(self): |
|
103 | 124 | self.log_user() |
|
104 |
self.app.get( |
|
|
125 | self.app.get(route_path('admin_permissions_object')) | |
|
105 | 126 | |
|
106 | 127 | @pytest.mark.parametrize( |
|
107 | 128 | 'repo, repo_group, user_group, expect_error, expect_form_error', [ |
@@ -127,7 +148,7 b' class TestAdminPermissionsController(Tes' | |||
|
127 | 148 | 'default_user_group_perm': user_group, |
|
128 | 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 | 152 | params=params) |
|
132 | 153 | if expect_form_error: |
|
133 | 154 | assert response.status_int == 200 |
@@ -141,7 +162,7 b' class TestAdminPermissionsController(Tes' | |||
|
141 | 162 | |
|
142 | 163 | def test_index_global(self): |
|
143 | 164 | self.log_user() |
|
144 |
self.app.get( |
|
|
165 | self.app.get(route_path('admin_permissions_global')) | |
|
145 | 166 | |
|
146 | 167 | @pytest.mark.parametrize( |
|
147 | 168 | 'repo_create, repo_create_write, user_group_create, repo_group_create,' |
@@ -175,7 +196,7 b' class TestAdminPermissionsController(Tes' | |||
|
175 | 196 | 'default_fork_create': fork_create, |
|
176 | 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 | 200 | params=params) |
|
180 | 201 | if expect_form_error: |
|
181 | 202 | assert response.status_int == 200 |
@@ -189,7 +210,7 b' class TestAdminPermissionsController(Tes' | |||
|
189 | 210 | |
|
190 | 211 | def test_index_ips(self): |
|
191 | 212 | self.log_user() |
|
192 |
response = self.app.get( |
|
|
213 | response = self.app.get(route_path('admin_permissions_ips')) | |
|
193 | 214 | # TODO: Test response... |
|
194 | 215 | response.mustcontain('All IP addresses are allowed') |
|
195 | 216 | |
@@ -203,7 +224,7 b' class TestAdminPermissionsController(Tes' | |||
|
203 | 224 | route_path('edit_user_ips_add', user_id=default_user_id), |
|
204 | 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 | 228 | response.mustcontain('127.0.0.0/24') |
|
208 | 229 | response.mustcontain('127.0.0.0 - 127.0.0.255') |
|
209 | 230 | |
@@ -219,11 +240,11 b' class TestAdminPermissionsController(Tes' | |||
|
219 | 240 | assert_session_flash(response, 'Removed ip address from user whitelist') |
|
220 | 241 | |
|
221 | 242 | clear_all_caches() |
|
222 |
response = self.app.get( |
|
|
243 | response = self.app.get(route_path('admin_permissions_ips')) | |
|
223 | 244 | response.mustcontain('All IP addresses are allowed') |
|
224 | 245 | response.mustcontain(no=['127.0.0.0/24']) |
|
225 | 246 | response.mustcontain(no=['127.0.0.0 - 127.0.0.255']) |
|
226 | 247 | |
|
227 | 248 | def test_index_overview(self): |
|
228 | 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 | 23 | import mock |
|
24 | 24 | import pytest |
|
25 | 25 | |
|
26 | from rhodecode.config.routing import ADMIN_PREFIX | |
|
27 | 26 | from rhodecode.tests import ( |
|
28 |
assert_session_flash |
|
|
27 | assert_session_flash, HG_REPO, TEST_USER_ADMIN_LOGIN, | |
|
29 | 28 | no_newline_id_generator) |
|
30 | 29 | from rhodecode.tests.fixture import Fixture |
|
31 | 30 | from rhodecode.lib.auth import check_password |
@@ -37,14 +36,32 b' from rhodecode.model.meta import Session' | |||
|
37 | 36 | |
|
38 | 37 | fixture = Fixture() |
|
39 | 38 | |
|
40 | # Hardcode URLs because we don't have a request object to use | |
|
41 | # pyramids URL generation methods. | |
|
42 | index_url = '/' | |
|
43 | login_url = ADMIN_PREFIX + '/login' | |
|
44 | logut_url = ADMIN_PREFIX + '/logout' | |
|
45 | register_url = ADMIN_PREFIX + '/register' | |
|
46 | pwd_reset_url = ADMIN_PREFIX + '/password_reset' | |
|
47 | pwd_reset_confirm_url = ADMIN_PREFIX + '/password_reset_confirmation' | |
|
39 | ||
|
40 | def route_path(name, params=None, **kwargs): | |
|
41 | import urllib | |
|
42 | from rhodecode.apps._base import ADMIN_PREFIX | |
|
43 | ||
|
44 | base_url = { | |
|
45 | 'login': ADMIN_PREFIX + '/login', | |
|
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 | 67 | @pytest.mark.usefixtures('app') |
@@ -63,12 +80,12 b' class TestLoginController(object):' | |||
|
63 | 80 | assert Notification.query().all() == [] |
|
64 | 81 | |
|
65 | 82 | def test_index(self): |
|
66 |
response = self.app.get( |
|
|
83 | response = self.app.get(route_path('login')) | |
|
67 | 84 | assert response.status == '200 OK' |
|
68 | 85 | # Test response... |
|
69 | 86 | |
|
70 | 87 | def test_login_admin_ok(self): |
|
71 |
response = self.app.post( |
|
|
88 | response = self.app.post(route_path('login'), | |
|
72 | 89 | {'username': 'test_admin', |
|
73 | 90 | 'password': 'test12'}) |
|
74 | 91 | assert response.status == '302 Found' |
@@ -79,7 +96,7 b' class TestLoginController(object):' | |||
|
79 | 96 | response.mustcontain('/%s' % HG_REPO) |
|
80 | 97 | |
|
81 | 98 | def test_login_regular_ok(self): |
|
82 |
response = self.app.post( |
|
|
99 | response = self.app.post(route_path('login'), | |
|
83 | 100 | {'username': 'test_regular', |
|
84 | 101 | 'password': 'test12'}) |
|
85 | 102 | |
@@ -92,7 +109,7 b' class TestLoginController(object):' | |||
|
92 | 109 | |
|
93 | 110 | def test_login_ok_came_from(self): |
|
94 | 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 | 113 | response = self.app.post( |
|
97 | 114 | _url, {'username': 'test_admin', 'password': 'test12'}) |
|
98 | 115 | assert response.status == '302 Found' |
@@ -113,7 +130,7 b' class TestLoginController(object):' | |||
|
113 | 130 | assert 'branch=stable' in response_query[0][1] |
|
114 | 131 | |
|
115 | 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 | 134 | response = self.app.get(_url) |
|
118 | 135 | assert 'branch%3Dstable' in response.form.action |
|
119 | 136 | |
@@ -126,7 +143,7 b' class TestLoginController(object):' | |||
|
126 | 143 | '/\r\nX-Forwarded-Host: http://example.org', |
|
127 | 144 | ], ids=no_newline_id_generator) |
|
128 | 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 | 147 | response = self.app.post( |
|
131 | 148 | _url, |
|
132 | 149 | {'username': 'test_admin', 'password': 'test12'}) |
@@ -136,7 +153,7 b' class TestLoginController(object):' | |||
|
136 | 153 | assert response.request.path == '/' |
|
137 | 154 | |
|
138 | 155 | def test_login_short_password(self): |
|
139 |
response = self.app.post( |
|
|
156 | response = self.app.post(route_path('login'), | |
|
140 | 157 | {'username': 'test_admin', |
|
141 | 158 | 'password': 'as'}) |
|
142 | 159 | assert response.status == '200 OK' |
@@ -145,7 +162,7 b' class TestLoginController(object):' | |||
|
145 | 162 | |
|
146 | 163 | def test_login_wrong_non_ascii_password(self, user_regular): |
|
147 | 164 | response = self.app.post( |
|
148 |
|
|
|
165 | route_path('login'), | |
|
149 | 166 | {'username': user_regular.username, |
|
150 | 167 | 'password': u'invalid-non-asci\xe4'.encode('utf8')}) |
|
151 | 168 | |
@@ -156,13 +173,13 b' class TestLoginController(object):' | |||
|
156 | 173 | password = u'valid-non-ascii\xe4' |
|
157 | 174 | user = user_util.create_user(password=password) |
|
158 | 175 | response = self.app.post( |
|
159 |
|
|
|
176 | route_path('login'), | |
|
160 | 177 | {'username': user.username, |
|
161 | 178 | 'password': password.encode('utf-8')}) |
|
162 | 179 | assert response.status_code == 302 |
|
163 | 180 | |
|
164 | 181 | def test_login_wrong_username_password(self): |
|
165 |
response = self.app.post( |
|
|
182 | response = self.app.post(route_path('login'), | |
|
166 | 183 | {'username': 'error', |
|
167 | 184 | 'password': 'test12'}) |
|
168 | 185 | |
@@ -180,7 +197,7 b' class TestLoginController(object):' | |||
|
180 | 197 | Session().add(user) |
|
181 | 198 | Session().commit() |
|
182 | 199 | self.destroy_users.add(temp_user) |
|
183 |
response = self.app.post( |
|
|
200 | response = self.app.post(route_path('login'), | |
|
184 | 201 | {'username': temp_user, |
|
185 | 202 | 'password': 'test123'}) |
|
186 | 203 | |
@@ -197,13 +214,13 b' class TestLoginController(object):' | |||
|
197 | 214 | |
|
198 | 215 | # REGISTRATIONS |
|
199 | 216 | def test_register(self): |
|
200 |
response = self.app.get(register |
|
|
217 | response = self.app.get(route_path('register')) | |
|
201 | 218 | response.mustcontain('Create an Account') |
|
202 | 219 | |
|
203 | 220 | def test_register_err_same_username(self): |
|
204 | 221 | uname = 'test_admin' |
|
205 | 222 | response = self.app.post( |
|
206 |
register |
|
|
223 | route_path('register'), | |
|
207 | 224 | { |
|
208 | 225 | 'username': uname, |
|
209 | 226 | 'password': 'test12', |
@@ -221,7 +238,7 b' class TestLoginController(object):' | |||
|
221 | 238 | |
|
222 | 239 | def test_register_err_same_email(self): |
|
223 | 240 | response = self.app.post( |
|
224 |
register |
|
|
241 | route_path('register'), | |
|
225 | 242 | { |
|
226 | 243 | 'username': 'test_admin_0', |
|
227 | 244 | 'password': 'test12', |
@@ -238,7 +255,7 b' class TestLoginController(object):' | |||
|
238 | 255 | |
|
239 | 256 | def test_register_err_same_email_case_sensitive(self): |
|
240 | 257 | response = self.app.post( |
|
241 |
register |
|
|
258 | route_path('register'), | |
|
242 | 259 | { |
|
243 | 260 | 'username': 'test_admin_1', |
|
244 | 261 | 'password': 'test12', |
@@ -254,7 +271,7 b' class TestLoginController(object):' | |||
|
254 | 271 | |
|
255 | 272 | def test_register_err_wrong_data(self): |
|
256 | 273 | response = self.app.post( |
|
257 |
register |
|
|
274 | route_path('register'), | |
|
258 | 275 | { |
|
259 | 276 | 'username': 'xs', |
|
260 | 277 | 'password': 'test', |
@@ -270,7 +287,7 b' class TestLoginController(object):' | |||
|
270 | 287 | |
|
271 | 288 | def test_register_err_username(self): |
|
272 | 289 | response = self.app.post( |
|
273 |
register |
|
|
290 | route_path('register'), | |
|
274 | 291 | { |
|
275 | 292 | 'username': 'error user', |
|
276 | 293 | 'password': 'test12', |
@@ -291,7 +308,7 b' class TestLoginController(object):' | |||
|
291 | 308 | def test_register_err_case_sensitive(self): |
|
292 | 309 | usr = 'Test_Admin' |
|
293 | 310 | response = self.app.post( |
|
294 |
register |
|
|
311 | route_path('register'), | |
|
295 | 312 | { |
|
296 | 313 | 'username': usr, |
|
297 | 314 | 'password': 'test12', |
@@ -309,7 +326,7 b' class TestLoginController(object):' | |||
|
309 | 326 | |
|
310 | 327 | def test_register_special_chars(self): |
|
311 | 328 | response = self.app.post( |
|
312 |
register |
|
|
329 | route_path('register'), | |
|
313 | 330 | { |
|
314 | 331 | 'username': 'xxxaxn', |
|
315 | 332 | 'password': 'ąćźżąśśśś', |
@@ -325,7 +342,7 b' class TestLoginController(object):' | |||
|
325 | 342 | |
|
326 | 343 | def test_register_password_mismatch(self): |
|
327 | 344 | response = self.app.post( |
|
328 |
register |
|
|
345 | route_path('register'), | |
|
329 | 346 | { |
|
330 | 347 | 'username': 'xs', |
|
331 | 348 | 'password': '123qwe', |
@@ -346,7 +363,7 b' class TestLoginController(object):' | |||
|
346 | 363 | lastname = 'testlastname' |
|
347 | 364 | |
|
348 | 365 | response = self.app.post( |
|
349 |
register |
|
|
366 | route_path('register'), | |
|
350 | 367 | { |
|
351 | 368 | 'username': username, |
|
352 | 369 | 'password': password, |
@@ -374,29 +391,29 b' class TestLoginController(object):' | |||
|
374 | 391 | def test_forgot_password_wrong_mail(self): |
|
375 | 392 | bad_email = 'marcin@wrongmail.org' |
|
376 | 393 | response = self.app.post( |
|
377 |
|
|
|
394 | route_path('reset_password'), {'email': bad_email, } | |
|
378 | 395 | ) |
|
379 | 396 | assert_session_flash(response, |
|
380 | 397 | 'If such email exists, a password reset link was sent to it.') |
|
381 | 398 | |
|
382 | 399 | def test_forgot_password(self, user_util): |
|
383 |
response = self.app.get( |
|
|
400 | response = self.app.get(route_path('reset_password')) | |
|
384 | 401 | assert response.status == '200 OK' |
|
385 | 402 | |
|
386 | 403 | user = user_util.create_user() |
|
387 | 404 | user_id = user.user_id |
|
388 | 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 | 409 | assert_session_flash(response, |
|
393 | 410 | 'If such email exists, a password reset link was sent to it.') |
|
394 | 411 | |
|
395 | 412 | # BAD KEY |
|
396 |
confirm_url = '{}?key={}'.format( |
|
|
413 | confirm_url = '{}?key={}'.format(route_path('reset_password_confirmation'), 'badkey') | |
|
397 | 414 | response = self.app.get(confirm_url) |
|
398 | 415 | assert response.status == '302 Found' |
|
399 |
assert response.location.endswith( |
|
|
416 | assert response.location.endswith(route_path('reset_password')) | |
|
400 | 417 | assert_session_flash(response, 'Given reset token is invalid') |
|
401 | 418 | |
|
402 | 419 | response.follow() # cleanup flash |
@@ -409,10 +426,10 b' class TestLoginController(object):' | |||
|
409 | 426 | |
|
410 | 427 | assert key |
|
411 | 428 | |
|
412 |
confirm_url = '{}?key={}'.format( |
|
|
429 | confirm_url = '{}?key={}'.format(route_path('reset_password_confirmation'), key.api_key) | |
|
413 | 430 | response = self.app.get(confirm_url) |
|
414 | 431 | assert response.status == '302 Found' |
|
415 |
assert response.location.endswith( |
|
|
432 | assert response.location.endswith(route_path('login')) | |
|
416 | 433 | |
|
417 | 434 | assert_session_flash( |
|
418 | 435 | response, |
@@ -442,10 +459,10 b' class TestLoginController(object):' | |||
|
442 | 459 | auth_token = user_admin.api_key |
|
443 | 460 | |
|
444 | 461 | with fixture.anon_access(False): |
|
445 |
self.app.get( |
|
|
446 | action='changeset_raw', | |
|
447 |
|
|
|
448 |
|
|
|
462 | self.app.get( | |
|
463 | route_path('repo_commit_raw', | |
|
464 | repo_name=HG_REPO, commit_id='tip', | |
|
465 | params=dict(api_key=auth_token)), | |
|
449 | 466 |
|
|
450 | 467 | |
|
451 | 468 | @pytest.mark.parametrize("test_name, auth_token, code", [ |
@@ -468,10 +485,10 b' class TestLoginController(object):' | |||
|
468 | 485 | assert auth_token |
|
469 | 486 | |
|
470 | 487 | with fixture.anon_access(False): |
|
471 |
self.app.get( |
|
|
472 | action='changeset_raw', | |
|
473 |
|
|
|
474 |
|
|
|
488 | self.app.get( | |
|
489 | route_path('repo_commit_raw', | |
|
490 | repo_name=HG_REPO, commit_id='tip', | |
|
491 | params=dict(api_key=auth_token)), | |
|
475 | 492 |
|
|
476 | 493 | |
|
477 | 494 | def test_access_page_via_extra_auth_token(self): |
@@ -485,10 +502,10 b' class TestLoginController(object):' | |||
|
485 | 502 | TEST_USER_ADMIN_LOGIN, 'test') |
|
486 | 503 | Session().commit() |
|
487 | 504 | with fixture.anon_access(False): |
|
488 |
self.app.get( |
|
|
489 | action='changeset_raw', | |
|
490 |
|
|
|
491 |
|
|
|
505 | self.app.get( | |
|
506 | route_path('repo_commit_raw', | |
|
507 | repo_name=HG_REPO, commit_id='tip', | |
|
508 | params=dict(api_key=new_auth_token.api_key)), | |
|
492 | 509 |
|
|
493 | 510 | |
|
494 | 511 | def test_access_page_via_expired_auth_token(self): |
@@ -506,8 +523,8 b' class TestLoginController(object):' | |||
|
506 | 523 | Session().add(new_auth_token) |
|
507 | 524 | Session().commit() |
|
508 | 525 | with fixture.anon_access(False): |
|
509 |
self.app.get( |
|
|
510 | action='changeset_raw', | |
|
511 |
|
|
|
512 |
|
|
|
526 | self.app.get( | |
|
527 | route_path('repo_commit_raw', | |
|
528 | repo_name=HG_REPO, commit_id='tip', | |
|
529 | params=dict(api_key=new_auth_token.api_key)), | |
|
513 | 530 |
|
@@ -20,23 +20,38 b'' | |||
|
20 | 20 | |
|
21 | 21 | import pytest |
|
22 | 22 | |
|
23 | from rhodecode.config.routing import ADMIN_PREFIX | |
|
23 | from rhodecode.lib import helpers as h | |
|
24 | 24 | from rhodecode.tests import ( |
|
25 |
TestController, clear_all_caches, |
|
|
25 | TestController, clear_all_caches, | |
|
26 | 26 | TEST_USER_ADMIN_LOGIN, TEST_USER_ADMIN_PASS) |
|
27 | 27 | from rhodecode.tests.fixture import Fixture |
|
28 | 28 | from rhodecode.tests.utils import AssertResponse |
|
29 | 29 | |
|
30 | 30 | fixture = Fixture() |
|
31 | 31 | |
|
32 | # Hardcode URLs because we don't have a request object to use | |
|
33 | # pyramids URL generation methods. | |
|
34 | index_url = '/' | |
|
35 | login_url = ADMIN_PREFIX + '/login' | |
|
36 | logut_url = ADMIN_PREFIX + '/logout' | |
|
37 | register_url = ADMIN_PREFIX + '/register' | |
|
38 | pwd_reset_url = ADMIN_PREFIX + '/password_reset' | |
|
39 | pwd_reset_confirm_url = ADMIN_PREFIX + '/password_reset_confirmation' | |
|
32 | ||
|
33 | def route_path(name, params=None, **kwargs): | |
|
34 | import urllib | |
|
35 | from rhodecode.apps._base import ADMIN_PREFIX | |
|
36 | ||
|
37 | base_url = { | |
|
38 | 'login': ADMIN_PREFIX + '/login', | |
|
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 | 57 | class TestPasswordReset(TestController): |
@@ -59,12 +74,12 b' class TestPasswordReset(TestController):' | |||
|
59 | 74 | 'default_password_reset': pwd_reset_setting, |
|
60 | 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 | 78 | self.logout_user() |
|
64 | 79 | |
|
65 |
login_page = self.app.get( |
|
|
80 | login_page = self.app.get(route_path('login')) | |
|
66 | 81 | asr_login = AssertResponse(login_page) |
|
67 |
index_page = self.app.get( |
|
|
82 | index_page = self.app.get(h.route_path('home')) | |
|
68 | 83 | asr_index = AssertResponse(index_page) |
|
69 | 84 | |
|
70 | 85 | if show_link: |
@@ -74,7 +89,7 b' class TestPasswordReset(TestController):' | |||
|
74 | 89 | asr_login.no_element_exists('a.pwd_reset') |
|
75 | 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 | 94 | assert_response = AssertResponse(response) |
|
80 | 95 | if show_reset: |
@@ -96,11 +111,11 b' class TestPasswordReset(TestController):' | |||
|
96 | 111 | 'default_password_reset': 'hg.password_reset.disabled', |
|
97 | 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 | 115 | self.logout_user() |
|
101 | 116 | |
|
102 | 117 | response = self.app.post( |
|
103 |
|
|
|
118 | route_path('reset_password'), {'email': 'lisa@rhodecode.com',} | |
|
104 | 119 | ) |
|
105 | 120 | response = response.follow() |
|
106 | 121 | response.mustcontain('Password reset is disabled.') |
@@ -321,32 +321,6 b' def make_map(config):' | |||
|
321 | 321 | '/user_groups/{user_group_id}/edit/members', jsroute=True, |
|
322 | 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 | 324 | # ADMIN DEFAULTS REST ROUTES |
|
351 | 325 | with rmap.submapper(path_prefix=ADMIN_PREFIX, |
|
352 | 326 | controller='admin/defaults') as m: |
@@ -62,62 +62,63 b' class PermissionModel(BaseModel):' | |||
|
62 | 62 | } |
|
63 | 63 | |
|
64 | 64 | def set_global_permission_choices(self, c_obj, gettext_translator): |
|
65 | _ = gettext_translator | |
|
65 | 66 | |
|
66 | 67 | c_obj.repo_perms_choices = [ |
|
67 |
('repository.none', |
|
|
68 |
('repository.read', |
|
|
69 |
('repository.write', |
|
|
70 |
('repository.admin', |
|
|
68 | ('repository.none', _('None'),), | |
|
69 | ('repository.read', _('Read'),), | |
|
70 | ('repository.write', _('Write'),), | |
|
71 | ('repository.admin', _('Admin'),)] | |
|
71 | 72 | |
|
72 | 73 | c_obj.group_perms_choices = [ |
|
73 |
('group.none', |
|
|
74 |
('group.read', |
|
|
75 |
('group.write', |
|
|
76 |
('group.admin', |
|
|
74 | ('group.none', _('None'),), | |
|
75 | ('group.read', _('Read'),), | |
|
76 | ('group.write', _('Write'),), | |
|
77 | ('group.admin', _('Admin'),)] | |
|
77 | 78 | |
|
78 | 79 | c_obj.user_group_perms_choices = [ |
|
79 |
('usergroup.none', |
|
|
80 |
('usergroup.read', |
|
|
81 |
('usergroup.write', |
|
|
82 |
('usergroup.admin', |
|
|
80 | ('usergroup.none', _('None'),), | |
|
81 | ('usergroup.read', _('Read'),), | |
|
82 | ('usergroup.write', _('Write'),), | |
|
83 | ('usergroup.admin', _('Admin'),)] | |
|
83 | 84 | |
|
84 | 85 | c_obj.register_choices = [ |
|
85 |
('hg.register.none', |
|
|
86 |
('hg.register.manual_activate', |
|
|
87 |
('hg.register.auto_activate', |
|
|
86 | ('hg.register.none', _('Disabled')), | |
|
87 | ('hg.register.manual_activate', _('Allowed with manual account activation')), | |
|
88 | ('hg.register.auto_activate', _('Allowed with automatic account activation')),] | |
|
88 | 89 | |
|
89 | 90 | c_obj.password_reset_choices = [ |
|
90 |
('hg.password_reset.enabled', |
|
|
91 |
('hg.password_reset.hidden', |
|
|
92 |
('hg.password_reset.disabled', |
|
|
91 | ('hg.password_reset.enabled', _('Allow password recovery')), | |
|
92 | ('hg.password_reset.hidden', _('Hide password recovery link')), | |
|
93 | ('hg.password_reset.disabled', _('Disable password recovery')),] | |
|
93 | 94 | |
|
94 | 95 | c_obj.extern_activate_choices = [ |
|
95 |
('hg.extern_activate.manual', |
|
|
96 |
('hg.extern_activate.auto', |
|
|
96 | ('hg.extern_activate.manual', _('Manual activation of external account')), | |
|
97 | ('hg.extern_activate.auto', _('Automatic activation of external account')),] | |
|
97 | 98 | |
|
98 | 99 | c_obj.repo_create_choices = [ |
|
99 |
('hg.create.none', |
|
|
100 |
('hg.create.repository', |
|
|
100 | ('hg.create.none', _('Disabled')), | |
|
101 | ('hg.create.repository', _('Enabled'))] | |
|
101 | 102 | |
|
102 | 103 | c_obj.repo_create_on_write_choices = [ |
|
103 |
('hg.create.write_on_repogroup.false', |
|
|
104 |
('hg.create.write_on_repogroup.true', |
|
|
104 | ('hg.create.write_on_repogroup.false', _('Disabled')), | |
|
105 | ('hg.create.write_on_repogroup.true', _('Enabled'))] | |
|
105 | 106 | |
|
106 | 107 | c_obj.user_group_create_choices = [ |
|
107 |
('hg.usergroup.create.false', |
|
|
108 |
('hg.usergroup.create.true', |
|
|
108 | ('hg.usergroup.create.false', _('Disabled')), | |
|
109 | ('hg.usergroup.create.true', _('Enabled'))] | |
|
109 | 110 | |
|
110 | 111 | c_obj.repo_group_create_choices = [ |
|
111 |
('hg.repogroup.create.false', |
|
|
112 |
('hg.repogroup.create.true', |
|
|
112 | ('hg.repogroup.create.false', _('Disabled')), | |
|
113 | ('hg.repogroup.create.true', _('Enabled'))] | |
|
113 | 114 | |
|
114 | 115 | c_obj.fork_choices = [ |
|
115 |
('hg.fork.none', |
|
|
116 |
('hg.fork.repository', |
|
|
116 | ('hg.fork.none', _('Disabled')), | |
|
117 | ('hg.fork.repository', _('Enabled'))] | |
|
117 | 118 | |
|
118 | 119 | c_obj.inherit_default_permission_choices = [ |
|
119 |
('hg.inherit_default_perms.false', |
|
|
120 |
('hg.inherit_default_perms.true', |
|
|
120 | ('hg.inherit_default_perms.false', _('Disabled')), | |
|
121 | ('hg.inherit_default_perms.true', _('Enabled'))] | |
|
121 | 122 | |
|
122 | 123 | def get_default_perms(self, object_perms, suffix): |
|
123 | 124 | defaults = {} |
@@ -63,7 +63,14 b' function registerRCRoutes() {' | |||
|
63 | 63 | pyroutes.register('admin_settings_sessions_cleanup', '/_admin/settings/sessions/cleanup', []); |
|
64 | 64 | pyroutes.register('admin_settings_process_management', '/_admin/settings/process_management', []); |
|
65 | 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 | 72 | pyroutes.register('admin_permissions_ips', '/_admin/permissions/ips', []); |
|
73 | pyroutes.register('admin_permissions_overview', '/_admin/permissions/overview', []); | |
|
67 | 74 | pyroutes.register('users', '/_admin/users', []); |
|
68 | 75 | pyroutes.register('users_data', '/_admin/users_data', []); |
|
69 | 76 | pyroutes.register('edit_user_auth_tokens', '/_admin/users/%(user_id)s/edit/auth_tokens', ['user_id']); |
@@ -30,19 +30,19 b'' | |||
|
30 | 30 | <div class="sidebar"> |
|
31 | 31 | <ul class="nav nav-pills nav-stacked"> |
|
32 | 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 | 34 | </li> |
|
35 | 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 | 37 | </li> |
|
38 | 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 | 40 | </li> |
|
41 | 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 | 43 | </li> |
|
44 | 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 | 46 | </li> |
|
47 | 47 | </ul> |
|
48 | 48 | </div> |
@@ -3,7 +3,7 b'' | |||
|
3 | 3 | <h3 class="panel-title">${_('System Wide Application Permissions')}</h3> |
|
4 | 4 | </div> |
|
5 | 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 | 7 | <div class="form"> |
|
8 | 8 | <!-- fields --> |
|
9 | 9 | <div class="fields"> |
@@ -15,7 +15,7 b'' | |||
|
15 | 15 | <div class="checkbox"> |
|
16 | 16 | ${h.checkbox('anonymous',True)} Allow Anonymous Access |
|
17 | 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 | 19 | </div> |
|
20 | 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 | 3 | <div class="form permissions-global"> |
|
4 | 4 | <!-- fields --> |
|
5 | 5 | <div class="fields"> |
@@ -6,6 +6,9 b'' | |||
|
6 | 6 | </div> |
|
7 | 7 | <div class="panel-body"> |
|
8 | 8 | <div class="ips_wrap"> |
|
9 | <h5>${_('Current IP address')}: <code>${c.rhodecode_user.ip_addr}</code></h5> | |
|
10 | ||
|
11 | ||
|
9 | 12 | <table class="rctable ip-whitelist"> |
|
10 | 13 | <tr> |
|
11 | 14 | <th>IP Address</th> |
@@ -5,7 +5,7 b'' | |||
|
5 | 5 | <div class="panel-body"> |
|
6 | 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 | 7 | </p> |
|
8 |
${h.secure_form(h. |
|
|
8 | ${h.secure_form(h.route_path('admin_permissions_object_update'), method='POST', request=request)} | |
|
9 | 9 | <div class="form"> |
|
10 | 10 | <div class="fields"> |
|
11 | 11 | <div class="field"> |
@@ -17,7 +17,7 b'' | |||
|
17 | 17 | <tr> |
|
18 | 18 | <td class="td-ip"><div class="ip">${ip.ip_addr}</div></td> |
|
19 | 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 | 21 | <td></td> |
|
22 | 22 | </tr> |
|
23 | 23 | %endfor |
@@ -77,7 +77,7 b'' | |||
|
77 | 77 | <li><a href="${h.url('repo_groups')}">${_('Repository groups')}</a></li> |
|
78 | 78 | <li><a href="${h.route_path('users')}">${_('Users')}</a></li> |
|
79 | 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 | 81 | <li><a href="${h.route_path('auth_home', traverse='')}">${_('Authentication')}</a></li> |
|
82 | 82 | <li><a href="${h.route_path('global_integrations_home')}">${_('Integrations')}</a></li> |
|
83 | 83 | <li><a href="${h.url('admin_defaults_repositories')}">${_('Defaults')}</a></li> |
@@ -106,7 +106,7 b'' | |||
|
106 | 106 | <span class="help-block"> |
|
107 | 107 | ${h.literal(_('Select to inherit permissions from %s permissions settings, ' |
|
108 | 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 | 110 | </span> |
|
111 | 111 | </div> |
|
112 | 112 | </div> |
@@ -76,7 +76,7 b'' | |||
|
76 | 76 | </td> |
|
77 | 77 | %if actions: |
|
78 | 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 | 80 | </td> |
|
81 | 81 | %endif |
|
82 | 82 | </tr> |
@@ -84,14 +84,14 b'' | |||
|
84 | 84 | |
|
85 | 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. |
|
|
88 |
${glob(_('Repository group default permission'), get_section_perms('group.', permissions[section]), 'group', h. |
|
|
89 |
${glob(_('User group default permission'), get_section_perms('usergroup.', permissions[section]), 'usergroup', 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.route_path('admin_permissions_object'))} | |
|
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. |
|
|
92 |
${glob(_('Fork repositories'), get_section_perms('hg.fork.', permissions[section]), custom_url=h. |
|
|
93 |
${glob(_('Create repository groups'), get_section_perms('hg.repogroup.create.', permissions[section]), custom_url=h. |
|
|
94 |
${glob(_('Create user groups'), get_section_perms('hg.usergroup.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.route_path('admin_permissions_global'))} | |
|
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.route_path('admin_permissions_global'))} | |
|
95 | 95 | |
|
96 | 96 | |
|
97 | 97 | </tbody> |
@@ -46,6 +46,7 b' from rhodecode.config.routing import ADM' | |||
|
46 | 46 | from rhodecode.model.meta import Session |
|
47 | 47 | from rhodecode.model.db import User |
|
48 | 48 | from rhodecode.lib import auth |
|
49 | from rhodecode.lib import helpers as h | |
|
49 | 50 | from rhodecode.lib.helpers import flash, link_to |
|
50 | 51 | from rhodecode.lib.utils2 import safe_unicode, safe_str |
|
51 | 52 | |
@@ -166,9 +167,9 b' class TestController(object):' | |||
|
166 | 167 | |
|
167 | 168 | def login_user_session( |
|
168 | 169 | app, username=TEST_USER_ADMIN_LOGIN, password=TEST_USER_ADMIN_PASS): |
|
169 | from rhodecode.tests.functional.test_login import login_url | |
|
170 | ||
|
170 | 171 | response = app.post( |
|
171 | login_url, | |
|
172 | h.route_path('login'), | |
|
172 | 173 | {'username': username, 'password': password}) |
|
173 | 174 | if 'invalid user name' in response.body: |
|
174 | 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 | 190 | def logout_user_session(app, csrf_token): |
|
190 | from rhodecode.tests.functional.test_login import logut_url | |
|
191 | app.post(logut_url, {'csrf_token': csrf_token}, status=302) | |
|
191 | app.post(h.route_path('logout'), {'csrf_token': csrf_token}, status=302) | |
|
192 | 192 | |
|
193 | 193 | |
|
194 | 194 | def login_user(app, username=TEST_USER_ADMIN_LOGIN, |
@@ -99,13 +99,12 b' class TestPullrequestsController(object)' | |||
|
99 | 99 | in response) != pr_merge_enabled |
|
100 | 100 | |
|
101 | 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 | 102 | # Logout |
|
104 | 103 | response = self.app.post( |
|
105 |
|
|
|
104 | h.route_path('logout'), | |
|
106 | 105 | params={'csrf_token': csrf_token}) |
|
107 | 106 | # Login as regular user |
|
108 |
response = self.app.post( |
|
|
107 | response = self.app.post(h.route_path('login'), | |
|
109 | 108 | {'username': TEST_USER_REGULAR_LOGIN, |
|
110 | 109 | 'password': 'test12'}) |
|
111 | 110 |
@@ -410,7 +410,12 b' def add_test_routes(config):' | |||
|
410 | 410 | """ |
|
411 | 411 | Adds test routing that can be used in different functional tests |
|
412 | 412 | """ |
|
413 | from rhodecode.apps._base import ADMIN_PREFIX | |
|
414 | ||
|
413 | 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 | 419 | config.add_route(name='repo_summary', pattern='/{repo_name}') |
|
415 | 420 | config.add_route(name='repo_summary_explicit', pattern='/{repo_name}/summary') |
|
416 | 421 | config.add_route(name='repo_group_home', pattern='/{repo_group_name}') |
|
1 | NO CONTENT: file was removed |
General Comments 0
You need to be logged in to leave comments.
Login now