##// END OF EJS Templates
permissions: flush all users permissions when creating a new user group....
super-admin -
r4727:ccc56075 default
parent child Browse files
Show More
@@ -1,254 +1,253 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2016-2020 RhodeCode GmbH
3 # Copyright (C) 2016-2020 RhodeCode GmbH
4 #
4 #
5 # This program is free software: you can redistribute it and/or modify
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
6 # it under the terms of the GNU Affero General Public License, version 3
7 # (only), as published by the Free Software Foundation.
7 # (only), as published by the Free Software Foundation.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU Affero General Public License
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/>.
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #
16 #
17 # This program is dual-licensed. If you wish to learn more about the
17 # This program is dual-licensed. If you wish to learn more about the
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 import logging
21 import logging
22
22
23 import formencode
23 import formencode
24 import formencode.htmlfill
24 import formencode.htmlfill
25
25
26 from pyramid.httpexceptions import HTTPFound
26 from pyramid.httpexceptions import HTTPFound
27
27
28 from pyramid.response import Response
28 from pyramid.response import Response
29 from pyramid.renderers import render
29 from pyramid.renderers import render
30
30
31 from rhodecode import events
31 from rhodecode import events
32 from rhodecode.apps._base import BaseAppView, DataGridAppView
32 from rhodecode.apps._base import BaseAppView, DataGridAppView
33 from rhodecode.lib.auth import (
33 from rhodecode.lib.auth import (
34 LoginRequired, NotAnonymous, CSRFRequired, HasPermissionAnyDecorator)
34 LoginRequired, NotAnonymous, CSRFRequired, HasPermissionAnyDecorator)
35 from rhodecode.lib import helpers as h, audit_logger
35 from rhodecode.lib import helpers as h, audit_logger
36 from rhodecode.lib.utils2 import safe_unicode
36 from rhodecode.lib.utils2 import safe_unicode
37
37
38 from rhodecode.model.forms import UserGroupForm
38 from rhodecode.model.forms import UserGroupForm
39 from rhodecode.model.permission import PermissionModel
39 from rhodecode.model.permission import PermissionModel
40 from rhodecode.model.scm import UserGroupList
40 from rhodecode.model.scm import UserGroupList
41 from rhodecode.model.db import (
41 from rhodecode.model.db import (
42 or_, count, User, UserGroup, UserGroupMember, in_filter_generator)
42 or_, count, User, UserGroup, UserGroupMember, in_filter_generator)
43 from rhodecode.model.meta import Session
43 from rhodecode.model.meta import Session
44 from rhodecode.model.user_group import UserGroupModel
44 from rhodecode.model.user_group import UserGroupModel
45 from rhodecode.model.db import true
45 from rhodecode.model.db import true
46
46
47 log = logging.getLogger(__name__)
47 log = logging.getLogger(__name__)
48
48
49
49
50 class AdminUserGroupsView(BaseAppView, DataGridAppView):
50 class AdminUserGroupsView(BaseAppView, DataGridAppView):
51
51
52 def load_default_context(self):
52 def load_default_context(self):
53 c = self._get_local_tmpl_context()
53 c = self._get_local_tmpl_context()
54 PermissionModel().set_global_permission_choices(
54 PermissionModel().set_global_permission_choices(
55 c, gettext_translator=self.request.translate)
55 c, gettext_translator=self.request.translate)
56 return c
56 return c
57
57
58 # permission check in data loading of
58 # permission check in data loading of
59 # `user_groups_list_data` via UserGroupList
59 # `user_groups_list_data` via UserGroupList
60 @LoginRequired()
60 @LoginRequired()
61 @NotAnonymous()
61 @NotAnonymous()
62 def user_groups_list(self):
62 def user_groups_list(self):
63 c = self.load_default_context()
63 c = self.load_default_context()
64 return self._get_template_context(c)
64 return self._get_template_context(c)
65
65
66 # permission check inside
66 # permission check inside
67 @LoginRequired()
67 @LoginRequired()
68 @NotAnonymous()
68 @NotAnonymous()
69 def user_groups_list_data(self):
69 def user_groups_list_data(self):
70 self.load_default_context()
70 self.load_default_context()
71 column_map = {
71 column_map = {
72 'active': 'users_group_active',
72 'active': 'users_group_active',
73 'description': 'user_group_description',
73 'description': 'user_group_description',
74 'members': 'members_total',
74 'members': 'members_total',
75 'owner': 'user_username',
75 'owner': 'user_username',
76 'sync': 'group_data'
76 'sync': 'group_data'
77 }
77 }
78 draw, start, limit = self._extract_chunk(self.request)
78 draw, start, limit = self._extract_chunk(self.request)
79 search_q, order_by, order_dir = self._extract_ordering(
79 search_q, order_by, order_dir = self._extract_ordering(
80 self.request, column_map=column_map)
80 self.request, column_map=column_map)
81
81
82 _render = self.request.get_partial_renderer(
82 _render = self.request.get_partial_renderer(
83 'rhodecode:templates/data_table/_dt_elements.mako')
83 'rhodecode:templates/data_table/_dt_elements.mako')
84
84
85 def user_group_name(user_group_name):
85 def user_group_name(user_group_name):
86 return _render("user_group_name", user_group_name)
86 return _render("user_group_name", user_group_name)
87
87
88 def user_group_actions(user_group_id, user_group_name):
88 def user_group_actions(user_group_id, user_group_name):
89 return _render("user_group_actions", user_group_id, user_group_name)
89 return _render("user_group_actions", user_group_id, user_group_name)
90
90
91 def user_profile(username):
91 def user_profile(username):
92 return _render('user_profile', username)
92 return _render('user_profile', username)
93
93
94 _perms = ['usergroup.admin']
94 _perms = ['usergroup.admin']
95 allowed_ids = [-1] + self._rhodecode_user.user_group_acl_ids_from_stack(_perms)
95 allowed_ids = [-1] + self._rhodecode_user.user_group_acl_ids_from_stack(_perms)
96
96
97 user_groups_data_total_count = UserGroup.query()\
97 user_groups_data_total_count = UserGroup.query()\
98 .filter(or_(
98 .filter(or_(
99 # generate multiple IN to fix limitation problems
99 # generate multiple IN to fix limitation problems
100 *in_filter_generator(UserGroup.users_group_id, allowed_ids)
100 *in_filter_generator(UserGroup.users_group_id, allowed_ids)
101 ))\
101 ))\
102 .count()
102 .count()
103
103
104 user_groups_data_total_inactive_count = UserGroup.query()\
104 user_groups_data_total_inactive_count = UserGroup.query()\
105 .filter(or_(
105 .filter(or_(
106 # generate multiple IN to fix limitation problems
106 # generate multiple IN to fix limitation problems
107 *in_filter_generator(UserGroup.users_group_id, allowed_ids)
107 *in_filter_generator(UserGroup.users_group_id, allowed_ids)
108 ))\
108 ))\
109 .filter(UserGroup.users_group_active != true()).count()
109 .filter(UserGroup.users_group_active != true()).count()
110
110
111 member_count = count(UserGroupMember.user_id)
111 member_count = count(UserGroupMember.user_id)
112 base_q = Session.query(
112 base_q = Session.query(
113 UserGroup.users_group_name,
113 UserGroup.users_group_name,
114 UserGroup.user_group_description,
114 UserGroup.user_group_description,
115 UserGroup.users_group_active,
115 UserGroup.users_group_active,
116 UserGroup.users_group_id,
116 UserGroup.users_group_id,
117 UserGroup.group_data,
117 UserGroup.group_data,
118 User,
118 User,
119 member_count.label('member_count')
119 member_count.label('member_count')
120 ) \
120 ) \
121 .filter(or_(
121 .filter(or_(
122 # generate multiple IN to fix limitation problems
122 # generate multiple IN to fix limitation problems
123 *in_filter_generator(UserGroup.users_group_id, allowed_ids)
123 *in_filter_generator(UserGroup.users_group_id, allowed_ids)
124 )) \
124 )) \
125 .outerjoin(UserGroupMember, UserGroupMember.users_group_id == UserGroup.users_group_id) \
125 .outerjoin(UserGroupMember, UserGroupMember.users_group_id == UserGroup.users_group_id) \
126 .join(User, User.user_id == UserGroup.user_id) \
126 .join(User, User.user_id == UserGroup.user_id) \
127 .group_by(UserGroup, User)
127 .group_by(UserGroup, User)
128
128
129 base_q_inactive = base_q.filter(UserGroup.users_group_active != true())
129 base_q_inactive = base_q.filter(UserGroup.users_group_active != true())
130
130
131 if search_q:
131 if search_q:
132 like_expression = u'%{}%'.format(safe_unicode(search_q))
132 like_expression = u'%{}%'.format(safe_unicode(search_q))
133 base_q = base_q.filter(or_(
133 base_q = base_q.filter(or_(
134 UserGroup.users_group_name.ilike(like_expression),
134 UserGroup.users_group_name.ilike(like_expression),
135 ))
135 ))
136 base_q_inactive = base_q.filter(UserGroup.users_group_active != true())
136 base_q_inactive = base_q.filter(UserGroup.users_group_active != true())
137
137
138 user_groups_data_total_filtered_count = base_q.count()
138 user_groups_data_total_filtered_count = base_q.count()
139 user_groups_data_total_filtered_inactive_count = base_q_inactive.count()
139 user_groups_data_total_filtered_inactive_count = base_q_inactive.count()
140
140
141 sort_defined = False
141 sort_defined = False
142 if order_by == 'members_total':
142 if order_by == 'members_total':
143 sort_col = member_count
143 sort_col = member_count
144 sort_defined = True
144 sort_defined = True
145 elif order_by == 'user_username':
145 elif order_by == 'user_username':
146 sort_col = User.username
146 sort_col = User.username
147 else:
147 else:
148 sort_col = getattr(UserGroup, order_by, None)
148 sort_col = getattr(UserGroup, order_by, None)
149
149
150 if sort_defined or sort_col:
150 if sort_defined or sort_col:
151 if order_dir == 'asc':
151 if order_dir == 'asc':
152 sort_col = sort_col.asc()
152 sort_col = sort_col.asc()
153 else:
153 else:
154 sort_col = sort_col.desc()
154 sort_col = sort_col.desc()
155
155
156 base_q = base_q.order_by(sort_col)
156 base_q = base_q.order_by(sort_col)
157 base_q = base_q.offset(start).limit(limit)
157 base_q = base_q.offset(start).limit(limit)
158
158
159 # authenticated access to user groups
159 # authenticated access to user groups
160 auth_user_group_list = base_q.all()
160 auth_user_group_list = base_q.all()
161
161
162 user_groups_data = []
162 user_groups_data = []
163 for user_gr in auth_user_group_list:
163 for user_gr in auth_user_group_list:
164 row = {
164 row = {
165 "users_group_name": user_group_name(user_gr.users_group_name),
165 "users_group_name": user_group_name(user_gr.users_group_name),
166 "description": h.escape(user_gr.user_group_description),
166 "description": h.escape(user_gr.user_group_description),
167 "members": user_gr.member_count,
167 "members": user_gr.member_count,
168 # NOTE(marcink): because of advanced query we
168 # NOTE(marcink): because of advanced query we
169 # need to load it like that
169 # need to load it like that
170 "sync": UserGroup._load_sync(
170 "sync": UserGroup._load_sync(
171 UserGroup._load_group_data(user_gr.group_data)),
171 UserGroup._load_group_data(user_gr.group_data)),
172 "active": h.bool2icon(user_gr.users_group_active),
172 "active": h.bool2icon(user_gr.users_group_active),
173 "owner": user_profile(user_gr.User.username),
173 "owner": user_profile(user_gr.User.username),
174 "action": user_group_actions(
174 "action": user_group_actions(
175 user_gr.users_group_id, user_gr.users_group_name)
175 user_gr.users_group_id, user_gr.users_group_name)
176 }
176 }
177 user_groups_data.append(row)
177 user_groups_data.append(row)
178
178
179 data = ({
179 data = ({
180 'draw': draw,
180 'draw': draw,
181 'data': user_groups_data,
181 'data': user_groups_data,
182 'recordsTotal': user_groups_data_total_count,
182 'recordsTotal': user_groups_data_total_count,
183 'recordsTotalInactive': user_groups_data_total_inactive_count,
183 'recordsTotalInactive': user_groups_data_total_inactive_count,
184 'recordsFiltered': user_groups_data_total_filtered_count,
184 'recordsFiltered': user_groups_data_total_filtered_count,
185 'recordsFilteredInactive': user_groups_data_total_filtered_inactive_count,
185 'recordsFilteredInactive': user_groups_data_total_filtered_inactive_count,
186 })
186 })
187
187
188 return data
188 return data
189
189
190 @LoginRequired()
190 @LoginRequired()
191 @HasPermissionAnyDecorator('hg.admin', 'hg.usergroup.create.true')
191 @HasPermissionAnyDecorator('hg.admin', 'hg.usergroup.create.true')
192 def user_groups_new(self):
192 def user_groups_new(self):
193 c = self.load_default_context()
193 c = self.load_default_context()
194 return self._get_template_context(c)
194 return self._get_template_context(c)
195
195
196 @LoginRequired()
196 @LoginRequired()
197 @HasPermissionAnyDecorator('hg.admin', 'hg.usergroup.create.true')
197 @HasPermissionAnyDecorator('hg.admin', 'hg.usergroup.create.true')
198 @CSRFRequired()
198 @CSRFRequired()
199 def user_groups_create(self):
199 def user_groups_create(self):
200 _ = self.request.translate
200 _ = self.request.translate
201 c = self.load_default_context()
201 c = self.load_default_context()
202 users_group_form = UserGroupForm(self.request.translate)()
202 users_group_form = UserGroupForm(self.request.translate)()
203
203
204 user_group_name = self.request.POST.get('users_group_name')
204 user_group_name = self.request.POST.get('users_group_name')
205 try:
205 try:
206 form_result = users_group_form.to_python(dict(self.request.POST))
206 form_result = users_group_form.to_python(dict(self.request.POST))
207 user_group = UserGroupModel().create(
207 user_group = UserGroupModel().create(
208 name=form_result['users_group_name'],
208 name=form_result['users_group_name'],
209 description=form_result['user_group_description'],
209 description=form_result['user_group_description'],
210 owner=self._rhodecode_user.user_id,
210 owner=self._rhodecode_user.user_id,
211 active=form_result['users_group_active'])
211 active=form_result['users_group_active'])
212 Session().flush()
212 Session().flush()
213 creation_data = user_group.get_api_data()
213 creation_data = user_group.get_api_data()
214 user_group_name = form_result['users_group_name']
214 user_group_name = form_result['users_group_name']
215
215
216 audit_logger.store_web(
216 audit_logger.store_web(
217 'user_group.create', action_data={'data': creation_data},
217 'user_group.create', action_data={'data': creation_data},
218 user=self._rhodecode_user)
218 user=self._rhodecode_user)
219
219
220 user_group_link = h.link_to(
220 user_group_link = h.link_to(
221 h.escape(user_group_name),
221 h.escape(user_group_name),
222 h.route_path(
222 h.route_path(
223 'edit_user_group', user_group_id=user_group.users_group_id))
223 'edit_user_group', user_group_id=user_group.users_group_id))
224 h.flash(h.literal(_('Created user group %(user_group_link)s')
224 h.flash(h.literal(_('Created user group %(user_group_link)s')
225 % {'user_group_link': user_group_link}),
225 % {'user_group_link': user_group_link}),
226 category='success')
226 category='success')
227 Session().commit()
227 Session().commit()
228 user_group_id = user_group.users_group_id
228 user_group_id = user_group.users_group_id
229 except formencode.Invalid as errors:
229 except formencode.Invalid as errors:
230
230
231 data = render(
231 data = render(
232 'rhodecode:templates/admin/user_groups/user_group_add.mako',
232 'rhodecode:templates/admin/user_groups/user_group_add.mako',
233 self._get_template_context(c), self.request)
233 self._get_template_context(c), self.request)
234 html = formencode.htmlfill.render(
234 html = formencode.htmlfill.render(
235 data,
235 data,
236 defaults=errors.value,
236 defaults=errors.value,
237 errors=errors.error_dict or {},
237 errors=errors.error_dict or {},
238 prefix_error=False,
238 prefix_error=False,
239 encoding="UTF-8",
239 encoding="UTF-8",
240 force_defaults=False
240 force_defaults=False
241 )
241 )
242 return Response(html)
242 return Response(html)
243
243
244 except Exception:
244 except Exception:
245 log.exception("Exception creating user group")
245 log.exception("Exception creating user group")
246 h.flash(_('Error occurred during creation of user group %s') \
246 h.flash(_('Error occurred during creation of user group %s') \
247 % user_group_name, category='error')
247 % user_group_name, category='error')
248 raise HTTPFound(h.route_path('user_groups_new'))
248 raise HTTPFound(h.route_path('user_groups_new'))
249
249
250 affected_user_ids = [self._rhodecode_user.user_id]
250 PermissionModel().trigger_permission_flush()
251 PermissionModel().trigger_permission_flush(affected_user_ids)
252
251
253 raise HTTPFound(
252 raise HTTPFound(
254 h.route_path('edit_user_group', user_group_id=user_group_id))
253 h.route_path('edit_user_group', user_group_id=user_group_id))
General Comments 0
You need to be logged in to leave comments. Login now