pilot-platform-common 2.2.0__tar.gz → 2.4.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pilot_platform_common-2.2.0 → pilot_platform_common-2.4.0}/PKG-INFO +1 -1
- {pilot_platform_common-2.2.0 → pilot_platform_common-2.4.0}/common/permissions/permissions.py +55 -6
- {pilot_platform_common-2.2.0 → pilot_platform_common-2.4.0}/common/project/project_client.py +6 -0
- {pilot_platform_common-2.2.0 → pilot_platform_common-2.4.0}/pilot_platform_common.egg-info/PKG-INFO +1 -1
- {pilot_platform_common-2.2.0 → pilot_platform_common-2.4.0}/pyproject.toml +1 -1
- {pilot_platform_common-2.2.0 → pilot_platform_common-2.4.0}/setup.py +1 -1
- {pilot_platform_common-2.2.0 → pilot_platform_common-2.4.0}/tests/conftest.py +8 -0
- {pilot_platform_common-2.2.0 → pilot_platform_common-2.4.0}/tests/permissions/test_permissions.py +187 -105
- {pilot_platform_common-2.2.0 → pilot_platform_common-2.4.0}/tests/test_project_client.py +3 -0
- {pilot_platform_common-2.2.0 → pilot_platform_common-2.4.0}/README.md +0 -0
- {pilot_platform_common-2.2.0 → pilot_platform_common-2.4.0}/common/__init__.py +0 -0
- {pilot_platform_common-2.2.0 → pilot_platform_common-2.4.0}/common/geid/__init__.py +0 -0
- {pilot_platform_common-2.2.0 → pilot_platform_common-2.4.0}/common/geid/geid_client.py +0 -0
- {pilot_platform_common-2.2.0 → pilot_platform_common-2.4.0}/common/jwt_handler/JWTHandler.py +0 -0
- {pilot_platform_common-2.2.0 → pilot_platform_common-2.4.0}/common/jwt_handler/__init__.py +0 -0
- {pilot_platform_common-2.2.0 → pilot_platform_common-2.4.0}/common/jwt_handler/jwt_handler_exception.py +0 -0
- {pilot_platform_common-2.2.0 → pilot_platform_common-2.4.0}/common/jwt_handler/models.py +0 -0
- {pilot_platform_common-2.2.0 → pilot_platform_common-2.4.0}/common/logging/__init__.py +0 -0
- {pilot_platform_common-2.2.0 → pilot_platform_common-2.4.0}/common/logging/formatter.py +0 -0
- {pilot_platform_common-2.2.0 → pilot_platform_common-2.4.0}/common/logging/logger.py +0 -0
- {pilot_platform_common-2.2.0 → pilot_platform_common-2.4.0}/common/logging/logging.py +0 -0
- {pilot_platform_common-2.2.0 → pilot_platform_common-2.4.0}/common/models/__init__.py +0 -0
- {pilot_platform_common-2.2.0 → pilot_platform_common-2.4.0}/common/models/config_center_policy.py +0 -0
- {pilot_platform_common-2.2.0 → pilot_platform_common-2.4.0}/common/models/service_id_generator.py +0 -0
- {pilot_platform_common-2.2.0 → pilot_platform_common-2.4.0}/common/object_storage_adaptor/__init__.py +0 -0
- {pilot_platform_common-2.2.0 → pilot_platform_common-2.4.0}/common/object_storage_adaptor/base_client.py +0 -0
- {pilot_platform_common-2.2.0 → pilot_platform_common-2.4.0}/common/object_storage_adaptor/boto3_admin_client.py +0 -0
- {pilot_platform_common-2.2.0 → pilot_platform_common-2.4.0}/common/object_storage_adaptor/boto3_client.py +0 -0
- {pilot_platform_common-2.2.0 → pilot_platform_common-2.4.0}/common/object_storage_adaptor/minio_policy_client.py +0 -0
- {pilot_platform_common-2.2.0 → pilot_platform_common-2.4.0}/common/permissions/__init__.py +0 -0
- {pilot_platform_common-2.2.0 → pilot_platform_common-2.4.0}/common/permissions/exceptions.py +0 -0
- {pilot_platform_common-2.2.0 → pilot_platform_common-2.4.0}/common/permissions/permissions_manager.py +0 -0
- {pilot_platform_common-2.2.0 → pilot_platform_common-2.4.0}/common/permissions/schemas.py +0 -0
- {pilot_platform_common-2.2.0 → pilot_platform_common-2.4.0}/common/project/__init__.py +0 -0
- {pilot_platform_common-2.2.0 → pilot_platform_common-2.4.0}/common/project/project_exceptions.py +0 -0
- {pilot_platform_common-2.2.0 → pilot_platform_common-2.4.0}/common/services/__init__.py +0 -0
- {pilot_platform_common-2.2.0 → pilot_platform_common-2.4.0}/common/services/auth_client.py +0 -0
- {pilot_platform_common-2.2.0 → pilot_platform_common-2.4.0}/common/vault/__init__.py +0 -0
- {pilot_platform_common-2.2.0 → pilot_platform_common-2.4.0}/common/vault/vault_client.py +0 -0
- {pilot_platform_common-2.2.0 → pilot_platform_common-2.4.0}/common/vault/vault_exception.py +0 -0
- {pilot_platform_common-2.2.0 → pilot_platform_common-2.4.0}/pilot_platform_common.egg-info/SOURCES.txt +0 -0
- {pilot_platform_common-2.2.0 → pilot_platform_common-2.4.0}/pilot_platform_common.egg-info/dependency_links.txt +0 -0
- {pilot_platform_common-2.2.0 → pilot_platform_common-2.4.0}/pilot_platform_common.egg-info/requires.txt +0 -0
- {pilot_platform_common-2.2.0 → pilot_platform_common-2.4.0}/pilot_platform_common.egg-info/top_level.txt +0 -0
- {pilot_platform_common-2.2.0 → pilot_platform_common-2.4.0}/setup.cfg +0 -0
- {pilot_platform_common-2.2.0 → pilot_platform_common-2.4.0}/tests/__init__.py +0 -0
- {pilot_platform_common-2.2.0 → pilot_platform_common-2.4.0}/tests/fixtures/__init__.py +0 -0
- {pilot_platform_common-2.2.0 → pilot_platform_common-2.4.0}/tests/fixtures/fake.py +0 -0
- {pilot_platform_common-2.2.0 → pilot_platform_common-2.4.0}/tests/fixtures/metadata.py +0 -0
- {pilot_platform_common-2.2.0 → pilot_platform_common-2.4.0}/tests/permissions/__init__.py +0 -0
- {pilot_platform_common-2.2.0 → pilot_platform_common-2.4.0}/tests/permissions/test_auth_client.py +0 -0
- {pilot_platform_common-2.2.0 → pilot_platform_common-2.4.0}/tests/permissions/test_permissions_manager.py +0 -0
- {pilot_platform_common-2.2.0 → pilot_platform_common-2.4.0}/tests/test_formatter.py +0 -0
- {pilot_platform_common-2.2.0 → pilot_platform_common-2.4.0}/tests/test_geid_client.py +0 -0
- {pilot_platform_common-2.2.0 → pilot_platform_common-2.4.0}/tests/test_jwt_handler.py +0 -0
- {pilot_platform_common-2.2.0 → pilot_platform_common-2.4.0}/tests/test_logging.py +0 -0
- {pilot_platform_common-2.2.0 → pilot_platform_common-2.4.0}/tests/test_vault_client.py +0 -0
{pilot_platform_common-2.2.0 → pilot_platform_common-2.4.0}/common/permissions/permissions.py
RENAMED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
#
|
|
3
3
|
# Contact Indoc Systems for any questions regarding the use of this source code.
|
|
4
4
|
|
|
5
|
+
import os
|
|
5
6
|
from typing import Any
|
|
6
7
|
from typing import Optional
|
|
7
8
|
|
|
@@ -10,11 +11,19 @@ from httpx import AsyncClient
|
|
|
10
11
|
from common.logging import logger
|
|
11
12
|
from common.permissions.exceptions import ProjectRoleNotFound
|
|
12
13
|
from common.permissions.permissions_manager import PermissionsManager
|
|
14
|
+
from common.project.project_client import ProjectClient
|
|
13
15
|
from common.services.auth_client import AuthClient
|
|
14
16
|
|
|
15
17
|
|
|
16
18
|
async def has_permission(
|
|
17
|
-
auth_url: str,
|
|
19
|
+
auth_url: str,
|
|
20
|
+
project_url: str,
|
|
21
|
+
redis_url: str,
|
|
22
|
+
project_code: str,
|
|
23
|
+
resource: str,
|
|
24
|
+
zone: str,
|
|
25
|
+
operation: str,
|
|
26
|
+
current_identity: dict[str, Any],
|
|
18
27
|
) -> bool:
|
|
19
28
|
if current_identity['role'] == 'admin':
|
|
20
29
|
role = 'platform_admin'
|
|
@@ -27,6 +36,13 @@ async def has_permission(
|
|
|
27
36
|
logger.info('Unable to get project role in permissions check, user might not belong to project')
|
|
28
37
|
return False
|
|
29
38
|
|
|
39
|
+
enable_state_check = os.environ.get('ENABLE_PROJECT_STATE_CHECK', 'true') == 'true'
|
|
40
|
+
if enable_state_check:
|
|
41
|
+
project_client = ProjectClient(project_url, redis_url)
|
|
42
|
+
project = await project_client.get(project_code)
|
|
43
|
+
if project.state == 'trashed':
|
|
44
|
+
return False
|
|
45
|
+
|
|
30
46
|
try:
|
|
31
47
|
payload = {
|
|
32
48
|
'role': role,
|
|
@@ -82,7 +98,13 @@ async def get_project_folder_entity(metadata_url: str, name: str, _type: str, zo
|
|
|
82
98
|
|
|
83
99
|
|
|
84
100
|
async def has_file_permission(
|
|
85
|
-
auth_url: str,
|
|
101
|
+
auth_url: str,
|
|
102
|
+
metadata_url: str,
|
|
103
|
+
project_url: str,
|
|
104
|
+
redis_url: str,
|
|
105
|
+
file_entity: dict,
|
|
106
|
+
operation: str,
|
|
107
|
+
current_identity: dict,
|
|
86
108
|
) -> bool:
|
|
87
109
|
if file_entity['container_type'] != 'project':
|
|
88
110
|
logger.info('Unsupport container type, permission denied')
|
|
@@ -111,18 +133,34 @@ async def has_file_permission(
|
|
|
111
133
|
project_folder_id = project_folder['id']
|
|
112
134
|
|
|
113
135
|
if not await has_permission(
|
|
114
|
-
auth_url,
|
|
136
|
+
auth_url,
|
|
137
|
+
project_url,
|
|
138
|
+
redis_url,
|
|
139
|
+
project_code,
|
|
140
|
+
f'file_shared_{project_folder_id}',
|
|
141
|
+
zone,
|
|
142
|
+
operation,
|
|
143
|
+
current_identity,
|
|
115
144
|
):
|
|
116
145
|
return False
|
|
117
146
|
elif root_folder == 'users':
|
|
118
147
|
name_folder_name = get_name_or_path(file_entity, folder_path_split)
|
|
119
148
|
# If the user has file_any permission return True, if the file is in the users namefolder and the
|
|
120
149
|
# user has file own permissions return True else False
|
|
121
|
-
if not await has_permission(
|
|
150
|
+
if not await has_permission(
|
|
151
|
+
auth_url, project_url, redis_url, project_code, 'file_any', zone, operation, current_identity
|
|
152
|
+
):
|
|
122
153
|
if name_folder_name != username:
|
|
123
154
|
return False
|
|
124
155
|
if not await has_permission(
|
|
125
|
-
auth_url,
|
|
156
|
+
auth_url,
|
|
157
|
+
project_url,
|
|
158
|
+
redis_url,
|
|
159
|
+
project_code,
|
|
160
|
+
'file_in_own_namefolder',
|
|
161
|
+
zone,
|
|
162
|
+
operation,
|
|
163
|
+
current_identity,
|
|
126
164
|
):
|
|
127
165
|
return False
|
|
128
166
|
else:
|
|
@@ -154,9 +192,20 @@ def get_name_or_path(file_entity: dict[str, str], folder_path_split: list[str])
|
|
|
154
192
|
|
|
155
193
|
|
|
156
194
|
async def has_permissions(
|
|
157
|
-
auth_url: str,
|
|
195
|
+
auth_url: str,
|
|
196
|
+
project_url: str,
|
|
197
|
+
redis_url: str,
|
|
198
|
+
project_code: str,
|
|
199
|
+
permissions: list[dict[str, str]],
|
|
200
|
+
current_identity: dict[str, Any],
|
|
158
201
|
) -> dict[str, bool]:
|
|
159
202
|
"""Performs bulk permission assertions for a project."""
|
|
203
|
+
enable_state_check = os.environ.get('ENABLE_PROJECT_STATE_CHECK', 'true') == 'true'
|
|
204
|
+
if enable_state_check:
|
|
205
|
+
project_client = ProjectClient(project_url, redis_url)
|
|
206
|
+
project = await project_client.get(project_code)
|
|
207
|
+
if project.state == 'trashed':
|
|
208
|
+
return False
|
|
160
209
|
|
|
161
210
|
permission_manager = PermissionsManager(project_code)
|
|
162
211
|
role = permission_manager.retrieve_project_role(current_identity)
|
{pilot_platform_common-2.2.0 → pilot_platform_common-2.4.0}/common/project/project_client.py
RENAMED
|
@@ -33,6 +33,7 @@ class ProjectObject:
|
|
|
33
33
|
'updated_at',
|
|
34
34
|
'is_favourite',
|
|
35
35
|
'state',
|
|
36
|
+
'created_by',
|
|
36
37
|
]
|
|
37
38
|
|
|
38
39
|
def __init__(self, data, project_client):
|
|
@@ -198,6 +199,7 @@ class ProjectClient:
|
|
|
198
199
|
name: str,
|
|
199
200
|
description: str,
|
|
200
201
|
operator: str,
|
|
202
|
+
created_by: str,
|
|
201
203
|
image_url: Union[str, None] = None,
|
|
202
204
|
tags: Union[list[str], None] = None,
|
|
203
205
|
system_tags: Union[list[str], None] = None,
|
|
@@ -216,6 +218,7 @@ class ProjectClient:
|
|
|
216
218
|
'tags': tags,
|
|
217
219
|
'system_tags': system_tags,
|
|
218
220
|
'is_discoverable': is_discoverable,
|
|
221
|
+
'created_by': created_by,
|
|
219
222
|
}
|
|
220
223
|
# remove blank items
|
|
221
224
|
data = {k: v for k, v in data.items() if v is not None}
|
|
@@ -226,6 +229,9 @@ class ProjectClient:
|
|
|
226
229
|
raise ProjectException(status_code=response.status_code, error_msg=response.json())
|
|
227
230
|
return self.project_object(response.json(), self)
|
|
228
231
|
|
|
232
|
+
async def clear_cache(self, code: str):
|
|
233
|
+
self.redis.delete(CACHE_PREFIX + code)
|
|
234
|
+
|
|
229
235
|
|
|
230
236
|
class ProjectObjectSync(ProjectObject):
|
|
231
237
|
def __init__(self, *args, **kwargs):
|
|
@@ -11,7 +11,7 @@ long_description = (this_directory / 'README.md').read_text()
|
|
|
11
11
|
|
|
12
12
|
setuptools.setup(
|
|
13
13
|
name='pilot-platform-common',
|
|
14
|
-
version='2.
|
|
14
|
+
version='2.4.0',
|
|
15
15
|
author='Indoc Systems',
|
|
16
16
|
author_email='etaylor@indocresearch.org',
|
|
17
17
|
description='Generates entity ID and connects with Vault (secret engine) to retrieve credentials',
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
# Contact Indoc Systems for any questions regarding the use of this source code.
|
|
4
4
|
|
|
5
5
|
import asyncio
|
|
6
|
+
import re
|
|
6
7
|
import time
|
|
7
8
|
from uuid import uuid4
|
|
8
9
|
|
|
@@ -28,6 +29,7 @@ PROJECT_DATA = {
|
|
|
28
29
|
'tags': ['tag1', 'tag2'],
|
|
29
30
|
'system_tags': ['system'],
|
|
30
31
|
'state': 'in_use',
|
|
32
|
+
'created_by': 'Test User',
|
|
31
33
|
}
|
|
32
34
|
|
|
33
35
|
PROJECT_CREDENTIALS = {
|
|
@@ -37,6 +39,12 @@ PROJECT_CREDENTIALS = {
|
|
|
37
39
|
}
|
|
38
40
|
|
|
39
41
|
|
|
42
|
+
@pytest.fixture
|
|
43
|
+
def project_mock(httpx_mock):
|
|
44
|
+
url = re.compile('^http://project/v1/projects/.*$')
|
|
45
|
+
httpx_mock.add_response(method='GET', json={'state': 'active'}, url=url)
|
|
46
|
+
|
|
47
|
+
|
|
40
48
|
@pytest_asyncio.fixture(scope='session')
|
|
41
49
|
def event_loop(request):
|
|
42
50
|
"""Create an instance of the default event loop for each test case."""
|
{pilot_platform_common-2.2.0 → pilot_platform_common-2.4.0}/tests/permissions/test_permissions.py
RENAMED
|
@@ -16,275 +16,325 @@ from common.permissions.exceptions import ProjectRoleNotFound
|
|
|
16
16
|
|
|
17
17
|
class TestPermissions:
|
|
18
18
|
@pytest.mark.asyncio
|
|
19
|
-
async def test_has_permission_true(self, httpx_mock):
|
|
19
|
+
async def test_has_permission_true(self, httpx_mock, redis, project_mock):
|
|
20
|
+
project_code = str(uuid4())
|
|
20
21
|
current_identity = {
|
|
21
22
|
'username': 'test',
|
|
22
23
|
'role': 'member',
|
|
23
|
-
'realm_roles': ['
|
|
24
|
+
'realm_roles': [f'{project_code}-admin'],
|
|
24
25
|
}
|
|
25
|
-
url = 'http://auth/authorize?role=admin&resource=project&zone=core&operation=view&project_code=
|
|
26
|
+
url = f'http://auth/authorize?role=admin&resource=project&zone=core&operation=view&project_code={project_code}'
|
|
26
27
|
httpx_mock.add_response(method='GET', json={'result': {'has_permission': True}}, url=url)
|
|
27
|
-
|
|
28
|
+
|
|
29
|
+
result = await has_permission(
|
|
30
|
+
'http://auth/', 'http://project', redis.url, project_code, 'project', 'core', 'view', current_identity
|
|
31
|
+
)
|
|
28
32
|
assert result is True
|
|
29
33
|
|
|
30
34
|
@pytest.mark.asyncio
|
|
31
|
-
async def test_has_permission_false(self, httpx_mock):
|
|
35
|
+
async def test_has_permission_false(self, httpx_mock, redis, project_mock):
|
|
36
|
+
project_code = str(uuid4())
|
|
32
37
|
current_identity = {
|
|
33
38
|
'username': 'test',
|
|
34
39
|
'role': 'member',
|
|
35
|
-
'realm_roles': ['
|
|
40
|
+
'realm_roles': [f'{project_code}-admin'],
|
|
36
41
|
}
|
|
37
|
-
url = 'http://auth/authorize?role=admin&resource=project&zone=core&operation=view&project_code=
|
|
42
|
+
url = f'http://auth/authorize?role=admin&resource=project&zone=core&operation=view&project_code={project_code}'
|
|
38
43
|
httpx_mock.add_response(method='GET', json={'result': {'has_permission': False}}, url=url)
|
|
39
|
-
result = await has_permission(
|
|
44
|
+
result = await has_permission(
|
|
45
|
+
'http://auth/', 'http://project', redis.url, project_code, 'project', 'core', 'view', current_identity
|
|
46
|
+
)
|
|
40
47
|
assert result is False
|
|
41
48
|
|
|
42
49
|
@pytest.mark.asyncio
|
|
43
|
-
async def test_has_permission_platform_admin_true(self, httpx_mock):
|
|
50
|
+
async def test_has_permission_platform_admin_true(self, httpx_mock, redis, project_mock):
|
|
51
|
+
project_code = str(uuid4())
|
|
44
52
|
current_identity = {
|
|
45
53
|
'username': 'test',
|
|
46
54
|
'role': 'admin',
|
|
47
55
|
}
|
|
48
56
|
url = (
|
|
49
57
|
'http://auth/authorize?role=platform_admin&resource=project&zone=core&operation=view'
|
|
50
|
-
'&project_code=
|
|
58
|
+
f'&project_code={project_code}'
|
|
51
59
|
)
|
|
52
60
|
httpx_mock.add_response(method='GET', json={'result': {'has_permission': True}}, url=url)
|
|
53
|
-
result = await has_permission(
|
|
61
|
+
result = await has_permission(
|
|
62
|
+
'http://auth/', 'http://project', redis.url, project_code, 'project', 'core', 'view', current_identity
|
|
63
|
+
)
|
|
54
64
|
assert result is True
|
|
55
65
|
|
|
56
66
|
@pytest.mark.asyncio
|
|
57
|
-
async def test_has_permission_no_project_code(self, httpx_mock):
|
|
67
|
+
async def test_has_permission_no_project_code(self, httpx_mock, redis):
|
|
68
|
+
project_code = str(uuid4())
|
|
58
69
|
current_identity = {
|
|
59
70
|
'username': 'test',
|
|
60
71
|
'role': 'member',
|
|
61
|
-
'realm_roles': ['
|
|
72
|
+
'realm_roles': [f'{project_code}-admin'],
|
|
62
73
|
}
|
|
63
|
-
result = await has_permission(
|
|
74
|
+
result = await has_permission(
|
|
75
|
+
'http://auth/', 'http://project', redis.url, '', 'project', 'core', 'view', current_identity
|
|
76
|
+
)
|
|
64
77
|
assert result is False
|
|
65
78
|
|
|
66
79
|
@pytest.mark.asyncio
|
|
67
|
-
async def test_has_permission_service_error(self, httpx_mock):
|
|
80
|
+
async def test_has_permission_service_error(self, httpx_mock, redis, project_mock):
|
|
81
|
+
project_code = str(uuid4())
|
|
68
82
|
current_identity = {
|
|
69
83
|
'username': 'test',
|
|
70
84
|
'role': 'member',
|
|
71
|
-
'realm_roles': ['
|
|
85
|
+
'realm_roles': [f'{project_code}-admin'],
|
|
72
86
|
}
|
|
73
|
-
url = 'http://auth/authorize?role=admin&resource=project&zone=core&operation=view&project_code=
|
|
87
|
+
url = f'http://auth/authorize?role=admin&resource=project&zone=core&operation=view&project_code={project_code}'
|
|
74
88
|
httpx_mock.add_response(method='GET', json={'result': {'has_permission': True}}, url=url, status_code=500)
|
|
75
89
|
with pytest.raises(Exception): # noqa: B017
|
|
76
|
-
await has_permission(
|
|
90
|
+
await has_permission(
|
|
91
|
+
'http://auth/', 'http://project', redis.url, project_code, 'project', 'core', 'view', current_identity
|
|
92
|
+
)
|
|
77
93
|
|
|
78
94
|
|
|
79
95
|
class TestFilePermissions:
|
|
80
96
|
@pytest.mark.asyncio
|
|
81
|
-
async def test_has_file_permission_in_namefolder_true(self, httpx_mock):
|
|
97
|
+
async def test_has_file_permission_in_namefolder_true(self, httpx_mock, redis, project_mock):
|
|
98
|
+
project_code = str(uuid4())
|
|
82
99
|
file_data = {
|
|
83
100
|
'parent_path': 'users/test',
|
|
84
101
|
'zone': 'core',
|
|
85
|
-
'container_code':
|
|
102
|
+
'container_code': project_code,
|
|
86
103
|
'container_type': 'project',
|
|
87
104
|
}
|
|
88
105
|
current_identity = {
|
|
89
106
|
'username': 'test',
|
|
90
107
|
'role': 'member',
|
|
91
|
-
'realm_roles': ['
|
|
108
|
+
'realm_roles': [f'{project_code}-admin'],
|
|
92
109
|
}
|
|
93
|
-
url = 'http://auth/authorize?role=admin&resource=file_any&zone=core&operation=view
|
|
110
|
+
url = f'http://auth/authorize?role=admin&resource=file_any&zone=core&operation=view&project_code={project_code}'
|
|
94
111
|
httpx_mock.add_response(method='GET', json={'result': {'has_permission': False}}, url=url)
|
|
95
112
|
url = (
|
|
96
113
|
'http://auth/authorize?role=admin&resource=file_in_own_namefolder&zone=core&operation=view'
|
|
97
|
-
'&project_code=
|
|
114
|
+
f'&project_code={project_code}'
|
|
98
115
|
)
|
|
99
116
|
httpx_mock.add_response(method='GET', json={'result': {'has_permission': True}}, url=url)
|
|
100
|
-
result = await has_file_permission(
|
|
117
|
+
result = await has_file_permission(
|
|
118
|
+
'http://auth/', 'http://metadata/v1/', 'http://project', redis.url, file_data, 'view', current_identity
|
|
119
|
+
)
|
|
101
120
|
assert result is True
|
|
102
121
|
|
|
103
122
|
@pytest.mark.asyncio
|
|
104
|
-
async def test_has_file_permission_in_other_namefolder_true(self, httpx_mock):
|
|
123
|
+
async def test_has_file_permission_in_other_namefolder_true(self, httpx_mock, redis, project_mock):
|
|
124
|
+
project_code = str(uuid4())
|
|
105
125
|
file_data = {
|
|
106
126
|
'parent_path': 'users/another',
|
|
107
127
|
'zone': 'core',
|
|
108
|
-
'container_code':
|
|
128
|
+
'container_code': project_code,
|
|
109
129
|
'container_type': 'project',
|
|
110
130
|
}
|
|
111
131
|
current_identity = {
|
|
112
132
|
'username': 'test',
|
|
113
133
|
'role': 'member',
|
|
114
|
-
'realm_roles': ['
|
|
134
|
+
'realm_roles': [f'{project_code}-admin'],
|
|
115
135
|
}
|
|
116
|
-
url = 'http://auth/authorize?role=admin&resource=file_any&zone=core&operation=view
|
|
136
|
+
url = f'http://auth/authorize?role=admin&resource=file_any&zone=core&operation=view&project_code={project_code}'
|
|
117
137
|
httpx_mock.add_response(method='GET', json={'result': {'has_permission': False}}, url=url)
|
|
118
|
-
result = await has_file_permission(
|
|
138
|
+
result = await has_file_permission(
|
|
139
|
+
'http://auth/', 'http://metadata/v1/', 'http://project', redis.url, file_data, 'view', current_identity
|
|
140
|
+
)
|
|
119
141
|
assert result is False
|
|
120
142
|
|
|
121
143
|
@pytest.mark.asyncio
|
|
122
|
-
async def test_has_file_permission_false(self, httpx_mock):
|
|
144
|
+
async def test_has_file_permission_false(self, httpx_mock, redis, project_mock):
|
|
145
|
+
project_code = str(uuid4())
|
|
123
146
|
file_data = {
|
|
124
147
|
'parent_path': 'users/test',
|
|
125
148
|
'zone': 'core',
|
|
126
|
-
'container_code':
|
|
149
|
+
'container_code': project_code,
|
|
127
150
|
'container_type': 'project',
|
|
128
151
|
}
|
|
129
152
|
current_identity = {
|
|
130
153
|
'username': 'test',
|
|
131
154
|
'role': 'member',
|
|
132
|
-
'realm_roles': ['
|
|
155
|
+
'realm_roles': [f'{project_code}-admin'],
|
|
133
156
|
}
|
|
134
|
-
url = 'http://auth/authorize?role=admin&resource=file_any&zone=core&operation=view
|
|
157
|
+
url = f'http://auth/authorize?role=admin&resource=file_any&zone=core&operation=view&project_code={project_code}'
|
|
135
158
|
httpx_mock.add_response(method='GET', json={'result': {'has_permission': False}}, url=url)
|
|
136
159
|
url = (
|
|
137
160
|
'http://auth/authorize?role=admin&resource=file_in_own_namefolder&zone=core&operation=view'
|
|
138
|
-
'&project_code=
|
|
161
|
+
f'&project_code={project_code}'
|
|
139
162
|
)
|
|
140
163
|
httpx_mock.add_response(method='GET', json={'result': {'has_permission': False}}, url=url)
|
|
141
|
-
result = await has_file_permission(
|
|
164
|
+
result = await has_file_permission(
|
|
165
|
+
'http://auth/', 'http://metadata/v1/', 'http://project', redis.url, file_data, 'view', current_identity
|
|
166
|
+
)
|
|
142
167
|
assert result is False
|
|
143
168
|
|
|
144
169
|
@pytest.mark.asyncio
|
|
145
|
-
async def test_has_file_permission_outside_of_namefolder_false(self, httpx_mock):
|
|
170
|
+
async def test_has_file_permission_outside_of_namefolder_false(self, httpx_mock, redis, project_mock):
|
|
171
|
+
project_code = str(uuid4())
|
|
146
172
|
file_data = {
|
|
147
173
|
'parent_path': 'users/test',
|
|
148
174
|
'zone': 'core',
|
|
149
|
-
'container_code':
|
|
175
|
+
'container_code': project_code,
|
|
150
176
|
'container_type': 'project',
|
|
151
177
|
}
|
|
152
178
|
current_identity = {
|
|
153
179
|
'username': 'test',
|
|
154
180
|
'role': 'member',
|
|
155
|
-
'realm_roles': ['
|
|
181
|
+
'realm_roles': [f'{project_code}-admin'],
|
|
156
182
|
}
|
|
157
|
-
url = 'http://auth/authorize?role=admin&resource=file_any&zone=core&operation=view
|
|
183
|
+
url = f'http://auth/authorize?role=admin&resource=file_any&zone=core&operation=view&project_code={project_code}'
|
|
158
184
|
httpx_mock.add_response(method='GET', json={'result': {'has_permission': False}}, url=url)
|
|
159
185
|
url = (
|
|
160
186
|
'http://auth/authorize?role=admin&resource=file_in_own_namefolder&zone=core&operation=view'
|
|
161
|
-
'&project_code=
|
|
187
|
+
f'&project_code={project_code}'
|
|
162
188
|
)
|
|
163
189
|
httpx_mock.add_response(method='GET', json={'result': {'has_permission': False}}, url=url)
|
|
164
|
-
result = await has_file_permission(
|
|
190
|
+
result = await has_file_permission(
|
|
191
|
+
'http://auth/', 'http://metadata/v1/', 'http://project', redis.url, file_data, 'view', current_identity
|
|
192
|
+
)
|
|
165
193
|
assert result is False
|
|
166
194
|
|
|
167
195
|
@pytest.mark.asyncio
|
|
168
|
-
async def test_has_file_permission_wrong_project(self, httpx_mock):
|
|
196
|
+
async def test_has_file_permission_wrong_project(self, httpx_mock, redis):
|
|
197
|
+
project_code = str(uuid4())
|
|
169
198
|
file_data = {
|
|
170
199
|
'parent_path': 'users/test',
|
|
171
200
|
'zone': 'core',
|
|
172
|
-
'container_code':
|
|
201
|
+
'container_code': project_code,
|
|
173
202
|
'container_type': 'project',
|
|
174
203
|
}
|
|
175
204
|
current_identity = {
|
|
176
205
|
'username': 'test',
|
|
177
206
|
'role': 'member',
|
|
178
|
-
'realm_roles': ['
|
|
207
|
+
'realm_roles': ['wrongproject-admin'],
|
|
179
208
|
}
|
|
180
|
-
result = await has_file_permission(
|
|
209
|
+
result = await has_file_permission(
|
|
210
|
+
'http://auth/', 'http://metadata/v1/', 'http://project', redis.url, file_data, 'view', current_identity
|
|
211
|
+
)
|
|
181
212
|
assert result is False
|
|
182
213
|
|
|
183
214
|
@pytest.mark.asyncio
|
|
184
|
-
async def test_has_file_permission_wrong_container_type(self, httpx_mock):
|
|
215
|
+
async def test_has_file_permission_wrong_container_type(self, httpx_mock, redis):
|
|
216
|
+
project_code = str(uuid4())
|
|
185
217
|
file_data = {
|
|
186
218
|
'parent_path': 'users/test',
|
|
187
219
|
'zone': 'core',
|
|
188
|
-
'container_code':
|
|
220
|
+
'container_code': project_code,
|
|
189
221
|
'container_type': 'dataset',
|
|
190
222
|
}
|
|
191
223
|
current_identity = {
|
|
192
224
|
'username': 'test',
|
|
193
225
|
'role': 'member',
|
|
194
|
-
'realm_roles': ['
|
|
226
|
+
'realm_roles': [f'{project_code}-admin'],
|
|
195
227
|
}
|
|
196
|
-
result = await has_file_permission(
|
|
228
|
+
result = await has_file_permission(
|
|
229
|
+
'http://auth/', 'http://metadata/v1/', 'http://project', redis.url, file_data, 'view', current_identity
|
|
230
|
+
)
|
|
197
231
|
assert result is False
|
|
198
232
|
|
|
199
233
|
@pytest.mark.asyncio
|
|
200
|
-
async def test_has_file_permission_trashed(self, httpx_mock):
|
|
234
|
+
async def test_has_file_permission_trashed(self, httpx_mock, redis, project_mock):
|
|
235
|
+
project_code = str(uuid4())
|
|
201
236
|
file_data = {
|
|
202
237
|
'status': 'TRASHED',
|
|
203
238
|
'restore_path': 'users/test',
|
|
204
239
|
'zone': 'core',
|
|
205
|
-
'container_code':
|
|
240
|
+
'container_code': project_code,
|
|
206
241
|
'container_type': 'project',
|
|
207
242
|
}
|
|
208
243
|
current_identity = {
|
|
209
244
|
'username': 'test',
|
|
210
245
|
'role': 'member',
|
|
211
|
-
'realm_roles': ['
|
|
246
|
+
'realm_roles': [f'{project_code}-admin'],
|
|
212
247
|
}
|
|
213
|
-
url = 'http://auth/authorize?role=admin&resource=file_any&zone=core&operation=view
|
|
248
|
+
url = f'http://auth/authorize?role=admin&resource=file_any&zone=core&operation=view&project_code={project_code}'
|
|
214
249
|
httpx_mock.add_response(method='GET', json={'result': {'has_permission': False}}, url=url)
|
|
215
250
|
url = (
|
|
216
251
|
'http://auth/authorize?role=admin&resource=file_in_own_namefolder&zone=core&operation=view'
|
|
217
|
-
'&project_code=
|
|
252
|
+
f'&project_code={project_code}'
|
|
218
253
|
)
|
|
219
254
|
httpx_mock.add_response(method='GET', json={'result': {'has_permission': True}}, url=url)
|
|
220
|
-
result = await has_file_permission(
|
|
255
|
+
result = await has_file_permission(
|
|
256
|
+
'http://auth/', 'http://metadata/v1/', 'http://project', redis.url, file_data, 'view', current_identity
|
|
257
|
+
)
|
|
221
258
|
assert result is True
|
|
222
259
|
|
|
223
260
|
@pytest.mark.asyncio
|
|
224
|
-
async def test_has_file_permission_namefolder(self, httpx_mock):
|
|
261
|
+
async def test_has_file_permission_namefolder(self, httpx_mock, redis, project_mock):
|
|
262
|
+
project_code = str(uuid4())
|
|
225
263
|
file_data = {
|
|
226
264
|
'parent_path': 'users',
|
|
227
265
|
'type': 'name_folder',
|
|
228
266
|
'name': 'test',
|
|
229
267
|
'zone': 'core',
|
|
230
|
-
'container_code':
|
|
268
|
+
'container_code': project_code,
|
|
231
269
|
'container_type': 'project',
|
|
232
270
|
}
|
|
233
271
|
current_identity = {
|
|
234
272
|
'username': 'test',
|
|
235
273
|
'role': 'member',
|
|
236
|
-
'realm_roles': ['
|
|
274
|
+
'realm_roles': [f'{project_code}-admin'],
|
|
237
275
|
}
|
|
238
|
-
url = 'http://auth/authorize?role=admin&resource=file_any&zone=core&operation=view
|
|
276
|
+
url = f'http://auth/authorize?role=admin&resource=file_any&zone=core&operation=view&project_code={project_code}'
|
|
239
277
|
httpx_mock.add_response(method='GET', json={'result': {'has_permission': False}}, url=url)
|
|
240
278
|
url = (
|
|
241
279
|
'http://auth/authorize?role=admin&resource=file_in_own_namefolder&zone=core&operation=view'
|
|
242
|
-
'&project_code=
|
|
280
|
+
f'&project_code={project_code}'
|
|
243
281
|
)
|
|
244
282
|
httpx_mock.add_response(method='GET', json={'result': {'has_permission': True}}, url=url)
|
|
245
|
-
result = await has_file_permission(
|
|
283
|
+
result = await has_file_permission(
|
|
284
|
+
'http://auth/', 'http://metadata/v1/', 'http://project', redis.url, file_data, 'view', current_identity
|
|
285
|
+
)
|
|
246
286
|
assert result is True
|
|
247
287
|
|
|
248
288
|
@pytest.mark.asyncio
|
|
249
289
|
@pytest.mark.parametrize('is_authorized', [True, False])
|
|
250
|
-
async def test_has_file_permission_file_in_shared_folder(
|
|
290
|
+
async def test_has_file_permission_file_in_shared_folder(
|
|
291
|
+
self, httpx_mock, get_project_folder, is_authorized, redis, project_mock
|
|
292
|
+
):
|
|
293
|
+
project_code = str(uuid4())
|
|
251
294
|
file_data = {
|
|
252
295
|
'type': 'file',
|
|
253
296
|
'name': 'test.txt',
|
|
254
297
|
'zone': 'core',
|
|
255
|
-
'container_code':
|
|
298
|
+
'container_code': project_code,
|
|
256
299
|
'container_type': 'project',
|
|
257
300
|
'parent_path': 'shared/user',
|
|
258
301
|
}
|
|
259
302
|
current_identity = {
|
|
260
303
|
'username': 'test',
|
|
261
304
|
'role': 'member',
|
|
262
|
-
'realm_roles': ['
|
|
305
|
+
'realm_roles': [f'{project_code}-admin'],
|
|
263
306
|
}
|
|
264
307
|
project_folder = get_project_folder
|
|
265
308
|
resource = 'file_shared_' + project_folder['id']
|
|
266
309
|
|
|
267
|
-
url =
|
|
310
|
+
url = (
|
|
311
|
+
f'http://auth/authorize?role=admin&resource={resource}&zone=core&operation=view&project_code={project_code}'
|
|
312
|
+
)
|
|
268
313
|
httpx_mock.add_response(method='GET', json={'result': {'has_permission': is_authorized}}, url=url)
|
|
269
314
|
|
|
270
|
-
result = await has_file_permission(
|
|
315
|
+
result = await has_file_permission(
|
|
316
|
+
'http://auth/', 'http://metadata/v1/', 'http://project', redis.url, file_data, 'view', current_identity
|
|
317
|
+
)
|
|
271
318
|
assert result is is_authorized
|
|
272
319
|
|
|
273
320
|
@pytest.mark.asyncio
|
|
274
321
|
@pytest.mark.parametrize('is_authorized', [True, False])
|
|
275
|
-
async def test_has_file_permission_file_in_shared_folder_trashed_sourced(
|
|
322
|
+
async def test_has_file_permission_file_in_shared_folder_trashed_sourced(
|
|
323
|
+
self, httpx_mock, is_authorized, redis, project_mock
|
|
324
|
+
):
|
|
325
|
+
project_code = str(uuid4())
|
|
276
326
|
file_data = {
|
|
277
327
|
'type': 'file',
|
|
278
328
|
'name': 'test.txt',
|
|
279
329
|
'zone': 'core',
|
|
280
|
-
'container_code':
|
|
330
|
+
'container_code': project_code,
|
|
281
331
|
'container_type': 'project',
|
|
282
332
|
'parent_path': 'shared/user',
|
|
283
333
|
}
|
|
284
334
|
current_identity = {
|
|
285
335
|
'username': 'test',
|
|
286
336
|
'role': 'member',
|
|
287
|
-
'realm_roles': ['
|
|
337
|
+
'realm_roles': [f'{project_code}-admin'],
|
|
288
338
|
}
|
|
289
339
|
PROJECT_FOLDER_DATA = {
|
|
290
340
|
'type': 'project_folder',
|
|
@@ -293,33 +343,40 @@ class TestFilePermissions:
|
|
|
293
343
|
}
|
|
294
344
|
|
|
295
345
|
url = (
|
|
296
|
-
'http://metadata/v1/item/?name=user&container_code=
|
|
346
|
+
f'http://metadata/v1/item/?name=user&container_code={project_code}&container_type=project&zone=1'
|
|
297
347
|
'&type=project_folder&status=ACTIVE'
|
|
298
348
|
)
|
|
299
349
|
httpx_mock.add_response(status_code=404, method='GET', json={}, url=url)
|
|
300
350
|
|
|
301
351
|
url = (
|
|
302
|
-
'http://metadata/v1/item/?name=user&container_code=
|
|
352
|
+
f'http://metadata/v1/item/?name=user&container_code={project_code}&container_type=project&zone=1'
|
|
303
353
|
'&type=project_folder&status=TRASHED'
|
|
304
354
|
)
|
|
305
355
|
httpx_mock.add_response(method='GET', json={'result': PROJECT_FOLDER_DATA}, url=url)
|
|
306
356
|
project_folder = PROJECT_FOLDER_DATA
|
|
307
357
|
|
|
308
358
|
resource = 'file_shared_' + project_folder['id']
|
|
309
|
-
url =
|
|
359
|
+
url = (
|
|
360
|
+
f'http://auth/authorize?role=admin&resource={resource}&zone=core&operation=view&project_code={project_code}'
|
|
361
|
+
)
|
|
310
362
|
httpx_mock.add_response(method='GET', json={'result': {'has_permission': is_authorized}}, url=url)
|
|
311
363
|
|
|
312
|
-
result = await has_file_permission(
|
|
364
|
+
result = await has_file_permission(
|
|
365
|
+
'http://auth/', 'http://metadata/v1/', 'http://project', redis.url, file_data, 'view', current_identity
|
|
366
|
+
)
|
|
313
367
|
assert result is is_authorized
|
|
314
368
|
|
|
315
369
|
@pytest.mark.asyncio
|
|
316
370
|
@pytest.mark.parametrize('is_authorized', [True, False])
|
|
317
|
-
async def test_has_file_permission_file_in_shared_folder_trash(
|
|
371
|
+
async def test_has_file_permission_file_in_shared_folder_trash(
|
|
372
|
+
self, httpx_mock, is_authorized, redis, project_mock
|
|
373
|
+
):
|
|
374
|
+
project_code = str(uuid4())
|
|
318
375
|
file_data = {
|
|
319
376
|
'type': 'file',
|
|
320
377
|
'name': 'test.txt',
|
|
321
378
|
'zone': 'core',
|
|
322
|
-
'container_code':
|
|
379
|
+
'container_code': project_code,
|
|
323
380
|
'container_type': 'project',
|
|
324
381
|
'restore_path': 'shared',
|
|
325
382
|
'status': 'TRASHED',
|
|
@@ -327,7 +384,7 @@ class TestFilePermissions:
|
|
|
327
384
|
current_identity = {
|
|
328
385
|
'username': 'test',
|
|
329
386
|
'role': 'member',
|
|
330
|
-
'realm_roles': ['
|
|
387
|
+
'realm_roles': [f'{project_code}-admin'],
|
|
331
388
|
}
|
|
332
389
|
PROJECT_FOLDER_DATA = {
|
|
333
390
|
'type': 'project_folder',
|
|
@@ -340,44 +397,56 @@ class TestFilePermissions:
|
|
|
340
397
|
|
|
341
398
|
resource = 'file_shared_' + PROJECT_FOLDER_DATA['id']
|
|
342
399
|
|
|
343
|
-
url =
|
|
400
|
+
url = (
|
|
401
|
+
f'http://auth/authorize?role=admin&resource={resource}&zone=core&operation=view&project_code={project_code}'
|
|
402
|
+
)
|
|
344
403
|
httpx_mock.add_response(method='GET', json={'result': {'has_permission': is_authorized}}, url=url)
|
|
345
404
|
|
|
346
|
-
result = await has_file_permission(
|
|
405
|
+
result = await has_file_permission(
|
|
406
|
+
'http://auth/', 'http://metadata/v1/', 'http://project', redis.url, file_data, 'view', current_identity
|
|
407
|
+
)
|
|
347
408
|
assert result is is_authorized
|
|
348
409
|
|
|
349
410
|
@pytest.mark.asyncio
|
|
350
411
|
@pytest.mark.parametrize('is_authorized', [True, False])
|
|
351
|
-
async def test_has_file_permission_shared_folder(
|
|
412
|
+
async def test_has_file_permission_shared_folder(
|
|
413
|
+
self, httpx_mock, get_project_folder, is_authorized, redis, project_mock
|
|
414
|
+
):
|
|
415
|
+
project_code = str(uuid4())
|
|
352
416
|
file_data = {
|
|
353
417
|
'type': 'project_folder',
|
|
354
418
|
'name': 'user',
|
|
355
419
|
'zone': 'core',
|
|
356
|
-
'container_code':
|
|
420
|
+
'container_code': project_code,
|
|
357
421
|
'container_type': 'project',
|
|
358
422
|
'parent_path': 'shared',
|
|
359
423
|
}
|
|
360
424
|
current_identity = {
|
|
361
425
|
'username': 'test',
|
|
362
426
|
'role': 'member',
|
|
363
|
-
'realm_roles': ['
|
|
427
|
+
'realm_roles': [f'{project_code}-admin'],
|
|
364
428
|
}
|
|
365
429
|
project_folder = get_project_folder
|
|
366
430
|
resource = 'file_shared_' + project_folder['id']
|
|
367
431
|
|
|
368
|
-
url =
|
|
432
|
+
url = (
|
|
433
|
+
f'http://auth/authorize?role=admin&resource={resource}&zone=core&operation=view&project_code={project_code}'
|
|
434
|
+
)
|
|
369
435
|
httpx_mock.add_response(method='GET', json={'result': {'has_permission': is_authorized}}, url=url)
|
|
370
436
|
|
|
371
|
-
result = await has_file_permission(
|
|
437
|
+
result = await has_file_permission(
|
|
438
|
+
'http://auth/', 'http://metadata/v1/', 'http://project', redis.url, file_data, 'view', current_identity
|
|
439
|
+
)
|
|
372
440
|
assert result is is_authorized
|
|
373
441
|
|
|
374
442
|
@pytest.mark.asyncio
|
|
375
|
-
async def test_has_file_permission_root_level_users(self, httpx_mock):
|
|
443
|
+
async def test_has_file_permission_root_level_users(self, httpx_mock, redis):
|
|
444
|
+
project_code = str(uuid4())
|
|
376
445
|
file_data = {
|
|
377
446
|
'type': 'root_folder',
|
|
378
447
|
'name': 'users',
|
|
379
448
|
'zone': 'core',
|
|
380
|
-
'container_code':
|
|
449
|
+
'container_code': project_code,
|
|
381
450
|
'container_type': 'project',
|
|
382
451
|
'parent_path': None,
|
|
383
452
|
'parent': None,
|
|
@@ -385,18 +454,21 @@ class TestFilePermissions:
|
|
|
385
454
|
current_identity = {
|
|
386
455
|
'username': 'test',
|
|
387
456
|
'role': 'member',
|
|
388
|
-
'realm_roles': ['
|
|
457
|
+
'realm_roles': [f'{project_code}-admin'],
|
|
389
458
|
}
|
|
390
|
-
result = await has_file_permission(
|
|
459
|
+
result = await has_file_permission(
|
|
460
|
+
'http://auth/', 'http://metadata/v1/', 'http://project', redis.url, file_data, 'view', current_identity
|
|
461
|
+
)
|
|
391
462
|
assert result is True
|
|
392
463
|
|
|
393
464
|
@pytest.mark.asyncio
|
|
394
|
-
async def test_has_file_permission_root_level_shared(self, httpx_mock):
|
|
465
|
+
async def test_has_file_permission_root_level_shared(self, httpx_mock, redis):
|
|
466
|
+
project_code = str(uuid4())
|
|
395
467
|
file_data = {
|
|
396
468
|
'type': 'root_folder',
|
|
397
469
|
'name': 'shared',
|
|
398
470
|
'zone': 'core',
|
|
399
|
-
'container_code':
|
|
471
|
+
'container_code': project_code,
|
|
400
472
|
'container_type': 'project',
|
|
401
473
|
'parent_path': None,
|
|
402
474
|
'parent': None,
|
|
@@ -404,40 +476,45 @@ class TestFilePermissions:
|
|
|
404
476
|
current_identity = {
|
|
405
477
|
'username': 'test',
|
|
406
478
|
'role': 'member',
|
|
407
|
-
'realm_roles': ['
|
|
479
|
+
'realm_roles': [f'{project_code}-admin'],
|
|
408
480
|
}
|
|
409
|
-
result = await has_file_permission(
|
|
481
|
+
result = await has_file_permission(
|
|
482
|
+
'http://auth/', 'http://metadata/v1/', 'http://project', redis.url, file_data, 'view', current_identity
|
|
483
|
+
)
|
|
410
484
|
assert result is True
|
|
411
485
|
|
|
412
486
|
|
|
413
487
|
class TestGetCurrentRole:
|
|
414
488
|
@pytest.mark.asyncio
|
|
415
489
|
async def test_get_current_role_admin(self, httpx_mock):
|
|
490
|
+
project_code = str(uuid4())
|
|
416
491
|
current_identity = {
|
|
417
492
|
'username': 'test',
|
|
418
493
|
'role': 'admin',
|
|
419
|
-
'realm_roles': ['
|
|
494
|
+
'realm_roles': [f'{project_code}-admin'],
|
|
420
495
|
}
|
|
421
|
-
result = await get_project_role(
|
|
496
|
+
result = await get_project_role(project_code, current_identity)
|
|
422
497
|
assert result == 'platform_admin'
|
|
423
498
|
|
|
424
499
|
@pytest.mark.asyncio
|
|
425
500
|
async def test_get_current_role_member(self, httpx_mock):
|
|
501
|
+
project_code = str(uuid4())
|
|
426
502
|
current_identity = {
|
|
427
503
|
'username': 'test',
|
|
428
504
|
'role': 'member',
|
|
429
|
-
'realm_roles': ['
|
|
505
|
+
'realm_roles': [f'{project_code}-admin'],
|
|
430
506
|
}
|
|
431
|
-
result = await get_project_role(
|
|
507
|
+
result = await get_project_role(project_code, current_identity)
|
|
432
508
|
assert result == 'admin'
|
|
433
509
|
|
|
434
510
|
async def test_get_current_role_non_default(self, httpx_mock):
|
|
511
|
+
project_code = str(uuid4())
|
|
435
512
|
current_identity = {
|
|
436
513
|
'username': 'test',
|
|
437
514
|
'role': 'member',
|
|
438
|
-
'realm_roles': ['
|
|
515
|
+
'realm_roles': [f'{project_code}-customrole'],
|
|
439
516
|
}
|
|
440
|
-
result = await get_project_role(
|
|
517
|
+
result = await get_project_role(project_code, current_identity)
|
|
441
518
|
assert result == 'customrole'
|
|
442
519
|
|
|
443
520
|
|
|
@@ -447,26 +524,31 @@ class TestBulkPermissions:
|
|
|
447
524
|
{'role': 'admin', 'zone': 'greenroom', 'resource': 'file_any', 'operation': 'copy'},
|
|
448
525
|
{'role': 'admin', 'zone': 'greenroom', 'resource': 'file_any', 'operation': 'view'},
|
|
449
526
|
]
|
|
450
|
-
current_identity = {'role': 'collaborator', 'realm_roles': ['test_project-collaborator']}
|
|
451
527
|
|
|
452
|
-
async def test_has_permissions_return_mapped_assertions(self, httpx_mock):
|
|
528
|
+
async def test_has_permissions_return_mapped_assertions(self, httpx_mock, redis, project_mock):
|
|
529
|
+
project_code = str(uuid4())
|
|
530
|
+
current_identity = {'role': 'collaborator', 'realm_roles': [f'{project_code}-collaborator']}
|
|
453
531
|
granted = {'has_permission': True}
|
|
454
532
|
mapped_result = {'greenroom_file_any_copy': True, 'greenroom_file_any_view': True}
|
|
455
533
|
|
|
456
534
|
httpx_mock.add_response(
|
|
457
535
|
method='POST',
|
|
458
|
-
url=f'{self.auth_service_url}authorize?project_code=
|
|
536
|
+
url=f'{self.auth_service_url}authorize?project_code={project_code}',
|
|
459
537
|
status_code=200,
|
|
460
538
|
json=granted,
|
|
461
539
|
)
|
|
462
540
|
mapped = await has_permissions(
|
|
463
|
-
self.auth_service_url, '
|
|
541
|
+
self.auth_service_url, 'http://project', redis.url, project_code, self.permission_request, current_identity
|
|
464
542
|
)
|
|
465
543
|
|
|
466
544
|
assert mapped == mapped_result
|
|
467
545
|
|
|
468
|
-
async def test_has_permissions_raise_project_role_not_found_exception_for_invalid_role(
|
|
469
|
-
|
|
470
|
-
|
|
546
|
+
async def test_has_permissions_raise_project_role_not_found_exception_for_invalid_role(
|
|
547
|
+
self, httpx_mock, redis, project_mock
|
|
548
|
+
):
|
|
549
|
+
project_code = str(uuid4())
|
|
550
|
+
identity = {'role': 'collaborator', 'realm_roles': ['invalid-collaborator']}
|
|
471
551
|
with pytest.raises(ProjectRoleNotFound):
|
|
472
|
-
await has_permissions(
|
|
552
|
+
await has_permissions(
|
|
553
|
+
self.auth_service_url, 'http://project', redis.url, project_code, self.permission_request, identity
|
|
554
|
+
)
|
|
@@ -110,9 +110,11 @@ def test_create_project_200(fake, redis, httpx_mock):
|
|
|
110
110
|
operator=fake.user_name(),
|
|
111
111
|
tags=PROJECT_DATA['tags'],
|
|
112
112
|
system_tags=PROJECT_DATA['system_tags'],
|
|
113
|
+
created_by=PROJECT_DATA['created_by'],
|
|
113
114
|
)
|
|
114
115
|
assert project.name == PROJECT_DATA['name']
|
|
115
116
|
assert project.state == PROJECT_DATA['state']
|
|
117
|
+
assert project.created_by == PROJECT_DATA['created_by']
|
|
116
118
|
|
|
117
119
|
|
|
118
120
|
def test_create_project_500(fake, redis, httpx_mock):
|
|
@@ -132,6 +134,7 @@ def test_create_project_500(fake, redis, httpx_mock):
|
|
|
132
134
|
operator=fake.user_name(),
|
|
133
135
|
tags=PROJECT_DATA['tags'],
|
|
134
136
|
system_tags=PROJECT_DATA['system_tags'],
|
|
137
|
+
created_by=PROJECT_DATA['created_by'],
|
|
135
138
|
)
|
|
136
139
|
|
|
137
140
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pilot_platform_common-2.2.0 → pilot_platform_common-2.4.0}/common/jwt_handler/JWTHandler.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pilot_platform_common-2.2.0 → pilot_platform_common-2.4.0}/common/models/config_center_policy.py
RENAMED
|
File without changes
|
{pilot_platform_common-2.2.0 → pilot_platform_common-2.4.0}/common/models/service_id_generator.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pilot_platform_common-2.2.0 → pilot_platform_common-2.4.0}/common/permissions/exceptions.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pilot_platform_common-2.2.0 → pilot_platform_common-2.4.0}/common/project/project_exceptions.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pilot_platform_common-2.2.0 → pilot_platform_common-2.4.0}/tests/permissions/test_auth_client.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|