Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

URL-encode keys #444

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions tiled/_tests/test_slash.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import numpy

from ..adapters.array import ArrayAdapter
from ..adapters.mapping import MapAdapter
from ..client import Context, from_context
from ..server.app import build_app

arr = numpy.ones(3)


def test_slash_in_key():
tree = MapAdapter(
{
"x": MapAdapter({"y": ArrayAdapter(1 * arr)}),
"x/y": ArrayAdapter(2 * arr),
}
)
with Context.from_app(build_app(tree)) as context:
client = from_context(context)
assert client["x", "y"].read()[0] == 1
assert client["x/y"].read()[0] == 2
2 changes: 2 additions & 0 deletions tiled/client/node.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import time
import warnings
from dataclasses import asdict
from urllib.parse import quote_plus

import entrypoints

Expand Down Expand Up @@ -264,6 +265,7 @@ def __getitem__(self, keys, _ignore_inlined_contents=False):
# which must only return a result if 'a' is contained in the search results.
if not isinstance(keys, tuple):
keys = (keys,)
keys = tuple(quote_plus(key) for key in keys)
if self._queries:
# Lookup this key *within the search results* of this Node.
key, *tail = keys
Expand Down
7 changes: 4 additions & 3 deletions tiled/server/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
from datetime import datetime, timedelta
from hashlib import md5
from typing import Any
from urllib.parse import quote_plus

import dateutil.tz
import jmespath
Expand Down Expand Up @@ -186,7 +187,7 @@ def construct_entries_response(
media_type,
max_depth,
):
path_parts = [segment for segment in path.split("/") if segment]
path_parts = [quote_plus(segment) for segment in path.split("/") if segment]
tree = apply_search(tree, filters, query_registry)
tree = apply_sort(tree, sort)

Expand Down Expand Up @@ -248,7 +249,7 @@ def construct_revisions_response(
limit,
media_type,
):
path_parts = [segment for segment in path.split("/") if segment]
path_parts = [quote_plus(segment) for segment in path.split("/") if segment]
revisions = entry.revisions[offset : offset + limit] # noqa: E203
data = []
for revision in revisions:
Expand Down Expand Up @@ -456,7 +457,7 @@ def construct_resource(
for key, direction in entry.sorting
]
d = {
"id": path_parts[-1] if path_parts else "",
"id": quote_plus(path_parts[-1]) if path_parts else "",
"attributes": schemas.NodeAttributes(**attributes),
}
if not omit_links:
Expand Down
3 changes: 2 additions & 1 deletion tiled/server/dependencies.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from functools import lru_cache
from typing import Optional
from urllib.parse import unquote

import pydantic
from fastapi import Depends, HTTPException, Query, Request, Security
Expand Down Expand Up @@ -52,7 +53,7 @@ def inner(
Walk down the path from the root tree, filtering each intermediate node by
'read:metadata' and finally filtering by the specified scope.
"""
path_parts = [segment for segment in path.split("/") if segment]
path_parts = [unquote(segment) for segment in path.split("/") if segment]
entry = root_tree
try:
# Traverse into sub-tree(s). This requires only 'read:metadata' scope.
Expand Down