##// END OF EJS Templates
user-groups: fix potential problem with group sync of external plugins....
marcink -
r2143:4314e88b default
parent child Browse files
Show More
@@ -1,641 +1,647 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2011-2017 RhodeCode GmbH
3 # Copyright (C) 2011-2017 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 import traceback
22 import traceback
23
23
24 from rhodecode.lib.utils2 import safe_str, safe_unicode
24 from rhodecode.lib.utils2 import safe_str, safe_unicode
25 from rhodecode.lib.exceptions import (
25 from rhodecode.lib.exceptions import (
26 UserGroupAssignedException, RepoGroupAssignmentError)
26 UserGroupAssignedException, RepoGroupAssignmentError)
27 from rhodecode.lib.utils2 import (
27 from rhodecode.lib.utils2 import (
28 get_current_rhodecode_user, action_logger_generic)
28 get_current_rhodecode_user, action_logger_generic)
29 from rhodecode.model import BaseModel
29 from rhodecode.model import BaseModel
30 from rhodecode.model.scm import UserGroupList
30 from rhodecode.model.scm import UserGroupList
31 from rhodecode.model.db import (
31 from rhodecode.model.db import (
32 true, func, User, UserGroupMember, UserGroup,
32 true, func, User, UserGroupMember, UserGroup,
33 UserGroupRepoToPerm, Permission, UserGroupToPerm, UserUserGroupToPerm,
33 UserGroupRepoToPerm, Permission, UserGroupToPerm, UserUserGroupToPerm,
34 UserGroupUserGroupToPerm, UserGroupRepoGroupToPerm)
34 UserGroupUserGroupToPerm, UserGroupRepoGroupToPerm)
35
35
36
36
37 log = logging.getLogger(__name__)
37 log = logging.getLogger(__name__)
38
38
39
39
40 class UserGroupModel(BaseModel):
40 class UserGroupModel(BaseModel):
41
41
42 cls = UserGroup
42 cls = UserGroup
43
43
44 def _get_user_group(self, user_group):
44 def _get_user_group(self, user_group):
45 return self._get_instance(UserGroup, user_group,
45 return self._get_instance(UserGroup, user_group,
46 callback=UserGroup.get_by_group_name)
46 callback=UserGroup.get_by_group_name)
47
47
48 def _create_default_perms(self, user_group):
48 def _create_default_perms(self, user_group):
49 # create default permission
49 # create default permission
50 default_perm = 'usergroup.read'
50 default_perm = 'usergroup.read'
51 def_user = User.get_default_user()
51 def_user = User.get_default_user()
52 for p in def_user.user_perms:
52 for p in def_user.user_perms:
53 if p.permission.permission_name.startswith('usergroup.'):
53 if p.permission.permission_name.startswith('usergroup.'):
54 default_perm = p.permission.permission_name
54 default_perm = p.permission.permission_name
55 break
55 break
56
56
57 user_group_to_perm = UserUserGroupToPerm()
57 user_group_to_perm = UserUserGroupToPerm()
58 user_group_to_perm.permission = Permission.get_by_key(default_perm)
58 user_group_to_perm.permission = Permission.get_by_key(default_perm)
59
59
60 user_group_to_perm.user_group = user_group
60 user_group_to_perm.user_group = user_group
61 user_group_to_perm.user_id = def_user.user_id
61 user_group_to_perm.user_id = def_user.user_id
62 return user_group_to_perm
62 return user_group_to_perm
63
63
64 def update_permissions(
64 def update_permissions(
65 self, user_group, perm_additions=None, perm_updates=None,
65 self, user_group, perm_additions=None, perm_updates=None,
66 perm_deletions=None, check_perms=True, cur_user=None):
66 perm_deletions=None, check_perms=True, cur_user=None):
67
67
68 from rhodecode.lib.auth import HasUserGroupPermissionAny
68 from rhodecode.lib.auth import HasUserGroupPermissionAny
69 if not perm_additions:
69 if not perm_additions:
70 perm_additions = []
70 perm_additions = []
71 if not perm_updates:
71 if not perm_updates:
72 perm_updates = []
72 perm_updates = []
73 if not perm_deletions:
73 if not perm_deletions:
74 perm_deletions = []
74 perm_deletions = []
75
75
76 req_perms = ('usergroup.read', 'usergroup.write', 'usergroup.admin')
76 req_perms = ('usergroup.read', 'usergroup.write', 'usergroup.admin')
77
77
78 changes = {
78 changes = {
79 'added': [],
79 'added': [],
80 'updated': [],
80 'updated': [],
81 'deleted': []
81 'deleted': []
82 }
82 }
83 # update permissions
83 # update permissions
84 for member_id, perm, member_type in perm_updates:
84 for member_id, perm, member_type in perm_updates:
85 member_id = int(member_id)
85 member_id = int(member_id)
86 if member_type == 'user':
86 if member_type == 'user':
87 member_name = User.get(member_id).username
87 member_name = User.get(member_id).username
88 # this updates existing one
88 # this updates existing one
89 self.grant_user_permission(
89 self.grant_user_permission(
90 user_group=user_group, user=member_id, perm=perm
90 user_group=user_group, user=member_id, perm=perm
91 )
91 )
92 else:
92 else:
93 # check if we have permissions to alter this usergroup
93 # check if we have permissions to alter this usergroup
94 member_name = UserGroup.get(member_id).users_group_name
94 member_name = UserGroup.get(member_id).users_group_name
95 if not check_perms or HasUserGroupPermissionAny(
95 if not check_perms or HasUserGroupPermissionAny(
96 *req_perms)(member_name, user=cur_user):
96 *req_perms)(member_name, user=cur_user):
97 self.grant_user_group_permission(
97 self.grant_user_group_permission(
98 target_user_group=user_group, user_group=member_id, perm=perm)
98 target_user_group=user_group, user_group=member_id, perm=perm)
99
99
100 changes['updated'].append({'type': member_type, 'id': member_id,
100 changes['updated'].append({'type': member_type, 'id': member_id,
101 'name': member_name, 'new_perm': perm})
101 'name': member_name, 'new_perm': perm})
102
102
103 # set new permissions
103 # set new permissions
104 for member_id, perm, member_type in perm_additions:
104 for member_id, perm, member_type in perm_additions:
105 member_id = int(member_id)
105 member_id = int(member_id)
106 if member_type == 'user':
106 if member_type == 'user':
107 member_name = User.get(member_id).username
107 member_name = User.get(member_id).username
108 self.grant_user_permission(
108 self.grant_user_permission(
109 user_group=user_group, user=member_id, perm=perm)
109 user_group=user_group, user=member_id, perm=perm)
110 else:
110 else:
111 # check if we have permissions to alter this usergroup
111 # check if we have permissions to alter this usergroup
112 member_name = UserGroup.get(member_id).users_group_name
112 member_name = UserGroup.get(member_id).users_group_name
113 if not check_perms or HasUserGroupPermissionAny(
113 if not check_perms or HasUserGroupPermissionAny(
114 *req_perms)(member_name, user=cur_user):
114 *req_perms)(member_name, user=cur_user):
115 self.grant_user_group_permission(
115 self.grant_user_group_permission(
116 target_user_group=user_group, user_group=member_id, perm=perm)
116 target_user_group=user_group, user_group=member_id, perm=perm)
117
117
118 changes['added'].append({'type': member_type, 'id': member_id,
118 changes['added'].append({'type': member_type, 'id': member_id,
119 'name': member_name, 'new_perm': perm})
119 'name': member_name, 'new_perm': perm})
120
120
121 # delete permissions
121 # delete permissions
122 for member_id, perm, member_type in perm_deletions:
122 for member_id, perm, member_type in perm_deletions:
123 member_id = int(member_id)
123 member_id = int(member_id)
124 if member_type == 'user':
124 if member_type == 'user':
125 member_name = User.get(member_id).username
125 member_name = User.get(member_id).username
126 self.revoke_user_permission(user_group=user_group, user=member_id)
126 self.revoke_user_permission(user_group=user_group, user=member_id)
127 else:
127 else:
128 # check if we have permissions to alter this usergroup
128 # check if we have permissions to alter this usergroup
129 member_name = UserGroup.get(member_id).users_group_name
129 member_name = UserGroup.get(member_id).users_group_name
130 if not check_perms or HasUserGroupPermissionAny(
130 if not check_perms or HasUserGroupPermissionAny(
131 *req_perms)(member_name, user=cur_user):
131 *req_perms)(member_name, user=cur_user):
132 self.revoke_user_group_permission(
132 self.revoke_user_group_permission(
133 target_user_group=user_group, user_group=member_id)
133 target_user_group=user_group, user_group=member_id)
134
134
135 changes['deleted'].append({'type': member_type, 'id': member_id,
135 changes['deleted'].append({'type': member_type, 'id': member_id,
136 'name': member_name, 'new_perm': perm})
136 'name': member_name, 'new_perm': perm})
137 return changes
137 return changes
138
138
139 def get(self, user_group_id, cache=False):
139 def get(self, user_group_id, cache=False):
140 return UserGroup.get(user_group_id)
140 return UserGroup.get(user_group_id)
141
141
142 def get_group(self, user_group):
142 def get_group(self, user_group):
143 return self._get_user_group(user_group)
143 return self._get_user_group(user_group)
144
144
145 def get_by_name(self, name, cache=False, case_insensitive=False):
145 def get_by_name(self, name, cache=False, case_insensitive=False):
146 return UserGroup.get_by_group_name(name, cache, case_insensitive)
146 return UserGroup.get_by_group_name(name, cache, case_insensitive)
147
147
148 def create(self, name, description, owner, active=True, group_data=None):
148 def create(self, name, description, owner, active=True, group_data=None):
149 try:
149 try:
150 new_user_group = UserGroup()
150 new_user_group = UserGroup()
151 new_user_group.user = self._get_user(owner)
151 new_user_group.user = self._get_user(owner)
152 new_user_group.users_group_name = name
152 new_user_group.users_group_name = name
153 new_user_group.user_group_description = description
153 new_user_group.user_group_description = description
154 new_user_group.users_group_active = active
154 new_user_group.users_group_active = active
155 if group_data:
155 if group_data:
156 new_user_group.group_data = group_data
156 new_user_group.group_data = group_data
157 self.sa.add(new_user_group)
157 self.sa.add(new_user_group)
158 perm_obj = self._create_default_perms(new_user_group)
158 perm_obj = self._create_default_perms(new_user_group)
159 self.sa.add(perm_obj)
159 self.sa.add(perm_obj)
160
160
161 self.grant_user_permission(user_group=new_user_group,
161 self.grant_user_permission(user_group=new_user_group,
162 user=owner, perm='usergroup.admin')
162 user=owner, perm='usergroup.admin')
163
163
164 return new_user_group
164 return new_user_group
165 except Exception:
165 except Exception:
166 log.error(traceback.format_exc())
166 log.error(traceback.format_exc())
167 raise
167 raise
168
168
169 def _get_memberships_for_user_ids(self, user_group, user_id_list):
169 def _get_memberships_for_user_ids(self, user_group, user_id_list):
170 members = []
170 members = []
171 for user_id in user_id_list:
171 for user_id in user_id_list:
172 member = self._get_membership(user_group.users_group_id, user_id)
172 member = self._get_membership(user_group.users_group_id, user_id)
173 members.append(member)
173 members.append(member)
174 return members
174 return members
175
175
176 def _get_added_and_removed_user_ids(self, user_group, user_id_list):
176 def _get_added_and_removed_user_ids(self, user_group, user_id_list):
177 current_members = user_group.members or []
177 current_members = user_group.members or []
178 current_members_ids = [m.user.user_id for m in current_members]
178 current_members_ids = [m.user.user_id for m in current_members]
179
179
180 added_members = [
180 added_members = [
181 user_id for user_id in user_id_list
181 user_id for user_id in user_id_list
182 if user_id not in current_members_ids]
182 if user_id not in current_members_ids]
183 if user_id_list == []:
183 if user_id_list == []:
184 # all members were deleted
184 # all members were deleted
185 deleted_members = current_members_ids
185 deleted_members = current_members_ids
186 else:
186 else:
187 deleted_members = [
187 deleted_members = [
188 user_id for user_id in current_members_ids
188 user_id for user_id in current_members_ids
189 if user_id not in user_id_list]
189 if user_id not in user_id_list]
190
190
191 return added_members, deleted_members
191 return added_members, deleted_members
192
192
193 def _set_users_as_members(self, user_group, user_ids):
193 def _set_users_as_members(self, user_group, user_ids):
194 user_group.members = []
194 user_group.members = []
195 self.sa.flush()
195 self.sa.flush()
196 members = self._get_memberships_for_user_ids(
196 members = self._get_memberships_for_user_ids(
197 user_group, user_ids)
197 user_group, user_ids)
198 user_group.members = members
198 user_group.members = members
199 self.sa.add(user_group)
199 self.sa.add(user_group)
200
200
201 def _update_members_from_user_ids(self, user_group, user_ids):
201 def _update_members_from_user_ids(self, user_group, user_ids):
202 added, removed = self._get_added_and_removed_user_ids(
202 added, removed = self._get_added_and_removed_user_ids(
203 user_group, user_ids)
203 user_group, user_ids)
204 self._set_users_as_members(user_group, user_ids)
204 self._set_users_as_members(user_group, user_ids)
205 self._log_user_changes('added to', user_group, added)
205 self._log_user_changes('added to', user_group, added)
206 self._log_user_changes('removed from', user_group, removed)
206 self._log_user_changes('removed from', user_group, removed)
207 return added, removed
207 return added, removed
208
208
209 def _clean_members_data(self, members_data):
209 def _clean_members_data(self, members_data):
210 if not members_data:
210 if not members_data:
211 members_data = []
211 members_data = []
212
212
213 members = []
213 members = []
214 for user in members_data:
214 for user in members_data:
215 uid = int(user['member_user_id'])
215 uid = int(user['member_user_id'])
216 if uid not in members and user['type'] in ['new', 'existing']:
216 if uid not in members and user['type'] in ['new', 'existing']:
217 members.append(uid)
217 members.append(uid)
218 return members
218 return members
219
219
220 def update(self, user_group, form_data):
220 def update(self, user_group, form_data):
221 user_group = self._get_user_group(user_group)
221 user_group = self._get_user_group(user_group)
222 if 'users_group_name' in form_data:
222 if 'users_group_name' in form_data:
223 user_group.users_group_name = form_data['users_group_name']
223 user_group.users_group_name = form_data['users_group_name']
224 if 'users_group_active' in form_data:
224 if 'users_group_active' in form_data:
225 user_group.users_group_active = form_data['users_group_active']
225 user_group.users_group_active = form_data['users_group_active']
226 if 'user_group_description' in form_data:
226 if 'user_group_description' in form_data:
227 user_group.user_group_description = form_data[
227 user_group.user_group_description = form_data[
228 'user_group_description']
228 'user_group_description']
229
229
230 # handle owner change
230 # handle owner change
231 if 'user' in form_data:
231 if 'user' in form_data:
232 owner = form_data['user']
232 owner = form_data['user']
233 if isinstance(owner, basestring):
233 if isinstance(owner, basestring):
234 owner = User.get_by_username(form_data['user'])
234 owner = User.get_by_username(form_data['user'])
235
235
236 if not isinstance(owner, User):
236 if not isinstance(owner, User):
237 raise ValueError(
237 raise ValueError(
238 'invalid owner for user group: %s' % form_data['user'])
238 'invalid owner for user group: %s' % form_data['user'])
239
239
240 user_group.user = owner
240 user_group.user = owner
241
241
242 added_user_ids = []
242 added_user_ids = []
243 removed_user_ids = []
243 removed_user_ids = []
244 if 'users_group_members' in form_data:
244 if 'users_group_members' in form_data:
245 members_id_list = self._clean_members_data(
245 members_id_list = self._clean_members_data(
246 form_data['users_group_members'])
246 form_data['users_group_members'])
247 added_user_ids, removed_user_ids = \
247 added_user_ids, removed_user_ids = \
248 self._update_members_from_user_ids(user_group, members_id_list)
248 self._update_members_from_user_ids(user_group, members_id_list)
249
249
250 self.sa.add(user_group)
250 self.sa.add(user_group)
251 return user_group, added_user_ids, removed_user_ids
251 return user_group, added_user_ids, removed_user_ids
252
252
253 def delete(self, user_group, force=False):
253 def delete(self, user_group, force=False):
254 """
254 """
255 Deletes repository group, unless force flag is used
255 Deletes repository group, unless force flag is used
256 raises exception if there are members in that group, else deletes
256 raises exception if there are members in that group, else deletes
257 group and users
257 group and users
258
258
259 :param user_group:
259 :param user_group:
260 :param force:
260 :param force:
261 """
261 """
262 user_group = self._get_user_group(user_group)
262 user_group = self._get_user_group(user_group)
263 if not user_group:
263 if not user_group:
264 return
264 return
265
265
266 try:
266 try:
267 # check if this group is not assigned to repo
267 # check if this group is not assigned to repo
268 assigned_to_repo = [x.repository for x in UserGroupRepoToPerm.query()\
268 assigned_to_repo = [x.repository for x in UserGroupRepoToPerm.query()\
269 .filter(UserGroupRepoToPerm.users_group == user_group).all()]
269 .filter(UserGroupRepoToPerm.users_group == user_group).all()]
270 # check if this group is not assigned to repo
270 # check if this group is not assigned to repo
271 assigned_to_repo_group = [x.group for x in UserGroupRepoGroupToPerm.query()\
271 assigned_to_repo_group = [x.group for x in UserGroupRepoGroupToPerm.query()\
272 .filter(UserGroupRepoGroupToPerm.users_group == user_group).all()]
272 .filter(UserGroupRepoGroupToPerm.users_group == user_group).all()]
273
273
274 if (assigned_to_repo or assigned_to_repo_group) and not force:
274 if (assigned_to_repo or assigned_to_repo_group) and not force:
275 assigned = ','.join(map(safe_str,
275 assigned = ','.join(map(safe_str,
276 assigned_to_repo+assigned_to_repo_group))
276 assigned_to_repo+assigned_to_repo_group))
277
277
278 raise UserGroupAssignedException(
278 raise UserGroupAssignedException(
279 'UserGroup assigned to %s' % (assigned,))
279 'UserGroup assigned to %s' % (assigned,))
280 self.sa.delete(user_group)
280 self.sa.delete(user_group)
281 except Exception:
281 except Exception:
282 log.error(traceback.format_exc())
282 log.error(traceback.format_exc())
283 raise
283 raise
284
284
285 def _log_user_changes(self, action, user_group, user_or_users):
285 def _log_user_changes(self, action, user_group, user_or_users):
286 users = user_or_users
286 users = user_or_users
287 if not isinstance(users, (list, tuple)):
287 if not isinstance(users, (list, tuple)):
288 users = [users]
288 users = [users]
289
289
290 group_name = user_group.users_group_name
290 group_name = user_group.users_group_name
291
291
292 for user_or_user_id in users:
292 for user_or_user_id in users:
293 user = self._get_user(user_or_user_id)
293 user = self._get_user(user_or_user_id)
294 log_text = 'User {user} {action} {group}'.format(
294 log_text = 'User {user} {action} {group}'.format(
295 action=action, user=user.username, group=group_name)
295 action=action, user=user.username, group=group_name)
296 action_logger_generic(log_text)
296 action_logger_generic(log_text)
297
297
298 def _find_user_in_group(self, user, user_group):
298 def _find_user_in_group(self, user, user_group):
299 user_group_member = None
299 user_group_member = None
300 for m in user_group.members:
300 for m in user_group.members:
301 if m.user_id == user.user_id:
301 if m.user_id == user.user_id:
302 # Found this user's membership row
302 # Found this user's membership row
303 user_group_member = m
303 user_group_member = m
304 break
304 break
305
305
306 return user_group_member
306 return user_group_member
307
307
308 def _get_membership(self, user_group_id, user_id):
308 def _get_membership(self, user_group_id, user_id):
309 user_group_member = UserGroupMember(user_group_id, user_id)
309 user_group_member = UserGroupMember(user_group_id, user_id)
310 return user_group_member
310 return user_group_member
311
311
312 def add_user_to_group(self, user_group, user):
312 def add_user_to_group(self, user_group, user):
313 user_group = self._get_user_group(user_group)
313 user_group = self._get_user_group(user_group)
314 user = self._get_user(user)
314 user = self._get_user(user)
315 user_member = self._find_user_in_group(user, user_group)
315 user_member = self._find_user_in_group(user, user_group)
316 if user_member:
316 if user_member:
317 # user already in the group, skip
317 # user already in the group, skip
318 return True
318 return True
319
319
320 member = self._get_membership(
320 member = self._get_membership(
321 user_group.users_group_id, user.user_id)
321 user_group.users_group_id, user.user_id)
322 user_group.members.append(member)
322 user_group.members.append(member)
323
323
324 try:
324 try:
325 self.sa.add(member)
325 self.sa.add(member)
326 except Exception:
326 except Exception:
327 # what could go wrong here?
327 # what could go wrong here?
328 log.error(traceback.format_exc())
328 log.error(traceback.format_exc())
329 raise
329 raise
330
330
331 self._log_user_changes('added to', user_group, user)
331 self._log_user_changes('added to', user_group, user)
332 return member
332 return member
333
333
334 def remove_user_from_group(self, user_group, user):
334 def remove_user_from_group(self, user_group, user):
335 user_group = self._get_user_group(user_group)
335 user_group = self._get_user_group(user_group)
336 user = self._get_user(user)
336 user = self._get_user(user)
337 user_group_member = self._find_user_in_group(user, user_group)
337 user_group_member = self._find_user_in_group(user, user_group)
338
338
339 if not user_group_member:
339 if not user_group_member:
340 # User isn't in that group
340 # User isn't in that group
341 return False
341 return False
342
342
343 try:
343 try:
344 self.sa.delete(user_group_member)
344 self.sa.delete(user_group_member)
345 except Exception:
345 except Exception:
346 log.error(traceback.format_exc())
346 log.error(traceback.format_exc())
347 raise
347 raise
348
348
349 self._log_user_changes('removed from', user_group, user)
349 self._log_user_changes('removed from', user_group, user)
350 return True
350 return True
351
351
352 def has_perm(self, user_group, perm):
352 def has_perm(self, user_group, perm):
353 user_group = self._get_user_group(user_group)
353 user_group = self._get_user_group(user_group)
354 perm = self._get_perm(perm)
354 perm = self._get_perm(perm)
355
355
356 return UserGroupToPerm.query()\
356 return UserGroupToPerm.query()\
357 .filter(UserGroupToPerm.users_group == user_group)\
357 .filter(UserGroupToPerm.users_group == user_group)\
358 .filter(UserGroupToPerm.permission == perm).scalar() is not None
358 .filter(UserGroupToPerm.permission == perm).scalar() is not None
359
359
360 def grant_perm(self, user_group, perm):
360 def grant_perm(self, user_group, perm):
361 user_group = self._get_user_group(user_group)
361 user_group = self._get_user_group(user_group)
362 perm = self._get_perm(perm)
362 perm = self._get_perm(perm)
363
363
364 # if this permission is already granted skip it
364 # if this permission is already granted skip it
365 _perm = UserGroupToPerm.query()\
365 _perm = UserGroupToPerm.query()\
366 .filter(UserGroupToPerm.users_group == user_group)\
366 .filter(UserGroupToPerm.users_group == user_group)\
367 .filter(UserGroupToPerm.permission == perm)\
367 .filter(UserGroupToPerm.permission == perm)\
368 .scalar()
368 .scalar()
369 if _perm:
369 if _perm:
370 return
370 return
371
371
372 new = UserGroupToPerm()
372 new = UserGroupToPerm()
373 new.users_group = user_group
373 new.users_group = user_group
374 new.permission = perm
374 new.permission = perm
375 self.sa.add(new)
375 self.sa.add(new)
376 return new
376 return new
377
377
378 def revoke_perm(self, user_group, perm):
378 def revoke_perm(self, user_group, perm):
379 user_group = self._get_user_group(user_group)
379 user_group = self._get_user_group(user_group)
380 perm = self._get_perm(perm)
380 perm = self._get_perm(perm)
381
381
382 obj = UserGroupToPerm.query()\
382 obj = UserGroupToPerm.query()\
383 .filter(UserGroupToPerm.users_group == user_group)\
383 .filter(UserGroupToPerm.users_group == user_group)\
384 .filter(UserGroupToPerm.permission == perm).scalar()
384 .filter(UserGroupToPerm.permission == perm).scalar()
385 if obj:
385 if obj:
386 self.sa.delete(obj)
386 self.sa.delete(obj)
387
387
388 def grant_user_permission(self, user_group, user, perm):
388 def grant_user_permission(self, user_group, user, perm):
389 """
389 """
390 Grant permission for user on given user group, or update
390 Grant permission for user on given user group, or update
391 existing one if found
391 existing one if found
392
392
393 :param user_group: Instance of UserGroup, users_group_id,
393 :param user_group: Instance of UserGroup, users_group_id,
394 or users_group_name
394 or users_group_name
395 :param user: Instance of User, user_id or username
395 :param user: Instance of User, user_id or username
396 :param perm: Instance of Permission, or permission_name
396 :param perm: Instance of Permission, or permission_name
397 """
397 """
398
398
399 user_group = self._get_user_group(user_group)
399 user_group = self._get_user_group(user_group)
400 user = self._get_user(user)
400 user = self._get_user(user)
401 permission = self._get_perm(perm)
401 permission = self._get_perm(perm)
402
402
403 # check if we have that permission already
403 # check if we have that permission already
404 obj = self.sa.query(UserUserGroupToPerm)\
404 obj = self.sa.query(UserUserGroupToPerm)\
405 .filter(UserUserGroupToPerm.user == user)\
405 .filter(UserUserGroupToPerm.user == user)\
406 .filter(UserUserGroupToPerm.user_group == user_group)\
406 .filter(UserUserGroupToPerm.user_group == user_group)\
407 .scalar()
407 .scalar()
408 if obj is None:
408 if obj is None:
409 # create new !
409 # create new !
410 obj = UserUserGroupToPerm()
410 obj = UserUserGroupToPerm()
411 obj.user_group = user_group
411 obj.user_group = user_group
412 obj.user = user
412 obj.user = user
413 obj.permission = permission
413 obj.permission = permission
414 self.sa.add(obj)
414 self.sa.add(obj)
415 log.debug('Granted perm %s to %s on %s', perm, user, user_group)
415 log.debug('Granted perm %s to %s on %s', perm, user, user_group)
416 action_logger_generic(
416 action_logger_generic(
417 'granted permission: {} to user: {} on usergroup: {}'.format(
417 'granted permission: {} to user: {} on usergroup: {}'.format(
418 perm, user, user_group), namespace='security.usergroup')
418 perm, user, user_group), namespace='security.usergroup')
419
419
420 return obj
420 return obj
421
421
422 def revoke_user_permission(self, user_group, user):
422 def revoke_user_permission(self, user_group, user):
423 """
423 """
424 Revoke permission for user on given user group
424 Revoke permission for user on given user group
425
425
426 :param user_group: Instance of UserGroup, users_group_id,
426 :param user_group: Instance of UserGroup, users_group_id,
427 or users_group name
427 or users_group name
428 :param user: Instance of User, user_id or username
428 :param user: Instance of User, user_id or username
429 """
429 """
430
430
431 user_group = self._get_user_group(user_group)
431 user_group = self._get_user_group(user_group)
432 user = self._get_user(user)
432 user = self._get_user(user)
433
433
434 obj = self.sa.query(UserUserGroupToPerm)\
434 obj = self.sa.query(UserUserGroupToPerm)\
435 .filter(UserUserGroupToPerm.user == user)\
435 .filter(UserUserGroupToPerm.user == user)\
436 .filter(UserUserGroupToPerm.user_group == user_group)\
436 .filter(UserUserGroupToPerm.user_group == user_group)\
437 .scalar()
437 .scalar()
438 if obj:
438 if obj:
439 self.sa.delete(obj)
439 self.sa.delete(obj)
440 log.debug('Revoked perm on %s on %s', user_group, user)
440 log.debug('Revoked perm on %s on %s', user_group, user)
441 action_logger_generic(
441 action_logger_generic(
442 'revoked permission from user: {} on usergroup: {}'.format(
442 'revoked permission from user: {} on usergroup: {}'.format(
443 user, user_group), namespace='security.usergroup')
443 user, user_group), namespace='security.usergroup')
444
444
445 def grant_user_group_permission(self, target_user_group, user_group, perm):
445 def grant_user_group_permission(self, target_user_group, user_group, perm):
446 """
446 """
447 Grant user group permission for given target_user_group
447 Grant user group permission for given target_user_group
448
448
449 :param target_user_group:
449 :param target_user_group:
450 :param user_group:
450 :param user_group:
451 :param perm:
451 :param perm:
452 """
452 """
453 target_user_group = self._get_user_group(target_user_group)
453 target_user_group = self._get_user_group(target_user_group)
454 user_group = self._get_user_group(user_group)
454 user_group = self._get_user_group(user_group)
455 permission = self._get_perm(perm)
455 permission = self._get_perm(perm)
456 # forbid assigning same user group to itself
456 # forbid assigning same user group to itself
457 if target_user_group == user_group:
457 if target_user_group == user_group:
458 raise RepoGroupAssignmentError('target repo:%s cannot be '
458 raise RepoGroupAssignmentError('target repo:%s cannot be '
459 'assigned to itself' % target_user_group)
459 'assigned to itself' % target_user_group)
460
460
461 # check if we have that permission already
461 # check if we have that permission already
462 obj = self.sa.query(UserGroupUserGroupToPerm)\
462 obj = self.sa.query(UserGroupUserGroupToPerm)\
463 .filter(UserGroupUserGroupToPerm.target_user_group == target_user_group)\
463 .filter(UserGroupUserGroupToPerm.target_user_group == target_user_group)\
464 .filter(UserGroupUserGroupToPerm.user_group == user_group)\
464 .filter(UserGroupUserGroupToPerm.user_group == user_group)\
465 .scalar()
465 .scalar()
466 if obj is None:
466 if obj is None:
467 # create new !
467 # create new !
468 obj = UserGroupUserGroupToPerm()
468 obj = UserGroupUserGroupToPerm()
469 obj.user_group = user_group
469 obj.user_group = user_group
470 obj.target_user_group = target_user_group
470 obj.target_user_group = target_user_group
471 obj.permission = permission
471 obj.permission = permission
472 self.sa.add(obj)
472 self.sa.add(obj)
473 log.debug(
473 log.debug(
474 'Granted perm %s to %s on %s', perm, target_user_group, user_group)
474 'Granted perm %s to %s on %s', perm, target_user_group, user_group)
475 action_logger_generic(
475 action_logger_generic(
476 'granted permission: {} to usergroup: {} on usergroup: {}'.format(
476 'granted permission: {} to usergroup: {} on usergroup: {}'.format(
477 perm, user_group, target_user_group),
477 perm, user_group, target_user_group),
478 namespace='security.usergroup')
478 namespace='security.usergroup')
479
479
480 return obj
480 return obj
481
481
482 def revoke_user_group_permission(self, target_user_group, user_group):
482 def revoke_user_group_permission(self, target_user_group, user_group):
483 """
483 """
484 Revoke user group permission for given target_user_group
484 Revoke user group permission for given target_user_group
485
485
486 :param target_user_group:
486 :param target_user_group:
487 :param user_group:
487 :param user_group:
488 """
488 """
489 target_user_group = self._get_user_group(target_user_group)
489 target_user_group = self._get_user_group(target_user_group)
490 user_group = self._get_user_group(user_group)
490 user_group = self._get_user_group(user_group)
491
491
492 obj = self.sa.query(UserGroupUserGroupToPerm)\
492 obj = self.sa.query(UserGroupUserGroupToPerm)\
493 .filter(UserGroupUserGroupToPerm.target_user_group == target_user_group)\
493 .filter(UserGroupUserGroupToPerm.target_user_group == target_user_group)\
494 .filter(UserGroupUserGroupToPerm.user_group == user_group)\
494 .filter(UserGroupUserGroupToPerm.user_group == user_group)\
495 .scalar()
495 .scalar()
496 if obj:
496 if obj:
497 self.sa.delete(obj)
497 self.sa.delete(obj)
498 log.debug(
498 log.debug(
499 'Revoked perm on %s on %s', target_user_group, user_group)
499 'Revoked perm on %s on %s', target_user_group, user_group)
500 action_logger_generic(
500 action_logger_generic(
501 'revoked permission from usergroup: {} on usergroup: {}'.format(
501 'revoked permission from usergroup: {} on usergroup: {}'.format(
502 user_group, target_user_group),
502 user_group, target_user_group),
503 namespace='security.repogroup')
503 namespace='security.repogroup')
504
504
505 def enforce_groups(self, user, groups, extern_type=None):
505 def enforce_groups(self, user, groups, extern_type=None):
506 user = self._get_user(user)
506 user = self._get_user(user)
507 log.debug('Enforcing groups %s on user %s', groups, user)
508 current_groups = user.group_member
507 current_groups = user.group_member
509 # find the external created groups
510 externals = [x.users_group for x in current_groups
511 if 'extern_type' in x.users_group.group_data]
512
508
509 # find the external created groups, i.e automatically created
510 log.debug('Enforcing user group set `%s` on user %s', groups, user)
513 # calculate from what groups user should be removed
511 # calculate from what groups user should be removed
514 # externals that are not in groups
512 # external_groups that are not in groups
515 for gr in externals:
513 for gr in [x.users_group for x in current_groups]:
516 if gr.users_group_name not in groups:
514 managed = gr.group_data.get('extern_type')
517 log.debug('Removing user %s from user group %s', user, gr)
515 if managed:
518 self.remove_user_from_group(gr, user)
516 if gr.users_group_name not in groups:
517 log.debug('Removing user %s from user group %s. '
518 'Group sync managed by: %s', user, gr, managed)
519 self.remove_user_from_group(gr, user)
520 else:
521 log.debug('Skipping removal from group %s since it is '
522 'not set to be automatically synchronized' % gr)
519
523
520 # now we calculate in which groups user should be == groups params
524 # now we calculate in which groups user should be == groups params
521 owner = User.get_first_super_admin().username
525 owner = User.get_first_super_admin().username
522 for gr in set(groups):
526 for gr in set(groups):
523 existing_group = UserGroup.get_by_group_name(gr)
527 existing_group = UserGroup.get_by_group_name(gr)
524 if not existing_group:
528 if not existing_group:
525 desc = 'Automatically created from plugin:%s' % extern_type
529 desc = 'Automatically created from plugin:%s' % extern_type
526 # we use first admin account to set the owner of the group
530 # we use first admin account to set the owner of the group
527 existing_group = UserGroupModel().create(
531 existing_group = UserGroupModel().create(
528 gr, desc, owner, group_data={'extern_type': extern_type})
532 gr, desc, owner, group_data={'extern_type': extern_type})
529
533
530 # we can only add users to special groups created via plugins
534 # we can only add users to groups which have set sync flag via
531 managed = 'extern_type' in existing_group.group_data
535 # extern_type attribute.
536 # This is either set and created via plugins, or manually
537 managed = existing_group.group_data.get('extern_type')
532 if managed:
538 if managed:
533 log.debug('Adding user %s to user group %s', user, gr)
539 log.debug('Adding user %s to user group %s', user, gr)
534 UserGroupModel().add_user_to_group(existing_group, user)
540 UserGroupModel().add_user_to_group(existing_group, user)
535 else:
541 else:
536 log.debug('Skipping addition to group %s since it is '
542 log.debug('Skipping addition to group %s since it is '
537 'not set to be automatically synchronized' % gr)
543 'not set to be automatically synchronized' % gr)
538
544
539 def change_groups(self, user, groups):
545 def change_groups(self, user, groups):
540 """
546 """
541 This method changes user group assignment
547 This method changes user group assignment
542 :param user: User
548 :param user: User
543 :param groups: array of UserGroupModel
549 :param groups: array of UserGroupModel
544 """
550 """
545 user = self._get_user(user)
551 user = self._get_user(user)
546 log.debug('Changing user(%s) assignment to groups(%s)', user, groups)
552 log.debug('Changing user(%s) assignment to groups(%s)', user, groups)
547 current_groups = user.group_member
553 current_groups = user.group_member
548 current_groups = [x.users_group for x in current_groups]
554 current_groups = [x.users_group for x in current_groups]
549
555
550 # calculate from what groups user should be removed/add
556 # calculate from what groups user should be removed/add
551 groups = set(groups)
557 groups = set(groups)
552 current_groups = set(current_groups)
558 current_groups = set(current_groups)
553
559
554 groups_to_remove = current_groups - groups
560 groups_to_remove = current_groups - groups
555 groups_to_add = groups - current_groups
561 groups_to_add = groups - current_groups
556
562
557 removed_from_groups = []
563 removed_from_groups = []
558 added_to_groups = []
564 added_to_groups = []
559 for gr in groups_to_remove:
565 for gr in groups_to_remove:
560 log.debug('Removing user %s from user group %s',
566 log.debug('Removing user %s from user group %s',
561 user.username, gr.users_group_name)
567 user.username, gr.users_group_name)
562 removed_from_groups.append(gr.users_group_id)
568 removed_from_groups.append(gr.users_group_id)
563 self.remove_user_from_group(gr.users_group_name, user.username)
569 self.remove_user_from_group(gr.users_group_name, user.username)
564 for gr in groups_to_add:
570 for gr in groups_to_add:
565 log.debug('Adding user %s to user group %s',
571 log.debug('Adding user %s to user group %s',
566 user.username, gr.users_group_name)
572 user.username, gr.users_group_name)
567 added_to_groups.append(gr.users_group_id)
573 added_to_groups.append(gr.users_group_id)
568 UserGroupModel().add_user_to_group(
574 UserGroupModel().add_user_to_group(
569 gr.users_group_name, user.username)
575 gr.users_group_name, user.username)
570
576
571 return added_to_groups, removed_from_groups
577 return added_to_groups, removed_from_groups
572
578
573 def _serialize_user_group(self, user_group):
579 def _serialize_user_group(self, user_group):
574 import rhodecode.lib.helpers as h
580 import rhodecode.lib.helpers as h
575 return {
581 return {
576 'id': user_group.users_group_id,
582 'id': user_group.users_group_id,
577 # TODO: marcink figure out a way to generate the url for the
583 # TODO: marcink figure out a way to generate the url for the
578 # icon
584 # icon
579 'icon_link': '',
585 'icon_link': '',
580 'value_display': 'Group: %s (%d members)' % (
586 'value_display': 'Group: %s (%d members)' % (
581 user_group.users_group_name, len(user_group.members),),
587 user_group.users_group_name, len(user_group.members),),
582 'value': user_group.users_group_name,
588 'value': user_group.users_group_name,
583 'description': user_group.user_group_description,
589 'description': user_group.user_group_description,
584 'owner': user_group.user.username,
590 'owner': user_group.user.username,
585
591
586 'owner_icon': h.gravatar_url(user_group.user.email, 30),
592 'owner_icon': h.gravatar_url(user_group.user.email, 30),
587 'value_display_owner': h.person(user_group.user.email),
593 'value_display_owner': h.person(user_group.user.email),
588
594
589 'value_type': 'user_group',
595 'value_type': 'user_group',
590 'active': user_group.users_group_active,
596 'active': user_group.users_group_active,
591 }
597 }
592
598
593 def get_user_groups(self, name_contains=None, limit=20, only_active=True,
599 def get_user_groups(self, name_contains=None, limit=20, only_active=True,
594 expand_groups=False):
600 expand_groups=False):
595 query = self.sa.query(UserGroup)
601 query = self.sa.query(UserGroup)
596 if only_active:
602 if only_active:
597 query = query.filter(UserGroup.users_group_active == true())
603 query = query.filter(UserGroup.users_group_active == true())
598
604
599 if name_contains:
605 if name_contains:
600 ilike_expression = u'%{}%'.format(safe_unicode(name_contains))
606 ilike_expression = u'%{}%'.format(safe_unicode(name_contains))
601 query = query.filter(
607 query = query.filter(
602 UserGroup.users_group_name.ilike(ilike_expression))\
608 UserGroup.users_group_name.ilike(ilike_expression))\
603 .order_by(func.length(UserGroup.users_group_name))\
609 .order_by(func.length(UserGroup.users_group_name))\
604 .order_by(UserGroup.users_group_name)
610 .order_by(UserGroup.users_group_name)
605
611
606 query = query.limit(limit)
612 query = query.limit(limit)
607 user_groups = query.all()
613 user_groups = query.all()
608 perm_set = ['usergroup.read', 'usergroup.write', 'usergroup.admin']
614 perm_set = ['usergroup.read', 'usergroup.write', 'usergroup.admin']
609 user_groups = UserGroupList(user_groups, perm_set=perm_set)
615 user_groups = UserGroupList(user_groups, perm_set=perm_set)
610
616
611 # store same serialize method to extract data from User
617 # store same serialize method to extract data from User
612 from rhodecode.model.user import UserModel
618 from rhodecode.model.user import UserModel
613 serialize_user = UserModel()._serialize_user
619 serialize_user = UserModel()._serialize_user
614
620
615 _groups = []
621 _groups = []
616 for group in user_groups:
622 for group in user_groups:
617 entry = self._serialize_user_group(group)
623 entry = self._serialize_user_group(group)
618 if expand_groups:
624 if expand_groups:
619 expanded_members = []
625 expanded_members = []
620 for member in group.members:
626 for member in group.members:
621 expanded_members.append(serialize_user(member.user))
627 expanded_members.append(serialize_user(member.user))
622 entry['members'] = expanded_members
628 entry['members'] = expanded_members
623 _groups.append(entry)
629 _groups.append(entry)
624 return _groups
630 return _groups
625
631
626 @staticmethod
632 @staticmethod
627 def get_user_groups_as_dict(user_group):
633 def get_user_groups_as_dict(user_group):
628 import rhodecode.lib.helpers as h
634 import rhodecode.lib.helpers as h
629
635
630 data = {
636 data = {
631 'users_group_id': user_group.users_group_id,
637 'users_group_id': user_group.users_group_id,
632 'group_name': user_group.users_group_name,
638 'group_name': user_group.users_group_name,
633 'group_description': user_group.user_group_description,
639 'group_description': user_group.user_group_description,
634 'active': user_group.users_group_active,
640 'active': user_group.users_group_active,
635 "owner": user_group.user.username,
641 "owner": user_group.user.username,
636 'owner_icon': h.gravatar_url(user_group.user.email, 30),
642 'owner_icon': h.gravatar_url(user_group.user.email, 30),
637 "owner_data": {
643 "owner_data": {
638 'owner': user_group.user.username,
644 'owner': user_group.user.username,
639 'owner_icon': h.gravatar_url(user_group.user.email, 30)}
645 'owner_icon': h.gravatar_url(user_group.user.email, 30)}
640 }
646 }
641 return data
647 return data
General Comments 0
You need to be logged in to leave comments. Login now