用于使用 SQL 查询配置权限检查的 Datasette 插件
在与 Datasette 相同的环境中安装此插件。
$ pip install datasette-permissions-sql
首先,阅读 Datasette 的认证和权限系统如何工作。
此插件允许您定义包含 SQL 查询的规则,这些查询将执行以检查当前认证的用户(actor)是否具有执行某些操作的权限。
考虑一个预设查询,只有当 users
表中的某一行表明认证用户是员工时,他们才能执行该查询。
mydatabase.db
数据库中的 users
表可能如下所示
id | username | is_staff |
---|---|---|
1 | cleopaws | 0 |
2 | simon | 1 |
认证用户有一个如下所示的 actor
{
"id": 2,
"username": "simon"
}
要将预设查询配置为仅由员工用户执行,请将以下内容添加到您的 metadata.json
中
{
"plugins": {
"datasette-permissions-sql": [
{
"action": "view-query",
"resource": ["mydatabase", "promote_to_staff"],
"sql": "SELECT * FROM users WHERE is_staff = 1 AND id = :actor_id"
}
]
},
"databases": {
"mydatabase": {
"queries": {
"promote_to_staff": {
"sql": "UPDATE users SET is is_staff=1 WHERE id=:id",
"write": true
}
}
}
}
}
"datasette-permissions-sql"
键是一个规则列表。每个规则具有以下形式
{
"action": "name-of-action",
"resource": ["resource identifier to run this on"],
"sql": "SQL query to execute",
"database": "mydatabase"
}
"action"
和 "resource"
都是可选的。如果存在,SQL 查询将仅在匹配的操作以及(如果存在)匹配的资源指示符的权限检查时执行。
"database"
也是可选的:它指定应该执行查询的命名数据库。如果不存在,将使用第一个连接的数据库。
Datasette 文档包含您可能希望在此处使用的内置权限列表。
如果 SQL 查询返回任何行,则允许该操作。如果未返回任何行,插件钩子将返回 False
并拒绝访问该操作。
SQL 查询会带有一些命名参数进行调用。您可以在查询中使用这些参数中的任何一个。
参数列表如下
action
- 操作,例如"view-database"
resource_1
- 资源的第一个组成部分,如果已传递resource_2
- 资源的第二个组成部分,如果可用actor_*
- actor 上每个键对应的参数。通常actor_id
会存在。
如果返回任何行,权限检查通过。如果未返回任何行,则检查失败。
另一个示例表,这次是授予对各个表的显式访问权限。考虑一个名为 table_access
的表,它看起来像这样
user_id | database | table |
---|---|---|
1 | mydb | dogs |
2 | mydb | dogs |
1 | mydb | cats |
以下 SQL 查询将授予用户 1 和 2 对 mydb.db
数据库中 dogs
表的访问权限 - 但会禁止用户 2 访问 cats
表
SELECT
*
FROM
table_access
WHERE
user_id = :actor_id
AND "database" = :resource_1
AND "table" = :resource_2
在 metadata.yaml
配置文件中,它将看起来像这样
databases:
mydb:
allow_sql: {}
plugins:
datasette-permissions-sql:
- action: view-table
sql: |-
SELECT
*
FROM
table_access
WHERE
user_id = :actor_id
AND "database" = :resource_1
AND "table" = :resource_2
我们在这里使用 allow_sql: {}
来禁用任意 SQL 查询。这可以防止用户直接运行 select * from cats
来绕过权限限制。
此插件的默认行为是完全控制指定的权限。SQL 查询将直接控制用户是否被允许或拒绝访问该权限。
这意味着将忽略每个权限的默认策略(在 Datasette 核心中,view-database
等权限的默认策略是“允许”)。这也意味着一旦此插件执行,任何其他 permission_allowed
插件将不会有机会执行。
您可以使用 "fallback": true
按规则更改此行为
{
"action": "view-table",
"resource": ["mydatabase", "mytable"],
"sql": "select * from admins where user_id = :actor_id",
"fallback": true
}
在回退模式下运行时,查询结果未返回任何行将导致插件钩子返回 None
- 这意味着“我对该权限没有意见,回退到其他插件或默认策略”。
在此模式下,您仍然可以通过返回一个包含单个值 -1
的单行来返回 False
(表示“拒绝访问”)。例如
{
"action": "view-table",
"resource": ["mydatabase", "mytable"],
"sql": "select -1 from banned where user_id = :actor_id",
"fallback": true
}