##// END OF EJS Templates
implemented usergroup permissions checks....
marcink -
r3737:46b17730 beta
parent child Browse files
Show More
@@ -1,368 +1,368 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """
2 """
3 rhodecode.controllers.admin.users_groups
3 rhodecode.controllers.admin.users_groups
4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5
5
6 User Groups crud controller for pylons
6 User Groups crud controller for pylons
7
7
8 :created_on: Jan 25, 2011
8 :created_on: Jan 25, 2011
9 :author: marcink
9 :author: marcink
10 :copyright: (C) 2010-2012 Marcin Kuzminski <marcin@python-works.com>
10 :copyright: (C) 2010-2012 Marcin Kuzminski <marcin@python-works.com>
11 :license: GPLv3, see COPYING for more details.
11 :license: GPLv3, see COPYING for more details.
12 """
12 """
13 # This program is free software: you can redistribute it and/or modify
13 # This program is free software: you can redistribute it and/or modify
14 # it under the terms of the GNU General Public License as published by
14 # it under the terms of the GNU General Public License as published by
15 # the Free Software Foundation, either version 3 of the License, or
15 # the Free Software Foundation, either version 3 of the License, or
16 # (at your option) any later version.
16 # (at your option) any later version.
17 #
17 #
18 # This program is distributed in the hope that it will be useful,
18 # This program is distributed in the hope that it will be useful,
19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 # GNU General Public License for more details.
21 # GNU General Public License for more details.
22 #
22 #
23 # You should have received a copy of the GNU General Public License
23 # You should have received a copy of the GNU General Public License
24 # along with this program. If not, see <http://www.gnu.org/licenses/>.
24 # along with this program. If not, see <http://www.gnu.org/licenses/>.
25
25
26 import logging
26 import logging
27 import traceback
27 import traceback
28 import formencode
28 import formencode
29
29
30 from formencode import htmlfill
30 from formencode import htmlfill
31 from pylons import request, session, tmpl_context as c, url, config
31 from pylons import request, session, tmpl_context as c, url, config
32 from pylons.controllers.util import abort, redirect
32 from pylons.controllers.util import abort, redirect
33 from pylons.i18n.translation import _
33 from pylons.i18n.translation import _
34
34
35 from rhodecode.lib import helpers as h
35 from rhodecode.lib import helpers as h
36 from rhodecode.lib.exceptions import UserGroupsAssignedException
36 from rhodecode.lib.exceptions import UserGroupsAssignedException
37 from rhodecode.lib.utils2 import safe_unicode, str2bool, safe_int
37 from rhodecode.lib.utils2 import safe_unicode, str2bool, safe_int
38 from rhodecode.lib.auth import LoginRequired, HasPermissionAllDecorator,\
38 from rhodecode.lib.auth import LoginRequired, HasPermissionAllDecorator,\
39 HasUserGroupPermissionAnyDecorator
39 HasUserGroupPermissionAnyDecorator, HasPermissionAnyDecorator
40 from rhodecode.lib.base import BaseController, render
40 from rhodecode.lib.base import BaseController, render
41 from rhodecode.model.scm import UserGroupList
41 from rhodecode.model.scm import UserGroupList
42 from rhodecode.model.users_group import UserGroupModel
42 from rhodecode.model.users_group import UserGroupModel
43 from rhodecode.model.repo import RepoModel
43 from rhodecode.model.repo import RepoModel
44 from rhodecode.model.db import User, UserGroup, UserGroupToPerm,\
44 from rhodecode.model.db import User, UserGroup, UserGroupToPerm,\
45 UserGroupRepoToPerm, UserGroupRepoGroupToPerm
45 UserGroupRepoToPerm, UserGroupRepoGroupToPerm
46 from rhodecode.model.forms import UserGroupForm, UserGroupPermsForm,\
46 from rhodecode.model.forms import UserGroupForm, UserGroupPermsForm,\
47 CustomDefaultPermissionsForm
47 CustomDefaultPermissionsForm
48 from rhodecode.model.meta import Session
48 from rhodecode.model.meta import Session
49 from rhodecode.lib.utils import action_logger
49 from rhodecode.lib.utils import action_logger
50 from sqlalchemy.orm import joinedload
50 from sqlalchemy.orm import joinedload
51 from webob.exc import HTTPInternalServerError
51 from webob.exc import HTTPInternalServerError
52
52
53 log = logging.getLogger(__name__)
53 log = logging.getLogger(__name__)
54
54
55
55
56 class UsersGroupsController(BaseController):
56 class UsersGroupsController(BaseController):
57 """REST Controller styled on the Atom Publishing Protocol"""
57 """REST Controller styled on the Atom Publishing Protocol"""
58 # To properly map this controller, ensure your config/routing.py
58 # To properly map this controller, ensure your config/routing.py
59 # file has a resource setup:
59 # file has a resource setup:
60 # map.resource('users_group', 'users_groups')
60 # map.resource('users_group', 'users_groups')
61
61
62 @LoginRequired()
62 @LoginRequired()
63 def __before__(self):
63 def __before__(self):
64 super(UsersGroupsController, self).__before__()
64 super(UsersGroupsController, self).__before__()
65 c.available_permissions = config['available_permissions']
65 c.available_permissions = config['available_permissions']
66
66
67 def __load_data(self, user_group_id):
67 def __load_data(self, user_group_id):
68 ugroup_repo_perms = UserGroupRepoToPerm.query()\
68 ugroup_repo_perms = UserGroupRepoToPerm.query()\
69 .options(joinedload(UserGroupRepoToPerm.permission))\
69 .options(joinedload(UserGroupRepoToPerm.permission))\
70 .options(joinedload(UserGroupRepoToPerm.repository))\
70 .options(joinedload(UserGroupRepoToPerm.repository))\
71 .filter(UserGroupRepoToPerm.users_group_id == user_group_id)\
71 .filter(UserGroupRepoToPerm.users_group_id == user_group_id)\
72 .all()
72 .all()
73
73
74 for gr in ugroup_repo_perms:
74 for gr in ugroup_repo_perms:
75 c.users_group.permissions['repositories'][gr.repository.repo_name] \
75 c.users_group.permissions['repositories'][gr.repository.repo_name] \
76 = gr.permission.permission_name
76 = gr.permission.permission_name
77
77
78 ugroup_group_perms = UserGroupRepoGroupToPerm.query()\
78 ugroup_group_perms = UserGroupRepoGroupToPerm.query()\
79 .options(joinedload(UserGroupRepoGroupToPerm.permission))\
79 .options(joinedload(UserGroupRepoGroupToPerm.permission))\
80 .options(joinedload(UserGroupRepoGroupToPerm.group))\
80 .options(joinedload(UserGroupRepoGroupToPerm.group))\
81 .filter(UserGroupRepoGroupToPerm.users_group_id == user_group_id)\
81 .filter(UserGroupRepoGroupToPerm.users_group_id == user_group_id)\
82 .all()
82 .all()
83
83
84 for gr in ugroup_group_perms:
84 for gr in ugroup_group_perms:
85 c.users_group.permissions['repositories_groups'][gr.group.group_name] \
85 c.users_group.permissions['repositories_groups'][gr.group.group_name] \
86 = gr.permission.permission_name
86 = gr.permission.permission_name
87
87
88 c.group_members_obj = sorted((x.user for x in c.users_group.members),
88 c.group_members_obj = sorted((x.user for x in c.users_group.members),
89 key=lambda u: u.username.lower())
89 key=lambda u: u.username.lower())
90
90
91 c.group_members = [(x.user_id, x.username) for x in c.group_members_obj]
91 c.group_members = [(x.user_id, x.username) for x in c.group_members_obj]
92 c.available_members = sorted(((x.user_id, x.username) for x in
92 c.available_members = sorted(((x.user_id, x.username) for x in
93 User.query().all()),
93 User.query().all()),
94 key=lambda u: u[1].lower())
94 key=lambda u: u[1].lower())
95 repo_model = RepoModel()
95 repo_model = RepoModel()
96 c.users_array = repo_model.get_users_js()
96 c.users_array = repo_model.get_users_js()
97
97
98 # commented out due to not now supporting assignment for user group
98 # commented out due to not now supporting assignment for user group
99 # on user group
99 # on user group
100 c.users_groups_array = "[]" # repo_model.get_users_groups_js()
100 c.users_groups_array = "[]" # repo_model.get_users_groups_js()
101 c.available_permissions = config['available_permissions']
101 c.available_permissions = config['available_permissions']
102
102
103 def __load_defaults(self, user_group_id):
103 def __load_defaults(self, user_group_id):
104 """
104 """
105 Load defaults settings for edit, and update
105 Load defaults settings for edit, and update
106
106
107 :param user_group_id:
107 :param user_group_id:
108 """
108 """
109 user_group = UserGroup.get_or_404(user_group_id)
109 user_group = UserGroup.get_or_404(user_group_id)
110 data = user_group.get_dict()
110 data = user_group.get_dict()
111
111
112 ug_model = UserGroupModel()
112 ug_model = UserGroupModel()
113
113
114 data.update({
114 data.update({
115 'create_repo_perm': ug_model.has_perm(user_group,
115 'create_repo_perm': ug_model.has_perm(user_group,
116 'hg.create.repository'),
116 'hg.create.repository'),
117 'create_user_group_perm': ug_model.has_perm(user_group,
117 'create_user_group_perm': ug_model.has_perm(user_group,
118 'hg.usergroup.create.true'),
118 'hg.usergroup.create.true'),
119 'fork_repo_perm': ug_model.has_perm(user_group,
119 'fork_repo_perm': ug_model.has_perm(user_group,
120 'hg.fork.repository'),
120 'hg.fork.repository'),
121 })
121 })
122
122
123 # fill user group users
123 # fill user group users
124 for p in user_group.user_user_group_to_perm:
124 for p in user_group.user_user_group_to_perm:
125 data.update({'u_perm_%s' % p.user.username:
125 data.update({'u_perm_%s' % p.user.username:
126 p.permission.permission_name})
126 p.permission.permission_name})
127
127
128 return data
128 return data
129
129
130 def index(self, format='html'):
130 def index(self, format='html'):
131 """GET /users_groups: All items in the collection"""
131 """GET /users_groups: All items in the collection"""
132 # url('users_groups')
132 # url('users_groups')
133
133
134 group_iter = UserGroupList(UserGroup().query().all(),
134 group_iter = UserGroupList(UserGroup().query().all(),
135 perm_set=['usergroup.admin'])
135 perm_set=['usergroup.admin'])
136 sk = lambda g: g.users_group_name
136 sk = lambda g: g.users_group_name
137 c.users_groups_list = sorted(group_iter, key=sk)
137 c.users_groups_list = sorted(group_iter, key=sk)
138 return render('admin/users_groups/users_groups.html')
138 return render('admin/users_groups/users_groups.html')
139
139
140 @HasPermissionAllDecorator('hg.admin')
140 @HasPermissionAnyDecorator('hg.admin', 'hg.usergroup.create.true')
141 def create(self):
141 def create(self):
142 """POST /users_groups: Create a new item"""
142 """POST /users_groups: Create a new item"""
143 # url('users_groups')
143 # url('users_groups')
144
144
145 users_group_form = UserGroupForm()()
145 users_group_form = UserGroupForm()()
146 try:
146 try:
147 form_result = users_group_form.to_python(dict(request.POST))
147 form_result = users_group_form.to_python(dict(request.POST))
148 UserGroupModel().create(name=form_result['users_group_name'],
148 UserGroupModel().create(name=form_result['users_group_name'],
149 owner=self.rhodecode_user.user_id,
149 owner=self.rhodecode_user.user_id,
150 active=form_result['users_group_active'])
150 active=form_result['users_group_active'])
151
151
152 gr = form_result['users_group_name']
152 gr = form_result['users_group_name']
153 action_logger(self.rhodecode_user,
153 action_logger(self.rhodecode_user,
154 'admin_created_users_group:%s' % gr,
154 'admin_created_users_group:%s' % gr,
155 None, self.ip_addr, self.sa)
155 None, self.ip_addr, self.sa)
156 h.flash(_('Created user group %s') % gr, category='success')
156 h.flash(_('Created user group %s') % gr, category='success')
157 Session().commit()
157 Session().commit()
158 except formencode.Invalid, errors:
158 except formencode.Invalid, errors:
159 return htmlfill.render(
159 return htmlfill.render(
160 render('admin/users_groups/users_group_add.html'),
160 render('admin/users_groups/users_group_add.html'),
161 defaults=errors.value,
161 defaults=errors.value,
162 errors=errors.error_dict or {},
162 errors=errors.error_dict or {},
163 prefix_error=False,
163 prefix_error=False,
164 encoding="UTF-8")
164 encoding="UTF-8")
165 except Exception:
165 except Exception:
166 log.error(traceback.format_exc())
166 log.error(traceback.format_exc())
167 h.flash(_('Error occurred during creation of user group %s') \
167 h.flash(_('Error occurred during creation of user group %s') \
168 % request.POST.get('users_group_name'), category='error')
168 % request.POST.get('users_group_name'), category='error')
169
169
170 return redirect(url('users_groups'))
170 return redirect(url('users_groups'))
171
171
172 @HasPermissionAllDecorator('hg.admin')
172 @HasPermissionAnyDecorator('hg.admin', 'hg.usergroup.create.true')
173 def new(self, format='html'):
173 def new(self, format='html'):
174 """GET /users_groups/new: Form to create a new item"""
174 """GET /users_groups/new: Form to create a new item"""
175 # url('new_users_group')
175 # url('new_users_group')
176 return render('admin/users_groups/users_group_add.html')
176 return render('admin/users_groups/users_group_add.html')
177
177
178 @HasUserGroupPermissionAnyDecorator('usergroup.admin')
178 @HasUserGroupPermissionAnyDecorator('usergroup.admin')
179 def update(self, id):
179 def update(self, id):
180 """PUT /users_groups/id: Update an existing item"""
180 """PUT /users_groups/id: Update an existing item"""
181 # Forms posted to this method should contain a hidden field:
181 # Forms posted to this method should contain a hidden field:
182 # <input type="hidden" name="_method" value="PUT" />
182 # <input type="hidden" name="_method" value="PUT" />
183 # Or using helpers:
183 # Or using helpers:
184 # h.form(url('users_group', id=ID),
184 # h.form(url('users_group', id=ID),
185 # method='put')
185 # method='put')
186 # url('users_group', id=ID)
186 # url('users_group', id=ID)
187
187
188 c.users_group = UserGroup.get_or_404(id)
188 c.users_group = UserGroup.get_or_404(id)
189 self.__load_data(id)
189 self.__load_data(id)
190
190
191 available_members = [safe_unicode(x[0]) for x in c.available_members]
191 available_members = [safe_unicode(x[0]) for x in c.available_members]
192
192
193 users_group_form = UserGroupForm(edit=True,
193 users_group_form = UserGroupForm(edit=True,
194 old_data=c.users_group.get_dict(),
194 old_data=c.users_group.get_dict(),
195 available_members=available_members)()
195 available_members=available_members)()
196
196
197 try:
197 try:
198 form_result = users_group_form.to_python(request.POST)
198 form_result = users_group_form.to_python(request.POST)
199 UserGroupModel().update(c.users_group, form_result)
199 UserGroupModel().update(c.users_group, form_result)
200 gr = form_result['users_group_name']
200 gr = form_result['users_group_name']
201 action_logger(self.rhodecode_user,
201 action_logger(self.rhodecode_user,
202 'admin_updated_users_group:%s' % gr,
202 'admin_updated_users_group:%s' % gr,
203 None, self.ip_addr, self.sa)
203 None, self.ip_addr, self.sa)
204 h.flash(_('Updated user group %s') % gr, category='success')
204 h.flash(_('Updated user group %s') % gr, category='success')
205 Session().commit()
205 Session().commit()
206 except formencode.Invalid, errors:
206 except formencode.Invalid, errors:
207 ug_model = UserGroupModel()
207 ug_model = UserGroupModel()
208 defaults = errors.value
208 defaults = errors.value
209 e = errors.error_dict or {}
209 e = errors.error_dict or {}
210 defaults.update({
210 defaults.update({
211 'create_repo_perm': ug_model.has_perm(id,
211 'create_repo_perm': ug_model.has_perm(id,
212 'hg.create.repository'),
212 'hg.create.repository'),
213 'fork_repo_perm': ug_model.has_perm(id,
213 'fork_repo_perm': ug_model.has_perm(id,
214 'hg.fork.repository'),
214 'hg.fork.repository'),
215 '_method': 'put'
215 '_method': 'put'
216 })
216 })
217
217
218 return htmlfill.render(
218 return htmlfill.render(
219 render('admin/users_groups/users_group_edit.html'),
219 render('admin/users_groups/users_group_edit.html'),
220 defaults=defaults,
220 defaults=defaults,
221 errors=e,
221 errors=e,
222 prefix_error=False,
222 prefix_error=False,
223 encoding="UTF-8")
223 encoding="UTF-8")
224 except Exception:
224 except Exception:
225 log.error(traceback.format_exc())
225 log.error(traceback.format_exc())
226 h.flash(_('Error occurred during update of user group %s') \
226 h.flash(_('Error occurred during update of user group %s') \
227 % request.POST.get('users_group_name'), category='error')
227 % request.POST.get('users_group_name'), category='error')
228
228
229 return redirect(url('edit_users_group', id=id))
229 return redirect(url('edit_users_group', id=id))
230
230
231 @HasUserGroupPermissionAnyDecorator('usergroup.admin')
231 @HasUserGroupPermissionAnyDecorator('usergroup.admin')
232 def delete(self, id):
232 def delete(self, id):
233 """DELETE /users_groups/id: Delete an existing item"""
233 """DELETE /users_groups/id: Delete an existing item"""
234 # Forms posted to this method should contain a hidden field:
234 # Forms posted to this method should contain a hidden field:
235 # <input type="hidden" name="_method" value="DELETE" />
235 # <input type="hidden" name="_method" value="DELETE" />
236 # Or using helpers:
236 # Or using helpers:
237 # h.form(url('users_group', id=ID),
237 # h.form(url('users_group', id=ID),
238 # method='delete')
238 # method='delete')
239 # url('users_group', id=ID)
239 # url('users_group', id=ID)
240 usr_gr = UserGroup.get_or_404(id)
240 usr_gr = UserGroup.get_or_404(id)
241 try:
241 try:
242 UserGroupModel().delete(usr_gr)
242 UserGroupModel().delete(usr_gr)
243 Session().commit()
243 Session().commit()
244 h.flash(_('Successfully deleted user group'), category='success')
244 h.flash(_('Successfully deleted user group'), category='success')
245 except UserGroupsAssignedException, e:
245 except UserGroupsAssignedException, e:
246 h.flash(e, category='error')
246 h.flash(e, category='error')
247 except Exception:
247 except Exception:
248 log.error(traceback.format_exc())
248 log.error(traceback.format_exc())
249 h.flash(_('An error occurred during deletion of user group'),
249 h.flash(_('An error occurred during deletion of user group'),
250 category='error')
250 category='error')
251 return redirect(url('users_groups'))
251 return redirect(url('users_groups'))
252
252
253 @HasUserGroupPermissionAnyDecorator('usergroup.admin')
253 @HasUserGroupPermissionAnyDecorator('usergroup.admin')
254 def set_user_group_perm_member(self, id):
254 def set_user_group_perm_member(self, id):
255 """
255 """
256 grant permission for given usergroup
256 grant permission for given usergroup
257
257
258 :param id:
258 :param id:
259 """
259 """
260 user_group = UserGroup.get_or_404(id)
260 user_group = UserGroup.get_or_404(id)
261 form = UserGroupPermsForm()().to_python(request.POST)
261 form = UserGroupPermsForm()().to_python(request.POST)
262
262
263 # set the permissions !
263 # set the permissions !
264 UserGroupModel()._update_permissions(user_group, form['perms_new'],
264 UserGroupModel()._update_permissions(user_group, form['perms_new'],
265 form['perms_updates'])
265 form['perms_updates'])
266 #TODO: implement this
266 #TODO: implement this
267 #action_logger(self.rhodecode_user, 'admin_changed_repo_permissions',
267 #action_logger(self.rhodecode_user, 'admin_changed_repo_permissions',
268 # repo_name, self.ip_addr, self.sa)
268 # repo_name, self.ip_addr, self.sa)
269 Session().commit()
269 Session().commit()
270 h.flash(_('User Group permissions updated'), category='success')
270 h.flash(_('User Group permissions updated'), category='success')
271 return redirect(url('edit_users_group', id=id))
271 return redirect(url('edit_users_group', id=id))
272
272
273 @HasUserGroupPermissionAnyDecorator('usergroup.admin')
273 @HasUserGroupPermissionAnyDecorator('usergroup.admin')
274 def delete_user_group_perm_member(self, id):
274 def delete_user_group_perm_member(self, id):
275 """
275 """
276 DELETE an existing repository group permission user
276 DELETE an existing repository group permission user
277
277
278 :param group_name:
278 :param group_name:
279 """
279 """
280 try:
280 try:
281 obj_type = request.POST.get('obj_type')
281 obj_type = request.POST.get('obj_type')
282 obj_id = None
282 obj_id = None
283 if obj_type == 'user':
283 if obj_type == 'user':
284 obj_id = safe_int(request.POST.get('user_id'))
284 obj_id = safe_int(request.POST.get('user_id'))
285 elif obj_type == 'user_group':
285 elif obj_type == 'user_group':
286 obj_id = safe_int(request.POST.get('user_group_id'))
286 obj_id = safe_int(request.POST.get('user_group_id'))
287
287
288 if not c.rhodecode_user.is_admin:
288 if not c.rhodecode_user.is_admin:
289 if obj_type == 'user' and c.rhodecode_user.user_id == obj_id:
289 if obj_type == 'user' and c.rhodecode_user.user_id == obj_id:
290 msg = _('Cannot revoke permission for yourself as admin')
290 msg = _('Cannot revoke permission for yourself as admin')
291 h.flash(msg, category='warning')
291 h.flash(msg, category='warning')
292 raise Exception('revoke admin permission on self')
292 raise Exception('revoke admin permission on self')
293 if obj_type == 'user':
293 if obj_type == 'user':
294 UserGroupModel().revoke_user_permission(user_group=id,
294 UserGroupModel().revoke_user_permission(user_group=id,
295 user=obj_id)
295 user=obj_id)
296 elif obj_type == 'user_group':
296 elif obj_type == 'user_group':
297 pass
297 pass
298 Session().commit()
298 Session().commit()
299 except Exception:
299 except Exception:
300 log.error(traceback.format_exc())
300 log.error(traceback.format_exc())
301 h.flash(_('An error occurred during revoking of permission'),
301 h.flash(_('An error occurred during revoking of permission'),
302 category='error')
302 category='error')
303 raise HTTPInternalServerError()
303 raise HTTPInternalServerError()
304
304
305 def show(self, id, format='html'):
305 def show(self, id, format='html'):
306 """GET /users_groups/id: Show a specific item"""
306 """GET /users_groups/id: Show a specific item"""
307 # url('users_group', id=ID)
307 # url('users_group', id=ID)
308
308
309 @HasUserGroupPermissionAnyDecorator('usergroup.admin')
309 @HasUserGroupPermissionAnyDecorator('usergroup.admin')
310 def edit(self, id, format='html'):
310 def edit(self, id, format='html'):
311 """GET /users_groups/id/edit: Form to edit an existing item"""
311 """GET /users_groups/id/edit: Form to edit an existing item"""
312 # url('edit_users_group', id=ID)
312 # url('edit_users_group', id=ID)
313
313
314 c.users_group = UserGroup.get_or_404(id)
314 c.users_group = UserGroup.get_or_404(id)
315 self.__load_data(id)
315 self.__load_data(id)
316
316
317 defaults = self.__load_defaults(id)
317 defaults = self.__load_defaults(id)
318
318
319 return htmlfill.render(
319 return htmlfill.render(
320 render('admin/users_groups/users_group_edit.html'),
320 render('admin/users_groups/users_group_edit.html'),
321 defaults=defaults,
321 defaults=defaults,
322 encoding="UTF-8",
322 encoding="UTF-8",
323 force_defaults=False
323 force_defaults=False
324 )
324 )
325
325
326 @HasUserGroupPermissionAnyDecorator('usergroup.admin')
326 @HasUserGroupPermissionAnyDecorator('usergroup.admin')
327 def update_perm(self, id):
327 def update_perm(self, id):
328 """PUT /users_perm/id: Update an existing item"""
328 """PUT /users_perm/id: Update an existing item"""
329 # url('users_group_perm', id=ID, method='put')
329 # url('users_group_perm', id=ID, method='put')
330
330
331 users_group = UserGroup.get_or_404(id)
331 users_group = UserGroup.get_or_404(id)
332
332
333 try:
333 try:
334 form = CustomDefaultPermissionsForm()()
334 form = CustomDefaultPermissionsForm()()
335 form_result = form.to_python(request.POST)
335 form_result = form.to_python(request.POST)
336
336
337 inherit_perms = form_result['inherit_default_permissions']
337 inherit_perms = form_result['inherit_default_permissions']
338 users_group.inherit_default_permissions = inherit_perms
338 users_group.inherit_default_permissions = inherit_perms
339 Session().add(users_group)
339 Session().add(users_group)
340 usergroup_model = UserGroupModel()
340 usergroup_model = UserGroupModel()
341
341
342 defs = UserGroupToPerm.query()\
342 defs = UserGroupToPerm.query()\
343 .filter(UserGroupToPerm.users_group == users_group)\
343 .filter(UserGroupToPerm.users_group == users_group)\
344 .all()
344 .all()
345 for ug in defs:
345 for ug in defs:
346 Session().delete(ug)
346 Session().delete(ug)
347
347
348 if form_result['create_repo_perm']:
348 if form_result['create_repo_perm']:
349 usergroup_model.grant_perm(id, 'hg.create.repository')
349 usergroup_model.grant_perm(id, 'hg.create.repository')
350 else:
350 else:
351 usergroup_model.grant_perm(id, 'hg.create.none')
351 usergroup_model.grant_perm(id, 'hg.create.none')
352 if form_result['create_user_group_perm']:
352 if form_result['create_user_group_perm']:
353 usergroup_model.grant_perm(id, 'hg.usergroup.create.true')
353 usergroup_model.grant_perm(id, 'hg.usergroup.create.true')
354 else:
354 else:
355 usergroup_model.grant_perm(id, 'hg.usergroup.create.false')
355 usergroup_model.grant_perm(id, 'hg.usergroup.create.false')
356 if form_result['fork_repo_perm']:
356 if form_result['fork_repo_perm']:
357 usergroup_model.grant_perm(id, 'hg.fork.repository')
357 usergroup_model.grant_perm(id, 'hg.fork.repository')
358 else:
358 else:
359 usergroup_model.grant_perm(id, 'hg.fork.none')
359 usergroup_model.grant_perm(id, 'hg.fork.none')
360
360
361 h.flash(_("Updated permissions"), category='success')
361 h.flash(_("Updated permissions"), category='success')
362 Session().commit()
362 Session().commit()
363 except Exception:
363 except Exception:
364 log.error(traceback.format_exc())
364 log.error(traceback.format_exc())
365 h.flash(_('An error occurred during permissions saving'),
365 h.flash(_('An error occurred during permissions saving'),
366 category='error')
366 category='error')
367
367
368 return redirect(url('edit_users_group', id=id))
368 return redirect(url('edit_users_group', id=id))
@@ -1,295 +1,299 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """
2 """
3 rhodecode.model.users_group
3 rhodecode.model.users_group
4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
5
5
6 user group model for RhodeCode
6 user group model for RhodeCode
7
7
8 :created_on: Oct 1, 2011
8 :created_on: Oct 1, 2011
9 :author: nvinot
9 :author: nvinot
10 :copyright: (C) 2011-2011 Nicolas Vinot <aeris@imirhil.fr>
10 :copyright: (C) 2011-2011 Nicolas Vinot <aeris@imirhil.fr>
11 :copyright: (C) 2010-2012 Marcin Kuzminski <marcin@python-works.com>
11 :copyright: (C) 2010-2012 Marcin Kuzminski <marcin@python-works.com>
12 :license: GPLv3, see COPYING for more details.
12 :license: GPLv3, see COPYING for more details.
13 """
13 """
14 # This program is free software: you can redistribute it and/or modify
14 # This program is free software: you can redistribute it and/or modify
15 # it under the terms of the GNU General Public License as published by
15 # it under the terms of the GNU General Public License as published by
16 # the Free Software Foundation, either version 3 of the License, or
16 # the Free Software Foundation, either version 3 of the License, or
17 # (at your option) any later version.
17 # (at your option) any later version.
18 #
18 #
19 # This program is distributed in the hope that it will be useful,
19 # This program is distributed in the hope that it will be useful,
20 # but WITHOUT ANY WARRANTY; without even the implied warranty of
20 # but WITHOUT ANY WARRANTY; without even the implied warranty of
21 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 # GNU General Public License for more details.
22 # GNU General Public License for more details.
23 #
23 #
24 # You should have received a copy of the GNU General Public License
24 # You should have received a copy of the GNU General Public License
25 # along with this program. If not, see <http://www.gnu.org/licenses/>.
25 # along with this program. If not, see <http://www.gnu.org/licenses/>.
26
26
27 import logging
27 import logging
28 import traceback
28 import traceback
29
29
30 from rhodecode.model import BaseModel
30 from rhodecode.model import BaseModel
31 from rhodecode.model.db import UserGroupMember, UserGroup,\
31 from rhodecode.model.db import UserGroupMember, UserGroup,\
32 UserGroupRepoToPerm, Permission, UserGroupToPerm, User, UserUserGroupToPerm
32 UserGroupRepoToPerm, Permission, UserGroupToPerm, User, UserUserGroupToPerm
33 from rhodecode.lib.exceptions import UserGroupsAssignedException
33 from rhodecode.lib.exceptions import UserGroupsAssignedException
34
34
35 log = logging.getLogger(__name__)
35 log = logging.getLogger(__name__)
36
36
37
37
38 class UserGroupModel(BaseModel):
38 class UserGroupModel(BaseModel):
39
39
40 cls = UserGroup
40 cls = UserGroup
41
41
42 def _get_user_group(self, users_group):
42 def _get_user_group(self, users_group):
43 return self._get_instance(UserGroup, users_group,
43 return self._get_instance(UserGroup, users_group,
44 callback=UserGroup.get_by_group_name)
44 callback=UserGroup.get_by_group_name)
45
45
46 def _create_default_perms(self, user_group):
46 def _create_default_perms(self, user_group):
47 # create default permission
47 # create default permission
48 default_perm = 'usergroup.read'
48 default_perm = 'usergroup.read'
49 def_user = User.get_default_user()
49 def_user = User.get_default_user()
50 for p in def_user.user_perms:
50 for p in def_user.user_perms:
51 if p.permission.permission_name.startswith('usergroup.'):
51 if p.permission.permission_name.startswith('usergroup.'):
52 default_perm = p.permission.permission_name
52 default_perm = p.permission.permission_name
53 break
53 break
54
54
55 user_group_to_perm = UserUserGroupToPerm()
55 user_group_to_perm = UserUserGroupToPerm()
56 user_group_to_perm.permission = Permission.get_by_key(default_perm)
56 user_group_to_perm.permission = Permission.get_by_key(default_perm)
57
57
58 user_group_to_perm.user_group = user_group
58 user_group_to_perm.user_group = user_group
59 user_group_to_perm.user_id = def_user.user_id
59 user_group_to_perm.user_id = def_user.user_id
60 return user_group_to_perm
60 return user_group_to_perm
61
61
62 def _update_permissions(self, user_group, perms_new=None,
62 def _update_permissions(self, user_group, perms_new=None,
63 perms_updates=None):
63 perms_updates=None):
64 if not perms_new:
64 if not perms_new:
65 perms_new = []
65 perms_new = []
66 if not perms_updates:
66 if not perms_updates:
67 perms_updates = []
67 perms_updates = []
68
68
69 # update permissions
69 # update permissions
70 for member, perm, member_type in perms_updates:
70 for member, perm, member_type in perms_updates:
71 if member_type == 'user':
71 if member_type == 'user':
72 # this updates existing one
72 # this updates existing one
73 self.grant_user_permission(
73 self.grant_user_permission(
74 user_group=user_group, user=member, perm=perm
74 user_group=user_group, user=member, perm=perm
75 )
75 )
76 else:
76 else:
77 self.grant_users_group_permission(
77 self.grant_users_group_permission(
78 user_group=user_group, group_name=member, perm=perm
78 user_group=user_group, group_name=member, perm=perm
79 )
79 )
80 # set new permissions
80 # set new permissions
81 for member, perm, member_type in perms_new:
81 for member, perm, member_type in perms_new:
82 if member_type == 'user':
82 if member_type == 'user':
83 self.grant_user_permission(
83 self.grant_user_permission(
84 user_group=user_group, user=member, perm=perm
84 user_group=user_group, user=member, perm=perm
85 )
85 )
86 else:
86 else:
87 self.grant_users_group_permission(
87 self.grant_users_group_permission(
88 user_group=user_group, group_name=member, perm=perm
88 user_group=user_group, group_name=member, perm=perm
89 )
89 )
90
90
91 def get(self, users_group_id, cache=False):
91 def get(self, users_group_id, cache=False):
92 return UserGroup.get(users_group_id)
92 return UserGroup.get(users_group_id)
93
93
94 def get_group(self, users_group):
94 def get_group(self, users_group):
95 return self._get_user_group(users_group)
95 return self._get_user_group(users_group)
96
96
97 def get_by_name(self, name, cache=False, case_insensitive=False):
97 def get_by_name(self, name, cache=False, case_insensitive=False):
98 return UserGroup.get_by_group_name(name, cache, case_insensitive)
98 return UserGroup.get_by_group_name(name, cache, case_insensitive)
99
99
100 def create(self, name, owner, active=True):
100 def create(self, name, owner, active=True):
101 try:
101 try:
102 new_user_group = UserGroup()
102 new_user_group = UserGroup()
103 new_user_group.user = self._get_user(owner)
103 new_user_group.user = self._get_user(owner)
104 new_user_group.users_group_name = name
104 new_user_group.users_group_name = name
105 new_user_group.users_group_active = active
105 new_user_group.users_group_active = active
106 self.sa.add(new_user_group)
106 self.sa.add(new_user_group)
107 perm_obj = self._create_default_perms(new_user_group)
107 perm_obj = self._create_default_perms(new_user_group)
108 self.sa.add(perm_obj)
108 self.sa.add(perm_obj)
109
110 self.grant_user_permission(user_group=new_user_group,
111 user=owner, perm='usergroup.admin')
112
109 return new_user_group
113 return new_user_group
110 except Exception:
114 except Exception:
111 log.error(traceback.format_exc())
115 log.error(traceback.format_exc())
112 raise
116 raise
113
117
114 def update(self, users_group, form_data):
118 def update(self, users_group, form_data):
115
119
116 try:
120 try:
117 users_group = self._get_user_group(users_group)
121 users_group = self._get_user_group(users_group)
118
122
119 for k, v in form_data.items():
123 for k, v in form_data.items():
120 if k == 'users_group_members':
124 if k == 'users_group_members':
121 users_group.members = []
125 users_group.members = []
122 self.sa.flush()
126 self.sa.flush()
123 members_list = []
127 members_list = []
124 if v:
128 if v:
125 v = [v] if isinstance(v, basestring) else v
129 v = [v] if isinstance(v, basestring) else v
126 for u_id in set(v):
130 for u_id in set(v):
127 member = UserGroupMember(users_group.users_group_id, u_id)
131 member = UserGroupMember(users_group.users_group_id, u_id)
128 members_list.append(member)
132 members_list.append(member)
129 setattr(users_group, 'members', members_list)
133 setattr(users_group, 'members', members_list)
130 setattr(users_group, k, v)
134 setattr(users_group, k, v)
131
135
132 self.sa.add(users_group)
136 self.sa.add(users_group)
133 except Exception:
137 except Exception:
134 log.error(traceback.format_exc())
138 log.error(traceback.format_exc())
135 raise
139 raise
136
140
137 def delete(self, users_group, force=False):
141 def delete(self, users_group, force=False):
138 """
142 """
139 Deletes repository group, unless force flag is used
143 Deletes repository group, unless force flag is used
140 raises exception if there are members in that group, else deletes
144 raises exception if there are members in that group, else deletes
141 group and users
145 group and users
142
146
143 :param users_group:
147 :param users_group:
144 :param force:
148 :param force:
145 """
149 """
146 try:
150 try:
147 users_group = self._get_user_group(users_group)
151 users_group = self._get_user_group(users_group)
148
152
149 # check if this group is not assigned to repo
153 # check if this group is not assigned to repo
150 assigned_groups = UserGroupRepoToPerm.query()\
154 assigned_groups = UserGroupRepoToPerm.query()\
151 .filter(UserGroupRepoToPerm.users_group == users_group).all()
155 .filter(UserGroupRepoToPerm.users_group == users_group).all()
152
156
153 if assigned_groups and not force:
157 if assigned_groups and not force:
154 raise UserGroupsAssignedException('RepoGroup assigned to %s' %
158 raise UserGroupsAssignedException('RepoGroup assigned to %s' %
155 assigned_groups)
159 assigned_groups)
156
160
157 self.sa.delete(users_group)
161 self.sa.delete(users_group)
158 except Exception:
162 except Exception:
159 log.error(traceback.format_exc())
163 log.error(traceback.format_exc())
160 raise
164 raise
161
165
162 def add_user_to_group(self, users_group, user):
166 def add_user_to_group(self, users_group, user):
163 users_group = self._get_user_group(users_group)
167 users_group = self._get_user_group(users_group)
164 user = self._get_user(user)
168 user = self._get_user(user)
165
169
166 for m in users_group.members:
170 for m in users_group.members:
167 u = m.user
171 u = m.user
168 if u.user_id == user.user_id:
172 if u.user_id == user.user_id:
169 return True
173 return True
170
174
171 try:
175 try:
172 users_group_member = UserGroupMember()
176 users_group_member = UserGroupMember()
173 users_group_member.user = user
177 users_group_member.user = user
174 users_group_member.users_group = users_group
178 users_group_member.users_group = users_group
175
179
176 users_group.members.append(users_group_member)
180 users_group.members.append(users_group_member)
177 user.group_member.append(users_group_member)
181 user.group_member.append(users_group_member)
178
182
179 self.sa.add(users_group_member)
183 self.sa.add(users_group_member)
180 return users_group_member
184 return users_group_member
181 except Exception:
185 except Exception:
182 log.error(traceback.format_exc())
186 log.error(traceback.format_exc())
183 raise
187 raise
184
188
185 def remove_user_from_group(self, users_group, user):
189 def remove_user_from_group(self, users_group, user):
186 users_group = self._get_user_group(users_group)
190 users_group = self._get_user_group(users_group)
187 user = self._get_user(user)
191 user = self._get_user(user)
188
192
189 users_group_member = None
193 users_group_member = None
190 for m in users_group.members:
194 for m in users_group.members:
191 if m.user.user_id == user.user_id:
195 if m.user.user_id == user.user_id:
192 # Found this user's membership row
196 # Found this user's membership row
193 users_group_member = m
197 users_group_member = m
194 break
198 break
195
199
196 if users_group_member:
200 if users_group_member:
197 try:
201 try:
198 self.sa.delete(users_group_member)
202 self.sa.delete(users_group_member)
199 return True
203 return True
200 except Exception:
204 except Exception:
201 log.error(traceback.format_exc())
205 log.error(traceback.format_exc())
202 raise
206 raise
203 else:
207 else:
204 # User isn't in that group
208 # User isn't in that group
205 return False
209 return False
206
210
207 def has_perm(self, users_group, perm):
211 def has_perm(self, users_group, perm):
208 users_group = self._get_user_group(users_group)
212 users_group = self._get_user_group(users_group)
209 perm = self._get_perm(perm)
213 perm = self._get_perm(perm)
210
214
211 return UserGroupToPerm.query()\
215 return UserGroupToPerm.query()\
212 .filter(UserGroupToPerm.users_group == users_group)\
216 .filter(UserGroupToPerm.users_group == users_group)\
213 .filter(UserGroupToPerm.permission == perm).scalar() is not None
217 .filter(UserGroupToPerm.permission == perm).scalar() is not None
214
218
215 def grant_perm(self, users_group, perm):
219 def grant_perm(self, users_group, perm):
216 users_group = self._get_user_group(users_group)
220 users_group = self._get_user_group(users_group)
217 perm = self._get_perm(perm)
221 perm = self._get_perm(perm)
218
222
219 # if this permission is already granted skip it
223 # if this permission is already granted skip it
220 _perm = UserGroupToPerm.query()\
224 _perm = UserGroupToPerm.query()\
221 .filter(UserGroupToPerm.users_group == users_group)\
225 .filter(UserGroupToPerm.users_group == users_group)\
222 .filter(UserGroupToPerm.permission == perm)\
226 .filter(UserGroupToPerm.permission == perm)\
223 .scalar()
227 .scalar()
224 if _perm:
228 if _perm:
225 return
229 return
226
230
227 new = UserGroupToPerm()
231 new = UserGroupToPerm()
228 new.users_group = users_group
232 new.users_group = users_group
229 new.permission = perm
233 new.permission = perm
230 self.sa.add(new)
234 self.sa.add(new)
231
235
232 def revoke_perm(self, users_group, perm):
236 def revoke_perm(self, users_group, perm):
233 users_group = self._get_user_group(users_group)
237 users_group = self._get_user_group(users_group)
234 perm = self._get_perm(perm)
238 perm = self._get_perm(perm)
235
239
236 obj = UserGroupToPerm.query()\
240 obj = UserGroupToPerm.query()\
237 .filter(UserGroupToPerm.users_group == users_group)\
241 .filter(UserGroupToPerm.users_group == users_group)\
238 .filter(UserGroupToPerm.permission == perm).scalar()
242 .filter(UserGroupToPerm.permission == perm).scalar()
239 if obj:
243 if obj:
240 self.sa.delete(obj)
244 self.sa.delete(obj)
241
245
242 def grant_user_permission(self, user_group, user, perm):
246 def grant_user_permission(self, user_group, user, perm):
243 """
247 """
244 Grant permission for user on given user group, or update
248 Grant permission for user on given user group, or update
245 existing one if found
249 existing one if found
246
250
247 :param user_group: Instance of UserGroup, users_group_id,
251 :param user_group: Instance of UserGroup, users_group_id,
248 or users_group_name
252 or users_group_name
249 :param user: Instance of User, user_id or username
253 :param user: Instance of User, user_id or username
250 :param perm: Instance of Permission, or permission_name
254 :param perm: Instance of Permission, or permission_name
251 """
255 """
252
256
253 user_group = self._get_user_group(user_group)
257 user_group = self._get_user_group(user_group)
254 user = self._get_user(user)
258 user = self._get_user(user)
255 permission = self._get_perm(perm)
259 permission = self._get_perm(perm)
256
260
257 # check if we have that permission already
261 # check if we have that permission already
258 obj = self.sa.query(UserUserGroupToPerm)\
262 obj = self.sa.query(UserUserGroupToPerm)\
259 .filter(UserUserGroupToPerm.user == user)\
263 .filter(UserUserGroupToPerm.user == user)\
260 .filter(UserUserGroupToPerm.user_group == user_group)\
264 .filter(UserUserGroupToPerm.user_group == user_group)\
261 .scalar()
265 .scalar()
262 if obj is None:
266 if obj is None:
263 # create new !
267 # create new !
264 obj = UserUserGroupToPerm()
268 obj = UserUserGroupToPerm()
265 obj.user_group = user_group
269 obj.user_group = user_group
266 obj.user = user
270 obj.user = user
267 obj.permission = permission
271 obj.permission = permission
268 self.sa.add(obj)
272 self.sa.add(obj)
269 log.debug('Granted perm %s to %s on %s' % (perm, user, user_group))
273 log.debug('Granted perm %s to %s on %s' % (perm, user, user_group))
270
274
271 def revoke_user_permission(self, user_group, user):
275 def revoke_user_permission(self, user_group, user):
272 """
276 """
273 Revoke permission for user on given repository group
277 Revoke permission for user on given repository group
274
278
275 :param user_group: Instance of ReposGroup, repositories_group_id,
279 :param user_group: Instance of ReposGroup, repositories_group_id,
276 or repositories_group name
280 or repositories_group name
277 :param user: Instance of User, user_id or username
281 :param user: Instance of User, user_id or username
278 """
282 """
279
283
280 user_group = self._get_user_group(user_group)
284 user_group = self._get_user_group(user_group)
281 user = self._get_user(user)
285 user = self._get_user(user)
282
286
283 obj = self.sa.query(UserUserGroupToPerm)\
287 obj = self.sa.query(UserUserGroupToPerm)\
284 .filter(UserUserGroupToPerm.user == user)\
288 .filter(UserUserGroupToPerm.user == user)\
285 .filter(UserUserGroupToPerm.user_group == user_group)\
289 .filter(UserUserGroupToPerm.user_group == user_group)\
286 .scalar()
290 .scalar()
287 if obj:
291 if obj:
288 self.sa.delete(obj)
292 self.sa.delete(obj)
289 log.debug('Revoked perm on %s on %s' % (user_group, user))
293 log.debug('Revoked perm on %s on %s' % (user_group, user))
290
294
291 def grant_users_group_permission(self, user_group, group_name, perm):
295 def grant_users_group_permission(self, user_group, group_name, perm):
292 raise NotImplementedError()
296 raise NotImplementedError()
293
297
294 def revoke_users_group_permission(self, user_group, group_name):
298 def revoke_users_group_permission(self, user_group, group_name):
295 raise NotImplementedError()
299 raise NotImplementedError()
@@ -1,65 +1,66 b''
1 ## -*- coding: utf-8 -*-
1 ## -*- coding: utf-8 -*-
2 <%inherit file="/base/base.html"/>
2 <%inherit file="/base/base.html"/>
3
3
4 <%def name="title()">
4 <%def name="title()">
5 ${_('User groups administration')} &middot; ${c.rhodecode_name}
5 ${_('User groups administration')} &middot; ${c.rhodecode_name}
6 </%def>
6 </%def>
7
7
8 <%def name="breadcrumbs_links()">
8 <%def name="breadcrumbs_links()">
9 ${h.link_to(_('Admin'),h.url('admin_home'))}
9 ${h.link_to(_('Admin'),h.url('admin_home'))}
10 &raquo;
10 &raquo;
11 ${_('User groups')}
11 ${_('User groups')}
12 </%def>
12 </%def>
13
13
14 <%def name="page_nav()">
14 <%def name="page_nav()">
15 ${self.menu('admin')}
15 ${self.menu('admin')}
16 </%def>
16 </%def>
17
17
18 <%def name="main()">
18 <%def name="main()">
19 <div class="box">
19 <div class="box">
20 <!-- box / title -->
20 <!-- box / title -->
21 <div class="title">
21 <div class="title">
22 ${self.breadcrumbs()}
22 ${self.breadcrumbs()}
23 <ul class="links">
23 <ul class="links">
24 %if h.HasPermissionAny('hg.usergroup.create.true')():
24 <li>
25 <li>
25 <span>${h.link_to(_(u'Add new user group'),h.url('new_users_group'))}</span>
26 <span>${h.link_to(_(u'Add new user group'),h.url('new_users_group'))}</span>
26 </li>
27 </li>
27
28 %endif
28 </ul>
29 </ul>
29 </div>
30 </div>
30 <!-- end box / title -->
31 <!-- end box / title -->
31
32
32 <div class="table">
33 <div class="table">
33 %if c.users_groups_list:
34 %if c.users_groups_list:
34 <table class="table_disp">
35 <table class="table_disp">
35 <tr class="header">
36 <tr class="header">
36 <th class="left">${_('Group name')}</th>
37 <th class="left">${_('Group name')}</th>
37 <th class="left">${_('Members')}</th>
38 <th class="left">${_('Members')}</th>
38 <th class="left">${_('Active')}</th>
39 <th class="left">${_('Active')}</th>
39 <th class="left" colspan="2">${_('Action')}</th>
40 <th class="left" colspan="2">${_('Action')}</th>
40 </tr>
41 </tr>
41 %for cnt,u_group in enumerate(c.users_groups_list):
42 %for cnt,u_group in enumerate(c.users_groups_list):
42 <tr class="parity${cnt%2}">
43 <tr class="parity${cnt%2}">
43 <td>${h.link_to(u_group.users_group_name,h.url('edit_users_group', id=u_group.users_group_id))}</td>
44 <td>${h.link_to(u_group.users_group_name,h.url('edit_users_group', id=u_group.users_group_id))}</td>
44 <td><span class="tooltip" title="${h.tooltip(', '.join(map(h.safe_unicode,[x.user.username for x in u_group.members[:50]])))}">${len(u_group.members)}</span></td>
45 <td><span class="tooltip" title="${h.tooltip(', '.join(map(h.safe_unicode,[x.user.username for x in u_group.members[:50]])))}">${len(u_group.members)}</span></td>
45 <td>${h.boolicon(u_group.users_group_active)}</td>
46 <td>${h.boolicon(u_group.users_group_active)}</td>
46 <td>
47 <td>
47 <a href="${h.url('edit_users_group', id=u_group.users_group_id)}" title="${_('Edit')}">
48 <a href="${h.url('edit_users_group', id=u_group.users_group_id)}" title="${_('Edit')}">
48 ${h.submit('edit_%s' % u_group.users_group_name,_('edit'),class_="edit_icon action_button")}
49 ${h.submit('edit_%s' % u_group.users_group_name,_('edit'),class_="edit_icon action_button")}
49 </a>
50 </a>
50 </td>
51 </td>
51 <td>
52 <td>
52 ${h.form(url('users_group', id=u_group.users_group_id),method='delete')}
53 ${h.form(url('users_group', id=u_group.users_group_id),method='delete')}
53 ${h.submit('remove_',_('delete'),id="remove_group_%s" % u_group.users_group_id,
54 ${h.submit('remove_',_('delete'),id="remove_group_%s" % u_group.users_group_id,
54 class_="delete_icon action_button",onclick="return confirm('"+_('Confirm to delete this user group: %s') % u_group.users_group_name+"');")}
55 class_="delete_icon action_button",onclick="return confirm('"+_('Confirm to delete this user group: %s') % u_group.users_group_name+"');")}
55 ${h.end_form()}
56 ${h.end_form()}
56 </td>
57 </td>
57 </tr>
58 </tr>
58 %endfor
59 %endfor
59 </table>
60 </table>
60 %else:
61 %else:
61 ${_('There are no user groups yet')}
62 ${_('There are no user groups yet')}
62 %endif
63 %endif
63 </div>
64 </div>
64 </div>
65 </div>
65 </%def>
66 </%def>
General Comments 0
You need to be logged in to leave comments. Login now