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