Skip to content

Commit d04ae50

Browse files
committed
Add discovery filtering
1 parent b3d8b3e commit d04ae50

1 file changed

Lines changed: 48 additions & 9 deletions

File tree

  • server/example_configurations/access_control/general/filter_server

server/example_configurations/access_control/general/filter_server/app.py

Lines changed: 48 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,10 @@ def _item_allowed(item: Any, allow_all: bool, allowed_ids: set[str]) -> bool:
160160
return _id_allowed(item_id, allow_all, allowed_ids)
161161

162162

163+
def _identifier_allowed(item: Any, allow_all: bool, allowed_ids: set[str]) -> bool:
164+
return isinstance(item, str) and bool(item) and _id_allowed(item, allow_all, allowed_ids)
165+
166+
163167
def _submodel_reference_id(reference: Any) -> str | None:
164168
if not isinstance(reference, dict):
165169
return None
@@ -378,6 +382,15 @@ def _is_submodel_descriptors_path(path: str) -> bool:
378382
return bool(segments) and segments[-1] == "submodel-descriptors"
379383

380384

385+
def _is_discovery_shells_path(path: str) -> bool:
386+
segments = _path_segments(path)
387+
return (
388+
len(segments) >= 2
389+
and segments[-2] == "lookup"
390+
and segments[-1] == "shells"
391+
)
392+
393+
381394
def _request_query_without_paging() -> list[tuple[str, str]]:
382395
query_items: list[tuple[str, str]] = []
383396
for key in request.args:
@@ -625,6 +638,28 @@ def _handle_filtered_submodel_descriptors(path: str, access_control: dict[str, A
625638
return jsonify(payload), status_code
626639

627640

641+
def _handle_filtered_discovery_shells(
642+
path: str,
643+
access_control: dict[str, Any],
644+
) -> Response:
645+
roles = _token_roles()
646+
original_payload, items, status_code = _fetch_collection(path)
647+
request_path = "/" + path.strip("/")
648+
allow_all, allowed_ids = _aas_resource_access(
649+
access_control,
650+
roles,
651+
request_path,
652+
)
653+
filtered_items = [
654+
identifier
655+
for identifier in items
656+
if _identifier_allowed(identifier, allow_all, allowed_ids)
657+
]
658+
659+
payload = _filtered_payload(original_payload, filtered_items)
660+
return jsonify(payload), status_code
661+
662+
628663
def _proxy_request(path: str, access_control: dict[str, Any]) -> Response:
629664
upstream_response = requests.request(
630665
request.method,
@@ -684,8 +719,11 @@ def repository_proxy(path: str) -> Response:
684719
normalized_path = f"/{path.strip('/')}"
685720
collection = _filtered_collection(normalized_path, access_control)
686721

687-
if request.method == "GET":
688-
try:
722+
try:
723+
if request.method == "GET":
724+
if _is_discovery_shells_path(normalized_path):
725+
return _handle_filtered_discovery_shells(path, access_control)
726+
689727
if _is_shell_descriptors_path(normalized_path):
690728
return _handle_filtered_shell_descriptors(path, access_control)
691729

@@ -697,13 +735,14 @@ def repository_proxy(path: str) -> Response:
697735

698736
if _is_submodel_refs_path(normalized_path):
699737
return _handle_filtered_submodel_refs(path, access_control)
700-
except requests.HTTPError as exc:
701-
response = exc.response
702-
return Response(
703-
response.content,
704-
status=response.status_code,
705-
headers=_response_headers(response),
706-
)
738+
739+
except requests.HTTPError as exc:
740+
response = exc.response
741+
return Response(
742+
response.content,
743+
status=response.status_code,
744+
headers=_response_headers(response),
745+
)
707746

708747
return _proxy_request(path, access_control)
709748

0 commit comments

Comments
 (0)