{"html_url": "https://github.com/simonw/datasette/issues/215#issuecomment-640960667", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/215", "id": 640960667, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MDk2MDY2Nw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-09T00:41:35Z", "updated_at": "2020-06-09T00:41:35Z", "author_association": "OWNER", "body": "I'm going to implement this one documentation-first in a pull request.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 314506669, "label": "Allow plugins to define additional URL routes and views"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/215#issuecomment-640960553", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/215", "id": 640960553, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MDk2MDU1Mw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-09T00:41:09Z", "updated_at": "2020-06-09T00:41:09Z", "author_association": "OWNER", "body": "I'm going to imitate `register_output_renderer` and `register_facet_classes` - both return a list of things to register.\r\n\r\nSo I'll do this:\r\n\r\n```python\r\n@hookspec\r\ndef register_routes():\r\n \"Register URL routes. Return a list of (regex, view_function) pairs\"\r\n```", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 314506669, "label": "Allow plugins to define additional URL routes and views"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/777#issuecomment-640957423", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/777", "id": 640957423, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MDk1NzQyMw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-09T00:29:03Z", "updated_at": "2020-06-09T00:29:03Z", "author_association": "OWNER", "body": "Here's why:\r\n\r\nhttps://github.com/simonw/datasette/blob/49d6d2f7b0f6cb02e25022e1c9403811f1fa0a7c/datasette/app.py#L1024-L1029\r\n\r\n404 errors are rendered by looking for a template from `[\"404.html\", \"500.html\"]`.\r\n\r\n`404.html` doesn't actually ship with Datasette (plugins or custom template directories can provide it). So the `500.html` template is used.\r\n\r\nThat template extends `base.html`, which expects there to be `base_url` and `app_css_hash` variables. But as you can see in the excerpt above, those variables are not being passed to the template context when the error page is rendered.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 626171242, "label": "Error pages not correctly loading CSS"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/777#issuecomment-640955788", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/777", "id": 640955788, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MDk1NTc4OA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-09T00:23:26Z", "updated_at": "2020-06-09T00:23:57Z", "author_association": "OWNER", "body": "Clue: https://latest.datasette.io/404 displays correctly but https://latest.datasette.io/fixtures/404 does not.\r\n\r\nThat's because `` does the correct thing if you are on the root of the site but not if you are in a sub-directory.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 626171242, "label": "Error pages not correctly loading CSS"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/813#issuecomment-640951947", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/813", "id": 640951947, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MDk1MTk0Nw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-09T00:09:56Z", "updated_at": "2020-06-09T00:09:56Z", "author_association": "OWNER", "body": "Documentation: https://datasette.readthedocs.io/en/latest/authentication.html#controlling-the-ability-to-execute-arbitrary-sql", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 634139848, "label": "Mechanism for specifying allow_sql permission in metadata.json"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/818#issuecomment-640929693", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/818", "id": 640929693, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MDkyOTY5Mw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-08T22:56:38Z", "updated_at": "2020-06-08T22:56:38Z", "author_association": "OWNER", "body": "https://datasette.readthedocs.io/en/latest/plugins.html#permission-allowed-datasette-actor-action-resource has a couple of examples now.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 634917088, "label": "Example permissions plugin"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/777#issuecomment-640925018", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/777", "id": 640925018, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MDkyNTAxOA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-08T22:41:42Z", "updated_at": "2020-06-08T22:41:42Z", "author_association": "OWNER", "body": "This is particularly worth fixing now that 403 forbidden pages are much more likely due to #811.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 626171242, "label": "Error pages not correctly loading CSS"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/493#issuecomment-640924558", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/493", "id": 640924558, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MDkyNDU1OA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-08T22:40:01Z", "updated_at": "2020-06-08T22:40:01Z", "author_association": "OWNER", "body": "I'll also rename `--config` to `--setting`.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 449886319, "label": "Rename metadata.json to config.json"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/493#issuecomment-640924482", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/493", "id": 640924482, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MDkyNDQ4Mg==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-08T22:39:45Z", "updated_at": "2020-06-08T22:39:45Z", "author_association": "OWNER", "body": "I'm definitely doing this rename, now that `metadata.json` is used for `allow` permissions configuration as well as-of #811.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 449886319, "label": "Rename metadata.json to config.json"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/806#issuecomment-640916991", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/806", "id": 640916991, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MDkxNjk5MQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-08T22:18:45Z", "updated_at": "2020-06-08T22:18:45Z", "author_association": "OWNER", "body": "Reminder for release notes: I removed `--config allow_sql:0` - see https://github.com/simonw/datasette/issues/813#issuecomment-640916807", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 632753851, "label": "Release Datasette 0.44"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/813#issuecomment-640916807", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/813", "id": 640916807, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MDkxNjgwNw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-08T22:18:09Z", "updated_at": "2020-06-08T22:18:09Z", "author_association": "OWNER", "body": "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.\r\n\r\nI'm going to do that.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 634139848, "label": "Mechanism for specifying allow_sql permission in metadata.json"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/813#issuecomment-640916290", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/813", "id": 640916290, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MDkxNjI5MA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-08T22:16:39Z", "updated_at": "2020-06-08T22:17:32Z", "author_association": "OWNER", "body": "Naming problem: Datasette already has a config option with this name:\r\n\r\n $ datasette serve data.db --config allow_sql:1\r\n\r\nhttps://datasette.readthedocs.io/en/stable/config.html#allow-sql\r\n\r\nIt's confusing to have two things called `allow_sql` that do slightly different things.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 634139848, "label": "Mechanism for specifying allow_sql permission in metadata.json"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/801#issuecomment-640905609", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/801", "id": 640905609, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MDkwNTYwOQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-08T21:48:44Z", "updated_at": "2020-06-08T21:48:44Z", "author_association": "OWNER", "body": "Dropping this out of Datasette 0.44 again - I have enough other stuff to finish, this can wait.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 631932926, "label": "allow_by_query setting for configuring permissions with a SQL statement"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/813#issuecomment-640837908", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/813", "id": 640837908, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MDgzNzkwOA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-08T19:33:03Z", "updated_at": "2020-06-08T19:33:03Z", "author_association": "OWNER", "body": "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", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 634139848, "label": "Mechanism for specifying allow_sql permission in metadata.json"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/813#issuecomment-640831842", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/813", "id": 640831842, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MDgzMTg0Mg==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-08T19:27:47Z", "updated_at": "2020-06-08T19:27:47Z", "author_association": "OWNER", "body": "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", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 634139848, "label": "Mechanism for specifying allow_sql permission in metadata.json"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/813#issuecomment-640830088", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/813", "id": 640830088, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MDgzMDA4OA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-08T19:26:15Z", "updated_at": "2020-06-08T19:26:15Z", "author_association": "OWNER", "body": "This needs to affect the `?_where=` parameter on table pages as well.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 634139848, "label": "Mechanism for specifying allow_sql permission in metadata.json"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/816#issuecomment-640815550", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/816", "id": 640815550, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MDgxNTU1MA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-08T19:06:44Z", "updated_at": "2020-06-08T19:06:44Z", "author_association": "OWNER", "body": "https://github.com/simonw/datasette/blob/c7d145e016522dd6ee229d4d0b3ba79a7a8877c1/docs/plugins.rst#extra_template_varstemplate-database-table-view_name-request-datasette", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 634783573, "label": "Come up with a new example for extra_template_vars plugin"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/817#issuecomment-640808161", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/817", "id": 640808161, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MDgwODE2MQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-08T18:51:42Z", "updated_at": "2020-06-08T18:54:37Z", "author_association": "OWNER", "body": "I'm also going to rename `resource_identifier` to just `resource`.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 634844634, "label": "Drop resource_type from permission_allowed system"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/816#issuecomment-640763899", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/816", "id": 640763899, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MDc2Mzg5OQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-08T17:21:59Z", "updated_at": "2020-06-08T17:21:59Z", "author_association": "OWNER", "body": "I'm going to show how to display the current user's user-agent.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 634783573, "label": "Come up with a new example for extra_template_vars plugin"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/815#issuecomment-640673405", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/815", "id": 640673405, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MDY3MzQwNQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-08T14:41:55Z", "updated_at": "2020-06-08T14:41:55Z", "author_association": "OWNER", "body": "I want to be able to display the HTTP path and verb - `GET /fixtures`, `POST /fixtures/myquery` etc. ", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 634663505, "label": "Group permission checks by request on /-/permissions debug page"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/815#issuecomment-640673138", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/815", "id": 640673138, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MDY3MzEzOA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-08T14:41:24Z", "updated_at": "2020-06-08T14:41:24Z", "author_association": "OWNER", "body": "I could reuse that `get_task_id()` function though (I can move it to utils).", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 634663505, "label": "Group permission checks by request on /-/permissions debug page"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/815#issuecomment-640672540", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/815", "id": 640672540, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MDY3MjU0MA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-08T14:40:22Z", "updated_at": "2020-06-08T14:40:22Z", "author_association": "OWNER", "body": "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.\r\n\r\nhttps://github.com/simonw/datasette/blob/1c063fae9dba70f70244db010d55a18846640f07/datasette/tracer.py#L27-L51\r\n\r\nFor permissions checks I want to ALWAYS track those calls, not just on requests that have opted in.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 634663505, "label": "Group permission checks by request on /-/permissions debug page"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/815#issuecomment-640671398", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/815", "id": 640671398, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MDY3MTM5OA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-08T14:38:20Z", "updated_at": "2020-06-08T14:38:20Z", "author_association": "OWNER", "body": "But `ds._permission_checks` is also used for unit tests.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 634663505, "label": "Group permission checks by request on /-/permissions debug page"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/815#issuecomment-640671241", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/815", "id": 640671241, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MDY3MTI0MQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-08T14:38:04Z", "updated_at": "2020-06-08T14:38:04Z", "author_association": "OWNER", "body": "Alternative to a correlation ID would be to use the existing `AsgiTracer` / `capture_traces` mechanism. That's probably smarter.\r\n\r\nIt could even start logging SQL queries to an in-memory deque too, so a debug tool could show you queries executed by other requests!", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 634663505, "label": "Group permission checks by request on /-/permissions debug page"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/815#issuecomment-640656143", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/815", "id": 640656143, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MDY1NjE0Mw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-08T14:25:48Z", "updated_at": "2020-06-08T14:26:45Z", "author_association": "OWNER", "body": "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.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 634663505, "label": "Group permission checks by request on /-/permissions debug page"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/814#issuecomment-640638057", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/814", "id": 640638057, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MDYzODA1Nw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-08T14:11:51Z", "updated_at": "2020-06-08T14:12:12Z", "author_association": "OWNER", "body": "The only impact it has at all is on this code here:\r\nhttps://github.com/simonw/datasette/blob/cc218fa9be55842656d030545c308392e3736053/datasette/views/base.py#L515-L527\r\n\r\nThat `ds.cache_headers` property looks like it needs rethinking too.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 634651079, "label": "Remove --debug option from datasette serve"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/811#issuecomment-640362879", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/811", "id": 640362879, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MDM2Mjg3OQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-08T04:42:28Z", "updated_at": "2020-06-08T13:39:46Z", "author_association": "OWNER", "body": "I'm finding myself repeating this pattern a lot:\r\n```python\r\n for table in table_counts:\r\n allowed = await self.ds.permission_allowed(\r\n request.scope.get(\"actor\"),\r\n \"view-table\",\r\n resource_type=\"table\",\r\n resource_identifier=(database, table),\r\n default=True,\r\n )\r\n if not allowed:\r\n continue\r\n private = not await self.ds.permission_allowed(\r\n None,\r\n \"view-table\",\r\n resource_type=\"table\",\r\n resource_identifier=(database, table),\r\n )\r\n```\r\nI 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.\r\n\r\nAn abstraction around this would be useful.\r\n\r\nIdea:\r\n\r\n```python\r\nvisible, private = await check_visibility(\r\n self.ds, actor, \"view-table\", \"table\", (database, table)\r\n)\r\n```", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 633578769, "label": "Support \"allow\" block on root, databases and tables, not just queries"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/811#issuecomment-640367128", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/811", "id": 640367128, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MDM2NzEyOA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-08T05:00:13Z", "updated_at": "2020-06-08T05:00:49Z", "author_association": "OWNER", "body": "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?\r\n\r\nInteresting question. If an instance is private, I'm not sure it makes sense to show padlocks on absolutely everything.\r\n\r\nLikewise, 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.\r\n\r\nI think \"Show \ud83d\udd12 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.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 633578769, "label": "Support \"allow\" block on root, databases and tables, not just queries"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/811#issuecomment-640365512", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/811", "id": 640365512, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MDM2NTUxMg==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-08T04:53:49Z", "updated_at": "2020-06-08T04:53:49Z", "author_association": "OWNER", "body": "I really like the padlocks. I should include a screenshot in the documentation that illustrates them.\r\n\r\n\"data\"\r\n\r\nMaybe I should figure out a way to have the https://latest.datasette.io/ demo illustrate both a logged-in and a logged-out state.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 633578769, "label": "Support \"allow\" block on root, databases and tables, not just queries"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/811#issuecomment-640348785", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/811", "id": 640348785, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MDM0ODc4NQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-08T03:51:50Z", "updated_at": "2020-06-08T03:51:50Z", "author_association": "OWNER", "body": "New convention: the \ud83d\udd12 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.\r\n\r\n\"Datasette__fixtures__data\"\r\n", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 633578769, "label": "Support \"allow\" block on root, databases and tables, not just queries"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/811#issuecomment-640345115", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/811", "id": 640345115, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MDM0NTExNQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-08T03:37:33Z", "updated_at": "2020-06-08T03:37:33Z", "author_association": "OWNER", "body": "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.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 633578769, "label": "Support \"allow\" block on root, databases and tables, not just queries"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/811#issuecomment-640344950", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/811", "id": 640344950, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MDM0NDk1MA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-08T03:36:49Z", "updated_at": "2020-06-08T03:36:49Z", "author_association": "OWNER", "body": "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?\r\n\r\n\"Datasette__fixtures__data\"\r\n", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 633578769, "label": "Support \"allow\" block on root, databases and tables, not just queries"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/801#issuecomment-640339828", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/801", "id": 640339828, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MDMzOTgyOA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-08T03:18:47Z", "updated_at": "2020-06-08T03:18:47Z", "author_association": "OWNER", "body": "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.\r\n```json\r\n{\r\n \"databases\": {\r\n \"fixtures\": {\r\n \"allow_by_query\": \"select * from users where id = :id and admin = 1\"\r\n }\r\n }\r\n}\r\n```", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 631932926, "label": "allow_by_query setting for configuring permissions with a SQL statement"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/811#issuecomment-640339674", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/811", "id": 640339674, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MDMzOTY3NA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-08T03:18:15Z", "updated_at": "2020-06-08T03:18:15Z", "author_association": "OWNER", "body": "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).", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 633578769, "label": "Support \"allow\" block on root, databases and tables, not just queries"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/801#issuecomment-640339117", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/801", "id": 640339117, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MDMzOTExNw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-08T03:16:16Z", "updated_at": "2020-06-08T03:16:16Z", "author_association": "OWNER", "body": "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).", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 631932926, "label": "allow_by_query setting for configuring permissions with a SQL statement"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/811#issuecomment-640338347", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/811", "id": 640338347, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MDMzODM0Nw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-08T03:13:23Z", "updated_at": "2020-06-08T03:13:23Z", "author_association": "OWNER", "body": "Do row-level permissions even make sense? Might be a good idea to remove those until I have a good use-case for them.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 633578769, "label": "Support \"allow\" block on root, databases and tables, not just queries"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/811#issuecomment-640338151", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/811", "id": 640338151, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MDMzODE1MQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-08T03:12:41Z", "updated_at": "2020-06-08T03:12:41Z", "author_association": "OWNER", "body": "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.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 633578769, "label": "Support \"allow\" block on root, databases and tables, not just queries"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/811#issuecomment-640337951", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/811", "id": 640337951, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MDMzNzk1MQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-08T03:11:58Z", "updated_at": "2020-06-08T03:11:58Z", "author_association": "OWNER", "body": "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.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 633578769, "label": "Support \"allow\" block on root, databases and tables, not just queries"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/811#issuecomment-640287967", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/811", "id": 640287967, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MDI4Nzk2Nw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-07T22:16:10Z", "updated_at": "2020-06-07T22:16:10Z", "author_association": "OWNER", "body": "The tests in test_permissions.py could check the .json variants and assert that permission checks were carried out too.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 633578769, "label": "Support \"allow\" block on root, databases and tables, not just queries"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/395#issuecomment-640280741", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/395", "id": 640280741, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MDI4MDc0MQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-07T21:12:57Z", "updated_at": "2020-06-07T21:12:57Z", "author_association": "OWNER", "body": "This is a pattern I like:\r\n```python\r\n with make_app_client(\r\n template_dir=str(pathlib.Path(__file__).parent / \"test_templates\")\r\n ) as client:\r\n response = client.get(\"/-/metadata\")\r\n assert response.status == 200\r\n```", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 396215043, "label": "Find a cleaner pattern for fixtures with arguments"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/801#issuecomment-640277775", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/801", "id": 640277775, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MDI3Nzc3NQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-07T20:49:40Z", "updated_at": "2020-06-07T20:49:40Z", "author_association": "OWNER", "body": "I'm going to pass the entire actor object as a dictionary of available named query parameters. So if the actor looks like this:\r\n```json\r\n{\r\n \"id\": \"simonw\",\r\n \"roles\": [\"staff\", \"developer\"]\r\n}\r\n```\r\nThen the SQL query will be called like this:\r\n\r\n```python\r\nconn.execute(sql, {\r\n \"id\": \"simonw\",\r\n \"roles: '[\"staff\", \"developer\"]',\r\n})\r\n```", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 631932926, "label": "allow_by_query setting for configuring permissions with a SQL statement"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/801#issuecomment-640277557", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/801", "id": 640277557, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MDI3NzU1Nw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-07T20:48:00Z", "updated_at": "2020-06-07T20:48:00Z", "author_association": "OWNER", "body": "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.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 631932926, "label": "allow_by_query setting for configuring permissions with a SQL statement"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/811#issuecomment-640274171", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/811", "id": 640274171, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MDI3NDE3MQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-07T20:21:14Z", "updated_at": "2020-06-07T20:21:14Z", "author_association": "OWNER", "body": "Next step: fix this\r\n```\r\n- # TODO: fix this to use that permission check\r\n- if not actor_matches_allow(\r\n- request.scope.get(\"actor\", None), metadata.get(\"allow\")\r\n- ):\r\n- return Response(\"Permission denied\", status=403)\r\n```", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 633578769, "label": "Support \"allow\" block on root, databases and tables, not just queries"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/811#issuecomment-640273945", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/811", "id": 640273945, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MDI3Mzk0NQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-07T20:19:15Z", "updated_at": "2020-06-07T20:19:15Z", "author_association": "OWNER", "body": "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`.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 633578769, "label": "Support \"allow\" block on root, databases and tables, not just queries"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/811#issuecomment-640270178", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/811", "id": 640270178, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MDI3MDE3OA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-07T19:48:39Z", "updated_at": "2020-06-07T19:48:39Z", "author_association": "OWNER", "body": "Testing pattern:\r\n```python\r\ndef test_canned_query_with_custom_metadata(app_client):\r\n response = app_client.get(\"/fixtures/neighborhood_search?text=town\")\r\n assert_permissions_checked(\r\n app_client.ds,\r\n [\r\n \"view-instance\",\r\n (\"view-database\", \"database\", \"fixtures\"),\r\n (\"view-query\", \"query\", (\"fixtures\", \"neighborhood_search\")),\r\n ],\r\n )\r\n```\r\n", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 633578769, "label": "Support \"allow\" block on root, databases and tables, not just queries"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/811#issuecomment-640248972", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/811", "id": 640248972, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MDI0ODk3Mg==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-07T17:04:22Z", "updated_at": "2020-06-07T17:04:22Z", "author_association": "OWNER", "body": "I'll need a neat testing pattern for this.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 633578769, "label": "Support \"allow\" block on root, databases and tables, not just queries"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/810#issuecomment-640248864", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/810", "id": 640248864, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MDI0ODg2NA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-07T17:03:15Z", "updated_at": "2020-06-07T17:03:15Z", "author_association": "OWNER", "body": "This is obsoleted by #811.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 633066114, "label": "Refactor permission check for canned query"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/811#issuecomment-640248669", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/811", "id": 640248669, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MDI0ODY2OQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-07T17:01:44Z", "updated_at": "2020-06-07T17:01:44Z", "author_association": "OWNER", "body": "If the allow block at the database level forbids access this needs to cascade down to the table, query and row levels as well.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 633578769, "label": "Support \"allow\" block on root, databases and tables, not just queries"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/215#issuecomment-640121917", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/215", "id": 640121917, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MDEyMTkxNw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-06T21:42:58Z", "updated_at": "2020-06-07T05:58:36Z", "author_association": "OWNER", "body": "I might use some dependency injection here, with `call_with_supported_arguments()` from https://github.com/simonw/datasette/commit/41a0cd7b6afe0397efbbf27ad822679fc574811a#diff-942305c83055fdc0ff5f4e7d6ab06b29\r\n\r\nMaybe a view function can take `request` and optionally also take `datasette`? Or `scope` or `receive` or `send`.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 314506669, "label": "Allow plugins to define additional URL routes and views"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/800#issuecomment-640160487", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/800", "id": 640160487, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MDE2MDQ4Nw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-07T05:34:07Z", "updated_at": "2020-06-07T05:34:07Z", "author_association": "OWNER", "body": "See #810 for work to finish this.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 631931408, "label": "Canned query permissions mechanism"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/808#issuecomment-640157216", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/808", "id": 640157216, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MDE1NzIxNg==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-07T04:58:40Z", "updated_at": "2020-06-07T04:58:40Z", "author_association": "OWNER", "body": "... and I want a unit test which confirms that all permissions are documented.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 632918799, "label": "Permission check for every view in Datasette (plus docs)"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/808#issuecomment-640152036", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/808", "id": 640152036, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MDE1MjAzNg==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-07T03:38:07Z", "updated_at": "2020-06-07T03:38:07Z", "author_association": "OWNER", "body": "I'm going to need to add permissions documentation for this.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 632918799, "label": "Permission check for every view in Datasette (plus docs)"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/807#issuecomment-640135332", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/807", "id": 640135332, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MDEzNTMzMg==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-07T00:13:51Z", "updated_at": "2020-06-07T00:13:51Z", "author_association": "OWNER", "body": "These should not be shipped as the latest version on Docker Hub. They also should not become the \"stable\" release on ReadTheDocs.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 632843030, "label": "Ability to ship alpha and beta releases"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/800#issuecomment-640123488", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/800", "id": 640123488, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MDEyMzQ4OA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-06T21:59:14Z", "updated_at": "2020-06-06T21:59:14Z", "author_association": "OWNER", "body": "I didn't build this quite right: it should be using the permissions plugin hook.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 631931408, "label": "Canned query permissions mechanism"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/805#issuecomment-640122664", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/805", "id": 640122664, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MDEyMjY2NA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-06T21:50:41Z", "updated_at": "2020-06-06T21:50:41Z", "author_association": "OWNER", "body": "Part of #806 ", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 632724154, "label": "Writable canned queries live demo on Glitch"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/215#issuecomment-504881900", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/215", "id": 504881900, "node_id": "MDEyOklzc3VlQ29tbWVudDUwNDg4MTkwMA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2019-06-24T06:51:29Z", "updated_at": "2020-06-06T21:47:11Z", "author_association": "OWNER", "body": "See also #520 - asgi_wrapper plugin hook.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 314506669, "label": "Allow plugins to define additional URL routes and views"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/215#issuecomment-398826108", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/215", "id": 398826108, "node_id": "MDEyOklzc3VlQ29tbWVudDM5ODgyNjEwOA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2018-06-20T17:09:18Z", "updated_at": "2020-06-06T21:46:51Z", "author_association": "OWNER", "body": "This depends on #272 - Datasette ported to ASGI.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 314506669, "label": "Allow plugins to define additional URL routes and views"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/215#issuecomment-640122120", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/215", "id": 640122120, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MDEyMjEyMA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-06T21:45:13Z", "updated_at": "2020-06-06T21:45:52Z", "author_association": "OWNER", "body": "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.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 314506669, "label": "Allow plugins to define additional URL routes and views"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/215#issuecomment-640121036", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/215", "id": 640121036, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MDEyMTAzNg==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-06T21:34:03Z", "updated_at": "2020-06-06T21:34:03Z", "author_association": "OWNER", "body": "I'll refactor existing code to register views using the same mechanism that plugins will have access to.\r\n\r\nMaybe plugins get to register their routes first? That would allow plugins to do things like entirely take over the / page.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 314506669, "label": "Allow plugins to define additional URL routes and views"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/215#issuecomment-640119259", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/215", "id": 640119259, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MDExOTI1OQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-06T21:16:46Z", "updated_at": "2020-06-06T21:16:46Z", "author_association": "OWNER", "body": "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\r\n\r\nBut... 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\r\n\r\nNow 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.\r\n\r\nSo 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. ", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 314506669, "label": "Allow plugins to define additional URL routes and views"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/215#issuecomment-640118802", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/215", "id": 640118802, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MDExODgwMg==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-06T21:12:41Z", "updated_at": "2020-06-06T21:12:41Z", "author_association": "OWNER", "body": "@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", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 314506669, "label": "Allow plugins to define additional URL routes and views"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/805#issuecomment-640116970", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/805", "id": 640116970, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MDExNjk3MA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-06T20:55:03Z", "updated_at": "2020-06-06T20:55:03Z", "author_association": "OWNER", "body": "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.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 632724154, "label": "Writable canned queries live demo on Glitch"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/805#issuecomment-640116842", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/805", "id": 640116842, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MDExNjg0Mg==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-06T20:53:51Z", "updated_at": "2020-06-06T20:53:51Z", "author_association": "OWNER", "body": "I'd like to illustrate writable canned queries without the risk of someone abusing and breaking it (or filling it with bad content).\r\n\r\nI 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.\r\n\r\nMaybe a polling app? If I'm only tracking integer numbers of votes it shouldn't ever run out of space.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 632724154, "label": "Writable canned queries live demo on Glitch"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/791#issuecomment-640116494", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/791", "id": 640116494, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MDExNjQ5NA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-06T20:50:41Z", "updated_at": "2020-06-06T20:50:41Z", "author_association": "OWNER", "body": "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.", "reactions": "{\"total_count\": 1, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 1, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 628572716, "label": "Tutorial: building a something-interesting with writable canned queries"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/787#issuecomment-640111383", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/787", "id": 640111383, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MDExMTM4Mw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-06T20:04:20Z", "updated_at": "2020-06-06T20:04:20Z", "author_association": "OWNER", "body": "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.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 628089318, "label": "\"datasette publish\" should bake in a random --secret"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/698#issuecomment-640108942", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/698", "id": 640108942, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MDEwODk0Mg==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-06T19:43:48Z", "updated_at": "2020-06-06T19:43:48Z", "author_association": "OWNER", "body": "Landed - documentation is here: https://datasette.readthedocs.io/en/latest/sql_queries.html#writable-canned-queries\r\n\r\nSee also https://datasette.readthedocs.io/en/latest/authentication.html#permissions-for-canned-queries", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 582517965, "label": "Ability for a canned query to write to the database"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/800#issuecomment-640108835", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/800", "id": 640108835, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MDEwODgzNQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-06T19:42:46Z", "updated_at": "2020-06-06T19:42:46Z", "author_association": "OWNER", "body": "This is implemented and documented: https://datasette.readthedocs.io/en/latest/authentication.html", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 631931408, "label": "Canned query permissions mechanism"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/699#issuecomment-640108763", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/699", "id": 640108763, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MDEwODc2Mw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-06T19:42:11Z", "updated_at": "2020-06-06T19:42:11Z", "author_association": "OWNER", "body": "I landed canned query writes. This feature can now be considered complete: https://datasette.readthedocs.io/en/latest/authentication.html", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 582526961, "label": "Authentication (and permissions) as a core concept"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/699#issuecomment-640106668", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/699", "id": 640106668, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MDEwNjY2OA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-06T19:22:36Z", "updated_at": "2020-06-06T19:22:36Z", "author_association": "OWNER", "body": "The canned queries feature is gaining permissions support in #800.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 582526961, "label": "Authentication (and permissions) as a core concept"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/804#issuecomment-640106569", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/804", "id": 640106569, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MDEwNjU2OQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-06T19:21:41Z", "updated_at": "2020-06-06T19:21:41Z", "author_association": "OWNER", "body": "I don't think this is fully documented either. Current partial documentation is on https://datasette.readthedocs.io/en/stable/contributing.html", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 632673972, "label": "python tests/fixtures.py command has a bug"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/804#issuecomment-640106342", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/804", "id": 640106342, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MDEwNjM0Mg==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-06T19:19:33Z", "updated_at": "2020-06-06T19:19:33Z", "author_association": "OWNER", "body": "I should replace the bodged-together argument passing with Click while I'm fixing this.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 632673972, "label": "python tests/fixtures.py command has a bug"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/804#issuecomment-640106202", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/804", "id": 640106202, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MDEwNjIwMg==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-06T19:18:23Z", "updated_at": "2020-06-06T19:18:43Z", "author_association": "OWNER", "body": "I broke this in #775 https://github.com/simonw/datasette/commit/446e5de65d1b9c6c877e38b0ef13bc9285c465a1\r\n\r\nHere's the now-broken code (I removed the `PLUGIN1` and `PLUGIN2` constants): https://github.com/simonw/datasette/blob/9c563d6aed072f14d3d25f58e84659f9caa1a243/tests/fixtures.py#L828-L835", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 632673972, "label": "python tests/fixtures.py command has a bug"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/800#issuecomment-640103204", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/800", "id": 640103204, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MDEwMzIwNA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-06T18:52:56Z", "updated_at": "2020-06-06T18:52:56Z", "author_association": "OWNER", "body": "I'm also going to add an indicator to the UI next to queries that you can only execute because you are signed in:\r\n\r\n\"data\"\r\n", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 631931408, "label": "Canned query permissions mechanism"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/800#issuecomment-640102200", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/800", "id": 640102200, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MDEwMjIwMA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-06T18:45:11Z", "updated_at": "2020-06-06T18:45:11Z", "author_association": "OWNER", "body": "In the code that's:\r\n\r\nhttps://github.com/simonw/datasette/blob/9c563d6aed072f14d3d25f58e84659f9caa1a243/datasette/views/database.py#L56-L64\r\n\r\nAnd:\r\n\r\nhttps://github.com/simonw/datasette/blob/9c563d6aed072f14d3d25f58e84659f9caa1a243/datasette/views/database.py#L98-L112\r\n", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 631931408, "label": "Canned query permissions mechanism"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/800#issuecomment-640101762", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/800", "id": 640101762, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MDEwMTc2Mg==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-06T18:41:20Z", "updated_at": "2020-06-06T18:41:20Z", "author_association": "OWNER", "body": "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", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 631931408, "label": "Canned query permissions mechanism"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/800#issuecomment-640101625", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/800", "id": 640101625, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MDEwMTYyNQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-06T18:40:09Z", "updated_at": "2020-06-06T18:40:09Z", "author_association": "OWNER", "body": "Documentation for `actor_matches_allow`: https://github.com/simonw/datasette/blob/14f6b4d200f24940a795ddc0825319ab2891bde2/docs/authentication.rst#actor_matches_allow", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 631931408, "label": "Canned query permissions mechanism"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/800#issuecomment-640099707", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/800", "id": 640099707, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MDA5OTcwNw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-06T18:24:54Z", "updated_at": "2020-06-06T18:24:54Z", "author_association": "OWNER", "body": "Next step: a utility function and tests for matching actors to allow blocks.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 631931408, "label": "Canned query permissions mechanism"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/800#issuecomment-640099404", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/800", "id": 640099404, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MDA5OTQwNA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-06T18:22:10Z", "updated_at": "2020-06-06T18:24:26Z", "author_association": "OWNER", "body": "Docs here: https://github.com/simonw/datasette/blob/d4c7b85f556230923d37ff327a068ed08aa9b62b/docs/authentication.rst#setting-permissions-for-canned-queries", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 631931408, "label": "Canned query permissions mechanism"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/800#issuecomment-640099434", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/800", "id": 640099434, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MDA5OTQzNA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-06T18:22:29Z", "updated_at": "2020-06-06T18:22:29Z", "author_association": "OWNER", "body": "I should add the '*' bit to the docs.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 631931408, "label": "Canned query permissions mechanism"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/786#issuecomment-640099333", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/786", "id": 640099333, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MDA5OTMzMw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-06T18:21:36Z", "updated_at": "2020-06-06T18:21:36Z", "author_association": "OWNER", "body": "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", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 628087971, "label": "Documentation page describing Datasette's authentication system"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/800#issuecomment-640090575", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/800", "id": 640090575, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MDA5MDU3NQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-06T17:06:28Z", "updated_at": "2020-06-06T17:06:28Z", "author_association": "OWNER", "body": "I'm going to implement this documentation-first.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 631931408, "label": "Canned query permissions mechanism"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/800#issuecomment-640090343", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/800", "id": 640090343, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MDA5MDM0Mw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-06T17:04:36Z", "updated_at": "2020-06-06T17:04:36Z", "author_association": "OWNER", "body": "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.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 631931408, "label": "Canned query permissions mechanism"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/802#issuecomment-639895450", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/802", "id": 639895450, "node_id": "MDEyOklzc3VlQ29tbWVudDYzOTg5NTQ1MA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-05T23:33:52Z", "updated_at": "2020-06-05T23:33:52Z", "author_association": "OWNER", "body": "https://github.com/simonw/datasette/blob/033a1bb22c70a955d9fd1d3b4675a0e2e5c8b8cd/datasette/cli.py#L126-L129\r\n\r\nBut I changed the `.plugins()` method to this:\r\n\r\nhttps://github.com/simonw/datasette/blob/033a1bb22c70a955d9fd1d3b4675a0e2e5c8b8cd/datasette/app.py#L628-L633", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 632056825, "label": "\"datasette plugins\" command is broken"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/800#issuecomment-639803719", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/800", "id": 639803719, "node_id": "MDEyOklzc3VlQ29tbWVudDYzOTgwMzcxOQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-05T20:40:34Z", "updated_at": "2020-06-05T20:40:34Z", "author_association": "OWNER", "body": "It's a bit obscure though. I'll try building both and see how they feel in practice.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 631931408, "label": "Canned query permissions mechanism"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/800#issuecomment-639803099", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/800", "id": 639803099, "node_id": "MDEyOklzc3VlQ29tbWVudDYzOTgwMzA5OQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-05T20:39:34Z", "updated_at": "2020-06-05T20:39:34Z", "author_association": "OWNER", "body": "Maybe #801 (configuring permissions with a SQL query) is enough here - might not need this mechanism at all, since that mechanism covers it.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 631931408, "label": "Canned query permissions mechanism"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/698#issuecomment-639788562", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/698", "id": 639788562, "node_id": "MDEyOklzc3VlQ29tbWVudDYzOTc4ODU2Mg==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-05T20:27:49Z", "updated_at": "2020-06-05T20:27:49Z", "author_association": "OWNER", "body": "There can be a detailed section explaining these different mechanisms on the authentication documentation page.\r\n\r\nI imagine they will end up applying to more than just canned queries.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 582517965, "label": "Ability for a canned query to write to the database"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/698#issuecomment-639787304", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/698", "id": 639787304, "node_id": "MDEyOklzc3VlQ29tbWVudDYzOTc4NzMwNA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-05T20:26:57Z", "updated_at": "2020-06-05T20:26:57Z", "author_association": "OWNER", "body": "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.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 582517965, "label": "Ability for a canned query to write to the database"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/698#issuecomment-639785878", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/698", "id": 639785878, "node_id": "MDEyOklzc3VlQ29tbWVudDYzOTc4NTg3OA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-05T20:25:55Z", "updated_at": "2020-06-05T20:25:55Z", "author_association": "OWNER", "body": "I'd really like to support SQL query defined permissions too, mainly to set an example for how plugins could do something similar.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 582517965, "label": "Ability for a canned query to write to the database"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/698#issuecomment-639784651", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/698", "id": 639784651, "node_id": "MDEyOklzc3VlQ29tbWVudDYzOTc4NDY1MQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-05T20:25:02Z", "updated_at": "2020-06-05T20:25:02Z", "author_association": "OWNER", "body": "Idea: default is anyone can execute a query.\r\n\r\nOr you can specify the following:\r\n\r\n```json\r\n\r\n{\r\n \"databases\": {\r\n \"my-database\": {\r\n \"queries\": {\r\n \"add_twitter_handle\": {\r\n \"sql\": \"insert into twitter_handles (username) values (:username)\",\r\n \"write\": true,\r\n \"allow\": {\r\n \"id\": [\"simon\"],\r\n \"role\": [\"staff\"]\r\n }\r\n }\r\n }\r\n }\r\n }\r\n}\r\n```\r\nThese 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.\r\n\r\n`\"id\": \"*\"` matches any actor with an `id` key.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 582517965, "label": "Ability for a canned query to write to the database"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/698#issuecomment-639779403", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/698", "id": 639779403, "node_id": "MDEyOklzc3VlQ29tbWVudDYzOTc3OTQwMw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-05T20:20:12Z", "updated_at": "2020-06-05T20:20:12Z", "author_association": "OWNER", "body": "CSRF is done. Last step: figure out a smart way to integrate this with permissions and authentication.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 582517965, "label": "Ability for a canned query to write to the database"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/pull/798#issuecomment-639712835", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/798", "id": 639712835, "node_id": "MDEyOklzc3VlQ29tbWVudDYzOTcxMjgzNQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-05T18:53:32Z", "updated_at": "2020-06-05T18:53:32Z", "author_association": "OWNER", "body": "Add unit tests illustrating the `Vary: Cookie` header and I'm done here.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 631300342, "label": "CSRF protection"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/pull/798#issuecomment-639685550", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/798", "id": 639685550, "node_id": "MDEyOklzc3VlQ29tbWVudDYzOTY4NTU1MA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-05T18:20:34Z", "updated_at": "2020-06-05T18:20:34Z", "author_association": "OWNER", "body": "I'm solving the compatibility with caching problem in this ticket: https://github.com/simonw/asgi-csrf/issues/7", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 631300342, "label": "CSRF protection"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/799#issuecomment-639661014", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/799", "id": 639661014, "node_id": "MDEyOklzc3VlQ29tbWVudDYzOTY2MTAxNA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-05T17:43:41Z", "updated_at": "2020-06-05T17:43:41Z", "author_association": "OWNER", "body": "I'm going to rename that `MultiParams` and use it in both places.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 631789422, "label": "TestResponse needs to handle multiple set-cookie headers"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/799#issuecomment-639660667", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/799", "id": 639660667, "node_id": "MDEyOklzc3VlQ29tbWVudDYzOTY2MDY2Nw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-05T17:43:08Z", "updated_at": "2020-06-05T17:43:08Z", "author_association": "OWNER", "body": "This really needs a `MultiValueDict` ala Django: https://github.com/django/django/blob/24b82cd201e21060fbc02117dc16d1702877a1f3/django/utils/datastructures.py#L42\r\n\r\nTurns out I have one of these in Datasette already - `RequestParameters` from https://github.com/simonw/datasette/commit/81be31322a968d23cf57cee62b58df55433385e3\r\n\r\nThe name isn't quite right though.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 631789422, "label": "TestResponse needs to handle multiple set-cookie headers"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/pull/798#issuecomment-639269994", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/798", "id": 639269994, "node_id": "MDEyOklzc3VlQ29tbWVudDYzOTI2OTk5NA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-05T05:36:35Z", "updated_at": "2020-06-05T05:38:25Z", "author_association": "OWNER", "body": "Django docs on CSRF and caching: https://docs.djangoproject.com/en/3.0/ref/csrf/#caching\r\n\r\n> 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\r\n\r\nSo the cookie is only set for pages that included a hidden csrftoken form field! This could work.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 631300342, "label": "CSRF protection"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/pull/798#issuecomment-639269559", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/798", "id": 639269559, "node_id": "MDEyOklzc3VlQ29tbWVudDYzOTI2OTU1OQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-05T05:34:56Z", "updated_at": "2020-06-05T05:35:23Z", "author_association": "OWNER", "body": "I don't want to set a cookie on a page response that is being cached.\r\n\r\nRight now the ASGI middleware will be doing exactly that, which is bad.\r\n\r\nBut 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?\r\n\r\nMaybe those pages should do something explicit to the request object indicating that the cookie is needed?\r\n\r\nThat 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.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 631300342, "label": "CSRF protection"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/pull/798#issuecomment-639249743", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/798", "id": 639249743, "node_id": "MDEyOklzc3VlQ29tbWVudDYzOTI0OTc0Mw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-05T04:23:01Z", "updated_at": "2020-06-05T04:23:01Z", "author_association": "OWNER", "body": "Needs unit tests.\r\n\r\nMore importantly: needs very, very careful consideration of how this plays with HTTP caching.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 631300342, "label": "CSRF protection"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/684#issuecomment-639053707", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/684", "id": 639053707, "node_id": "MDEyOklzc3VlQ29tbWVudDYzOTA1MzcwNw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-04T18:56:15Z", "updated_at": "2020-06-04T18:56:15Z", "author_association": "OWNER", "body": "This documentation is live here: https://datasette.readthedocs.io/en/latest/internals.html#database-introspection", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 570301333, "label": "Add documentation on Database introspection methods to internals.rst"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/119#issuecomment-639047315", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/119", "id": 639047315, "node_id": "MDEyOklzc3VlQ29tbWVudDYzOTA0NzMxNQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-04T18:46:39Z", "updated_at": "2020-06-04T18:46:39Z", "author_association": "OWNER", "body": "The OAuth dance needed for this is a pretty nasty barrier to plugin installation and configuration.\r\n\r\nI'm going to focus on making it easy to copy and paste data into sheets instead.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 275082158, "label": "Build an \"export this data to google sheets\" plugin"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/793#issuecomment-638462052", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/793", "id": 638462052, "node_id": "MDEyOklzc3VlQ29tbWVudDYzODQ2MjA1Mg==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-03T21:07:39Z", "updated_at": "2020-06-03T21:07:39Z", "author_association": "OWNER", "body": "I need to land and release the fix for signing cookies in https://github.com/simonw/asgi-csrf/issues/2", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 629524205, "label": "CSRF protection for /-/messages tool and writable canned queries"}, "performed_via_github_app": null}