issue_comments
19 rows where author_association = "OWNER", issue = 1423336089 and user = 9599 sorted by updated_at descending
This data as json, CSV (advanced)
Suggested facets: created_at (date), updated_at (date)
issue 1
- `datasette create-token` ability to create tokens with a reduced set of permissions · 19 ✖
id | html_url | issue_url | node_id | user | created_at | updated_at ▲ | author_association | body | reactions | issue | performed_via_github_app |
---|---|---|---|---|---|---|---|---|---|---|---|
1347761892 | https://github.com/simonw/datasette/issues/1855#issuecomment-1347761892 | https://api.github.com/repos/simonw/datasette/issues/1855 | IC_kwDOBm6k_c5QVTbk | simonw 9599 | 2022-12-13T05:14:25Z | 2022-12-13T05:14:25Z | OWNER | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
`datasette create-token` ability to create tokens with a reduced set of permissions 1423336089 | ||
1347759522 | https://github.com/simonw/datasette/issues/1855#issuecomment-1347759522 | https://api.github.com/repos/simonw/datasette/issues/1855 | IC_kwDOBm6k_c5QVS2i | simonw 9599 | 2022-12-13T05:11:43Z | 2022-12-13T05:11:43Z | OWNER | Decided to do the |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
`datasette create-token` ability to create tokens with a reduced set of permissions 1423336089 | |
1347731288 | https://github.com/simonw/datasette/issues/1855#issuecomment-1347731288 | https://api.github.com/repos/simonw/datasette/issues/1855 | IC_kwDOBm6k_c5QVL9Y | simonw 9599 | 2022-12-13T04:24:50Z | 2022-12-13T04:24:50Z | OWNER | For the tests for |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
`datasette create-token` ability to create tokens with a reduced set of permissions 1423336089 | |
1347726302 | https://github.com/simonw/datasette/issues/1855#issuecomment-1347726302 | https://api.github.com/repos/simonw/datasette/issues/1855 | IC_kwDOBm6k_c5QVKve | simonw 9599 | 2022-12-13T04:16:26Z | 2022-12-13T04:16:26Z | OWNER | I'm going to move this code into |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
`datasette create-token` ability to create tokens with a reduced set of permissions 1423336089 | |
1347707683 | https://github.com/simonw/datasette/issues/1855#issuecomment-1347707683 | https://api.github.com/repos/simonw/datasette/issues/1855 | IC_kwDOBm6k_c5QVGMj | simonw 9599 | 2022-12-13T03:55:35Z | 2022-12-13T04:15:27Z | OWNER | Help looks like this: ``` Usage: datasette create-token [OPTIONS] ID Create a signed API token for the specified actor ID Example:
To only allow create-table:
Or to only allow insert-row against a specific table:
Restricted actions can be specified multiple times using multiple --all, --database, and --resource options. Add --debug to see a decoded version of the token. Options: --secret TEXT Secret used for signing the API tokens [required] -e, --expires-after INTEGER Token should expire after this many seconds -a, --all ACTION Restrict token to this action -d, --database DB ACTION Restrict token to this action on this database -r, --resource DB RESOURCE ACTION Restrict token to this action on this database resource (a table, SQL view or named query) --debug Show decoded token --plugins-dir DIRECTORY Path to directory containing custom plugins --help Show this message and exit. ``` |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
`datasette create-token` ability to create tokens with a reduced set of permissions 1423336089 | |
1347695728 | https://github.com/simonw/datasette/issues/1855#issuecomment-1347695728 | https://api.github.com/repos/simonw/datasette/issues/1855 | IC_kwDOBm6k_c5QVDRw | simonw 9599 | 2022-12-13T03:30:09Z | 2022-12-13T03:30:09Z | OWNER | I just noticed this in the existing code: Hard-coding those action names should not be necessary any more, especially now we have |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
`datasette create-token` ability to create tokens with a reduced set of permissions 1423336089 | |
1347694871 | https://github.com/simonw/datasette/issues/1855#issuecomment-1347694871 | https://api.github.com/repos/simonw/datasette/issues/1855 | IC_kwDOBm6k_c5QVDEX | simonw 9599 | 2022-12-13T03:28:15Z | 2022-12-13T03:28:15Z | OWNER | Initial prototype of the
|
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
`datasette create-token` ability to create tokens with a reduced set of permissions 1423336089 | |
1347693620 | https://github.com/simonw/datasette/issues/1855#issuecomment-1347693620 | https://api.github.com/repos/simonw/datasette/issues/1855 | IC_kwDOBm6k_c5QVCw0 | simonw 9599 | 2022-12-13T03:25:41Z | 2022-12-13T03:25:41Z | OWNER | I'm going to rename "t" in the magic format to "r" for resource. |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
`datasette create-token` ability to create tokens with a reduced set of permissions 1423336089 | |
1347675456 | https://github.com/simonw/datasette/issues/1855#issuecomment-1347675456 | https://api.github.com/repos/simonw/datasette/issues/1855 | IC_kwDOBm6k_c5QU-VA | simonw 9599 | 2022-12-13T02:57:46Z | 2022-12-13T02:57:46Z | OWNER | 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 So I might have it output warnings instead. |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
`datasette create-token` ability to create tokens with a reduced set of permissions 1423336089 | |
1313148519 | https://github.com/simonw/datasette/issues/1855#issuecomment-1313148519 | https://api.github.com/repos/simonw/datasette/issues/1855 | IC_kwDOBm6k_c5ORQ5n | simonw 9599 | 2022-11-14T06:13:43Z | 2022-12-13T02:46:51Z | OWNER | The Right now that command looks like this: ``` % datasette create-token --help Usage: datasette create-token [OPTIONS] ID Create a signed API token for the specified actor ID Options:
--secret TEXT Secret used for signing the API tokens
[required]
-e, --expires-after INTEGER Token should expire after this many seconds
--debug Show decoded token
--help Show this message and exit.
Decoded: {
"a": "root",
"token": "dstok",
"t": 1668406213,
"d": 445
}
Syntax for adding "insert row" for everything, "update row" for all in the "data" database and "delete row" just for the docs / titles table:
UPDATE: I have decided to use the term So |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
`datasette create-token` ability to create tokens with a reduced set of permissions 1423336089 | |
1347669087 | https://github.com/simonw/datasette/issues/1855#issuecomment-1347669087 | https://api.github.com/repos/simonw/datasette/issues/1855 | IC_kwDOBm6k_c5QU8xf | simonw 9599 | 2022-12-13T02:45:15Z | 2022-12-13T02:45:15Z | OWNER | The hardest piece here is the UI. I'm going to implement the CLI command first. |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
`datasette create-token` ability to create tokens with a reduced set of permissions 1423336089 | |
1339952692 | https://github.com/simonw/datasette/issues/1855#issuecomment-1339952692 | https://api.github.com/repos/simonw/datasette/issues/1855 | IC_kwDOBm6k_c5P3g40 | simonw 9599 | 2022-12-06T20:15:50Z | 2022-12-06T20:16:00Z | OWNER | That commit there https://github.com/simonw/datasette/commit/6da17d5529773dfe41b53ed4ce5a6ecb46ed2457 (which will be squash-merged in a PR later on) made it so that I needed that mechanism to write a test that exercised different API permissions. |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
`datasette create-token` ability to create tokens with a reduced set of permissions 1423336089 | |
1302815929 | https://github.com/simonw/datasette/issues/1855#issuecomment-1302815929 | https://api.github.com/repos/simonw/datasette/issues/1855 | IC_kwDOBm6k_c5Np2S5 | simonw 9599 | 2022-11-04T00:19:10Z | 2022-12-03T07:05:51Z | OWNER | Added the tests. |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
`datasette create-token` ability to create tokens with a reduced set of permissions 1423336089 | |
1301646670 | https://github.com/simonw/datasette/issues/1855#issuecomment-1301646670 | https://api.github.com/repos/simonw/datasette/issues/1855 | IC_kwDOBm6k_c5NlY1O | simonw 9599 | 2022-11-03T05:11:26Z | 2022-11-03T05:11:26Z | OWNER | That still needs comprehensive tests before I land it. |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
`datasette create-token` ability to create tokens with a reduced set of permissions 1423336089 | |
1301646493 | https://github.com/simonw/datasette/issues/1855#issuecomment-1301646493 | https://api.github.com/repos/simonw/datasette/issues/1855 | IC_kwDOBm6k_c5NlYyd | simonw 9599 | 2022-11-03T05:11:06Z | 2022-11-03T05:11:06Z | OWNER | Built a prototype of the above: ```diff diff --git a/datasette/default_permissions.py b/datasette/default_permissions.py index 32b0c758..f68aa38f 100644 --- a/datasette/default_permissions.py +++ b/datasette/default_permissions.py @@ -6,8 +6,8 @@ import json import time -@hookimpl(tryfirst=True) -def permission_allowed(datasette, actor, action, resource): +@hookimpl(tryfirst=True, specname="permission_allowed") +def permission_allowed_default(datasette, actor, action, resource): async def inner(): if action in ( "permissions-debug", @@ -57,6 +57,44 @@ def permission_allowed(datasette, actor, action, resource): return inner +@hookimpl(specname="permission_allowed") +def permission_allowed_actor_restrictions(actor, action, resource): + if actor is None: + return None + r = actor.get("_r") + if not _r: + # No restrictions, so we have no opinion + return None + action_initials = "".join([word[0] for word in action.split("-")]) + # If _r is defined then we use those to further restrict the actor + # Crucially, we only use this to say NO (return False) - we never + # use it to return YES (True) because that might over-ride other + # restrictions placed on this actor + all_allowed = _r.get("a") + if all_allowed is not None: + assert isinstance(all_allowed, list) + if action_initials in all_allowed: + return None + # How about for the current database? + if action in ("view-database", "view-database-download", "execute-sql"): + database_allowed = _r.get("d", {}).get(resource) + if database_allowed is not None: + assert isinstance(database_allowed, list) + if action_initials in database_allowed: + return None + # Or the current table? That's any time the resource is (database, table) + if not isinstance(resource, str) and len(resource) == 2: + database, table = resource + table_allowed = _r.get("t", {}).get(database, {}).get(table) + # TODO: What should this do for canned queries? + if table_allowed is not None: + assert isinstance(table_allowed, list) + if action_initials in table_allowed: + return None + # This action is not specifically allowed, so reject it + return False + + @hookimpl def actor_from_request(datasette, request): prefix = "dstok" ``` |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
`datasette create-token` ability to create tokens with a reduced set of permissions 1423336089 | |
1301594495 | https://github.com/simonw/datasette/issues/1855#issuecomment-1301594495 | https://api.github.com/repos/simonw/datasette/issues/1855 | IC_kwDOBm6k_c5NlMF_ | simonw 9599 | 2022-11-03T03:11:17Z | 2022-11-03T03:11:17Z | OWNER | Maybe the way to do this is through a new standard mechanism on the actor: a set of additional restrictions, e.g.:
The way this works is there's a default permission_allowed(datasette, actor, action, resource) hook which only consults these, and crucially just says NO if those rules do not match. In this way it would apply as an extra layer of permission rules over the defaults (which for this |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
`datasette create-token` ability to create tokens with a reduced set of permissions 1423336089 | |
1292962813 | https://github.com/simonw/datasette/issues/1855#issuecomment-1292962813 | https://api.github.com/repos/simonw/datasette/issues/1855 | IC_kwDOBm6k_c5NEQv9 | simonw 9599 | 2022-10-27T04:31:40Z | 2022-10-27T04:31:40Z | OWNER | My hunch on this is that anyone with that level of complex permissions requirements needs to be using a custom authentication plugin which includes much more concrete token rules, rather than the default signed stateless token implementation that ships with Datasette core. |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
`datasette create-token` ability to create tokens with a reduced set of permissions 1423336089 | |
1292959886 | https://github.com/simonw/datasette/issues/1855#issuecomment-1292959886 | https://api.github.com/repos/simonw/datasette/issues/1855 | IC_kwDOBm6k_c5NEQCO | simonw 9599 | 2022-10-27T04:30:07Z | 2022-10-27T04:30:07Z | OWNER | Here's an interesting edge-case to consider: what if a user creates themselves a token for a specific table, then deletes that table, and waits for another user to create a table of the same name... and then uses their previously created token to write to the table that someone else created? Not sure if this is a threat I need to actively consider, but it's worth thinking a little bit about the implications of such a thing - since there will be APIs that allow users to create tables, and there may be cases where people want to have a concept of users "owning" specific tables. This is probably something that could be left for plugins to solve, but it still needs to be understood and potentially documented. There may even be a world in which tracking the timestamp at which a table was created becomes useful - because that could then be baked into API tokens, such that a token created BEFORE the table was created does not grant access to that table. |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
`datasette create-token` ability to create tokens with a reduced set of permissions 1423336089 | |
1291485444 | https://github.com/simonw/datasette/issues/1855#issuecomment-1291485444 | https://api.github.com/repos/simonw/datasette/issues/1855 | IC_kwDOBm6k_c5M-oEE | simonw 9599 | 2022-10-26T04:30:34Z | 2022-10-26T04:30:34Z | OWNER | I'm going to delay working on this until after I have some of the write APIs built to try it against: - #1851 |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
`datasette create-token` ability to create tokens with a reduced set of permissions 1423336089 |
Advanced export
JSON shape: default, array, newline-delimited, object
CREATE TABLE [issue_comments] ( [html_url] TEXT, [issue_url] TEXT, [id] INTEGER PRIMARY KEY, [node_id] TEXT, [user] INTEGER REFERENCES [users]([id]), [created_at] TEXT, [updated_at] TEXT, [author_association] TEXT, [body] TEXT, [reactions] TEXT, [issue] INTEGER REFERENCES [issues]([id]) , [performed_via_github_app] TEXT); CREATE INDEX [idx_issue_comments_issue] ON [issue_comments] ([issue]); CREATE INDEX [idx_issue_comments_user] ON [issue_comments] ([user]);
user 1