Show More
@@ -140,7 +140,6 b' def admin_routes(config):' | |||||
140 | name='admin_settings_visual_update', |
|
140 | name='admin_settings_visual_update', | |
141 | pattern='/settings/visual/update') |
|
141 | pattern='/settings/visual/update') | |
142 |
|
142 | |||
143 |
|
||||
144 | config.add_route( |
|
143 | config.add_route( | |
145 | name='admin_settings_issuetracker', |
|
144 | name='admin_settings_issuetracker', | |
146 | pattern='/settings/issue-tracker') |
|
145 | pattern='/settings/issue-tracker') | |
@@ -415,6 +414,10 b' def admin_routes(config):' | |||||
415 | pattern='/repos') |
|
414 | pattern='/repos') | |
416 |
|
415 | |||
417 | config.add_route( |
|
416 | config.add_route( | |
|
417 | name='repos_data', | |||
|
418 | pattern='/repos_data') | |||
|
419 | ||||
|
420 | config.add_route( | |||
418 | name='repo_new', |
|
421 | name='repo_new', | |
419 | pattern='/repos/new') |
|
422 | pattern='/repos/new') | |
420 |
|
423 |
@@ -65,7 +65,7 b' class AdminRepoGroupsView(BaseAppView, D' | |||||
65 | # and display only those we have ADMIN right |
|
65 | # and display only those we have ADMIN right | |
66 | groups_with_admin_rights = RepoGroupList( |
|
66 | groups_with_admin_rights = RepoGroupList( | |
67 | RepoGroup.query().all(), |
|
67 | RepoGroup.query().all(), | |
68 | perm_set=['group.admin']) |
|
68 | perm_set=['group.admin'], extra_kwargs=dict(user=self._rhodecode_user)) | |
69 | c.repo_groups = RepoGroup.groups_choices( |
|
69 | c.repo_groups = RepoGroup.groups_choices( | |
70 | groups=groups_with_admin_rights, |
|
70 | groups=groups_with_admin_rights, | |
71 | show_empty_group=allow_empty_group) |
|
71 | show_empty_group=allow_empty_group) | |
@@ -150,12 +150,8 b' class AdminRepoGroupsView(BaseAppView, D' | |||||
150 | def user_profile(username): |
|
150 | def user_profile(username): | |
151 | return _render('user_profile', username) |
|
151 | return _render('user_profile', username) | |
152 |
|
152 | |||
153 | auth_repo_group_list = RepoGroupList( |
|
153 | _perms = ['group.admin'] | |
154 | RepoGroup.query().all(), perm_set=['group.admin']) |
|
154 | allowed_ids = [-1] + self._rhodecode_user.repo_group_acl_ids_from_stack(_perms) | |
155 |
|
||||
156 | allowed_ids = [-1] |
|
|||
157 | for repo_group in auth_repo_group_list: |
|
|||
158 | allowed_ids.append(repo_group.group_id) |
|
|||
159 |
|
155 | |||
160 | repo_groups_data_total_count = RepoGroup.query()\ |
|
156 | repo_groups_data_total_count = RepoGroup.query()\ | |
161 | .filter(or_( |
|
157 | .filter(or_( |
@@ -31,7 +31,6 b' from rhodecode import events' | |||||
31 | from rhodecode.apps._base import BaseAppView, DataGridAppView |
|
31 | from rhodecode.apps._base import BaseAppView, DataGridAppView | |
32 | from rhodecode.lib.celerylib.utils import get_task_id |
|
32 | from rhodecode.lib.celerylib.utils import get_task_id | |
33 |
|
33 | |||
34 | from rhodecode.lib.ext_json import json |
|
|||
35 | from rhodecode.lib.auth import ( |
|
34 | from rhodecode.lib.auth import ( | |
36 | LoginRequired, CSRFRequired, NotAnonymous, |
|
35 | LoginRequired, CSRFRequired, NotAnonymous, | |
37 | HasPermissionAny, HasRepoGroupPermissionAny) |
|
36 | HasPermissionAny, HasRepoGroupPermissionAny) | |
@@ -43,7 +42,8 b' from rhodecode.model.permission import P' | |||||
43 | from rhodecode.model.repo import RepoModel |
|
42 | from rhodecode.model.repo import RepoModel | |
44 | from rhodecode.model.scm import RepoList, RepoGroupList, ScmModel |
|
43 | from rhodecode.model.scm import RepoList, RepoGroupList, ScmModel | |
45 | from rhodecode.model.settings import SettingsModel |
|
44 | from rhodecode.model.settings import SettingsModel | |
46 |
from rhodecode.model.db import |
|
45 | from rhodecode.model.db import ( | |
|
46 | in_filter_generator, or_, func, Session, Repository, RepoGroup, User) | |||
47 |
|
47 | |||
48 | log = logging.getLogger(__name__) |
|
48 | log = logging.getLogger(__name__) | |
49 |
|
49 | |||
@@ -70,15 +70,94 b' class AdminReposView(BaseAppView, DataGr' | |||||
70 | renderer='rhodecode:templates/admin/repos/repos.mako') |
|
70 | renderer='rhodecode:templates/admin/repos/repos.mako') | |
71 | def repository_list(self): |
|
71 | def repository_list(self): | |
72 | c = self.load_default_context() |
|
72 | c = self.load_default_context() | |
|
73 | return self._get_template_context(c) | |||
73 |
|
74 | |||
74 | repo_list = Repository.get_all_repos() |
|
75 | @LoginRequired() | |
75 | c.repo_list = RepoList(repo_list, perm_set=['repository.admin']) |
|
76 | @NotAnonymous() | |
|
77 | # perms check inside | |||
|
78 | @view_config( | |||
|
79 | route_name='repos_data', request_method='GET', | |||
|
80 | renderer='json_ext', xhr=True) | |||
|
81 | def repository_list_data(self): | |||
|
82 | self.load_default_context() | |||
|
83 | column_map = { | |||
|
84 | 'name_raw': 'repo_name', | |||
|
85 | 'desc': 'description', | |||
|
86 | 'last_change_raw': 'updated_on', | |||
|
87 | 'owner': 'user_username', | |||
|
88 | } | |||
|
89 | draw, start, limit = self._extract_chunk(self.request) | |||
|
90 | search_q, order_by, order_dir = self._extract_ordering( | |||
|
91 | self.request, column_map=column_map) | |||
|
92 | ||||
|
93 | _perms = ['repository.admin'] | |||
|
94 | allowed_ids = [-1] + self._rhodecode_user.repo_acl_ids_from_stack(_perms) | |||
|
95 | ||||
|
96 | repos_data_total_count = Repository.query() \ | |||
|
97 | .filter(or_( | |||
|
98 | # generate multiple IN to fix limitation problems | |||
|
99 | *in_filter_generator(Repository.repo_id, allowed_ids)) | |||
|
100 | ) \ | |||
|
101 | .count() | |||
|
102 | ||||
|
103 | base_q = Session.query( | |||
|
104 | Repository.repo_id, | |||
|
105 | Repository.repo_name, | |||
|
106 | Repository.description, | |||
|
107 | Repository.repo_type, | |||
|
108 | Repository.repo_state, | |||
|
109 | Repository.private, | |||
|
110 | Repository.archived, | |||
|
111 | Repository.fork, | |||
|
112 | Repository.updated_on, | |||
|
113 | Repository._changeset_cache, | |||
|
114 | User, | |||
|
115 | ) \ | |||
|
116 | .filter(or_( | |||
|
117 | # generate multiple IN to fix limitation problems | |||
|
118 | *in_filter_generator(Repository.repo_id, allowed_ids)) | |||
|
119 | ) \ | |||
|
120 | .join(User, User.user_id == Repository.user_id) \ | |||
|
121 | .group_by(Repository, User) | |||
|
122 | ||||
|
123 | if search_q: | |||
|
124 | like_expression = u'%{}%'.format(safe_unicode(search_q)) | |||
|
125 | base_q = base_q.filter(or_( | |||
|
126 | Repository.repo_name.ilike(like_expression), | |||
|
127 | )) | |||
|
128 | ||||
|
129 | repos_data_total_filtered_count = base_q.count() | |||
|
130 | ||||
|
131 | sort_defined = False | |||
|
132 | if order_by == 'repo_name': | |||
|
133 | sort_col = func.lower(Repository.repo_name) | |||
|
134 | sort_defined = True | |||
|
135 | elif order_by == 'user_username': | |||
|
136 | sort_col = User.username | |||
|
137 | else: | |||
|
138 | sort_col = getattr(Repository, order_by, None) | |||
|
139 | ||||
|
140 | if sort_defined or sort_col: | |||
|
141 | if order_dir == 'asc': | |||
|
142 | sort_col = sort_col.asc() | |||
|
143 | else: | |||
|
144 | sort_col = sort_col.desc() | |||
|
145 | ||||
|
146 | base_q = base_q.order_by(sort_col) | |||
|
147 | base_q = base_q.offset(start).limit(limit) | |||
|
148 | ||||
|
149 | repos_list = base_q.all() | |||
|
150 | ||||
76 | repos_data = RepoModel().get_repos_as_dict( |
|
151 | repos_data = RepoModel().get_repos_as_dict( | |
77 |
repo_list= |
|
152 | repo_list=repos_list, admin=True, super_user_actions=True) | |
78 | # json used to render the grid |
|
|||
79 | c.data = json.dumps(repos_data) |
|
|||
80 |
|
153 | |||
81 | return self._get_template_context(c) |
|
154 | data = ({ | |
|
155 | 'draw': draw, | |||
|
156 | 'data': repos_data, | |||
|
157 | 'recordsTotal': repos_data_total_count, | |||
|
158 | 'recordsFiltered': repos_data_total_filtered_count, | |||
|
159 | }) | |||
|
160 | return data | |||
82 |
|
161 | |||
83 | @LoginRequired() |
|
162 | @LoginRequired() | |
84 | @NotAnonymous() |
|
163 | @NotAnonymous() |
@@ -99,12 +99,8 b' class AdminUserGroupsView(BaseAppView, D' | |||||
99 | def user_profile(username): |
|
99 | def user_profile(username): | |
100 | return _render('user_profile', username) |
|
100 | return _render('user_profile', username) | |
101 |
|
101 | |||
102 | auth_user_group_list = UserGroupList( |
|
102 | _perms = ['usergroup.admin'] | |
103 | UserGroup.query().all(), perm_set=['usergroup.admin']) |
|
103 | allowed_ids = [-1] + self._rhodecode_user.user_group_acl_ids_from_stack(_perms) | |
104 |
|
||||
105 | allowed_ids = [-1] |
|
|||
106 | for user_group in auth_user_group_list: |
|
|||
107 | allowed_ids.append(user_group.users_group_id) |
|
|||
108 |
|
104 | |||
109 | user_groups_data_total_count = UserGroup.query()\ |
|
105 | user_groups_data_total_count = UserGroup.query()\ | |
110 | .filter(or_( |
|
106 | .filter(or_( |
@@ -352,23 +352,23 b' class PermOriginDict(dict):' | |||||
352 | `.perm_origin_stack` will return the stack of (perm, origin) set per key |
|
352 | `.perm_origin_stack` will return the stack of (perm, origin) set per key | |
353 |
|
353 | |||
354 | >>> perms = PermOriginDict() |
|
354 | >>> perms = PermOriginDict() | |
355 | >>> perms['resource'] = 'read', 'default' |
|
355 | >>> perms['resource'] = 'read', 'default', 1 | |
356 | >>> perms['resource'] |
|
356 | >>> perms['resource'] | |
357 | 'read' |
|
357 | 'read' | |
358 | >>> perms['resource'] = 'write', 'admin' |
|
358 | >>> perms['resource'] = 'write', 'admin', 2 | |
359 | >>> perms['resource'] |
|
359 | >>> perms['resource'] | |
360 | 'write' |
|
360 | 'write' | |
361 | >>> perms.perm_origin_stack |
|
361 | >>> perms.perm_origin_stack | |
362 | {'resource': [('read', 'default'), ('write', 'admin')]} |
|
362 | {'resource': [('read', 'default', 1), ('write', 'admin', 2)]} | |
363 | """ |
|
363 | """ | |
364 |
|
364 | |||
365 | def __init__(self, *args, **kw): |
|
365 | def __init__(self, *args, **kw): | |
366 | dict.__init__(self, *args, **kw) |
|
366 | dict.__init__(self, *args, **kw) | |
367 | self.perm_origin_stack = collections.OrderedDict() |
|
367 | self.perm_origin_stack = collections.OrderedDict() | |
368 |
|
368 | |||
369 | def __setitem__(self, key, (perm, origin)): |
|
369 | def __setitem__(self, key, (perm, origin, obj_id)): | |
370 | self.perm_origin_stack.setdefault(key, []).append( |
|
370 | self.perm_origin_stack.setdefault(key, []).append( | |
371 | (perm, origin)) |
|
371 | (perm, origin, obj_id)) | |
372 | dict.__setitem__(self, key, perm) |
|
372 | dict.__setitem__(self, key, perm) | |
373 |
|
373 | |||
374 |
|
374 | |||
@@ -463,26 +463,29 b' class PermissionCalculator(object):' | |||||
463 | # repositories |
|
463 | # repositories | |
464 | for perm in self.default_repo_perms: |
|
464 | for perm in self.default_repo_perms: | |
465 | r_k = perm.UserRepoToPerm.repository.repo_name |
|
465 | r_k = perm.UserRepoToPerm.repository.repo_name | |
|
466 | obj_id = perm.UserRepoToPerm.repository.repo_id | |||
466 | archived = perm.UserRepoToPerm.repository.archived |
|
467 | archived = perm.UserRepoToPerm.repository.archived | |
467 | p = 'repository.admin' |
|
468 | p = 'repository.admin' | |
468 | self.permissions_repositories[r_k] = p, PermOrigin.SUPER_ADMIN |
|
469 | self.permissions_repositories[r_k] = p, PermOrigin.SUPER_ADMIN, obj_id | |
469 | # special case for archived repositories, which we block still even for |
|
470 | # special case for archived repositories, which we block still even for | |
470 | # super admins |
|
471 | # super admins | |
471 | if archived: |
|
472 | if archived: | |
472 | p = 'repository.read' |
|
473 | p = 'repository.read' | |
473 | self.permissions_repositories[r_k] = p, PermOrigin.ARCHIVED |
|
474 | self.permissions_repositories[r_k] = p, PermOrigin.ARCHIVED, obj_id | |
474 |
|
475 | |||
475 | # repository groups |
|
476 | # repository groups | |
476 | for perm in self.default_repo_groups_perms: |
|
477 | for perm in self.default_repo_groups_perms: | |
477 | rg_k = perm.UserRepoGroupToPerm.group.group_name |
|
478 | rg_k = perm.UserRepoGroupToPerm.group.group_name | |
|
479 | obj_id = perm.UserRepoGroupToPerm.group.group_id | |||
478 | p = 'group.admin' |
|
480 | p = 'group.admin' | |
479 | self.permissions_repository_groups[rg_k] = p, PermOrigin.SUPER_ADMIN |
|
481 | self.permissions_repository_groups[rg_k] = p, PermOrigin.SUPER_ADMIN, obj_id | |
480 |
|
482 | |||
481 | # user groups |
|
483 | # user groups | |
482 | for perm in self.default_user_group_perms: |
|
484 | for perm in self.default_user_group_perms: | |
483 | u_k = perm.UserUserGroupToPerm.user_group.users_group_name |
|
485 | u_k = perm.UserUserGroupToPerm.user_group.users_group_name | |
|
486 | obj_id = perm.UserUserGroupToPerm.user_group.users_group_id | |||
484 | p = 'usergroup.admin' |
|
487 | p = 'usergroup.admin' | |
485 | self.permissions_user_groups[u_k] = p, PermOrigin.SUPER_ADMIN |
|
488 | self.permissions_user_groups[u_k] = p, PermOrigin.SUPER_ADMIN, obj_id | |
486 |
|
489 | |||
487 | # branch permissions |
|
490 | # branch permissions | |
488 | # since super-admin also can have custom rule permissions |
|
491 | # since super-admin also can have custom rule permissions | |
@@ -578,10 +581,11 b' class PermissionCalculator(object):' | |||||
578 | def _calculate_default_permissions_repositories(self, user_inherit_object_permissions): |
|
581 | def _calculate_default_permissions_repositories(self, user_inherit_object_permissions): | |
579 | for perm in self.default_repo_perms: |
|
582 | for perm in self.default_repo_perms: | |
580 | r_k = perm.UserRepoToPerm.repository.repo_name |
|
583 | r_k = perm.UserRepoToPerm.repository.repo_name | |
|
584 | obj_id = perm.UserRepoToPerm.repository.repo_id | |||
581 | archived = perm.UserRepoToPerm.repository.archived |
|
585 | archived = perm.UserRepoToPerm.repository.archived | |
582 | p = perm.Permission.permission_name |
|
586 | p = perm.Permission.permission_name | |
583 | o = PermOrigin.REPO_DEFAULT |
|
587 | o = PermOrigin.REPO_DEFAULT | |
584 | self.permissions_repositories[r_k] = p, o |
|
588 | self.permissions_repositories[r_k] = p, o, obj_id | |
585 |
|
589 | |||
586 | # if we decide this user isn't inheriting permissions from |
|
590 | # if we decide this user isn't inheriting permissions from | |
587 | # default user we set him to .none so only explicit |
|
591 | # default user we set him to .none so only explicit | |
@@ -589,25 +593,25 b' class PermissionCalculator(object):' | |||||
589 | if not user_inherit_object_permissions: |
|
593 | if not user_inherit_object_permissions: | |
590 | p = 'repository.none' |
|
594 | p = 'repository.none' | |
591 | o = PermOrigin.REPO_DEFAULT_NO_INHERIT |
|
595 | o = PermOrigin.REPO_DEFAULT_NO_INHERIT | |
592 | self.permissions_repositories[r_k] = p, o |
|
596 | self.permissions_repositories[r_k] = p, o, obj_id | |
593 |
|
597 | |||
594 | if perm.Repository.private and not ( |
|
598 | if perm.Repository.private and not ( | |
595 | perm.Repository.user_id == self.user_id): |
|
599 | perm.Repository.user_id == self.user_id): | |
596 | # disable defaults for private repos, |
|
600 | # disable defaults for private repos, | |
597 | p = 'repository.none' |
|
601 | p = 'repository.none' | |
598 | o = PermOrigin.REPO_PRIVATE |
|
602 | o = PermOrigin.REPO_PRIVATE | |
599 | self.permissions_repositories[r_k] = p, o |
|
603 | self.permissions_repositories[r_k] = p, o, obj_id | |
600 |
|
604 | |||
601 | elif perm.Repository.user_id == self.user_id: |
|
605 | elif perm.Repository.user_id == self.user_id: | |
602 | # set admin if owner |
|
606 | # set admin if owner | |
603 | p = 'repository.admin' |
|
607 | p = 'repository.admin' | |
604 | o = PermOrigin.REPO_OWNER |
|
608 | o = PermOrigin.REPO_OWNER | |
605 | self.permissions_repositories[r_k] = p, o |
|
609 | self.permissions_repositories[r_k] = p, o, obj_id | |
606 |
|
610 | |||
607 | if self.user_is_admin: |
|
611 | if self.user_is_admin: | |
608 | p = 'repository.admin' |
|
612 | p = 'repository.admin' | |
609 | o = PermOrigin.SUPER_ADMIN |
|
613 | o = PermOrigin.SUPER_ADMIN | |
610 | self.permissions_repositories[r_k] = p, o |
|
614 | self.permissions_repositories[r_k] = p, o, obj_id | |
611 |
|
615 | |||
612 | # finally in case of archived repositories, we downgrade higher |
|
616 | # finally in case of archived repositories, we downgrade higher | |
613 | # permissions to read |
|
617 | # permissions to read | |
@@ -616,7 +620,7 b' class PermissionCalculator(object):' | |||||
616 | if current_perm in ['repository.write', 'repository.admin']: |
|
620 | if current_perm in ['repository.write', 'repository.admin']: | |
617 | p = 'repository.read' |
|
621 | p = 'repository.read' | |
618 | o = PermOrigin.ARCHIVED |
|
622 | o = PermOrigin.ARCHIVED | |
619 | self.permissions_repositories[r_k] = p, o |
|
623 | self.permissions_repositories[r_k] = p, o, obj_id | |
620 |
|
624 | |||
621 | def _calculate_default_permissions_repository_branches(self, user_inherit_object_permissions): |
|
625 | def _calculate_default_permissions_repository_branches(self, user_inherit_object_permissions): | |
622 | for perm in self.default_branch_repo_perms: |
|
626 | for perm in self.default_branch_repo_perms: | |
@@ -641,52 +645,54 b' class PermissionCalculator(object):' | |||||
641 | def _calculate_default_permissions_repository_groups(self, user_inherit_object_permissions): |
|
645 | def _calculate_default_permissions_repository_groups(self, user_inherit_object_permissions): | |
642 | for perm in self.default_repo_groups_perms: |
|
646 | for perm in self.default_repo_groups_perms: | |
643 | rg_k = perm.UserRepoGroupToPerm.group.group_name |
|
647 | rg_k = perm.UserRepoGroupToPerm.group.group_name | |
|
648 | obj_id = perm.UserRepoGroupToPerm.group.group_id | |||
644 | p = perm.Permission.permission_name |
|
649 | p = perm.Permission.permission_name | |
645 | o = PermOrigin.REPOGROUP_DEFAULT |
|
650 | o = PermOrigin.REPOGROUP_DEFAULT | |
646 | self.permissions_repository_groups[rg_k] = p, o |
|
651 | self.permissions_repository_groups[rg_k] = p, o, obj_id | |
647 |
|
652 | |||
648 | # if we decide this user isn't inheriting permissions from default |
|
653 | # if we decide this user isn't inheriting permissions from default | |
649 | # user we set him to .none so only explicit permissions work |
|
654 | # user we set him to .none so only explicit permissions work | |
650 | if not user_inherit_object_permissions: |
|
655 | if not user_inherit_object_permissions: | |
651 | p = 'group.none' |
|
656 | p = 'group.none' | |
652 | o = PermOrigin.REPOGROUP_DEFAULT_NO_INHERIT |
|
657 | o = PermOrigin.REPOGROUP_DEFAULT_NO_INHERIT | |
653 | self.permissions_repository_groups[rg_k] = p, o |
|
658 | self.permissions_repository_groups[rg_k] = p, o, obj_id | |
654 |
|
659 | |||
655 | if perm.RepoGroup.user_id == self.user_id: |
|
660 | if perm.RepoGroup.user_id == self.user_id: | |
656 | # set admin if owner |
|
661 | # set admin if owner | |
657 | p = 'group.admin' |
|
662 | p = 'group.admin' | |
658 | o = PermOrigin.REPOGROUP_OWNER |
|
663 | o = PermOrigin.REPOGROUP_OWNER | |
659 | self.permissions_repository_groups[rg_k] = p, o |
|
664 | self.permissions_repository_groups[rg_k] = p, o, obj_id | |
660 |
|
665 | |||
661 | if self.user_is_admin: |
|
666 | if self.user_is_admin: | |
662 | p = 'group.admin' |
|
667 | p = 'group.admin' | |
663 | o = PermOrigin.SUPER_ADMIN |
|
668 | o = PermOrigin.SUPER_ADMIN | |
664 | self.permissions_repository_groups[rg_k] = p, o |
|
669 | self.permissions_repository_groups[rg_k] = p, o, obj_id | |
665 |
|
670 | |||
666 | def _calculate_default_permissions_user_groups(self, user_inherit_object_permissions): |
|
671 | def _calculate_default_permissions_user_groups(self, user_inherit_object_permissions): | |
667 | for perm in self.default_user_group_perms: |
|
672 | for perm in self.default_user_group_perms: | |
668 | u_k = perm.UserUserGroupToPerm.user_group.users_group_name |
|
673 | u_k = perm.UserUserGroupToPerm.user_group.users_group_name | |
|
674 | obj_id = perm.UserUserGroupToPerm.user_group.users_group_id | |||
669 | p = perm.Permission.permission_name |
|
675 | p = perm.Permission.permission_name | |
670 | o = PermOrigin.USERGROUP_DEFAULT |
|
676 | o = PermOrigin.USERGROUP_DEFAULT | |
671 | self.permissions_user_groups[u_k] = p, o |
|
677 | self.permissions_user_groups[u_k] = p, o, obj_id | |
672 |
|
678 | |||
673 | # if we decide this user isn't inheriting permissions from default |
|
679 | # if we decide this user isn't inheriting permissions from default | |
674 | # user we set him to .none so only explicit permissions work |
|
680 | # user we set him to .none so only explicit permissions work | |
675 | if not user_inherit_object_permissions: |
|
681 | if not user_inherit_object_permissions: | |
676 | p = 'usergroup.none' |
|
682 | p = 'usergroup.none' | |
677 | o = PermOrigin.USERGROUP_DEFAULT_NO_INHERIT |
|
683 | o = PermOrigin.USERGROUP_DEFAULT_NO_INHERIT | |
678 | self.permissions_user_groups[u_k] = p, o |
|
684 | self.permissions_user_groups[u_k] = p, o, obj_id | |
679 |
|
685 | |||
680 | if perm.UserGroup.user_id == self.user_id: |
|
686 | if perm.UserGroup.user_id == self.user_id: | |
681 | # set admin if owner |
|
687 | # set admin if owner | |
682 | p = 'usergroup.admin' |
|
688 | p = 'usergroup.admin' | |
683 | o = PermOrigin.USERGROUP_OWNER |
|
689 | o = PermOrigin.USERGROUP_OWNER | |
684 | self.permissions_user_groups[u_k] = p, o |
|
690 | self.permissions_user_groups[u_k] = p, o, obj_id | |
685 |
|
691 | |||
686 | if self.user_is_admin: |
|
692 | if self.user_is_admin: | |
687 | p = 'usergroup.admin' |
|
693 | p = 'usergroup.admin' | |
688 | o = PermOrigin.SUPER_ADMIN |
|
694 | o = PermOrigin.SUPER_ADMIN | |
689 | self.permissions_user_groups[u_k] = p, o |
|
695 | self.permissions_user_groups[u_k] = p, o, obj_id | |
690 |
|
696 | |||
691 | def _calculate_default_permissions(self): |
|
697 | def _calculate_default_permissions(self): | |
692 | """ |
|
698 | """ | |
@@ -738,6 +744,7 b' class PermissionCalculator(object):' | |||||
738 | multiple_counter = collections.defaultdict(int) |
|
744 | multiple_counter = collections.defaultdict(int) | |
739 | for perm in user_repo_perms_from_user_group: |
|
745 | for perm in user_repo_perms_from_user_group: | |
740 | r_k = perm.UserGroupRepoToPerm.repository.repo_name |
|
746 | r_k = perm.UserGroupRepoToPerm.repository.repo_name | |
|
747 | obj_id = perm.UserGroupRepoToPerm.repository.repo_id | |||
741 | multiple_counter[r_k] += 1 |
|
748 | multiple_counter[r_k] += 1 | |
742 | p = perm.Permission.permission_name |
|
749 | p = perm.Permission.permission_name | |
743 | o = PermOrigin.REPO_USERGROUP % perm.UserGroupRepoToPerm\ |
|
750 | o = PermOrigin.REPO_USERGROUP % perm.UserGroupRepoToPerm\ | |
@@ -747,18 +754,18 b' class PermissionCalculator(object):' | |||||
747 | cur_perm = self.permissions_repositories[r_k] |
|
754 | cur_perm = self.permissions_repositories[r_k] | |
748 | p = self._choose_permission(p, cur_perm) |
|
755 | p = self._choose_permission(p, cur_perm) | |
749 |
|
756 | |||
750 | self.permissions_repositories[r_k] = p, o |
|
757 | self.permissions_repositories[r_k] = p, o, obj_id | |
751 |
|
758 | |||
752 | if perm.Repository.user_id == self.user_id: |
|
759 | if perm.Repository.user_id == self.user_id: | |
753 | # set admin if owner |
|
760 | # set admin if owner | |
754 | p = 'repository.admin' |
|
761 | p = 'repository.admin' | |
755 | o = PermOrigin.REPO_OWNER |
|
762 | o = PermOrigin.REPO_OWNER | |
756 | self.permissions_repositories[r_k] = p, o |
|
763 | self.permissions_repositories[r_k] = p, o, obj_id | |
757 |
|
764 | |||
758 | if self.user_is_admin: |
|
765 | if self.user_is_admin: | |
759 | p = 'repository.admin' |
|
766 | p = 'repository.admin' | |
760 | o = PermOrigin.SUPER_ADMIN |
|
767 | o = PermOrigin.SUPER_ADMIN | |
761 | self.permissions_repositories[r_k] = p, o |
|
768 | self.permissions_repositories[r_k] = p, o, obj_id | |
762 |
|
769 | |||
763 | # user explicit permissions for repositories, overrides any specified |
|
770 | # user explicit permissions for repositories, overrides any specified | |
764 | # by the group permission |
|
771 | # by the group permission | |
@@ -766,6 +773,7 b' class PermissionCalculator(object):' | |||||
766 | self.user_id, self.scope_repo_id) |
|
773 | self.user_id, self.scope_repo_id) | |
767 | for perm in user_repo_perms: |
|
774 | for perm in user_repo_perms: | |
768 | r_k = perm.UserRepoToPerm.repository.repo_name |
|
775 | r_k = perm.UserRepoToPerm.repository.repo_name | |
|
776 | obj_id = perm.UserRepoToPerm.repository.repo_id | |||
769 | p = perm.Permission.permission_name |
|
777 | p = perm.Permission.permission_name | |
770 | o = PermOrigin.REPO_USER % perm.UserRepoToPerm.user.username |
|
778 | o = PermOrigin.REPO_USER % perm.UserRepoToPerm.user.username | |
771 |
|
779 | |||
@@ -774,18 +782,18 b' class PermissionCalculator(object):' | |||||
774 | r_k, 'repository.none') |
|
782 | r_k, 'repository.none') | |
775 | p = self._choose_permission(p, cur_perm) |
|
783 | p = self._choose_permission(p, cur_perm) | |
776 |
|
784 | |||
777 | self.permissions_repositories[r_k] = p, o |
|
785 | self.permissions_repositories[r_k] = p, o, obj_id | |
778 |
|
786 | |||
779 | if perm.Repository.user_id == self.user_id: |
|
787 | if perm.Repository.user_id == self.user_id: | |
780 | # set admin if owner |
|
788 | # set admin if owner | |
781 | p = 'repository.admin' |
|
789 | p = 'repository.admin' | |
782 | o = PermOrigin.REPO_OWNER |
|
790 | o = PermOrigin.REPO_OWNER | |
783 | self.permissions_repositories[r_k] = p, o |
|
791 | self.permissions_repositories[r_k] = p, o, obj_id | |
784 |
|
792 | |||
785 | if self.user_is_admin: |
|
793 | if self.user_is_admin: | |
786 | p = 'repository.admin' |
|
794 | p = 'repository.admin' | |
787 | o = PermOrigin.SUPER_ADMIN |
|
795 | o = PermOrigin.SUPER_ADMIN | |
788 | self.permissions_repositories[r_k] = p, o |
|
796 | self.permissions_repositories[r_k] = p, o, obj_id | |
789 |
|
797 | |||
790 | def _calculate_repository_branch_permissions(self): |
|
798 | def _calculate_repository_branch_permissions(self): | |
791 | # user group for repositories permissions |
|
799 | # user group for repositories permissions | |
@@ -847,6 +855,7 b' class PermissionCalculator(object):' | |||||
847 | multiple_counter = collections.defaultdict(int) |
|
855 | multiple_counter = collections.defaultdict(int) | |
848 | for perm in user_repo_group_perms_from_user_group: |
|
856 | for perm in user_repo_group_perms_from_user_group: | |
849 | rg_k = perm.UserGroupRepoGroupToPerm.group.group_name |
|
857 | rg_k = perm.UserGroupRepoGroupToPerm.group.group_name | |
|
858 | obj_id = perm.UserGroupRepoGroupToPerm.group.group_id | |||
850 | multiple_counter[rg_k] += 1 |
|
859 | multiple_counter[rg_k] += 1 | |
851 | o = PermOrigin.REPOGROUP_USERGROUP % perm.UserGroupRepoGroupToPerm\ |
|
860 | o = PermOrigin.REPOGROUP_USERGROUP % perm.UserGroupRepoGroupToPerm\ | |
852 | .users_group.users_group_name |
|
861 | .users_group.users_group_name | |
@@ -855,24 +864,25 b' class PermissionCalculator(object):' | |||||
855 | if multiple_counter[rg_k] > 1: |
|
864 | if multiple_counter[rg_k] > 1: | |
856 | cur_perm = self.permissions_repository_groups[rg_k] |
|
865 | cur_perm = self.permissions_repository_groups[rg_k] | |
857 | p = self._choose_permission(p, cur_perm) |
|
866 | p = self._choose_permission(p, cur_perm) | |
858 | self.permissions_repository_groups[rg_k] = p, o |
|
867 | self.permissions_repository_groups[rg_k] = p, o, obj_id | |
859 |
|
868 | |||
860 | if perm.RepoGroup.user_id == self.user_id: |
|
869 | if perm.RepoGroup.user_id == self.user_id: | |
861 | # set admin if owner, even for member of other user group |
|
870 | # set admin if owner, even for member of other user group | |
862 | p = 'group.admin' |
|
871 | p = 'group.admin' | |
863 | o = PermOrigin.REPOGROUP_OWNER |
|
872 | o = PermOrigin.REPOGROUP_OWNER | |
864 | self.permissions_repository_groups[rg_k] = p, o |
|
873 | self.permissions_repository_groups[rg_k] = p, o, obj_id | |
865 |
|
874 | |||
866 | if self.user_is_admin: |
|
875 | if self.user_is_admin: | |
867 | p = 'group.admin' |
|
876 | p = 'group.admin' | |
868 | o = PermOrigin.SUPER_ADMIN |
|
877 | o = PermOrigin.SUPER_ADMIN | |
869 | self.permissions_repository_groups[rg_k] = p, o |
|
878 | self.permissions_repository_groups[rg_k] = p, o, obj_id | |
870 |
|
879 | |||
871 | # user explicit permissions for repository groups |
|
880 | # user explicit permissions for repository groups | |
872 | user_repo_groups_perms = Permission.get_default_group_perms( |
|
881 | user_repo_groups_perms = Permission.get_default_group_perms( | |
873 | self.user_id, self.scope_repo_group_id) |
|
882 | self.user_id, self.scope_repo_group_id) | |
874 | for perm in user_repo_groups_perms: |
|
883 | for perm in user_repo_groups_perms: | |
875 | rg_k = perm.UserRepoGroupToPerm.group.group_name |
|
884 | rg_k = perm.UserRepoGroupToPerm.group.group_name | |
|
885 | obj_id = perm.UserRepoGroupToPerm.group.group_id | |||
876 | o = PermOrigin.REPOGROUP_USER % perm.UserRepoGroupToPerm\ |
|
886 | o = PermOrigin.REPOGROUP_USER % perm.UserRepoGroupToPerm\ | |
877 | .user.username |
|
887 | .user.username | |
878 | p = perm.Permission.permission_name |
|
888 | p = perm.Permission.permission_name | |
@@ -881,18 +891,18 b' class PermissionCalculator(object):' | |||||
881 | cur_perm = self.permissions_repository_groups.get(rg_k, 'group.none') |
|
891 | cur_perm = self.permissions_repository_groups.get(rg_k, 'group.none') | |
882 | p = self._choose_permission(p, cur_perm) |
|
892 | p = self._choose_permission(p, cur_perm) | |
883 |
|
893 | |||
884 | self.permissions_repository_groups[rg_k] = p, o |
|
894 | self.permissions_repository_groups[rg_k] = p, o, obj_id | |
885 |
|
895 | |||
886 | if perm.RepoGroup.user_id == self.user_id: |
|
896 | if perm.RepoGroup.user_id == self.user_id: | |
887 | # set admin if owner |
|
897 | # set admin if owner | |
888 | p = 'group.admin' |
|
898 | p = 'group.admin' | |
889 | o = PermOrigin.REPOGROUP_OWNER |
|
899 | o = PermOrigin.REPOGROUP_OWNER | |
890 | self.permissions_repository_groups[rg_k] = p, o |
|
900 | self.permissions_repository_groups[rg_k] = p, o, obj_id | |
891 |
|
901 | |||
892 | if self.user_is_admin: |
|
902 | if self.user_is_admin: | |
893 | p = 'group.admin' |
|
903 | p = 'group.admin' | |
894 | o = PermOrigin.SUPER_ADMIN |
|
904 | o = PermOrigin.SUPER_ADMIN | |
895 | self.permissions_repository_groups[rg_k] = p, o |
|
905 | self.permissions_repository_groups[rg_k] = p, o, obj_id | |
896 |
|
906 | |||
897 | def _calculate_user_group_permissions(self): |
|
907 | def _calculate_user_group_permissions(self): | |
898 | """ |
|
908 | """ | |
@@ -905,8 +915,8 b' class PermissionCalculator(object):' | |||||
905 |
|
915 | |||
906 | multiple_counter = collections.defaultdict(int) |
|
916 | multiple_counter = collections.defaultdict(int) | |
907 | for perm in user_group_from_user_group: |
|
917 | for perm in user_group_from_user_group: | |
908 |
ug_k = perm.UserGroupUserGroupToPerm |
|
918 | ug_k = perm.UserGroupUserGroupToPerm.target_user_group.users_group_name | |
909 |
|
|
919 | obj_id = perm.UserGroupUserGroupToPerm.target_user_group.users_group_id | |
910 | multiple_counter[ug_k] += 1 |
|
920 | multiple_counter[ug_k] += 1 | |
911 | o = PermOrigin.USERGROUP_USERGROUP % perm.UserGroupUserGroupToPerm\ |
|
921 | o = PermOrigin.USERGROUP_USERGROUP % perm.UserGroupUserGroupToPerm\ | |
912 | .user_group.users_group_name |
|
922 | .user_group.users_group_name | |
@@ -916,24 +926,25 b' class PermissionCalculator(object):' | |||||
916 | cur_perm = self.permissions_user_groups[ug_k] |
|
926 | cur_perm = self.permissions_user_groups[ug_k] | |
917 | p = self._choose_permission(p, cur_perm) |
|
927 | p = self._choose_permission(p, cur_perm) | |
918 |
|
928 | |||
919 | self.permissions_user_groups[ug_k] = p, o |
|
929 | self.permissions_user_groups[ug_k] = p, o, obj_id | |
920 |
|
930 | |||
921 | if perm.UserGroup.user_id == self.user_id: |
|
931 | if perm.UserGroup.user_id == self.user_id: | |
922 | # set admin if owner, even for member of other user group |
|
932 | # set admin if owner, even for member of other user group | |
923 | p = 'usergroup.admin' |
|
933 | p = 'usergroup.admin' | |
924 | o = PermOrigin.USERGROUP_OWNER |
|
934 | o = PermOrigin.USERGROUP_OWNER | |
925 | self.permissions_user_groups[ug_k] = p, o |
|
935 | self.permissions_user_groups[ug_k] = p, o, obj_id | |
926 |
|
936 | |||
927 | if self.user_is_admin: |
|
937 | if self.user_is_admin: | |
928 | p = 'usergroup.admin' |
|
938 | p = 'usergroup.admin' | |
929 | o = PermOrigin.SUPER_ADMIN |
|
939 | o = PermOrigin.SUPER_ADMIN | |
930 | self.permissions_user_groups[ug_k] = p, o |
|
940 | self.permissions_user_groups[ug_k] = p, o, obj_id | |
931 |
|
941 | |||
932 | # user explicit permission for user groups |
|
942 | # user explicit permission for user groups | |
933 | user_user_groups_perms = Permission.get_default_user_group_perms( |
|
943 | user_user_groups_perms = Permission.get_default_user_group_perms( | |
934 | self.user_id, self.scope_user_group_id) |
|
944 | self.user_id, self.scope_user_group_id) | |
935 | for perm in user_user_groups_perms: |
|
945 | for perm in user_user_groups_perms: | |
936 | ug_k = perm.UserUserGroupToPerm.user_group.users_group_name |
|
946 | ug_k = perm.UserUserGroupToPerm.user_group.users_group_name | |
|
947 | obj_id = perm.UserUserGroupToPerm.user_group.users_group_id | |||
937 | o = PermOrigin.USERGROUP_USER % perm.UserUserGroupToPerm\ |
|
948 | o = PermOrigin.USERGROUP_USER % perm.UserUserGroupToPerm\ | |
938 | .user.username |
|
949 | .user.username | |
939 | p = perm.Permission.permission_name |
|
950 | p = perm.Permission.permission_name | |
@@ -942,18 +953,18 b' class PermissionCalculator(object):' | |||||
942 | cur_perm = self.permissions_user_groups.get(ug_k, 'usergroup.none') |
|
953 | cur_perm = self.permissions_user_groups.get(ug_k, 'usergroup.none') | |
943 | p = self._choose_permission(p, cur_perm) |
|
954 | p = self._choose_permission(p, cur_perm) | |
944 |
|
955 | |||
945 | self.permissions_user_groups[ug_k] = p, o |
|
956 | self.permissions_user_groups[ug_k] = p, o, obj_id | |
946 |
|
957 | |||
947 | if perm.UserGroup.user_id == self.user_id: |
|
958 | if perm.UserGroup.user_id == self.user_id: | |
948 | # set admin if owner |
|
959 | # set admin if owner | |
949 | p = 'usergroup.admin' |
|
960 | p = 'usergroup.admin' | |
950 | o = PermOrigin.USERGROUP_OWNER |
|
961 | o = PermOrigin.USERGROUP_OWNER | |
951 | self.permissions_user_groups[ug_k] = p, o |
|
962 | self.permissions_user_groups[ug_k] = p, o, obj_id | |
952 |
|
963 | |||
953 | if self.user_is_admin: |
|
964 | if self.user_is_admin: | |
954 | p = 'usergroup.admin' |
|
965 | p = 'usergroup.admin' | |
955 | o = PermOrigin.SUPER_ADMIN |
|
966 | o = PermOrigin.SUPER_ADMIN | |
956 | self.permissions_user_groups[ug_k] = p, o |
|
967 | self.permissions_user_groups[ug_k] = p, o, obj_id | |
957 |
|
968 | |||
958 | def _choose_permission(self, new_perm, cur_perm): |
|
969 | def _choose_permission(self, new_perm, cur_perm): | |
959 | new_perm_val = Permission.PERM_WEIGHTS[new_perm] |
|
970 | new_perm_val = Permission.PERM_WEIGHTS[new_perm] | |
@@ -1277,6 +1288,18 b' class AuthUser(object):' | |||||
1277 | x[0] for x in self.permissions['user_groups'].items() |
|
1288 | x[0] for x in self.permissions['user_groups'].items() | |
1278 | if x[1] == 'usergroup.admin'] |
|
1289 | if x[1] == 'usergroup.admin'] | |
1279 |
|
1290 | |||
|
1291 | def repo_acl_ids_from_stack(self, perms=None, prefix_filter=None, cache=False): | |||
|
1292 | if not perms: | |||
|
1293 | perms = ['repository.read', 'repository.write', 'repository.admin'] | |||
|
1294 | allowed_ids = [] | |||
|
1295 | for k, stack_data in self.permissions['repositories'].perm_origin_stack.items(): | |||
|
1296 | perm, origin, obj_id = stack_data[-1] # last item is the current permission | |||
|
1297 | if prefix_filter and not k.startswith(prefix_filter): | |||
|
1298 | continue | |||
|
1299 | if perm in perms: | |||
|
1300 | allowed_ids.append(obj_id) | |||
|
1301 | return allowed_ids | |||
|
1302 | ||||
1280 | def repo_acl_ids(self, perms=None, name_filter=None, cache=False): |
|
1303 | def repo_acl_ids(self, perms=None, name_filter=None, cache=False): | |
1281 | """ |
|
1304 | """ | |
1282 | Returns list of repository ids that user have access to based on given |
|
1305 | Returns list of repository ids that user have access to based on given | |
@@ -1285,8 +1308,7 b' class AuthUser(object):' | |||||
1285 | """ |
|
1308 | """ | |
1286 | from rhodecode.model.scm import RepoList |
|
1309 | from rhodecode.model.scm import RepoList | |
1287 | if not perms: |
|
1310 | if not perms: | |
1288 | perms = [ |
|
1311 | perms = ['repository.read', 'repository.write', 'repository.admin'] | |
1289 | 'repository.read', 'repository.write', 'repository.admin'] |
|
|||
1290 |
|
1312 | |||
1291 | def _cached_repo_acl(user_id, perm_def, _name_filter): |
|
1313 | def _cached_repo_acl(user_id, perm_def, _name_filter): | |
1292 | qry = Repository.query() |
|
1314 | qry = Repository.query() | |
@@ -1296,10 +1318,22 b' class AuthUser(object):' | |||||
1296 | Repository.repo_name.ilike(ilike_expression)) |
|
1318 | Repository.repo_name.ilike(ilike_expression)) | |
1297 |
|
1319 | |||
1298 | return [x.repo_id for x in |
|
1320 | return [x.repo_id for x in | |
1299 | RepoList(qry, perm_set=perm_def)] |
|
1321 | RepoList(qry, perm_set=perm_def, extra_kwargs={'user': self})] | |
1300 |
|
1322 | |||
1301 | return _cached_repo_acl(self.user_id, perms, name_filter) |
|
1323 | return _cached_repo_acl(self.user_id, perms, name_filter) | |
1302 |
|
1324 | |||
|
1325 | def repo_group_acl_ids_from_stack(self, perms=None, prefix_filter=None, cache=False): | |||
|
1326 | if not perms: | |||
|
1327 | perms = ['group.read', 'group.write', 'group.admin'] | |||
|
1328 | allowed_ids = [] | |||
|
1329 | for k, stack_data in self.permissions['repositories_groups'].perm_origin_stack.items(): | |||
|
1330 | perm, origin, obj_id = stack_data[-1] # last item is the current permission | |||
|
1331 | if prefix_filter and not k.startswith(prefix_filter): | |||
|
1332 | continue | |||
|
1333 | if perm in perms: | |||
|
1334 | allowed_ids.append(obj_id) | |||
|
1335 | return allowed_ids | |||
|
1336 | ||||
1303 | def repo_group_acl_ids(self, perms=None, name_filter=None, cache=False): |
|
1337 | def repo_group_acl_ids(self, perms=None, name_filter=None, cache=False): | |
1304 | """ |
|
1338 | """ | |
1305 | Returns list of repository group ids that user have access to based on given |
|
1339 | Returns list of repository group ids that user have access to based on given | |
@@ -1308,8 +1342,7 b' class AuthUser(object):' | |||||
1308 | """ |
|
1342 | """ | |
1309 | from rhodecode.model.scm import RepoGroupList |
|
1343 | from rhodecode.model.scm import RepoGroupList | |
1310 | if not perms: |
|
1344 | if not perms: | |
1311 | perms = [ |
|
1345 | perms = ['group.read', 'group.write', 'group.admin'] | |
1312 | 'group.read', 'group.write', 'group.admin'] |
|
|||
1313 |
|
1346 | |||
1314 | def _cached_repo_group_acl(user_id, perm_def, _name_filter): |
|
1347 | def _cached_repo_group_acl(user_id, perm_def, _name_filter): | |
1315 | qry = RepoGroup.query() |
|
1348 | qry = RepoGroup.query() | |
@@ -1319,10 +1352,20 b' class AuthUser(object):' | |||||
1319 | RepoGroup.group_name.ilike(ilike_expression)) |
|
1352 | RepoGroup.group_name.ilike(ilike_expression)) | |
1320 |
|
1353 | |||
1321 | return [x.group_id for x in |
|
1354 | return [x.group_id for x in | |
1322 | RepoGroupList(qry, perm_set=perm_def)] |
|
1355 | RepoGroupList(qry, perm_set=perm_def, extra_kwargs={'user': self})] | |
1323 |
|
1356 | |||
1324 | return _cached_repo_group_acl(self.user_id, perms, name_filter) |
|
1357 | return _cached_repo_group_acl(self.user_id, perms, name_filter) | |
1325 |
|
1358 | |||
|
1359 | def user_group_acl_ids_from_stack(self, perms=None, cache=False): | |||
|
1360 | if not perms: | |||
|
1361 | perms = ['usergroup.read', 'usergroup.write', 'usergroup.admin'] | |||
|
1362 | allowed_ids = [] | |||
|
1363 | for k, stack_data in self.permissions['user_groups'].perm_origin_stack.items(): | |||
|
1364 | perm, origin, obj_id = stack_data[-1] # last item is the current permission | |||
|
1365 | if perm in perms: | |||
|
1366 | allowed_ids.append(obj_id) | |||
|
1367 | return allowed_ids | |||
|
1368 | ||||
1326 | def user_group_acl_ids(self, perms=None, name_filter=None, cache=False): |
|
1369 | def user_group_acl_ids(self, perms=None, name_filter=None, cache=False): | |
1327 | """ |
|
1370 | """ | |
1328 | Returns list of user group ids that user have access to based on given |
|
1371 | Returns list of user group ids that user have access to based on given | |
@@ -1331,8 +1374,7 b' class AuthUser(object):' | |||||
1331 | """ |
|
1374 | """ | |
1332 | from rhodecode.model.scm import UserGroupList |
|
1375 | from rhodecode.model.scm import UserGroupList | |
1333 | if not perms: |
|
1376 | if not perms: | |
1334 | perms = [ |
|
1377 | perms = ['usergroup.read', 'usergroup.write', 'usergroup.admin'] | |
1335 | 'usergroup.read', 'usergroup.write', 'usergroup.admin'] |
|
|||
1336 |
|
1378 | |||
1337 | def _cached_user_group_acl(user_id, perm_def, name_filter): |
|
1379 | def _cached_user_group_acl(user_id, perm_def, name_filter): | |
1338 | qry = UserGroup.query() |
|
1380 | qry = UserGroup.query() | |
@@ -1342,7 +1384,7 b' class AuthUser(object):' | |||||
1342 | UserGroup.users_group_name.ilike(ilike_expression)) |
|
1384 | UserGroup.users_group_name.ilike(ilike_expression)) | |
1343 |
|
1385 | |||
1344 | return [x.users_group_id for x in |
|
1386 | return [x.users_group_id for x in | |
1345 | UserGroupList(qry, perm_set=perm_def)] |
|
1387 | UserGroupList(qry, perm_set=perm_def, extra_kwargs={'user': self})] | |
1346 |
|
1388 | |||
1347 | return _cached_user_group_acl(self.user_id, perms, name_filter) |
|
1389 | return _cached_user_group_acl(self.user_id, perms, name_filter) | |
1348 |
|
1390 |
@@ -1646,7 +1646,7 b' class Repository(Base, BaseModel):' | |||||
1646 | primary_key=True) |
|
1646 | primary_key=True) | |
1647 | _repo_name = Column( |
|
1647 | _repo_name = Column( | |
1648 | "repo_name", Text(), nullable=False, default=None) |
|
1648 | "repo_name", Text(), nullable=False, default=None) | |
1649 |
|
|
1649 | repo_name_hash = Column( | |
1650 | "repo_name_hash", String(255), nullable=False, unique=True) |
|
1650 | "repo_name_hash", String(255), nullable=False, unique=True) | |
1651 | repo_state = Column("repo_state", String(255), nullable=True) |
|
1651 | repo_state = Column("repo_state", String(255), nullable=True) | |
1652 |
|
1652 | |||
@@ -1772,22 +1772,26 b' class Repository(Base, BaseModel):' | |||||
1772 | else: |
|
1772 | else: | |
1773 | self._locked = None |
|
1773 | self._locked = None | |
1774 |
|
1774 | |||
1775 | @hybrid_property |
|
1775 | @classmethod | |
1776 | def changeset_cache(self): |
|
1776 | def _load_changeset_cache(cls, repo_id, changeset_cache_raw): | |
1777 | from rhodecode.lib.vcs.backends.base import EmptyCommit |
|
1777 | from rhodecode.lib.vcs.backends.base import EmptyCommit | |
1778 | dummy = EmptyCommit().__json__() |
|
1778 | dummy = EmptyCommit().__json__() | |
1779 |
if not |
|
1779 | if not changeset_cache_raw: | |
1780 |
dummy['source_repo_id'] = |
|
1780 | dummy['source_repo_id'] = repo_id | |
1781 | return json.loads(json.dumps(dummy)) |
|
1781 | return json.loads(json.dumps(dummy)) | |
1782 |
|
1782 | |||
1783 | try: |
|
1783 | try: | |
1784 |
return json.loads( |
|
1784 | return json.loads(changeset_cache_raw) | |
1785 | except TypeError: |
|
1785 | except TypeError: | |
1786 | return dummy |
|
1786 | return dummy | |
1787 | except Exception: |
|
1787 | except Exception: | |
1788 | log.error(traceback.format_exc()) |
|
1788 | log.error(traceback.format_exc()) | |
1789 | return dummy |
|
1789 | return dummy | |
1790 |
|
1790 | |||
|
1791 | @hybrid_property | |||
|
1792 | def changeset_cache(self): | |||
|
1793 | return self._load_changeset_cache(self.repo_id, self._changeset_cache) | |||
|
1794 | ||||
1791 | @changeset_cache.setter |
|
1795 | @changeset_cache.setter | |
1792 | def changeset_cache(self, val): |
|
1796 | def changeset_cache(self, val): | |
1793 | try: |
|
1797 | try: | |
@@ -1802,7 +1806,7 b' class Repository(Base, BaseModel):' | |||||
1802 | @repo_name.setter |
|
1806 | @repo_name.setter | |
1803 | def repo_name(self, value): |
|
1807 | def repo_name(self, value): | |
1804 | self._repo_name = value |
|
1808 | self._repo_name = value | |
1805 |
self. |
|
1809 | self.repo_name_hash = hashlib.sha1(safe_str(value)).hexdigest() | |
1806 |
|
1810 | |||
1807 | @classmethod |
|
1811 | @classmethod | |
1808 | def normalize_repo_name(cls, repo_name): |
|
1812 | def normalize_repo_name(cls, repo_name): | |
@@ -2239,17 +2243,21 b' class Repository(Base, BaseModel):' | |||||
2239 | def last_commit_cache_update_diff(self): |
|
2243 | def last_commit_cache_update_diff(self): | |
2240 | return time.time() - (safe_int(self.changeset_cache.get('updated_on')) or 0) |
|
2244 | return time.time() - (safe_int(self.changeset_cache.get('updated_on')) or 0) | |
2241 |
|
2245 | |||
2242 | @property |
|
2246 | @classmethod | |
2243 |
def |
|
2247 | def _load_commit_change(cls, last_commit_cache): | |
2244 | from rhodecode.lib.vcs.utils.helpers import parse_datetime |
|
2248 | from rhodecode.lib.vcs.utils.helpers import parse_datetime | |
2245 | empty_date = datetime.datetime.fromtimestamp(0) |
|
2249 | empty_date = datetime.datetime.fromtimestamp(0) | |
2246 |
date_latest = |
|
2250 | date_latest = last_commit_cache.get('date', empty_date) | |
2247 | try: |
|
2251 | try: | |
2248 | return parse_datetime(date_latest) |
|
2252 | return parse_datetime(date_latest) | |
2249 | except Exception: |
|
2253 | except Exception: | |
2250 | return empty_date |
|
2254 | return empty_date | |
2251 |
|
2255 | |||
2252 | @property |
|
2256 | @property | |
|
2257 | def last_commit_change(self): | |||
|
2258 | return self._load_commit_change(self.changeset_cache) | |||
|
2259 | ||||
|
2260 | @property | |||
2253 | def last_db_change(self): |
|
2261 | def last_db_change(self): | |
2254 | return self.updated_on |
|
2262 | return self.updated_on | |
2255 |
|
2263 | |||
@@ -2598,8 +2606,7 b' class RepoGroup(Base, BaseModel):' | |||||
2598 | created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) |
|
2606 | created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) | |
2599 | updated_on = Column('updated_on', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now) |
|
2607 | updated_on = Column('updated_on', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now) | |
2600 | personal = Column('personal', Boolean(), nullable=True, unique=None, default=None) |
|
2608 | personal = Column('personal', Boolean(), nullable=True, unique=None, default=None) | |
2601 | _changeset_cache = Column( |
|
2609 | _changeset_cache = Column("changeset_cache", LargeBinary(), nullable=True) # JSON data | |
2602 | "changeset_cache", LargeBinary(), nullable=True) # JSON data |
|
|||
2603 |
|
2610 | |||
2604 | repo_group_to_perm = relationship('UserRepoGroupToPerm', cascade='all', order_by='UserRepoGroupToPerm.group_to_perm_id') |
|
2611 | repo_group_to_perm = relationship('UserRepoGroupToPerm', cascade='all', order_by='UserRepoGroupToPerm.group_to_perm_id') | |
2605 | users_group_to_perm = relationship('UserGroupRepoGroupToPerm', cascade='all') |
|
2612 | users_group_to_perm = relationship('UserGroupRepoGroupToPerm', cascade='all') | |
@@ -2627,22 +2634,26 b' class RepoGroup(Base, BaseModel):' | |||||
2627 | self._group_name = value |
|
2634 | self._group_name = value | |
2628 | self.group_name_hash = self.hash_repo_group_name(value) |
|
2635 | self.group_name_hash = self.hash_repo_group_name(value) | |
2629 |
|
2636 | |||
2630 | @hybrid_property |
|
2637 | @classmethod | |
2631 | def changeset_cache(self): |
|
2638 | def _load_changeset_cache(cls, repo_id, changeset_cache_raw): | |
2632 | from rhodecode.lib.vcs.backends.base import EmptyCommit |
|
2639 | from rhodecode.lib.vcs.backends.base import EmptyCommit | |
2633 | dummy = EmptyCommit().__json__() |
|
2640 | dummy = EmptyCommit().__json__() | |
2634 |
if not |
|
2641 | if not changeset_cache_raw: | |
2635 |
dummy['source_repo_id'] = |
|
2642 | dummy['source_repo_id'] = repo_id | |
2636 | return json.loads(json.dumps(dummy)) |
|
2643 | return json.loads(json.dumps(dummy)) | |
2637 |
|
2644 | |||
2638 | try: |
|
2645 | try: | |
2639 |
return json.loads( |
|
2646 | return json.loads(changeset_cache_raw) | |
2640 | except TypeError: |
|
2647 | except TypeError: | |
2641 | return dummy |
|
2648 | return dummy | |
2642 | except Exception: |
|
2649 | except Exception: | |
2643 | log.error(traceback.format_exc()) |
|
2650 | log.error(traceback.format_exc()) | |
2644 | return dummy |
|
2651 | return dummy | |
2645 |
|
2652 | |||
|
2653 | @hybrid_property | |||
|
2654 | def changeset_cache(self): | |||
|
2655 | return self._load_changeset_cache('', self._changeset_cache) | |||
|
2656 | ||||
2646 | @changeset_cache.setter |
|
2657 | @changeset_cache.setter | |
2647 | def changeset_cache(self, val): |
|
2658 | def changeset_cache(self, val): | |
2648 | try: |
|
2659 | try: | |
@@ -2771,17 +2782,21 b' class RepoGroup(Base, BaseModel):' | |||||
2771 | def last_commit_cache_update_diff(self): |
|
2782 | def last_commit_cache_update_diff(self): | |
2772 | return time.time() - (safe_int(self.changeset_cache.get('updated_on')) or 0) |
|
2783 | return time.time() - (safe_int(self.changeset_cache.get('updated_on')) or 0) | |
2773 |
|
2784 | |||
2774 | @property |
|
2785 | @classmethod | |
2775 |
def |
|
2786 | def _load_commit_change(cls, last_commit_cache): | |
2776 | from rhodecode.lib.vcs.utils.helpers import parse_datetime |
|
2787 | from rhodecode.lib.vcs.utils.helpers import parse_datetime | |
2777 | empty_date = datetime.datetime.fromtimestamp(0) |
|
2788 | empty_date = datetime.datetime.fromtimestamp(0) | |
2778 |
date_latest = |
|
2789 | date_latest = last_commit_cache.get('date', empty_date) | |
2779 | try: |
|
2790 | try: | |
2780 | return parse_datetime(date_latest) |
|
2791 | return parse_datetime(date_latest) | |
2781 | except Exception: |
|
2792 | except Exception: | |
2782 | return empty_date |
|
2793 | return empty_date | |
2783 |
|
2794 | |||
2784 | @property |
|
2795 | @property | |
|
2796 | def last_commit_change(self): | |||
|
2797 | return self._load_commit_change(self.changeset_cache) | |||
|
2798 | ||||
|
2799 | @property | |||
2785 | def last_db_change(self): |
|
2800 | def last_db_change(self): | |
2786 | return self.updated_on |
|
2801 | return self.updated_on | |
2787 |
|
2802 |
@@ -149,8 +149,7 b' class RepoList(_PermCheckIterator):' | |||||
149 |
|
149 | |||
150 | def __init__(self, db_repo_list, perm_set=None, extra_kwargs=None): |
|
150 | def __init__(self, db_repo_list, perm_set=None, extra_kwargs=None): | |
151 | if not perm_set: |
|
151 | if not perm_set: | |
152 | perm_set = [ |
|
152 | perm_set = ['repository.read', 'repository.write', 'repository.admin'] | |
153 | 'repository.read', 'repository.write', 'repository.admin'] |
|
|||
154 |
|
153 | |||
155 | super(RepoList, self).__init__( |
|
154 | super(RepoList, self).__init__( | |
156 | obj_list=db_repo_list, |
|
155 | obj_list=db_repo_list, |
@@ -133,6 +133,7 b' function registerRCRoutes() {' | |||||
133 | pyroutes.register('user_groups_new', '/_admin/user_groups/new', []); |
|
133 | pyroutes.register('user_groups_new', '/_admin/user_groups/new', []); | |
134 | pyroutes.register('user_groups_create', '/_admin/user_groups/create', []); |
|
134 | pyroutes.register('user_groups_create', '/_admin/user_groups/create', []); | |
135 | pyroutes.register('repos', '/_admin/repos', []); |
|
135 | pyroutes.register('repos', '/_admin/repos', []); | |
|
136 | pyroutes.register('repos_data', '/_admin/repos_data', []); | |||
136 | pyroutes.register('repo_new', '/_admin/repos/new', []); |
|
137 | pyroutes.register('repo_new', '/_admin/repos/new', []); | |
137 | pyroutes.register('repo_create', '/_admin/repos/create', []); |
|
138 | pyroutes.register('repo_create', '/_admin/repos/create', []); | |
138 | pyroutes.register('repo_groups', '/_admin/repo_groups', []); |
|
139 | pyroutes.register('repo_groups', '/_admin/repo_groups', []); |
@@ -23,7 +23,7 b'' | |||||
23 |
|
23 | |||
24 | <div class="title"> |
|
24 | <div class="title"> | |
25 | <input class="q_filter_box" id="q_filter" size="15" type="text" name="filter" placeholder="${_('quick filter...')}" value=""/> |
|
25 | <input class="q_filter_box" id="q_filter" size="15" type="text" name="filter" placeholder="${_('quick filter...')}" value=""/> | |
26 |
<span id="repo_group_count"> |
|
26 | <span id="repo_group_count"></span> | |
27 |
|
27 | |||
28 | <ul class="links"> |
|
28 | <ul class="links"> | |
29 | %if c.can_create_repo_group: |
|
29 | %if c.can_create_repo_group: | |
@@ -108,6 +108,7 b'' | |||||
108 | ).draw(); |
|
108 | ).draw(); | |
109 | }) |
|
109 | }) | |
110 | ); |
|
110 | ); | |
|
111 | ||||
111 | }); |
|
112 | }); | |
112 |
|
113 | |||
113 | </script> |
|
114 | </script> |
@@ -23,7 +23,7 b'' | |||||
23 |
|
23 | |||
24 | <div class="title"> |
|
24 | <div class="title"> | |
25 | <input class="q_filter_box" id="q_filter" size="15" type="text" name="filter" placeholder="${_('quick filter...')}" value=""/> |
|
25 | <input class="q_filter_box" id="q_filter" size="15" type="text" name="filter" placeholder="${_('quick filter...')}" value=""/> | |
26 |
<span id="repo_count"> |
|
26 | <span id="repo_count"></span> | |
27 |
|
27 | |||
28 | <ul class="links"> |
|
28 | <ul class="links"> | |
29 | %if c.can_create_repo: |
|
29 | %if c.can_create_repo: | |
@@ -36,68 +36,112 b'' | |||||
36 | <div id="repos_list_wrap"> |
|
36 | <div id="repos_list_wrap"> | |
37 | <table id="repo_list_table" class="display"></table> |
|
37 | <table id="repo_list_table" class="display"></table> | |
38 | </div> |
|
38 | </div> | |
|
39 | ||||
39 | </div> |
|
40 | </div> | |
40 |
|
41 | |||
41 | <script> |
|
42 | <script> | |
42 | $(document).ready(function() { |
|
43 | $(document).ready(function() { | |
43 |
|
44 | var $repoListTable = $('#repo_list_table'); | ||
44 | var get_datatable_count = function(){ |
|
|||
45 | var api = $('#repo_list_table').dataTable().api(); |
|
|||
46 | $('#repo_count').text(api.page.info().recordsDisplay); |
|
|||
47 | }; |
|
|||
48 |
|
||||
49 |
|
45 | |||
50 | // repo list |
|
46 | // repo list | |
51 |
$ |
|
47 | $repoListTable.DataTable({ | |
52 | data: ${c.data|n}, |
|
48 | processing: true, | |
|
49 | serverSide: true, | |||
|
50 | ajax: { | |||
|
51 | "url": "${h.route_path('repos_data')}", | |||
|
52 | "dataSrc": function (json) { | |||
|
53 | var filteredCount = json.recordsFiltered; | |||
|
54 | var total = json.recordsTotal; | |||
|
55 | ||||
|
56 | var _text = _gettext( | |||
|
57 | "{0} of {1} repositories").format( | |||
|
58 | filteredCount, total); | |||
|
59 | ||||
|
60 | if (total === filteredCount) { | |||
|
61 | _text = _gettext("{0} repositories").format(total); | |||
|
62 | } | |||
|
63 | $('#repo_count').text(_text); | |||
|
64 | ||||
|
65 | return json.data; | |||
|
66 | }, | |||
|
67 | }, | |||
53 | dom: 'rtp', |
|
68 | dom: 'rtp', | |
54 | pageLength: ${c.visual.admin_grid_items}, |
|
69 | pageLength: ${c.visual.admin_grid_items}, | |
55 | order: [[ 0, "asc" ]], |
|
70 | order: [[ 0, "asc" ]], | |
56 | columns: [ |
|
71 | columns: [ | |
57 | { data: {"_": "name", |
|
72 | { | |
58 | "sort": "name_raw"}, title: "${_('Name')}", className: "td-componentname" }, |
|
73 | data: { | |
59 | { data: 'menu', "bSortable": false, className: "quick_repo_menu" }, |
|
74 | "_": "name", | |
60 | { data: {"_": "desc", |
|
75 | "sort": "name_raw" | |
61 |
|
|
76 | }, title: "${_('Name')}", className: "td-componentname" | |
62 | { data: {"_": "last_change", |
|
77 | }, | |
|
78 | { | |||
|
79 | data: 'menu', "bSortable": false, className: "quick_repo_menu"}, | |||
|
80 | { | |||
|
81 | data: { | |||
|
82 | "_": "desc", | |||
|
83 | "sort": "desc" | |||
|
84 | }, title: "${_('Description')}", className: "td-description" | |||
|
85 | }, | |||
|
86 | { | |||
|
87 | data: { | |||
|
88 | "_": "last_change", | |||
63 | "sort": "last_change_raw", |
|
89 | "sort": "last_change_raw", | |
64 | "type": Number}, title: "${_('Last Change')}", className: "td-time" }, |
|
90 | "type": Number | |
65 | { data: {"_": "last_changeset", |
|
91 | }, title: "${_('Last Change')}", className: "td-time" | |
|
92 | }, | |||
|
93 | { | |||
|
94 | data: { | |||
|
95 | "_": "last_changeset", | |||
66 | "sort": "last_changeset_raw", |
|
96 | "sort": "last_changeset_raw", | |
67 | "type": Number}, title: "${_('Commit')}", className: "td-commit" }, |
|
97 | "type": Number | |
68 | { data: {"_": "owner", |
|
98 | }, title: "${_('Commit')}", className: "td-commit", orderable: false | |
69 | "sort": "owner"}, title: "${_('Owner')}", className: "td-user" }, |
|
99 | }, | |
70 | { data: {"_": "state", |
|
100 | { | |
71 | "sort": "state"}, title: "${_('State')}", className: "td-tags td-state" }, |
|
101 | data: { | |
72 |
|
|
102 | "_": "owner", | |
73 | "sort": "action"}, title: "${_('Action')}", className: "td-action", orderable: false } |
|
103 | "sort": "owner" | |
|
104 | }, title: "${_('Owner')}", className: "td-user" | |||
|
105 | }, | |||
|
106 | { | |||
|
107 | data: { | |||
|
108 | "_": "state", | |||
|
109 | "sort": "state" | |||
|
110 | }, title: "${_('State')}", className: "td-tags td-state" | |||
|
111 | }, | |||
|
112 | { | |||
|
113 | data: { | |||
|
114 | "_": "action", | |||
|
115 | "sort": "action" | |||
|
116 | }, title: "${_('Action')}", className: "td-action", orderable: false | |||
|
117 | } | |||
74 | ], |
|
118 | ], | |
75 | language: { |
|
119 | language: { | |
76 | paginate: DEFAULT_GRID_PAGINATION, |
|
120 | paginate: DEFAULT_GRID_PAGINATION, | |
77 | emptyTable:_gettext("No repositories available yet.") |
|
121 | sProcessing: _gettext('loading...'), | |
|
122 | emptyTable:_gettext("No repositories present.") | |||
78 | }, |
|
123 | }, | |
79 | "initComplete": function( settings, json ) { |
|
124 | "initComplete": function( settings, json ) { | |
80 | get_datatable_count(); |
|
|||
81 | quick_repo_menu(); |
|
125 | quick_repo_menu(); | |
82 | } |
|
126 | } | |
83 | }); |
|
127 | }); | |
84 |
|
128 | |||
85 | // update the counter when doing search |
|
129 | $repoListTable.on('xhr.dt', function(e, settings, json, xhr){ | |
86 | $('#repo_list_table').on( 'search.dt', function (e,settings) { |
|
130 | $repoListTable.css('opacity', 1); | |
87 | get_datatable_count(); |
|
131 | }); | |
|
132 | ||||
|
133 | $repoListTable.on('preXhr.dt', function(e, settings, data){ | |||
|
134 | $repoListTable.css('opacity', 0.3); | |||
88 | }); |
|
135 | }); | |
89 |
|
136 | |||
90 | // filter, filter both grids |
|
137 | $('#q_filter').on('keyup', | |
91 | $('#q_filter').on( 'keyup', function () { |
|
138 | $.debounce(250, function() { | |
92 | var repo_api = $('#repo_list_table').dataTable().api(); |
|
139 | $repoListTable.DataTable().search( | |
93 | repo_api |
|
140 | $('#q_filter').val() | |
94 | .columns(0) |
|
141 | ).draw(); | |
95 | .search(this.value) |
|
142 | }) | |
96 | .draw(); |
|
143 | ); | |
97 | }); |
|
|||
98 |
|
144 | |||
99 | // refilter table if page load via back button |
|
|||
100 | $("#q_filter").trigger('keyup'); |
|
|||
101 | }); |
|
145 | }); | |
102 |
|
146 | |||
103 | </script> |
|
147 | </script> |
@@ -278,7 +278,7 b'' | |||||
278 | <td class="td-tags"> |
|
278 | <td class="td-tags"> | |
279 | %if hasattr(permissions[section], 'perm_origin_stack'): |
|
279 | %if hasattr(permissions[section], 'perm_origin_stack'): | |
280 | <div> |
|
280 | <div> | |
281 | %for i, (perm, origin) in enumerate(reversed(permissions[section].perm_origin_stack[k])): |
|
281 | %for i, (perm, origin, obj_id) in enumerate(reversed(permissions[section].perm_origin_stack[k])): | |
282 | <% _css_class = i > 0 and 'perm_overriden' or '' %> |
|
282 | <% _css_class = i > 0 and 'perm_overriden' or '' %> | |
283 | % if i > 0: |
|
283 | % if i > 0: | |
284 | <div style="color: #979797"> |
|
284 | <div style="color: #979797"> |
@@ -35,29 +35,29 b' from rhodecode.model.user_group import U' | |||||
35 |
|
35 | |||
36 | def test_perm_origin_dict(): |
|
36 | def test_perm_origin_dict(): | |
37 | pod = auth.PermOriginDict() |
|
37 | pod = auth.PermOriginDict() | |
38 | pod['thing'] = 'read', 'default' |
|
38 | pod['thing'] = 'read', 'default', 1 | |
39 | assert pod['thing'] == 'read' |
|
39 | assert pod['thing'] == 'read' | |
40 |
|
40 | |||
41 | assert pod.perm_origin_stack == { |
|
41 | assert pod.perm_origin_stack == { | |
42 | 'thing': [('read', 'default')]} |
|
42 | 'thing': [('read', 'default', 1)]} | |
43 |
|
43 | |||
44 | pod['thing'] = 'write', 'admin' |
|
44 | pod['thing'] = 'write', 'admin', 1 | |
45 | assert pod['thing'] == 'write' |
|
45 | assert pod['thing'] == 'write' | |
46 |
|
46 | |||
47 | assert pod.perm_origin_stack == { |
|
47 | assert pod.perm_origin_stack == { | |
48 | 'thing': [('read', 'default'), ('write', 'admin')]} |
|
48 | 'thing': [('read', 'default', 1), ('write', 'admin', 1)]} | |
49 |
|
49 | |||
50 | pod['other'] = 'write', 'default' |
|
50 | pod['other'] = 'write', 'default', 8 | |
51 |
|
51 | |||
52 | assert pod.perm_origin_stack == { |
|
52 | assert pod.perm_origin_stack == { | |
53 | 'other': [('write', 'default')], |
|
53 | 'other': [('write', 'default', 8)], | |
54 | 'thing': [('read', 'default'), ('write', 'admin')]} |
|
54 | 'thing': [('read', 'default', 1), ('write', 'admin', 1)]} | |
55 |
|
55 | |||
56 | pod['other'] = 'none', 'override' |
|
56 | pod['other'] = 'none', 'override', 8 | |
57 |
|
57 | |||
58 | assert pod.perm_origin_stack == { |
|
58 | assert pod.perm_origin_stack == { | |
59 | 'other': [('write', 'default'), ('none', 'override')], |
|
59 | 'other': [('write', 'default', 8), ('none', 'override', 8)], | |
60 | 'thing': [('read', 'default'), ('write', 'admin')]} |
|
60 | 'thing': [('read', 'default', 1), ('write', 'admin', 1)]} | |
61 |
|
61 | |||
62 | with pytest.raises(ValueError): |
|
62 | with pytest.raises(ValueError): | |
63 | pod['thing'] = 'read' |
|
63 | pod['thing'] = 'read' |
General Comments 0
You need to be logged in to leave comments.
Login now