home / content / repos

repos: 271408895

This data as json

id node_id name full_name private owner html_url description fork created_at updated_at pushed_at homepage size stargazers_count watchers_count language has_issues has_projects has_downloads has_wiki has_pages forks_count archived disabled open_issues_count license topics forks open_issues watchers default_branch permissions temp_clone_token organization network_count subscribers_count readme readme_html allow_forking visibility is_template template_repository web_commit_signoff_required has_discussions
271408895 MDEwOlJlcG9zaXRvcnkyNzE0MDg4OTU= datasette-permissions-sql simonw/datasette-permissions-sql 0 9599 https://github.com/simonw/datasette-permissions-sql Datasette plugin for configuring permission checks using SQL queries 0 2020-06-10T23:48:13Z 2020-06-12T07:06:12Z 2020-06-12T07:06:15Z   25 0 0 Python 1 1 1 1 0 0 0 0 0 apache-2.0 ["datasette", "datasette-plugin", "datasette-io"] 0 0 0 master {"admin": false, "push": false, "pull": false}     0 1 # datasette-permissions-sql [![PyPI](https://img.shields.io/pypi/v/datasette-permissions-sql.svg)](https://pypi.org/project/datasette-permissions-sql/) [![CircleCI](https://circleci.com/gh/simonw/datasette-permissions-sql.svg?style=svg)](https://circleci.com/gh/simonw/datasette-permissions-sql) [![License](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](https://github.com/simonw/datasette-permissions-sql/blob/master/LICENSE) Datasette plugin for configuring permission checks using SQL queries ## Installation Install this plugin in the same environment as Datasette. $ pip install datasette-permissions-sql ## Usage First, read up on how Datasette's [authentication and permissions system](https://datasette.readthedocs.io/en/latest/authentication.html) works. This plugin lets you define rules containing SQL queries that are executed to see if the currently authenticated actor has permission to perform certain actions. Consider a canned query which authenticated users should only be able to execute if a row in the `users` table says that they are a member of staff. That `users` table in the `mydatabase.db` database could look like this: | id | username | is_staff | |--|--------|--------| | 1 | cleopaws | 0 | | 2 | simon | 1 | Authenticated users have an `actor` that looks like this: ```json { "id": 2, "username": "simon" } ``` To configure the canned query to only be executable by staff users, add the following to your `metadata.json`: ```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 } } } } } ``` The `"datasette-permissions-sql"` key is a list of rules. Each of those rules has the following shape: ```json { "action": "name-of-action", "resource": ["resource identifier to run this on"], "sql": "SQL query to execute", "database": "mydatabase" } ``` Both `"action"` and `"resource"` are optional. If present, the SQL query will only be executed on permission checks that match the action and, if present, the resource indicators. `"database"` is also optional: it specifies the named database that the query should be executed against. If it is not present the first connected database will be used. The Datasette documentation includes a [list of built-in permissions](https://datasette.readthedocs.io/en/stable/authentication.html#built-in-permissions) that you might want to use here. ### The SQL query If the SQL query returns any rows the action will be allowed. If it returns no rows, the plugin hook will return `False` and deny access to that action. The SQL query is called with a number of named parameters. You can use any of these as part of the query. The list of parameters is as follows: * `action` - the action, e.g. `"view-database"` * `resource_1` - the first component of the resource, if one was passed * `resource_2` - the second component of the resource, if available * `actor_*` - a parameter for every key on the actor. Usually `actor_id` is present. If any rows are returned, the permission check passes. If no rows are returned the check fails. Another example table, this time granting explicit access to individual tables. Consider a table called `table_access` that looks like this: | user_id | database | table | | - | - | - | | 1 | mydb | dogs | | 2 | mydb | dogs | | 1 | mydb | cats | The following SQL query would grant access to the `dogs` ttable in the `mydb.db` database to users 1 and 2 - but would forbid access for user 2 to the `cats` table: ```sql SELECT * FROM table_access WHERE user_id = :actor_id AND "database" = :resource_1 AND "table" = :resource_2 ``` In a `metadata.yaml` configuration file that would look like this: ```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 ``` We're using `allow_sql: {}` here to disable arbitrary SQL queries. This prevents users from running `select * from cats` directly to work around the permissions limits. ### Fallback mode The default behaviour of this plugin is to take full control of specified permissions. The SQL query will directly control if the user is allowed or denied access to the permission. This means that the default policy for each permission (which in Datasette core is "allow" for `view-database` and friends) will be ignored. It also means that any other `permission_allowed` plugins will not get their turn once this plugin has executed. You can change this on a per-rule basis using ``"fallback": true``: ```json { "action": "view-table", "resource": ["mydatabase", "mytable"], "sql": "select * from admins where user_id = :actor_id", "fallback": true } ``` When running in fallback mode, a query result returning no rows will cause the plugin hook to return ``None`` - which means "I have no opinion on this permission, fall back to other plugins or the default". In this mode you can still return `False` (for "deny access") by returning a single row with a single value of `-1`. For example: ```json { "action": "view-table", "resource": ["mydatabase", "mytable"], "sql": "select -1 from banned where user_id = :actor_id", "fallback": true } ``` <div id="readme" class="md" data-path="README.md"><article class="markdown-body entry-content container-lg" itemprop="text"><h1><a id="user-content-datasette-permissions-sql" class="anchor" aria-hidden="true" href="#user-content-datasette-permissions-sql"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a>datasette-permissions-sql</h1> <p><a href="https://pypi.org/project/datasette-permissions-sql/" rel="nofollow"><img src="https://camo.githubusercontent.com/898a57540c5f63707e7d55e28f18598cd101ae1b7cbad1ff71ead7f4a12174f4/68747470733a2f2f696d672e736869656c64732e696f2f707970692f762f6461746173657474652d7065726d697373696f6e732d73716c2e737667" alt="PyPI" data-canonical-src="https://img.shields.io/pypi/v/datasette-permissions-sql.svg" style="max-width:100%;"></a> <a href="https://circleci.com/gh/simonw/datasette-permissions-sql" rel="nofollow"><img src="https://camo.githubusercontent.com/587e99cf6d88c2bcfe530b5748d7f0f2ed638809bec3aa914244b7bf2ddcdc82/68747470733a2f2f636972636c6563692e636f6d2f67682f73696d6f6e772f6461746173657474652d7065726d697373696f6e732d73716c2e7376673f7374796c653d737667" alt="CircleCI" data-canonical-src="https://circleci.com/gh/simonw/datasette-permissions-sql.svg?style=svg" style="max-width:100%;"></a> <a href="https://github.com/simonw/datasette-permissions-sql/blob/master/LICENSE"><img src="https://camo.githubusercontent.com/1698104e976c681143eb0841f9675c6f802bb7aa832afc0c7a4e719b1f3cf955/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d417061636865253230322e302d626c75652e737667" alt="License" data-canonical-src="https://img.shields.io/badge/license-Apache%202.0-blue.svg" style="max-width:100%;"></a></p> <p>Datasette plugin for configuring permission checks using SQL queries</p> <h2><a id="user-content-installation" class="anchor" aria-hidden="true" href="#user-content-installation"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a>Installation</h2> <p>Install this plugin in the same environment as Datasette.</p> <div class="snippet-clipboard-content position-relative" data-snippet-clipboard-copy-content="$ pip install datasette-permissions-sql "><pre><code>$ pip install datasette-permissions-sql </code></pre></div> <h2><a id="user-content-usage" class="anchor" aria-hidden="true" href="#user-content-usage"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a>Usage</h2> <p>First, read up on how Datasette's <a href="https://datasette.readthedocs.io/en/latest/authentication.html" rel="nofollow">authentication and permissions system</a> works.</p> <p>This plugin lets you define rules containing SQL queries that are executed to see if the currently authenticated actor has permission to perform certain actions.</p> <p>Consider a canned query which authenticated users should only be able to execute if a row in the <code>users</code> table says that they are a member of staff.</p> <p>That <code>users</code> table in the <code>mydatabase.db</code> database could look like this:</p> <table> <thead> <tr> <th>id</th> <th>username</th> <th>is_staff</th> </tr> </thead> <tbody> <tr> <td>1</td> <td>cleopaws</td> <td>0</td> </tr> <tr> <td>2</td> <td>simon</td> <td>1</td> </tr> </tbody> </table> <p>Authenticated users have an <code>actor</code> that looks like this:</p> <div class="highlight highlight-source-json position-relative" data-snippet-clipboard-copy-content="{ &quot;id&quot;: 2, &quot;username&quot;: &quot;simon&quot; } "><pre>{ <span class="pl-s"><span class="pl-pds">"</span>id<span class="pl-pds">"</span></span>: <span class="pl-c1">2</span>, <span class="pl-s"><span class="pl-pds">"</span>username<span class="pl-pds">"</span></span>: <span class="pl-s"><span class="pl-pds">"</span>simon<span class="pl-pds">"</span></span> }</pre></div> <p>To configure the canned query to only be executable by staff users, add the following to your <code>metadata.json</code>:</p> <div class="highlight highlight-source-json position-relative" data-snippet-clipboard-copy-content="{ &quot;plugins&quot;: { &quot;datasette-permissions-sql&quot;: [ { &quot;action&quot;: &quot;view-query&quot;, &quot;resource&quot;: [&quot;mydatabase&quot;, &quot;promote_to_staff&quot;], &quot;sql&quot;: &quot;SELECT * FROM users WHERE is_staff = 1 AND id = :actor_id&quot; } ] }, &quot;databases&quot;: { &quot;mydatabase&quot;: { &quot;queries&quot;: { &quot;promote_to_staff&quot;: { &quot;sql&quot;: &quot;UPDATE users SET is is_staff=1 WHERE id=:id&quot;, &quot;write&quot;: true } } } } } "><pre>{ <span class="pl-s"><span class="pl-pds">"</span>plugins<span class="pl-pds">"</span></span>: { <span class="pl-s"><span class="pl-pds">"</span>datasette-permissions-sql<span class="pl-pds">"</span></span>: [ { <span class="pl-s"><span class="pl-pds">"</span>action<span class="pl-pds">"</span></span>: <span class="pl-s"><span class="pl-pds">"</span>view-query<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>resource<span class="pl-pds">"</span></span>: [<span class="pl-s"><span class="pl-pds">"</span>mydatabase<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>promote_to_staff<span class="pl-pds">"</span></span>], <span class="pl-s"><span class="pl-pds">"</span>sql<span class="pl-pds">"</span></span>: <span class="pl-s"><span class="pl-pds">"</span>SELECT * FROM users WHERE is_staff = 1 AND id = :actor_id<span class="pl-pds">"</span></span> } ] }, <span class="pl-s"><span class="pl-pds">"</span>databases<span class="pl-pds">"</span></span>: { <span class="pl-s"><span class="pl-pds">"</span>mydatabase<span class="pl-pds">"</span></span>: { <span class="pl-s"><span class="pl-pds">"</span>queries<span class="pl-pds">"</span></span>: { <span class="pl-s"><span class="pl-pds">"</span>promote_to_staff<span class="pl-pds">"</span></span>: { <span class="pl-s"><span class="pl-pds">"</span>sql<span class="pl-pds">"</span></span>: <span class="pl-s"><span class="pl-pds">"</span>UPDATE users SET is is_staff=1 WHERE id=:id<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>write<span class="pl-pds">"</span></span>: <span class="pl-c1">true</span> } } } } }</pre></div> <p>The <code>"datasette-permissions-sql"</code> key is a list of rules. Each of those rules has the following shape:</p> <div class="highlight highlight-source-json position-relative" data-snippet-clipboard-copy-content="{ &quot;action&quot;: &quot;name-of-action&quot;, &quot;resource&quot;: [&quot;resource identifier to run this on&quot;], &quot;sql&quot;: &quot;SQL query to execute&quot;, &quot;database&quot;: &quot;mydatabase&quot; } "><pre>{ <span class="pl-s"><span class="pl-pds">"</span>action<span class="pl-pds">"</span></span>: <span class="pl-s"><span class="pl-pds">"</span>name-of-action<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>resource<span class="pl-pds">"</span></span>: [<span class="pl-s"><span class="pl-pds">"</span>resource identifier to run this on<span class="pl-pds">"</span></span>], <span class="pl-s"><span class="pl-pds">"</span>sql<span class="pl-pds">"</span></span>: <span class="pl-s"><span class="pl-pds">"</span>SQL query to execute<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>database<span class="pl-pds">"</span></span>: <span class="pl-s"><span class="pl-pds">"</span>mydatabase<span class="pl-pds">"</span></span> }</pre></div> <p>Both <code>"action"</code> and <code>"resource"</code> are optional. If present, the SQL query will only be executed on permission checks that match the action and, if present, the resource indicators.</p> <p><code>"database"</code> is also optional: it specifies the named database that the query should be executed against. If it is not present the first connected database will be used.</p> <p>The Datasette documentation includes a <a href="https://datasette.readthedocs.io/en/stable/authentication.html#built-in-permissions" rel="nofollow">list of built-in permissions</a> that you might want to use here.</p> <h3><a id="user-content-the-sql-query" class="anchor" aria-hidden="true" href="#user-content-the-sql-query"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a>The SQL query</h3> <p>If the SQL query returns any rows the action will be allowed. If it returns no rows, the plugin hook will return <code>False</code> and deny access to that action.</p> <p>The SQL query is called with a number of named parameters. You can use any of these as part of the query.</p> <p>The list of parameters is as follows:</p> <ul> <li><code>action</code> - the action, e.g. <code>"view-database"</code></li> <li><code>resource_1</code> - the first component of the resource, if one was passed</li> <li><code>resource_2</code> - the second component of the resource, if available</li> <li><code>actor_*</code> - a parameter for every key on the actor. Usually <code>actor_id</code> is present.</li> </ul> <p>If any rows are returned, the permission check passes. If no rows are returned the check fails.</p> <p>Another example table, this time granting explicit access to individual tables. Consider a table called <code>table_access</code> that looks like this:</p> <table> <thead> <tr> <th>user_id</th> <th>database</th> <th>table</th> </tr> </thead> <tbody> <tr> <td>1</td> <td>mydb</td> <td>dogs</td> </tr> <tr> <td>2</td> <td>mydb</td> <td>dogs</td> </tr> <tr> <td>1</td> <td>mydb</td> <td>cats</td> </tr> </tbody> </table> <p>The following SQL query would grant access to the <code>dogs</code> ttable in the <code>mydb.db</code> database to users 1 and 2 - but would forbid access for user 2 to the <code>cats</code> table:</p> <div class="highlight highlight-source-sql position-relative" data-snippet-clipboard-copy-content="SELECT * FROM table_access WHERE user_id = :actor_id AND &quot;database&quot; = :resource_1 AND &quot;table&quot; = :resource_2 "><pre><span class="pl-k">SELECT</span> <span class="pl-k">*</span> <span class="pl-k">FROM</span> table_access <span class="pl-k">WHERE</span> user_id <span class="pl-k">=</span> :actor_id <span class="pl-k">AND</span> <span class="pl-s"><span class="pl-pds">"</span>database<span class="pl-pds">"</span></span> <span class="pl-k">=</span> :resource_1 <span class="pl-k">AND</span> <span class="pl-s"><span class="pl-pds">"</span>table<span class="pl-pds">"</span></span> <span class="pl-k">=</span> :resource_2</pre></div> <p>In a <code>metadata.yaml</code> configuration file that would look like this:</p> <div class="highlight highlight-source-yaml position-relative" data-snippet-clipboard-copy-content="databases: mydb: allow_sql: {} plugins: datasette-permissions-sql: - action: view-table sql: |- SELECT * FROM table_access WHERE user_id = :actor_id AND &quot;database&quot; = :resource_1 AND &quot;table&quot; = :resource_2 "><pre><span class="pl-ent">databases</span>: <span class="pl-ent">mydb</span>: <span class="pl-ent">allow_sql</span>: <span class="pl-s">{}</span> <span class="pl-ent">plugins</span>: <span class="pl-ent">datasette-permissions-sql</span>: - <span class="pl-ent">action</span>: <span class="pl-s">view-table</span> <span class="pl-ent">sql</span>: <span class="pl-s">|-</span> <span class="pl-s"> SELECT</span> <span class="pl-s"> *</span> <span class="pl-s"> FROM</span> <span class="pl-s"> table_access</span> <span class="pl-s"> WHERE</span> <span class="pl-s"> user_id = :actor_id</span> <span class="pl-s"> AND "database" = :resource_1</span> <span class="pl-s"> AND "table" = :resource_2</span></pre></div> <p>We're using <code>allow_sql: {}</code> here to disable arbitrary SQL queries. This prevents users from running <code>select * from cats</code> directly to work around the permissions limits.</p> <h3><a id="user-content-fallback-mode" class="anchor" aria-hidden="true" href="#user-content-fallback-mode"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a>Fallback mode</h3> <p>The default behaviour of this plugin is to take full control of specified permissions. The SQL query will directly control if the user is allowed or denied access to the permission.</p> <p>This means that the default policy for each permission (which in Datasette core is "allow" for <code>view-database</code> and friends) will be ignored. It also means that any other <code>permission_allowed</code> plugins will not get their turn once this plugin has executed.</p> <p>You can change this on a per-rule basis using <code>"fallback": true</code>:</p> <div class="highlight highlight-source-json position-relative" data-snippet-clipboard-copy-content="{ &quot;action&quot;: &quot;view-table&quot;, &quot;resource&quot;: [&quot;mydatabase&quot;, &quot;mytable&quot;], &quot;sql&quot;: &quot;select * from admins where user_id = :actor_id&quot;, &quot;fallback&quot;: true } "><pre>{ <span class="pl-s"><span class="pl-pds">"</span>action<span class="pl-pds">"</span></span>: <span class="pl-s"><span class="pl-pds">"</span>view-table<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>resource<span class="pl-pds">"</span></span>: [<span class="pl-s"><span class="pl-pds">"</span>mydatabase<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>mytable<span class="pl-pds">"</span></span>], <span class="pl-s"><span class="pl-pds">"</span>sql<span class="pl-pds">"</span></span>: <span class="pl-s"><span class="pl-pds">"</span>select * from admins where user_id = :actor_id<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>fallback<span class="pl-pds">"</span></span>: <span class="pl-c1">true</span> }</pre></div> <p>When running in fallback mode, a query result returning no rows will cause the plugin hook to return <code>None</code> - which means "I have no opinion on this permission, fall back to other plugins or the default".</p> <p>In this mode you can still return <code>False</code> (for "deny access") by returning a single row with a single value of <code>-1</code>. For example:</p> <div class="highlight highlight-source-json position-relative" data-snippet-clipboard-copy-content="{ &quot;action&quot;: &quot;view-table&quot;, &quot;resource&quot;: [&quot;mydatabase&quot;, &quot;mytable&quot;], &quot;sql&quot;: &quot;select -1 from banned where user_id = :actor_id&quot;, &quot;fallback&quot;: true } "><pre>{ <span class="pl-s"><span class="pl-pds">"</span>action<span class="pl-pds">"</span></span>: <span class="pl-s"><span class="pl-pds">"</span>view-table<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>resource<span class="pl-pds">"</span></span>: [<span class="pl-s"><span class="pl-pds">"</span>mydatabase<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>mytable<span class="pl-pds">"</span></span>], <span class="pl-s"><span class="pl-pds">"</span>sql<span class="pl-pds">"</span></span>: <span class="pl-s"><span class="pl-pds">"</span>select -1 from banned where user_id = :actor_id<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>fallback<span class="pl-pds">"</span></span>: <span class="pl-c1">true</span> }</pre></div> </article></div>            

Links from other tables

  • 4 rows from repo in releases
Powered by Datasette · Queries took 1.308ms