comparison rhodecode/model/user.py @ 2709:d2d35cf2b351 beta

RhodeCode now has a option to explicitly set forking permissions. ref #508 - changed the way permissons on users groups behave. Now explicit set on user is more important than permission set on users group
author Marcin Kuzminski <marcin@python-works.com>
date Fri, 10 Aug 2012 03:09:36 +0200
parents 001c7e2ae986
children 63e58ef80ef1 c0cc8f8a71b0
comparison
equal deleted inserted replaced
2708:9bce679a3f49 2709:d2d35cf2b351
23 # You should have received a copy of the GNU General Public License 23 # You should have received a copy of the GNU General Public License
24 # along with this program. If not, see <http://www.gnu.org/licenses/>. 24 # along with this program. If not, see <http://www.gnu.org/licenses/>.
25 25
26 import logging 26 import logging
27 import traceback 27 import traceback
28 28 import itertools
29 from pylons import url 29 from pylons import url
30 from pylons.i18n.translation import _ 30 from pylons.i18n.translation import _
31 31
32 from sqlalchemy.exc import DatabaseError 32 from sqlalchemy.exc import DatabaseError
33 from sqlalchemy.orm import joinedload 33 from sqlalchemy.orm import joinedload
43 UserOwnsReposException 43 UserOwnsReposException
44 44
45 45
46 log = logging.getLogger(__name__) 46 log = logging.getLogger(__name__)
47 47
48 48 PERM_WEIGHTS = Permission.PERM_WEIGHTS
49 PERM_WEIGHTS = {
50 'repository.none': 0,
51 'repository.read': 1,
52 'repository.write': 3,
53 'repository.admin': 4,
54 'group.none': 0,
55 'group.read': 1,
56 'group.write': 3,
57 'group.admin': 4,
58 }
59 49
60 50
61 class UserModel(BaseModel): 51 class UserModel(BaseModel):
62 cls = User 52 cls = User
63 53
430 p = 'group.admin' 420 p = 'group.admin'
431 user.permissions[GK][rg_k] = p 421 user.permissions[GK][rg_k] = p
432 return user 422 return user
433 423
434 #================================================================== 424 #==================================================================
435 # set default permissions first for repositories and groups 425 # SET DEFAULTS GLOBAL, REPOS, REPOS GROUPS
436 #================================================================== 426 #==================================================================
437 uid = user.user_id 427 uid = user.user_id
438 428
439 # default global permissions 429 # default global permissions taken fron the default user
440 default_global_perms = self.sa.query(UserToPerm)\ 430 default_global_perms = self.sa.query(UserToPerm)\
441 .filter(UserToPerm.user_id == default_user_id) 431 .filter(UserToPerm.user_id == default_user_id)
442 432
443 for perm in default_global_perms: 433 for perm in default_global_perms:
444 user.permissions[GLOBAL].add(perm.permission.permission_name) 434 user.permissions[GLOBAL].add(perm.permission.permission_name)
462 for perm in default_repo_groups_perms: 452 for perm in default_repo_groups_perms:
463 rg_k = perm.UserRepoGroupToPerm.group.group_name 453 rg_k = perm.UserRepoGroupToPerm.group.group_name
464 p = perm.Permission.permission_name 454 p = perm.Permission.permission_name
465 user.permissions[GK][rg_k] = p 455 user.permissions[GK][rg_k] = p
466 456
467 #================================================================== 457 #======================================================================
468 # overwrite defaults with user permissions if any found 458 # !! OVERRIDE GLOBALS !! with user permissions if any found
469 #================================================================== 459 #======================================================================
470 460 # those can be configured from groups or users explicitly
471 # user global permissions 461 _configurable = set(['hg.fork.none', 'hg.fork.repository',
462 'hg.create.none', 'hg.create.repository'])
463
464 # USER GROUPS comes first
465 # users group global permissions
466 user_perms_from_users_groups = self.sa.query(UsersGroupToPerm)\
467 .options(joinedload(UsersGroupToPerm.permission))\
468 .join((UsersGroupMember, UsersGroupToPerm.users_group_id ==
469 UsersGroupMember.users_group_id))\
470 .filter(UsersGroupMember.user_id == uid)\
471 .order_by(UsersGroupToPerm.users_group_id)\
472 .all()
473 #need to group here by groups since user can be in more than one group
474 _grouped = [[x, list(y)] for x, y in
475 itertools.groupby(user_perms_from_users_groups,
476 lambda x:x.users_group)]
477 for gr, perms in _grouped:
478 # since user can be in multiple groups iterate over them and
479 # select the lowest permissions first (more explicit)
480 ##TODO: do this^^
481 if not gr.inherit_default_permissions:
482 # NEED TO IGNORE all configurable permissions and
483 # replace them with explicitly set
484 user.permissions[GLOBAL] = user.permissions[GLOBAL]\
485 .difference(_configurable)
486 for perm in perms:
487 user.permissions[GLOBAL].add(perm.permission.permission_name)
488
489 # user specific global permissions
472 user_perms = self.sa.query(UserToPerm)\ 490 user_perms = self.sa.query(UserToPerm)\
473 .options(joinedload(UserToPerm.permission))\ 491 .options(joinedload(UserToPerm.permission))\
474 .filter(UserToPerm.user_id == uid).all() 492 .filter(UserToPerm.user_id == uid).all()
475 493
476 for perm in user_perms: 494 if not user.inherit_default_permissions:
477 user.permissions[GLOBAL].add(perm.permission.permission_name) 495 # NEED TO IGNORE all configurable permissions and
496 # replace them with explicitly set
497 user.permissions[GLOBAL] = user.permissions[GLOBAL]\
498 .difference(_configurable)
499
500 for perm in user_perms:
501 user.permissions[GLOBAL].add(perm.permission.permission_name)
502
503 #======================================================================
504 # !! REPO PERMISSIONS !!
505 #======================================================================
506 #======================================================================
507 # check if user is part of user groups for this repository and
508 # fill in (or NOT replace with higher `or 1` permissions
509 #======================================================================
510 # users group for repositories permissions
511 user_repo_perms_from_users_groups = \
512 self.sa.query(UsersGroupRepoToPerm, Permission, Repository,)\
513 .join((Repository, UsersGroupRepoToPerm.repository_id ==
514 Repository.repo_id))\
515 .join((Permission, UsersGroupRepoToPerm.permission_id ==
516 Permission.permission_id))\
517 .join((UsersGroupMember, UsersGroupRepoToPerm.users_group_id ==
518 UsersGroupMember.users_group_id))\
519 .filter(UsersGroupMember.user_id == uid)\
520 .all()
521
522 for perm in user_repo_perms_from_users_groups:
523 r_k = perm.UsersGroupRepoToPerm.repository.repo_name
524 p = perm.Permission.permission_name
525 cur_perm = user.permissions[RK][r_k]
526 # overwrite permission only if it's greater than permission
527 # given from other sources
528 if PERM_WEIGHTS[p] > PERM_WEIGHTS[cur_perm] or 1: # disable check
529 user.permissions[RK][r_k] = p
478 530
479 # user explicit permissions for repositories 531 # user explicit permissions for repositories
480 user_repo_perms = \ 532 user_repo_perms = \
481 self.sa.query(UserRepoToPerm, Permission, Repository)\ 533 self.sa.query(UserRepoToPerm, Permission, Repository)\
482 .join((Repository, UserRepoToPerm.repository_id == Repository.repo_id))\ 534 .join((Repository, UserRepoToPerm.repository_id ==
483 .join((Permission, UserRepoToPerm.permission_id == Permission.permission_id))\ 535 Repository.repo_id))\
484 .filter(UserRepoToPerm.user_id == uid)\ 536 .join((Permission, UserRepoToPerm.permission_id ==
485 .all() 537 Permission.permission_id))\
538 .filter(UserRepoToPerm.user_id == uid)\
539 .all()
486 540
487 for perm in user_repo_perms: 541 for perm in user_repo_perms:
488 # set admin if owner 542 # set admin if owner
489 r_k = perm.UserRepoToPerm.repository.repo_name 543 r_k = perm.UserRepoToPerm.repository.repo_name
490 if perm.Repository.user_id == uid: 544 if perm.Repository.user_id == uid:
491 p = 'repository.admin' 545 p = 'repository.admin'
492 else: 546 else:
493 p = perm.Permission.permission_name 547 p = perm.Permission.permission_name
494 user.permissions[RK][r_k] = p 548 user.permissions[RK][r_k] = p
495 549
496 # USER GROUP
497 #==================================================================
498 # check if user is part of user groups for this repository and
499 # fill in (or replace with higher) permissions
500 #==================================================================
501
502 # users group global
503 user_perms_from_users_groups = self.sa.query(UsersGroupToPerm)\
504 .options(joinedload(UsersGroupToPerm.permission))\
505 .join((UsersGroupMember, UsersGroupToPerm.users_group_id ==
506 UsersGroupMember.users_group_id))\
507 .filter(UsersGroupMember.user_id == uid).all()
508
509 for perm in user_perms_from_users_groups:
510 user.permissions[GLOBAL].add(perm.permission.permission_name)
511
512 # users group for repositories permissions
513 user_repo_perms_from_users_groups = \
514 self.sa.query(UsersGroupRepoToPerm, Permission, Repository,)\
515 .join((Repository, UsersGroupRepoToPerm.repository_id == Repository.repo_id))\
516 .join((Permission, UsersGroupRepoToPerm.permission_id == Permission.permission_id))\
517 .join((UsersGroupMember, UsersGroupRepoToPerm.users_group_id == UsersGroupMember.users_group_id))\
518 .filter(UsersGroupMember.user_id == uid)\
519 .all()
520
521 for perm in user_repo_perms_from_users_groups:
522 r_k = perm.UsersGroupRepoToPerm.repository.repo_name
523 p = perm.Permission.permission_name
524 cur_perm = user.permissions[RK][r_k]
525 # overwrite permission only if it's greater than permission
526 # given from other sources
527 if PERM_WEIGHTS[p] > PERM_WEIGHTS[cur_perm]:
528 user.permissions[RK][r_k] = p
529
530 # REPO GROUP 550 # REPO GROUP
531 #================================================================== 551 #==================================================================
532 # get access for this user for repos group and override defaults 552 # get access for this user for repos group and override defaults
533 #================================================================== 553 #==================================================================
534 554
572 user.permissions[GK][g_k] = p 592 user.permissions[GK][g_k] = p
573 593
574 return user 594 return user
575 595
576 def has_perm(self, user, perm): 596 def has_perm(self, user, perm):
577 if not isinstance(perm, Permission): 597 perm = self._get_perm(perm)
578 raise Exception('perm needs to be an instance of Permission class '
579 'got %s instead' % type(perm))
580
581 user = self._get_user(user) 598 user = self._get_user(user)
582 599
583 return UserToPerm.query().filter(UserToPerm.user == user)\ 600 return UserToPerm.query().filter(UserToPerm.user == user)\
584 .filter(UserToPerm.permission == perm).scalar() is not None 601 .filter(UserToPerm.permission == perm).scalar() is not None
585 602