html_url,issue_url,id,node_id,user,created_at,updated_at,author_association,body,reactions,issue,performed_via_github_app https://github.com/simonw/datasette/issues/813#issuecomment-640951947,https://api.github.com/repos/simonw/datasette/issues/813,640951947,MDEyOklzc3VlQ29tbWVudDY0MDk1MTk0Nw==,9599,2020-06-09T00:09:56Z,2020-06-09T00:09:56Z,OWNER,Documentation: https://datasette.readthedocs.io/en/latest/authentication.html#controlling-the-ability-to-execute-arbitrary-sql,"{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",634139848, https://github.com/simonw/datasette/issues/818#issuecomment-640929693,https://api.github.com/repos/simonw/datasette/issues/818,640929693,MDEyOklzc3VlQ29tbWVudDY0MDkyOTY5Mw==,9599,2020-06-08T22:56:38Z,2020-06-08T22:56:38Z,OWNER,https://datasette.readthedocs.io/en/latest/plugins.html#permission-allowed-datasette-actor-action-resource has a couple of examples now.,"{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",634917088, https://github.com/simonw/datasette/issues/777#issuecomment-640925018,https://api.github.com/repos/simonw/datasette/issues/777,640925018,MDEyOklzc3VlQ29tbWVudDY0MDkyNTAxOA==,9599,2020-06-08T22:41:42Z,2020-06-08T22:41:42Z,OWNER,This is particularly worth fixing now that 403 forbidden pages are much more likely due to #811.,"{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",626171242, https://github.com/simonw/datasette/issues/493#issuecomment-640924558,https://api.github.com/repos/simonw/datasette/issues/493,640924558,MDEyOklzc3VlQ29tbWVudDY0MDkyNDU1OA==,9599,2020-06-08T22:40:01Z,2020-06-08T22:40:01Z,OWNER,I'll also rename `--config` to `--setting`.,"{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",449886319, https://github.com/simonw/datasette/issues/493#issuecomment-640924482,https://api.github.com/repos/simonw/datasette/issues/493,640924482,MDEyOklzc3VlQ29tbWVudDY0MDkyNDQ4Mg==,9599,2020-06-08T22:39:45Z,2020-06-08T22:39:45Z,OWNER,"I'm definitely doing this rename, now that `metadata.json` is used for `allow` permissions configuration as well as-of #811.","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",449886319, https://github.com/simonw/datasette/issues/806#issuecomment-640916991,https://api.github.com/repos/simonw/datasette/issues/806,640916991,MDEyOklzc3VlQ29tbWVudDY0MDkxNjk5MQ==,9599,2020-06-08T22:18:45Z,2020-06-08T22:18:45Z,OWNER,Reminder for release notes: I removed `--config allow_sql:0` - see https://github.com/simonw/datasette/issues/813#issuecomment-640916807,"{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",632753851, https://github.com/simonw/datasette/issues/813#issuecomment-640916807,https://api.github.com/repos/simonw/datasette/issues/813,640916807,MDEyOklzc3VlQ29tbWVudDY0MDkxNjgwNw==,9599,2020-06-08T22:18:09Z,2020-06-08T22:18:09Z,OWNER,"I could retire the `--config allow_sql:0` option entirely, since the new `metadata.json` mechanism can be used to achieve the exact same thing. I'm going to do that.","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",634139848, https://github.com/simonw/datasette/issues/813#issuecomment-640916290,https://api.github.com/repos/simonw/datasette/issues/813,640916290,MDEyOklzc3VlQ29tbWVudDY0MDkxNjI5MA==,9599,2020-06-08T22:16:39Z,2020-06-08T22:17:32Z,OWNER,"Naming problem: Datasette already has a config option with this name: $ datasette serve data.db --config allow_sql:1 https://datasette.readthedocs.io/en/stable/config.html#allow-sql It's confusing to have two things called `allow_sql` that do slightly different things.","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",634139848, https://github.com/simonw/datasette/issues/801#issuecomment-640905609,https://api.github.com/repos/simonw/datasette/issues/801,640905609,MDEyOklzc3VlQ29tbWVudDY0MDkwNTYwOQ==,9599,2020-06-08T21:48:44Z,2020-06-08T21:48:44Z,OWNER,"Dropping this out of Datasette 0.44 again - I have enough other stuff to finish, this can wait.","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",631932926, https://github.com/simonw/datasette/issues/813#issuecomment-640837908,https://api.github.com/repos/simonw/datasette/issues/813,640837908,MDEyOklzc3VlQ29tbWVudDY0MDgzNzkwOA==,9599,2020-06-08T19:33:03Z,2020-06-08T19:33:03Z,OWNER,Don't forget to link to the `allow_sql` docs from the warning block here: https://github.com/simonw/datasette/blob/54370853828bdf87ca844fd0fc00900e0e2e659d/docs/authentication.rst#controlling-access-to-specific-tables-and-views,"{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",634139848, https://github.com/simonw/datasette/issues/813#issuecomment-640831842,https://api.github.com/repos/simonw/datasette/issues/813,640831842,MDEyOklzc3VlQ29tbWVudDY0MDgzMTg0Mg==,9599,2020-06-08T19:27:47Z,2020-06-08T19:27:47Z,OWNER,"This needs to be ready for Datasette 0.44 because without it the ""view-table"" permission is useless - it will protect the https://latest.datasette.io/fixtures/facetable page but will not prevent users from executing https://latest.datasette.io/fixtures?sql=select+*+from+facetable","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",634139848, https://github.com/simonw/datasette/issues/813#issuecomment-640830088,https://api.github.com/repos/simonw/datasette/issues/813,640830088,MDEyOklzc3VlQ29tbWVudDY0MDgzMDA4OA==,9599,2020-06-08T19:26:15Z,2020-06-08T19:26:15Z,OWNER,This needs to affect the `?_where=` parameter on table pages as well.,"{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",634139848, https://github.com/simonw/datasette/issues/816#issuecomment-640815550,https://api.github.com/repos/simonw/datasette/issues/816,640815550,MDEyOklzc3VlQ29tbWVudDY0MDgxNTU1MA==,9599,2020-06-08T19:06:44Z,2020-06-08T19:06:44Z,OWNER,https://github.com/simonw/datasette/blob/c7d145e016522dd6ee229d4d0b3ba79a7a8877c1/docs/plugins.rst#extra_template_varstemplate-database-table-view_name-request-datasette,"{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",634783573, https://github.com/simonw/datasette/issues/817#issuecomment-640808161,https://api.github.com/repos/simonw/datasette/issues/817,640808161,MDEyOklzc3VlQ29tbWVudDY0MDgwODE2MQ==,9599,2020-06-08T18:51:42Z,2020-06-08T18:54:37Z,OWNER,I'm also going to rename `resource_identifier` to just `resource`.,"{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",634844634, https://github.com/simonw/datasette/issues/816#issuecomment-640763899,https://api.github.com/repos/simonw/datasette/issues/816,640763899,MDEyOklzc3VlQ29tbWVudDY0MDc2Mzg5OQ==,9599,2020-06-08T17:21:59Z,2020-06-08T17:21:59Z,OWNER,I'm going to show how to display the current user's user-agent.,"{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",634783573, https://github.com/simonw/datasette/issues/815#issuecomment-640673405,https://api.github.com/repos/simonw/datasette/issues/815,640673405,MDEyOklzc3VlQ29tbWVudDY0MDY3MzQwNQ==,9599,2020-06-08T14:41:55Z,2020-06-08T14:41:55Z,OWNER,"I want to be able to display the HTTP path and verb - `GET /fixtures`, `POST /fixtures/myquery` etc. ","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",634663505, https://github.com/simonw/datasette/issues/815#issuecomment-640673138,https://api.github.com/repos/simonw/datasette/issues/815,640673138,MDEyOklzc3VlQ29tbWVudDY0MDY3MzEzOA==,9599,2020-06-08T14:41:24Z,2020-06-08T14:41:24Z,OWNER,I could reuse that `get_task_id()` function though (I can move it to utils).,"{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",634663505, https://github.com/simonw/datasette/issues/815#issuecomment-640672540,https://api.github.com/repos/simonw/datasette/issues/815,640672540,MDEyOklzc3VlQ29tbWVudDY0MDY3MjU0MA==,9599,2020-06-08T14:40:22Z,2020-06-08T14:40:22Z,OWNER,"Here's the current tracer mechanism. Note that it captures a stacktrace (which is expensive) - but only if the tracer system has been enabled for a request. https://github.com/simonw/datasette/blob/1c063fae9dba70f70244db010d55a18846640f07/datasette/tracer.py#L27-L51 For permissions checks I want to ALWAYS track those calls, not just on requests that have opted in.","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",634663505, https://github.com/simonw/datasette/issues/815#issuecomment-640671398,https://api.github.com/repos/simonw/datasette/issues/815,640671398,MDEyOklzc3VlQ29tbWVudDY0MDY3MTM5OA==,9599,2020-06-08T14:38:20Z,2020-06-08T14:38:20Z,OWNER,But `ds._permission_checks` is also used for unit tests.,"{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",634663505, https://github.com/simonw/datasette/issues/815#issuecomment-640671241,https://api.github.com/repos/simonw/datasette/issues/815,640671241,MDEyOklzc3VlQ29tbWVudDY0MDY3MTI0MQ==,9599,2020-06-08T14:38:04Z,2020-06-08T14:38:04Z,OWNER,"Alternative to a correlation ID would be to use the existing `AsgiTracer` / `capture_traces` mechanism. That's probably smarter. It could even start logging SQL queries to an in-memory deque too, so a debug tool could show you queries executed by other requests!","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",634663505, https://github.com/simonw/datasette/issues/815#issuecomment-640656143,https://api.github.com/repos/simonw/datasette/issues/815,640656143,MDEyOklzc3VlQ29tbWVudDY0MDY1NjE0Mw==,9599,2020-06-08T14:25:48Z,2020-06-08T14:26:45Z,OWNER,Will we need a request correlation ID for this? Multiple asyncio threads can write things to the `ds._permission_checks` deque at the same time.,"{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",634663505, https://github.com/simonw/datasette/issues/814#issuecomment-640638057,https://api.github.com/repos/simonw/datasette/issues/814,640638057,MDEyOklzc3VlQ29tbWVudDY0MDYzODA1Nw==,9599,2020-06-08T14:11:51Z,2020-06-08T14:12:12Z,OWNER,"The only impact it has at all is on this code here: https://github.com/simonw/datasette/blob/cc218fa9be55842656d030545c308392e3736053/datasette/views/base.py#L515-L527 That `ds.cache_headers` property looks like it needs rethinking too.","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",634651079, https://github.com/simonw/datasette/issues/811#issuecomment-640362879,https://api.github.com/repos/simonw/datasette/issues/811,640362879,MDEyOklzc3VlQ29tbWVudDY0MDM2Mjg3OQ==,9599,2020-06-08T04:42:28Z,2020-06-08T13:39:46Z,OWNER,"I'm finding myself repeating this pattern a lot: ```python for table in table_counts: allowed = await self.ds.permission_allowed( request.scope.get(""actor""), ""view-table"", resource_type=""table"", resource_identifier=(database, table), default=True, ) if not allowed: continue private = not await self.ds.permission_allowed( None, ""view-table"", resource_type=""table"", resource_identifier=(database, table), ) ``` I use a similar pattern for lists of databases and lists of queries, and I'll be doing the same thing for lists of SQL views too. An abstraction around this would be useful. Idea: ```python visible, private = await check_visibility( self.ds, actor, ""view-table"", ""table"", (database, table) ) ```","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",633578769, https://github.com/simonw/datasette/issues/811#issuecomment-640367128,https://api.github.com/repos/simonw/datasette/issues/811,640367128,MDEyOklzc3VlQ29tbWVudDY0MDM2NzEyOA==,9599,2020-06-08T05:00:13Z,2020-06-08T05:00:49Z,OWNER,"Should the padlock show up on tables that are private only because they inherited their privacy from their parent database or even the parent instance? Interesting question. If an instance is private, I'm not sure it makes sense to show padlocks on absolutely everything. Likewise, a list of tables shown on the database table with a padlock next to every single table (when the database itself is private) doesn't seem to add any useful information. I think ""Show 🔒 in header on private database page"" will resolve this for me. I'll always show the padlock in the header of a database/table page even if that privacy is inherited - but I won't do that for padlocks shown in the list of tables or list of databases.","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",633578769, https://github.com/simonw/datasette/issues/811#issuecomment-640365512,https://api.github.com/repos/simonw/datasette/issues/811,640365512,MDEyOklzc3VlQ29tbWVudDY0MDM2NTUxMg==,9599,2020-06-08T04:53:49Z,2020-06-08T04:53:49Z,OWNER,"I really like the padlocks. I should include a screenshot in the documentation that illustrates them. Maybe I should figure out a way to have the https://latest.datasette.io/ demo illustrate both a logged-in and a logged-out state.","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",633578769, https://github.com/simonw/datasette/issues/811#issuecomment-640348785,https://api.github.com/repos/simonw/datasette/issues/811,640348785,MDEyOklzc3VlQ29tbWVudDY0MDM0ODc4NQ==,9599,2020-06-08T03:51:50Z,2020-06-08T03:51:50Z,OWNER,"New convention: the 🔒 icon is now shown next to resources that are private - that are visible to you now, but would not be visible to the anonymous user. ","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",633578769, https://github.com/simonw/datasette/issues/811#issuecomment-640345115,https://api.github.com/repos/simonw/datasette/issues/811,640345115,MDEyOklzc3VlQ29tbWVudDY0MDM0NTExNQ==,9599,2020-06-08T03:37:33Z,2020-06-08T03:37:33Z,OWNER,Per-table permissions is pretty interesting for large installations though - an organization might have hundreds of CSV files imported into Datasette and then allow users to specify which exact users within that organization are allowed to see which CSV.,"{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",633578769, https://github.com/simonw/datasette/issues/811#issuecomment-640344950,https://api.github.com/repos/simonw/datasette/issues/811,640344950,MDEyOklzc3VlQ29tbWVudDY0MDM0NDk1MA==,9599,2020-06-08T03:36:49Z,2020-06-08T03:36:49Z,OWNER,"Oh this is a bit awkward - should I be running per-table permission checks for every table that might be shown on the index page? ","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",633578769, https://github.com/simonw/datasette/issues/801#issuecomment-640339828,https://api.github.com/repos/simonw/datasette/issues/801,640339828,MDEyOklzc3VlQ29tbWVudDY0MDMzOTgyOA==,9599,2020-06-08T03:18:47Z,2020-06-08T03:18:47Z,OWNER,"Example. This will only allow users to access the `fixtures` database if the logged-in actor's ID value appears for a record in the `users` table which has `admin` = 1. ```json { ""databases"": { ""fixtures"": { ""allow_by_query"": ""select * from users where id = :id and admin = 1"" } } } ```","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",631932926, https://github.com/simonw/datasette/issues/811#issuecomment-640339674,https://api.github.com/repos/simonw/datasette/issues/811,640339674,MDEyOklzc3VlQ29tbWVudDY0MDMzOTY3NA==,9599,2020-06-08T03:18:15Z,2020-06-08T03:18:15Z,OWNER,I should take these permissions into account when displaying a list of tables or a list of databases (like I do right now when displaying a list of queries).,"{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",633578769, https://github.com/simonw/datasette/issues/801#issuecomment-640339117,https://api.github.com/repos/simonw/datasette/issues/801,640339117,MDEyOklzc3VlQ29tbWVudDY0MDMzOTExNw==,9599,2020-06-08T03:16:16Z,2020-06-08T03:16:16Z,OWNER,"I'm going to call this key `""allow_by_query""` - I think I need `allow_sql` for something else (for configuring if users are allowed to execute arbitrary SQL queries).","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",631932926, https://github.com/simonw/datasette/issues/811#issuecomment-640338347,https://api.github.com/repos/simonw/datasette/issues/811,640338347,MDEyOklzc3VlQ29tbWVudDY0MDMzODM0Nw==,9599,2020-06-08T03:13:23Z,2020-06-08T03:13:23Z,OWNER,Do row-level permissions even make sense? Might be a good idea to remove those until I have a good use-case for them.,"{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",633578769, https://github.com/simonw/datasette/issues/811#issuecomment-640338151,https://api.github.com/repos/simonw/datasette/issues/811,640338151,MDEyOklzc3VlQ29tbWVudDY0MDMzODE1MQ==,9599,2020-06-08T03:12:41Z,2020-06-08T03:12:41Z,OWNER,"Also need to expand the docs on https://datasette.readthedocs.io/en/latest/authentication.html to explain where you can put `allow` blocks to control access to the instance, database or table.","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",633578769, https://github.com/simonw/datasette/issues/811#issuecomment-640337951,https://api.github.com/repos/simonw/datasette/issues/811,640337951,MDEyOklzc3VlQ29tbWVudDY0MDMzNzk1MQ==,9599,2020-06-08T03:11:58Z,2020-06-08T03:11:58Z,OWNER,"I'd like to be able to apply permissions for the ability to run a SQL query - but I'm not sure where the best place for that `""allow""` block to live would be.","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",633578769, https://github.com/simonw/datasette/issues/811#issuecomment-640287967,https://api.github.com/repos/simonw/datasette/issues/811,640287967,MDEyOklzc3VlQ29tbWVudDY0MDI4Nzk2Nw==,9599,2020-06-07T22:16:10Z,2020-06-07T22:16:10Z,OWNER,The tests in test_permissions.py could check the .json variants and assert that permission checks were carried out too.,"{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",633578769, https://github.com/simonw/datasette/issues/395#issuecomment-640280741,https://api.github.com/repos/simonw/datasette/issues/395,640280741,MDEyOklzc3VlQ29tbWVudDY0MDI4MDc0MQ==,9599,2020-06-07T21:12:57Z,2020-06-07T21:12:57Z,OWNER,"This is a pattern I like: ```python with make_app_client( template_dir=str(pathlib.Path(__file__).parent / ""test_templates"") ) as client: response = client.get(""/-/metadata"") assert response.status == 200 ```","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",396215043, https://github.com/simonw/datasette/issues/801#issuecomment-640277775,https://api.github.com/repos/simonw/datasette/issues/801,640277775,MDEyOklzc3VlQ29tbWVudDY0MDI3Nzc3NQ==,9599,2020-06-07T20:49:40Z,2020-06-07T20:49:40Z,OWNER,"I'm going to pass the entire actor object as a dictionary of available named query parameters. So if the actor looks like this: ```json { ""id"": ""simonw"", ""roles"": [""staff"", ""developer""] } ``` Then the SQL query will be called like this: ```python conn.execute(sql, { ""id"": ""simonw"", ""roles: '[""staff"", ""developer""]', }) ```","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",631932926, https://github.com/simonw/datasette/issues/801#issuecomment-640277557,https://api.github.com/repos/simonw/datasette/issues/801,640277557,MDEyOklzc3VlQ29tbWVudDY0MDI3NzU1Nw==,9599,2020-06-07T20:48:00Z,2020-06-07T20:48:00Z,OWNER,"Now that I'm expanding permission checks to everything else too (#811), not just canned queries, I think it makes sense to re-prioritize this.","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",631932926, https://github.com/simonw/datasette/issues/811#issuecomment-640274171,https://api.github.com/repos/simonw/datasette/issues/811,640274171,MDEyOklzc3VlQ29tbWVudDY0MDI3NDE3MQ==,9599,2020-06-07T20:21:14Z,2020-06-07T20:21:14Z,OWNER,"Next step: fix this ``` - # TODO: fix this to use that permission check - if not actor_matches_allow( - request.scope.get(""actor"", None), metadata.get(""allow"") - ): - return Response(""Permission denied"", status=403) ```","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",633578769, https://github.com/simonw/datasette/issues/811#issuecomment-640273945,https://api.github.com/repos/simonw/datasette/issues/811,640273945,MDEyOklzc3VlQ29tbWVudDY0MDI3Mzk0NQ==,9599,2020-06-07T20:19:15Z,2020-06-07T20:19:15Z,OWNER,I'm going to add a `test_permissions.py` module that checks for 403 errors against different patterns of the `actors` block at different levels in `metadata.json`.,"{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",633578769, https://github.com/simonw/datasette/issues/811#issuecomment-640270178,https://api.github.com/repos/simonw/datasette/issues/811,640270178,MDEyOklzc3VlQ29tbWVudDY0MDI3MDE3OA==,9599,2020-06-07T19:48:39Z,2020-06-07T19:48:39Z,OWNER,"Testing pattern: ```python def test_canned_query_with_custom_metadata(app_client): response = app_client.get(""/fixtures/neighborhood_search?text=town"") assert_permissions_checked( app_client.ds, [ ""view-instance"", (""view-database"", ""database"", ""fixtures""), (""view-query"", ""query"", (""fixtures"", ""neighborhood_search"")), ], ) ``` ","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",633578769, https://github.com/simonw/datasette/issues/811#issuecomment-640248972,https://api.github.com/repos/simonw/datasette/issues/811,640248972,MDEyOklzc3VlQ29tbWVudDY0MDI0ODk3Mg==,9599,2020-06-07T17:04:22Z,2020-06-07T17:04:22Z,OWNER,I'll need a neat testing pattern for this.,"{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",633578769, https://github.com/simonw/datasette/issues/810#issuecomment-640248864,https://api.github.com/repos/simonw/datasette/issues/810,640248864,MDEyOklzc3VlQ29tbWVudDY0MDI0ODg2NA==,9599,2020-06-07T17:03:15Z,2020-06-07T17:03:15Z,OWNER,This is obsoleted by #811.,"{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",633066114, https://github.com/simonw/datasette/issues/811#issuecomment-640248669,https://api.github.com/repos/simonw/datasette/issues/811,640248669,MDEyOklzc3VlQ29tbWVudDY0MDI0ODY2OQ==,9599,2020-06-07T17:01:44Z,2020-06-07T17:01:44Z,OWNER,"If the allow block at the database level forbids access this needs to cascade down to the table, query and row levels as well.","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",633578769, https://github.com/simonw/datasette/issues/215#issuecomment-640121917,https://api.github.com/repos/simonw/datasette/issues/215,640121917,MDEyOklzc3VlQ29tbWVudDY0MDEyMTkxNw==,9599,2020-06-06T21:42:58Z,2020-06-07T05:58:36Z,OWNER,"I might use some dependency injection here, with `call_with_supported_arguments()` from https://github.com/simonw/datasette/commit/41a0cd7b6afe0397efbbf27ad822679fc574811a#diff-942305c83055fdc0ff5f4e7d6ab06b29 Maybe a view function can take `request` and optionally also take `datasette`? Or `scope` or `receive` or `send`.","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",314506669, https://github.com/simonw/datasette/issues/800#issuecomment-640160487,https://api.github.com/repos/simonw/datasette/issues/800,640160487,MDEyOklzc3VlQ29tbWVudDY0MDE2MDQ4Nw==,9599,2020-06-07T05:34:07Z,2020-06-07T05:34:07Z,OWNER,See #810 for work to finish this.,"{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",631931408, https://github.com/simonw/datasette/issues/808#issuecomment-640157216,https://api.github.com/repos/simonw/datasette/issues/808,640157216,MDEyOklzc3VlQ29tbWVudDY0MDE1NzIxNg==,9599,2020-06-07T04:58:40Z,2020-06-07T04:58:40Z,OWNER,... and I want a unit test which confirms that all permissions are documented.,"{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",632918799, https://github.com/simonw/datasette/issues/808#issuecomment-640152036,https://api.github.com/repos/simonw/datasette/issues/808,640152036,MDEyOklzc3VlQ29tbWVudDY0MDE1MjAzNg==,9599,2020-06-07T03:38:07Z,2020-06-07T03:38:07Z,OWNER,I'm going to need to add permissions documentation for this.,"{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",632918799, https://github.com/simonw/datasette/issues/807#issuecomment-640135332,https://api.github.com/repos/simonw/datasette/issues/807,640135332,MDEyOklzc3VlQ29tbWVudDY0MDEzNTMzMg==,9599,2020-06-07T00:13:51Z,2020-06-07T00:13:51Z,OWNER,"These should not be shipped as the latest version on Docker Hub. They also should not become the ""stable"" release on ReadTheDocs.","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",632843030, https://github.com/simonw/datasette/issues/800#issuecomment-640123488,https://api.github.com/repos/simonw/datasette/issues/800,640123488,MDEyOklzc3VlQ29tbWVudDY0MDEyMzQ4OA==,9599,2020-06-06T21:59:14Z,2020-06-06T21:59:14Z,OWNER,I didn't build this quite right: it should be using the permissions plugin hook.,"{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",631931408, https://github.com/simonw/datasette/issues/805#issuecomment-640122664,https://api.github.com/repos/simonw/datasette/issues/805,640122664,MDEyOklzc3VlQ29tbWVudDY0MDEyMjY2NA==,9599,2020-06-06T21:50:41Z,2020-06-06T21:50:41Z,OWNER,Part of #806 ,"{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",632724154, https://github.com/simonw/datasette/issues/215#issuecomment-504881900,https://api.github.com/repos/simonw/datasette/issues/215,504881900,MDEyOklzc3VlQ29tbWVudDUwNDg4MTkwMA==,9599,2019-06-24T06:51:29Z,2020-06-06T21:47:11Z,OWNER,See also #520 - asgi_wrapper plugin hook.,"{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",314506669, https://github.com/simonw/datasette/issues/215#issuecomment-398826108,https://api.github.com/repos/simonw/datasette/issues/215,398826108,MDEyOklzc3VlQ29tbWVudDM5ODgyNjEwOA==,9599,2018-06-20T17:09:18Z,2020-06-06T21:46:51Z,OWNER,This depends on #272 - Datasette ported to ASGI.,"{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",314506669, https://github.com/simonw/datasette/issues/215#issuecomment-640122120,https://api.github.com/repos/simonw/datasette/issues/215,640122120,MDEyOklzc3VlQ29tbWVudDY0MDEyMjEyMA==,9599,2020-06-06T21:45:13Z,2020-06-06T21:45:52Z,OWNER,"Stretch goal: make it easy for plugin views to implement formats, so they can produce HTML by default and .json or .csv etc as alternative outputs.","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",314506669, https://github.com/simonw/datasette/issues/215#issuecomment-640121036,https://api.github.com/repos/simonw/datasette/issues/215,640121036,MDEyOklzc3VlQ29tbWVudDY0MDEyMTAzNg==,9599,2020-06-06T21:34:03Z,2020-06-06T21:34:03Z,OWNER,"I'll refactor existing code to register views using the same mechanism that plugins will have access to. Maybe plugins get to register their routes first? That would allow plugins to do things like entirely take over the / page.","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",314506669, https://github.com/simonw/datasette/issues/215#issuecomment-640119259,https://api.github.com/repos/simonw/datasette/issues/215,640119259,MDEyOklzc3VlQ29tbWVudDY0MDExOTI1OQ==,9599,2020-06-06T21:16:46Z,2020-06-06T21:16:46Z,OWNER,"I deprioritised this a while ago because the asgi_wrapper hook allowed me to set up new URL routes: https://datasette.readthedocs.io/en/0.43/plugins.html#asgi-wrapper-datasette But... those were pretty low level, for example this code here: https://github.com/simonw/datasette-auth-github/blob/6c971064f6f4e6857bade5c6b88842f9cdeca9d9/datasette_auth_github/github_auth.py#L104-L113 Now that Datasette has a documented request object #706 and that object is used by things like the flash messages system (#790) - https://datasette.readthedocs.io/en/latest/internals.html#add-message-request-message-message-type-datasette-info - I find myself wanting to add views which get a request, as opposed to an ASGI scope. So I'm re-prioritising this, with the main need being a way for plugins to hook up their own view functions that can accept a request and return a response. ","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",314506669, https://github.com/simonw/datasette/issues/215#issuecomment-640118802,https://api.github.com/repos/simonw/datasette/issues/215,640118802,MDEyOklzc3VlQ29tbWVudDY0MDExODgwMg==,9599,2020-06-06T21:12:41Z,2020-06-06T21:12:41Z,OWNER,@clausjuhl your use-case there is now covered by custom pages from Datasette 0.41 https://datasette.readthedocs.io/en/stable/changelog.html#v0-41,"{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",314506669, https://github.com/simonw/datasette/issues/805#issuecomment-640116970,https://api.github.com/repos/simonw/datasette/issues/805,640116970,MDEyOklzc3VlQ29tbWVudDY0MDExNjk3MA==,9599,2020-06-06T20:55:03Z,2020-06-06T20:55:03Z,OWNER,"Would be useful if I had a plugin that could authenticate users based on a secret environment variable (maybe for a password) - that way I could have an ""admin"" account on the Glitch app that is allowed to setup new polls, while anonymous users can only vote on them.","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",632724154, https://github.com/simonw/datasette/issues/805#issuecomment-640116842,https://api.github.com/repos/simonw/datasette/issues/805,640116842,MDEyOklzc3VlQ29tbWVudDY0MDExNjg0Mg==,9599,2020-06-06T20:53:51Z,2020-06-06T20:53:51Z,OWNER,"I'd like to illustrate writable canned queries without the risk of someone abusing and breaking it (or filling it with bad content). I don't want to have to monitor it, so an application that won't run out of disk space after a few months would be good too. Maybe a polling app? If I'm only tracking integer numbers of votes it shouldn't ever run out of space.","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",632724154, https://github.com/simonw/datasette/issues/791#issuecomment-640116494,https://api.github.com/repos/simonw/datasette/issues/791,640116494,MDEyOklzc3VlQ29tbWVudDY0MDExNjQ5NA==,9599,2020-06-06T20:50:41Z,2020-06-06T20:50:41Z,OWNER,"I have a better idea: a feed reader! You can insert URLs to feeds, then have a command which fetches the latest entries from them into a separate table. Then implement favorites as a canned query, let you search your favorites, etc.","{""total_count"": 1, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 1, ""rocket"": 0, ""eyes"": 0}",628572716, https://github.com/simonw/datasette/issues/787#issuecomment-640111383,https://api.github.com/repos/simonw/datasette/issues/787,640111383,MDEyOklzc3VlQ29tbWVudDY0MDExMTM4Mw==,9599,2020-06-06T20:04:20Z,2020-06-06T20:04:20Z,OWNER,"I should let people running the 'publish' command set this explicitly if they want to, so they can re-deploy a published Datasette without invalidating every user's cookies.","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",628089318, https://github.com/simonw/datasette/issues/698#issuecomment-640108942,https://api.github.com/repos/simonw/datasette/issues/698,640108942,MDEyOklzc3VlQ29tbWVudDY0MDEwODk0Mg==,9599,2020-06-06T19:43:48Z,2020-06-06T19:43:48Z,OWNER,"Landed - documentation is here: https://datasette.readthedocs.io/en/latest/sql_queries.html#writable-canned-queries See also https://datasette.readthedocs.io/en/latest/authentication.html#permissions-for-canned-queries","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",582517965, https://github.com/simonw/datasette/issues/800#issuecomment-640108835,https://api.github.com/repos/simonw/datasette/issues/800,640108835,MDEyOklzc3VlQ29tbWVudDY0MDEwODgzNQ==,9599,2020-06-06T19:42:46Z,2020-06-06T19:42:46Z,OWNER,This is implemented and documented: https://datasette.readthedocs.io/en/latest/authentication.html,"{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",631931408, https://github.com/simonw/datasette/issues/699#issuecomment-640108763,https://api.github.com/repos/simonw/datasette/issues/699,640108763,MDEyOklzc3VlQ29tbWVudDY0MDEwODc2Mw==,9599,2020-06-06T19:42:11Z,2020-06-06T19:42:11Z,OWNER,I landed canned query writes. This feature can now be considered complete: https://datasette.readthedocs.io/en/latest/authentication.html,"{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",582526961, https://github.com/simonw/datasette/issues/699#issuecomment-640106668,https://api.github.com/repos/simonw/datasette/issues/699,640106668,MDEyOklzc3VlQ29tbWVudDY0MDEwNjY2OA==,9599,2020-06-06T19:22:36Z,2020-06-06T19:22:36Z,OWNER,The canned queries feature is gaining permissions support in #800.,"{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",582526961, https://github.com/simonw/datasette/issues/804#issuecomment-640106569,https://api.github.com/repos/simonw/datasette/issues/804,640106569,MDEyOklzc3VlQ29tbWVudDY0MDEwNjU2OQ==,9599,2020-06-06T19:21:41Z,2020-06-06T19:21:41Z,OWNER,I don't think this is fully documented either. Current partial documentation is on https://datasette.readthedocs.io/en/stable/contributing.html,"{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",632673972, https://github.com/simonw/datasette/issues/804#issuecomment-640106342,https://api.github.com/repos/simonw/datasette/issues/804,640106342,MDEyOklzc3VlQ29tbWVudDY0MDEwNjM0Mg==,9599,2020-06-06T19:19:33Z,2020-06-06T19:19:33Z,OWNER,I should replace the bodged-together argument passing with Click while I'm fixing this.,"{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",632673972, https://github.com/simonw/datasette/issues/804#issuecomment-640106202,https://api.github.com/repos/simonw/datasette/issues/804,640106202,MDEyOklzc3VlQ29tbWVudDY0MDEwNjIwMg==,9599,2020-06-06T19:18:23Z,2020-06-06T19:18:43Z,OWNER,"I broke this in #775 https://github.com/simonw/datasette/commit/446e5de65d1b9c6c877e38b0ef13bc9285c465a1 Here's the now-broken code (I removed the `PLUGIN1` and `PLUGIN2` constants): https://github.com/simonw/datasette/blob/9c563d6aed072f14d3d25f58e84659f9caa1a243/tests/fixtures.py#L828-L835","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",632673972, https://github.com/simonw/datasette/issues/800#issuecomment-640103204,https://api.github.com/repos/simonw/datasette/issues/800,640103204,MDEyOklzc3VlQ29tbWVudDY0MDEwMzIwNA==,9599,2020-06-06T18:52:56Z,2020-06-06T18:52:56Z,OWNER,"I'm also going to add an indicator to the UI next to queries that you can only execute because you are signed in: ","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",631931408, https://github.com/simonw/datasette/issues/800#issuecomment-640102200,https://api.github.com/repos/simonw/datasette/issues/800,640102200,MDEyOklzc3VlQ29tbWVudDY0MDEwMjIwMA==,9599,2020-06-06T18:45:11Z,2020-06-06T18:45:11Z,OWNER,"In the code that's: https://github.com/simonw/datasette/blob/9c563d6aed072f14d3d25f58e84659f9caa1a243/datasette/views/database.py#L56-L64 And: https://github.com/simonw/datasette/blob/9c563d6aed072f14d3d25f58e84659f9caa1a243/datasette/views/database.py#L98-L112 ","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",631931408, https://github.com/simonw/datasette/issues/800#issuecomment-640101762,https://api.github.com/repos/simonw/datasette/issues/800,640101762,MDEyOklzc3VlQ29tbWVudDY0MDEwMTc2Mg==,9599,2020-06-06T18:41:20Z,2020-06-06T18:41:20Z,OWNER,Now the actual permission checks. I need these in two places: the code that generates the list of available queries on https://latest.datasette.io/fixtures#queries and the query page itself at https://latest.datasette.io/fixtures/pragma_cache_size,"{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",631931408, https://github.com/simonw/datasette/issues/800#issuecomment-640101625,https://api.github.com/repos/simonw/datasette/issues/800,640101625,MDEyOklzc3VlQ29tbWVudDY0MDEwMTYyNQ==,9599,2020-06-06T18:40:09Z,2020-06-06T18:40:09Z,OWNER,Documentation for `actor_matches_allow`: https://github.com/simonw/datasette/blob/14f6b4d200f24940a795ddc0825319ab2891bde2/docs/authentication.rst#actor_matches_allow,"{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",631931408, https://github.com/simonw/datasette/issues/800#issuecomment-640099707,https://api.github.com/repos/simonw/datasette/issues/800,640099707,MDEyOklzc3VlQ29tbWVudDY0MDA5OTcwNw==,9599,2020-06-06T18:24:54Z,2020-06-06T18:24:54Z,OWNER,Next step: a utility function and tests for matching actors to allow blocks.,"{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",631931408, https://github.com/simonw/datasette/issues/800#issuecomment-640099404,https://api.github.com/repos/simonw/datasette/issues/800,640099404,MDEyOklzc3VlQ29tbWVudDY0MDA5OTQwNA==,9599,2020-06-06T18:22:10Z,2020-06-06T18:24:26Z,OWNER,Docs here: https://github.com/simonw/datasette/blob/d4c7b85f556230923d37ff327a068ed08aa9b62b/docs/authentication.rst#setting-permissions-for-canned-queries,"{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",631931408, https://github.com/simonw/datasette/issues/800#issuecomment-640099434,https://api.github.com/repos/simonw/datasette/issues/800,640099434,MDEyOklzc3VlQ29tbWVudDY0MDA5OTQzNA==,9599,2020-06-06T18:22:29Z,2020-06-06T18:22:29Z,OWNER,I should add the '*' bit to the docs.,"{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",631931408, https://github.com/simonw/datasette/issues/786#issuecomment-640099333,https://api.github.com/repos/simonw/datasette/issues/786,640099333,MDEyOklzc3VlQ29tbWVudDY0MDA5OTMzMw==,9599,2020-06-06T18:21:36Z,2020-06-06T18:21:36Z,OWNER,"This is done but currently lives in a branch, will close this issue when that branch lands: Implemented in this branch: https://github.com/simonw/datasette/blob/30a8132d58a89fed0e034e058b62fab5180fae0f/docs/authentication.rst","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",628087971, https://github.com/simonw/datasette/issues/800#issuecomment-640090575,https://api.github.com/repos/simonw/datasette/issues/800,640090575,MDEyOklzc3VlQ29tbWVudDY0MDA5MDU3NQ==,9599,2020-06-06T17:06:28Z,2020-06-06T17:06:28Z,OWNER,I'm going to implement this documentation-first.,"{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",631931408, https://github.com/simonw/datasette/issues/800#issuecomment-640090343,https://api.github.com/repos/simonw/datasette/issues/800,640090343,MDEyOklzc3VlQ29tbWVudDY0MDA5MDM0Mw==,9599,2020-06-06T17:04:36Z,2020-06-06T17:04:36Z,OWNER,I like this mechanism better than the SQL query one. Constructing SQL queries that return true if a particular string is embedded inside a JSON list in a larger object is decidedly non-trivial.,"{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",631931408, https://github.com/simonw/datasette/issues/802#issuecomment-639895450,https://api.github.com/repos/simonw/datasette/issues/802,639895450,MDEyOklzc3VlQ29tbWVudDYzOTg5NTQ1MA==,9599,2020-06-05T23:33:52Z,2020-06-05T23:33:52Z,OWNER,"https://github.com/simonw/datasette/blob/033a1bb22c70a955d9fd1d3b4675a0e2e5c8b8cd/datasette/cli.py#L126-L129 But I changed the `.plugins()` method to this: https://github.com/simonw/datasette/blob/033a1bb22c70a955d9fd1d3b4675a0e2e5c8b8cd/datasette/app.py#L628-L633","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",632056825, https://github.com/simonw/datasette/issues/800#issuecomment-639803719,https://api.github.com/repos/simonw/datasette/issues/800,639803719,MDEyOklzc3VlQ29tbWVudDYzOTgwMzcxOQ==,9599,2020-06-05T20:40:34Z,2020-06-05T20:40:34Z,OWNER,It's a bit obscure though. I'll try building both and see how they feel in practice.,"{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",631931408, https://github.com/simonw/datasette/issues/800#issuecomment-639803099,https://api.github.com/repos/simonw/datasette/issues/800,639803099,MDEyOklzc3VlQ29tbWVudDYzOTgwMzA5OQ==,9599,2020-06-05T20:39:34Z,2020-06-05T20:39:34Z,OWNER,"Maybe #801 (configuring permissions with a SQL query) is enough here - might not need this mechanism at all, since that mechanism covers it.","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",631931408, https://github.com/simonw/datasette/issues/698#issuecomment-639788562,https://api.github.com/repos/simonw/datasette/issues/698,639788562,MDEyOklzc3VlQ29tbWVudDYzOTc4ODU2Mg==,9599,2020-06-05T20:27:49Z,2020-06-05T20:27:49Z,OWNER,"There can be a detailed section explaining these different mechanisms on the authentication documentation page. I imagine they will end up applying to more than just canned queries.","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",582517965, https://github.com/simonw/datasette/issues/698#issuecomment-639787304,https://api.github.com/repos/simonw/datasette/issues/698,639787304,MDEyOklzc3VlQ29tbWVudDYzOTc4NzMwNA==,9599,2020-06-05T20:26:57Z,2020-06-05T20:26:57Z,OWNER,"Idea: an `""allow_sql""` key with a SQL query that gets passed the actor JSON as `:actor` and can extract the relevant keys from it and return 1 or 0.","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",582517965, https://github.com/simonw/datasette/issues/698#issuecomment-639785878,https://api.github.com/repos/simonw/datasette/issues/698,639785878,MDEyOklzc3VlQ29tbWVudDYzOTc4NTg3OA==,9599,2020-06-05T20:25:55Z,2020-06-05T20:25:55Z,OWNER,"I'd really like to support SQL query defined permissions too, mainly to set an example for how plugins could do something similar.","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",582517965, https://github.com/simonw/datasette/issues/698#issuecomment-639784651,https://api.github.com/repos/simonw/datasette/issues/698,639784651,MDEyOklzc3VlQ29tbWVudDYzOTc4NDY1MQ==,9599,2020-06-05T20:25:02Z,2020-06-05T20:25:02Z,OWNER,"Idea: default is anyone can execute a query. Or you can specify the following: ```json { ""databases"": { ""my-database"": { ""queries"": { ""add_twitter_handle"": { ""sql"": ""insert into twitter_handles (username) values (:username)"", ""write"": true, ""allow"": { ""id"": [""simon""], ""role"": [""staff""] } } } } } } ``` These get matched against the actor JSON. If any of the fields in any of the keys of `""allow""` match a key on the actor, the query is allowed. `""id"": ""*""` matches any actor with an `id` key.","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",582517965, https://github.com/simonw/datasette/issues/698#issuecomment-639779403,https://api.github.com/repos/simonw/datasette/issues/698,639779403,MDEyOklzc3VlQ29tbWVudDYzOTc3OTQwMw==,9599,2020-06-05T20:20:12Z,2020-06-05T20:20:12Z,OWNER,CSRF is done. Last step: figure out a smart way to integrate this with permissions and authentication.,"{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",582517965, https://github.com/simonw/datasette/pull/798#issuecomment-639712835,https://api.github.com/repos/simonw/datasette/issues/798,639712835,MDEyOklzc3VlQ29tbWVudDYzOTcxMjgzNQ==,9599,2020-06-05T18:53:32Z,2020-06-05T18:53:32Z,OWNER,Add unit tests illustrating the `Vary: Cookie` header and I'm done here.,"{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",631300342, https://github.com/simonw/datasette/pull/798#issuecomment-639685550,https://api.github.com/repos/simonw/datasette/issues/798,639685550,MDEyOklzc3VlQ29tbWVudDYzOTY4NTU1MA==,9599,2020-06-05T18:20:34Z,2020-06-05T18:20:34Z,OWNER,I'm solving the compatibility with caching problem in this ticket: https://github.com/simonw/asgi-csrf/issues/7,"{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",631300342, https://github.com/simonw/datasette/issues/799#issuecomment-639661014,https://api.github.com/repos/simonw/datasette/issues/799,639661014,MDEyOklzc3VlQ29tbWVudDYzOTY2MTAxNA==,9599,2020-06-05T17:43:41Z,2020-06-05T17:43:41Z,OWNER,I'm going to rename that `MultiParams` and use it in both places.,"{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",631789422, https://github.com/simonw/datasette/issues/799#issuecomment-639660667,https://api.github.com/repos/simonw/datasette/issues/799,639660667,MDEyOklzc3VlQ29tbWVudDYzOTY2MDY2Nw==,9599,2020-06-05T17:43:08Z,2020-06-05T17:43:08Z,OWNER,"This really needs a `MultiValueDict` ala Django: https://github.com/django/django/blob/24b82cd201e21060fbc02117dc16d1702877a1f3/django/utils/datastructures.py#L42 Turns out I have one of these in Datasette already - `RequestParameters` from https://github.com/simonw/datasette/commit/81be31322a968d23cf57cee62b58df55433385e3 The name isn't quite right though.","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",631789422, https://github.com/simonw/datasette/pull/798#issuecomment-639269994,https://api.github.com/repos/simonw/datasette/issues/798,639269994,MDEyOklzc3VlQ29tbWVudDYzOTI2OTk5NA==,9599,2020-06-05T05:36:35Z,2020-06-05T05:38:25Z,OWNER,"Django docs on CSRF and caching: https://docs.djangoproject.com/en/3.0/ref/csrf/#caching > If the csrf_token template tag is used by a template (or the get_token function is called some other way), CsrfViewMiddleware will add a cookie and a Vary: Cookie header to the response. This means that the middleware will play well with the cache middleware if it is used as instructed So the cookie is only set for pages that included a hidden csrftoken form field! This could work.","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",631300342, https://github.com/simonw/datasette/pull/798#issuecomment-639269559,https://api.github.com/repos/simonw/datasette/issues/798,639269559,MDEyOklzc3VlQ29tbWVudDYzOTI2OTU1OQ==,9599,2020-06-05T05:34:56Z,2020-06-05T05:35:23Z,OWNER,"I don't want to set a cookie on a page response that is being cached. Right now the ASGI middleware will be doing exactly that, which is bad. But how do I get certainty that when you load a page with a form that will be CSRF protected you have been served the cookie? Maybe those pages should do something explicit to the request object indicating that the cookie is needed? That works for Datasette (since it has mutable request objects) but I'm not sure how it would work in the asgi-csrf pure ASGI middleware context.","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",631300342, https://github.com/simonw/datasette/pull/798#issuecomment-639249743,https://api.github.com/repos/simonw/datasette/issues/798,639249743,MDEyOklzc3VlQ29tbWVudDYzOTI0OTc0Mw==,9599,2020-06-05T04:23:01Z,2020-06-05T04:23:01Z,OWNER,"Needs unit tests. More importantly: needs very, very careful consideration of how this plays with HTTP caching.","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",631300342, https://github.com/simonw/datasette/issues/684#issuecomment-639053707,https://api.github.com/repos/simonw/datasette/issues/684,639053707,MDEyOklzc3VlQ29tbWVudDYzOTA1MzcwNw==,9599,2020-06-04T18:56:15Z,2020-06-04T18:56:15Z,OWNER,This documentation is live here: https://datasette.readthedocs.io/en/latest/internals.html#database-introspection,"{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",570301333, https://github.com/simonw/datasette/issues/119#issuecomment-639047315,https://api.github.com/repos/simonw/datasette/issues/119,639047315,MDEyOklzc3VlQ29tbWVudDYzOTA0NzMxNQ==,9599,2020-06-04T18:46:39Z,2020-06-04T18:46:39Z,OWNER,"The OAuth dance needed for this is a pretty nasty barrier to plugin installation and configuration. I'm going to focus on making it easy to copy and paste data into sheets instead.","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",275082158, https://github.com/simonw/datasette/issues/793#issuecomment-638462052,https://api.github.com/repos/simonw/datasette/issues/793,638462052,MDEyOklzc3VlQ29tbWVudDYzODQ2MjA1Mg==,9599,2020-06-03T21:07:39Z,2020-06-03T21:07:39Z,OWNER,I need to land and release the fix for signing cookies in https://github.com/simonw/asgi-csrf/issues/2,"{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",629524205, https://github.com/simonw/datasette/issues/797#issuecomment-638461797,https://api.github.com/repos/simonw/datasette/issues/797,638461797,MDEyOklzc3VlQ29tbWVudDYzODQ2MTc5Nw==,9599,2020-06-03T21:07:06Z,2020-06-03T21:07:06Z,OWNER,"Docs here (search for ""params""): https://datasette.readthedocs.io/en/latest/sql_queries.html#canned-queries-named-parameters","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",630120235, https://github.com/simonw/datasette/issues/797#issuecomment-638289878,https://api.github.com/repos/simonw/datasette/issues/797,638289878,MDEyOklzc3VlQ29tbWVudDYzODI4OTg3OA==,9599,2020-06-03T15:57:47Z,2020-06-03T15:57:47Z,OWNER,Also mention ability to pre-fill the form for writable canned queries using the querystring.,"{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",630120235, https://github.com/simonw/datasette/issues/698#issuecomment-638266171,https://api.github.com/repos/simonw/datasette/issues/698,638266171,MDEyOklzc3VlQ29tbWVudDYzODI2NjE3MQ==,9599,2020-06-03T15:18:49Z,2020-06-03T15:18:49Z,OWNER,Landed the work so far from #796! Here's the documentation: https://datasette.readthedocs.io/en/latest/sql_queries.html#writable-canned-queries,"{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",582517965, https://github.com/simonw/datasette/issues/793#issuecomment-638265394,https://api.github.com/repos/simonw/datasette/issues/793,638265394,MDEyOklzc3VlQ29tbWVudDYzODI2NTM5NA==,9599,2020-06-03T15:17:35Z,2020-06-03T15:17:51Z,OWNER,I need this for writable canned queries in #698 and #796 too.,"{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",629524205, https://github.com/simonw/datasette/pull/796#issuecomment-638257697,https://api.github.com/repos/simonw/datasette/issues/796,638257697,MDEyOklzc3VlQ29tbWVudDYzODI1NzY5Nw==,9599,2020-06-03T15:05:07Z,2020-06-03T15:05:07Z,OWNER,"I'm going to document this, land it and then continue to work on the other pieces - CSRF protection and .json mode - in separate tickets.","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",629595228,