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-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-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 permission in all_permissions %}
+
+ {% endfor %}
+
+
+ {% for database in databases %}
+
All tables in database: {{ database }}
+
+ {% for permission in database_permissions %}
+
+ {% endfor %}
+
+ {% endfor %}
+
Specific tables
+ {% for dbt in database_with_tables %}
+ {% for table in dbt.tables %}
+
{{ dbt.database }}: {{ table }}
+
+ {% for permission in table_permissions %}
+
+ {% endfor %}
+
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-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-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-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-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:
+
+
+
+
{% 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-1349974287,https://api.github.com/repos/simonw/datasette/issues/1947,1349974287,IC_kwDOBm6k_c5QdvkP,9599,2022-12-13T22:59:44Z,2022-12-13T22:59:44Z,OWNER,"Got an option group thing working:
But... it strikes me that any time you're considering a `