Mercurial > kallithea
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 |