Use dash encoding for database names, too, refs #1439

pull/1648/head
Simon Willison 2022-03-07 07:31:37 -08:00
rodzic b760264ae6
commit 32548b88fd
5 zmienionych plików z 28 dodań i 14 usunięć

Wyświetl plik

@ -31,10 +31,10 @@ class Urls:
db = self.ds.databases[database]
if self.ds.setting("hash_urls") and db.hash:
path = self.path(
f"{urllib.parse.quote(database)}-{db.hash[:HASH_LENGTH]}", format=format
f"{dash_encode(database)}-{db.hash[:HASH_LENGTH]}", format=format
)
else:
path = self.path(urllib.parse.quote(database), format=format)
path = self.path(dash_encode(database), format=format)
return path
def table(self, database, table, format=None):

Wyświetl plik

@ -205,17 +205,17 @@ class DataView(BaseView):
async def resolve_db_name(self, request, db_name, **kwargs):
hash = None
name = None
db_name = urllib.parse.unquote_plus(db_name)
if db_name not in self.ds.databases and "-" in db_name:
decoded_name = dash_decode(db_name)
if decoded_name not in self.ds.databases and "-" in db_name:
# No matching DB found, maybe it's a name-hash?
name_bit, hash_bit = db_name.rsplit("-", 1)
if name_bit not in self.ds.databases:
if dash_decode(name_bit) not in self.ds.databases:
raise NotFound(f"Database not found: {name}")
else:
name = name_bit
name = dash_decode(name_bit)
hash = hash_bit
else:
name = db_name
name = decoded_name
try:
db = self.ds.databases[name]

Wyświetl plik

@ -942,7 +942,7 @@ def test_cors(app_client_with_cors, path, status_code):
)
def test_database_with_space_in_name(app_client_two_attached_databases, path):
response = app_client_two_attached_databases.get(
"/extra database" + path, follow_redirects=True
"/extra-20database" + path, follow_redirects=True
)
assert response.status == 200
@ -953,7 +953,7 @@ def test_common_prefix_database_names(app_client_conflicting_database_names):
d["name"]
for d in app_client_conflicting_database_names.get("/-/databases.json").json
]
for db_name, path in (("foo", "/foo.json"), ("foo-bar", "/foo-bar.json")):
for db_name, path in (("foo", "/foo.json"), ("foo-bar", "/foo-2Dbar.json")):
data = app_client_conflicting_database_names.get(path).json
assert db_name == data["database"]
@ -992,3 +992,16 @@ async def test_hidden_sqlite_stat1_table():
data = (await ds.client.get("/db.json?_show_hidden=1")).json()
tables = [(t["name"], t["hidden"]) for t in data["tables"]]
assert tables == [("normal", False), ("sqlite_stat1", True)]
@pytest.mark.asyncio
@pytest.mark.parametrize("db_name", ("foo", r"fo%o", "f~/c.d"))
async def test_dash_encoded_database_names(db_name):
ds = Datasette()
ds.add_memory_database(db_name)
response = await ds.client.get("/.json")
assert db_name in response.json().keys()
path = response.json()[db_name]["path"]
# And the JSON for that database
response2 = await ds.client.get(path + ".json")
assert response2.status_code == 200

Wyświetl plik

@ -9,6 +9,7 @@ from datasette.app import SETTINGS
from datasette.plugins import DEFAULT_PLUGINS
from datasette.cli import cli, serve
from datasette.version import __version__
from datasette.utils import dash_encode
from datasette.utils.sqlite import sqlite3
from click.testing import CliRunner
import io
@ -294,12 +295,12 @@ def test_weird_database_names(ensure_eventloop, tmpdir, filename):
assert result1.exit_code == 0, result1.output
filename_no_stem = filename.rsplit(".", 1)[0]
expected_link = '<a href="/{}">{}</a>'.format(
urllib.parse.quote(filename_no_stem), filename_no_stem
dash_encode(filename_no_stem), filename_no_stem
)
assert expected_link in result1.output
# Now try hitting that database page
result2 = runner.invoke(
cli, [db_path, "--get", "/{}".format(urllib.parse.quote(filename_no_stem))]
cli, [db_path, "--get", "/{}".format(dash_encode(filename_no_stem))]
)
assert result2.exit_code == 0, result2.output

Wyświetl plik

@ -29,7 +29,7 @@ def test_homepage(app_client_two_attached_databases):
)
# Should be two attached databases
assert [
{"href": r"/extra%20database", "text": "extra database"},
{"href": r"/extra-20database", "text": "extra database"},
{"href": "/fixtures", "text": "fixtures"},
] == [{"href": a["href"], "text": a.text.strip()} for a in soup.select("h2 a")]
# Database should show count text and attached tables
@ -44,8 +44,8 @@ def test_homepage(app_client_two_attached_databases):
{"href": a["href"], "text": a.text.strip()} for a in links_p.findAll("a")
]
assert [
{"href": r"/extra%20database/searchable", "text": "searchable"},
{"href": r"/extra%20database/searchable_view", "text": "searchable_view"},
{"href": r"/extra-20database/searchable", "text": "searchable"},
{"href": r"/extra-20database/searchable_view", "text": "searchable_view"},
] == table_links