Show More
@@ -0,0 +1,128 b'' | |||||
|
1 | # -*- coding: utf-8 -*- | |||
|
2 | ||||
|
3 | # Copyright (C) 2016-2017 RhodeCode GmbH | |||
|
4 | # | |||
|
5 | # This program is free software: you can redistribute it and/or modify | |||
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |||
|
7 | # (only), as published by the Free Software Foundation. | |||
|
8 | # | |||
|
9 | # This program is distributed in the hope that it will be useful, | |||
|
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
|
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
|
12 | # GNU General Public License for more details. | |||
|
13 | # | |||
|
14 | # You should have received a copy of the GNU Affero General Public License | |||
|
15 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
|
16 | # | |||
|
17 | # This program is dual-licensed. If you wish to learn more about the | |||
|
18 | # RhodeCode Enterprise Edition, including its added features, Support services, | |||
|
19 | # and proprietary license terms, please see https://rhodecode.com/licenses/ | |||
|
20 | ||||
|
21 | import pytest | |||
|
22 | ||||
|
23 | from rhodecode.tests import ( | |||
|
24 | TestController, url, assert_session_flash, link_to) | |||
|
25 | from rhodecode.model.db import User, UserGroup | |||
|
26 | from rhodecode.model.meta import Session | |||
|
27 | from rhodecode.tests.fixture import Fixture | |||
|
28 | ||||
|
29 | ||||
|
30 | fixture = Fixture() | |||
|
31 | ||||
|
32 | ||||
|
33 | class TestAdminUsersGroupsController(TestController): | |||
|
34 | ||||
|
35 | def test_regular_user_cannot_see_admin_interfaces(self, user_util): | |||
|
36 | user = user_util.create_user(password='qweqwe') | |||
|
37 | self.log_user(user.username, 'qweqwe') | |||
|
38 | ||||
|
39 | # check if in home view, such user doesn't see the "admin" menus | |||
|
40 | response = self.app.get(url('home')) | |||
|
41 | ||||
|
42 | assert_response = response.assert_response() | |||
|
43 | ||||
|
44 | assert_response.no_element_exists('li.local-admin-repos') | |||
|
45 | assert_response.no_element_exists('li.local-admin-repo-groups') | |||
|
46 | assert_response.no_element_exists('li.local-admin-user-groups') | |||
|
47 | ||||
|
48 | response = self.app.get(url('repos'), status=200) | |||
|
49 | response.mustcontain('data: []') | |||
|
50 | ||||
|
51 | response = self.app.get(url('repo_groups'), status=200) | |||
|
52 | response.mustcontain('data: []') | |||
|
53 | ||||
|
54 | response = self.app.get(url('users_groups'), status=200) | |||
|
55 | response.mustcontain('data: []') | |||
|
56 | ||||
|
57 | def test_regular_user_can_see_admin_interfaces_if_owner(self, user_util): | |||
|
58 | user = user_util.create_user(password='qweqwe') | |||
|
59 | username = user.username | |||
|
60 | ||||
|
61 | repo = user_util.create_repo(owner=username) | |||
|
62 | repo_name = repo.repo_name | |||
|
63 | ||||
|
64 | repo_group = user_util.create_repo_group(owner=username) | |||
|
65 | repo_group_name = repo_group.group_name | |||
|
66 | ||||
|
67 | user_group = user_util.create_user_group(owner=username) | |||
|
68 | user_group_name = user_group.users_group_name | |||
|
69 | ||||
|
70 | self.log_user(username, 'qweqwe') | |||
|
71 | # check if in home view, such user doesn't see the "admin" menus | |||
|
72 | response = self.app.get(url('home')) | |||
|
73 | ||||
|
74 | assert_response = response.assert_response() | |||
|
75 | ||||
|
76 | assert_response.one_element_exists('li.local-admin-repos') | |||
|
77 | assert_response.one_element_exists('li.local-admin-repo-groups') | |||
|
78 | assert_response.one_element_exists('li.local-admin-user-groups') | |||
|
79 | ||||
|
80 | # admin interfaces have visible elements | |||
|
81 | response = self.app.get(url('repos'), status=200) | |||
|
82 | response.mustcontain('"name_raw": "{}"'.format(repo_name)) | |||
|
83 | ||||
|
84 | response = self.app.get(url('repo_groups'), status=200) | |||
|
85 | response.mustcontain('"name_raw": "{}"'.format(repo_group_name)) | |||
|
86 | ||||
|
87 | response = self.app.get(url('users_groups'), status=200) | |||
|
88 | response.mustcontain('"group_name_raw": "{}"'.format(user_group_name)) | |||
|
89 | ||||
|
90 | def test_regular_user_can_see_admin_interfaces_if_admin_perm(self, user_util): | |||
|
91 | user = user_util.create_user(password='qweqwe') | |||
|
92 | username = user.username | |||
|
93 | ||||
|
94 | repo = user_util.create_repo() | |||
|
95 | repo_name = repo.repo_name | |||
|
96 | ||||
|
97 | repo_group = user_util.create_repo_group() | |||
|
98 | repo_group_name = repo_group.group_name | |||
|
99 | ||||
|
100 | user_group = user_util.create_user_group() | |||
|
101 | user_group_name = user_group.users_group_name | |||
|
102 | ||||
|
103 | user_util.grant_user_permission_to_repo( | |||
|
104 | repo, user, 'repository.admin') | |||
|
105 | user_util.grant_user_permission_to_repo_group( | |||
|
106 | repo_group, user, 'group.admin') | |||
|
107 | user_util.grant_user_permission_to_user_group( | |||
|
108 | user_group, user, 'usergroup.admin') | |||
|
109 | ||||
|
110 | self.log_user(username, 'qweqwe') | |||
|
111 | # check if in home view, such user doesn't see the "admin" menus | |||
|
112 | response = self.app.get(url('home')) | |||
|
113 | ||||
|
114 | assert_response = response.assert_response() | |||
|
115 | ||||
|
116 | assert_response.one_element_exists('li.local-admin-repos') | |||
|
117 | assert_response.one_element_exists('li.local-admin-repo-groups') | |||
|
118 | assert_response.one_element_exists('li.local-admin-user-groups') | |||
|
119 | ||||
|
120 | # admin interfaces have visible elements | |||
|
121 | response = self.app.get(url('repos'), status=200) | |||
|
122 | response.mustcontain('"name_raw": "{}"'.format(repo_name)) | |||
|
123 | ||||
|
124 | response = self.app.get(url('repo_groups'), status=200) | |||
|
125 | response.mustcontain('"name_raw": "{}"'.format(repo_group_name)) | |||
|
126 | ||||
|
127 | response = self.app.get(url('users_groups'), status=200) | |||
|
128 | response.mustcontain('"group_name_raw": "{}"'.format(user_group_name)) |
@@ -571,8 +571,14 b' class PermissionCalculator(object):' | |||||
571 | # on given user group |
|
571 | # on given user group | |
572 | for perm in self.default_user_group_perms: |
|
572 | for perm in self.default_user_group_perms: | |
573 | u_k = perm.UserUserGroupToPerm.user_group.users_group_name |
|
573 | u_k = perm.UserUserGroupToPerm.user_group.users_group_name | |
|
574 | o = PermOrigin.USERGROUP_DEFAULT | |||
|
575 | if perm.UserGroup.user_id == self.user_id: | |||
|
576 | # set admin if owner | |||
|
577 | p = 'usergroup.admin' | |||
|
578 | o = PermOrigin.USERGROUP_OWNER | |||
|
579 | else: | |||
574 | p = perm.Permission.permission_name |
|
580 | p = perm.Permission.permission_name | |
575 | o = PermOrigin.USERGROUP_DEFAULT |
|
581 | ||
576 | # if we decide this user isn't inheriting permissions from default |
|
582 | # if we decide this user isn't inheriting permissions from default | |
577 | # user we set him to .none so only explicit permissions work |
|
583 | # user we set him to .none so only explicit permissions work | |
578 | if not user_inherit_object_permissions: |
|
584 | if not user_inherit_object_permissions: | |
@@ -651,7 +657,7 b' class PermissionCalculator(object):' | |||||
651 | multiple_counter[g_k] += 1 |
|
657 | multiple_counter[g_k] += 1 | |
652 | p = perm.Permission.permission_name |
|
658 | p = perm.Permission.permission_name | |
653 | if perm.RepoGroup.user_id == self.user_id: |
|
659 | if perm.RepoGroup.user_id == self.user_id: | |
654 | # set admin if owner |
|
660 | # set admin if owner, even for member of other user group | |
655 | p = 'group.admin' |
|
661 | p = 'group.admin' | |
656 | o = PermOrigin.REPOGROUP_OWNER |
|
662 | o = PermOrigin.REPOGROUP_OWNER | |
657 | else: |
|
663 | else: | |
@@ -687,7 +693,7 b' class PermissionCalculator(object):' | |||||
687 | # user group for user group permissions |
|
693 | # user group for user group permissions | |
688 | user_group_from_user_group = Permission\ |
|
694 | user_group_from_user_group = Permission\ | |
689 | .get_default_user_group_perms_from_user_group( |
|
695 | .get_default_user_group_perms_from_user_group( | |
690 |
self.user_id, self.scope_ |
|
696 | self.user_id, self.scope_user_group_id) | |
691 |
|
697 | |||
692 | multiple_counter = collections.defaultdict(int) |
|
698 | multiple_counter = collections.defaultdict(int) | |
693 | for perm in user_group_from_user_group: |
|
699 | for perm in user_group_from_user_group: | |
@@ -698,6 +704,12 b' class PermissionCalculator(object):' | |||||
698 | o = PermOrigin.USERGROUP_USERGROUP % u_k |
|
704 | o = PermOrigin.USERGROUP_USERGROUP % u_k | |
699 | multiple_counter[g_k] += 1 |
|
705 | multiple_counter[g_k] += 1 | |
700 | p = perm.Permission.permission_name |
|
706 | p = perm.Permission.permission_name | |
|
707 | ||||
|
708 | if perm.UserGroup.user_id == self.user_id: | |||
|
709 | # set admin if owner, even for member of other user group | |||
|
710 | p = 'usergroup.admin' | |||
|
711 | o = PermOrigin.USERGROUP_OWNER | |||
|
712 | else: | |||
701 | if multiple_counter[g_k] > 1: |
|
713 | if multiple_counter[g_k] > 1: | |
702 | cur_perm = self.permissions_user_groups[g_k] |
|
714 | cur_perm = self.permissions_user_groups[g_k] | |
703 | p = self._choose_permission(p, cur_perm) |
|
715 | p = self._choose_permission(p, cur_perm) | |
@@ -709,8 +721,14 b' class PermissionCalculator(object):' | |||||
709 | for perm in user_user_groups_perms: |
|
721 | for perm in user_user_groups_perms: | |
710 | ug_k = perm.UserUserGroupToPerm.user_group.users_group_name |
|
722 | ug_k = perm.UserUserGroupToPerm.user_group.users_group_name | |
711 | u_k = perm.UserUserGroupToPerm.user.username |
|
723 | u_k = perm.UserUserGroupToPerm.user.username | |
|
724 | o = PermOrigin.USERGROUP_USER % u_k | |||
|
725 | ||||
|
726 | if perm.UserGroup.user_id == self.user_id: | |||
|
727 | # set admin if owner | |||
|
728 | p = 'usergroup.admin' | |||
|
729 | o = PermOrigin.USERGROUP_OWNER | |||
|
730 | else: | |||
712 | p = perm.Permission.permission_name |
|
731 | p = perm.Permission.permission_name | |
713 | o = PermOrigin.USERGROUP_USER % u_k |
|
|||
714 | if not self.explicit: |
|
732 | if not self.explicit: | |
715 | cur_perm = self.permissions_user_groups.get( |
|
733 | cur_perm = self.permissions_user_groups.get( | |
716 | ug_k, 'usergroup.none') |
|
734 | ug_k, 'usergroup.none') | |
@@ -942,7 +960,8 b' class AuthUser(object):' | |||||
942 | """ |
|
960 | """ | |
943 | Returns list of repositories you're an admin of |
|
961 | Returns list of repositories you're an admin of | |
944 | """ |
|
962 | """ | |
945 | return [x[0] for x in self.permissions['repositories'].iteritems() |
|
963 | return [ | |
|
964 | x[0] for x in self.permissions['repositories'].iteritems() | |||
946 |
|
|
965 | if x[1] == 'repository.admin'] | |
947 |
|
966 | |||
948 | @property |
|
967 | @property | |
@@ -950,8 +969,8 b' class AuthUser(object):' | |||||
950 | """ |
|
969 | """ | |
951 | Returns list of repository groups you're an admin of |
|
970 | Returns list of repository groups you're an admin of | |
952 | """ |
|
971 | """ | |
953 |
return [ |
|
972 | return [ | |
954 |
|
|
973 | x[0] for x in self.permissions['repositories_groups'].iteritems() | |
955 |
|
|
974 | if x[1] == 'group.admin'] | |
956 |
|
975 | |||
957 | @property |
|
976 | @property | |
@@ -959,7 +978,8 b' class AuthUser(object):' | |||||
959 | """ |
|
978 | """ | |
960 | Returns list of user groups you're an admin of |
|
979 | Returns list of user groups you're an admin of | |
961 | """ |
|
980 | """ | |
962 | return [x[0] for x in self.permissions['user_groups'].iteritems() |
|
981 | return [ | |
|
982 | x[0] for x in self.permissions['user_groups'].iteritems() | |||
963 |
|
|
983 | if x[1] == 'usergroup.admin'] | |
964 |
|
984 | |||
965 | @property |
|
985 | @property |
@@ -142,13 +142,13 b'' | |||||
142 | <%def name="admin_menu_simple(repositories=None, repository_groups=None, user_groups=None)"> |
|
142 | <%def name="admin_menu_simple(repositories=None, repository_groups=None, user_groups=None)"> | |
143 | <ul class="submenu"> |
|
143 | <ul class="submenu"> | |
144 | %if repositories: |
|
144 | %if repositories: | |
145 | <li><a href="${h.url('repos')}">${_('Repositories')}</a></li> |
|
145 | <li class="local-admin-repos"><a href="${h.url('repos')}">${_('Repositories')}</a></li> | |
146 | %endif |
|
146 | %endif | |
147 | %if repository_groups: |
|
147 | %if repository_groups: | |
148 | <li><a href="${h.url('repo_groups')}">${_('Repository groups')}</a></li> |
|
148 | <li class="local-admin-repo-groups"><a href="${h.url('repo_groups')}">${_('Repository groups')}</a></li> | |
149 | %endif |
|
149 | %endif | |
150 | %if user_groups: |
|
150 | %if user_groups: | |
151 | <li><a href="${h.url('users_groups')}">${_('User groups')}</a></li> |
|
151 | <li class="local-admin-user-groups"><a href="${h.url('users_groups')}">${_('User groups')}</a></li> | |
152 | %endif |
|
152 | %endif | |
153 | </ul> |
|
153 | </ul> | |
154 | </%def> |
|
154 | </%def> |
@@ -137,8 +137,7 b' class _BaseTest(TestController):' | |||||
137 | assert new_repo_group.group_name == repo_group_name_unicode |
|
137 | assert new_repo_group.group_name == repo_group_name_unicode | |
138 | assert new_repo_group.group_description == description |
|
138 | assert new_repo_group.group_description == description | |
139 |
|
139 | |||
140 | # |
|
140 | # test if the repository is visible in the list ? | |
141 | # # test if the repository is visible in the list ? |
|
|||
142 | response = self.app.get( |
|
141 | response = self.app.get( | |
143 | url('repo_group_home', group_name=repo_group_name)) |
|
142 | url('repo_group_home', group_name=repo_group_name)) | |
144 | response.mustcontain(repo_group_name) |
|
143 | response.mustcontain(repo_group_name) |
@@ -130,14 +130,36 b' class TestPermissions(object):' | |||||
130 | assert group_perms(self.a1) == { |
|
130 | assert group_perms(self.a1) == { | |
131 | 'test1': 'group.admin', 'test2': 'group.admin'} |
|
131 | 'test1': 'group.admin', 'test2': 'group.admin'} | |
132 |
|
132 | |||
133 |
def test_default_owner_ |
|
133 | def test_default_owner_repo_perms(self, backend, user_util, test_repo): | |
134 | # "u1" shall be owner without any special permission assigned |
|
134 | user = user_util.create_user() | |
135 | self.g1 = fixture.create_repo_group('test1') |
|
135 | repo = test_repo('minimal', backend.alias) | |
136 | assert group_perms(self.u1) == {'test1': 'group.read'} |
|
136 | org_owner = repo.user | |
|
137 | assert repo_perms(user)[repo.repo_name] == 'repository.read' | |||
|
138 | ||||
|
139 | repo.user = user | |||
|
140 | assert repo_perms(user)[repo.repo_name] == 'repository.admin' | |||
|
141 | repo.user = org_owner | |||
|
142 | ||||
|
143 | def test_default_owner_repo_group_perms(self, user_util, test_repo_group): | |||
|
144 | user = user_util.create_user() | |||
|
145 | org_owner = test_repo_group.user | |||
137 |
|
146 | |||
138 | # Make him owner, but do not add any special permissions |
|
147 | assert group_perms(user)[test_repo_group.group_name] == 'group.read' | |
139 | self.g1.user = self.u1 |
|
148 | ||
140 | assert group_perms(self.u1) == {'test1': 'group.admin'} |
|
149 | test_repo_group.user = user | |
|
150 | assert group_perms(user)[test_repo_group.group_name] == 'group.admin' | |||
|
151 | test_repo_group.user = org_owner | |||
|
152 | ||||
|
153 | def test_default_owner_user_group_perms(self, user_util, test_user_group): | |||
|
154 | user = user_util.create_user() | |||
|
155 | org_owner = test_user_group.user | |||
|
156 | ||||
|
157 | assert user_group_perms(user)[test_user_group.users_group_name] == 'usergroup.read' | |||
|
158 | ||||
|
159 | test_user_group.user = user | |||
|
160 | assert user_group_perms(user)[test_user_group.users_group_name] == 'usergroup.admin' | |||
|
161 | ||||
|
162 | test_user_group.user = org_owner | |||
141 |
|
163 | |||
142 | def test_propagated_permission_from_users_group_by_explicit_perms_exist( |
|
164 | def test_propagated_permission_from_users_group_by_explicit_perms_exist( | |
143 | self, repo_name): |
|
165 | self, repo_name): |
General Comments 0
You need to be logged in to leave comments.
Login now