{"id": 628121234, "node_id": "MDU6SXNzdWU2MjgxMjEyMzQ=", "number": 788, "title": " /-/permissions debugging tool", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": {"value": 5512395, "label": "Datasette 0.44"}, "comments": 2, "created_at": "2020-06-01T03:13:47Z", "updated_at": "2020-06-06T00:43:40Z", "closed_at": "2020-06-01T05:01:01Z", "author_association": "OWNER", "pull_request": null, "body": "> Debugging tool idea: `/-/permissions` page which shows you the actor and lets you type in the strings for `action`, `resource_type` and `resource_identifier` - then shows you EVERY plugin hook that would have executed and what it would have said, plus when the chain would have terminated.\r\n>\r\n> Bonus: if you're logged in as the `root` user (or a user that matches some kind of permission check, maybe a check for `permissions_debug`) you get to see a rolling log of the last 30 permission checks and what the results were across the whole of Datasette. This should make figuring out permissions policies a whole lot easier.\r\n\r\n_Originally posted by @simonw in https://github.com/simonw/datasette/issues/699#issuecomment-636576603_", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/788/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 628089318, "node_id": "MDU6SXNzdWU2MjgwODkzMTg=", "number": 787, "title": "\"datasette publish\" should bake in a random --secret", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": {"value": 5512395, "label": "Datasette 0.44"}, "comments": 1, "created_at": "2020-06-01T01:15:26Z", "updated_at": "2020-06-11T16:02:05Z", "closed_at": "2020-06-11T16:02:05Z", "author_association": "OWNER", "pull_request": null, "body": "To allow signed cookies etc to work reliably (see #785) all of the `datasette publish` commands should generate a random secret on publish and bake it into the configuration - probably by setting the `DATASETTE_SECRET` environment variable.\r\n\r\n- [ ] Cloud Run\r\n- [ ] Heroku\r\n- [ ] https://github.com/simonw/datasette-publish-now\r\n- [ ] https://github.com/simonw/datasette-publish-fly", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/787/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 628499086, "node_id": "MDU6SXNzdWU2Mjg0OTkwODY=", "number": 790, "title": "\"flash messages\" mechanism", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": {"value": 5512395, "label": "Datasette 0.44"}, "comments": 20, "created_at": "2020-06-01T14:55:44Z", "updated_at": "2020-06-08T19:33:59Z", "closed_at": "2020-06-02T21:14:03Z", "author_association": "OWNER", "pull_request": null, "body": "> Passing `?_success` like this isn't necessarily the best approach. Potential improvements include:\r\n> \r\n> - Signing this message so it can't be tampered with (I could generate a signing secret on startup)\r\n> - Using a cookie with a temporary flash message in it instead\r\n> - Using HTML5 history API to remove the `?_success=` from the URL bar when the user lands on the page\r\n> \r\n> If I add an option to redirect the user to another page after success I may need a mechanism to show a flash message on that page as well, in which case I'll need a general flash message solution that works for any page.\r\n\r\n_Originally posted by @simonw in https://github.com/simonw/datasette/pull/703_", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/790/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 637253789, "node_id": "MDU6SXNzdWU2MzcyNTM3ODk=", "number": 833, "title": "/-/metadata and so on should respect view-instance permission", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": {"value": 5512395, "label": "Datasette 0.44"}, "comments": 4, "created_at": "2020-06-11T19:07:21Z", "updated_at": "2020-06-11T22:15:32Z", "closed_at": "2020-06-11T22:14:59Z", "author_association": "OWNER", "pull_request": null, "body": "The only URLs that should be available without authentication at all times are the `/-/static/` prefix, to allow for HTTP caching.", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/833/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 582517965, "node_id": "MDU6SXNzdWU1ODI1MTc5NjU=", "number": 698, "title": "Ability for a canned query to write to the database", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": {"value": 5512395, "label": "Datasette 0.44"}, "comments": 26, "created_at": "2020-03-16T18:31:59Z", "updated_at": "2020-06-06T19:43:49Z", "closed_at": "2020-06-06T19:43:48Z", "author_association": "OWNER", "pull_request": null, "body": "Canned queries are currently read-only: https://datasette.readthedocs.io/en/0.38/sql_queries.html#canned-queries\r\n\r\nAdd a `\"write\": true` option to their definition in `metadata.json` which turns them into queries that are submitted via POST and send their queries to the write queue.\r\n\r\nThen they can be used as a really quick way to define a writable interface and JSON API!", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/698/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 636426530, "node_id": "MDU6SXNzdWU2MzY0MjY1MzA=", "number": 829, "title": "Ability to set ds_actor cookie such that it expires", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": {"value": 5512395, "label": "Datasette 0.44"}, "comments": 6, "created_at": "2020-06-10T17:31:40Z", "updated_at": "2020-06-10T19:41:35Z", "closed_at": "2020-06-10T19:40:05Z", "author_association": "OWNER", "pull_request": null, "body": "I need this for `datasette-auth-github`: https://github.com/simonw/datasette-auth-github/issues/62#issuecomment-642152076", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/829/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 628003707, "node_id": "MDU6SXNzdWU2MjgwMDM3MDc=", "number": 784, "title": "Ability to sign in to Datasette as a root account", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": {"value": 5512395, "label": "Datasette 0.44"}, "comments": 5, "created_at": "2020-05-31T17:10:15Z", "updated_at": "2020-07-06T19:31:53Z", "closed_at": "2020-06-01T01:18:20Z", "author_association": "OWNER", "pull_request": null, "body": "> I'm going to draw the line here: default Datasette supports authentication but only for a single user account (\"admin\"). Plugins can then add support for multiple user accounts, social auth, SSO etc.\r\n\r\n_Originally posted by @simonw in https://github.com/simonw/datasette/issues/699#issuecomment-636498770_", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/784/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 635076066, "node_id": "MDU6SXNzdWU2MzUwNzYwNjY=", "number": 821, "title": "Add Response class to internals documentation", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": {"value": 5512395, "label": "Datasette 0.44"}, "comments": 0, "created_at": "2020-06-09T03:11:06Z", "updated_at": "2020-06-09T03:32:16Z", "closed_at": "2020-06-09T03:32:16Z", "author_association": "OWNER", "pull_request": null, "body": "> I'll need to add documentation of the `Response` object (and `Response.html()` and `Response.text()` class methods - I should add `Response.json()` too) to the internals page https://datasette.readthedocs.io/en/stable/internals.html\r\n\r\n_Originally posted by @simonw in https://github.com/simonw/datasette/issues/215#issuecomment-640971470_", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/821/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 314506669, "node_id": "MDU6SXNzdWUzMTQ1MDY2Njk=", "number": 215, "title": "Allow plugins to define additional URL routes and views", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": {"value": 5512395, "label": "Datasette 0.44"}, "comments": 14, "created_at": "2018-04-16T05:31:09Z", "updated_at": "2020-06-09T03:14:32Z", "closed_at": "2020-06-09T03:12:08Z", "author_association": "OWNER", "pull_request": null, "body": "Might be as simple as having plugins get passed the `app` after the other routes have been defined:\r\n\r\nhttps://github.com/simonw/datasette/blob/b2955d9065ea019500c7d072bcd9d49d1967f051/datasette/app.py#L1270-L1274\r\n\r\nRefs #14", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/215/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 582526961, "node_id": "MDU6SXNzdWU1ODI1MjY5NjE=", "number": 699, "title": "Authentication (and permissions) as a core concept", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": {"value": 5512395, "label": "Datasette 0.44"}, "comments": 40, "created_at": "2020-03-16T18:48:00Z", "updated_at": "2020-06-06T19:42:11Z", "closed_at": "2020-06-06T19:42:11Z", "author_association": "OWNER", "pull_request": null, "body": "Right now Datasette authentication is provided exclusively by plugins:\r\n\r\n* https://github.com/simonw/datasette-auth-github\r\n* https://github.com/simonw/datasette-auth-existing-cookies\r\n\r\nThis is an all-or-nothing approach: either your Datasette instance requires authentication at the top level or it does not.\r\n\r\nBut... as I build new plugins like https://github.com/simonw/datasette-configure-fts and https://github.com/simonw/datasette-edit-tables I increasingly have individual features which should be reserved for logged-in users while still wanting other parts of Datasette to be open to all.\r\n\r\nThis is too much for plugins to own independently of Datasette core. Datasette needs to ship a single \"user is authenticated\" concept (independent of how users actually sign in) so that different plugins can integrate with it.", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/699/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 631300342, "node_id": "MDExOlB1bGxSZXF1ZXN0NDI4MjEyNDIx", "number": 798, "title": "CSRF protection", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": {"value": 5512395, "label": "Datasette 0.44"}, "comments": 5, "created_at": "2020-06-05T04:22:35Z", "updated_at": "2020-06-06T00:43:41Z", "closed_at": "2020-06-05T19:05:58Z", "author_association": "OWNER", "pull_request": "simonw/datasette/pulls/798", "body": "Refs #793", "repo": {"value": 107914493, "label": "datasette"}, "type": "pull", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/798/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": 0, "state_reason": null} {"id": 629524205, "node_id": "MDU6SXNzdWU2Mjk1MjQyMDU=", "number": 793, "title": "CSRF protection for /-/messages tool and writable canned queries", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": {"value": 5512395, "label": "Datasette 0.44"}, "comments": 3, "created_at": "2020-06-02T21:22:21Z", "updated_at": "2020-06-06T00:43:41Z", "closed_at": "2020-06-05T19:05:59Z", "author_association": "OWNER", "pull_request": null, "body": "> The `/-/messages` debug tool will need CSRF protection or people will be able to add messages using a hidden form on another website.\r\n_Originally posted by @simonw in https://github.com/simonw/datasette/issues/790#issuecomment-637790860_", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/793/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 631931408, "node_id": "MDU6SXNzdWU2MzE5MzE0MDg=", "number": 800, "title": "Canned query permissions mechanism", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": {"value": 5512395, "label": "Datasette 0.44"}, "comments": 14, "created_at": "2020-06-05T20:28:21Z", "updated_at": "2020-06-07T16:22:53Z", "closed_at": "2020-06-07T16:22:53Z", "author_association": "OWNER", "pull_request": null, "body": "> Idea: default is anyone can execute a query.\r\n> \r\n> Or 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\n> 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.\r\n> \r\n> `\"id\": \"*\"` matches any actor with an `id` key.\r\n\r\n_Originally posted by @simonw in https://github.com/simonw/datasette/issues/698#issuecomment-639784651_", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/800/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 634783573, "node_id": "MDU6SXNzdWU2MzQ3ODM1NzM=", "number": 816, "title": "Come up with a new example for extra_template_vars plugin", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": {"value": 5512395, "label": "Datasette 0.44"}, "comments": 2, "created_at": "2020-06-08T16:57:59Z", "updated_at": "2020-06-08T19:06:44Z", "closed_at": "2020-06-08T19:06:11Z", "author_association": "OWNER", "pull_request": null, "body": "This example is obsolete, it's from a time before `request.actor` and authentication as a built-in concept (#699):\r\nhttps://github.com/simonw/datasette/blob/0c064c5fe220b7b3d8dcf85b02b4e60452c47232/docs/plugins.rst#L696-L700\r\n\r\nhttps://github.com/simonw/datasette/blob/0c064c5fe220b7b3d8dcf85b02b4e60452c47232/docs/plugins.rst#extra_template_varstemplate-database-table-view_name-request-datasette", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/816/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 628025100, "node_id": "MDU6SXNzdWU2MjgwMjUxMDA=", "number": 785, "title": "Datasette secret mechanism - initially for signed cookies", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": {"value": 5512395, "label": "Datasette 0.44"}, "comments": 11, "created_at": "2020-05-31T19:14:52Z", "updated_at": "2020-06-06T00:43:40Z", "closed_at": "2020-06-01T00:18:40Z", "author_association": "OWNER", "pull_request": null, "body": "See comment in https://github.com/simonw/datasette/issues/784#issuecomment-636514974\r\n\r\nDatasette needs to be able to set signed cookies - which means it needs a mechanism for safely handling a signing secret.\r\n\r\nSince Datasette is a long-running process the default behaviour here can be to create a random secret on startup. This means that if the server restarts any signed cookies will be invalidated.\r\n\r\nIf the user wants a persistent secret they'll have to generate it themselves - maybe by setting an environment variable?", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/785/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 635696400, "node_id": "MDU6SXNzdWU2MzU2OTY0MDA=", "number": 827, "title": "Document CSRF protection (for plugins)", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": {"value": 5512395, "label": "Datasette 0.44"}, "comments": 1, "created_at": "2020-06-09T19:19:10Z", "updated_at": "2020-06-09T19:38:30Z", "closed_at": "2020-06-09T19:35:13Z", "author_association": "OWNER", "pull_request": null, "body": "Plugin authors need to know that if they want to POST a form they should include this:\r\n```html+jinja\r\n\r\n```", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/827/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 635519358, "node_id": "MDU6SXNzdWU2MzU1MTkzNTg=", "number": 826, "title": "Document the ds_actor signed cookie", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": {"value": 5512395, "label": "Datasette 0.44"}, "comments": 3, "created_at": "2020-06-09T15:06:52Z", "updated_at": "2020-06-09T22:33:12Z", "closed_at": "2020-06-09T22:32:31Z", "author_association": "OWNER", "pull_request": null, "body": "Most authentication plugins (https://github.com/simonw/datasette-auth-github for example) are likely to work by setting the `ds_actor` signed cookie, which is already magically decoded and supported by default Datasette here:\r\n\r\nhttps://github.com/simonw/datasette/blob/4fa7cf68536628344356d3ef8c92c25c249067a0/datasette/actor_auth_cookie.py#L1-L13\r\n\r\nI should document this.", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/826/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 630120235, "node_id": "MDU6SXNzdWU2MzAxMjAyMzU=", "number": 797, "title": "Documentation for new \"params\" setting for canned queries", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": {"value": 5512395, "label": "Datasette 0.44"}, "comments": 3, "created_at": "2020-06-03T15:55:11Z", "updated_at": "2020-06-09T04:00:40Z", "closed_at": "2020-06-03T21:04:51Z", "author_association": "OWNER", "pull_request": null, "body": "Added here: https://github.com/simonw/datasette/commit/aa82d0370463580f2cb10d9617f1bcbe45cc994a#diff-5e0ffd62fced7d46339b9b2cd167c2f9R236", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/797/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 635107393, "node_id": "MDU6SXNzdWU2MzUxMDczOTM=", "number": 823, "title": "Documentation is inconsistent about \"id\" as required field on actor", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": {"value": 5512395, "label": "Datasette 0.44"}, "comments": 3, "created_at": "2020-06-09T04:47:58Z", "updated_at": "2020-06-09T14:58:36Z", "closed_at": "2020-06-09T14:58:19Z", "author_association": "OWNER", "pull_request": null, "body": "Docs at https://github.com/simonw/datasette/blob/5a6a73e3190cac103906b479d56129413e5ef190/docs/authentication.rst#actors say:\r\n\r\n> The only required field in an actor is `\"id\"`, which must be a string.\r\n\r\nBut the example here returns `{\"token\": token}`:\r\n\r\n```python\r\n@hookimpl\r\ndef actor_from_request(datasette, request):\r\n async def inner():\r\n token = request.args.get(\"_token\")\r\n if not token:\r\n return None\r\n # Look up ?_token=xxx in sessions table\r\n result = await datasette.get_database().execute(\r\n \"select count(*) from sessions where token = ?\", [token]\r\n )\r\n if result.first()[0]:\r\n return {\"token\": token}\r\n else:\r\n return None\r\n\r\n return inner\r\n```", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/823/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 628087971, "node_id": "MDU6SXNzdWU2MjgwODc5NzE=", "number": 786, "title": "Documentation page describing Datasette's authentication system", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": {"value": 5512395, "label": "Datasette 0.44"}, "comments": 2, "created_at": "2020-06-01T01:10:06Z", "updated_at": "2020-06-06T19:40:20Z", "closed_at": "2020-06-06T19:40:20Z", "author_association": "OWNER", "pull_request": null, "body": "_Originally posted by @simonw in https://github.com/simonw/datasette/issues/699#issuecomment-636562999_", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/786/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 626171242, "node_id": "MDU6SXNzdWU2MjYxNzEyNDI=", "number": 777, "title": "Error pages not correctly loading CSS", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": {"value": 5512395, "label": "Datasette 0.44"}, "comments": 4, "created_at": "2020-05-28T02:47:52Z", "updated_at": "2020-06-09T00:35:29Z", "closed_at": "2020-06-09T00:35:29Z", "author_association": "OWNER", "pull_request": null, "body": "e.g. https://latest.datasette.io/fixtures/compound_three_primary_keys.tsv?_size=max\r\n\r\n\r\n\r\nThe HTML starts like this:\r\n\r\n```html\r\n\r\n\r\n
\r\n