Fix for /foo v.s. /foo-bar issue, closes #597

Pull request #599
This commit is contained in:
Simon Willison 2019-10-18 15:51:07 -07:00 committed by GitHub
commit b647b5efc2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 33 additions and 8 deletions

View file

@ -193,14 +193,14 @@ class DataView(BaseView):
async def resolve_db_name(self, request, db_name, **kwargs):
hash = None
name = None
if "-" in db_name:
# Might be name-and-hash, or might just be
# a name with a hyphen in it
name, hash = db_name.rsplit("-", 1)
if name not in self.ds.databases:
# Try the whole name
name = db_name
hash = None
if db_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:
raise NotFound("Database not found: {}".format(name))
else:
name = name_bit
hash = hash_bit
else:
name = db_name
# Verify the hash

View file

@ -178,6 +178,13 @@ def app_client_two_attached_databases():
)
@pytest.fixture(scope="session")
def app_client_conflicting_database_names():
yield from make_app_client(
extra_databases={"foo.db": EXTRA_DATABASE_SQL, "foo-bar.db": EXTRA_DATABASE_SQL}
)
@pytest.fixture(scope="session")
def app_client_two_attached_databases_one_immutable():
yield from make_app_client(

View file

@ -7,6 +7,7 @@ from .fixtures import ( # noqa
app_client_larger_cache_size,
app_client_returned_rows_matches_page_size,
app_client_two_attached_databases_one_immutable,
app_client_conflicting_database_names,
app_client_with_cors,
app_client_with_dot,
generate_compound_rows,
@ -1652,3 +1653,20 @@ def test_cors(app_client_with_cors, path, status_code):
response = app_client_with_cors.get(path)
assert response.status == status_code
assert "*" == response.headers["Access-Control-Allow-Origin"]
def test_common_prefix_database_names(app_client_conflicting_database_names):
# https://github.com/simonw/datasette/issues/597
assert ["fixtures", "foo", "foo-bar"] == [
d["name"]
for d in json.loads(
app_client_conflicting_database_names.get("/-/databases.json").body.decode(
"utf8"
)
)
]
for db_name, path in (("foo", "/foo.json"), ("foo-bar", "/foo-bar.json")):
data = json.loads(
app_client_conflicting_database_names.get(path).body.decode("utf8")
)
assert db_name == data["database"]