{"html_url": "https://github.com/simonw/datasette/pull/1940#issuecomment-1347632350", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1940", "id": 1347632350, "node_id": "IC_kwDOBm6k_c5QUzze", "user": {"value": 22429695, "label": "codecov[bot]"}, "created_at": "2022-12-13T01:48:40Z", "updated_at": "2022-12-13T02:00:52Z", "author_association": "NONE", "body": "# [Codecov](https://codecov.io/gh/simonw/datasette/pull/1940?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) Report\nBase: **92.00**% // Head: **92.03**% // Increases project coverage by **`+0.02%`** :tada:\n> Coverage data is based on head [(`a1317ab`)](https://codecov.io/gh/simonw/datasette/pull/1940?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) compared to base [(`e539c1c`)](https://codecov.io/gh/simonw/datasette/commit/e539c1c024bc62d88df91d9107cbe37e7f0fe55f?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison).\n> Patch coverage: 100.00% of modified lines in pull request are covered.\n\n> :exclamation: Current head a1317ab differs from pull request most recent head 94e5c75. Consider uploading reports for the commit 94e5c75 to get more accurate results\n\n
Additional details and impacted files\n\n\n```diff\n@@ Coverage Diff @@\n## main #1940 +/- ##\n==========================================\n+ Coverage 92.00% 92.03% +0.02% \n==========================================\n Files 38 38 \n Lines 5378 5396 +18 \n==========================================\n+ Hits 4948 4966 +18 \n Misses 430 430 \n```\n\n\n| [Impacted Files](https://codecov.io/gh/simonw/datasette/pull/1940?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) | Coverage \u0394 | |\n|---|---|---|\n| [datasette/permissions.py](https://codecov.io/gh/simonw/datasette/pull/1940/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison#diff-ZGF0YXNldHRlL3Blcm1pc3Npb25zLnB5) | `100.00% <\u00f8> (\u00f8)` | |\n| [datasette/views/database.py](https://codecov.io/gh/simonw/datasette/pull/1940/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison#diff-ZGF0YXNldHRlL3ZpZXdzL2RhdGFiYXNlLnB5) | `96.26% <\u00f8> (\u00f8)` | |\n| [datasette/views/index.py](https://codecov.io/gh/simonw/datasette/pull/1940/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison#diff-ZGF0YXNldHRlL3ZpZXdzL2luZGV4LnB5) | `96.49% <\u00f8> (\u00f8)` | |\n| [datasette/views/special.py](https://codecov.io/gh/simonw/datasette/pull/1940/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison#diff-ZGF0YXNldHRlL3ZpZXdzL3NwZWNpYWwucHk=) | `79.20% <\u00f8> (-0.21%)` | :arrow_down: |\n| [datasette/views/table.py](https://codecov.io/gh/simonw/datasette/pull/1940/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison#diff-ZGF0YXNldHRlL3ZpZXdzL3RhYmxlLnB5) | `92.57% <\u00f8> (\u00f8)` | |\n| [datasette/\\_\\_init\\_\\_.py](https://codecov.io/gh/simonw/datasette/pull/1940/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison#diff-ZGF0YXNldHRlL19faW5pdF9fLnB5) | `100.00% <100.00%> (\u00f8)` | |\n| [datasette/app.py](https://codecov.io/gh/simonw/datasette/pull/1940/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison#diff-ZGF0YXNldHRlL2FwcC5weQ==) | `94.47% <100.00%> (+0.04%)` | :arrow_up: |\n| [datasette/default\\_permissions.py](https://codecov.io/gh/simonw/datasette/pull/1940/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison#diff-ZGF0YXNldHRlL2RlZmF1bHRfcGVybWlzc2lvbnMucHk=) | `95.20% <100.00%> (+0.39%)` | :arrow_up: |\n| [datasette/hookspecs.py](https://codecov.io/gh/simonw/datasette/pull/1940/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison#diff-ZGF0YXNldHRlL2hvb2tzcGVjcy5weQ==) | `100.00% <100.00%> (\u00f8)` | |\n\nHelp us with your feedback. Take ten seconds to tell us [how you rate us](https://about.codecov.io/nps?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison). Have a feature suggestion? [Share it here.](https://app.codecov.io/gh/feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison)\n\n
\n\n[:umbrella: View full report at Codecov](https://codecov.io/gh/simonw/datasette/pull/1940?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison). \n:loudspeaker: Do you have feedback about the report comment? [Let us know in this issue](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison).\n", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1486011362, "label": "register_permissions() plugin hook"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1947#issuecomment-1347768549", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1947", "id": 1347768549, "node_id": "IC_kwDOBm6k_c5QVVDl", "user": {"value": 9599, "label": "simonw"}, "created_at": "2022-12-13T05:25:56Z", "updated_at": "2022-12-13T22:29:12Z", "author_association": "OWNER", "body": "- [x] I should add a `--database` example to that help text.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1493390939, "label": "UI to create reduced scope tokens from the `/-/create-token` page"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1636#issuecomment-1347647298", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1636", "id": 1347647298, "node_id": "IC_kwDOBm6k_c5QU3dC", "user": {"value": 9599, "label": "simonw"}, "created_at": "2022-12-13T02:08:46Z", "updated_at": "2022-12-13T02:08:46Z", "author_association": "OWNER", "body": "A bunch of the work for this just landed - in particular the new scheme is now documented (even though it doesn't work yet):\r\n\r\nhttps://docs.datasette.io/en/latest/authentication.html#other-permissions-in-metadata", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1138008042, "label": "\"permissions\" propery in metadata for configuring arbitrary permissions"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/pull/1940#issuecomment-1347634128", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1940", "id": 1347634128, "node_id": "IC_kwDOBm6k_c5QU0PQ", "user": {"value": 9599, "label": "simonw"}, "created_at": "2022-12-13T01:51:56Z", "updated_at": "2022-12-13T01:51:56Z", "author_association": "OWNER", "body": "Actually one last thing: I said that the error would only occur if the permissions differed in some way.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1486011362, "label": "register_permissions() plugin hook"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1937#issuecomment-1347770871", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1937", "id": 1347770871, "node_id": "IC_kwDOBm6k_c5QVVn3", "user": {"value": 9599, "label": "simonw"}, "created_at": "2022-12-13T05:30:43Z", "updated_at": "2022-12-13T05:30:43Z", "author_association": "OWNER", "body": "Also you should need `update-row` permission to use the `\"replace\": true` option - I should add that rule to `/-/insert` add well.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1483320357, "label": "/db/-/create API should require insert-rows permission to use row: or rows: option"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1947#issuecomment-1350008636", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1947", "id": 1350008636, "node_id": "IC_kwDOBm6k_c5Qd388", "user": {"value": 9599, "label": "simonw"}, "created_at": "2022-12-13T23:14:33Z", "updated_at": "2022-12-13T23:14:33Z", "author_association": "OWNER", "body": "Checkbox interface looks like this. It's not beautiful but it's good enough for the moment:\r\n\r\n\"image\"\r\n", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1493390939, "label": "UI to create reduced scope tokens from the `/-/create-token` page"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1855#issuecomment-1347759522", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1855", "id": 1347759522, "node_id": "IC_kwDOBm6k_c5QVS2i", "user": {"value": 9599, "label": "simonw"}, "created_at": "2022-12-13T05:11:43Z", "updated_at": "2022-12-13T05:11:43Z", "author_association": "OWNER", "body": "Decided to do the `/-/create-token` UI in a separate ticket:\r\n- #1947", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1423336089, "label": "`datasette create-token` ability to create tokens with a reduced set of permissions"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1946#issuecomment-1347733217", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1946", "id": 1347733217, "node_id": "IC_kwDOBm6k_c5QVMbh", "user": {"value": 9599, "label": "simonw"}, "created_at": "2022-12-13T04:28:45Z", "updated_at": "2022-12-13T04:28:45Z", "author_association": "OWNER", "body": "Demo of the new feature:\r\n```\r\n% datasette create-token --secret s root\r\ndstok_eyJhIjoicm9vdCIsInRva2VuIjoiZHN0b2siLCJ0IjoxNjcwOTA1NjgwfQ.pqSWOwCSNp678hEWl9l5o7m1GaM\r\n% datasette --get /-/actor.json\r\n{\"actor\": null}\r\n% DATASETTE_SECRET=s datasette --get /-/actor.json --token dstok_eyJhIjoicm9vdCIsInRva2VuIjoiZHN0b2siLCJ0IjoxNjcwOTA1NjgwfQ.pqSWOwCSNp678hEWl9l5o7m1GaM\r\n{\"actor\": {\"id\": \"root\", \"token\": \"dstok\"}}\r\n```", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1493339206, "label": "`datasette --get` mechanism for sending tokens"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1939#issuecomment-1347646516", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1939", "id": 1347646516, "node_id": "IC_kwDOBm6k_c5QU3Q0", "user": {"value": 9599, "label": "simonw"}, "created_at": "2022-12-13T02:07:50Z", "updated_at": "2022-12-13T02:07:50Z", "author_association": "OWNER", "body": "Documentation for the new hook: https://docs.datasette.io/en/latest/plugin_hooks.html#register-permissions-datasette", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1485757511, "label": "register_permissions(datasette) plugin hook"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1947#issuecomment-1347760109", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1947", "id": 1347760109, "node_id": "IC_kwDOBm6k_c5QVS_t", "user": {"value": 9599, "label": "simonw"}, "created_at": "2022-12-13T05:12:00Z", "updated_at": "2022-12-13T05:12:00Z", "author_association": "OWNER", "body": "For the UI: I think I'm going to dump a whole bunch of form elements on the page (so you can set up to 3 of each category of limit without any JavaScript), then add JavaScript that hides all but one of the options and gives you a \"add another\" widget that adds multiple more.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1493390939, "label": "UI to create reduced scope tokens from the `/-/create-token` page"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1855#issuecomment-1347731288", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1855", "id": 1347731288, "node_id": "IC_kwDOBm6k_c5QVL9Y", "user": {"value": 9599, "label": "simonw"}, "created_at": "2022-12-13T04:24:50Z", "updated_at": "2022-12-13T04:24:50Z", "author_association": "OWNER", "body": "For the tests for `datasette create-token` it would be useful if `datasette --get` had a mechanism for sending an `Authorization: Bearer X` header.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1423336089, "label": "`datasette create-token` ability to create tokens with a reduced set of permissions"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1947#issuecomment-1349974287", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1947", "id": 1349974287, "node_id": "IC_kwDOBm6k_c5QdvkP", "user": {"value": 9599, "label": "simonw"}, "created_at": "2022-12-13T22:59:44Z", "updated_at": "2022-12-13T22:59:44Z", "author_association": "OWNER", "body": "Got an option group thing working:\r\n\r\n\"image\"\r\n\r\nBut... it strikes me that any time you're considering a `\r\n \r\n \r\n- \r\n+\r\n+
\r\n+ Restrict actions that can be performed using this token\r\n+

All databases and tables

\r\n+ \r\n+\r\n+ {% for database in databases %}\r\n+

All tables in database: {{ database }}

\r\n+ \r\n+ {% endfor %}\r\n+

Specific tables

\r\n+ {% for dbt in database_with_tables %}\r\n+ {% for table in dbt.tables %}\r\n+

{{ dbt.database }}: {{ table }}

\r\n+ \r\n+ {% endfor %}\r\n+ {% endfor %}\r\n+
\r\n+\r\n \r\n+\r\n \r\n {% if token %}\r\n
\r\ndiff --git a/datasette/views/special.py b/datasette/views/special.py\r\nindex 30345d14..48357f87 100644\r\n--- a/datasette/views/special.py\r\n+++ b/datasette/views/special.py\r\n@@ -231,12 +231,37 @@ class CreateTokenView(BaseView):\r\n return await self.render(\r\n [\"create_token.html\"],\r\n request,\r\n- {\"actor\": request.actor},\r\n+ {\r\n+ \"actor\": request.actor,\r\n+ \"all_permissions\": self.ds.permissions.keys(),\r\n+ \"database_permissions\": [\r\n+ key\r\n+ for key, value in self.ds.permissions.items()\r\n+ if value.takes_database\r\n+ ],\r\n+ \"table_permissions\": [\r\n+ key\r\n+ for key, value in self.ds.permissions.items()\r\n+ if value.takes_resource\r\n+ ],\r\n+ \"databases\": [k for k in self.ds.databases.keys() if k != \"_internal\"],\r\n+ \"database_with_tables\": [\r\n+ {\r\n+ \"database\": db.name,\r\n+ \"tables\": await db.table_names(),\r\n+ }\r\n+ for db in self.ds.databases.values()\r\n+ if db.name != \"_internal\"\r\n+ ],\r\n+ },\r\n )\r\n \r\n async def post(self, request):\r\n self.check_permission(request)\r\n post = await request.post_vars()\r\n+ from pprint import pprint\r\n+\r\n+ pprint(post)\r\n errors = []\r\n duration = None\r\n if post.get(\"expire_type\"):\r\n```", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1493390939, "label": "UI to create reduced scope tokens from the `/-/create-token` page"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1855#issuecomment-1347695728", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1855", "id": 1347695728, "node_id": "IC_kwDOBm6k_c5QVDRw", "user": {"value": 9599, "label": "simonw"}, "created_at": "2022-12-13T03:30:09Z", "updated_at": "2022-12-13T03:30:09Z", "author_association": "OWNER", "body": "I just noticed this in the existing code:\r\n\r\nhttps://github.com/simonw/datasette/blob/c5d30b58a1cd1c66bbddcf3561db005543ecaf25/datasette/default_permissions.py#L195-L203\r\n\r\nHard-coding those action names should not be necessary any more, especially now we have `datasette.permissions` for looking up metadata about the permissions.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1423336089, "label": "`datasette create-token` ability to create tokens with a reduced set of permissions"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/pull/1938#issuecomment-1347767048", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1938", "id": 1347767048, "node_id": "IC_kwDOBm6k_c5QVUsI", "user": {"value": 9599, "label": "simonw"}, "created_at": "2022-12-13T05:23:18Z", "updated_at": "2022-12-13T05:23:18Z", "author_association": "OWNER", "body": "I landed this already:\r\n- #1636 ", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1485488236, "label": "\"permissions\" blocks in metadata.json/yaml"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1958#issuecomment-1352644262", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1958", "id": 1352644262, "node_id": "IC_kwDOBm6k_c5Qn7am", "user": {"value": 11729897, "label": "davidhaley"}, "created_at": "2022-12-13T16:49:31Z", "updated_at": "2022-12-13T16:49:52Z", "author_association": "NONE", "body": "I may have found the reason. I don't think the `--root` option is taking effect.\r\n\r\nVisited: http://127.0.0.1:8001/-/permissions\r\n\r\n![image](https://user-images.githubusercontent.com/11729897/207394127-59f8320f-3410-4ff8-869d-b19ab955d67c.png)", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1497909798, "label": "datasette --root running in Docker doesn't reliably show the magic URL"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1948#issuecomment-1347766530", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1948", "id": 1347766530, "node_id": "IC_kwDOBm6k_c5QVUkC", "user": {"value": 9599, "label": "simonw"}, "created_at": "2022-12-13T05:22:19Z", "updated_at": "2022-12-13T05:22:19Z", "author_association": "OWNER", "body": "I tested:\r\n\r\n```\r\n{\"id\": \"root\", \"_r\": {\"a\": \"view-table\"}}\r\n```", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1493404423, "label": "500 error on permission debug page when testing actors with _r"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1947#issuecomment-1350002434", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1947", "id": 1350002434, "node_id": "IC_kwDOBm6k_c5Qd2cC", "user": {"value": 9599, "label": "simonw"}, "created_at": "2022-12-13T23:11:50Z", "updated_at": "2022-12-13T23:11:59Z", "author_association": "OWNER", "body": "I think checkboxes will work well.\r\n\r\nHere's the data I get back from them (as `post_vars()`):\r\n\r\n```\r\n{'all:debug-menu': 'on',\r\n 'all:insert-row': 'on',\r\n 'expire_duration': '',\r\n 'expire_type': '',\r\n 'table:fixtures:delete-row': 'on',\r\n 'table:fixtures:drop-table': 'on',\r\n 'table:fixtures:view-query': 'on'}\r\n```", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1493390939, "label": "UI to create reduced scope tokens from the `/-/create-token` page"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1855#issuecomment-1347675456", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1855", "id": 1347675456, "node_id": "IC_kwDOBm6k_c5QU-VA", "user": {"value": 9599, "label": "simonw"}, "created_at": "2022-12-13T02:57:46Z", "updated_at": "2022-12-13T02:57:46Z", "author_association": "OWNER", "body": "I was going to have the CLI command throw an error if you attempt to use a permission that isn't registered with Datasette, but then I remembered that one of the uses for the CLI tool is to create signed tokens that will work against other Datasette instances (via the `--secret` option) that might have different plugins installed that register different permission names.\r\n\r\nSo I might have it output warnings instead.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1423336089, "label": "`datasette create-token` ability to create tokens with a reduced set of permissions"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1947#issuecomment-1349972480", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1947", "id": 1349972480, "node_id": "IC_kwDOBm6k_c5QdvIA", "user": {"value": 9599, "label": "simonw"}, "created_at": "2022-12-13T22:58:51Z", "updated_at": "2022-12-13T22:58:51Z", "author_association": "OWNER", "body": "I'm experimenting with a `` prototype:\r\n```diff\r\ndiff --git a/datasette/templates/create_token.html b/datasette/templates/create_token.html\r\nindex a94881ed..5bd641cc 100644\r\n--- a/datasette/templates/create_token.html\r\n+++ b/datasette/templates/create_token.html\r\n@@ -6,7 +6,7 @@\r\n \r\n

Create an API token

\r\n \r\n-

This token will allow API access with the same abilities as your current user.

\r\n+

This token will allow API access with the same abilities as your current user, {{ request.actor.id }}

\r\n \r\n {% if errors %}\r\n {% for error in errors %}\r\n@@ -28,6 +28,36 @@\r\n \r\n \r\n
\r\n+\r\n+
\r\n+ Restrict actions that can be performed using this token\r\n+

Restrict actions that can be performed using this token:

\r\n+

All databases and tables:

\r\n+

\r\n+
\r\n+\r\n \r\n \r\n {% if token %}\r\ndiff --git a/datasette/views/special.py b/datasette/views/special.py\r\nindex 30345d14..9d0fcd31 100644\r\n--- a/datasette/views/special.py\r\n+++ b/datasette/views/special.py\r\n@@ -231,7 +231,17 @@ class CreateTokenView(BaseView):\r\n return await self.render(\r\n [\"create_token.html\"],\r\n request,\r\n- {\"actor\": request.actor},\r\n+ {\r\n+ \"actor\": request.actor,\r\n+ \"all_permissions\": self.ds.permissions.keys(),\r\n+ \"database_permissions\": [key for key, value in self.ds.permissions.items() if value.takes_database],\r\n+ \"table_permissions\": [key for key, value in self.ds.permissions.items() if value.takes_resource],\r\n+ \"databases\": self.ds.databases.keys(),\r\n+ \"database_with_tables\": [{\r\n+ \"database\": db.name,\r\n+ \"tables\": await db.table_names(),\r\n+ } for db in self.ds.databases.values()],\r\n+ },\r\n )\r\n \r\n async def post(self, request):\r\n```", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1493390939, "label": "UI to create reduced scope tokens from the `/-/create-token` page"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1855#issuecomment-1347761892", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1855", "id": 1347761892, "node_id": "IC_kwDOBm6k_c5QVTbk", "user": {"value": 9599, "label": "simonw"}, "created_at": "2022-12-13T05:14:25Z", "updated_at": "2022-12-13T05:14:25Z", "author_association": "OWNER", "body": "New documentation: https://docs.datasette.io/en/latest/authentication.html#restricting-the-actions-that-a-token-can-perform", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1423336089, "label": "`datasette create-token` ability to create tokens with a reduced set of permissions"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1914#issuecomment-1347801679", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1914", "id": 1347801679, "node_id": "IC_kwDOBm6k_c5QVdJP", "user": {"value": 9599, "label": "simonw"}, "created_at": "2022-12-13T06:15:54Z", "updated_at": "2022-12-13T06:15:54Z", "author_association": "OWNER", "body": "Should make sure that every API that returns an object as the top level (that's almost all of them) includes `\"ok\": true` to indicate no errors.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1468689139, "label": "Finalize design of JSON for Datasette 1.0"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1947#issuecomment-1350013016", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1947", "id": 1350013016, "node_id": "IC_kwDOBm6k_c5Qd5BY", "user": {"value": 9599, "label": "simonw"}, "created_at": "2022-12-13T23:16:24Z", "updated_at": "2022-12-13T23:17:17Z", "author_association": "OWNER", "body": "Slightly tricky thing here is that it should only show permissions that the user themselves has - on databases and tables that they have permission to access.\r\n\r\nI have a nasty feeling this may require looping through _everything_ and running every permission check, which could get very expensive if there are plugins involved that do their own storage check to resolve a permission.\r\n\r\nIt's that classic permission system problem: how to efficiently iterate through everything the user has permission to do in one go?\r\n\r\nMight be that I have to punt on that, and show the user a list of permissions to select that they might not actually have ability for.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1493390939, "label": "UI to create reduced scope tokens from the `/-/create-token` page"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1855#issuecomment-1347669087", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1855", "id": 1347669087, "node_id": "IC_kwDOBm6k_c5QU8xf", "user": {"value": 9599, "label": "simonw"}, "created_at": "2022-12-13T02:45:15Z", "updated_at": "2022-12-13T02:45:15Z", "author_association": "OWNER", "body": "The hardest piece here is the UI. I'm going to implement the CLI command first.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1423336089, "label": "`datasette create-token` ability to create tokens with a reduced set of permissions"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1636#issuecomment-1347648326", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1636", "id": 1347648326, "node_id": "IC_kwDOBm6k_c5QU3tG", "user": {"value": 9599, "label": "simonw"}, "created_at": "2022-12-13T02:10:02Z", "updated_at": "2022-12-13T02:10:02Z", "author_association": "OWNER", "body": "The implementation for this will go here: https://github.com/simonw/datasette/blob/8bf06a76b51bc9ace7cf72cf0cca8f1da7704ea7/datasette/default_permissions.py#L81-L83\r\n\r\nHere's the start of the tests (currently marked as `xfail`):\r\n\r\nhttps://github.com/simonw/datasette/blob/8bf06a76b51bc9ace7cf72cf0cca8f1da7704ea7/tests/test_permissions.py#L652-L689", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1138008042, "label": "\"permissions\" propery in metadata for configuring arbitrary permissions"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1636#issuecomment-1347655074", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1636", "id": 1347655074, "node_id": "IC_kwDOBm6k_c5QU5Wi", "user": {"value": 9599, "label": "simonw"}, "created_at": "2022-12-13T02:21:04Z", "updated_at": "2022-12-13T02:21:23Z", "author_association": "OWNER", "body": "The thing I'm stuck on at the moment is how to implement it such that an `allow` block for `create-table` at the root of the metadata will be checked correctly.\r\n\r\nMaybe the algorithm when `_resolve_metadata_permissions_blocks(datasette, actor, action, resource)` is called should do this:\r\n\r\n1. If a root permission block matching that action exists, test with that\r\n2. Next, if resource has been passed, check at the database level\r\n3. If the resource included a table/query, check at that level too\r\n\r\nSo everything is keyed off the incoming `action` name.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1138008042, "label": "\"permissions\" propery in metadata for configuring arbitrary permissions"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/pull/1940#issuecomment-1347640542", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1940", "id": 1347640542, "node_id": "IC_kwDOBm6k_c5QU1ze", "user": {"value": 9599, "label": "simonw"}, "created_at": "2022-12-13T02:02:10Z", "updated_at": "2022-12-13T02:02:10Z", "author_association": "OWNER", "body": "This PR ended up bundling part of the implementation of:\r\n- #1636\r\n\r\nI'm going to be bad an NOT untangle that from this before I merge it.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1486011362, "label": "register_permissions() plugin hook"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1943#issuecomment-1347645615", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1943", "id": 1347645615, "node_id": "IC_kwDOBm6k_c5QU3Cv", "user": {"value": 9599, "label": "simonw"}, "created_at": "2022-12-13T02:06:47Z", "updated_at": "2022-12-13T02:06:47Z", "author_association": "OWNER", "body": "This URL is already used for the https://latest.datasette.io/-/permissions tool - but it could include a block on that page that tells you what permissions are available.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1490576818, "label": "`/-/permissions` should list available permissions"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1946#issuecomment-1347732039", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1946", "id": 1347732039, "node_id": "IC_kwDOBm6k_c5QVMJH", "user": {"value": 9599, "label": "simonw"}, "created_at": "2022-12-13T04:26:20Z", "updated_at": "2022-12-13T04:26:20Z", "author_association": "OWNER", "body": "Two options:\r\n\r\n- `--header \"Authorization: Bearer XXX\"` which can be used to send any headers\r\n- `--token XXX` to specify the token, which is then sent using that header\r\n\r\nI like the second option more, simply because there are currently no other headers that affect how Datasette works. `--token` feels obvious and easy to use.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1493339206, "label": "`datasette --get` mechanism for sending tokens"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1958#issuecomment-1352644267", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1958", "id": 1352644267, "node_id": "IC_kwDOBm6k_c5Qn7ar", "user": {"value": 9599, "label": "simonw"}, "created_at": "2022-12-13T18:33:32Z", "updated_at": "2022-12-13T18:33:32Z", "author_association": "OWNER", "body": "When you run `--root` you need to follow the special link that gets output to the console:\r\n\r\n```\r\n% datasette --root\r\nhttp://127.0.0.1:8001/-/auth-token?token=036d8055cc8000e9667f21c1dd08722a9358c066463873ad9566d23d88765c52\r\nINFO: Started server process [53934]\r\nINFO: Waiting for application startup.\r\nINFO: Application startup complete.\r\n```\r\nThat `/-/auth-token?...` link is the one that sets the cookie and lets you in.", "reactions": "{\"total_count\": 1, \"+1\": 1, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1497909798, "label": "datasette --root running in Docker doesn't reliably show the magic URL"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1950#issuecomment-1349855620", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1950", "id": 1349855620, "node_id": "IC_kwDOBm6k_c5QdSmE", "user": {"value": 9599, "label": "simonw"}, "created_at": "2022-12-13T22:08:50Z", "updated_at": "2022-12-13T22:08:50Z", "author_association": "OWNER", "body": "https://github.com/simonw/datasette/blob/d4b98d3924dec625a99236e65b1b169ff957381f/datasette/views/table.py#L392-L400", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1495241162, "label": "Bad ?_sort returns a 500 error, should be a 400"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1947#issuecomment-1347768328", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1947", "id": 1347768328, "node_id": "IC_kwDOBm6k_c5QVVAI", "user": {"value": 9599, "label": "simonw"}, "created_at": "2022-12-13T05:25:31Z", "updated_at": "2022-12-13T22:25:46Z", "author_association": "OWNER", "body": "https://latest.datasette.io/-/create-token currently looks like this:\n\n\n![Image](https://user-images.githubusercontent.com/9599/207458002-7c46940b-22c0-45d3-a668-ec7f1082588c.png)\n\n\nAs a reminder, the CLI options that this needs to provide an alternative to are:\n\nhttps://github.com/simonw/datasette/blob/d4b98d3924dec625a99236e65b1b169ff957381f/docs/cli-reference.rst#L619-L638", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1493390939, "label": "UI to create reduced scope tokens from the `/-/create-token` page"}, "performed_via_github_app": null}