##// END OF EJS Templates
Repository groups: super admin shouldn't have the permission set...
marcink -
r3853:be2b7577 beta
parent child Browse files
Show More
@@ -1,438 +1,440 b''
1 1 # -*- coding: utf-8 -*-
2 2 """
3 3 rhodecode.model.user_group
4 4 ~~~~~~~~~~~~~~~~~~~~~~~~~~
5 5
6 6 repo group model for RhodeCode
7 7
8 8 :created_on: Jan 25, 2011
9 9 :author: marcink
10 10 :copyright: (C) 2011-2012 Marcin Kuzminski <marcin@python-works.com>
11 11 :license: GPLv3, see COPYING for more details.
12 12 """
13 13 # This program is free software: you can redistribute it and/or modify
14 14 # it under the terms of the GNU General Public License as published by
15 15 # the Free Software Foundation, either version 3 of the License, or
16 16 # (at your option) any later version.
17 17 #
18 18 # This program is distributed in the hope that it will be useful,
19 19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
20 20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 21 # GNU General Public License for more details.
22 22 #
23 23 # You should have received a copy of the GNU General Public License
24 24 # along with this program. If not, see <http://www.gnu.org/licenses/>.
25 25
26 26 import os
27 27 import logging
28 28 import traceback
29 29 import shutil
30 30 import datetime
31 31
32 32 from rhodecode.lib.utils2 import LazyProperty
33 33
34 34 from rhodecode.model import BaseModel
35 35 from rhodecode.model.db import RepoGroup, RhodeCodeUi, UserRepoGroupToPerm, \
36 36 User, Permission, UserGroupRepoGroupToPerm, UserGroup, Repository
37 37
38 38 log = logging.getLogger(__name__)
39 39
40 40
41 41 class ReposGroupModel(BaseModel):
42 42
43 43 cls = RepoGroup
44 44
45 45 def _get_user_group(self, users_group):
46 46 return self._get_instance(UserGroup, users_group,
47 47 callback=UserGroup.get_by_group_name)
48 48
49 49 def _get_repo_group(self, repos_group):
50 50 return self._get_instance(RepoGroup, repos_group,
51 51 callback=RepoGroup.get_by_group_name)
52 52
53 53 @LazyProperty
54 54 def repos_path(self):
55 55 """
56 56 Get's the repositories root path from database
57 57 """
58 58
59 59 q = RhodeCodeUi.get_by_key('/')
60 60 return q.ui_value
61 61
62 62 def _create_default_perms(self, new_group):
63 63 # create default permission
64 64 default_perm = 'group.read'
65 65 def_user = User.get_default_user()
66 66 for p in def_user.user_perms:
67 67 if p.permission.permission_name.startswith('group.'):
68 68 default_perm = p.permission.permission_name
69 69 break
70 70
71 71 repo_group_to_perm = UserRepoGroupToPerm()
72 72 repo_group_to_perm.permission = Permission.get_by_key(default_perm)
73 73
74 74 repo_group_to_perm.group = new_group
75 75 repo_group_to_perm.user_id = def_user.user_id
76 76 return repo_group_to_perm
77 77
78 78 def __create_group(self, group_name):
79 79 """
80 80 makes repository group on filesystem
81 81
82 82 :param repo_name:
83 83 :param parent_id:
84 84 """
85 85
86 86 create_path = os.path.join(self.repos_path, group_name)
87 87 log.debug('creating new group in %s' % create_path)
88 88
89 89 if os.path.isdir(create_path):
90 90 raise Exception('That directory already exists !')
91 91
92 92 os.makedirs(create_path)
93 93
94 94 def __rename_group(self, old, new):
95 95 """
96 96 Renames a group on filesystem
97 97
98 98 :param group_name:
99 99 """
100 100
101 101 if old == new:
102 102 log.debug('skipping group rename')
103 103 return
104 104
105 105 log.debug('renaming repository group from %s to %s' % (old, new))
106 106
107 107 old_path = os.path.join(self.repos_path, old)
108 108 new_path = os.path.join(self.repos_path, new)
109 109
110 110 log.debug('renaming repos paths from %s to %s' % (old_path, new_path))
111 111
112 112 if os.path.isdir(new_path):
113 113 raise Exception('Was trying to rename to already '
114 114 'existing dir %s' % new_path)
115 115 shutil.move(old_path, new_path)
116 116
117 117 def __delete_group(self, group, force_delete=False):
118 118 """
119 119 Deletes a group from a filesystem
120 120
121 121 :param group: instance of group from database
122 122 :param force_delete: use shutil rmtree to remove all objects
123 123 """
124 124 paths = group.full_path.split(RepoGroup.url_sep())
125 125 paths = os.sep.join(paths)
126 126
127 127 rm_path = os.path.join(self.repos_path, paths)
128 128 log.info("Removing group %s" % (rm_path))
129 129 # delete only if that path really exists
130 130 if os.path.isdir(rm_path):
131 131 if force_delete:
132 132 shutil.rmtree(rm_path)
133 133 else:
134 134 #archive that group`
135 135 _now = datetime.datetime.now()
136 136 _ms = str(_now.microsecond).rjust(6, '0')
137 137 _d = 'rm__%s_GROUP_%s' % (_now.strftime('%Y%m%d_%H%M%S_' + _ms),
138 138 group.name)
139 139 shutil.move(rm_path, os.path.join(self.repos_path, _d))
140 140
141 141 def create(self, group_name, group_description, owner, parent=None, just_db=False):
142 142 try:
143 user = self._get_user(owner)
143 144 new_repos_group = RepoGroup()
144 new_repos_group.user = self._get_user(owner)
145 new_repos_group.user = user
145 146 new_repos_group.group_description = group_description or group_name
146 147 new_repos_group.parent_group = self._get_repo_group(parent)
147 148 new_repos_group.group_name = new_repos_group.get_new_name(group_name)
148 149
149 150 self.sa.add(new_repos_group)
150 151 perm_obj = self._create_default_perms(new_repos_group)
151 152 self.sa.add(perm_obj)
152 153
153 #create an ADMIN permission for owner, later owner should go into
154 #the owner field of groups
155 self.grant_user_permission(repos_group=new_repos_group,
156 user=owner, perm='group.admin')
154 #create an ADMIN permission for owner except if we're super admin,
155 #later owner should go into the owner field of groups
156 if not user.is_admin:
157 self.grant_user_permission(repos_group=new_repos_group,
158 user=owner, perm='group.admin')
157 159
158 160 if not just_db:
159 161 # we need to flush here, in order to check if database won't
160 162 # throw any exceptions, create filesystem dirs at the very end
161 163 self.sa.flush()
162 164 self.__create_group(new_repos_group.group_name)
163 165
164 166 return new_repos_group
165 167 except Exception:
166 168 log.error(traceback.format_exc())
167 169 raise
168 170
169 171 def _update_permissions(self, repos_group, perms_new=None,
170 172 perms_updates=None, recursive=False,
171 173 check_perms=True):
172 174 from rhodecode.model.repo import RepoModel
173 175 from rhodecode.lib.auth import HasUserGroupPermissionAny
174 176
175 177 if not perms_new:
176 178 perms_new = []
177 179 if not perms_updates:
178 180 perms_updates = []
179 181
180 182 def _set_perm_user(obj, user, perm):
181 183 if isinstance(obj, RepoGroup):
182 184 self.grant_user_permission(
183 185 repos_group=obj, user=user, perm=perm
184 186 )
185 187 elif isinstance(obj, Repository):
186 188 #we do this ONLY IF repository is non-private
187 189 if obj.private:
188 190 return
189 191
190 192 # we set group permission but we have to switch to repo
191 193 # permission
192 194 perm = perm.replace('group.', 'repository.')
193 195 RepoModel().grant_user_permission(
194 196 repo=obj, user=user, perm=perm
195 197 )
196 198
197 199 def _set_perm_group(obj, users_group, perm):
198 200 if isinstance(obj, RepoGroup):
199 201 self.grant_users_group_permission(
200 202 repos_group=obj, group_name=users_group, perm=perm
201 203 )
202 204 elif isinstance(obj, Repository):
203 205 # we set group permission but we have to switch to repo
204 206 # permission
205 207 perm = perm.replace('group.', 'repository.')
206 208 RepoModel().grant_users_group_permission(
207 209 repo=obj, group_name=users_group, perm=perm
208 210 )
209 211 updates = []
210 212 log.debug('Now updating permissions for %s in recursive mode:%s'
211 213 % (repos_group, recursive))
212 214
213 215 for obj in repos_group.recursive_groups_and_repos():
214 216 #obj is an instance of a group or repositories in that group
215 217 if not recursive:
216 218 obj = repos_group
217 219
218 220 # update permissions
219 221 for member, perm, member_type in perms_updates:
220 222 ## set for user
221 223 if member_type == 'user':
222 224 # this updates also current one if found
223 225 _set_perm_user(obj, user=member, perm=perm)
224 226 ## set for user group
225 227 else:
226 228 #check if we have permissions to alter this usergroup
227 229 req_perms = ('usergroup.read', 'usergroup.write', 'usergroup.admin')
228 230 if not check_perms or HasUserGroupPermissionAny(*req_perms)(member):
229 231 _set_perm_group(obj, users_group=member, perm=perm)
230 232 # set new permissions
231 233 for member, perm, member_type in perms_new:
232 234 if member_type == 'user':
233 235 _set_perm_user(obj, user=member, perm=perm)
234 236 else:
235 237 #check if we have permissions to alter this usergroup
236 238 req_perms = ('usergroup.read', 'usergroup.write', 'usergroup.admin')
237 239 if not check_perms or HasUserGroupPermissionAny(*req_perms)(member):
238 240 _set_perm_group(obj, users_group=member, perm=perm)
239 241 updates.append(obj)
240 242 #if it's not recursive call
241 243 # break the loop and don't proceed with other changes
242 244 if not recursive:
243 245 break
244 246 return updates
245 247
246 248 def update(self, repos_group, form_data):
247 249
248 250 try:
249 251 repos_group = self._get_repo_group(repos_group)
250 252 old_path = repos_group.full_path
251 253
252 254 # change properties
253 255 repos_group.group_description = form_data['group_description']
254 256 repos_group.group_parent_id = form_data['group_parent_id']
255 257 repos_group.enable_locking = form_data['enable_locking']
256 258
257 259 repos_group.parent_group = RepoGroup.get(form_data['group_parent_id'])
258 260 repos_group.group_name = repos_group.get_new_name(form_data['group_name'])
259 261 new_path = repos_group.full_path
260 262 self.sa.add(repos_group)
261 263
262 264 # iterate over all members of this groups and do fixes
263 265 # set locking if given
264 266 # if obj is a repoGroup also fix the name of the group according
265 267 # to the parent
266 268 # if obj is a Repo fix it's name
267 269 # this can be potentially heavy operation
268 270 for obj in repos_group.recursive_groups_and_repos():
269 271 #set the value from it's parent
270 272 obj.enable_locking = repos_group.enable_locking
271 273 if isinstance(obj, RepoGroup):
272 274 new_name = obj.get_new_name(obj.name)
273 275 log.debug('Fixing group %s to new name %s' \
274 276 % (obj.group_name, new_name))
275 277 obj.group_name = new_name
276 278 elif isinstance(obj, Repository):
277 279 # we need to get all repositories from this new group and
278 280 # rename them accordingly to new group path
279 281 new_name = obj.get_new_name(obj.just_name)
280 282 log.debug('Fixing repo %s to new name %s' \
281 283 % (obj.repo_name, new_name))
282 284 obj.repo_name = new_name
283 285 self.sa.add(obj)
284 286
285 287 self.__rename_group(old_path, new_path)
286 288
287 289 return repos_group
288 290 except Exception:
289 291 log.error(traceback.format_exc())
290 292 raise
291 293
292 294 def delete(self, repos_group, force_delete=False):
293 295 repos_group = self._get_repo_group(repos_group)
294 296 try:
295 297 self.sa.delete(repos_group)
296 298 self.__delete_group(repos_group, force_delete)
297 299 except Exception:
298 300 log.error('Error removing repos_group %s' % repos_group)
299 301 raise
300 302
301 303 def delete_permission(self, repos_group, obj, obj_type, recursive):
302 304 """
303 305 Revokes permission for repos_group for given obj(user or users_group),
304 306 obj_type can be user or user group
305 307
306 308 :param repos_group:
307 309 :param obj: user or user group id
308 310 :param obj_type: user or user group type
309 311 :param recursive: recurse to all children of group
310 312 """
311 313 from rhodecode.model.repo import RepoModel
312 314 repos_group = self._get_repo_group(repos_group)
313 315
314 316 for el in repos_group.recursive_groups_and_repos():
315 317 if not recursive:
316 318 # if we don't recurse set the permission on only the top level
317 319 # object
318 320 el = repos_group
319 321
320 322 if isinstance(el, RepoGroup):
321 323 if obj_type == 'user':
322 324 ReposGroupModel().revoke_user_permission(el, user=obj)
323 325 elif obj_type == 'users_group':
324 326 ReposGroupModel().revoke_users_group_permission(el, group_name=obj)
325 327 else:
326 328 raise Exception('undefined object type %s' % obj_type)
327 329 elif isinstance(el, Repository):
328 330 if obj_type == 'user':
329 331 RepoModel().revoke_user_permission(el, user=obj)
330 332 elif obj_type == 'users_group':
331 333 RepoModel().revoke_users_group_permission(el, group_name=obj)
332 334 else:
333 335 raise Exception('undefined object type %s' % obj_type)
334 336
335 337 #if it's not recursive call
336 338 # break the loop and don't proceed with other changes
337 339 if not recursive:
338 340 break
339 341
340 342 def grant_user_permission(self, repos_group, user, perm):
341 343 """
342 344 Grant permission for user on given repository group, or update
343 345 existing one if found
344 346
345 347 :param repos_group: Instance of ReposGroup, repositories_group_id,
346 348 or repositories_group name
347 349 :param user: Instance of User, user_id or username
348 350 :param perm: Instance of Permission, or permission_name
349 351 """
350 352
351 353 repos_group = self._get_repo_group(repos_group)
352 354 user = self._get_user(user)
353 355 permission = self._get_perm(perm)
354 356
355 357 # check if we have that permission already
356 358 obj = self.sa.query(UserRepoGroupToPerm)\
357 359 .filter(UserRepoGroupToPerm.user == user)\
358 360 .filter(UserRepoGroupToPerm.group == repos_group)\
359 361 .scalar()
360 362 if obj is None:
361 363 # create new !
362 364 obj = UserRepoGroupToPerm()
363 365 obj.group = repos_group
364 366 obj.user = user
365 367 obj.permission = permission
366 368 self.sa.add(obj)
367 369 log.debug('Granted perm %s to %s on %s' % (perm, user, repos_group))
368 370
369 371 def revoke_user_permission(self, repos_group, user):
370 372 """
371 373 Revoke permission for user on given repository group
372 374
373 375 :param repos_group: Instance of ReposGroup, repositories_group_id,
374 376 or repositories_group name
375 377 :param user: Instance of User, user_id or username
376 378 """
377 379
378 380 repos_group = self._get_repo_group(repos_group)
379 381 user = self._get_user(user)
380 382
381 383 obj = self.sa.query(UserRepoGroupToPerm)\
382 384 .filter(UserRepoGroupToPerm.user == user)\
383 385 .filter(UserRepoGroupToPerm.group == repos_group)\
384 386 .scalar()
385 387 if obj:
386 388 self.sa.delete(obj)
387 389 log.debug('Revoked perm on %s on %s' % (repos_group, user))
388 390
389 391 def grant_users_group_permission(self, repos_group, group_name, perm):
390 392 """
391 393 Grant permission for user group on given repository group, or update
392 394 existing one if found
393 395
394 396 :param repos_group: Instance of ReposGroup, repositories_group_id,
395 397 or repositories_group name
396 398 :param group_name: Instance of UserGroup, users_group_id,
397 399 or user group name
398 400 :param perm: Instance of Permission, or permission_name
399 401 """
400 402 repos_group = self._get_repo_group(repos_group)
401 403 group_name = self._get_user_group(group_name)
402 404 permission = self._get_perm(perm)
403 405
404 406 # check if we have that permission already
405 407 obj = self.sa.query(UserGroupRepoGroupToPerm)\
406 408 .filter(UserGroupRepoGroupToPerm.group == repos_group)\
407 409 .filter(UserGroupRepoGroupToPerm.users_group == group_name)\
408 410 .scalar()
409 411
410 412 if obj is None:
411 413 # create new
412 414 obj = UserGroupRepoGroupToPerm()
413 415
414 416 obj.group = repos_group
415 417 obj.users_group = group_name
416 418 obj.permission = permission
417 419 self.sa.add(obj)
418 420 log.debug('Granted perm %s to %s on %s' % (perm, group_name, repos_group))
419 421
420 422 def revoke_users_group_permission(self, repos_group, group_name):
421 423 """
422 424 Revoke permission for user group on given repository group
423 425
424 426 :param repos_group: Instance of ReposGroup, repositories_group_id,
425 427 or repositories_group name
426 428 :param group_name: Instance of UserGroup, users_group_id,
427 429 or user group name
428 430 """
429 431 repos_group = self._get_repo_group(repos_group)
430 432 group_name = self._get_user_group(group_name)
431 433
432 434 obj = self.sa.query(UserGroupRepoGroupToPerm)\
433 435 .filter(UserGroupRepoGroupToPerm.group == repos_group)\
434 436 .filter(UserGroupRepoGroupToPerm.users_group == group_name)\
435 437 .scalar()
436 438 if obj:
437 439 self.sa.delete(obj)
438 440 log.debug('Revoked perm to %s on %s' % (repos_group, group_name))
General Comments 0
You need to be logged in to leave comments. Login now