mirror of
https://github.com/simonw/datasette.git
synced 2025-12-10 16:51:24 +01:00
Label expand permission check respects cascade, closes #2178
This commit is contained in:
parent
ab040470e2
commit
c26370485a
2 changed files with 57 additions and 17 deletions
|
|
@ -950,13 +950,19 @@ class Datasette:
|
|||
except IndexError:
|
||||
return {}
|
||||
# Ensure user has permission to view the referenced table
|
||||
if not await self.permission_allowed(
|
||||
actor=actor,
|
||||
action="view-table",
|
||||
resource=(database, fk["other_table"]),
|
||||
):
|
||||
other_table = fk["other_table"]
|
||||
other_column = fk["other_column"]
|
||||
visible, _ = await self.check_visibility(
|
||||
actor,
|
||||
permissions=[
|
||||
("view-table", (database, other_table)),
|
||||
("view-database", database),
|
||||
"view-instance",
|
||||
],
|
||||
)
|
||||
if not visible:
|
||||
return {}
|
||||
label_column = await db.label_column_for_table(fk["other_table"])
|
||||
label_column = await db.label_column_for_table(other_table)
|
||||
if not label_column:
|
||||
return {(fk["column"], value): str(value) for value in values}
|
||||
labeled_fks = {}
|
||||
|
|
@ -965,9 +971,9 @@ class Datasette:
|
|||
from {other_table}
|
||||
where {other_column} in ({placeholders})
|
||||
""".format(
|
||||
other_column=escape_sqlite(fk["other_column"]),
|
||||
other_column=escape_sqlite(other_column),
|
||||
label_column=escape_sqlite(label_column),
|
||||
other_table=escape_sqlite(fk["other_table"]),
|
||||
other_table=escape_sqlite(other_table),
|
||||
placeholders=", ".join(["?"] * len(set(values))),
|
||||
)
|
||||
try:
|
||||
|
|
|
|||
|
|
@ -1207,9 +1207,11 @@ async def test_format_of_binary_links(size, title, length_bytes):
|
|||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_foreign_key_labels_obey_permissions():
|
||||
ds = Datasette(
|
||||
metadata={
|
||||
@pytest.mark.parametrize(
|
||||
"metadata",
|
||||
(
|
||||
# Blocked at table level
|
||||
{
|
||||
"databases": {
|
||||
"foreign_key_labels": {
|
||||
"tables": {
|
||||
|
|
@ -1218,15 +1220,47 @@ async def test_foreign_key_labels_obey_permissions():
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
},
|
||||
# Blocked at database level
|
||||
{
|
||||
"databases": {
|
||||
"foreign_key_labels": {
|
||||
# Only root can view this database
|
||||
"allow": {"id": "root"},
|
||||
"tables": {
|
||||
# But table b is visible to everyone
|
||||
"b": {"allow": True},
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
# Blocked at the instance level
|
||||
{
|
||||
"allow": {"id": "root"},
|
||||
"databases": {
|
||||
"foreign_key_labels": {
|
||||
"tables": {
|
||||
# Table b is visible to everyone
|
||||
"b": {"allow": True},
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
),
|
||||
)
|
||||
async def test_foreign_key_labels_obey_permissions(metadata):
|
||||
ds = Datasette(metadata=metadata)
|
||||
db = ds.add_memory_database("foreign_key_labels")
|
||||
await db.execute_write("create table a(id integer primary key, name text)")
|
||||
await db.execute_write("insert into a (id, name) values (1, 'hello')")
|
||||
await db.execute_write(
|
||||
"create table b(id integer primary key, name text, a_id integer references a(id))"
|
||||
"create table if not exists a(id integer primary key, name text)"
|
||||
)
|
||||
await db.execute_write("insert or replace into a (id, name) values (1, 'hello')")
|
||||
await db.execute_write(
|
||||
"create table if not exists b(id integer primary key, name text, a_id integer references a(id))"
|
||||
)
|
||||
await db.execute_write(
|
||||
"insert or replace into b (id, name, a_id) values (1, 'world', 1)"
|
||||
)
|
||||
await db.execute_write("insert into b (id, name, a_id) values (1, 'world', 1)")
|
||||
# Anonymous user can see table b but not table a
|
||||
blah = await ds.client.get("/foreign_key_labels.json")
|
||||
anon_a = await ds.client.get("/foreign_key_labels/a.json?_labels=on")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue