datasette-permissions-sql 作者 simonw

加星

README 源代码

datasette-permissions-sql

PyPI CircleCI License

用于使用 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 查询

如果 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
}