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:
|
except IndexError:
|
||||||
return {}
|
return {}
|
||||||
# Ensure user has permission to view the referenced table
|
# Ensure user has permission to view the referenced table
|
||||||
if not await self.permission_allowed(
|
other_table = fk["other_table"]
|
||||||
actor=actor,
|
other_column = fk["other_column"]
|
||||||
action="view-table",
|
visible, _ = await self.check_visibility(
|
||||||
resource=(database, fk["other_table"]),
|
actor,
|
||||||
):
|
permissions=[
|
||||||
|
("view-table", (database, other_table)),
|
||||||
|
("view-database", database),
|
||||||
|
"view-instance",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
if not visible:
|
||||||
return {}
|
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:
|
if not label_column:
|
||||||
return {(fk["column"], value): str(value) for value in values}
|
return {(fk["column"], value): str(value) for value in values}
|
||||||
labeled_fks = {}
|
labeled_fks = {}
|
||||||
|
|
@ -965,9 +971,9 @@ class Datasette:
|
||||||
from {other_table}
|
from {other_table}
|
||||||
where {other_column} in ({placeholders})
|
where {other_column} in ({placeholders})
|
||||||
""".format(
|
""".format(
|
||||||
other_column=escape_sqlite(fk["other_column"]),
|
other_column=escape_sqlite(other_column),
|
||||||
label_column=escape_sqlite(label_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))),
|
placeholders=", ".join(["?"] * len(set(values))),
|
||||||
)
|
)
|
||||||
try:
|
try:
|
||||||
|
|
|
||||||
|
|
@ -1207,9 +1207,11 @@ async def test_format_of_binary_links(size, title, length_bytes):
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
async def test_foreign_key_labels_obey_permissions():
|
@pytest.mark.parametrize(
|
||||||
ds = Datasette(
|
"metadata",
|
||||||
metadata={
|
(
|
||||||
|
# Blocked at table level
|
||||||
|
{
|
||||||
"databases": {
|
"databases": {
|
||||||
"foreign_key_labels": {
|
"foreign_key_labels": {
|
||||||
"tables": {
|
"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")
|
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(
|
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
|
# Anonymous user can see table b but not table a
|
||||||
blah = await ds.client.get("/foreign_key_labels.json")
|
blah = await ds.client.get("/foreign_key_labels.json")
|
||||||
anon_a = await ds.client.get("/foreign_key_labels/a.json?_labels=on")
|
anon_a = await ds.client.get("/foreign_key_labels/a.json?_labels=on")
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue