Mercurial > kallithea
comparison rhodecode/controllers/admin/user_groups.py @ 4116:ffd45b185016 rhodecode-2.2.5-gpl
Imported some of the GPLv3'd changes from RhodeCode v2.2.5.
This imports changes between changesets 21af6c4eab3d and 6177597791c2 in
RhodeCode's original repository, including only changes to Python files and HTML.
RhodeCode clearly licensed its changes to these files under GPLv3
in their /LICENSE file, which states the following:
The Python code and integrated HTML are licensed under the GPLv3 license.
(See:
https://code.rhodecode.com/rhodecode/files/v2.2.5/LICENSE
or
http://web.archive.org/web/20140512193334/https://code.rhodecode.com/rhodecode/files/f3b123159901f15426d18e3dc395e8369f70ebe0/LICENSE
for an online copy of that LICENSE file)
Conservancy reviewed these changes and confirmed that they can be licensed as
a whole to the Kallithea project under GPLv3-only.
While some of the contents committed herein are clearly licensed
GPLv3-or-later, on the whole we must assume the are GPLv3-only, since the
statement above from RhodeCode indicates that they intend GPLv3-only as their
license, per GPLv3ยง14 and other relevant sections of GPLv3.
author | Bradley M. Kuhn <bkuhn@sfconservancy.org> |
---|---|
date | Wed, 02 Jul 2014 19:03:13 -0400 |
parents | |
children | 7e5f8c12a3fc |
comparison
equal
deleted
inserted
replaced
4115:8b7294a804a0 | 4116:ffd45b185016 |
---|---|
1 # -*- coding: utf-8 -*- | |
2 # This program is free software: you can redistribute it and/or modify | |
3 # it under the terms of the GNU General Public License as published by | |
4 # the Free Software Foundation, either version 3 of the License, or | |
5 # (at your option) any later version. | |
6 # | |
7 # This program is distributed in the hope that it will be useful, | |
8 # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
9 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
10 # GNU General Public License for more details. | |
11 # | |
12 # You should have received a copy of the GNU General Public License | |
13 # along with this program. If not, see <http://www.gnu.org/licenses/>. | |
14 """ | |
15 rhodecode.controllers.admin.users_groups | |
16 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
17 | |
18 User Groups crud controller for pylons | |
19 | |
20 :created_on: Jan 25, 2011 | |
21 :author: marcink | |
22 :copyright: (c) 2013 RhodeCode GmbH. | |
23 :license: GPLv3, see LICENSE for more details. | |
24 """ | |
25 | |
26 import logging | |
27 import traceback | |
28 import formencode | |
29 | |
30 from formencode import htmlfill | |
31 from pylons import request, session, tmpl_context as c, url, config | |
32 from pylons.controllers.util import abort, redirect | |
33 from pylons.i18n.translation import _ | |
34 | |
35 from sqlalchemy.orm import joinedload | |
36 from sqlalchemy.sql.expression import func | |
37 from webob.exc import HTTPInternalServerError | |
38 | |
39 import rhodecode | |
40 from rhodecode.lib import helpers as h | |
41 from rhodecode.lib.exceptions import UserGroupsAssignedException,\ | |
42 RepoGroupAssignmentError | |
43 from rhodecode.lib.utils2 import safe_unicode, str2bool, safe_int | |
44 from rhodecode.lib.auth import LoginRequired, HasPermissionAllDecorator,\ | |
45 HasUserGroupPermissionAnyDecorator, HasPermissionAnyDecorator | |
46 from rhodecode.lib.base import BaseController, render | |
47 from rhodecode.model.scm import UserGroupList | |
48 from rhodecode.model.user_group import UserGroupModel | |
49 from rhodecode.model.repo import RepoModel | |
50 from rhodecode.model.db import User, UserGroup, UserGroupToPerm,\ | |
51 UserGroupRepoToPerm, UserGroupRepoGroupToPerm | |
52 from rhodecode.model.forms import UserGroupForm, UserGroupPermsForm,\ | |
53 CustomDefaultPermissionsForm | |
54 from rhodecode.model.meta import Session | |
55 from rhodecode.lib.utils import action_logger | |
56 from rhodecode.lib.compat import json | |
57 | |
58 log = logging.getLogger(__name__) | |
59 | |
60 | |
61 class UserGroupsController(BaseController): | |
62 """REST Controller styled on the Atom Publishing Protocol""" | |
63 | |
64 @LoginRequired() | |
65 def __before__(self): | |
66 super(UserGroupsController, self).__before__() | |
67 c.available_permissions = config['available_permissions'] | |
68 | |
69 def __load_data(self, user_group_id): | |
70 c.group_members_obj = sorted((x.user for x in c.user_group.members), | |
71 key=lambda u: u.username.lower()) | |
72 | |
73 c.group_members = [(x.user_id, x.username) for x in c.group_members_obj] | |
74 c.available_members = sorted(((x.user_id, x.username) for x in | |
75 User.query().all()), | |
76 key=lambda u: u[1].lower()) | |
77 | |
78 def __load_defaults(self, user_group_id): | |
79 """ | |
80 Load defaults settings for edit, and update | |
81 | |
82 :param user_group_id: | |
83 """ | |
84 user_group = UserGroup.get_or_404(user_group_id) | |
85 data = user_group.get_dict() | |
86 return data | |
87 | |
88 def index(self, format='html'): | |
89 """GET /users_groups: All items in the collection""" | |
90 # url('users_groups') | |
91 _list = UserGroup.query()\ | |
92 .order_by(func.lower(UserGroup.users_group_name))\ | |
93 .all() | |
94 group_iter = UserGroupList(_list, perm_set=['usergroup.admin']) | |
95 user_groups_data = [] | |
96 total_records = len(group_iter) | |
97 _tmpl_lookup = rhodecode.CONFIG['pylons.app_globals'].mako_lookup | |
98 template = _tmpl_lookup.get_template('data_table/_dt_elements.html') | |
99 | |
100 user_group_name = lambda user_group_id, user_group_name: ( | |
101 template.get_def("user_group_name") | |
102 .render(user_group_id, user_group_name, _=_, h=h, c=c) | |
103 ) | |
104 user_group_actions = lambda user_group_id, user_group_name: ( | |
105 template.get_def("user_group_actions") | |
106 .render(user_group_id, user_group_name, _=_, h=h, c=c) | |
107 ) | |
108 for user_gr in group_iter: | |
109 | |
110 user_groups_data.append({ | |
111 "raw_name": user_gr.users_group_name, | |
112 "group_name": user_group_name(user_gr.users_group_id, | |
113 user_gr.users_group_name), | |
114 "desc": user_gr.user_group_description, | |
115 "members": len(user_gr.members), | |
116 "active": h.boolicon(user_gr.users_group_active), | |
117 "owner": h.person(user_gr.user.username), | |
118 "action": user_group_actions(user_gr.users_group_id, user_gr.users_group_name) | |
119 }) | |
120 | |
121 c.data = json.dumps({ | |
122 "totalRecords": total_records, | |
123 "startIndex": 0, | |
124 "sort": None, | |
125 "dir": "asc", | |
126 "records": user_groups_data | |
127 }) | |
128 | |
129 return render('admin/user_groups/user_groups.html') | |
130 | |
131 @HasPermissionAnyDecorator('hg.admin', 'hg.usergroup.create.true') | |
132 def create(self): | |
133 """POST /users_groups: Create a new item""" | |
134 # url('users_groups') | |
135 | |
136 users_group_form = UserGroupForm()() | |
137 try: | |
138 form_result = users_group_form.to_python(dict(request.POST)) | |
139 UserGroupModel().create(name=form_result['users_group_name'], | |
140 description=form_result['user_group_description'], | |
141 owner=self.rhodecode_user.user_id, | |
142 active=form_result['users_group_active']) | |
143 | |
144 gr = form_result['users_group_name'] | |
145 action_logger(self.rhodecode_user, | |
146 'admin_created_users_group:%s' % gr, | |
147 None, self.ip_addr, self.sa) | |
148 h.flash(_('Created user group %s') % gr, category='success') | |
149 Session().commit() | |
150 except formencode.Invalid, errors: | |
151 return htmlfill.render( | |
152 render('admin/user_groups/user_group_add.html'), | |
153 defaults=errors.value, | |
154 errors=errors.error_dict or {}, | |
155 prefix_error=False, | |
156 encoding="UTF-8") | |
157 except Exception: | |
158 log.error(traceback.format_exc()) | |
159 h.flash(_('Error occurred during creation of user group %s') \ | |
160 % request.POST.get('users_group_name'), category='error') | |
161 | |
162 return redirect(url('users_groups')) | |
163 | |
164 @HasPermissionAnyDecorator('hg.admin', 'hg.usergroup.create.true') | |
165 def new(self, format='html'): | |
166 """GET /user_groups/new: Form to create a new item""" | |
167 # url('new_users_group') | |
168 return render('admin/user_groups/user_group_add.html') | |
169 | |
170 @HasUserGroupPermissionAnyDecorator('usergroup.admin') | |
171 def update(self, id): | |
172 """PUT /user_groups/id: Update an existing item""" | |
173 # Forms posted to this method should contain a hidden field: | |
174 # <input type="hidden" name="_method" value="PUT" /> | |
175 # Or using helpers: | |
176 # h.form(url('users_group', id=ID), | |
177 # method='put') | |
178 # url('users_group', id=ID) | |
179 | |
180 c.user_group = UserGroup.get_or_404(id) | |
181 c.active = 'settings' | |
182 self.__load_data(id) | |
183 | |
184 available_members = [safe_unicode(x[0]) for x in c.available_members] | |
185 | |
186 users_group_form = UserGroupForm(edit=True, | |
187 old_data=c.user_group.get_dict(), | |
188 available_members=available_members)() | |
189 | |
190 try: | |
191 form_result = users_group_form.to_python(request.POST) | |
192 UserGroupModel().update(c.user_group, form_result) | |
193 gr = form_result['users_group_name'] | |
194 action_logger(self.rhodecode_user, | |
195 'admin_updated_users_group:%s' % gr, | |
196 None, self.ip_addr, self.sa) | |
197 h.flash(_('Updated user group %s') % gr, category='success') | |
198 Session().commit() | |
199 except formencode.Invalid, errors: | |
200 ug_model = UserGroupModel() | |
201 defaults = errors.value | |
202 e = errors.error_dict or {} | |
203 defaults.update({ | |
204 'create_repo_perm': ug_model.has_perm(id, | |
205 'hg.create.repository'), | |
206 'fork_repo_perm': ug_model.has_perm(id, | |
207 'hg.fork.repository'), | |
208 '_method': 'put' | |
209 }) | |
210 | |
211 return htmlfill.render( | |
212 render('admin/user_groups/user_group_edit.html'), | |
213 defaults=defaults, | |
214 errors=e, | |
215 prefix_error=False, | |
216 encoding="UTF-8") | |
217 except Exception: | |
218 log.error(traceback.format_exc()) | |
219 h.flash(_('Error occurred during update of user group %s') \ | |
220 % request.POST.get('users_group_name'), category='error') | |
221 | |
222 return redirect(url('edit_users_group', id=id)) | |
223 | |
224 @HasUserGroupPermissionAnyDecorator('usergroup.admin') | |
225 def delete(self, id): | |
226 """DELETE /user_groups/id: Delete an existing item""" | |
227 # Forms posted to this method should contain a hidden field: | |
228 # <input type="hidden" name="_method" value="DELETE" /> | |
229 # Or using helpers: | |
230 # h.form(url('users_group', id=ID), | |
231 # method='delete') | |
232 # url('users_group', id=ID) | |
233 usr_gr = UserGroup.get_or_404(id) | |
234 try: | |
235 UserGroupModel().delete(usr_gr) | |
236 Session().commit() | |
237 h.flash(_('Successfully deleted user group'), category='success') | |
238 except UserGroupsAssignedException, e: | |
239 h.flash(e, category='error') | |
240 except Exception: | |
241 log.error(traceback.format_exc()) | |
242 h.flash(_('An error occurred during deletion of user group'), | |
243 category='error') | |
244 return redirect(url('users_groups')) | |
245 | |
246 def show(self, id, format='html'): | |
247 """GET /user_groups/id: Show a specific item""" | |
248 # url('users_group', id=ID) | |
249 | |
250 @HasUserGroupPermissionAnyDecorator('usergroup.admin') | |
251 def edit(self, id, format='html'): | |
252 """GET /user_groups/id/edit: Form to edit an existing item""" | |
253 # url('edit_users_group', id=ID) | |
254 | |
255 c.user_group = UserGroup.get_or_404(id) | |
256 c.active = 'settings' | |
257 self.__load_data(id) | |
258 | |
259 defaults = self.__load_defaults(id) | |
260 | |
261 return htmlfill.render( | |
262 render('admin/user_groups/user_group_edit.html'), | |
263 defaults=defaults, | |
264 encoding="UTF-8", | |
265 force_defaults=False | |
266 ) | |
267 | |
268 @HasUserGroupPermissionAnyDecorator('usergroup.admin') | |
269 def edit_perms(self, id): | |
270 c.user_group = UserGroup.get_or_404(id) | |
271 c.active = 'perms' | |
272 | |
273 repo_model = RepoModel() | |
274 c.users_array = repo_model.get_users_js() | |
275 c.user_groups_array = repo_model.get_user_groups_js() | |
276 | |
277 defaults = {} | |
278 # fill user group users | |
279 for p in c.user_group.user_user_group_to_perm: | |
280 defaults.update({'u_perm_%s' % p.user.username: | |
281 p.permission.permission_name}) | |
282 | |
283 for p in c.user_group.user_group_user_group_to_perm: | |
284 defaults.update({'g_perm_%s' % p.user_group.users_group_name: | |
285 p.permission.permission_name}) | |
286 | |
287 return htmlfill.render( | |
288 render('admin/user_groups/user_group_edit.html'), | |
289 defaults=defaults, | |
290 encoding="UTF-8", | |
291 force_defaults=False | |
292 ) | |
293 | |
294 @HasUserGroupPermissionAnyDecorator('usergroup.admin') | |
295 def update_perms(self, id): | |
296 """ | |
297 grant permission for given usergroup | |
298 | |
299 :param id: | |
300 """ | |
301 user_group = UserGroup.get_or_404(id) | |
302 form = UserGroupPermsForm()().to_python(request.POST) | |
303 | |
304 # set the permissions ! | |
305 try: | |
306 UserGroupModel()._update_permissions(user_group, form['perms_new'], | |
307 form['perms_updates']) | |
308 except RepoGroupAssignmentError: | |
309 h.flash(_('Target group cannot be the same'), category='error') | |
310 return redirect(url('edit_user_group_perms', id=id)) | |
311 #TODO: implement this | |
312 #action_logger(self.rhodecode_user, 'admin_changed_repo_permissions', | |
313 # repo_name, self.ip_addr, self.sa) | |
314 Session().commit() | |
315 h.flash(_('User Group permissions updated'), category='success') | |
316 return redirect(url('edit_user_group_perms', id=id)) | |
317 | |
318 @HasUserGroupPermissionAnyDecorator('usergroup.admin') | |
319 def delete_perms(self, id): | |
320 """ | |
321 DELETE an existing repository group permission user | |
322 | |
323 :param group_name: | |
324 """ | |
325 try: | |
326 obj_type = request.POST.get('obj_type') | |
327 obj_id = None | |
328 if obj_type == 'user': | |
329 obj_id = safe_int(request.POST.get('user_id')) | |
330 elif obj_type == 'user_group': | |
331 obj_id = safe_int(request.POST.get('user_group_id')) | |
332 | |
333 if not c.rhodecode_user.is_admin: | |
334 if obj_type == 'user' and c.rhodecode_user.user_id == obj_id: | |
335 msg = _('Cannot revoke permission for yourself as admin') | |
336 h.flash(msg, category='warning') | |
337 raise Exception('revoke admin permission on self') | |
338 if obj_type == 'user': | |
339 UserGroupModel().revoke_user_permission(user_group=id, | |
340 user=obj_id) | |
341 elif obj_type == 'user_group': | |
342 UserGroupModel().revoke_user_group_permission(target_user_group=id, | |
343 user_group=obj_id) | |
344 Session().commit() | |
345 except Exception: | |
346 log.error(traceback.format_exc()) | |
347 h.flash(_('An error occurred during revoking of permission'), | |
348 category='error') | |
349 raise HTTPInternalServerError() | |
350 | |
351 @HasUserGroupPermissionAnyDecorator('usergroup.admin') | |
352 def edit_default_perms(self, id): | |
353 c.user_group = UserGroup.get_or_404(id) | |
354 c.active = 'default_perms' | |
355 | |
356 permissions = { | |
357 'repositories': {}, | |
358 'repositories_groups': {} | |
359 } | |
360 ugroup_repo_perms = UserGroupRepoToPerm.query()\ | |
361 .options(joinedload(UserGroupRepoToPerm.permission))\ | |
362 .options(joinedload(UserGroupRepoToPerm.repository))\ | |
363 .filter(UserGroupRepoToPerm.users_group_id == id)\ | |
364 .all() | |
365 | |
366 for gr in ugroup_repo_perms: | |
367 permissions['repositories'][gr.repository.repo_name] \ | |
368 = gr.permission.permission_name | |
369 | |
370 ugroup_group_perms = UserGroupRepoGroupToPerm.query()\ | |
371 .options(joinedload(UserGroupRepoGroupToPerm.permission))\ | |
372 .options(joinedload(UserGroupRepoGroupToPerm.group))\ | |
373 .filter(UserGroupRepoGroupToPerm.users_group_id == id)\ | |
374 .all() | |
375 | |
376 for gr in ugroup_group_perms: | |
377 permissions['repositories_groups'][gr.group.group_name] \ | |
378 = gr.permission.permission_name | |
379 c.permissions = permissions | |
380 | |
381 ug_model = UserGroupModel() | |
382 | |
383 defaults = c.user_group.get_dict() | |
384 defaults.update({ | |
385 'create_repo_perm': ug_model.has_perm(c.user_group, | |
386 'hg.create.repository'), | |
387 'create_user_group_perm': ug_model.has_perm(c.user_group, | |
388 'hg.usergroup.create.true'), | |
389 'fork_repo_perm': ug_model.has_perm(c.user_group, | |
390 'hg.fork.repository'), | |
391 }) | |
392 | |
393 return htmlfill.render( | |
394 render('admin/user_groups/user_group_edit.html'), | |
395 defaults=defaults, | |
396 encoding="UTF-8", | |
397 force_defaults=False | |
398 ) | |
399 | |
400 @HasUserGroupPermissionAnyDecorator('usergroup.admin') | |
401 def update_default_perms(self, id): | |
402 """PUT /users_perm/id: Update an existing item""" | |
403 # url('users_group_perm', id=ID, method='put') | |
404 | |
405 user_group = UserGroup.get_or_404(id) | |
406 | |
407 try: | |
408 form = CustomDefaultPermissionsForm()() | |
409 form_result = form.to_python(request.POST) | |
410 | |
411 inherit_perms = form_result['inherit_default_permissions'] | |
412 user_group.inherit_default_permissions = inherit_perms | |
413 Session().add(user_group) | |
414 usergroup_model = UserGroupModel() | |
415 | |
416 defs = UserGroupToPerm.query()\ | |
417 .filter(UserGroupToPerm.users_group == user_group)\ | |
418 .all() | |
419 for ug in defs: | |
420 Session().delete(ug) | |
421 | |
422 if form_result['create_repo_perm']: | |
423 usergroup_model.grant_perm(id, 'hg.create.repository') | |
424 else: | |
425 usergroup_model.grant_perm(id, 'hg.create.none') | |
426 if form_result['create_user_group_perm']: | |
427 usergroup_model.grant_perm(id, 'hg.usergroup.create.true') | |
428 else: | |
429 usergroup_model.grant_perm(id, 'hg.usergroup.create.false') | |
430 if form_result['fork_repo_perm']: | |
431 usergroup_model.grant_perm(id, 'hg.fork.repository') | |
432 else: | |
433 usergroup_model.grant_perm(id, 'hg.fork.none') | |
434 | |
435 h.flash(_("Updated permissions"), category='success') | |
436 Session().commit() | |
437 except Exception: | |
438 log.error(traceback.format_exc()) | |
439 h.flash(_('An error occurred during permissions saving'), | |
440 category='error') | |
441 | |
442 return redirect(url('edit_user_group_default_perms', id=id)) | |
443 | |
444 @HasUserGroupPermissionAnyDecorator('usergroup.admin') | |
445 def edit_advanced(self, id): | |
446 c.user_group = UserGroup.get_or_404(id) | |
447 c.active = 'advanced' | |
448 c.group_members_obj = sorted((x.user for x in c.user_group.members), | |
449 key=lambda u: u.username.lower()) | |
450 return render('admin/user_groups/user_group_edit.html') | |
451 | |
452 | |
453 @HasUserGroupPermissionAnyDecorator('usergroup.admin') | |
454 def edit_members(self, id): | |
455 c.user_group = UserGroup.get_or_404(id) | |
456 c.active = 'members' | |
457 c.group_members_obj = sorted((x.user for x in c.user_group.members), | |
458 key=lambda u: u.username.lower()) | |
459 | |
460 c.group_members = [(x.user_id, x.username) for x in c.group_members_obj] | |
461 return render('admin/user_groups/user_group_edit.html') |