issue_comments
9 rows where issue = 1434094365
This data as json, CSV (advanced)
Suggested facets: created_at (date), updated_at (date)
id ▼ | html_url | issue_url | node_id | user | created_at | updated_at | author_association | body | reactions | issue | performed_via_github_app |
---|---|---|---|---|---|---|---|---|---|---|---|
1301635340 | https://github.com/simonw/datasette/issues/1881#issuecomment-1301635340 | https://api.github.com/repos/simonw/datasette/issues/1881 | IC_kwDOBm6k_c5NlWEM | simonw 9599 | 2022-11-03T04:46:41Z | 2022-11-03T04:46:41Z | OWNER | Built this prototype: ![prototype](https://user-images.githubusercontent.com/9599/199649219-f146e43b-bfb5-45e6-9777-956f21a79887.gif) In building it I realized I needed to know which permissions took a table, a database, both or neither. So I had to bake that into the code. Here's the prototype so far (which includes a prototype of the logic for the `_r` field on actor, see #1855): ```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 databa… | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Tool for simulating permission checks against actors 1434094365 | |
1301635906 | https://github.com/simonw/datasette/issues/1881#issuecomment-1301635906 | https://api.github.com/repos/simonw/datasette/issues/1881 | IC_kwDOBm6k_c5NlWNC | simonw 9599 | 2022-11-03T04:48:09Z | 2022-11-03T04:48:09Z | OWNER | I built this prototype on the http://127.0.0.1:8001/-/allow-debug page, which is open to anyone to visit. But... I just realized that using this tool can leak information - you can use it to guess the names of invisible databases and tables and run theoretical permission checks against them. Using the tool also pollutes the list of permission checks that show up on the root-anlo `/-/permissions` page. So.... I'm going to restrict the usage of this tool to users with access to `/-/permissions` and put it on that page instead. | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Tool for simulating permission checks against actors 1434094365 | |
1301638156 | https://github.com/simonw/datasette/issues/1881#issuecomment-1301638156 | https://api.github.com/repos/simonw/datasette/issues/1881 | IC_kwDOBm6k_c5NlWwM | simonw 9599 | 2022-11-03T04:54:00Z | 2022-11-03T04:54:00Z | OWNER | If I have the permissions defined like this: ```python PERMISSIONS = ( Permission("view-instance", "vi", False, False, True), Permission("view-database", "vd", True, False, True), Permission("view-database-download", "vdd", True, False, True), Permission("view-table", "vt", True, True, True), Permission("view-query", "vq", True, True, True), Permission("insert-row", "ir", True, True, False), Permission("delete-row", "dr", True, True, False), Permission("drop-table", "dt", True, True, False), Permission("execute-sql", "es", True, False, True), Permission("permissions-debug", "pd", False, False, False), Permission("debug-menu", "dm", False, False, False), ) ``` Instead of just calling them by their undeclared names in places like this: ```python await self.ds.permission_allowed( request.actor, "execute-sql", database, default=True ) ``` On the one hand I can ditch that confusing `default=True` option - whether a permission is on by default becomes a characteristic of that `Permission()` itself, which feels much neater. On the other hand though, plugins that introduce their own permissions - like https://datasette.io/plugins/datasette-edit-schema - will need a way to register those permissions with Datasette core. Probably another plugin hook. | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Tool for simulating permission checks against actors 1434094365 | |
1301638918 | https://github.com/simonw/datasette/issues/1881#issuecomment-1301638918 | https://api.github.com/repos/simonw/datasette/issues/1881 | IC_kwDOBm6k_c5NlW8G | simonw 9599 | 2022-11-03T04:56:06Z | 2022-11-03T04:56:06Z | OWNER | I've also introduced a new concept of a permission abbreviation, which like the permission name needs to be globally unique. That's a problem for plugins - they might just be able to guarantee that their permission long-form name is unique among other plugins (through sensible naming conventions) but the thing where they declare a initial-letters-only abbreviation is far more risky. I think abbreviations are optional - they are provided for core permissions but plugins are advised not to use them. Also Datasette could check that the installed plugins do not provide conflicting permissions on startup and refuse to start if they do. | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Tool for simulating permission checks against actors 1434094365 | |
1301639370 | https://github.com/simonw/datasette/issues/1881#issuecomment-1301639370 | https://api.github.com/repos/simonw/datasette/issues/1881 | IC_kwDOBm6k_c5NlXDK | simonw 9599 | 2022-11-03T04:57:21Z | 2022-11-03T04:57:21Z | OWNER | The plugin hook would be called `register_permissions()`, for consistency with `register_routes()` and `register_commands()`. | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Tool for simulating permission checks against actors 1434094365 | |
1301639741 | https://github.com/simonw/datasette/issues/1881#issuecomment-1301639741 | https://api.github.com/repos/simonw/datasette/issues/1881 | IC_kwDOBm6k_c5NlXI9 | simonw 9599 | 2022-11-03T04:58:21Z | 2022-11-03T04:58:21Z | OWNER | The whole `database_name` or `(database_name, table_name)` tuple for resource is a bit of a code smell. Maybe this is a chance to tidy that up too? | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Tool for simulating permission checks against actors 1434094365 | |
1301645921 | https://github.com/simonw/datasette/issues/1881#issuecomment-1301645921 | https://api.github.com/repos/simonw/datasette/issues/1881 | IC_kwDOBm6k_c5NlYph | simonw 9599 | 2022-11-03T05:10:05Z | 2022-12-09T01:38:21Z | OWNER | I'd love to come up with a good short name for the second part of the resource two-tuple, the thing which is usually the name of a table but could also be the name of a SQL view or the name of a canned query. Idea 8th December: why not call it resource? A resource could be a thing that lives inside a database. | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Tool for simulating permission checks against actors 1434094365 | |
1302812918 | https://github.com/simonw/datasette/issues/1881#issuecomment-1302812918 | https://api.github.com/repos/simonw/datasette/issues/1881 | IC_kwDOBm6k_c5Np1j2 | simonw 9599 | 2022-11-04T00:13:05Z | 2022-11-04T00:13:05Z | OWNER | Has tests now. | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Tool for simulating permission checks against actors 1434094365 | |
1302813449 | https://github.com/simonw/datasette/issues/1881#issuecomment-1302813449 | https://api.github.com/repos/simonw/datasette/issues/1881 | IC_kwDOBm6k_c5Np1sJ | simonw 9599 | 2022-11-04T00:14:07Z | 2022-11-04T00:14:07Z | OWNER | Tool is now live here: https://latest-1-0-dev.datasette.io/-/permissions Needs root perms, so access this first: https://latest-1-0-dev.datasette.io/login-as-root | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | Tool for simulating permission checks against actors 1434094365 |
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]);