用于使用 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
}