html_url,issue_url,id,node_id,user,user_label,created_at,updated_at,author_association,body,reactions,issue,issue_label,performed_via_github_app https://github.com/simonw/datasette/pull/798#issuecomment-639249743,https://api.github.com/repos/simonw/datasette/issues/798,639249743,MDEyOklzc3VlQ29tbWVudDYzOTI0OTc0Mw==,9599,simonw,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,CSRF protection, https://github.com/simonw/datasette/pull/798#issuecomment-639269559,https://api.github.com/repos/simonw/datasette/issues/798,639269559,MDEyOklzc3VlQ29tbWVudDYzOTI2OTU1OQ==,9599,simonw,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,CSRF protection, https://github.com/simonw/datasette/pull/798#issuecomment-639269994,https://api.github.com/repos/simonw/datasette/issues/798,639269994,MDEyOklzc3VlQ29tbWVudDYzOTI2OTk5NA==,9599,simonw,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,CSRF protection, https://github.com/simonw/datasette/issues/799#issuecomment-639660667,https://api.github.com/repos/simonw/datasette/issues/799,639660667,MDEyOklzc3VlQ29tbWVudDYzOTY2MDY2Nw==,9599,simonw,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,TestResponse needs to handle multiple set-cookie headers, https://github.com/simonw/datasette/issues/799#issuecomment-639661014,https://api.github.com/repos/simonw/datasette/issues/799,639661014,MDEyOklzc3VlQ29tbWVudDYzOTY2MTAxNA==,9599,simonw,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,TestResponse needs to handle multiple set-cookie headers, https://github.com/simonw/datasette/pull/798#issuecomment-639685550,https://api.github.com/repos/simonw/datasette/issues/798,639685550,MDEyOklzc3VlQ29tbWVudDYzOTY4NTU1MA==,9599,simonw,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,CSRF protection, https://github.com/simonw/datasette/pull/798#issuecomment-639712835,https://api.github.com/repos/simonw/datasette/issues/798,639712835,MDEyOklzc3VlQ29tbWVudDYzOTcxMjgzNQ==,9599,simonw,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,CSRF protection, https://github.com/simonw/datasette/issues/698#issuecomment-639779403,https://api.github.com/repos/simonw/datasette/issues/698,639779403,MDEyOklzc3VlQ29tbWVudDYzOTc3OTQwMw==,9599,simonw,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,Ability for a canned query to write to the database, https://github.com/simonw/datasette/issues/698#issuecomment-639784651,https://api.github.com/repos/simonw/datasette/issues/698,639784651,MDEyOklzc3VlQ29tbWVudDYzOTc4NDY1MQ==,9599,simonw,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,Ability for a canned query to write to the database, https://github.com/simonw/datasette/issues/698#issuecomment-639785878,https://api.github.com/repos/simonw/datasette/issues/698,639785878,MDEyOklzc3VlQ29tbWVudDYzOTc4NTg3OA==,9599,simonw,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,Ability for a canned query to write to the database, https://github.com/simonw/datasette/issues/698#issuecomment-639787304,https://api.github.com/repos/simonw/datasette/issues/698,639787304,MDEyOklzc3VlQ29tbWVudDYzOTc4NzMwNA==,9599,simonw,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,Ability for a canned query to write to the database, https://github.com/simonw/datasette/issues/698#issuecomment-639788562,https://api.github.com/repos/simonw/datasette/issues/698,639788562,MDEyOklzc3VlQ29tbWVudDYzOTc4ODU2Mg==,9599,simonw,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,Ability for a canned query to write to the database, https://github.com/simonw/datasette/issues/800#issuecomment-639803099,https://api.github.com/repos/simonw/datasette/issues/800,639803099,MDEyOklzc3VlQ29tbWVudDYzOTgwMzA5OQ==,9599,simonw,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,Canned query permissions mechanism, https://github.com/simonw/datasette/issues/800#issuecomment-639803719,https://api.github.com/repos/simonw/datasette/issues/800,639803719,MDEyOklzc3VlQ29tbWVudDYzOTgwMzcxOQ==,9599,simonw,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,Canned query permissions mechanism, https://github.com/simonw/datasette/issues/802#issuecomment-639895450,https://api.github.com/repos/simonw/datasette/issues/802,639895450,MDEyOklzc3VlQ29tbWVudDYzOTg5NTQ1MA==,9599,simonw,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,"""datasette plugins"" command is broken",