html_url,issue_url,id,node_id,user,created_at,updated_at,author_association,body,reactions,issue,performed_via_github_app https://github.com/simonw/datasette/issues/1947#issuecomment-1347760109,https://api.github.com/repos/simonw/datasette/issues/1947,1347760109,IC_kwDOBm6k_c5QVS_t,9599,2022-12-13T05:12:00Z,2022-12-13T05:12:00Z,OWNER,"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.","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1493390939, https://github.com/simonw/datasette/issues/1947#issuecomment-1347768328,https://api.github.com/repos/simonw/datasette/issues/1947,1347768328,IC_kwDOBm6k_c5QVVAI,9599,2022-12-13T05:25:31Z,2022-12-13T22:25:46Z,OWNER,"https://latest.datasette.io/-/create-token currently looks like this: ![Image](https://user-images.githubusercontent.com/9599/207458002-7c46940b-22c0-45d3-a668-ec7f1082588c.png) As a reminder, the CLI options that this needs to provide an alternative to are: https://github.com/simonw/datasette/blob/d4b98d3924dec625a99236e65b1b169ff957381f/docs/cli-reference.rst#L619-L638","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1493390939, https://github.com/simonw/datasette/issues/1947#issuecomment-1347768549,https://api.github.com/repos/simonw/datasette/issues/1947,1347768549,IC_kwDOBm6k_c5QVVDl,9599,2022-12-13T05:25:56Z,2022-12-13T22:29:12Z,OWNER,- [x] I should add a `--database` example to that help text.,"{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1493390939, https://github.com/simonw/datasette/issues/1947#issuecomment-1347775760,https://api.github.com/repos/simonw/datasette/issues/1947,1347775760,IC_kwDOBm6k_c5QVW0Q,9599,2022-12-13T05:38:47Z,2022-12-13T05:38:47Z,OWNER,I'm going to hide the options for reducing the scope of the token inside a details/summary element.,"{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1493390939, https://github.com/simonw/datasette/issues/1947#issuecomment-1349972480,https://api.github.com/repos/simonw/datasette/issues/1947,1349972480,IC_kwDOBm6k_c5QdvIA,9599,2022-12-13T22:58:51Z,2022-12-13T22:58:51Z,OWNER,"I'm experimenting with a `` like this a nested list of checkboxes would actually be better - easier for people to use.","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1493390939, https://github.com/simonw/datasette/issues/1947#issuecomment-1349975255,https://api.github.com/repos/simonw/datasette/issues/1947,1349975255,IC_kwDOBm6k_c5QdvzX,9599,2022-12-13T23:00:11Z,2022-12-13T23:00:11Z,OWNER,"My ` + +
+ Restrict actions that can be performed using this token +

Restrict actions that can be performed using this token:

+

All databases and tables:

+

+
+ {% if token %} diff --git a/datasette/views/special.py b/datasette/views/special.py index 30345d14..9d0fcd31 100644 --- a/datasette/views/special.py +++ b/datasette/views/special.py @@ -231,7 +231,17 @@ class CreateTokenView(BaseView): return await self.render( [""create_token.html""], request, - {""actor"": request.actor}, + { + ""actor"": request.actor, + ""all_permissions"": self.ds.permissions.keys(), + ""database_permissions"": [key for key, value in self.ds.permissions.items() if value.takes_database], + ""table_permissions"": [key for key, value in self.ds.permissions.items() if value.takes_resource], + ""databases"": self.ds.databases.keys(), + ""database_with_tables"": [{ + ""database"": db.name, + ""tables"": await db.table_names(), + } for db in self.ds.databases.values()], + }, ) async def post(self, request): ```","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1493390939, https://github.com/simonw/datasette/issues/1947#issuecomment-1350002434,https://api.github.com/repos/simonw/datasette/issues/1947,1350002434,IC_kwDOBm6k_c5Qd2cC,9599,2022-12-13T23:11:50Z,2022-12-13T23:11:59Z,OWNER,"I think checkboxes will work well. Here's the data I get back from them (as `post_vars()`): ``` {'all:debug-menu': 'on', 'all:insert-row': 'on', 'expire_duration': '', 'expire_type': '', 'table:fixtures:delete-row': 'on', 'table:fixtures:drop-table': 'on', 'table:fixtures:view-query': 'on'} ```","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1493390939, https://github.com/simonw/datasette/issues/1947#issuecomment-1350008636,https://api.github.com/repos/simonw/datasette/issues/1947,1350008636,IC_kwDOBm6k_c5Qd388,9599,2022-12-13T23:14:33Z,2022-12-13T23:14:33Z,OWNER,"Checkbox interface looks like this. It's not beautiful but it's good enough for the moment: ","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1493390939, https://github.com/simonw/datasette/issues/1947#issuecomment-1350013016,https://api.github.com/repos/simonw/datasette/issues/1947,1350013016,IC_kwDOBm6k_c5Qd5BY,9599,2022-12-13T23:16:24Z,2022-12-13T23:17:17Z,OWNER,"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. I 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. It's that classic permission system problem: how to efficiently iterate through everything the user has permission to do in one go? Might 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.","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1493390939, https://github.com/simonw/datasette/issues/1947#issuecomment-1350019528,https://api.github.com/repos/simonw/datasette/issues/1947,1350019528,IC_kwDOBm6k_c5Qd6nI,9599,2022-12-13T23:19:16Z,2022-12-13T23:19:16Z,OWNER,"Here's the checkbox prototype: ```diff diff --git a/datasette/templates/create_token.html b/datasette/templates/create_token.html index a94881ed..1795ebaf 100644 --- a/datasette/templates/create_token.html +++ b/datasette/templates/create_token.html @@ -2,11 +2,20 @@ {% block title %}Create an API token{% endblock %} +{% block extra_head %} + +{% endblock %} + {% block content %}

Create an API token

-

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

+

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

{% if errors %} {% for error in errors %} @@ -27,8 +36,39 @@ - + +
+ Restrict actions that can be performed using this token +

All databases and tables

+ + + {% for database in databases %} +

All tables in database: {{ database }}

+ + {% endfor %} +

Specific tables

+ {% for dbt in database_with_tables %} + {% for table in dbt.tables %} +

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

+ + {% endfor %} + {% endfor %} +
+ + {% if token %}
diff --git a/datasette/views/special.py b/datasette/views/special.py index 30345d14..48357f87 100644 --- a/datasette/views/special.py +++ b/datasette/views/special.py @@ -231,12 +231,37 @@ class CreateTokenView(BaseView): return await self.render( [""create_token.html""], request, - {""actor"": request.actor}, + { + ""actor"": request.actor, + ""all_permissions"": self.ds.permissions.keys(), + ""database_permissions"": [ + key + for key, value in self.ds.permissions.items() + if value.takes_database + ], + ""table_permissions"": [ + key + for key, value in self.ds.permissions.items() + if value.takes_resource + ], + ""databases"": [k for k in self.ds.databases.keys() if k != ""_internal""], + ""database_with_tables"": [ + { + ""database"": db.name, + ""tables"": await db.table_names(), + } + for db in self.ds.databases.values() + if db.name != ""_internal"" + ], + }, ) async def post(self, request): self.check_permission(request) post = await request.post_vars() + from pprint import pprint + + pprint(post) errors = [] duration = None if post.get(""expire_type""): ```","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1493390939, https://github.com/simonw/datasette/issues/1947#issuecomment-1350037572,https://api.github.com/repos/simonw/datasette/issues/1947,1350037572,IC_kwDOBm6k_c5Qd_BE,9599,2022-12-13T23:27:32Z,2022-12-13T23:27:32Z,OWNER,"I'm going to ignore the permissions issue for the moment - I'll allow people to select any permissions they like in any of the databases or tables that are visible to them (don't want to leak the existence of databases/tables to users who shouldn't be able to see them). I think the value of getting this working outweights any potential confusion from not using finely grained permission checks to decide if the user should be able to apply a permission or not. The tokens themselves won't be able to perform `insert-row` or similar if the user doesn't have the ability to do that, even if they selected that checkbox.","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1493390939, https://github.com/simonw/datasette/issues/1947#issuecomment-1350124381,https://api.github.com/repos/simonw/datasette/issues/1947,1350124381,IC_kwDOBm6k_c5QeUNd,9599,2022-12-14T00:07:51Z,2022-12-14T00:07:51Z,OWNER,"Another thing to consider in the future: once Datasette can support thousands of tables (see #417) the list on this page will turn into multiple MBs of HTML, which may cause all kinds of problems - not to mention the overhead of all of those table visibility permission checks. Hopefully by then I'll have a good fix for the permission listings problem: - #1152 And I can apply the same mechanism here.","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1493390939, https://github.com/simonw/datasette/issues/1947#issuecomment-1350125018,https://api.github.com/repos/simonw/datasette/issues/1947,1350125018,IC_kwDOBm6k_c5QeUXa,9599,2022-12-14T00:08:09Z,2022-12-14T00:08:09Z,OWNER,Also: don't show hidden tables.,"{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1493390939, https://github.com/simonw/datasette/issues/1947#issuecomment-1350148192,https://api.github.com/repos/simonw/datasette/issues/1947,1350148192,IC_kwDOBm6k_c5QeaBg,9599,2022-12-14T00:19:06Z,2022-12-14T00:19:06Z,OWNER,"Another option: I could set a time limit - say 200ms - on how long I'm willing to spend calculating permissions before displaying this form First calculate view permissions for tables and databases (and maybe views and canned queries too). Then see if I can check every permission that I'm going to show as a checkbox on this page. If I get that done within the time limit use that to show the options. If I run out of time show all options and maybe include a note saying that some of them may not actually be available.","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1493390939, https://github.com/simonw/datasette/issues/1947#issuecomment-1350215936,https://api.github.com/repos/simonw/datasette/issues/1947,1350215936,IC_kwDOBm6k_c5QeqkA,9599,2022-12-14T01:23:42Z,2022-12-14T01:23:42Z,OWNER,"With tilde-encoding for database and table names the HTML looks like this: ```html ```","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1493390939, https://github.com/simonw/datasette/issues/1947#issuecomment-1350401651,https://api.github.com/repos/simonw/datasette/issues/1947,1350401651,IC_kwDOBm6k_c5QfX5z,9599,2022-12-14T05:03:59Z,2022-12-14T05:03:59Z,OWNER,I shipped a working interface. Could still do with some extra tests.,"{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1493390939, https://github.com/simonw/datasette/issues/1947#issuecomment-1350402667,https://api.github.com/repos/simonw/datasette/issues/1947,1350402667,IC_kwDOBm6k_c5QfYJr,9599,2022-12-14T05:05:10Z,2022-12-14T05:05:10Z,OWNER,"Tests can go here: https://github.com/simonw/datasette/blob/d98a8effb10ce8fe04a03eae42baa8a9cb0ca3f7/tests/test_auth.py#L143-L160","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1493390939, https://github.com/simonw/datasette/issues/1947#issuecomment-1350409537,https://api.github.com/repos/simonw/datasette/issues/1947,1350409537,IC_kwDOBm6k_c5QfZ1B,9599,2022-12-14T05:14:16Z,2022-12-14T05:14:16Z,OWNER,"New interface now live at https://latest.datasette.io/-/create-token It shouldn't be showing `_memory` though.","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1493390939, https://github.com/simonw/datasette/issues/1947#issuecomment-1350413555,https://api.github.com/repos/simonw/datasette/issues/1947,1350413555,IC_kwDOBm6k_c5Qfazz,9599,2022-12-14T05:19:52Z,2022-12-14T05:19:52Z,OWNER,"Maybe I should have kept `_memory` listed for instances that are running with `--crossdb` enabled? Yeah I think I should.","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1493390939, https://github.com/simonw/datasette/issues/1947#issuecomment-1350414402,https://api.github.com/repos/simonw/datasette/issues/1947,1350414402,IC_kwDOBm6k_c5QfbBC,9599,2022-12-14T05:21:07Z,2022-12-14T05:21:07Z,OWNER,"It would be neat not to show write permissions against immutable databases too - and not hard from a performance perspective since it doesn't involve hundreds more permission checks. That will need permissions to grow a flag for if they need a mutable database though, which is a bigger job.","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1493390939, https://github.com/simonw/datasette/issues/1947#issuecomment-1350414961,https://api.github.com/repos/simonw/datasette/issues/1947,1350414961,IC_kwDOBm6k_c5QfbJx,9599,2022-12-14T05:22:00Z,2022-12-14T05:22:00Z,OWNER,I think the next big step for this feature is for me to actually use it to build a few things.,"{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1493390939,