{"id": 635049296, "node_id": "MDU6SXNzdWU2MzUwNDkyOTY=", "number": 820, "title": "Idea: Plugin hook for registering canned queries", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 2, "created_at": "2020-06-09T01:58:21Z", "updated_at": "2020-06-18T17:58:02Z", "closed_at": "2020-06-18T17:58:02Z", "author_association": "OWNER", "pull_request": null, "body": "Thought of this while thinking about possible permissions plugins (#818).\r\n\r\nImagine an API key plugin which allows access for API keys. It could let users register new API keys by providing a writable canned query for writing to the `api_keys` table.\r\n\r\nTo do this the plugin needs to register the query. At the moment queries have to be registered in `metadata.json` - a plugin hook for registering additional queries could help solve this.\r\n\r\nOne challenge: how does the plugin know which named database the query should be registered for?\r\n\r\nIt could default to the first attached database and allow users to optionally tell the plugin \"actually use this named database instead\" in plugin configuration.", "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/820/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": 635108074, "node_id": "MDU6SXNzdWU2MzUxMDgwNzQ=", "number": 824, "title": "Example authentication plugin", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": {"value": 5512395, "label": "Datasette 0.44"}, "comments": 4, "created_at": "2020-06-09T04:49:53Z", "updated_at": "2020-06-12T00:11:51Z", "closed_at": "2020-06-12T00:11:50Z", "author_association": "OWNER", "pull_request": null, "body": "https://github.com/simonw/datasette-auth-github/issues/62 will work for 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/824/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": 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": 635147716, "node_id": "MDU6SXNzdWU2MzUxNDc3MTY=", "number": 825, "title": "Way to enable a default=False permission for anonymous users", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": {"value": 5512395, "label": "Datasette 0.44"}, "comments": 6, "created_at": "2020-06-09T06:26:27Z", "updated_at": "2020-06-09T17:19:19Z", "closed_at": "2020-06-09T17:01:10Z", "author_association": "OWNER", "pull_request": null, "body": "I'd like plugins to be able to ship with a default that says \"anonymous users cannot do this\", but allow site administrators to over-ride that such that anonymous users can use the feature after all.\r\n\r\nThis is tricky because right now the anonymous user doesn't have an actor dictionary at all, so there's no key to match to an allow block.", "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/825/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": 635077656, "node_id": "MDU6SXNzdWU2MzUwNzc2NTY=", "number": 822, "title": "request.url_vars helper property", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": {"value": 5512395, "label": "Datasette 0.44"}, "comments": 2, "created_at": "2020-06-09T03:15:53Z", "updated_at": "2020-06-09T03:40:07Z", "closed_at": "2020-06-09T03:40:06Z", "author_association": "OWNER", "pull_request": null, "body": "This example: https://github.com/simonw/datasette/blob/f5e79adf26d0daa3831e3fba022f1b749a9efdee/docs/plugins.rst#register_routes\r\n\r\n```python\r\nfrom datasette.utils.asgi import Response\r\nimport html\r\n\r\n\r\nasync def hello_from(scope):\r\n name = scope[\"url_route\"][\"kwargs\"][\"name\"]\r\n return Response.html(\"Hello from {}\".format(\r\n html.escape(name)\r\n ))\r\n\r\n\r\n@hookimpl\r\ndef register_routes():\r\n return [\r\n (r\"^/hello-from/(?P.*)$\"), hello_from)\r\n ]\r\n```\r\nWould be nicer if you could easily get `scope[\"url_route\"][\"kwargs\"][\"name\"]` directly from the request object, without looking at the `scope`.", "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/822/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": 635037204, "node_id": "MDExOlB1bGxSZXF1ZXN0NDMxNDc4NzI0", "number": 819, "title": "register_routes() plugin hook", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": {"value": 5512395, "label": "Datasette 0.44"}, "comments": 0, "created_at": "2020-06-09T01:20:44Z", "updated_at": "2020-06-09T03:12:08Z", "closed_at": "2020-06-09T03:12:07Z", "author_association": "OWNER", "pull_request": "simonw/datasette/pulls/819", "body": "Refs #215", "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/819/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}