elody 0.0.195__tar.gz → 0.0.196__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.
- {elody-0.0.195 → elody-0.0.196}/PKG-INFO +1 -1
- {elody-0.0.195 → elody-0.0.196}/pyproject.toml +1 -1
- {elody-0.0.195 → elody-0.0.196}/src/elody/policies/authorization/filter_generic_objects_policy_v2.py +8 -0
- {elody-0.0.195 → elody-0.0.196}/src/elody/policies/authorization/generic_object_request_policy_v2.py +12 -3
- {elody-0.0.195 → elody-0.0.196}/src/elody/policies/helpers.py +18 -0
- {elody-0.0.195 → elody-0.0.196}/src/elody/policies/permission_handler.py +35 -9
- {elody-0.0.195 → elody-0.0.196}/src/elody.egg-info/PKG-INFO +1 -1
- {elody-0.0.195 → elody-0.0.196}/LICENSE +0 -0
- {elody-0.0.195 → elody-0.0.196}/README.md +0 -0
- {elody-0.0.195 → elody-0.0.196}/setup.cfg +0 -0
- {elody-0.0.195 → elody-0.0.196}/src/__init__.py +0 -0
- {elody-0.0.195 → elody-0.0.196}/src/elody/__init__.py +0 -0
- {elody-0.0.195 → elody-0.0.196}/src/elody/client.py +0 -0
- {elody-0.0.195 → elody-0.0.196}/src/elody/csv.py +0 -0
- {elody-0.0.195 → elody-0.0.196}/src/elody/error_codes.py +0 -0
- {elody-0.0.195 → elody-0.0.196}/src/elody/exceptions.py +0 -0
- {elody-0.0.195 → elody-0.0.196}/src/elody/job.py +0 -0
- {elody-0.0.195 → elody-0.0.196}/src/elody/loader.py +0 -0
- {elody-0.0.195 → elody-0.0.196}/src/elody/migration/__init__.py +0 -0
- {elody-0.0.195 → elody-0.0.196}/src/elody/migration/base_object_migrator.py +0 -0
- {elody-0.0.195 → elody-0.0.196}/src/elody/object_configurations/__init__.py +0 -0
- {elody-0.0.195 → elody-0.0.196}/src/elody/object_configurations/base_object_configuration.py +0 -0
- {elody-0.0.195 → elody-0.0.196}/src/elody/object_configurations/elody_configuration.py +0 -0
- {elody-0.0.195 → elody-0.0.196}/src/elody/object_configurations/job_configuration.py +0 -0
- {elody-0.0.195 → elody-0.0.196}/src/elody/policies/__init__.py +0 -0
- {elody-0.0.195 → elody-0.0.196}/src/elody/policies/authentication/__init__.py +0 -0
- {elody-0.0.195 → elody-0.0.196}/src/elody/policies/authentication/base_user_tenant_validation_policy.py +0 -0
- {elody-0.0.195 → elody-0.0.196}/src/elody/policies/authentication/multi_tenant_policy.py +0 -0
- {elody-0.0.195 → elody-0.0.196}/src/elody/policies/authorization/__init__.py +0 -0
- {elody-0.0.195 → elody-0.0.196}/src/elody/policies/authorization/filter_generic_objects_policy.py +0 -0
- {elody-0.0.195 → elody-0.0.196}/src/elody/policies/authorization/generic_object_detail_policy.py +0 -0
- {elody-0.0.195 → elody-0.0.196}/src/elody/policies/authorization/generic_object_mediafiles_policy.py +0 -0
- {elody-0.0.195 → elody-0.0.196}/src/elody/policies/authorization/generic_object_metadata_policy.py +0 -0
- {elody-0.0.195 → elody-0.0.196}/src/elody/policies/authorization/generic_object_relations_policy.py +0 -0
- {elody-0.0.195 → elody-0.0.196}/src/elody/policies/authorization/generic_object_request_policy.py +0 -0
- {elody-0.0.195 → elody-0.0.196}/src/elody/policies/authorization/mediafile_derivatives_policy.py +0 -0
- {elody-0.0.195 → elody-0.0.196}/src/elody/policies/authorization/mediafile_download_policy.py +0 -0
- {elody-0.0.195 → elody-0.0.196}/src/elody/policies/authorization/multi_tenant_policy.py +0 -0
- {elody-0.0.195 → elody-0.0.196}/src/elody/policies/authorization/tenant_request_policy.py +0 -0
- {elody-0.0.195 → elody-0.0.196}/src/elody/schemas.py +0 -0
- {elody-0.0.195 → elody-0.0.196}/src/elody/util.py +0 -0
- {elody-0.0.195 → elody-0.0.196}/src/elody/validator.py +0 -0
- {elody-0.0.195 → elody-0.0.196}/src/elody.egg-info/SOURCES.txt +0 -0
- {elody-0.0.195 → elody-0.0.196}/src/elody.egg-info/dependency_links.txt +0 -0
- {elody-0.0.195 → elody-0.0.196}/src/elody.egg-info/requires.txt +0 -0
- {elody-0.0.195 → elody-0.0.196}/src/elody.egg-info/top_level.txt +0 -0
- {elody-0.0.195 → elody-0.0.196}/src/tests/__init_.py +0 -0
- {elody-0.0.195 → elody-0.0.196}/src/tests/data.py +0 -0
- {elody-0.0.195 → elody-0.0.196}/src/tests/unit/__init__.py +0 -0
- {elody-0.0.195 → elody-0.0.196}/src/tests/unit/test_csv.py +0 -0
- {elody-0.0.195 → elody-0.0.196}/src/tests/unit/test_utils.py +0 -0
{elody-0.0.195 → elody-0.0.196}/src/elody/policies/authorization/filter_generic_objects_policy_v2.py
RENAMED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import re as regex
|
|
2
2
|
|
|
3
3
|
from copy import deepcopy
|
|
4
|
+
from elody.policies.helpers import generate_filter_key_and_lookup_from_restricted_key
|
|
4
5
|
from elody.policies.permission_handler import (
|
|
5
6
|
get_permissions,
|
|
6
7
|
mask_protected_content_post_request_hook,
|
|
@@ -123,6 +124,11 @@ class PostRequestRules:
|
|
|
123
124
|
restrictions = schemas[schema].get("object_restrictions", {})
|
|
124
125
|
for restricted_key, restricting_value in restrictions.items():
|
|
125
126
|
index, restricted_key = restricted_key.split(":")
|
|
127
|
+
restricted_key, lookup = (
|
|
128
|
+
generate_filter_key_and_lookup_from_restricted_key(
|
|
129
|
+
restricted_key
|
|
130
|
+
)
|
|
131
|
+
)
|
|
126
132
|
key = f"{schema}|{restricted_key}"
|
|
127
133
|
if group := restrictions_grouped_by_index.get(index):
|
|
128
134
|
group["key"].append(key)
|
|
@@ -130,6 +136,7 @@ class PostRequestRules:
|
|
|
130
136
|
restrictions_grouped_by_index.update(
|
|
131
137
|
{
|
|
132
138
|
index: {
|
|
139
|
+
"lookup": lookup,
|
|
133
140
|
"key": [key],
|
|
134
141
|
"value": restricting_value,
|
|
135
142
|
}
|
|
@@ -155,6 +162,7 @@ class PostRequestRules:
|
|
|
155
162
|
for restriction in restrictions_grouped_by_index.values():
|
|
156
163
|
user_context.access_restrictions.filters.append( # pyright: ignore
|
|
157
164
|
{
|
|
165
|
+
"lookup": restriction["lookup"],
|
|
158
166
|
"type": "selection",
|
|
159
167
|
"key": restriction["key"],
|
|
160
168
|
"value": restriction["value"],
|
{elody-0.0.195 → elody-0.0.196}/src/elody/policies/authorization/generic_object_request_policy_v2.py
RENAMED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import re as regex
|
|
2
2
|
|
|
3
3
|
from configuration import get_object_configuration_mapper # pyright: ignore
|
|
4
|
-
from elody.policies.helpers import
|
|
4
|
+
from elody.policies.helpers import (
|
|
5
|
+
generate_filter_key_and_lookup_from_restricted_key,
|
|
6
|
+
get_content,
|
|
7
|
+
)
|
|
5
8
|
from elody.policies.permission_handler import (
|
|
6
9
|
get_permissions,
|
|
7
10
|
handle_single_item_request,
|
|
@@ -82,7 +85,7 @@ class GetRequestRules:
|
|
|
82
85
|
type_permissions[schemas[0]].get("object_restrictions", {}).keys()
|
|
83
86
|
)
|
|
84
87
|
for i in range(number_of_object_restrictions):
|
|
85
|
-
keys, values = [], []
|
|
88
|
+
lookup, keys, values = {}, [], []
|
|
86
89
|
for schema in schemas:
|
|
87
90
|
object_restrictions = type_permissions[schema].get(
|
|
88
91
|
"object_restrictions", {}
|
|
@@ -92,10 +95,16 @@ class GetRequestRules:
|
|
|
92
95
|
for key in object_restrictions.keys()
|
|
93
96
|
if key.startswith(f"{i}:")
|
|
94
97
|
][0]
|
|
95
|
-
keys.append(f"{schema}|{key.split(':')[1]}")
|
|
96
98
|
values = object_restrictions[key]
|
|
99
|
+
key, lookup = (
|
|
100
|
+
generate_filter_key_and_lookup_from_restricted_key(
|
|
101
|
+
key.split(":")[1]
|
|
102
|
+
)
|
|
103
|
+
)
|
|
104
|
+
keys.append(f"{schema}|{key}")
|
|
97
105
|
filters.append(
|
|
98
106
|
{
|
|
107
|
+
"lookup": lookup,
|
|
99
108
|
"type": "selection",
|
|
100
109
|
"key": keys,
|
|
101
110
|
"value": values,
|
|
@@ -4,6 +4,24 @@ from serialization.serialize import serialize # pyright: ignore
|
|
|
4
4
|
from werkzeug.exceptions import NotFound
|
|
5
5
|
|
|
6
6
|
|
|
7
|
+
def generate_filter_key_and_lookup_from_restricted_key(key):
|
|
8
|
+
if (keys := key.split("@", 1)) and len(keys) == 1:
|
|
9
|
+
return key, {}
|
|
10
|
+
|
|
11
|
+
local_field = keys[0]
|
|
12
|
+
document_type, key = keys[1].split("-", 1)
|
|
13
|
+
collection = (
|
|
14
|
+
get_object_configuration_mapper().get(document_type).crud()["collection"]
|
|
15
|
+
)
|
|
16
|
+
lookup = {
|
|
17
|
+
"from": collection,
|
|
18
|
+
"local_field": local_field,
|
|
19
|
+
"foreign_field": "identifiers",
|
|
20
|
+
"as": f"__lookup.virtual_relations.{document_type}",
|
|
21
|
+
}
|
|
22
|
+
return f"{lookup['as']}.{key}", lookup
|
|
23
|
+
|
|
24
|
+
|
|
7
25
|
def get_content(item, request, content):
|
|
8
26
|
return serialize(
|
|
9
27
|
content,
|
|
@@ -3,9 +3,11 @@ import re as regex
|
|
|
3
3
|
from configuration import get_object_configuration_mapper # pyright: ignore
|
|
4
4
|
from copy import deepcopy
|
|
5
5
|
from elody.error_codes import ErrorCode, get_error_code, get_read
|
|
6
|
+
from elody.policies.helpers import get_item
|
|
6
7
|
from elody.util import flatten_dict, interpret_flat_key
|
|
7
8
|
from inuits_policy_based_auth.contexts.user_context import UserContext
|
|
8
9
|
from logging_elody.log import log # pyright: ignore
|
|
10
|
+
from storage.storagemanager import StorageManager # pyright: ignore
|
|
9
11
|
|
|
10
12
|
|
|
11
13
|
_permissions = {}
|
|
@@ -63,7 +65,7 @@ def handle_single_item_request(
|
|
|
63
65
|
)
|
|
64
66
|
|
|
65
67
|
is_allowed_to_crud_item = (
|
|
66
|
-
__is_allowed_to_crud_item(flat_item, restrictions_schema)
|
|
68
|
+
__is_allowed_to_crud_item(flat_item, restrictions_schema, user_context)
|
|
67
69
|
if flat_item
|
|
68
70
|
else None
|
|
69
71
|
)
|
|
@@ -131,10 +133,7 @@ def __prepare_item_for_permission_check(item, permissions, crud):
|
|
|
131
133
|
if item.get("type", "") not in permissions[crud].keys():
|
|
132
134
|
return item, None, None, None
|
|
133
135
|
|
|
134
|
-
|
|
135
|
-
object_lists = config.document_info().get("object_lists", {})
|
|
136
|
-
flat_item = flatten_dict(object_lists, item)
|
|
137
|
-
|
|
136
|
+
flat_item, object_lists = __get_flat_item_and_object_lists(item)
|
|
138
137
|
return (
|
|
139
138
|
item,
|
|
140
139
|
flat_item,
|
|
@@ -159,13 +158,15 @@ def __get_restrictions_schema(flat_item, permissions, crud):
|
|
|
159
158
|
return schemas[schema] if schemas and schema else {}
|
|
160
159
|
|
|
161
160
|
|
|
162
|
-
def __is_allowed_to_crud_item(
|
|
161
|
+
def __is_allowed_to_crud_item(
|
|
162
|
+
flat_item, restrictions_schema, user_context: UserContext
|
|
163
|
+
):
|
|
163
164
|
restrictions = restrictions_schema.get("object_restrictions", {})
|
|
164
165
|
|
|
165
166
|
for restricted_key, restricting_values in restrictions.items():
|
|
166
167
|
restricted_key = restricted_key.split(":")[1]
|
|
167
168
|
item_value_in_restricting_values = __item_value_in_values(
|
|
168
|
-
flat_item, restricted_key, restricting_values
|
|
169
|
+
flat_item, restricted_key, restricting_values, {}, user_context
|
|
169
170
|
)
|
|
170
171
|
if not item_value_in_restricting_values:
|
|
171
172
|
return None
|
|
@@ -192,7 +193,11 @@ def __is_allowed_to_crud_item_keys(
|
|
|
192
193
|
condition_match = True
|
|
193
194
|
for condition_key, condition_values in restricting_conditions.items():
|
|
194
195
|
condition_match = __item_value_in_values(
|
|
195
|
-
flat_item,
|
|
196
|
+
flat_item,
|
|
197
|
+
condition_key,
|
|
198
|
+
condition_values,
|
|
199
|
+
flat_request_body,
|
|
200
|
+
user_context,
|
|
196
201
|
)
|
|
197
202
|
if not condition_match:
|
|
198
203
|
break
|
|
@@ -228,7 +233,9 @@ def __is_allowed_to_crud_item_keys(
|
|
|
228
233
|
return len(user_context.bag["restricted_keys"]) == 0
|
|
229
234
|
|
|
230
235
|
|
|
231
|
-
def __item_value_in_values(
|
|
236
|
+
def __item_value_in_values(
|
|
237
|
+
flat_item, key, values: list, flat_request_body, user_context: UserContext
|
|
238
|
+
):
|
|
232
239
|
negate_condition = False
|
|
233
240
|
is_optional = False
|
|
234
241
|
|
|
@@ -239,6 +246,10 @@ def __item_value_in_values(flat_item, key, values: list, flat_request_body: dict
|
|
|
239
246
|
key = key[1:]
|
|
240
247
|
is_optional = True
|
|
241
248
|
|
|
249
|
+
key_of_relation = None
|
|
250
|
+
if (keys := key.split("@", 1)) and len(keys) == 2:
|
|
251
|
+
key = keys[0]
|
|
252
|
+
key_of_relation = keys[1].split("-", 1)[1]
|
|
242
253
|
try:
|
|
243
254
|
item_value = flat_request_body.get(key, flat_item[key])
|
|
244
255
|
if is_optional:
|
|
@@ -249,6 +260,15 @@ def __item_value_in_values(flat_item, key, values: list, flat_request_body: dict
|
|
|
249
260
|
f"{get_error_code(ErrorCode.METADATA_KEY_UNDEFINED, get_read())} | key:{key} | document:{flat_item.get('_id', flat_item["type"])} - Key {key} not found in document {flat_item.get('_id', flat_item["type"])}. Either prefix the key with '?' in your permission configuration to make it an optional restriction, or patch the document to include the key. '?' will allow access if key does not exist, '!?' will deny access if key does not exist."
|
|
250
261
|
)
|
|
251
262
|
return not negate_condition
|
|
263
|
+
else:
|
|
264
|
+
if key_of_relation:
|
|
265
|
+
if isinstance(item_value, list):
|
|
266
|
+
item_value = item_value[0]
|
|
267
|
+
item = get_item(StorageManager(), user_context.bag, {"id": item_value})
|
|
268
|
+
flat_item, _ = __get_flat_item_and_object_lists(item)
|
|
269
|
+
return __item_value_in_values(
|
|
270
|
+
flat_item, key_of_relation, values, flat_request_body, user_context
|
|
271
|
+
)
|
|
252
272
|
|
|
253
273
|
expected_values = []
|
|
254
274
|
for value in values:
|
|
@@ -280,3 +300,9 @@ def __get_element_from_object_list_of_item(
|
|
|
280
300
|
if element[object_lists[object_list]] == key:
|
|
281
301
|
return element
|
|
282
302
|
return {}
|
|
303
|
+
|
|
304
|
+
|
|
305
|
+
def __get_flat_item_and_object_lists(item):
|
|
306
|
+
config = get_object_configuration_mapper().get(item["type"])
|
|
307
|
+
object_lists = config.document_info().get("object_lists", {})
|
|
308
|
+
return flatten_dict(object_lists, item), object_lists
|
|
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
|
{elody-0.0.195 → elody-0.0.196}/src/elody/object_configurations/base_object_configuration.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
|
{elody-0.0.195 → elody-0.0.196}/src/elody/policies/authorization/filter_generic_objects_policy.py
RENAMED
|
File without changes
|
{elody-0.0.195 → elody-0.0.196}/src/elody/policies/authorization/generic_object_detail_policy.py
RENAMED
|
File without changes
|
{elody-0.0.195 → elody-0.0.196}/src/elody/policies/authorization/generic_object_mediafiles_policy.py
RENAMED
|
File without changes
|
{elody-0.0.195 → elody-0.0.196}/src/elody/policies/authorization/generic_object_metadata_policy.py
RENAMED
|
File without changes
|
{elody-0.0.195 → elody-0.0.196}/src/elody/policies/authorization/generic_object_relations_policy.py
RENAMED
|
File without changes
|
{elody-0.0.195 → elody-0.0.196}/src/elody/policies/authorization/generic_object_request_policy.py
RENAMED
|
File without changes
|
{elody-0.0.195 → elody-0.0.196}/src/elody/policies/authorization/mediafile_derivatives_policy.py
RENAMED
|
File without changes
|
{elody-0.0.195 → elody-0.0.196}/src/elody/policies/authorization/mediafile_download_policy.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
|