##// END OF EJS Templates
user-groups: rewrote the app to pyramid...
marcink -
r2068:71f5d13f default
parent child Browse files
Show More
@@ -0,0 +1,101 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
22 from rhodecode.apps.admin.navigation import NavigationRegistry
23 from rhodecode.config.routing import ADMIN_PREFIX
24 from rhodecode.lib.utils2 import str2bool
25
26
27 def admin_routes(config):
28 """
29 User groups /_admin prefixed routes
30 """
31
32 config.add_route(
33 name='user_group_members_data',
34 pattern='/user_groups/{user_group_id:\d+}/members',
35 user_group_route=True)
36
37 # user groups perms
38 config.add_route(
39 name='edit_user_group_perms_summary',
40 pattern='/user_groups/{user_group_id:\d+}/edit/permissions_summary',
41 user_group_route=True)
42 config.add_route(
43 name='edit_user_group_perms_summary_json',
44 pattern='/user_groups/{user_group_id:\d+}/edit/permissions_summary/json',
45 user_group_route=True)
46
47 # user groups edit
48 config.add_route(
49 name='edit_user_group',
50 pattern='/user_groups/{user_group_id:\d+}/edit',
51 user_group_route=True)
52
53 # user groups update
54 config.add_route(
55 name='user_groups_update',
56 pattern='/user_groups/{user_group_id:\d+}/update',
57 user_group_route=True)
58
59 config.add_route(
60 name='edit_user_group_global_perms',
61 pattern='/user_groups/{user_group_id:\d+}/edit/global_permissions',
62 user_group_route=True)
63
64 config.add_route(
65 name='edit_user_group_global_perms_update',
66 pattern='/user_groups/{user_group_id:\d+}/edit/global_permissions/update',
67 user_group_route=True)
68
69 config.add_route(
70 name='edit_user_group_perms',
71 pattern='/user_groups/{user_group_id:\d+}/edit/permissions',
72 user_group_route=True)
73
74 config.add_route(
75 name='edit_user_group_perms_update',
76 pattern='/user_groups/{user_group_id:\d+}/edit/permissions/update',
77 user_group_route=True)
78
79 config.add_route(
80 name='edit_user_group_advanced',
81 pattern='/user_groups/{user_group_id:\d+}/edit/advanced',
82 user_group_route=True)
83
84 config.add_route(
85 name='edit_user_group_advanced_sync',
86 pattern='/user_groups/{user_group_id:\d+}/edit/advanced/sync',
87 user_group_route=True)
88
89 # user groups delete
90 config.add_route(
91 name='user_groups_delete',
92 pattern='/user_groups/{user_group_id:\d+}/delete',
93 user_group_route=True)
94
95
96 def includeme(config):
97 # main admin routes
98 config.include(admin_routes, route_prefix=ADMIN_PREFIX)
99
100 # Scan module for configuration decorators.
101 config.scan('.views', ignore='.tests')
@@ -0,0 +1,19 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/\
This diff has been collapsed as it changes many lines, (529 lines changed) Show them Hide them
@@ -0,0 +1,529 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
23 import peppercorn
24 import formencode
25 import formencode.htmlfill
26 from pyramid.httpexceptions import HTTPFound
27 from pyramid.view import view_config
28 from pyramid.response import Response
29 from pyramid.renderers import render
30
31 from rhodecode.lib.exceptions import (
32 RepoGroupAssignmentError, UserGroupAssignedException)
33 from rhodecode.model.forms import (
34 UserGroupPermsForm, UserGroupForm, UserIndividualPermissionsForm,
35 UserPermissionsForm)
36 from rhodecode.model.permission import PermissionModel
37
38 from rhodecode.apps._base import UserGroupAppView
39 from rhodecode.lib.auth import (
40 LoginRequired, HasUserGroupPermissionAnyDecorator, CSRFRequired)
41 from rhodecode.lib import helpers as h, audit_logger
42 from rhodecode.lib.utils2 import str2bool
43 from rhodecode.model.db import (
44 joinedload, User, UserGroupRepoToPerm, UserGroupRepoGroupToPerm)
45 from rhodecode.model.meta import Session
46 from rhodecode.model.user_group import UserGroupModel
47
48 log = logging.getLogger(__name__)
49
50
51 class UserGroupsView(UserGroupAppView):
52
53 def load_default_context(self):
54 c = self._get_local_tmpl_context()
55
56 PermissionModel().set_global_permission_choices(
57 c, gettext_translator=self.request.translate)
58
59 self._register_global_c(c)
60 return c
61
62 def _get_perms_summary(self, user_group_id):
63 permissions = {
64 'repositories': {},
65 'repositories_groups': {},
66 }
67 ugroup_repo_perms = UserGroupRepoToPerm.query()\
68 .options(joinedload(UserGroupRepoToPerm.permission))\
69 .options(joinedload(UserGroupRepoToPerm.repository))\
70 .filter(UserGroupRepoToPerm.users_group_id == user_group_id)\
71 .all()
72
73 for gr in ugroup_repo_perms:
74 permissions['repositories'][gr.repository.repo_name] \
75 = gr.permission.permission_name
76
77 ugroup_group_perms = UserGroupRepoGroupToPerm.query()\
78 .options(joinedload(UserGroupRepoGroupToPerm.permission))\
79 .options(joinedload(UserGroupRepoGroupToPerm.group))\
80 .filter(UserGroupRepoGroupToPerm.users_group_id == user_group_id)\
81 .all()
82
83 for gr in ugroup_group_perms:
84 permissions['repositories_groups'][gr.group.group_name] \
85 = gr.permission.permission_name
86 return permissions
87
88 @LoginRequired()
89 @HasUserGroupPermissionAnyDecorator('usergroup.admin')
90 @view_config(
91 route_name='user_group_members_data', request_method='GET',
92 renderer='json_ext', xhr=True)
93 def user_group_members(self):
94 """
95 Return members of given user group
96 """
97 user_group = self.db_user_group
98 group_members_obj = sorted((x.user for x in user_group.members),
99 key=lambda u: u.username.lower())
100
101 group_members = [
102 {
103 'id': user.user_id,
104 'first_name': user.first_name,
105 'last_name': user.last_name,
106 'username': user.username,
107 'icon_link': h.gravatar_url(user.email, 30),
108 'value_display': h.person(user.email),
109 'value': user.username,
110 'value_type': 'user',
111 'active': user.active,
112 }
113 for user in group_members_obj
114 ]
115
116 return {
117 'members': group_members
118 }
119
120 @LoginRequired()
121 @HasUserGroupPermissionAnyDecorator('usergroup.admin')
122 @view_config(
123 route_name='edit_user_group_perms_summary', request_method='GET',
124 renderer='rhodecode:templates/admin/user_groups/user_group_edit.mako')
125 def user_group_perms_summary(self):
126 c = self.load_default_context()
127 c.user_group = self.db_user_group
128 c.active = 'perms_summary'
129 c.permissions = self._get_perms_summary(c.user_group.users_group_id)
130 return self._get_template_context(c)
131
132 @LoginRequired()
133 @HasUserGroupPermissionAnyDecorator('usergroup.admin')
134 @view_config(
135 route_name='edit_user_group_perms_summary_json', request_method='GET',
136 renderer='json_ext')
137 def user_group_perms_summary_json(self):
138 self.load_default_context()
139 user_group = self.db_user_group
140 return self._get_perms_summary(user_group.users_group_id)
141
142 def _revoke_perms_on_yourself(self, form_result):
143 _updates = filter(lambda u: self._rhodecode_user.user_id == int(u[0]),
144 form_result['perm_updates'])
145 _additions = filter(lambda u: self._rhodecode_user.user_id == int(u[0]),
146 form_result['perm_additions'])
147 _deletions = filter(lambda u: self._rhodecode_user.user_id == int(u[0]),
148 form_result['perm_deletions'])
149 admin_perm = 'usergroup.admin'
150 if _updates and _updates[0][1] != admin_perm or \
151 _additions and _additions[0][1] != admin_perm or \
152 _deletions and _deletions[0][1] != admin_perm:
153 return True
154 return False
155
156 @LoginRequired()
157 @HasUserGroupPermissionAnyDecorator('usergroup.admin')
158 @CSRFRequired()
159 @view_config(
160 route_name='user_groups_update', request_method='POST',
161 renderer='rhodecode:templates/admin/user_groups/user_group_edit.mako')
162 def user_group_update(self):
163 _ = self.request.translate
164
165 user_group = self.db_user_group
166 user_group_id = user_group.users_group_id
167
168 c = self.load_default_context()
169 c.user_group = user_group
170 c.group_members_obj = [x.user for x in c.user_group.members]
171 c.group_members_obj.sort(key=lambda u: u.username.lower())
172 c.group_members = [(x.user_id, x.username) for x in c.group_members_obj]
173 c.active = 'settings'
174
175 users_group_form = UserGroupForm(
176 edit=True, old_data=c.user_group.get_dict(), allow_disabled=True)()
177
178 old_values = c.user_group.get_api_data()
179 user_group_name = self.request.POST.get('users_group_name')
180 try:
181 form_result = users_group_form.to_python(self.request.POST)
182 pstruct = peppercorn.parse(self.request.POST.items())
183 form_result['users_group_members'] = pstruct['user_group_members']
184
185 user_group, added_members, removed_members = \
186 UserGroupModel().update(c.user_group, form_result)
187 updated_user_group = form_result['users_group_name']
188
189 audit_logger.store_web(
190 'user_group.edit', action_data={'old_data': old_values},
191 user=self._rhodecode_user)
192
193 # TODO(marcink): use added/removed to set user_group.edit.member.add
194
195 h.flash(_('Updated user group %s') % updated_user_group,
196 category='success')
197 Session().commit()
198 except formencode.Invalid as errors:
199 defaults = errors.value
200 e = errors.error_dict or {}
201
202 data = render(
203 'rhodecode:templates/admin/user_groups/user_group_edit.mako',
204 self._get_template_context(c), self.request)
205 html = formencode.htmlfill.render(
206 data,
207 defaults=defaults,
208 errors=e,
209 prefix_error=False,
210 encoding="UTF-8",
211 force_defaults=False
212 )
213 return Response(html)
214
215 except Exception:
216 log.exception("Exception during update of user group")
217 h.flash(_('Error occurred during update of user group %s')
218 % user_group_name, category='error')
219
220 raise HTTPFound(
221 h.route_path('edit_user_group', user_group_id=user_group_id))
222
223 @LoginRequired()
224 @HasUserGroupPermissionAnyDecorator('usergroup.admin')
225 @CSRFRequired()
226 @view_config(
227 route_name='user_groups_delete', request_method='POST',
228 renderer='rhodecode:templates/admin/user_groups/user_group_edit.mako')
229 def user_group_delete(self):
230 _ = self.request.translate
231 user_group = self.db_user_group
232
233 self.load_default_context()
234 force = str2bool(self.request.POST.get('force'))
235
236 old_values = user_group.get_api_data()
237 try:
238 UserGroupModel().delete(user_group, force=force)
239 audit_logger.store_web(
240 'user.delete', action_data={'old_data': old_values},
241 user=self._rhodecode_user)
242 Session().commit()
243 h.flash(_('Successfully deleted user group'), category='success')
244 except UserGroupAssignedException as e:
245 h.flash(str(e), category='error')
246 except Exception:
247 log.exception("Exception during deletion of user group")
248 h.flash(_('An error occurred during deletion of user group'),
249 category='error')
250 raise HTTPFound(h.route_path('user_groups'))
251
252 @LoginRequired()
253 @HasUserGroupPermissionAnyDecorator('usergroup.admin')
254 @view_config(
255 route_name='edit_user_group', request_method='GET',
256 renderer='rhodecode:templates/admin/user_groups/user_group_edit.mako')
257 def user_group_edit(self):
258 user_group = self.db_user_group
259
260 c = self.load_default_context()
261 c.user_group = user_group
262 c.group_members_obj = [x.user for x in c.user_group.members]
263 c.group_members_obj.sort(key=lambda u: u.username.lower())
264 c.group_members = [(x.user_id, x.username) for x in c.group_members_obj]
265
266 c.active = 'settings'
267
268 defaults = user_group.get_dict()
269 # fill owner
270 if user_group.user:
271 defaults.update({'user': user_group.user.username})
272 else:
273 replacement_user = User.get_first_super_admin().username
274 defaults.update({'user': replacement_user})
275
276 data = render(
277 'rhodecode:templates/admin/user_groups/user_group_edit.mako',
278 self._get_template_context(c), self.request)
279 html = formencode.htmlfill.render(
280 data,
281 defaults=defaults,
282 encoding="UTF-8",
283 force_defaults=False
284 )
285 return Response(html)
286
287 @LoginRequired()
288 @HasUserGroupPermissionAnyDecorator('usergroup.admin')
289 @view_config(
290 route_name='edit_user_group_perms', request_method='GET',
291 renderer='rhodecode:templates/admin/user_groups/user_group_edit.mako')
292 def user_group_edit_perms(self):
293 user_group = self.db_user_group
294 c = self.load_default_context()
295 c.user_group = user_group
296 c.active = 'perms'
297
298 defaults = {}
299 # fill user group users
300 for p in c.user_group.user_user_group_to_perm:
301 defaults.update({'u_perm_%s' % p.user.user_id:
302 p.permission.permission_name})
303
304 for p in c.user_group.user_group_user_group_to_perm:
305 defaults.update({'g_perm_%s' % p.user_group.users_group_id:
306 p.permission.permission_name})
307
308 data = render(
309 'rhodecode:templates/admin/user_groups/user_group_edit.mako',
310 self._get_template_context(c), self.request)
311 html = formencode.htmlfill.render(
312 data,
313 defaults=defaults,
314 encoding="UTF-8",
315 force_defaults=False
316 )
317 return Response(html)
318
319 @LoginRequired()
320 @HasUserGroupPermissionAnyDecorator('usergroup.admin')
321 @CSRFRequired()
322 @view_config(
323 route_name='edit_user_group_perms_update', request_method='POST',
324 renderer='rhodecode:templates/admin/user_groups/user_group_edit.mako')
325 def user_group_update_perms(self):
326 """
327 grant permission for given user group
328 """
329 _ = self.request.translate
330
331 user_group = self.db_user_group
332 user_group_id = user_group.users_group_id
333 c = self.load_default_context()
334 c.user_group = user_group
335 form = UserGroupPermsForm()().to_python(self.request.POST)
336
337 if not self._rhodecode_user.is_admin:
338 if self._revoke_perms_on_yourself(form):
339 msg = _('Cannot change permission for yourself as admin')
340 h.flash(msg, category='warning')
341 raise HTTPFound(
342 h.route_path('edit_user_group_perms',
343 user_group_id=user_group_id))
344
345 try:
346 changes = UserGroupModel().update_permissions(
347 user_group_id,
348 form['perm_additions'], form['perm_updates'],
349 form['perm_deletions'])
350
351 except RepoGroupAssignmentError:
352 h.flash(_('Target group cannot be the same'), category='error')
353 raise HTTPFound(
354 h.route_path('edit_user_group_perms',
355 user_group_id=user_group_id))
356
357 action_data = {
358 'added': changes['added'],
359 'updated': changes['updated'],
360 'deleted': changes['deleted'],
361 }
362 audit_logger.store_web(
363 'user_group.edit.permissions', action_data=action_data,
364 user=self._rhodecode_user)
365
366 Session().commit()
367 h.flash(_('User Group permissions updated'), category='success')
368 raise HTTPFound(
369 h.route_path('edit_user_group_perms', user_group_id=user_group_id))
370
371 @LoginRequired()
372 @HasUserGroupPermissionAnyDecorator('usergroup.admin')
373 @view_config(
374 route_name='edit_user_group_global_perms', request_method='GET',
375 renderer='rhodecode:templates/admin/user_groups/user_group_edit.mako')
376 def user_group_global_perms_edit(self):
377 user_group = self.db_user_group
378 c = self.load_default_context()
379 c.user_group = user_group
380 c.active = 'global_perms'
381
382 c.default_user = User.get_default_user()
383 defaults = c.user_group.get_dict()
384 defaults.update(c.default_user.get_default_perms(suffix='_inherited'))
385 defaults.update(c.user_group.get_default_perms())
386
387 data = render(
388 'rhodecode:templates/admin/user_groups/user_group_edit.mako',
389 self._get_template_context(c), self.request)
390 html = formencode.htmlfill.render(
391 data,
392 defaults=defaults,
393 encoding="UTF-8",
394 force_defaults=False
395 )
396 return Response(html)
397
398 @LoginRequired()
399 @HasUserGroupPermissionAnyDecorator('usergroup.admin')
400 @CSRFRequired()
401 @view_config(
402 route_name='edit_user_group_global_perms_update', request_method='POST',
403 renderer='rhodecode:templates/admin/user_groups/user_group_edit.mako')
404 def user_group_global_perms_update(self):
405 _ = self.request.translate
406 user_group = self.db_user_group
407 user_group_id = self.db_user_group.users_group_id
408
409 c = self.load_default_context()
410 c.user_group = user_group
411 c.active = 'global_perms'
412
413 try:
414 # first stage that verifies the checkbox
415 _form = UserIndividualPermissionsForm()
416 form_result = _form.to_python(dict(self.request.POST))
417 inherit_perms = form_result['inherit_default_permissions']
418 user_group.inherit_default_permissions = inherit_perms
419 Session().add(user_group)
420
421 if not inherit_perms:
422 # only update the individual ones if we un check the flag
423 _form = UserPermissionsForm(
424 [x[0] for x in c.repo_create_choices],
425 [x[0] for x in c.repo_create_on_write_choices],
426 [x[0] for x in c.repo_group_create_choices],
427 [x[0] for x in c.user_group_create_choices],
428 [x[0] for x in c.fork_choices],
429 [x[0] for x in c.inherit_default_permission_choices])()
430
431 form_result = _form.to_python(dict(self.request.POST))
432 form_result.update(
433 {'perm_user_group_id': user_group.users_group_id})
434
435 PermissionModel().update_user_group_permissions(form_result)
436
437 Session().commit()
438 h.flash(_('User Group global permissions updated successfully'),
439 category='success')
440
441 except formencode.Invalid as errors:
442 defaults = errors.value
443
444 data = render(
445 'rhodecode:templates/admin/user_groups/user_group_edit.mako',
446 self._get_template_context(c), self.request)
447 html = formencode.htmlfill.render(
448 data,
449 defaults=defaults,
450 errors=errors.error_dict or {},
451 prefix_error=False,
452 encoding="UTF-8",
453 force_defaults=False
454 )
455 return Response(html)
456 except Exception:
457 log.exception("Exception during permissions saving")
458 h.flash(_('An error occurred during permissions saving'),
459 category='error')
460
461 raise HTTPFound(
462 h.route_path('edit_user_group_global_perms',
463 user_group_id=user_group_id))
464
465 @LoginRequired()
466 @HasUserGroupPermissionAnyDecorator('usergroup.admin')
467 @view_config(
468 route_name='edit_user_group_advanced', request_method='GET',
469 renderer='rhodecode:templates/admin/user_groups/user_group_edit.mako')
470 def user_group_edit_advanced(self):
471 user_group = self.db_user_group
472
473 c = self.load_default_context()
474 c.user_group = user_group
475 c.active = 'advanced'
476 c.group_members_obj = sorted(
477 (x.user for x in c.user_group.members),
478 key=lambda u: u.username.lower())
479
480 c.group_to_repos = sorted(
481 (x.repository for x in c.user_group.users_group_repo_to_perm),
482 key=lambda u: u.repo_name.lower())
483
484 c.group_to_repo_groups = sorted(
485 (x.group for x in c.user_group.users_group_repo_group_to_perm),
486 key=lambda u: u.group_name.lower())
487
488 c.group_to_review_rules = sorted(
489 (x.users_group for x in c.user_group.user_group_review_rules),
490 key=lambda u: u.users_group_name.lower())
491
492 return self._get_template_context(c)
493
494 @LoginRequired()
495 @HasUserGroupPermissionAnyDecorator('usergroup.admin')
496 @CSRFRequired()
497 @view_config(
498 route_name='edit_user_group_advanced_sync', request_method='POST',
499 renderer='rhodecode:templates/admin/user_groups/user_group_edit.mako')
500 def user_group_edit_advanced_set_synchronization(self):
501 _ = self.request.translate
502 user_group = self.db_user_group
503 user_group_id = user_group.users_group_id
504
505 existing = user_group.group_data.get('extern_type')
506
507 if existing:
508 new_state = user_group.group_data
509 new_state['extern_type'] = None
510 else:
511 new_state = user_group.group_data
512 new_state['extern_type'] = 'manual'
513 new_state['extern_type_set_by'] = self._rhodecode_user.username
514
515 try:
516 user_group.group_data = new_state
517 Session().add(user_group)
518 Session().commit()
519
520 h.flash(_('User Group synchronization updated successfully'),
521 category='success')
522 except Exception:
523 log.exception("Exception during sync settings saving")
524 h.flash(_('An error occurred during synchronization update'),
525 category='error')
526
527 raise HTTPFound(
528 h.route_path('edit_user_group_advanced',
529 user_group_id=user_group_id))
@@ -29,6 +29,7 b' from rhodecode.lib.utils2 import StrictA'
29 from rhodecode.lib.vcs.exceptions import RepositoryRequirementError
29 from rhodecode.lib.vcs.exceptions import RepositoryRequirementError
30 from rhodecode.model import repo
30 from rhodecode.model import repo
31 from rhodecode.model import repo_group
31 from rhodecode.model import repo_group
32 from rhodecode.model import user_group
32 from rhodecode.model.db import User
33 from rhodecode.model.db import User
33 from rhodecode.model.scm import ScmModel
34 from rhodecode.model.scm import ScmModel
34
35
@@ -259,6 +260,13 b' class RepoGroupAppView(BaseAppView):'
259 self.db_repo_group_name = self.db_repo_group.group_name
260 self.db_repo_group_name = self.db_repo_group.group_name
260
261
261
262
263 class UserGroupAppView(BaseAppView):
264 def __init__(self, context, request):
265 super(UserGroupAppView, self).__init__(context, request)
266 self.db_user_group = request.db_user_group
267 self.db_user_group_name = self.db_user_group.users_group_name
268
269
262 class DataGridAppView(object):
270 class DataGridAppView(object):
263 """
271 """
264 Common class to have re-usable grid rendering components
272 Common class to have re-usable grid rendering components
@@ -462,6 +470,33 b' class RepoGroupRoutePredicate(object):'
462 return False
470 return False
463
471
464
472
473 class UserGroupRoutePredicate(object):
474 def __init__(self, val, config):
475 self.val = val
476
477 def text(self):
478 return 'user_group_route = %s' % self.val
479
480 phash = text
481
482 def __call__(self, info, request):
483 if hasattr(request, 'vcs_call'):
484 # skip vcs calls
485 return
486
487 user_group_id = info['match']['user_group_id']
488 user_group_model = user_group.UserGroup()
489 by_name_match = user_group_model.get(
490 user_group_id, cache=True)
491
492 if by_name_match:
493 # register this as request object we can re-use later
494 request.db_user_group = by_name_match
495 return True
496
497 return False
498
499
465 def includeme(config):
500 def includeme(config):
466 config.add_route_predicate(
501 config.add_route_predicate(
467 'repo_route', RepoRoutePredicate)
502 'repo_route', RepoRoutePredicate)
@@ -469,3 +504,5 b' def includeme(config):'
469 'repo_accepted_types', RepoTypeRoutePredicate)
504 'repo_accepted_types', RepoTypeRoutePredicate)
470 config.add_route_predicate(
505 config.add_route_predicate(
471 'repo_group_route', RepoGroupRoutePredicate)
506 'repo_group_route', RepoGroupRoutePredicate)
507 config.add_route_predicate(
508 'user_group_route', UserGroupRoutePredicate)
@@ -180,7 +180,7 b' def admin_routes(config):'
180 name='edit_user_perms_summary_json',
180 name='edit_user_perms_summary_json',
181 pattern='/users/{user_id:\d+}/edit/permissions_summary/json')
181 pattern='/users/{user_id:\d+}/edit/permissions_summary/json')
182
182
183 # user groups management
183 # user user groups management
184 config.add_route(
184 config.add_route(
185 name='edit_user_groups_management',
185 name='edit_user_groups_management',
186 pattern='/users/{user_id:\d+}/edit/groups_management')
186 pattern='/users/{user_id:\d+}/edit/groups_management')
@@ -194,7 +194,7 b' def admin_routes(config):'
194 name='edit_user_audit_logs',
194 name='edit_user_audit_logs',
195 pattern='/users/{user_id:\d+}/edit/audit')
195 pattern='/users/{user_id:\d+}/edit/audit')
196
196
197 # user groups admin
197 # user-groups admin
198 config.add_route(
198 config.add_route(
199 name='user_groups',
199 name='user_groups',
200 pattern='/user_groups')
200 pattern='/user_groups')
@@ -204,16 +204,12 b' def admin_routes(config):'
204 pattern='/user_groups_data')
204 pattern='/user_groups_data')
205
205
206 config.add_route(
206 config.add_route(
207 name='user_group_members_data',
207 name='user_groups_new',
208 pattern='/user_groups/{user_group_id:\d+}/members')
208 pattern='/user_groups/new')
209
209
210 # user groups perms
211 config.add_route(
210 config.add_route(
212 name='edit_user_group_perms_summary',
211 name='user_groups_create',
213 pattern='/user_groups/{user_group_id:\d+}/edit/permissions_summary')
212 pattern='/user_groups/create')
214 config.add_route(
215 name='edit_user_group_perms_summary_json',
216 pattern='/user_groups/{user_group_id:\d+}/edit/permissions_summary/json')
217
213
218 # repos admin
214 # repos admin
219 config.add_route(
215 config.add_route(
@@ -38,6 +38,9 b' def route_path(name, params=None, **kwar'
38 'user_groups': ADMIN_PREFIX + '/user_groups',
38 'user_groups': ADMIN_PREFIX + '/user_groups',
39 'user_groups_data': ADMIN_PREFIX + '/user_groups_data',
39 'user_groups_data': ADMIN_PREFIX + '/user_groups_data',
40 'user_group_members_data': ADMIN_PREFIX + '/user_groups/{user_group_id}/members',
40 'user_group_members_data': ADMIN_PREFIX + '/user_groups/{user_group_id}/members',
41 'user_groups_new': ADMIN_PREFIX + '/user_groups/new',
42 'user_groups_create': ADMIN_PREFIX + '/user_groups/create',
43 'edit_user_group': ADMIN_PREFIX + '/user_groups/{user_group_id}/edit',
41 }[name].format(**kwargs)
44 }[name].format(**kwargs)
42
45
43 if params:
46 if params:
@@ -107,7 +110,61 b' class TestAdminUserGroupsView(TestContro'
107 members = [u.user_id for u in User.get_all()]
110 members = [u.user_id for u in User.get_all()]
108 ug = user_util.create_user_group(members=members)
111 ug = user_util.create_user_group(members=members)
109 response = self.app.get(
112 response = self.app.get(
110 route_path('user_group_members_data', user_group_id=ug.users_group_id),
113 route_path('user_group_members_data',
114 user_group_id=ug.users_group_id),
111 extra_environ=xhr_header)
115 extra_environ=xhr_header)
112
116
113 assert len(response.json['members']) == len(members)
117 assert len(response.json['members']) == len(members)
118
119 def test_creation_page(self):
120 self.log_user()
121 self.app.get(route_path('user_groups_new'), status=200)
122
123 def test_create(self):
124 from rhodecode.lib import helpers as h
125
126 self.log_user()
127 users_group_name = 'test_user_group'
128 response = self.app.post(route_path('user_groups_create'), {
129 'users_group_name': users_group_name,
130 'user_group_description': 'DESC',
131 'active': True,
132 'csrf_token': self.csrf_token})
133
134 user_group_id = UserGroup.get_by_group_name(
135 users_group_name).users_group_id
136
137 user_group_link = h.link_to(
138 users_group_name,
139 route_path('edit_user_group', user_group_id=user_group_id))
140
141 assert_session_flash(
142 response,
143 'Created user group %s' % user_group_link)
144
145 fixture.destroy_user_group(users_group_name)
146
147 def test_create_with_empty_name(self):
148 self.log_user()
149
150 response = self.app.post(route_path('user_groups_create'), {
151 'users_group_name': '',
152 'user_group_description': 'DESC',
153 'active': True,
154 'csrf_token': self.csrf_token}, status=200)
155
156 response.mustcontain('Please enter a value')
157
158 def test_create_duplicate(self, user_util):
159 self.log_user()
160
161 user_group = user_util.create_user_group()
162 duplicate_name = user_group.users_group_name
163 response = self.app.post(route_path('user_groups_create'), {
164 'users_group_name': duplicate_name,
165 'user_group_description': 'DESC',
166 'active': True,
167 'csrf_token': self.csrf_token}, status=200)
168
169 response.mustcontain(
170 'User group `{}` already exists'.format(user_group.users_group_name))
@@ -20,22 +20,28 b''
20
20
21 import logging
21 import logging
22
22
23 import formencode
24 import formencode.htmlfill
25
23 from pyramid.httpexceptions import HTTPFound
26 from pyramid.httpexceptions import HTTPFound
24 from pyramid.view import view_config
27 from pyramid.view import view_config
25
28 from pyramid.response import Response
26 from rhodecode.model.scm import UserGroupList
29 from pyramid.renderers import render
27
30
28 from rhodecode.apps._base import BaseAppView, DataGridAppView
31 from rhodecode.apps._base import BaseAppView, DataGridAppView
29 from rhodecode.lib.auth import (
32 from rhodecode.lib.auth import (
30 LoginRequired, NotAnonymous,
33 LoginRequired, NotAnonymous, CSRFRequired, HasPermissionAnyDecorator)
31 HasUserGroupPermissionAnyDecorator)
34 from rhodecode.lib import helpers as h, audit_logger
32 from rhodecode.lib import helpers as h
33 from rhodecode.lib.utils import PartialRenderer
35 from rhodecode.lib.utils import PartialRenderer
34 from rhodecode.lib.utils2 import safe_unicode
36 from rhodecode.lib.utils2 import safe_unicode
37
38 from rhodecode.model.forms import UserGroupForm
39 from rhodecode.model.permission import PermissionModel
40 from rhodecode.model.scm import UserGroupList
35 from rhodecode.model.db import (
41 from rhodecode.model.db import (
36 joinedload, or_, count, User, UserGroup, UserGroupMember,
42 or_, count, User, UserGroup, UserGroupMember)
37 UserGroupRepoToPerm, UserGroupRepoGroupToPerm)
38 from rhodecode.model.meta import Session
43 from rhodecode.model.meta import Session
44 from rhodecode.model.user_group import UserGroupModel
39
45
40 log = logging.getLogger(__name__)
46 log = logging.getLogger(__name__)
41
47
@@ -44,6 +50,10 b' class AdminUserGroupsView(BaseAppView, D'
44
50
45 def load_default_context(self):
51 def load_default_context(self):
46 c = self._get_local_tmpl_context()
52 c = self._get_local_tmpl_context()
53
54 PermissionModel().set_global_permission_choices(
55 c, gettext_translator=self.request.translate)
56
47 self._register_global_c(c)
57 self._register_global_c(c)
48 return c
58 return c
49
59
@@ -168,89 +178,70 b' class AdminUserGroupsView(BaseAppView, D'
168 return data
178 return data
169
179
170 @LoginRequired()
180 @LoginRequired()
171 @HasUserGroupPermissionAnyDecorator('usergroup.admin')
181 @HasPermissionAnyDecorator('hg.admin', 'hg.usergroup.create.true')
172 @view_config(
182 @view_config(
173 route_name='user_group_members_data', request_method='GET',
183 route_name='user_groups_new', request_method='GET',
174 renderer='json_ext', xhr=True)
184 renderer='rhodecode:templates/admin/user_groups/user_group_add.mako')
175 def user_group_members(self):
185 def user_groups_new(self):
176 """
177 Return members of given user group
178 """
179 user_group_id = self.request.matchdict['user_group_id']
180 user_group = UserGroup.get_or_404(user_group_id)
181 group_members_obj = sorted((x.user for x in user_group.members),
182 key=lambda u: u.username.lower())
183
184 group_members = [
185 {
186 'id': user.user_id,
187 'first_name': user.first_name,
188 'last_name': user.last_name,
189 'username': user.username,
190 'icon_link': h.gravatar_url(user.email, 30),
191 'value_display': h.person(user.email),
192 'value': user.username,
193 'value_type': 'user',
194 'active': user.active,
195 }
196 for user in group_members_obj
197 ]
198
199 return {
200 'members': group_members
201 }
202
203 def _get_perms_summary(self, user_group_id):
204 permissions = {
205 'repositories': {},
206 'repositories_groups': {},
207 }
208 ugroup_repo_perms = UserGroupRepoToPerm.query()\
209 .options(joinedload(UserGroupRepoToPerm.permission))\
210 .options(joinedload(UserGroupRepoToPerm.repository))\
211 .filter(UserGroupRepoToPerm.users_group_id == user_group_id)\
212 .all()
213
214 for gr in ugroup_repo_perms:
215 permissions['repositories'][gr.repository.repo_name] \
216 = gr.permission.permission_name
217
218 ugroup_group_perms = UserGroupRepoGroupToPerm.query()\
219 .options(joinedload(UserGroupRepoGroupToPerm.permission))\
220 .options(joinedload(UserGroupRepoGroupToPerm.group))\
221 .filter(UserGroupRepoGroupToPerm.users_group_id == user_group_id)\
222 .all()
223
224 for gr in ugroup_group_perms:
225 permissions['repositories_groups'][gr.group.group_name] \
226 = gr.permission.permission_name
227 return permissions
228
229 @LoginRequired()
230 @HasUserGroupPermissionAnyDecorator('usergroup.admin')
231 @view_config(
232 route_name='edit_user_group_perms_summary', request_method='GET',
233 renderer='rhodecode:templates/admin/user_groups/user_group_edit.mako')
234 def user_group_perms_summary(self):
235 c = self.load_default_context()
186 c = self.load_default_context()
236
237 user_group_id = self.request.matchdict.get('user_group_id')
238 c.user_group = UserGroup.get_or_404(user_group_id)
239
240 c.active = 'perms_summary'
241
242 c.permissions = self._get_perms_summary(c.user_group.users_group_id)
243 return self._get_template_context(c)
187 return self._get_template_context(c)
244
188
245 @LoginRequired()
189 @LoginRequired()
246 @HasUserGroupPermissionAnyDecorator('usergroup.admin')
190 @HasPermissionAnyDecorator('hg.admin', 'hg.usergroup.create.true')
191 @CSRFRequired()
247 @view_config(
192 @view_config(
248 route_name='edit_user_group_perms_summary_json', request_method='GET',
193 route_name='user_groups_create', request_method='POST',
249 renderer='json_ext')
194 renderer='rhodecode:templates/admin/user_groups/user_group_add.mako')
250 def user_group_perms_summary_json(self):
195 def user_groups_create(self):
251 self.load_default_context()
196 _ = self.request.translate
197 c = self.load_default_context()
198 users_group_form = UserGroupForm()()
199
200 user_group_name = self.request.POST.get('users_group_name')
201 try:
202 form_result = users_group_form.to_python(dict(self.request.POST))
203 user_group = UserGroupModel().create(
204 name=form_result['users_group_name'],
205 description=form_result['user_group_description'],
206 owner=self._rhodecode_user.user_id,
207 active=form_result['users_group_active'])
208 Session().flush()
209 creation_data = user_group.get_api_data()
210 user_group_name = form_result['users_group_name']
211
212 audit_logger.store_web(
213 'user_group.create', action_data={'data': creation_data},
214 user=self._rhodecode_user)
252
215
253 user_group_id = self.request.matchdict.get('user_group_id')
216 user_group_link = h.link_to(
254 user_group = UserGroup.get_or_404(user_group_id)
217 h.escape(user_group_name),
218 h.route_path(
219 'edit_user_group', user_group_id=user_group.users_group_id))
220 h.flash(h.literal(_('Created user group %(user_group_link)s')
221 % {'user_group_link': user_group_link}),
222 category='success')
223 Session().commit()
224 user_group_id = user_group.users_group_id
225 except formencode.Invalid as errors:
255
226
256 return self._get_perms_summary(user_group.users_group_id)
227 data = render(
228 'rhodecode:templates/admin/user_groups/user_group_add.mako',
229 self._get_template_context(c), self.request)
230 html = formencode.htmlfill.render(
231 data,
232 defaults=errors.value,
233 errors=errors.error_dict or {},
234 prefix_error=False,
235 encoding="UTF-8",
236 force_defaults=False
237 )
238 return Response(html)
239
240 except Exception:
241 log.exception("Exception creating user group")
242 h.flash(_('Error occurred during creation of user group %s') \
243 % user_group_name, category='error')
244 raise HTTPFound(h.route_path('user_groups_new'))
245
246 raise HTTPFound(
247 h.route_path('edit_user_group', user_group_id=user_group_id))
@@ -21,98 +21,83 b''
21 import pytest
21 import pytest
22
22
23 from rhodecode.tests import (
23 from rhodecode.tests import (
24 TestController, url, assert_session_flash, link_to, TEST_USER_ADMIN_LOGIN)
24 TestController, assert_session_flash, TEST_USER_ADMIN_LOGIN)
25 from rhodecode.model.db import User, UserGroup
25 from rhodecode.model.db import UserGroup
26 from rhodecode.model.meta import Session
26 from rhodecode.model.meta import Session
27 from rhodecode.tests.fixture import Fixture
27 from rhodecode.tests.fixture import Fixture
28
28
29 TEST_USER_GROUP = 'admins_test'
30
31 fixture = Fixture()
29 fixture = Fixture()
32
30
33
31
34 class TestAdminUsersGroupsController(TestController):
32 def route_path(name, params=None, **kwargs):
35
33 import urllib
36 def test_create(self):
34 from rhodecode.apps._base import ADMIN_PREFIX
37 self.log_user()
38 users_group_name = TEST_USER_GROUP
39 response = self.app.post(url('users_groups'), {
40 'users_group_name': users_group_name,
41 'user_group_description': 'DESC',
42 'active': True,
43 'csrf_token': self.csrf_token})
44
35
45 user_group_link = link_to(
36 base_url = {
46 users_group_name,
37 'user_groups': ADMIN_PREFIX + '/user_groups',
47 url('edit_users_group',
38 'user_groups_data': ADMIN_PREFIX + '/user_groups_data',
48 user_group_id=UserGroup.get_by_group_name(
39 'user_group_members_data': ADMIN_PREFIX + '/user_groups/{user_group_id}/members',
49 users_group_name).users_group_id))
40 'user_groups_new': ADMIN_PREFIX + '/user_groups/new',
50 assert_session_flash(
41 'user_groups_create': ADMIN_PREFIX + '/user_groups/create',
51 response,
42 'edit_user_group': ADMIN_PREFIX + '/user_groups/{user_group_id}/edit',
52 'Created user group %s' % user_group_link)
43 'edit_user_group_advanced_sync': ADMIN_PREFIX + '/user_groups/{user_group_id}/edit/advanced/sync',
44 'edit_user_group_global_perms_update': ADMIN_PREFIX + '/user_groups/{user_group_id}/edit/global_permissions/update',
45 'user_groups_update': ADMIN_PREFIX + '/user_groups/{user_group_id}/update',
46 'user_groups_delete': ADMIN_PREFIX + '/user_groups/{user_group_id}/delete',
53
47
54 def test_set_synchronization(self):
48 }[name].format(**kwargs)
49
50 if params:
51 base_url = '{}?{}'.format(base_url, urllib.urlencode(params))
52 return base_url
53
54
55 class TestUserGroupsView(TestController):
56
57 def test_set_synchronization(self, user_util):
55 self.log_user()
58 self.log_user()
56 users_group_name = TEST_USER_GROUP + 'sync'
59 user_group_name = user_util.create_user_group().users_group_name
57 response = self.app.post(url('users_groups'), {
58 'users_group_name': users_group_name,
59 'user_group_description': 'DESC',
60 'active': True,
61 'csrf_token': self.csrf_token})
62
60
63 group = Session().query(UserGroup).filter(
61 group = Session().query(UserGroup).filter(
64 UserGroup.users_group_name == users_group_name).one()
62 UserGroup.users_group_name == user_group_name).one()
65
63
66 assert group.group_data.get('extern_type') is None
64 assert group.group_data.get('extern_type') is None
67
65
68 # enable
66 # enable
69 self.app.post(
67 self.app.post(
70 url('edit_user_group_advanced_sync', user_group_id=group.users_group_id),
68 route_path('edit_user_group_advanced_sync',
69 user_group_id=group.users_group_id),
71 params={'csrf_token': self.csrf_token}, status=302)
70 params={'csrf_token': self.csrf_token}, status=302)
72
71
73 group = Session().query(UserGroup).filter(
72 group = Session().query(UserGroup).filter(
74 UserGroup.users_group_name == users_group_name).one()
73 UserGroup.users_group_name == user_group_name).one()
75 assert group.group_data.get('extern_type') == 'manual'
74 assert group.group_data.get('extern_type') == 'manual'
76 assert group.group_data.get('extern_type_set_by') == TEST_USER_ADMIN_LOGIN
75 assert group.group_data.get('extern_type_set_by') == TEST_USER_ADMIN_LOGIN
77
76
78 # disable
77 # disable
79 self.app.post(
78 self.app.post(
80 url('edit_user_group_advanced_sync',
79 route_path('edit_user_group_advanced_sync',
81 user_group_id=group.users_group_id),
80 user_group_id=group.users_group_id),
82 params={'csrf_token': self.csrf_token}, status=302)
81 params={'csrf_token': self.csrf_token}, status=302)
83
82
84 group = Session().query(UserGroup).filter(
83 group = Session().query(UserGroup).filter(
85 UserGroup.users_group_name == users_group_name).one()
84 UserGroup.users_group_name == user_group_name).one()
86 assert group.group_data.get('extern_type') is None
85 assert group.group_data.get('extern_type') is None
87 assert group.group_data.get('extern_type_set_by') == TEST_USER_ADMIN_LOGIN
86 assert group.group_data.get('extern_type_set_by') == TEST_USER_ADMIN_LOGIN
88
87
89 def test_delete(self):
88 def test_delete_user_group(self, user_util):
90 self.log_user()
89 self.log_user()
91 users_group_name = TEST_USER_GROUP + 'another'
90 user_group_id = user_util.create_user_group().users_group_id
92 response = self.app.post(url('users_groups'), {
93 'users_group_name': users_group_name,
94 'user_group_description': 'DESC',
95 'active': True,
96 'csrf_token': self.csrf_token})
97
98 user_group_link = link_to(
99 users_group_name,
100 url('edit_users_group',
101 user_group_id=UserGroup.get_by_group_name(
102 users_group_name).users_group_id))
103 assert_session_flash(
104 response,
105 'Created user group %s' % user_group_link)
106
91
107 group = Session().query(UserGroup).filter(
92 group = Session().query(UserGroup).filter(
108 UserGroup.users_group_name == users_group_name).one()
93 UserGroup.users_group_id == user_group_id).one()
109
94
110 self.app.post(
95 self.app.post(
111 url('delete_users_group', user_group_id=group.users_group_id),
96 route_path('user_groups_delete', user_group_id=group.users_group_id),
112 params={'_method': 'delete', 'csrf_token': self.csrf_token})
97 params={'csrf_token': self.csrf_token})
113
98
114 group = Session().query(UserGroup).filter(
99 group = Session().query(UserGroup).filter(
115 UserGroup.users_group_name == users_group_name).scalar()
100 UserGroup.users_group_id == user_group_id).scalar()
116
101
117 assert group is None
102 assert group is None
118
103
@@ -122,26 +107,16 b' class TestAdminUsersGroupsController(Tes'
122 ('hg.create.XXX', 'hg.create.write_on_repogroup.true', 'hg.usergroup.create.true', 'hg.repogroup.create.true', 'hg.fork.repository', 'hg.inherit_default_perms.false', False, True),
107 ('hg.create.XXX', 'hg.create.write_on_repogroup.true', 'hg.usergroup.create.true', 'hg.repogroup.create.true', 'hg.fork.repository', 'hg.inherit_default_perms.false', False, True),
123 ('', '', '', '', '', '', True, False),
108 ('', '', '', '', '', '', True, False),
124 ])
109 ])
125 def test_global_perms_on_group(
110 def test_global_permissions_on_user_group(
126 self, repo_create, repo_create_write, user_group_create,
111 self, repo_create, repo_create_write, user_group_create,
127 repo_group_create, fork_create, expect_error, expect_form_error,
112 repo_group_create, fork_create, expect_error, expect_form_error,
128 inherit_default_permissions):
113 inherit_default_permissions, user_util):
129 self.log_user()
130 users_group_name = TEST_USER_GROUP + 'another2'
131 response = self.app.post(url('users_groups'),
132 {'users_group_name': users_group_name,
133 'user_group_description': 'DESC',
134 'active': True,
135 'csrf_token': self.csrf_token})
136
114
137 ug = UserGroup.get_by_group_name(users_group_name)
115 self.log_user()
138 user_group_link = link_to(
116 user_group = user_util.create_user_group()
139 users_group_name,
117
140 url('edit_users_group', user_group_id=ug.users_group_id))
118 user_group_name = user_group.users_group_name
141 assert_session_flash(
119 user_group_id = user_group.users_group_id
142 response,
143 'Created user group %s' % user_group_link)
144 response.follow()
145
120
146 # ENABLE REPO CREATE ON A GROUP
121 # ENABLE REPO CREATE ON A GROUP
147 perm_params = {
122 perm_params = {
@@ -153,12 +128,11 b' class TestAdminUsersGroupsController(Tes'
153 'default_fork_create': fork_create,
128 'default_fork_create': fork_create,
154 'default_inherit_default_permissions': inherit_default_permissions,
129 'default_inherit_default_permissions': inherit_default_permissions,
155
130
156 '_method': 'put',
157 'csrf_token': self.csrf_token,
131 'csrf_token': self.csrf_token,
158 }
132 }
159 response = self.app.post(
133 response = self.app.post(
160 url('edit_user_group_global_perms',
134 route_path('edit_user_group_global_perms_update',
161 user_group_id=ug.users_group_id),
135 user_group_id=user_group_id),
162 params=perm_params)
136 params=perm_params)
163
137
164 if expect_form_error:
138 if expect_form_error:
@@ -169,21 +143,76 b' class TestAdminUsersGroupsController(Tes'
169 msg = 'An error occurred during permissions saving'
143 msg = 'An error occurred during permissions saving'
170 else:
144 else:
171 msg = 'User Group global permissions updated successfully'
145 msg = 'User Group global permissions updated successfully'
172 ug = UserGroup.get_by_group_name(users_group_name)
146 ug = UserGroup.get_by_group_name(user_group_name)
173 del perm_params['_method']
174 del perm_params['csrf_token']
147 del perm_params['csrf_token']
175 del perm_params['inherit_default_permissions']
148 del perm_params['inherit_default_permissions']
176 assert perm_params == ug.get_default_perms()
149 assert perm_params == ug.get_default_perms()
177 assert_session_flash(response, msg)
150 assert_session_flash(response, msg)
178
151
179 fixture.destroy_user_group(users_group_name)
152 def test_edit_view(self, user_util):
180
181 def test_edit_autocomplete(self):
182 self.log_user()
153 self.log_user()
183 ug = fixture.create_user_group(TEST_USER_GROUP, skip_if_exists=True)
154
184 response = self.app.get(
155 user_group = user_util.create_user_group()
185 url('edit_users_group', user_group_id=ug.users_group_id))
156 self.app.get(
186 fixture.destroy_user_group(TEST_USER_GROUP)
157 route_path('edit_user_group',
158 user_group_id=user_group.users_group_id),
159 status=200)
160
161 def test_update_user_group(self, user_util):
162 user = self.log_user()
163
164 user_group = user_util.create_user_group()
165 users_group_id = user_group.users_group_id
166 new_name = user_group.users_group_name + '_CHANGE'
167
168 params = [
169 ('users_group_active', False),
170 ('user_group_description', 'DESC'),
171 ('users_group_name', new_name),
172 ('user', user['username']),
173 ('csrf_token', self.csrf_token),
174 ('__start__', 'user_group_members:sequence'),
175 ('__start__', 'member:mapping'),
176 ('member_user_id', user['user_id']),
177 ('type', 'existing'),
178 ('__end__', 'member:mapping'),
179 ('__end__', 'user_group_members:sequence'),
180 ]
181
182 self.app.post(
183 route_path('user_groups_update',
184 user_group_id=users_group_id),
185 params=params,
186 status=302)
187
188 user_group = UserGroup.get(users_group_id)
189 assert user_group
190
191 assert user_group.users_group_name == new_name
192 assert user_group.user_group_description == 'DESC'
193 assert user_group.users_group_active == False
194
195 def test_update_user_group_name_conflicts(self, user_util):
196 self.log_user()
197 user_group_old = user_util.create_user_group()
198 new_name = user_group_old.users_group_name
199
200 user_group = user_util.create_user_group()
201
202 params = dict(
203 users_group_active=False,
204 user_group_description='DESC',
205 users_group_name=new_name,
206 csrf_token=self.csrf_token)
207
208 response = self.app.post(
209 route_path('user_groups_update',
210 user_group_id=user_group.users_group_id),
211 params=params,
212 status=200)
213
214 response.mustcontain('User group `{}` already exists'.format(
215 new_name))
187
216
188 def test_update_members_from_user_ids(self, user_regular):
217 def test_update_members_from_user_ids(self, user_regular):
189 uid = user_regular.user_id
218 uid = user_regular.user_id
@@ -197,7 +226,6 b' class TestAdminUsersGroupsController(Tes'
197
226
198 form_data = [
227 form_data = [
199 ('csrf_token', self.csrf_token),
228 ('csrf_token', self.csrf_token),
200 ('_method', 'put'),
201 ('user', username),
229 ('user', username),
202 ('users_group_name', 'changed_name'),
230 ('users_group_name', 'changed_name'),
203 ('users_group_active', expected_active_state),
231 ('users_group_active', expected_active_state),
@@ -211,7 +239,8 b' class TestAdminUsersGroupsController(Tes'
211 ('__end__', 'user_group_members:sequence'),
239 ('__end__', 'user_group_members:sequence'),
212 ]
240 ]
213 ugid = user_group.users_group_id
241 ugid = user_group.users_group_id
214 self.app.post(url('update_users_group', user_group_id=ugid), form_data)
242 self.app.post(
243 route_path('user_groups_update', user_group_id=ugid), form_data)
215
244
216 user_group = UserGroup.get(ugid)
245 user_group = UserGroup.get(ugid)
217 assert user_group
246 assert user_group
@@ -296,6 +296,7 b' def includeme(config):'
296 config.include('rhodecode.apps.journal')
296 config.include('rhodecode.apps.journal')
297 config.include('rhodecode.apps.repository')
297 config.include('rhodecode.apps.repository')
298 config.include('rhodecode.apps.repo_group')
298 config.include('rhodecode.apps.repo_group')
299 config.include('rhodecode.apps.user_group')
299 config.include('rhodecode.apps.search')
300 config.include('rhodecode.apps.search')
300 config.include('rhodecode.apps.user_profile')
301 config.include('rhodecode.apps.user_profile')
301 config.include('rhodecode.apps.my_account')
302 config.include('rhodecode.apps.my_account')
@@ -254,44 +254,6 b' def make_map(config):'
254 m.connect('edit_user_global_perms', '/users/{user_id}/edit/global_permissions',
254 m.connect('edit_user_global_perms', '/users/{user_id}/edit/global_permissions',
255 action='update_global_perms', conditions={'method': ['PUT']})
255 action='update_global_perms', conditions={'method': ['PUT']})
256
256
257 # ADMIN USER GROUPS REST ROUTES
258 with rmap.submapper(path_prefix=ADMIN_PREFIX,
259 controller='admin/user_groups') as m:
260 m.connect('users_groups', '/user_groups',
261 action='create', conditions={'method': ['POST']})
262 m.connect('new_users_group', '/user_groups/new',
263 action='new', conditions={'method': ['GET']})
264 m.connect('update_users_group', '/user_groups/{user_group_id}',
265 action='update', conditions={'method': ['PUT']})
266 m.connect('delete_users_group', '/user_groups/{user_group_id}',
267 action='delete', conditions={'method': ['DELETE']})
268 m.connect('edit_users_group', '/user_groups/{user_group_id}/edit',
269 action='edit', conditions={'method': ['GET']},
270 function=check_user_group)
271
272 # EXTRAS USER GROUP ROUTES
273 m.connect('edit_user_group_global_perms',
274 '/user_groups/{user_group_id}/edit/global_permissions',
275 action='edit_global_perms', conditions={'method': ['GET']})
276 m.connect('edit_user_group_global_perms',
277 '/user_groups/{user_group_id}/edit/global_permissions',
278 action='update_global_perms', conditions={'method': ['PUT']})
279
280 m.connect('edit_user_group_perms',
281 '/user_groups/{user_group_id}/edit/permissions',
282 action='edit_perms', conditions={'method': ['GET']})
283 m.connect('edit_user_group_perms',
284 '/user_groups/{user_group_id}/edit/permissions',
285 action='update_perms', conditions={'method': ['PUT']})
286
287 m.connect('edit_user_group_advanced',
288 '/user_groups/{user_group_id}/edit/advanced',
289 action='edit_advanced', conditions={'method': ['GET']})
290
291 m.connect('edit_user_group_advanced_sync',
292 '/user_groups/{user_group_id}/edit/advanced/sync',
293 action='edit_advanced_set_synchronization', conditions={'method': ['POST']})
294
295 # ADMIN DEFAULTS REST ROUTES
257 # ADMIN DEFAULTS REST ROUTES
296 with rmap.submapper(path_prefix=ADMIN_PREFIX,
258 with rmap.submapper(path_prefix=ADMIN_PREFIX,
297 controller='admin/defaults') as m:
259 controller='admin/defaults') as m:
@@ -1305,7 +1305,7 b' def get_csrf_token(session=None, force_n'
1305 return session.get(csrf_token_key)
1305 return session.get(csrf_token_key)
1306
1306
1307
1307
1308 def get_request(perm_class):
1308 def get_request(perm_class_instance):
1309 from pyramid.threadlocal import get_current_request
1309 from pyramid.threadlocal import get_current_request
1310 pyramid_request = get_current_request()
1310 pyramid_request = get_current_request()
1311 if not pyramid_request:
1311 if not pyramid_request:
@@ -378,7 +378,6 b' class UserGroup(Base, BaseModel):'
378 "get_user_%s" % group_name))
378 "get_user_%s" % group_name))
379 return gr.scalar()
379 return gr.scalar()
380
380
381
382 @classmethod
381 @classmethod
383 def get(cls, users_group_id, cache=False):
382 def get(cls, users_group_id, cache=False):
384 users_group = cls.query()
383 users_group = cls.query()
@@ -390,13 +389,13 b' class UserGroup(Base, BaseModel):'
390 @classmethod
389 @classmethod
391 def create(cls, form_data):
390 def create(cls, form_data):
392 try:
391 try:
393 new_users_group = cls()
392 new_user_group = cls()
394 for k, v in form_data.items():
393 for k, v in form_data.items():
395 setattr(new_users_group, k, v)
394 setattr(new_user_group, k, v)
396
395
397 Session.add(new_users_group)
396 Session.add(new_user_group)
398 Session.commit()
397 Session.commit()
399 return new_users_group
398 return new_user_group
400 except:
399 except:
401 log.error(traceback.format_exc())
400 log.error(traceback.format_exc())
402 Session.rollback()
401 Session.rollback()
@@ -136,22 +136,29 b' def get_repo_group_slug(request):'
136
136
137
137
138 def get_user_group_slug(request):
138 def get_user_group_slug(request):
139 if isinstance(request, Request) and getattr(request, 'matchdict', None):
139 _user_group = ''
140 if isinstance(request, Request):
141
142 if hasattr(request, 'db_user_group'):
143 _user_group = request.db_user_group.users_group_name
144 elif getattr(request, 'matchdict', None):
140 # pyramid
145 # pyramid
141 _group = request.matchdict.get('user_group_id')
146 _user_group = request.matchdict.get('user_group_id')
142 else:
143 _group = request.environ['pylons.routes_dict'].get('user_group_id')
144
147
145 try:
148 try:
146 _group = UserGroup.get(_group)
149 _user_group = UserGroup.get(_user_group)
147 if _group:
150 if _user_group:
148 _group = _group.users_group_name
151 _user_group = _user_group.users_group_name
149 except Exception:
152 except Exception:
150 log.exception('Failed to get user group by id')
153 log.exception('Failed to get user group by id')
151 # catch all failures here
154 # catch all failures here
152 return None
155 return None
153
156
154 return _group
157 # TODO(marcink): remove after pylons migration...
158 if not _user_group:
159 _user_group = request.environ['pylons.routes_dict'].get('user_group_id')
160
161 return _user_group
155
162
156
163
157 def get_filesystem_repos(path, recursive=False, skip_removed_repos=True):
164 def get_filesystem_repos(path, recursive=False, skip_removed_repos=True):
@@ -68,7 +68,7 b' class RepositoryPermissionModel(BaseMode'
68 .filter(UserGroupRepoToPerm.repository == repository) \
68 .filter(UserGroupRepoToPerm.repository == repository) \
69 .scalar()
69 .scalar()
70
70
71 def update_users_group_permission(self, repository, users_group,
71 def update_user_group_permission(self, repository, users_group,
72 permission):
72 permission):
73 permission = Permission.get_by_key(permission)
73 permission = Permission.get_by_key(permission)
74 current = self.get_users_group_permission(repository, users_group)
74 current = self.get_users_group_permission(repository, users_group)
@@ -96,7 +96,7 b' class RepositoryPermissionModel(BaseMode'
96 def update_or_delete_users_group_permission(self, repository, user_group,
96 def update_or_delete_users_group_permission(self, repository, user_group,
97 permission):
97 permission):
98 if permission:
98 if permission:
99 self.update_users_group_permission(repository, user_group,
99 self.update_user_group_permission(repository, user_group,
100 permission)
100 permission)
101 else:
101 else:
102 self.delete_users_group_permission(repository, user_group)
102 self.delete_users_group_permission(repository, user_group)
@@ -18,12 +18,6 b''
18 # RhodeCode Enterprise Edition, including its added features, Support services,
18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
20
21
22 """
23 user group model for RhodeCode
24 """
25
26
27 import logging
21 import logging
28 import traceback
22 import traceback
29
23
@@ -67,8 +61,10 b' class UserGroupModel(BaseModel):'
67 user_group_to_perm.user_id = def_user.user_id
61 user_group_to_perm.user_id = def_user.user_id
68 return user_group_to_perm
62 return user_group_to_perm
69
63
70 def update_permissions(self, user_group, perm_additions=None, perm_updates=None,
64 def update_permissions(
65 self, user_group, perm_additions=None, perm_updates=None,
71 perm_deletions=None, check_perms=True, cur_user=None):
66 perm_deletions=None, check_perms=True, cur_user=None):
67
72 from rhodecode.lib.auth import HasUserGroupPermissionAny
68 from rhodecode.lib.auth import HasUserGroupPermissionAny
73 if not perm_additions:
69 if not perm_additions:
74 perm_additions = []
70 perm_additions = []
@@ -79,10 +75,16 b' class UserGroupModel(BaseModel):'
79
75
80 req_perms = ('usergroup.read', 'usergroup.write', 'usergroup.admin')
76 req_perms = ('usergroup.read', 'usergroup.write', 'usergroup.admin')
81
77
78 changes = {
79 'added': [],
80 'updated': [],
81 'deleted': []
82 }
82 # update permissions
83 # update permissions
83 for member_id, perm, member_type in perm_updates:
84 for member_id, perm, member_type in perm_updates:
84 member_id = int(member_id)
85 member_id = int(member_id)
85 if member_type == 'user':
86 if member_type == 'user':
87 member_name = User.get(member_id).username
86 # this updates existing one
88 # this updates existing one
87 self.grant_user_permission(
89 self.grant_user_permission(
88 user_group=user_group, user=member_id, perm=perm
90 user_group=user_group, user=member_id, perm=perm
@@ -90,38 +92,49 b' class UserGroupModel(BaseModel):'
90 else:
92 else:
91 # check if we have permissions to alter this usergroup
93 # check if we have permissions to alter this usergroup
92 member_name = UserGroup.get(member_id).users_group_name
94 member_name = UserGroup.get(member_id).users_group_name
93 if not check_perms or HasUserGroupPermissionAny(*req_perms)(member_name, user=cur_user):
95 if not check_perms or HasUserGroupPermissionAny(
96 *req_perms)(member_name, user=cur_user):
94 self.grant_user_group_permission(
97 self.grant_user_group_permission(
95 target_user_group=user_group, user_group=member_id, perm=perm
98 target_user_group=user_group, user_group=member_id, perm=perm)
96 )
99
100 changes['updated'].append({'type': member_type, 'id': member_id,
101 'name': member_name, 'new_perm': perm})
97
102
98 # set new permissions
103 # set new permissions
99 for member_id, perm, member_type in perm_additions:
104 for member_id, perm, member_type in perm_additions:
100 member_id = int(member_id)
105 member_id = int(member_id)
101 if member_type == 'user':
106 if member_type == 'user':
107 member_name = User.get(member_id).username
102 self.grant_user_permission(
108 self.grant_user_permission(
103 user_group=user_group, user=member_id, perm=perm
109 user_group=user_group, user=member_id, perm=perm)
104 )
105 else:
110 else:
106 # check if we have permissions to alter this usergroup
111 # check if we have permissions to alter this usergroup
107 member_name = UserGroup.get(member_id).users_group_name
112 member_name = UserGroup.get(member_id).users_group_name
108 if not check_perms or HasUserGroupPermissionAny(*req_perms)(member_name, user=cur_user):
113 if not check_perms or HasUserGroupPermissionAny(
114 *req_perms)(member_name, user=cur_user):
109 self.grant_user_group_permission(
115 self.grant_user_group_permission(
110 target_user_group=user_group, user_group=member_id, perm=perm
116 target_user_group=user_group, user_group=member_id, perm=perm)
111 )
117
118 changes['added'].append({'type': member_type, 'id': member_id,
119 'name': member_name, 'new_perm': perm})
112
120
113 # delete permissions
121 # delete permissions
114 for member_id, perm, member_type in perm_deletions:
122 for member_id, perm, member_type in perm_deletions:
115 member_id = int(member_id)
123 member_id = int(member_id)
116 if member_type == 'user':
124 if member_type == 'user':
125 member_name = User.get(member_id).username
117 self.revoke_user_permission(user_group=user_group, user=member_id)
126 self.revoke_user_permission(user_group=user_group, user=member_id)
118 else:
127 else:
119 # check if we have permissions to alter this usergroup
128 # check if we have permissions to alter this usergroup
120 member_name = UserGroup.get(member_id).users_group_name
129 member_name = UserGroup.get(member_id).users_group_name
121 if not check_perms or HasUserGroupPermissionAny(*req_perms)(member_name, user=cur_user):
130 if not check_perms or HasUserGroupPermissionAny(
131 *req_perms)(member_name, user=cur_user):
122 self.revoke_user_group_permission(
132 self.revoke_user_group_permission(
123 target_user_group=user_group, user_group=member_id
133 target_user_group=user_group, user_group=member_id)
124 )
134
135 changes['deleted'].append({'type': member_type, 'id': member_id,
136 'name': member_name, 'new_perm': perm})
137 return changes
125
138
126 def get(self, user_group_id, cache=False):
139 def get(self, user_group_id, cache=False):
127 return UserGroup.get(user_group_id)
140 return UserGroup.get(user_group_id)
@@ -247,6 +260,9 b' class UserGroupModel(BaseModel):'
247 :param force:
260 :param force:
248 """
261 """
249 user_group = self._get_user_group(user_group)
262 user_group = self._get_user_group(user_group)
263 if not user_group:
264 return
265
250 try:
266 try:
251 # check if this group is not assigned to repo
267 # check if this group is not assigned to repo
252 assigned_to_repo = [x.repository for x in UserGroupRepoToPerm.query()\
268 assigned_to_repo = [x.repository for x in UserGroupRepoToPerm.query()\
@@ -527,7 +543,6 b' class UserGroupModel(BaseModel):'
527 This method changes user group assignment
543 This method changes user group assignment
528 :param user: User
544 :param user: User
529 :param groups: array of UserGroupModel
545 :param groups: array of UserGroupModel
530 :return:
531 """
546 """
532 user = self._get_user(user)
547 user = self._get_user(user)
533 log.debug('Changing user(%s) assignment to groups(%s)', user, groups)
548 log.debug('Changing user(%s) assignment to groups(%s)', user, groups)
@@ -542,11 +557,14 b' class UserGroupModel(BaseModel):'
542 groups_to_add = groups - current_groups
557 groups_to_add = groups - current_groups
543
558
544 for gr in groups_to_remove:
559 for gr in groups_to_remove:
545 log.debug('Removing user %s from user group %s', user.username, gr.users_group_name)
560 log.debug('Removing user %s from user group %s',
561 user.username, gr.users_group_name)
546 self.remove_user_from_group(gr.users_group_name, user.username)
562 self.remove_user_from_group(gr.users_group_name, user.username)
547 for gr in groups_to_add:
563 for gr in groups_to_add:
548 log.debug('Adding user %s to user group %s', user.username, gr.users_group_name)
564 log.debug('Adding user %s to user group %s',
549 UserGroupModel().add_user_to_group(gr.users_group_name, user.username)
565 user.username, gr.users_group_name)
566 UserGroupModel().add_user_to_group(
567 gr.users_group_name, user.username)
550
568
551 def _serialize_user_group(self, user_group):
569 def _serialize_user_group(self, user_group):
552 import rhodecode.lib.helpers as h
570 import rhodecode.lib.helpers as h
@@ -617,7 +635,3 b' class UserGroupModel(BaseModel):'
617 'owner_icon': h.gravatar_url(user_group.user.email, 30)}
635 'owner_icon': h.gravatar_url(user_group.user.email, 30)}
618 }
636 }
619 return data
637 return data
620
621
622
623
@@ -221,7 +221,7 b' def ValidUserGroup(edit=False, old_data='
221 class _validator(formencode.validators.FancyValidator):
221 class _validator(formencode.validators.FancyValidator):
222 messages = {
222 messages = {
223 'invalid_group': _(u'Invalid user group name'),
223 'invalid_group': _(u'Invalid user group name'),
224 'group_exist': _(u'User group "%(usergroup)s" already exists'),
224 'group_exist': _(u'User group `%(usergroup)s` already exists'),
225 'invalid_usergroup_name':
225 'invalid_usergroup_name':
226 _(u'user group name may only contain alphanumeric '
226 _(u'user group name may only contain alphanumeric '
227 u'characters underscores, periods or dashes and must begin '
227 u'characters underscores, periods or dashes and must begin '
@@ -81,9 +81,8 b' function registerRCRoutes() {'
81 pyroutes.register('edit_user_audit_logs', '/_admin/users/%(user_id)s/edit/audit', ['user_id']);
81 pyroutes.register('edit_user_audit_logs', '/_admin/users/%(user_id)s/edit/audit', ['user_id']);
82 pyroutes.register('user_groups', '/_admin/user_groups', []);
82 pyroutes.register('user_groups', '/_admin/user_groups', []);
83 pyroutes.register('user_groups_data', '/_admin/user_groups_data', []);
83 pyroutes.register('user_groups_data', '/_admin/user_groups_data', []);
84 pyroutes.register('user_group_members_data', '/_admin/user_groups/%(user_group_id)s/members', ['user_group_id']);
84 pyroutes.register('user_groups_new', '/_admin/user_groups/new', []);
85 pyroutes.register('edit_user_group_perms_summary', '/_admin/user_groups/%(user_group_id)s/edit/permissions_summary', ['user_group_id']);
85 pyroutes.register('user_groups_create', '/_admin/user_groups/create', []);
86 pyroutes.register('edit_user_group_perms_summary_json', '/_admin/user_groups/%(user_group_id)s/edit/permissions_summary/json', ['user_group_id']);
87 pyroutes.register('repos', '/_admin/repos', []);
86 pyroutes.register('repos', '/_admin/repos', []);
88 pyroutes.register('repo_new', '/_admin/repos/new', []);
87 pyroutes.register('repo_new', '/_admin/repos/new', []);
89 pyroutes.register('repo_create', '/_admin/repos/create', []);
88 pyroutes.register('repo_create', '/_admin/repos/create', []);
@@ -210,6 +209,18 b' function registerRCRoutes() {'
210 pyroutes.register('repo_summary_slash', '/%(repo_name)s/', ['repo_name']);
209 pyroutes.register('repo_summary_slash', '/%(repo_name)s/', ['repo_name']);
211 pyroutes.register('repo_group_home', '/%(repo_group_name)s', ['repo_group_name']);
210 pyroutes.register('repo_group_home', '/%(repo_group_name)s', ['repo_group_name']);
212 pyroutes.register('repo_group_home_slash', '/%(repo_group_name)s/', ['repo_group_name']);
211 pyroutes.register('repo_group_home_slash', '/%(repo_group_name)s/', ['repo_group_name']);
212 pyroutes.register('user_group_members_data', '/_admin/user_groups/%(user_group_id)s/members', ['user_group_id']);
213 pyroutes.register('edit_user_group_perms_summary', '/_admin/user_groups/%(user_group_id)s/edit/permissions_summary', ['user_group_id']);
214 pyroutes.register('edit_user_group_perms_summary_json', '/_admin/user_groups/%(user_group_id)s/edit/permissions_summary/json', ['user_group_id']);
215 pyroutes.register('edit_user_group', '/_admin/user_groups/%(user_group_id)s/edit', ['user_group_id']);
216 pyroutes.register('user_groups_update', '/_admin/user_groups/%(user_group_id)s/update', ['user_group_id']);
217 pyroutes.register('edit_user_group_global_perms', '/_admin/user_groups/%(user_group_id)s/edit/global_permissions', ['user_group_id']);
218 pyroutes.register('edit_user_group_global_perms_update', '/_admin/user_groups/%(user_group_id)s/edit/global_permissions/update', ['user_group_id']);
219 pyroutes.register('edit_user_group_perms', '/_admin/user_groups/%(user_group_id)s/edit/permissions', ['user_group_id']);
220 pyroutes.register('edit_user_group_perms_update', '/_admin/user_groups/%(user_group_id)s/edit/permissions/update', ['user_group_id']);
221 pyroutes.register('edit_user_group_advanced', '/_admin/user_groups/%(user_group_id)s/edit/advanced', ['user_group_id']);
222 pyroutes.register('edit_user_group_advanced_sync', '/_admin/user_groups/%(user_group_id)s/edit/advanced/sync', ['user_group_id']);
223 pyroutes.register('user_groups_delete', '/_admin/user_groups/%(user_group_id)s/delete', ['user_group_id']);
213 pyroutes.register('search', '/_admin/search', []);
224 pyroutes.register('search', '/_admin/search', []);
214 pyroutes.register('search_repo', '/%(repo_name)s/search', ['repo_name']);
225 pyroutes.register('search_repo', '/%(repo_name)s/search', ['repo_name']);
215 pyroutes.register('user_profile', '/_profiles/%(username)s', ['username']);
226 pyroutes.register('user_profile', '/_profiles/%(username)s', ['username']);
@@ -96,7 +96,7 b''
96 <td class="td-componentname">
96 <td class="td-componentname">
97 <i class="icon-group" ></i>
97 <i class="icon-group" ></i>
98 %if h.HasPermissionAny('hg.admin')():
98 %if h.HasPermissionAny('hg.admin')():
99 <a href="${h.url('edit_users_group',user_group_id=_user_group.users_group_id)}">
99 <a href="${h.route_path('edit_user_group',user_group_id=_user_group.users_group_id)}">
100 ${_user_group.users_group_name}
100 ${_user_group.users_group_name}
101 </a>
101 </a>
102 %else:
102 %else:
@@ -85,7 +85,7 b''
85 <td class="td-componentname">
85 <td class="td-componentname">
86 <i class="icon-group" ></i>
86 <i class="icon-group" ></i>
87 %if h.HasPermissionAny('hg.admin')():
87 %if h.HasPermissionAny('hg.admin')():
88 <a href="${h.url('edit_users_group',user_group_id=_user_group.users_group_id)}">
88 <a href="${h.route_path('edit_user_group',user_group_id=_user_group.users_group_id)}">
89 ${_user_group.users_group_name}
89 ${_user_group.users_group_name}
90 </a>
90 </a>
91 %else:
91 %else:
@@ -10,7 +10,7 b''
10 <%def name="breadcrumbs_links()">
10 <%def name="breadcrumbs_links()">
11 ${h.link_to(_('Admin'),h.route_path('admin_home'))}
11 ${h.link_to(_('Admin'),h.route_path('admin_home'))}
12 &raquo;
12 &raquo;
13 ${h.link_to(_('User groups'),h.url('users_groups'))}
13 ${h.link_to(_('User groups'),h.route_path('user_groups'))}
14 &raquo;
14 &raquo;
15 ${_('Add User Group')}
15 ${_('Add User Group')}
16 </%def>
16 </%def>
@@ -26,7 +26,7 b''
26 ${self.breadcrumbs()}
26 ${self.breadcrumbs()}
27 </div>
27 </div>
28 <!-- end box / title -->
28 <!-- end box / title -->
29 ${h.secure_form(h.url('users_groups'))}
29 ${h.secure_form(h.route_path('user_groups_create'), method='POST', request=request)}
30 <div class="form">
30 <div class="form">
31 <!-- fields -->
31 <!-- fields -->
32 <div class="fields">
32 <div class="fields">
@@ -11,7 +11,7 b''
11 <%def name="breadcrumbs_links()">
11 <%def name="breadcrumbs_links()">
12 ${h.link_to(_('Admin'),h.route_path('admin_home'))}
12 ${h.link_to(_('Admin'),h.route_path('admin_home'))}
13 &raquo;
13 &raquo;
14 ${h.link_to(_('User Groups'),h.url('users_groups'))}
14 ${h.link_to(_('User Groups'),h.route_path('user_groups'))}
15 &raquo;
15 &raquo;
16 ${c.user_group.users_group_name}
16 ${c.user_group.users_group_name}
17 </%def>
17 </%def>
@@ -30,10 +30,10 b''
30 <div class="sidebar-col-wrapper">
30 <div class="sidebar-col-wrapper">
31 <div class="sidebar">
31 <div class="sidebar">
32 <ul class="nav nav-pills nav-stacked">
32 <ul class="nav nav-pills nav-stacked">
33 <li class="${'active' if c.active=='settings' else ''}"><a href="${h.url('edit_users_group', user_group_id=c.user_group.users_group_id)}">${_('Settings')}</a></li>
33 <li class="${'active' if c.active=='settings' else ''}"><a href="${h.route_path('edit_user_group', user_group_id=c.user_group.users_group_id)}">${_('Settings')}</a></li>
34 <li class="${'active' if c.active=='perms' else ''}"><a href="${h.url('edit_user_group_perms', user_group_id=c.user_group.users_group_id)}">${_('Permissions')}</a></li>
34 <li class="${'active' if c.active=='perms' else ''}"><a href="${h.route_path('edit_user_group_perms', user_group_id=c.user_group.users_group_id)}">${_('Permissions')}</a></li>
35 <li class="${'active' if c.active=='advanced' else ''}"><a href="${h.url('edit_user_group_advanced', user_group_id=c.user_group.users_group_id)}">${_('Advanced')}</a></li>
35 <li class="${'active' if c.active=='advanced' else ''}"><a href="${h.route_path('edit_user_group_advanced', user_group_id=c.user_group.users_group_id)}">${_('Advanced')}</a></li>
36 <li class="${'active' if c.active=='global_perms' else ''}"><a href="${h.url('edit_user_group_global_perms', user_group_id=c.user_group.users_group_id)}">${_('Global permissions')}</a></li>
36 <li class="${'active' if c.active=='global_perms' else ''}"><a href="${h.route_path('edit_user_group_global_perms', user_group_id=c.user_group.users_group_id)}">${_('Global permissions')}</a></li>
37 <li class="${'active' if c.active=='perms_summary' else ''}"><a href="${h.route_path('edit_user_group_perms_summary', user_group_id=c.user_group.users_group_id)}">${_('Permissions summary')}</a></li>
37 <li class="${'active' if c.active=='perms_summary' else ''}"><a href="${h.route_path('edit_user_group_perms_summary', user_group_id=c.user_group.users_group_id)}">${_('Permissions summary')}</a></li>
38 </ul>
38 </ul>
39 </div>
39 </div>
@@ -44,7 +44,7 b''
44 % endif
44 % endif
45
45
46 <div>
46 <div>
47 ${h.secure_form(h.url('edit_user_group_advanced_sync', user_group_id=c.user_group.users_group_id), method='post')}
47 ${h.secure_form(h.route_path('edit_user_group_advanced_sync', user_group_id=c.user_group.users_group_id), method='POST', request=request)}
48 <div class="field">
48 <div class="field">
49 <button class="btn btn-default" type="submit">
49 <button class="btn btn-default" type="submit">
50 %if sync_type:
50 %if sync_type:
@@ -72,7 +72,7 b''
72 <h3 class="panel-title">${_('Delete User Group')}</h3>
72 <h3 class="panel-title">${_('Delete User Group')}</h3>
73 </div>
73 </div>
74 <div class="panel-body">
74 <div class="panel-body">
75 ${h.secure_form(h.url('delete_users_group', user_group_id=c.user_group.users_group_id),method='delete')}
75 ${h.secure_form(h.route_path('user_groups_delete', user_group_id=c.user_group.users_group_id), method='POST', request=request)}
76 ${h.hidden('force', 1)}
76 ${h.hidden('force', 1)}
77 <button class="btn btn-small btn-danger" type="submit"
77 <button class="btn btn-small btn-danger" type="submit"
78 onclick="return confirm('${_('Confirm to delete user group `%(ugroup)s` with all permission assignments') % {'ugroup': c.user_group.users_group_name}}');">
78 onclick="return confirm('${_('Confirm to delete user group `%(ugroup)s` with all permission assignments') % {'ugroup': c.user_group.users_group_name}}');">
@@ -1,3 +1,3 b''
1 <%namespace name="dpb" file="/base/default_perms_box.mako"/>
1 <%namespace name="dpb" file="/base/default_perms_box.mako"/>
2 ${dpb.default_perms_box(h.url('edit_user_group_global_perms', user_group_id=c.user_group.users_group_id))}
2 ${dpb.default_perms_box(form_url=h.route_path('edit_user_group_global_perms_update', user_group_id=c.user_group.users_group_id))}
3
3
@@ -5,7 +5,7 b''
5 <h3 class="panel-title">${_('User Group Permissions')}</h3>
5 <h3 class="panel-title">${_('User Group Permissions')}</h3>
6 </div>
6 </div>
7 <div class="panel-body">
7 <div class="panel-body">
8 ${h.secure_form(h.url('edit_user_group_perms', user_group_id=c.user_group.users_group_id),method='put')}
8 ${h.secure_form(h.route_path('edit_user_group_perms_update', user_group_id=c.user_group.users_group_id), method='POST', request=request)}
9 <table id="permissions_manage" class="rctable permissions">
9 <table id="permissions_manage" class="rctable permissions">
10 <tr>
10 <tr>
11 <th class="td-radio">${_('None')}</th>
11 <th class="td-radio">${_('None')}</th>
@@ -96,7 +96,7 b''
96 <td class="td-user">
96 <td class="td-user">
97 <i class="icon-group" ></i>
97 <i class="icon-group" ></i>
98 %if h.HasPermissionAny('hg.admin')():
98 %if h.HasPermissionAny('hg.admin')():
99 <a href="${h.url('edit_users_group',user_group_id=_user_group.users_group_id)}">
99 <a href="${h.route_path('edit_user_group',user_group_id=_user_group.users_group_id)}">
100 ${_user_group.users_group_name}
100 ${_user_group.users_group_name}
101 </a>
101 </a>
102 %else:
102 %else:
@@ -6,7 +6,7 b''
6 <h3 class="panel-title">${_('User Group: %s') % c.user_group.users_group_name}</h3>
6 <h3 class="panel-title">${_('User Group: %s') % c.user_group.users_group_name}</h3>
7 </div>
7 </div>
8 <div class="panel-body">
8 <div class="panel-body">
9 ${h.secure_form(h.url('update_users_group', user_group_id=c.user_group.users_group_id),method='put', id='edit_users_group')}
9 ${h.secure_form(h.route_path('user_groups_update', user_group_id=c.user_group.users_group_id), id='edit_user_group', method='POST', request=request)}
10 <div class="form">
10 <div class="form">
11 <!-- fields -->
11 <!-- fields -->
12 <div class="fields">
12 <div class="fields">
@@ -25,7 +25,7 b''
25 <ul class="links">
25 <ul class="links">
26 %if h.HasPermissionAny('hg.admin', 'hg.usergroup.create.true')():
26 %if h.HasPermissionAny('hg.admin', 'hg.usergroup.create.true')():
27 <li>
27 <li>
28 <a href="${h.url('new_users_group')}" class="btn btn-small btn-success">${_(u'Add User Group')}</a>
28 <a href="${h.route_path('user_groups_new')}" class="btn btn-small btn-success">${_(u'Add User Group')}</a>
29 </li>
29 </li>
30 %endif
30 %endif
31 </ul>
31 </ul>
@@ -76,7 +76,7 b''
76 <li><a href="${h.route_path('repos')}">${_('Repositories')}</a></li>
76 <li><a href="${h.route_path('repos')}">${_('Repositories')}</a></li>
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.route_path('user_groups')}">${_('User groups')}</a></li>
80 <li><a href="${h.route_path('admin_permissions_application')}">${_('Permissions')}</a></li>
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>
@@ -151,7 +151,7 b''
151 <li class="local-admin-repo-groups"><a href="${h.url('repo_groups')}">${_('Repository groups')}</a></li>
151 <li class="local-admin-repo-groups"><a href="${h.url('repo_groups')}">${_('Repository groups')}</a></li>
152 %endif
152 %endif
153 %if user_groups:
153 %if user_groups:
154 <li class="local-admin-user-groups"><a href="${h.url('users_groups')}">${_('User groups')}</a></li>
154 <li class="local-admin-user-groups"><a href="${h.route_path('user_groups')}">${_('User groups')}</a></li>
155 %endif
155 %endif
156 </ul>
156 </ul>
157 </%def>
157 </%def>
@@ -94,7 +94,7 b''
94 </%def>
94 </%def>
95
95
96 <%def name="default_perms_box(form_url)">
96 <%def name="default_perms_box(form_url)">
97 ${h.secure_form(form_url, method='put')}
97 ${h.secure_form(form_url, method='POST', request=request)}
98 <div class="form">
98 <div class="form">
99 <div class="fields">
99 <div class="fields">
100 <div class="field panel panel-default panel-body">
100 <div class="field panel panel-default panel-body">
@@ -175,7 +175,7 b''
175 %elif section == 'repositories_groups':
175 %elif section == 'repositories_groups':
176 <a href="${h.route_path('repo_group_home', repo_group_name=k)}">${k}</a>
176 <a href="${h.route_path('repo_group_home', repo_group_name=k)}">${k}</a>
177 %elif section == 'user_groups':
177 %elif section == 'user_groups':
178 ##<a href="${h.url('edit_users_group',user_group_id=k)}">${k}</a>
178 ##<a href="${h.route_path('edit_user_group',user_group_id=k)}">${k}</a>
179 ${k}
179 ${k}
180 %endif
180 %endif
181 </td>
181 </td>
@@ -211,7 +211,7 b''
211 %elif section == 'repositories_groups':
211 %elif section == 'repositories_groups':
212 <a href="${h.url('edit_repo_group_perms',group_name=k,anchor='permissions_manage')}">${_('edit')}</a>
212 <a href="${h.url('edit_repo_group_perms',group_name=k,anchor='permissions_manage')}">${_('edit')}</a>
213 %elif section == 'user_groups':
213 %elif section == 'user_groups':
214 ##<a href="${h.url('edit_users_group',user_group_id=k)}">${_('edit')}</a>
214 ##<a href="${h.route_path('edit_user_group',user_group_id=k)}">${_('edit')}</a>
215 %endif
215 %endif
216 </td>
216 </td>
217 %endif
217 %endif
@@ -200,10 +200,10 b''
200
200
201 <%def name="user_group_actions(user_group_id, user_group_name)">
201 <%def name="user_group_actions(user_group_id, user_group_name)">
202 <div class="grid_edit">
202 <div class="grid_edit">
203 <a href="${h.url('edit_users_group', user_group_id=user_group_id)}" title="${_('Edit')}">Edit</a>
203 <a href="${h.route_path('edit_user_group', user_group_id=user_group_id)}" title="${_('Edit')}">Edit</a>
204 </div>
204 </div>
205 <div class="grid_delete">
205 <div class="grid_delete">
206 ${h.secure_form(h.url('delete_users_group', user_group_id=user_group_id),method='delete')}
206 ${h.secure_form(h.route_path('user_groups_delete', user_group_id=user_group_id), method='POST', request=request)}
207 ${h.submit('remove_',_('Delete'),id="remove_group_%s" % user_group_id, class_="btn btn-link btn-danger",
207 ${h.submit('remove_',_('Delete'),id="remove_group_%s" % user_group_id, class_="btn btn-link btn-danger",
208 onclick="return confirm('"+_('Confirm to delete this user group: %s') % user_group_name+"');")}
208 onclick="return confirm('"+_('Confirm to delete this user group: %s') % user_group_name+"');")}
209 ${h.end_form()}
209 ${h.end_form()}
@@ -221,7 +221,7 b''
221
221
222 <%def name="user_group_name(user_group_id, user_group_name)">
222 <%def name="user_group_name(user_group_id, user_group_name)">
223 <div>
223 <div>
224 <a href="${h.url('edit_users_group', user_group_id=user_group_id)}">
224 <a href="${h.route_path('edit_user_group', user_group_id=user_group_id)}">
225 <i class="icon-group" title="${_('User group')}"></i> ${user_group_name}</a>
225 <i class="icon-group" title="${_('User group')}"></i> ${user_group_name}</a>
226 </div>
226 </div>
227 </%def>
227 </%def>
@@ -260,12 +260,6 b''
260 </div>
260 </div>
261 </fieldset>
261 </fieldset>
262
262
263 <script>
264 $(document).ready(function(){
265 MultiSelectWidget('users_group_members2','available_members', 'edit_users_group');
266 })
267 </script>
268
269 <div class="buttons">
263 <div class="buttons">
270 <input type="submit" value="Save" id="example_save" class="btn">
264 <input type="submit" value="Save" id="example_save" class="btn">
271 <input type="reset" value="Reset" id="example_reset" class="btn">
265 <input type="reset" value="Reset" id="example_reset" class="btn">
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