##// END OF EJS Templates
added permission overview into users group
marcink -
r3861:c74eaaae beta
parent child Browse files
Show More
@@ -1,375 +1,379 b''
1 1 # -*- coding: utf-8 -*-
2 2 """
3 3 rhodecode.controllers.admin.users_groups
4 4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5 5
6 6 User Groups crud controller for pylons
7 7
8 8 :created_on: Jan 25, 2011
9 9 :author: marcink
10 10 :copyright: (C) 2010-2012 Marcin Kuzminski <marcin@python-works.com>
11 11 :license: GPLv3, see COPYING for more details.
12 12 """
13 13 # This program is free software: you can redistribute it and/or modify
14 14 # it under the terms of the GNU General Public License as published by
15 15 # the Free Software Foundation, either version 3 of the License, or
16 16 # (at your option) any later version.
17 17 #
18 18 # This program is distributed in the hope that it will be useful,
19 19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
20 20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 21 # GNU General Public License for more details.
22 22 #
23 23 # You should have received a copy of the GNU General Public License
24 24 # along with this program. If not, see <http://www.gnu.org/licenses/>.
25 25
26 26 import logging
27 27 import traceback
28 28 import formencode
29 29
30 30 from formencode import htmlfill
31 31 from pylons import request, session, tmpl_context as c, url, config
32 32 from pylons.controllers.util import abort, redirect
33 33 from pylons.i18n.translation import _
34 34
35 35 from rhodecode.lib import helpers as h
36 36 from rhodecode.lib.exceptions import UserGroupsAssignedException,\
37 37 RepoGroupAssignmentError
38 38 from rhodecode.lib.utils2 import safe_unicode, str2bool, safe_int
39 39 from rhodecode.lib.auth import LoginRequired, HasPermissionAllDecorator,\
40 40 HasUserGroupPermissionAnyDecorator, HasPermissionAnyDecorator
41 41 from rhodecode.lib.base import BaseController, render
42 42 from rhodecode.model.scm import UserGroupList
43 43 from rhodecode.model.users_group import UserGroupModel
44 44 from rhodecode.model.repo import RepoModel
45 45 from rhodecode.model.db import User, UserGroup, UserGroupToPerm,\
46 46 UserGroupRepoToPerm, UserGroupRepoGroupToPerm
47 47 from rhodecode.model.forms import UserGroupForm, UserGroupPermsForm,\
48 48 CustomDefaultPermissionsForm
49 49 from rhodecode.model.meta import Session
50 50 from rhodecode.lib.utils import action_logger
51 51 from sqlalchemy.orm import joinedload
52 52 from webob.exc import HTTPInternalServerError
53 53
54 54 log = logging.getLogger(__name__)
55 55
56 56
57 57 class UsersGroupsController(BaseController):
58 58 """REST Controller styled on the Atom Publishing Protocol"""
59 59 # To properly map this controller, ensure your config/routing.py
60 60 # file has a resource setup:
61 61 # map.resource('users_group', 'users_groups')
62 62
63 63 @LoginRequired()
64 64 def __before__(self):
65 65 super(UsersGroupsController, self).__before__()
66 66 c.available_permissions = config['available_permissions']
67 67
68 68 def __load_data(self, user_group_id):
69 permissions = {
70 'repositories': {},
71 'repositories_groups': {}
72 }
69 73 ugroup_repo_perms = UserGroupRepoToPerm.query()\
70 74 .options(joinedload(UserGroupRepoToPerm.permission))\
71 75 .options(joinedload(UserGroupRepoToPerm.repository))\
72 76 .filter(UserGroupRepoToPerm.users_group_id == user_group_id)\
73 77 .all()
74 78
75 79 for gr in ugroup_repo_perms:
76 c.users_group.permissions['repositories'][gr.repository.repo_name] \
80 permissions['repositories'][gr.repository.repo_name] \
77 81 = gr.permission.permission_name
78 82
79 83 ugroup_group_perms = UserGroupRepoGroupToPerm.query()\
80 84 .options(joinedload(UserGroupRepoGroupToPerm.permission))\
81 85 .options(joinedload(UserGroupRepoGroupToPerm.group))\
82 86 .filter(UserGroupRepoGroupToPerm.users_group_id == user_group_id)\
83 87 .all()
84 88
85 89 for gr in ugroup_group_perms:
86 c.users_group.permissions['repositories_groups'][gr.group.group_name] \
90 permissions['repositories_groups'][gr.group.group_name] \
87 91 = gr.permission.permission_name
88
92 c.permissions = permissions
89 93 c.group_members_obj = sorted((x.user for x in c.users_group.members),
90 94 key=lambda u: u.username.lower())
91 95
92 96 c.group_members = [(x.user_id, x.username) for x in c.group_members_obj]
93 97 c.available_members = sorted(((x.user_id, x.username) for x in
94 98 User.query().all()),
95 99 key=lambda u: u[1].lower())
96 100 repo_model = RepoModel()
97 101 c.users_array = repo_model.get_users_js()
98 102 c.users_groups_array = repo_model.get_users_groups_js()
99 103 c.available_permissions = config['available_permissions']
100 104
101 105 def __load_defaults(self, user_group_id):
102 106 """
103 107 Load defaults settings for edit, and update
104 108
105 109 :param user_group_id:
106 110 """
107 111 user_group = UserGroup.get_or_404(user_group_id)
108 112 data = user_group.get_dict()
109 113
110 114 ug_model = UserGroupModel()
111 115
112 116 data.update({
113 117 'create_repo_perm': ug_model.has_perm(user_group,
114 118 'hg.create.repository'),
115 119 'create_user_group_perm': ug_model.has_perm(user_group,
116 120 'hg.usergroup.create.true'),
117 121 'fork_repo_perm': ug_model.has_perm(user_group,
118 122 'hg.fork.repository'),
119 123 })
120 124
121 125 # fill user group users
122 126 for p in user_group.user_user_group_to_perm:
123 127 data.update({'u_perm_%s' % p.user.username:
124 128 p.permission.permission_name})
125 129
126 130 for p in user_group.user_group_user_group_to_perm:
127 131 data.update({'g_perm_%s' % p.user_group.users_group_name:
128 132 p.permission.permission_name})
129 133
130 134 return data
131 135
132 136 def index(self, format='html'):
133 137 """GET /users_groups: All items in the collection"""
134 138 # url('users_groups')
135 139
136 140 group_iter = UserGroupList(UserGroup().query().all(),
137 141 perm_set=['usergroup.admin'])
138 142 sk = lambda g: g.users_group_name
139 143 c.users_groups_list = sorted(group_iter, key=sk)
140 144 return render('admin/users_groups/users_groups.html')
141 145
142 146 @HasPermissionAnyDecorator('hg.admin', 'hg.usergroup.create.true')
143 147 def create(self):
144 148 """POST /users_groups: Create a new item"""
145 149 # url('users_groups')
146 150
147 151 users_group_form = UserGroupForm()()
148 152 try:
149 153 form_result = users_group_form.to_python(dict(request.POST))
150 154 UserGroupModel().create(name=form_result['users_group_name'],
151 155 owner=self.rhodecode_user.user_id,
152 156 active=form_result['users_group_active'])
153 157
154 158 gr = form_result['users_group_name']
155 159 action_logger(self.rhodecode_user,
156 160 'admin_created_users_group:%s' % gr,
157 161 None, self.ip_addr, self.sa)
158 162 h.flash(_('Created user group %s') % gr, category='success')
159 163 Session().commit()
160 164 except formencode.Invalid, errors:
161 165 return htmlfill.render(
162 166 render('admin/users_groups/users_group_add.html'),
163 167 defaults=errors.value,
164 168 errors=errors.error_dict or {},
165 169 prefix_error=False,
166 170 encoding="UTF-8")
167 171 except Exception:
168 172 log.error(traceback.format_exc())
169 173 h.flash(_('Error occurred during creation of user group %s') \
170 174 % request.POST.get('users_group_name'), category='error')
171 175
172 176 return redirect(url('users_groups'))
173 177
174 178 @HasPermissionAnyDecorator('hg.admin', 'hg.usergroup.create.true')
175 179 def new(self, format='html'):
176 180 """GET /users_groups/new: Form to create a new item"""
177 181 # url('new_users_group')
178 182 return render('admin/users_groups/users_group_add.html')
179 183
180 184 @HasUserGroupPermissionAnyDecorator('usergroup.admin')
181 185 def update(self, id):
182 186 """PUT /users_groups/id: Update an existing item"""
183 187 # Forms posted to this method should contain a hidden field:
184 188 # <input type="hidden" name="_method" value="PUT" />
185 189 # Or using helpers:
186 190 # h.form(url('users_group', id=ID),
187 191 # method='put')
188 192 # url('users_group', id=ID)
189 193
190 194 c.users_group = UserGroup.get_or_404(id)
191 195 self.__load_data(id)
192 196
193 197 available_members = [safe_unicode(x[0]) for x in c.available_members]
194 198
195 199 users_group_form = UserGroupForm(edit=True,
196 200 old_data=c.users_group.get_dict(),
197 201 available_members=available_members)()
198 202
199 203 try:
200 204 form_result = users_group_form.to_python(request.POST)
201 205 UserGroupModel().update(c.users_group, form_result)
202 206 gr = form_result['users_group_name']
203 207 action_logger(self.rhodecode_user,
204 208 'admin_updated_users_group:%s' % gr,
205 209 None, self.ip_addr, self.sa)
206 210 h.flash(_('Updated user group %s') % gr, category='success')
207 211 Session().commit()
208 212 except formencode.Invalid, errors:
209 213 ug_model = UserGroupModel()
210 214 defaults = errors.value
211 215 e = errors.error_dict or {}
212 216 defaults.update({
213 217 'create_repo_perm': ug_model.has_perm(id,
214 218 'hg.create.repository'),
215 219 'fork_repo_perm': ug_model.has_perm(id,
216 220 'hg.fork.repository'),
217 221 '_method': 'put'
218 222 })
219 223
220 224 return htmlfill.render(
221 225 render('admin/users_groups/users_group_edit.html'),
222 226 defaults=defaults,
223 227 errors=e,
224 228 prefix_error=False,
225 229 encoding="UTF-8")
226 230 except Exception:
227 231 log.error(traceback.format_exc())
228 232 h.flash(_('Error occurred during update of user group %s') \
229 233 % request.POST.get('users_group_name'), category='error')
230 234
231 235 return redirect(url('edit_users_group', id=id))
232 236
233 237 @HasUserGroupPermissionAnyDecorator('usergroup.admin')
234 238 def delete(self, id):
235 239 """DELETE /users_groups/id: Delete an existing item"""
236 240 # Forms posted to this method should contain a hidden field:
237 241 # <input type="hidden" name="_method" value="DELETE" />
238 242 # Or using helpers:
239 243 # h.form(url('users_group', id=ID),
240 244 # method='delete')
241 245 # url('users_group', id=ID)
242 246 usr_gr = UserGroup.get_or_404(id)
243 247 try:
244 248 UserGroupModel().delete(usr_gr)
245 249 Session().commit()
246 250 h.flash(_('Successfully deleted user group'), category='success')
247 251 except UserGroupsAssignedException, e:
248 252 h.flash(e, category='error')
249 253 except Exception:
250 254 log.error(traceback.format_exc())
251 255 h.flash(_('An error occurred during deletion of user group'),
252 256 category='error')
253 257 return redirect(url('users_groups'))
254 258
255 259 @HasUserGroupPermissionAnyDecorator('usergroup.admin')
256 260 def set_user_group_perm_member(self, id):
257 261 """
258 262 grant permission for given usergroup
259 263
260 264 :param id:
261 265 """
262 266 user_group = UserGroup.get_or_404(id)
263 267 form = UserGroupPermsForm()().to_python(request.POST)
264 268
265 269 # set the permissions !
266 270 try:
267 271 UserGroupModel()._update_permissions(user_group, form['perms_new'],
268 272 form['perms_updates'])
269 273 except RepoGroupAssignmentError:
270 274 h.flash(_('Target group cannot be the same'), category='error')
271 275 return redirect(url('edit_users_group', id=id))
272 276 #TODO: implement this
273 277 #action_logger(self.rhodecode_user, 'admin_changed_repo_permissions',
274 278 # repo_name, self.ip_addr, self.sa)
275 279 Session().commit()
276 280 h.flash(_('User Group permissions updated'), category='success')
277 281 return redirect(url('edit_users_group', id=id))
278 282
279 283 @HasUserGroupPermissionAnyDecorator('usergroup.admin')
280 284 def delete_user_group_perm_member(self, id):
281 285 """
282 286 DELETE an existing repository group permission user
283 287
284 288 :param group_name:
285 289 """
286 290 try:
287 291 obj_type = request.POST.get('obj_type')
288 292 obj_id = None
289 293 if obj_type == 'user':
290 294 obj_id = safe_int(request.POST.get('user_id'))
291 295 elif obj_type == 'user_group':
292 296 obj_id = safe_int(request.POST.get('user_group_id'))
293 297
294 298 if not c.rhodecode_user.is_admin:
295 299 if obj_type == 'user' and c.rhodecode_user.user_id == obj_id:
296 300 msg = _('Cannot revoke permission for yourself as admin')
297 301 h.flash(msg, category='warning')
298 302 raise Exception('revoke admin permission on self')
299 303 if obj_type == 'user':
300 304 UserGroupModel().revoke_user_permission(user_group=id,
301 305 user=obj_id)
302 306 elif obj_type == 'user_group':
303 307 UserGroupModel().revoke_users_group_permission(target_user_group=id,
304 308 user_group=obj_id)
305 309 Session().commit()
306 310 except Exception:
307 311 log.error(traceback.format_exc())
308 312 h.flash(_('An error occurred during revoking of permission'),
309 313 category='error')
310 314 raise HTTPInternalServerError()
311 315
312 316 def show(self, id, format='html'):
313 317 """GET /users_groups/id: Show a specific item"""
314 318 # url('users_group', id=ID)
315 319
316 320 @HasUserGroupPermissionAnyDecorator('usergroup.admin')
317 321 def edit(self, id, format='html'):
318 322 """GET /users_groups/id/edit: Form to edit an existing item"""
319 323 # url('edit_users_group', id=ID)
320 324
321 325 c.users_group = UserGroup.get_or_404(id)
322 326 self.__load_data(id)
323 327
324 328 defaults = self.__load_defaults(id)
325 329
326 330 return htmlfill.render(
327 331 render('admin/users_groups/users_group_edit.html'),
328 332 defaults=defaults,
329 333 encoding="UTF-8",
330 334 force_defaults=False
331 335 )
332 336
333 337 @HasUserGroupPermissionAnyDecorator('usergroup.admin')
334 338 def update_perm(self, id):
335 339 """PUT /users_perm/id: Update an existing item"""
336 340 # url('users_group_perm', id=ID, method='put')
337 341
338 342 users_group = UserGroup.get_or_404(id)
339 343
340 344 try:
341 345 form = CustomDefaultPermissionsForm()()
342 346 form_result = form.to_python(request.POST)
343 347
344 348 inherit_perms = form_result['inherit_default_permissions']
345 349 users_group.inherit_default_permissions = inherit_perms
346 350 Session().add(users_group)
347 351 usergroup_model = UserGroupModel()
348 352
349 353 defs = UserGroupToPerm.query()\
350 354 .filter(UserGroupToPerm.users_group == users_group)\
351 355 .all()
352 356 for ug in defs:
353 357 Session().delete(ug)
354 358
355 359 if form_result['create_repo_perm']:
356 360 usergroup_model.grant_perm(id, 'hg.create.repository')
357 361 else:
358 362 usergroup_model.grant_perm(id, 'hg.create.none')
359 363 if form_result['create_user_group_perm']:
360 364 usergroup_model.grant_perm(id, 'hg.usergroup.create.true')
361 365 else:
362 366 usergroup_model.grant_perm(id, 'hg.usergroup.create.false')
363 367 if form_result['fork_repo_perm']:
364 368 usergroup_model.grant_perm(id, 'hg.fork.repository')
365 369 else:
366 370 usergroup_model.grant_perm(id, 'hg.fork.none')
367 371
368 372 h.flash(_("Updated permissions"), category='success')
369 373 Session().commit()
370 374 except Exception:
371 375 log.error(traceback.format_exc())
372 376 h.flash(_('An error occurred during permissions saving'),
373 377 category='error')
374 378
375 379 return redirect(url('edit_users_group', id=id))
@@ -1,150 +1,154 b''
1 1 ## -*- coding: utf-8 -*-
2 2 <%inherit file="/base/base.html"/>
3 3
4 4 <%def name="title()">
5 5 ${_('Edit user group')} ${c.users_group.users_group_name} &middot; ${c.rhodecode_name}
6 6 </%def>
7 7
8 8 <%def name="breadcrumbs_links()">
9 9 ${h.link_to(_('Admin'),h.url('admin_home'))}
10 10 &raquo;
11 11 ${h.link_to(_('UserGroups'),h.url('users_groups'))}
12 12 &raquo;
13 13 ${_('Edit %s') % c.users_group.users_group_name}
14 14 </%def>
15 15
16 16 <%def name="page_nav()">
17 17 ${self.menu('admin')}
18 18 </%def>
19 19
20 20 <%def name="main()">
21 21 <div class="box box-left" style="clear:left">
22 22 <!-- box / title -->
23 23 <div class="title">
24 24 ${self.breadcrumbs()}
25 25 </div>
26 26 <!-- end box / title -->
27 27 ${h.form(url('users_group', id=c.users_group.users_group_id),method='put', id='edit_users_group')}
28 28 <div class="form">
29 29 <!-- fields -->
30 30 <div class="fields">
31 31 <div class="field">
32 32 <div class="label">
33 33 <label for="users_group_name">${_('Group name')}:</label>
34 34 </div>
35 35 <div class="input">
36 36 ${h.text('users_group_name',class_='small')}
37 37 </div>
38 38 </div>
39 39
40 40 <div class="field">
41 41 <div class="label label-checkbox">
42 42 <label for="users_group_active">${_('Active')}:</label>
43 43 </div>
44 44 <div class="checkboxes">
45 45 ${h.checkbox('users_group_active',value=True)}
46 46 </div>
47 47 </div>
48 48 <div class="field">
49 49 <div class="label">
50 50 <label for="users_group_active">${_('Members')}:</label>
51 51 </div>
52 52 <div class="select">
53 53 <table>
54 54 <tr>
55 55 <td>
56 56 <div>
57 57 <div style="float:left">
58 58 <div class="text" style="padding: 0px 0px 6px;">${_('Chosen group members')}</div>
59 59 ${h.select('users_group_members',[x[0] for x in c.group_members],c.group_members,multiple=True,size=8,style="min-width:210px")}
60 60 <div id="remove_all_elements" style="cursor:pointer;text-align:center">
61 61 ${_('Remove all elements')}
62 62 <img alt="remove" style="vertical-align:text-bottom" src="${h.url('/images/icons/arrow_right.png')}"/>
63 63 </div>
64 64 </div>
65 65 <div style="float:left;width:20px;padding-top:50px">
66 66 <img alt="add" id="add_element"
67 67 style="padding:2px;cursor:pointer"
68 68 src="${h.url('/images/icons/arrow_left.png')}"/>
69 69 <br />
70 70 <img alt="remove" id="remove_element"
71 71 style="padding:2px;cursor:pointer"
72 72 src="${h.url('/images/icons/arrow_right.png')}"/>
73 73 </div>
74 74 <div style="float:left">
75 75 <div class="text" style="padding: 0px 0px 6px;">${_('Available members')}</div>
76 76 ${h.select('available_members',[],c.available_members,multiple=True,size=8,style="min-width:210px")}
77 77 <div id="add_all_elements" style="cursor:pointer;text-align:center">
78 78 <img alt="add" style="vertical-align:text-bottom" src="${h.url('/images/icons/arrow_left.png')}"/>
79 79 ${_('Add all elements')}
80 80 </div>
81 81 </div>
82 82 </div>
83 83 </td>
84 84 </tr>
85 85 </table>
86 86 </div>
87 87
88 88 </div>
89 89 <div class="buttons">
90 90 ${h.submit('Save',_('Save'),class_="ui-btn large")}
91 91 </div>
92 92 </div>
93 93 </div>
94 94 ${h.end_form()}
95 95 <div class="group_members_wrap">
96 96 % if c.group_members_obj:
97 97 <ul class="group_members">
98 98 %for user in c.group_members_obj:
99 99 <li>
100 100 <div class="group_member">
101 101 <div class="gravatar"><img alt="gravatar" src="${h.gravatar_url(user.email,24)}"/> </div>
102 102 <div>${h.link_to(user.username, h.url('edit_user',id=user.user_id))}</div>
103 103 <div>${user.full_name}</div>
104 104 </div>
105 105 </li>
106 106 %endfor
107 107 </ul>
108 108 %else:
109 109 <span class="empty_data">${_('No members yet')}</span>
110 110 %endif
111 111 </div>
112 112 </div>
113 113
114 114 <div class="box box-right">
115 115 <!-- box / title -->
116 116 <div class="title">
117 117 <h5>${_('Global Permissions')}</h5>
118 118 </div>
119 119 <%namespace name="dpb" file="/base/default_perms_box.html"/>
120 120 ${dpb.default_perms_box(url('users_group_perm', id=c.users_group.users_group_id))}
121
122 ## permissions overview
123 <%namespace name="p" file="/base/perms_summary.html"/>
124 ${p.perms_summary(c.permissions)}
121 125 </div>
122 126
123 <div class="box box-right">
127 <div class="box box-right" style="clear:right">
124 128 <div class="title">
125 129 <h5>${_('Permissions')}</h5>
126 130 </div>
127 131 ${h.form(url('set_user_group_perm_member', id=c.users_group.users_group_id),method='post')}
128 132 <div class="form">
129 133 <div class="fields">
130 134 <div class="field">
131 135 <div class="label">
132 136 <label for="input">${_('Permissions')}:</label>
133 137 </div>
134 138 <div class="input">
135 139 <%include file="user_group_edit_perms.html"/>
136 140 </div>
137 141 </div>
138 142 <div class="buttons">
139 143 ${h.submit('save',_('Save'),class_="ui-btn large")}
140 144 ${h.reset('reset',_('Reset'),class_="ui-btn large")}
141 145 </div>
142 146 </div>
143 147 </div>
144 148 ${h.end_form()}
145 149 </div>
146 150
147 151 <script type="text/javascript">
148 152 MultiSelectWidget('users_group_members','available_members','edit_users_group');
149 153 </script>
150 154 </%def>
General Comments 0
You need to be logged in to leave comments. Login now