Mercurial > kallithea
comparison rhodecode/model/user_group.py @ 4116:ffd45b185016 rhodecode-2.2.5-gpl
Imported some of the GPLv3'd changes from RhodeCode v2.2.5.
This imports changes between changesets 21af6c4eab3d and 6177597791c2 in
RhodeCode's original repository, including only changes to Python files and HTML.
RhodeCode clearly licensed its changes to these files under GPLv3
in their /LICENSE file, which states the following:
The Python code and integrated HTML are licensed under the GPLv3 license.
(See:
https://code.rhodecode.com/rhodecode/files/v2.2.5/LICENSE
or
http://web.archive.org/web/20140512193334/https://code.rhodecode.com/rhodecode/files/f3b123159901f15426d18e3dc395e8369f70ebe0/LICENSE
for an online copy of that LICENSE file)
Conservancy reviewed these changes and confirmed that they can be licensed as
a whole to the Kallithea project under GPLv3-only.
While some of the contents committed herein are clearly licensed
GPLv3-or-later, on the whole we must assume the are GPLv3-only, since the
statement above from RhodeCode indicates that they intend GPLv3-only as their
license, per GPLv3ยง14 and other relevant sections of GPLv3.
author | Bradley M. Kuhn <bkuhn@sfconservancy.org> |
---|---|
date | Wed, 02 Jul 2014 19:03:13 -0400 |
parents | |
children | 7e5f8c12a3fc |
comparison
equal
deleted
inserted
replaced
4115:8b7294a804a0 | 4116:ffd45b185016 |
---|---|
1 # -*- coding: utf-8 -*- | |
2 # This program is free software: you can redistribute it and/or modify | |
3 # it under the terms of the GNU General Public License as published by | |
4 # the Free Software Foundation, either version 3 of the License, or | |
5 # (at your option) any later version. | |
6 # | |
7 # This program is distributed in the hope that it will be useful, | |
8 # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
9 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
10 # GNU General Public License for more details. | |
11 # | |
12 # You should have received a copy of the GNU General Public License | |
13 # along with this program. If not, see <http://www.gnu.org/licenses/>. | |
14 """ | |
15 rhodecode.model.users_group | |
16 ~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
17 | |
18 user group model for RhodeCode | |
19 | |
20 :created_on: Oct 1, 2011 | |
21 :author: nvinot, marcink | |
22 """ | |
23 | |
24 | |
25 import logging | |
26 import traceback | |
27 | |
28 from rhodecode.model import BaseModel | |
29 from rhodecode.model.db import UserGroupMember, UserGroup,\ | |
30 UserGroupRepoToPerm, Permission, UserGroupToPerm, User, UserUserGroupToPerm,\ | |
31 UserGroupUserGroupToPerm | |
32 from rhodecode.lib.exceptions import UserGroupsAssignedException,\ | |
33 RepoGroupAssignmentError | |
34 | |
35 log = logging.getLogger(__name__) | |
36 | |
37 | |
38 class UserGroupModel(BaseModel): | |
39 | |
40 cls = UserGroup | |
41 | |
42 def _get_user_group(self, user_group): | |
43 return self._get_instance(UserGroup, user_group, | |
44 callback=UserGroup.get_by_group_name) | |
45 | |
46 def _create_default_perms(self, user_group): | |
47 # create default permission | |
48 default_perm = 'usergroup.read' | |
49 def_user = User.get_default_user() | |
50 for p in def_user.user_perms: | |
51 if p.permission.permission_name.startswith('usergroup.'): | |
52 default_perm = p.permission.permission_name | |
53 break | |
54 | |
55 user_group_to_perm = UserUserGroupToPerm() | |
56 user_group_to_perm.permission = Permission.get_by_key(default_perm) | |
57 | |
58 user_group_to_perm.user_group = user_group | |
59 user_group_to_perm.user_id = def_user.user_id | |
60 return user_group_to_perm | |
61 | |
62 def _update_permissions(self, user_group, perms_new=None, | |
63 perms_updates=None): | |
64 from rhodecode.lib.auth import HasUserGroupPermissionAny | |
65 if not perms_new: | |
66 perms_new = [] | |
67 if not perms_updates: | |
68 perms_updates = [] | |
69 | |
70 # update permissions | |
71 for member, perm, member_type in perms_updates: | |
72 if member_type == 'user': | |
73 # this updates existing one | |
74 self.grant_user_permission( | |
75 user_group=user_group, user=member, perm=perm | |
76 ) | |
77 else: | |
78 #check if we have permissions to alter this usergroup | |
79 if HasUserGroupPermissionAny('usergroup.read', 'usergroup.write', | |
80 'usergroup.admin')(member): | |
81 self.grant_user_group_permission( | |
82 target_user_group=user_group, user_group=member, perm=perm | |
83 ) | |
84 # set new permissions | |
85 for member, perm, member_type in perms_new: | |
86 if member_type == 'user': | |
87 self.grant_user_permission( | |
88 user_group=user_group, user=member, perm=perm | |
89 ) | |
90 else: | |
91 #check if we have permissions to alter this usergroup | |
92 if HasUserGroupPermissionAny('usergroup.read', 'usergroup.write', | |
93 'usergroup.admin')(member): | |
94 self.grant_user_group_permission( | |
95 target_user_group=user_group, user_group=member, perm=perm | |
96 ) | |
97 | |
98 def get(self, user_group_id, cache=False): | |
99 return UserGroup.get(user_group_id) | |
100 | |
101 def get_group(self, user_group): | |
102 return self._get_user_group(user_group) | |
103 | |
104 def get_by_name(self, name, cache=False, case_insensitive=False): | |
105 return UserGroup.get_by_group_name(name, cache, case_insensitive) | |
106 | |
107 def create(self, name, description, owner, active=True, group_data=None): | |
108 try: | |
109 new_user_group = UserGroup() | |
110 new_user_group.user = self._get_user(owner) | |
111 new_user_group.users_group_name = name | |
112 new_user_group.user_group_description = description | |
113 new_user_group.users_group_active = active | |
114 if group_data: | |
115 new_user_group.group_data = group_data | |
116 self.sa.add(new_user_group) | |
117 perm_obj = self._create_default_perms(new_user_group) | |
118 self.sa.add(perm_obj) | |
119 | |
120 self.grant_user_permission(user_group=new_user_group, | |
121 user=owner, perm='usergroup.admin') | |
122 | |
123 return new_user_group | |
124 except Exception: | |
125 log.error(traceback.format_exc()) | |
126 raise | |
127 | |
128 def update(self, user_group, form_data): | |
129 | |
130 try: | |
131 user_group = self._get_user_group(user_group) | |
132 | |
133 for k, v in form_data.items(): | |
134 if k == 'users_group_members': | |
135 user_group.members = [] | |
136 self.sa.flush() | |
137 members_list = [] | |
138 if v: | |
139 v = [v] if isinstance(v, basestring) else v | |
140 for u_id in set(v): | |
141 member = UserGroupMember(user_group.users_group_id, u_id) | |
142 members_list.append(member) | |
143 setattr(user_group, 'members', members_list) | |
144 setattr(user_group, k, v) | |
145 | |
146 self.sa.add(user_group) | |
147 except Exception: | |
148 log.error(traceback.format_exc()) | |
149 raise | |
150 | |
151 def delete(self, user_group, force=False): | |
152 """ | |
153 Deletes repository group, unless force flag is used | |
154 raises exception if there are members in that group, else deletes | |
155 group and users | |
156 | |
157 :param user_group: | |
158 :param force: | |
159 """ | |
160 user_group = self._get_user_group(user_group) | |
161 try: | |
162 # check if this group is not assigned to repo | |
163 assigned_groups = UserGroupRepoToPerm.query()\ | |
164 .filter(UserGroupRepoToPerm.users_group == user_group).all() | |
165 | |
166 if assigned_groups and not force: | |
167 raise UserGroupsAssignedException( | |
168 'RepoGroup assigned to %s' % assigned_groups) | |
169 self.sa.delete(user_group) | |
170 except Exception: | |
171 log.error(traceback.format_exc()) | |
172 raise | |
173 | |
174 def add_user_to_group(self, user_group, user): | |
175 user_group = self._get_user_group(user_group) | |
176 user = self._get_user(user) | |
177 | |
178 for m in user_group.members: | |
179 u = m.user | |
180 if u.user_id == user.user_id: | |
181 # user already in the group, skip | |
182 return True | |
183 | |
184 try: | |
185 user_group_member = UserGroupMember() | |
186 user_group_member.user = user | |
187 user_group_member.users_group = user_group | |
188 | |
189 user_group.members.append(user_group_member) | |
190 user.group_member.append(user_group_member) | |
191 | |
192 self.sa.add(user_group_member) | |
193 return user_group_member | |
194 except Exception: | |
195 log.error(traceback.format_exc()) | |
196 raise | |
197 | |
198 def remove_user_from_group(self, user_group, user): | |
199 user_group = self._get_user_group(user_group) | |
200 user = self._get_user(user) | |
201 | |
202 user_group_member = None | |
203 for m in user_group.members: | |
204 if m.user.user_id == user.user_id: | |
205 # Found this user's membership row | |
206 user_group_member = m | |
207 break | |
208 | |
209 if user_group_member: | |
210 try: | |
211 self.sa.delete(user_group_member) | |
212 return True | |
213 except Exception: | |
214 log.error(traceback.format_exc()) | |
215 raise | |
216 else: | |
217 # User isn't in that group | |
218 return False | |
219 | |
220 def has_perm(self, user_group, perm): | |
221 user_group = self._get_user_group(user_group) | |
222 perm = self._get_perm(perm) | |
223 | |
224 return UserGroupToPerm.query()\ | |
225 .filter(UserGroupToPerm.users_group == user_group)\ | |
226 .filter(UserGroupToPerm.permission == perm).scalar() is not None | |
227 | |
228 def grant_perm(self, user_group, perm): | |
229 user_group = self._get_user_group(user_group) | |
230 perm = self._get_perm(perm) | |
231 | |
232 # if this permission is already granted skip it | |
233 _perm = UserGroupToPerm.query()\ | |
234 .filter(UserGroupToPerm.users_group == user_group)\ | |
235 .filter(UserGroupToPerm.permission == perm)\ | |
236 .scalar() | |
237 if _perm: | |
238 return | |
239 | |
240 new = UserGroupToPerm() | |
241 new.users_group = user_group | |
242 new.permission = perm | |
243 self.sa.add(new) | |
244 return new | |
245 | |
246 def revokehas_permrevoke_permgrant_perm_perm(self, user_group, perm): | |
247 user_group = self._get_user_group(user_group) | |
248 perm = self._get_perm(perm) | |
249 | |
250 obj = UserGroupToPerm.query()\ | |
251 .filter(UserGroupToPerm.users_group == user_group)\ | |
252 .filter(UserGroupToPerm.permission == perm).scalar() | |
253 if obj: | |
254 self.sa.delete(obj) | |
255 | |
256 def grant_user_permission(self, user_group, user, perm): | |
257 """ | |
258 Grant permission for user on given user group, or update | |
259 existing one if found | |
260 | |
261 :param user_group: Instance of UserGroup, users_group_id, | |
262 or users_group_name | |
263 :param user: Instance of User, user_id or username | |
264 :param perm: Instance of Permission, or permission_name | |
265 """ | |
266 | |
267 user_group = self._get_user_group(user_group) | |
268 user = self._get_user(user) | |
269 permission = self._get_perm(perm) | |
270 | |
271 # check if we have that permission already | |
272 obj = self.sa.query(UserUserGroupToPerm)\ | |
273 .filter(UserUserGroupToPerm.user == user)\ | |
274 .filter(UserUserGroupToPerm.user_group == user_group)\ | |
275 .scalar() | |
276 if obj is None: | |
277 # create new ! | |
278 obj = UserUserGroupToPerm() | |
279 obj.user_group = user_group | |
280 obj.user = user | |
281 obj.permission = permission | |
282 self.sa.add(obj) | |
283 log.debug('Granted perm %s to %s on %s' % (perm, user, user_group)) | |
284 return obj | |
285 | |
286 def revoke_user_permission(self, user_group, user): | |
287 """ | |
288 Revoke permission for user on given repository group | |
289 | |
290 :param user_group: Instance of RepoGroup, repositories_group_id, | |
291 or repositories_group name | |
292 :param user: Instance of User, user_id or username | |
293 """ | |
294 | |
295 user_group = self._get_user_group(user_group) | |
296 user = self._get_user(user) | |
297 | |
298 obj = self.sa.query(UserUserGroupToPerm)\ | |
299 .filter(UserUserGroupToPerm.user == user)\ | |
300 .filter(UserUserGroupToPerm.user_group == user_group)\ | |
301 .scalar() | |
302 if obj: | |
303 self.sa.delete(obj) | |
304 log.debug('Revoked perm on %s on %s' % (user_group, user)) | |
305 | |
306 def grant_user_group_permission(self, target_user_group, user_group, perm): | |
307 """ | |
308 Grant user group permission for given target_user_group | |
309 | |
310 :param target_user_group: | |
311 :param user_group: | |
312 :param perm: | |
313 """ | |
314 target_user_group = self._get_user_group(target_user_group) | |
315 user_group = self._get_user_group(user_group) | |
316 permission = self._get_perm(perm) | |
317 # forbid assigning same user group to itself | |
318 if target_user_group == user_group: | |
319 raise RepoGroupAssignmentError('target repo:%s cannot be ' | |
320 'assigned to itself' % target_user_group) | |
321 | |
322 # check if we have that permission already | |
323 obj = self.sa.query(UserGroupUserGroupToPerm)\ | |
324 .filter(UserGroupUserGroupToPerm.target_user_group == target_user_group)\ | |
325 .filter(UserGroupUserGroupToPerm.user_group == user_group)\ | |
326 .scalar() | |
327 if obj is None: | |
328 # create new ! | |
329 obj = UserGroupUserGroupToPerm() | |
330 obj.user_group = user_group | |
331 obj.target_user_group = target_user_group | |
332 obj.permission = permission | |
333 self.sa.add(obj) | |
334 log.debug('Granted perm %s to %s on %s' % (perm, target_user_group, user_group)) | |
335 return obj | |
336 | |
337 def revoke_user_group_permission(self, target_user_group, user_group): | |
338 """ | |
339 Revoke user group permission for given target_user_group | |
340 | |
341 :param target_user_group: | |
342 :param user_group: | |
343 """ | |
344 target_user_group = self._get_user_group(target_user_group) | |
345 user_group = self._get_user_group(user_group) | |
346 | |
347 obj = self.sa.query(UserGroupUserGroupToPerm)\ | |
348 .filter(UserGroupUserGroupToPerm.target_user_group == target_user_group)\ | |
349 .filter(UserGroupUserGroupToPerm.user_group == user_group)\ | |
350 .scalar() | |
351 if obj: | |
352 self.sa.delete(obj) | |
353 log.debug('Revoked perm on %s on %s' % (target_user_group, user_group)) | |
354 | |
355 def enforce_groups(self, user, groups, extern_type=None): | |
356 user = self._get_user(user) | |
357 log.debug('Enforcing groups %s on user %s' % (user, groups)) | |
358 current_groups = user.group_member | |
359 # find the external created groups | |
360 externals = [x.users_group for x in current_groups | |
361 if 'extern_type' in x.users_group.group_data] | |
362 | |
363 # calculate from what groups user should be removed | |
364 # externals that are not in groups | |
365 for gr in externals: | |
366 if gr.users_group_name not in groups: | |
367 log.debug('Removing user %s from user group %s' % (user, gr)) | |
368 self.remove_user_from_group(gr, user) | |
369 | |
370 # now we calculate in which groups user should be == groups params | |
371 owner = User.get_first_admin().username | |
372 for gr in set(groups): | |
373 existing_group = UserGroup.get_by_group_name(gr) | |
374 if not existing_group: | |
375 desc = 'Automatically created from plugin:%s' % extern_type | |
376 # we use first admin account to set the owner of the group | |
377 existing_group = UserGroupModel().create(gr, desc, owner, | |
378 group_data={'extern_type': extern_type}) | |
379 | |
380 # we can only add users to special groups created via plugins | |
381 managed = 'extern_type' in existing_group.group_data | |
382 if managed: | |
383 log.debug('Adding user %s to user group %s' % (user, gr)) | |
384 UserGroupModel().add_user_to_group(existing_group, user) | |
385 else: | |
386 log.debug('Skipping addition to group %s since it is ' | |
387 'not managed by auth plugins' % gr) |