{"html_url": "https://github.com/simonw/datasette/issues/843#issuecomment-643676314", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/843", "id": 643676314, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MzY3NjMxNA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-13T20:47:37Z", "updated_at": "2020-06-13T20:47:37Z", "author_association": "OWNER", "body": "I can use this action: https://github.com/codecov/codecov-action", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 638229448, "label": "Configure codecov.io"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/843#issuecomment-643676069", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/843", "id": 643676069, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MzY3NjA2OQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-13T20:45:29Z", "updated_at": "2020-06-13T20:45:29Z", "author_association": "OWNER", "body": "I set up https://codecov.io/gh/simonw/datasette/settings and added a `CODECOV_TOKEN` to the GitHub Actions secrets for this repo.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 638229448, "label": "Configure codecov.io"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/842#issuecomment-643663005", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/842", "id": 643663005, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MzY2MzAwNQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-13T18:51:57Z", "updated_at": "2020-06-13T18:51:57Z", "author_association": "OWNER", "body": "Two potential designs:\r\n\r\n- `_actor_id`, `_request_ip`, `_now_timestamp` - so special reserved parameters\r\n- a SQL function: `update blah set up = special('ip')`\r\n\r\nI fee the first would be easier to implement.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 638212085, "label": "Magic parameters for canned queries"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/841#issuecomment-643661125", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/841", "id": 643661125, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MzY2MTEyNQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-13T18:35:30Z", "updated_at": "2020-06-13T18:36:50Z", "author_association": "OWNER", "body": "I ran export CODECOV_TOKEN=\"f7935cad...\", then ran this:\r\n```\r\ndatasette $ bash <(curl -s https://codecov.io/bash) \r\n _____ _\r\n / ____| | |\r\n| | ___ __| | ___ ___ _____ __\r\n| | / _ \\ / _` |/ _ \\/ __/ _ \\ \\ / /\r\n| |___| (_) | (_| | __/ (_| (_) \\ V /\r\n \\_____\\___/ \\__,_|\\___|\\___\\___/ \\_/\r\n Bash-20200602-f809a24\r\n\r\n\r\nx> No CI provider detected.\r\n Testing inside Docker? http://docs.codecov.io/docs/testing-with-docker\r\n Testing with Tox? https://docs.codecov.io/docs/python#section-testing-with-tox\r\n project root: .\r\n--> token set from env\r\n Yaml not found, that's ok! Learn more at http://docs.codecov.io/docs/codecov-yaml\r\n==> Running gcov in . (disable via -X gcov)\r\n==> Searching for coverage reports in:\r\n + .\r\n -> Found 1 reports\r\n==> Detecting git/mercurial file structure\r\n==> Reading reports\r\n + ./coverage.xml bytes=139174\r\n==> Appending adjustments\r\n https://docs.codecov.io/docs/fixing-reports\r\n -> No adjustments found\r\n==> Gzipping contents\r\n==> Uploading reports\r\n url: https://codecov.io\r\n query: branch=master&commit=0e49842e227a0f1f69d48108c87d17fe0379e548&build=&build_url=&name=&tag=&slug=simonw%2Fdatasette&service=&flags=&pr=&job=\r\n -> Pinging Codecov\r\nhttps://codecov.io/upload/v4?package=bash-20200602-f809a24&token=secret&branch=master&commit=0e49842e227a0f1f69d48108c87d17fe0379e548&build=&build_url=&name=&tag=&slug=simonw%2Fdatasette&service=&flags=&pr=&job=\r\n -> Uploading\r\n -> View reports at https://codecov.io/github/simonw/datasette/commit/0e49842e227a0f1f69d48108c87d17fe0379e548\r\n```\r\nBut https://codecov.io/github/simonw/datasette/commit/0e49842e227a0f1f69d48108c87d17fe0379e548 is a 404, so it doesn't seem to have worked?\r\n\r\nUPDATE: It works now, took about 30 seconds before the report showed up at that URL.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 638104520, "label": "Research feasibility of 100% test coverage"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/841#issuecomment-643660757", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/841", "id": 643660757, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MzY2MDc1Nw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-13T18:32:20Z", "updated_at": "2020-06-13T18:32:20Z", "author_association": "OWNER", "body": "Looking at options for publishing coverage reports:\r\n\r\n* https://github.com/codecov/codecov-action\r\n* https://github.com/coveralls-clients/coveralls-python\r\n\r\nI'm going to try https://codecov.io/", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 638104520, "label": "Research feasibility of 100% test coverage"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/841#issuecomment-643660427", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/841", "id": 643660427, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MzY2MDQyNw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-13T18:29:30Z", "updated_at": "2020-06-13T18:29:36Z", "author_association": "OWNER", "body": "This one looks easy enough to fix:\r\n\r\n\"Coverage_for_datasette_actor_auth_cookie_py__84_\"", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 638104520, "label": "Research feasibility of 100% test coverage"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/841#issuecomment-643658036", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/841", "id": 643658036, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MzY1ODAzNg==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-13T18:08:13Z", "updated_at": "2020-06-13T18:08:13Z", "author_association": "OWNER", "body": "From digging through that report it looks like the majority stuff that isn't fully covered is corner-cases... which are the kind of things I really do want the tests to catch.\r\n\r\nI'm not entirely ready to commit to 100%, but I'm going to start digging through and seeing how close I can get. If I can get to 98% (I'm on 91% already) I may as well push all the way to 100.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 638104520, "label": "Research feasibility of 100% test coverage"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/841#issuecomment-643657287", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/841", "id": 643657287, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MzY1NzI4Nw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-13T18:01:39Z", "updated_at": "2020-06-13T18:01:39Z", "author_association": "OWNER", "body": "Added `--cov-report html` and got this report: https://static.simonwillison.net/static/2020/htmlcov-issue-841/index.html", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 638104520, "label": "Research feasibility of 100% test coverage"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/841#issuecomment-643656053", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/841", "id": 643656053, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MzY1NjA1Mw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-13T17:50:34Z", "updated_at": "2020-06-13T17:50:34Z", "author_association": "OWNER", "body": "Added a `.coveragerc` file:\r\n```\r\n[run]\r\nomit = datasette/_version.py, datasette/utils/shutil_backport.py\r\n```\r\nAnd ran again: `pytest --cov=datasette --cov-config=.coveragerc`\r\n```\r\nName Stmts Miss Cover\r\n------------------------------------------------------\r\ndatasette/__init__.py 3 0 100%\r\ndatasette/__main__.py 3 3 0%\r\ndatasette/actor_auth_cookie.py 19 3 84%\r\ndatasette/app.py 499 27 95%\r\ndatasette/cli.py 157 45 71%\r\ndatasette/database.py 233 17 93%\r\ndatasette/default_permissions.py 39 0 100%\r\ndatasette/facets.py 209 24 89%\r\ndatasette/filters.py 122 7 94%\r\ndatasette/hookspecs.py 19 0 100%\r\ndatasette/inspect.py 37 23 38%\r\ndatasette/plugins.py 34 6 82%\r\ndatasette/publish/__init__.py 0 0 100%\r\ndatasette/publish/cloudrun.py 55 2 96%\r\ndatasette/publish/common.py 19 1 95%\r\ndatasette/publish/heroku.py 95 13 86%\r\ndatasette/renderer.py 63 4 94%\r\ndatasette/sql_functions.py 4 0 100%\r\ndatasette/tracer.py 85 16 81%\r\ndatasette/utils/__init__.py 503 31 94%\r\ndatasette/utils/asgi.py 253 25 90%\r\ndatasette/version.py 4 0 100%\r\ndatasette/views/__init__.py 0 0 100%\r\ndatasette/views/base.py 288 19 93%\r\ndatasette/views/database.py 120 2 98%\r\ndatasette/views/index.py 57 2 96%\r\ndatasette/views/special.py 72 16 78%\r\ndatasette/views/table.py 418 18 96%\r\n------------------------------------------------------\r\nTOTAL 3410 304 91%\r\n```", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 638104520, "label": "Research feasibility of 100% test coverage"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/841#issuecomment-643655108", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/841", "id": 643655108, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MzY1NTEwOA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-13T17:43:15Z", "updated_at": "2020-06-13T17:43:15Z", "author_association": "OWNER", "body": "Using https://pypi.org/project/pytest-cov/ and running `pytest --cov=datasette`:\r\n```\r\n---------- coverage: platform darwin, python 3.7.7-final-0 -----------\r\nName Stmts Miss Cover\r\n--------------------------------------------------------\r\ndatasette/__init__.py 3 0 100%\r\ndatasette/__main__.py 3 3 0%\r\ndatasette/_version.py 277 152 45%\r\ndatasette/actor_auth_cookie.py 19 3 84%\r\ndatasette/app.py 499 27 95%\r\ndatasette/cli.py 157 45 71%\r\ndatasette/database.py 233 17 93%\r\ndatasette/default_permissions.py 39 0 100%\r\ndatasette/facets.py 209 24 89%\r\ndatasette/filters.py 122 7 94%\r\ndatasette/hookspecs.py 19 0 100%\r\ndatasette/inspect.py 37 23 38%\r\ndatasette/plugins.py 34 6 82%\r\ndatasette/publish/__init__.py 0 0 100%\r\ndatasette/publish/cloudrun.py 55 2 96%\r\ndatasette/publish/common.py 19 1 95%\r\ndatasette/publish/heroku.py 95 13 86%\r\ndatasette/renderer.py 63 4 94%\r\ndatasette/sql_functions.py 4 0 100%\r\ndatasette/tracer.py 85 16 81%\r\ndatasette/utils/__init__.py 503 31 94%\r\ndatasette/utils/asgi.py 253 25 90%\r\ndatasette/utils/shutil_backport.py 44 40 9%\r\ndatasette/version.py 4 0 100%\r\ndatasette/views/__init__.py 0 0 100%\r\ndatasette/views/base.py 288 19 93%\r\ndatasette/views/database.py 120 2 98%\r\ndatasette/views/index.py 57 2 96%\r\ndatasette/views/special.py 72 16 78%\r\ndatasette/views/table.py 418 18 96%\r\n--------------------------------------------------------\r\nTOTAL 3731 496 87%\r\n```", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 638104520, "label": "Research feasibility of 100% test coverage"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/834#issuecomment-643648359", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/834", "id": 643648359, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MzY0ODM1OQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-13T16:47:29Z", "updated_at": "2020-06-13T16:47:29Z", "author_association": "OWNER", "body": "Implementing this is proving surprisingly tricky, because of the need to be able to optionally `await` the returned value. It's a bit of a fiddle to get this to work within unit tests because they run in non-async functions - due to this cunning `async_to_sync` usage in the test client:\r\n\r\nhttps://github.com/simonw/datasette/blob/b906030235efbdff536405d66078f4868ce0d3bd/tests/fixtures.py#L115-L133\r\n\r\nI could switch to using `async def test_*` functions decorated with `@pytest.mark.asyncio` but I'd rather not re-engineer the entire test suite just for this one feature, so I'll try to find another way.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 637342551, "label": "startup() plugin hook"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/841#issuecomment-643576372", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/841", "id": 643576372, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MzU3NjM3Mg==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-13T06:08:34Z", "updated_at": "2020-06-13T06:08:34Z", "author_association": "OWNER", "body": "Starlette achieves this. https://github.com/encode/starlette", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 638104520, "label": "Research feasibility of 100% test coverage"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/834#issuecomment-643510240", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/834", "id": 643510240, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MzUxMDI0MA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-12T22:40:26Z", "updated_at": "2020-06-12T22:40:26Z", "author_association": "OWNER", "body": "Another use-case: plugins that need their own database with the correct tables. They can write to the database on startup to create their tables.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 637342551, "label": "startup() plugin hook"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/834#issuecomment-643509358", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/834", "id": 643509358, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MzUwOTM1OA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-12T22:36:37Z", "updated_at": "2020-06-12T22:36:37Z", "author_association": "OWNER", "body": "This should be able to optionally return an async function which is then awaited.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 637342551, "label": "startup() plugin hook"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/805#issuecomment-643501428", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/805", "id": 643501428, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MzUwMTQyOA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-12T22:06:08Z", "updated_at": "2020-06-12T22:06:08Z", "author_association": "OWNER", "body": "This needs the `startup` hook, see https://github.com/simonw/datasette/issues/834#issuecomment-643501064", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 632724154, "label": "Writable canned queries live demo on Glitch"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/834#issuecomment-643501064", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/834", "id": 643501064, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MzUwMTA2NA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-12T22:04:43Z", "updated_at": "2020-06-12T22:04:43Z", "author_association": "OWNER", "body": "Another use-case for this: I want to use the `--root` option on Glitch but it gives me a 127.0.0.1 URL. Glitch has a `PROJECT_DOMAIN` environment variable which tells me the URL. A `datasette-glitch` plugin could use a `startup` hook to output the correct login URL.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 637342551, "label": "startup() plugin hook"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/840#issuecomment-643454625", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/840", "id": 643454625, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MzQ1NDYyNQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-12T19:47:38Z", "updated_at": "2020-06-12T19:47:53Z", "author_association": "OWNER", "body": "Another problem: what to display in the \"you are logged in as\", since we don't dictate an actor design.\r\n\r\nI'm going to use a includes template for this that can easily be over-ridden by administrators or by plugins.\r\n\r\nThe default will look for the first available of the following keys:\r\n\r\n- display\r\n- name\r\n- username\r\n- login\r\n- id", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 637966833, "label": "Log out mechanism for clearing ds_actor cookie"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/840#issuecomment-643453128", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/840", "id": 643453128, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MzQ1MzEyOA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-12T19:43:15Z", "updated_at": "2020-06-12T19:43:15Z", "author_association": "OWNER", "body": "I don't like how this often involves a logout link that can be maliciously activated.\r\n\r\nI'm going to use a CSRF protected form button styled to look like a link instead.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 637966833, "label": "Log out mechanism for clearing ds_actor cookie"}, "performed_via_github_app": null} {"html_url": "https://github.com/dogsheep/github-to-sqlite/issues/40#issuecomment-643414646", "issue_url": "https://api.github.com/repos/dogsheep/github-to-sqlite/issues/40", "id": 643414646, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MzQxNDY0Ng==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-12T18:06:48Z", "updated_at": "2020-06-12T18:06:48Z", "author_association": "MEMBER", "body": "That fixed it.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 637899539, "label": "Demo deploy is broken"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/sqlite-utils/issues/115#issuecomment-643406939", "issue_url": "https://api.github.com/repos/simonw/sqlite-utils/issues/115", "id": 643406939, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MzQwNjkzOQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-12T17:51:11Z", "updated_at": "2020-06-12T17:51:11Z", "author_association": "OWNER", "body": "https://github.com/simonw/sqlite-utils/blob/03ee97d2258254581bea72842518904fc1cbe60f/tests/test_cli.py#L1112-L1128", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 637889964, "label": "Ability to execute insert/update statements with the CLI"}, "performed_via_github_app": null} {"html_url": "https://github.com/dogsheep/github-to-sqlite/issues/40#issuecomment-643393506", "issue_url": "https://api.github.com/repos/dogsheep/github-to-sqlite/issues/40", "id": 643393506, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MzM5MzUwNg==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-12T17:21:14Z", "updated_at": "2020-06-12T17:21:14Z", "author_association": "MEMBER", "body": "I only install SQLite for this:\r\n\r\nhttps://github.com/dogsheep/github-to-sqlite/blob/c0d54e0260468be38152293df5abd775c068495d/.github/workflows/deploy-demo.yml#L77-L78\r\n\r\nI'm going to remove the need to install sqlite3 by making this possible with sqlite-utils: https://github.com/simonw/sqlite-utils/issues/115", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 637899539, "label": "Demo deploy is broken"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/838#issuecomment-643083451", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/838", "id": 643083451, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MzA4MzQ1MQ==", "user": {"value": 79913, "label": "tsibley"}, "created_at": "2020-06-12T06:04:14Z", "updated_at": "2020-06-12T06:04:14Z", "author_association": "NONE", "body": "Hmm, I haven't tried removing `ProxyPassReverse`, but it doesn't touch the HTML, which is the issue I'm seeing. You can read the [documentation here](https://httpd.apache.org/docs/2.4/mod/mod_proxy.html#proxypassreverse). `ProxyPassReverse` is a standard directive when proxying with Apache. I've used it dozens of times with other applications.\r\n\r\nLooking a little more at the code, I think the issue here is that the behaviour of `base_url` makes sense when Datasette is _mounted_ at a path within a larger application, but not when HTTP requests are being _proxied_ to it.\r\n\r\nIn a _mount_ situation, it is perfectly fine to construct URLs reusing the domain and path from the request. In a _proxy_ situation, it never is, as the domain and path in the request are not the domain and path that the non-proxy client actually needs to use. That is, links which include the Apache \u2192 Datasette request origin, `localhost:8001`, instead of the browser \u2192 Apache request origin, `example.com`, will be broken.\r\n\r\nThe tests you pointed to also reflect this in two ways:\r\n\r\n1. They strip a leading `http://localhost`, allowing such URLs in the facet links to pass, but inclusion of that in a proxy situation would mean the URL is broken.\r\n\r\n2. The test client emits direct ASGI events instead of actual proxied HTTP requests. The headers of these ASGI events don't reflect the way an HTTP proxy works; instead they pass through the original request path which contains `base_url`. This works because Datasette responds to requests equivalently at either `/\u2026` or `/{base_url}/\u2026`, which makes some sense in a _mount_ situation but is unconventional (albeit workable) for a proxied app.\r\n\r\nApps that support being proxied automatically support being mounted, but apps that only support being mounted don't automatically support being proxied.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 637395097, "label": "Incorrect URLs when served behind a proxy with base_url set"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/806#issuecomment-643010591", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/806", "id": 643010591, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MzAxMDU5MQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-12T01:13:06Z", "updated_at": "2020-06-12T01:13:06Z", "author_association": "OWNER", "body": "Tests are passing again: https://github.com/simonw/datasette/commit/9ae0d483ead93c0832142e5dc85959ae3c8f73ea", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 632753851, "label": "Release Datasette 0.44"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/806#issuecomment-643000948", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/806", "id": 643000948, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MzAwMDk0OA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-12T00:34:21Z", "updated_at": "2020-06-12T00:34:21Z", "author_association": "OWNER", "body": "I'm going to add https://github.com/simonw/datasette-auth-tokens and https://github.com/simonw/datasette-permissions-sql to the documentation and release notes in a few places.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 632753851, "label": "Release Datasette 0.44"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/806#issuecomment-642998097", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/806", "id": 642998097, "node_id": "MDEyOklzc3VlQ29tbWVudDY0Mjk5ODA5Nw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-12T00:26:00Z", "updated_at": "2020-06-12T00:26:00Z", "author_association": "OWNER", "body": "OK, I'm ready to ship. Last check of the release notes, then I'll update the news section in the README and release 0.44!", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 632753851, "label": "Release Datasette 0.44"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/838#issuecomment-642993277", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/838", "id": 642993277, "node_id": "MDEyOklzc3VlQ29tbWVudDY0Mjk5MzI3Nw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-12T00:18:26Z", "updated_at": "2020-06-12T00:18:50Z", "author_association": "OWNER", "body": "Have you tried this without the `ProxyPassReverse` directive? I'm worried that might be confusing Datasette.\r\n\r\nThis is the test I used to ensure this feature works - it scrapes all of the links on a bunch of different pages. Could it be missing something here?\r\n\r\nhttps://github.com/simonw/datasette/blob/647c5ff0f3e8140f40d7f41f0874ce4e1f4df65c/tests/test_html.py#L1233-L1274\r\n\r\n", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 637395097, "label": "Incorrect URLs when served behind a proxy with base_url set"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/824#issuecomment-642991513", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/824", "id": 642991513, "node_id": "MDEyOklzc3VlQ29tbWVudDY0Mjk5MTUxMw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-12T00:11:50Z", "updated_at": "2020-06-12T00:11:50Z", "author_association": "OWNER", "body": "Done: https://github.com/simonw/datasette-auth-tokens and https://pypi.org/project/datasette-auth-tokens/", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 635108074, "label": "Example authentication plugin"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/833#issuecomment-642958225", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/833", "id": 642958225, "node_id": "MDEyOklzc3VlQ29tbWVudDY0Mjk1ODIyNQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-11T22:15:32Z", "updated_at": "2020-06-11T22:15:32Z", "author_association": "OWNER", "body": "https://github.com/simonw/datasette/blob/29c5ff493ad7918b8fc44ea7920b41530e56dd5d/tests/test_permissions.py#L327-L348", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 637253789, "label": "/-/metadata and so on should respect view-instance permission"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/824#issuecomment-642953605", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/824", "id": 642953605, "node_id": "MDEyOklzc3VlQ29tbWVudDY0Mjk1MzYwNQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-11T22:02:32Z", "updated_at": "2020-06-11T22:02:32Z", "author_association": "OWNER", "body": "`datasette-auth-tokens` can be the name. I can get a simple initial version of it running pretty quickly.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 635108074, "label": "Example authentication plugin"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/824#issuecomment-642952962", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/824", "id": 642952962, "node_id": "MDEyOklzc3VlQ29tbWVudDY0Mjk1Mjk2Mg==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-11T22:01:58Z", "updated_at": "2020-06-11T22:01:58Z", "author_association": "OWNER", "body": "Alternative idea: a plugin that handles Bearer token authentication. Uses `metadata.json` with secret plugin values to map an incoming token to an actor dictionary, which can then be mapped to permissions.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 635108074, "label": "Example authentication plugin"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/824#issuecomment-642951150", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/824", "id": 642951150, "node_id": "MDEyOklzc3VlQ29tbWVudDY0Mjk1MTE1MA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-11T22:00:17Z", "updated_at": "2020-06-11T22:00:17Z", "author_association": "OWNER", "body": "I got this working: https://github.com/simonw/datasette-auth-github/pull/64\r\n\r\nJust one problem: it uses the existing `ds_actor` cookie, which means it doesn't actually exercise the `actor_from_request` plugin!\r\n\r\nIt does use `register_routes` though.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 635108074, "label": "Example authentication plugin"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/220#issuecomment-642944645", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/220", "id": 642944645, "node_id": "MDEyOklzc3VlQ29tbWVudDY0Mjk0NDY0NQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-11T21:49:55Z", "updated_at": "2020-06-11T21:49:55Z", "author_association": "OWNER", "body": "I'm OK with not implementing this - I've got used to the existing mechanism, and it doesn't frustrate me enough to work on this more.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 314847571, "label": "Investigate syntactic sugar for plugins"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/832#issuecomment-642907021", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/832", "id": 642907021, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MjkwNzAyMQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-11T20:20:35Z", "updated_at": "2020-06-11T20:20:35Z", "author_association": "OWNER", "body": "I think the new `.check_permissions()` should be a documented utility that is available to plugins.\r\n Maybe a method on `datasette`?", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 636722501, "label": "Having view-table permission but NOT view-database should still grant access to /db/table"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/832#issuecomment-642906681", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/832", "id": 642906681, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MjkwNjY4MQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-11T20:19:47Z", "updated_at": "2020-06-11T20:20:02Z", "author_association": "OWNER", "body": "So for the following:\r\n```\r\nawait self.check_permissions(request, [\r\n (\"view-table\", (database, table)),\r\n (\"view-database\", database),\r\n \"view-instance\",\r\n])\r\n```\r\nThe logic is: if the first test returns `True`, you get access. If it returns `False` you are denied. If it says `None` then move on to the next check in the list and repeat.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 636722501, "label": "Having view-table permission but NOT view-database should still grant access to /db/table"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/833#issuecomment-642905424", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/833", "id": 642905424, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MjkwNTQyNA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-11T20:16:41Z", "updated_at": "2020-06-11T20:16:41Z", "author_association": "OWNER", "body": "I'll add a new test in `test_permissions.py` which locks down an instance and then loops through paths as the anonymous user making sure they aren't accessible.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 637253789, "label": "/-/metadata and so on should respect view-instance permission"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/833#issuecomment-642902208", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/833", "id": 642902208, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MjkwMjIwOA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-11T20:08:57Z", "updated_at": "2020-06-11T20:08:57Z", "author_association": "OWNER", "body": "I'm tempted to add a `view-instance` check before routing any URLs, but that wouldn't be compatible with the idea in #832 that having `view-table` should be enough to view a table even if you don't pass `view-instance`.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 637253789, "label": "/-/metadata and so on should respect view-instance permission"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/833#issuecomment-642874724", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/833", "id": 642874724, "node_id": "MDEyOklzc3VlQ29tbWVudDY0Mjg3NDcyNA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-11T19:07:49Z", "updated_at": "2020-06-11T19:07:49Z", "author_association": "OWNER", "body": "A live demo running the `datasette-auth-github` plugin will help demonstrate this.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 637253789, "label": "/-/metadata and so on should respect view-instance permission"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/801#issuecomment-642870553", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/801", "id": 642870553, "node_id": "MDEyOklzc3VlQ29tbWVudDY0Mjg3MDU1Mw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-11T18:58:49Z", "updated_at": "2020-06-11T18:58:49Z", "author_association": "OWNER", "body": "I've implemented this in a plugin instead: https://github.com/simonw/datasette-permissions-sql", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 631932926, "label": "allow_by_query setting for configuring permissions with a SQL statement"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/832#issuecomment-642795966", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/832", "id": 642795966, "node_id": "MDEyOklzc3VlQ29tbWVudDY0Mjc5NTk2Ng==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-11T16:37:21Z", "updated_at": "2020-06-11T16:37:21Z", "author_association": "OWNER", "body": "How would I document this? Probably in another section on https://datasette.readthedocs.io/en/latest/authentication.html#permissions\r\n\r\nBut I'd also need to add documentation to the individual views stating what permissions are checked and in what order. I could do that on this page: https://datasette.readthedocs.io/en/latest/pages.html", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 636722501, "label": "Having view-table permission but NOT view-database should still grant access to /db/table"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/pull/809#issuecomment-642772344", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/809", "id": 642772344, "node_id": "MDEyOklzc3VlQ29tbWVudDY0Mjc3MjM0NA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-11T16:01:15Z", "updated_at": "2020-06-11T16:01:15Z", "author_association": "OWNER", "body": "```\r\ndatasette package fixtures.db --secret woot --branch master\r\nSending build context to Docker daemon 260.6kB\r\nStep 1/9 : FROM python:3.8\r\n3.8: Pulling from library/python\r\ne9afc4f90ab0: Downloading [=======> ] 7.195MB/50.39MB\r\n989e6b19a265: Downloading [============================> ] 4.475MB/7.812MB\r\naf14b6c2f878: Downloading [===========================> ] 5.422MB/9.996MB\r\n5573c4b30949: Waiting \r\n11a88e764313: Waiting \r\nee776f0e36af: Waiting \r\n513c90a1afc3: Waiting \r\ndf9b9e95bdb9: Waiting \r\n86c9edb54464: Waiting \r\n...\r\ndatasette package fixtures.db --secret woot --branch master\r\ndocker run -p 8001:8001 a155798bd842\r\n```\r\nThis works too.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 632919570, "label": "Publish secrets"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/pull/809#issuecomment-642754589", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/809", "id": 642754589, "node_id": "MDEyOklzc3VlQ29tbWVudDY0Mjc1NDU4OQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-11T15:45:25Z", "updated_at": "2020-06-11T15:45:25Z", "author_association": "OWNER", "body": " datasette publish cloudrun fixtures.db --service datasette-publish-secret --branch=master\r\n\r\nhttps://datasette-publish-secret-j7hipcg4aq-uw.a.run.app/-/messages", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 632919570, "label": "Publish secrets"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/pull/809#issuecomment-642750790", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/809", "id": 642750790, "node_id": "MDEyOklzc3VlQ29tbWVudDY0Mjc1MDc5MA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-11T15:42:23Z", "updated_at": "2020-06-11T15:42:23Z", "author_association": "OWNER", "body": " datasette publish heroku fixtures.db -n datasette-publish-secret --branch=master\r\n\r\nhttps://datasette-publish-secret.herokuapp.com/-/messages - Heroku works.\r\n", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 632919570, "label": "Publish secrets"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/pull/809#issuecomment-642745518", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/809", "id": 642745518, "node_id": "MDEyOklzc3VlQ29tbWVudDY0Mjc0NTUxOA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-11T15:38:51Z", "updated_at": "2020-06-11T15:38:51Z", "author_association": "OWNER", "body": "The way to manually test this is to publish a database to each provider and then check that the `/-/messages` debug tool works.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 632919570, "label": "Publish secrets"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/832#issuecomment-642741930", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/832", "id": 642741930, "node_id": "MDEyOklzc3VlQ29tbWVudDY0Mjc0MTkzMA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-11T15:35:53Z", "updated_at": "2020-06-11T15:36:05Z", "author_association": "OWNER", "body": "May the fix here is to implement a `.check_permissions()` method which passes when the first permission passes?\r\n```python\r\nawait self.check_permissions(request, [\r\n (\"view-table\", (database, table)),\r\n (\"view-database\", database),\r\n \"view-instance\",\r\n])\r\n```", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 636722501, "label": "Having view-table permission but NOT view-database should still grant access to /db/table"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/394#issuecomment-642522285", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/394", "id": 642522285, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MjUyMjI4NQ==", "user": {"value": 58298410, "label": "LVerneyPEReN"}, "created_at": "2020-06-11T09:15:19Z", "updated_at": "2020-06-11T09:15:19Z", "author_association": "NONE", "body": "Hi @wragge,\r\n\r\nThis looks great, thanks for the share! I refactored it into a self-contained function, binding on a random available TCP port (multi-user context). I am using subprocess API directly since the `%run` magic was leaving defunct process behind :/\r\n\r\n![image](https://user-images.githubusercontent.com/58298410/84367566-b5d0d500-abd4-11ea-96e2-f5c05a28e506.png)\r\n\r\n```python\r\nimport socket\r\n\r\nfrom signal import SIGINT\r\nfrom subprocess import Popen, PIPE\r\n\r\nfrom IPython.display import display, HTML\r\nfrom notebook.notebookapp import list_running_servers\r\n\r\n\r\ndef get_free_tcp_port():\r\n \"\"\"\r\n Get a free TCP port.\r\n \"\"\"\r\n tcp = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\r\n tcp.bind(('', 0))\r\n _, port = tcp.getsockname()\r\n tcp.close()\r\n return port\r\n\r\n\r\ndef datasette(database):\r\n \"\"\"\r\n Run datasette on an SQLite database.\r\n \"\"\"\r\n # Get current running servers\r\n servers = list_running_servers()\r\n\r\n # Get the current base url\r\n base_url = next(servers)['base_url']\r\n\r\n # Get a free port\r\n port = get_free_tcp_port()\r\n\r\n # Create a base url for Datasette suing the proxy path\r\n proxy_url = f'{base_url}proxy/absolute/{port}/'\r\n\r\n # Display a link to Datasette\r\n display(HTML(f'

View Datasette (Click on the stop button to close the Datasette server)

'))\r\n\r\n # Launch Datasette\r\n with Popen(\r\n [\r\n 'python', '-m', 'datasette', '--',\r\n database,\r\n '--port', str(port),\r\n '--config', f'base_url:{proxy_url}'\r\n ],\r\n stdout=PIPE,\r\n stderr=PIPE,\r\n bufsize=1,\r\n universal_newlines=True\r\n ) as p:\r\n print(p.stdout.readline(), end='')\r\n while True:\r\n try:\r\n line = p.stderr.readline()\r\n if not line:\r\n break\r\n print(line, end='')\r\n exit_code = p.poll()\r\n except KeyboardInterrupt:\r\n p.send_signal(SIGINT)\r\n```\r\n\r\nIdeally, I'd like some extra magic to notify users when they are leaving the closing the notebook tab and make them terminate the running datasette processes. I'll be looking for it.", "reactions": "{\"total_count\": 1, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 1, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 396212021, "label": "base_url configuration setting"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/818#issuecomment-642420375", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/818", "id": 642420375, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MjQyMDM3NQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-11T05:40:07Z", "updated_at": "2020-06-11T05:40:07Z", "author_association": "OWNER", "body": "https://github.com/simonw/datasette-permissions-sql is now released as a 0.1a here: https://pypi.org/project/datasette-permissions-sql/", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 634917088, "label": "Example permissions plugin"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/832#issuecomment-642412017", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/832", "id": 642412017, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MjQxMjAxNw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-11T05:13:59Z", "updated_at": "2020-06-11T05:13:59Z", "author_association": "OWNER", "body": "Relevant code:\r\n\r\nhttps://github.com/simonw/datasette/blob/ce4958018ede00fbdadf0c37a99889b6901bfb9b/datasette/views/table.py#L267-L272", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 636722501, "label": "Having view-table permission but NOT view-database should still grant access to /db/table"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/831#issuecomment-642324847", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/831", "id": 642324847, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MjMyNDg0Nw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-10T23:50:55Z", "updated_at": "2020-06-10T23:50:55Z", "author_association": "OWNER", "body": "Actually I'm not sure about this. If `\"allow\": null` means \"no-one can do this\", what's the allow block syntax for \"everyone can do this\"?\r\n\r\nIt could be `\"allow\": {}` - but that's not intuitive because normally the allow block shows keys that need to match. `{}` suggests to me that no matches are possible.\r\n\r\nSo I think I'm going to stick with the current mechanism, which is that `\"allow\": null` means \"anyone can do this\" and `\"allow\": {}` means \"no-one can do this\".", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 636614868, "label": "It would be more intuitive if \"allow\": none meant \"no-one can do this\""}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/818#issuecomment-642231871", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/818", "id": 642231871, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MjIzMTg3MQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-10T20:11:50Z", "updated_at": "2020-06-10T20:11:50Z", "author_association": "OWNER", "body": "`datasette-permissions-sql`\r\n```yaml\r\nplugins:\r\n datasette-permissions-sql:\r\n view-instance: |-\r\n select count(*) from users where admin = 1 and id = :id\r\n```", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 634917088, "label": "Example permissions plugin"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/818#issuecomment-642230499", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/818", "id": 642230499, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MjIzMDQ5OQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-10T20:08:46Z", "updated_at": "2020-06-10T20:09:26Z", "author_association": "OWNER", "body": "What's a simple but useful plugin I could release that exercises this hook?\r\n\r\nIdeally one which executes permission checks against the database somehow.\r\n\r\nI could do a simplest-possible implementation of the idea in #801 (allow-by-query).", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 634917088, "label": "Example permissions plugin"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/818#issuecomment-642229899", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/818", "id": 642229899, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MjIyOTg5OQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-10T20:07:36Z", "updated_at": "2020-06-10T20:07:36Z", "author_association": "OWNER", "body": "New policy in 9f236c4 dictates that this should be in Milestone 0.44 after all:\r\n\r\n> * **New plugin hooks** should only be shipped if accompanied by a separate release of a non-demo plugin that uses them.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 634917088, "label": "Example permissions plugin"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/829#issuecomment-642217520", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/829", "id": 642217520, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MjIxNzUyMA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-10T19:41:35Z", "updated_at": "2020-06-10T19:41:35Z", "author_association": "OWNER", "body": "I didn't bother with the alternative epoch - it only shaves off two or three bytes from the cookie.\r\n\r\nDocumentation for the new `ds_actor` cookie shape is here: https://datasette.readthedocs.io/en/latest/authentication.html#the-ds-actor-cookie", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 636426530, "label": "Ability to set ds_actor cookie such that it expires"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/829#issuecomment-642178604", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/829", "id": 642178604, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MjE3ODYwNA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-10T18:18:36Z", "updated_at": "2020-06-10T18:20:19Z", "author_association": "OWNER", "body": "Even shorter: encode an integer that is the difference between that expiry timestamp and a more recent epoch - June 1st 2020 will do.\r\n\r\n```\r\n>>> import datetime, calendar\r\n>>> calendar.timegm(datetime.date(2020, 6, 1).timetuple())\r\n1590969600\r\n>>> import baseconv\r\n>>> baseconv.base62.encode(int(time.time() - 1590969600))\r\n'3XST'\r\n```", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 636426530, "label": "Ability to set ds_actor cookie such that it expires"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/829#issuecomment-642176180", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/829", "id": 642176180, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MjE3NjE4MA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-10T18:14:02Z", "updated_at": "2020-06-10T18:14:15Z", "author_association": "OWNER", "body": "And the `e` key can be `null`or missing for \"never expires\".", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 636426530, "label": "Ability to set ds_actor cookie such that it expires"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/829#issuecomment-642175892", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/829", "id": 642175892, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MjE3NTg5Mg==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-10T18:13:26Z", "updated_at": "2020-06-10T18:13:26Z", "author_association": "OWNER", "body": "I'm going with `expires_at` - except to keep the cookies shorter the key will be called `e` and the actor will go in `a`, like this:\r\n\r\n```json\r\n{\r\n \"e\": \"1UuHoo\",\r\n \"a\": {\"id\": \"root\"}\r\n}\r\n```\r\nThat `e` value is a base64 encoded expiry integer timestamp (again for a shorter cookie) - using https://pypi.org/project/python-baseconv/", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 636426530, "label": "Ability to set ds_actor cookie such that it expires"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/829#issuecomment-642174272", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/829", "id": 642174272, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MjE3NDI3Mg==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-10T18:10:13Z", "updated_at": "2020-06-10T18:10:13Z", "author_association": "OWNER", "body": "Some options:\r\n\r\n- Redesign the `ds_actor` cookie to be `{\"expires_at\": 1591811250, \"actor\": ...}` - check if it has expired in that default `actor_from_request` hook\r\n- Let plugins set an additional cookie of some sort\r\n- Expect plugins that care about this to set a cookie with a different name and implement their own `actor_from_request` against that", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 636426530, "label": "Ability to set ds_actor cookie such that it expires"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/829#issuecomment-642161210", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/829", "id": 642161210, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MjE2MTIxMA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-10T17:45:58Z", "updated_at": "2020-06-10T17:45:58Z", "author_association": "OWNER", "body": "`itsdangerous` has this ability but you specify the max-age when you call unsign: https://itsdangerous.palletsprojects.com/en/1.1.x/timed/\r\n\r\n> s.unsign(string, max_age=5)\r\n> Traceback (most recent call last):\r\n> ...\r\n> itsdangerous.exc.SignatureExpired: Signature age 15 > 5 seconds\r\n\r\nI currently only decode the `ds_actor` cookie in one place: https://github.com/simonw/datasette/blob/d828abaddec0dce3ec4b4eeddc3a74384e52cf34/datasette/actor_auth_cookie.py#L5-L12\r\n\r\nIf plugins want to be able to set their own policies on how long the `ds_actor` cookie should remain valid, how do I know to listen to them when decoding the cookie here?", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 636426530, "label": "Ability to set ds_actor cookie such that it expires"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/394#issuecomment-641908346", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/394", "id": 641908346, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MTkwODM0Ng==", "user": {"value": 127565, "label": "wragge"}, "created_at": "2020-06-10T10:22:54Z", "updated_at": "2020-06-10T10:22:54Z", "author_association": "CONTRIBUTOR", "body": "There's a working demo here: https://github.com/wragge/datasette-test\r\n\r\nAnd if you want something that's more than just proof-of-concept, here's a notebook which does some harvesting from web archives and then displays the results using Datasette: https://nbviewer.jupyter.org/github/GLAM-Workbench/web-archives/blob/master/explore_presentations.ipynb", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 396212021, "label": "base_url configuration setting"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/394#issuecomment-641889565", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/394", "id": 641889565, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MTg4OTU2NQ==", "user": {"value": 58298410, "label": "LVerneyPEReN"}, "created_at": "2020-06-10T09:49:34Z", "updated_at": "2020-06-10T09:49:34Z", "author_association": "NONE", "body": "Hi,\r\n\r\nI came across this issue while looking for a way to spawn Datasette as a SQLite files viewer in JupyterLab. I found https://github.com/simonw/jupyterserverproxy-datasette-demo which seems to be the most up to date proof of concept, but it seems to be failing to list the available db (at least in the Binder demo, https://hub.gke.mybinder.org/user/simonw-jupyters--datasette-demo-uw4dmlnn/datasette/, I only have `:memory`).\r\n\r\nDoes anyone tried to improve on this proof of concept to have a Datasette visualization for SQLite files?\r\n\r\nThanks!", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 396212021, "label": "base_url configuration setting"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/828#issuecomment-641713087", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/828", "id": 641713087, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MTcxMzA4Nw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-10T04:28:17Z", "updated_at": "2020-06-10T04:28:17Z", "author_association": "OWNER", "body": "Fixed. https://datasette.readthedocs.io/en/latest/changelog.html\r\n\r\n\"Changelog_\u2014_Datasette_documentation\"\r\n", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 635914822, "label": "Horizontal scrollbar on changelog page on mobile"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/828#issuecomment-641710745", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/828", "id": 641710745, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MTcxMDc0NQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-10T04:19:31Z", "updated_at": "2020-06-10T04:19:31Z", "author_association": "OWNER", "body": "https://docs.readthedocs.io/en/stable/guides/adding-custom-css.html", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 635914822, "label": "Horizontal scrollbar on changelog page on mobile"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/828#issuecomment-641710670", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/828", "id": 641710670, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MTcxMDY3MA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-10T04:19:17Z", "updated_at": "2020-06-10T04:19:17Z", "author_association": "OWNER", "body": "This CSS seems to fix it:\r\n```css\r\na.external {overflow-wrap: anywhere;}\r\n```", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 635914822, "label": "Horizontal scrollbar on changelog page on mobile"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/806#issuecomment-641637696", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/806", "id": 641637696, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MTYzNzY5Ng==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-09T23:46:00Z", "updated_at": "2020-06-09T23:46:00Z", "author_association": "OWNER", "body": "The issues that should be referenced from this release are:\r\n\r\n#395, #519, #576, #699, #706, #774, #777, #781, #784, #788, #790, #797, #798, #800, #802, #804, #819, #822 ", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 632753851, "label": "Release Datasette 0.44"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/806#issuecomment-641634749", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/806", "id": 641634749, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MTYzNDc0OQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-09T23:34:52Z", "updated_at": "2020-06-09T23:34:52Z", "author_association": "OWNER", "body": "Preview of the release notes is now available here: https://datasette.readthedocs.io/en/latest/changelog.html#v0-44", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 632753851, "label": "Release Datasette 0.44"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/795#issuecomment-641616185", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/795", "id": 641616185, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MTYxNjE4NQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-09T22:33:33Z", "updated_at": "2020-06-09T22:33:33Z", "author_association": "OWNER", "body": "Documentation: https://datasette.readthedocs.io/en/latest/internals.html#setting-cookies-with-response-set-cookie", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 629541395, "label": "response.set_cookie() method"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/826#issuecomment-641616060", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/826", "id": 641616060, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MTYxNjA2MA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-09T22:33:12Z", "updated_at": "2020-06-09T22:33:12Z", "author_association": "OWNER", "body": "https://datasette.readthedocs.io/en/latest/authentication.html#the-ds-actor-cookie", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 635519358, "label": "Document the ds_actor signed cookie"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/806#issuecomment-641604210", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/806", "id": 641604210, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MTYwNDIxMA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-09T21:59:33Z", "updated_at": "2020-06-09T22:00:11Z", "author_association": "OWNER", "body": "AWS IAM uses action and resource terminology: https://docs.aws.amazon.com/IAM/latest/UserGuide/introduction_access-management.html - I think that's where I got that language:\r\n\r\n> ```json\r\n> {\r\n> \"Version\": \"2012-10-17\",\r\n> \"Statement\": {\r\n> \"Effect\": \"Allow\",\r\n> \"Action\": \"dynamodb:*\",\r\n> \"Resource\": \"arn:aws:dynamodb:us-east-2:123456789012:table/Books\"\r\n> }\r\n> }\r\n> ```\r\nI'm going to stick with \"action\" in its current meaning.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 632753851, "label": "Release Datasette 0.44"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/806#issuecomment-641603457", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/806", "id": 641603457, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MTYwMzQ1Nw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-09T21:57:32Z", "updated_at": "2020-06-09T21:57:32Z", "author_association": "OWNER", "body": "operation, procedure, process as alternative words for those menu items?", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 632753851, "label": "Release Datasette 0.44"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/806#issuecomment-641602794", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/806", "id": 641602794, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MTYwMjc5NA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-09T21:55:45Z", "updated_at": "2020-06-09T21:55:45Z", "author_association": "OWNER", "body": "Last-minute thought:\r\n\r\nShould I worry about calling permissions \"actions\", when I have an idea for a future plugin hook that allows plugins to add something I was going to call \"actions\" to database, table and row pages?\r\n\r\nThose actions would take the form of menu item commands that Do Something to the selected object. If I use \"actions\" to mean permission names, will I be able to find a good alternative name for these dynamic menu items?", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 632753851, "label": "Release Datasette 0.44"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/804#issuecomment-641538982", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/804", "id": 641538982, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MTUzODk4Mg==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-09T20:01:30Z", "updated_at": "2020-06-09T20:01:30Z", "author_association": "OWNER", "body": "Now fully documented here: https://datasette.readthedocs.io/en/latest/contributing.html#setting-up-a-development-environment", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 632673972, "label": "python tests/fixtures.py command has a bug"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/804#issuecomment-641538799", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/804", "id": 641538799, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MTUzODc5OQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-09T20:01:08Z", "updated_at": "2020-06-09T20:01:08Z", "author_association": "OWNER", "body": " $ python tests/fixtures.py fixtures.db fixtures-metadata.json fixtures-plugins\r\n Test tables written to fixtures.db\r\n - metadata written to fixtures-metadata.json\r\n Wrote plugin: fixtures-plugins/register_output_renderer.py\r\n Wrote plugin: fixtures-plugins/view_name.py\r\n Wrote plugin: fixtures-plugins/my_plugin.py\r\n Wrote plugin: fixtures-plugins/messages_output_renderer.py\r\n Wrote plugin: fixtures-plugins/my_plugin_2.py", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 632673972, "label": "python tests/fixtures.py command has a bug"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/804#issuecomment-641528737", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/804", "id": 641528737, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MTUyODczNw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-09T19:39:24Z", "updated_at": "2020-06-09T19:39:24Z", "author_association": "OWNER", "body": "Switched to 0.44 milestone because I don't like shipping releases with known bugs.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 632673972, "label": "python tests/fixtures.py command has a bug"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/827#issuecomment-641528269", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/827", "id": 641528269, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MTUyODI2OQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-09T19:38:30Z", "updated_at": "2020-06-09T19:38:30Z", "author_association": "OWNER", "body": "https://datasette.readthedocs.io/en/latest/internals.html#csrf-protection", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 635696400, "label": "Document CSRF protection (for plugins)"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/825#issuecomment-641406944", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/825", "id": 641406944, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MTQwNjk0NA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-09T16:12:02Z", "updated_at": "2020-06-09T17:19:19Z", "author_association": "OWNER", "body": "Alternative design: leave actor alone. Instead specify that allow blocks can look like this:\r\n\r\n```json\r\n{\r\n \"allow\": {\r\n \"unauthenticated\": true\r\n }\r\n}\r\n```\r\n\r\nI like this: the above block is very self-documenting.\r\n\r\nThe `\"id\": \"*\"` mechanism means there is already precedent for allow keys with special meaning.\r\n\r\n**I'm going with this design.**", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 635147716, "label": "Way to enable a default=False permission for anonymous users"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/825#issuecomment-641452563", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/825", "id": 641452563, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MTQ1MjU2Mw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-09T17:08:00Z", "updated_at": "2020-06-09T17:08:00Z", "author_association": "OWNER", "body": "https://datasette.readthedocs.io/en/latest/authentication.html#defining-permissions-with-allow-blocks", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 635147716, "label": "Way to enable a default=False permission for anonymous users"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/825#issuecomment-641449725", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/825", "id": 641449725, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MTQ0OTcyNQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-09T17:02:31Z", "updated_at": "2020-06-09T17:02:31Z", "author_association": "OWNER", "body": "Documented at the bottom of this section: https://github.com/simonw/datasette/blob/7633b9ab249b2dce5ee0b4fcf9542c13a1703ef0/docs/authentication.rst#defining-permissions-with-allow-blocks", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 635147716, "label": "Way to enable a default=False permission for anonymous users"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/825#issuecomment-641412424", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/825", "id": 641412424, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MTQxMjQyNA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-09T16:22:07Z", "updated_at": "2020-06-09T16:22:07Z", "author_association": "OWNER", "body": "When I implement this I should also document default allow vs default deny as a concept, and specify that default next to every documented permission.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 635147716, "label": "Way to enable a default=False permission for anonymous users"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/795#issuecomment-641361311", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/795", "id": 641361311, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MTM2MTMxMQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-09T15:11:50Z", "updated_at": "2020-06-09T15:11:50Z", "author_association": "OWNER", "body": "Also: https://github.com/simonw/datasette/blob/dfff34e1987976e72f58ee7b274952840b1f4b71/datasette/views/special.py#L63-L76", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 629541395, "label": "response.set_cookie() method"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/826#issuecomment-641360187", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/826", "id": 641360187, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MTM2MDE4Nw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-09T15:10:00Z", "updated_at": "2020-06-09T15:11:24Z", "author_association": "OWNER", "body": "Also a good reminder that I need a `set_cookie()` function (#795) so I don't have to mess around with `SimpleCookie` directly.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 635519358, "label": "Document the ds_actor signed cookie"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/826#issuecomment-641359103", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/826", "id": 641359103, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MTM1OTEwMw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-09T15:08:07Z", "updated_at": "2020-06-09T15:10:33Z", "author_association": "OWNER", "body": "I should probably add a utility function for setting that cookie - right now the only code that does that is here:\r\n\r\nhttps://github.com/simonw/datasette/blob/dfff34e1987976e72f58ee7b274952840b1f4b71/datasette/views/special.py#L63-L76", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 635519358, "label": "Document the ds_actor signed cookie"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/812#issuecomment-641353729", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/812", "id": 641353729, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MTM1MzcyOQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-09T14:59:25Z", "updated_at": "2020-06-09T14:59:25Z", "author_association": "OWNER", "body": "I'm going to figure this out by working with https://github.com/simonw/datasette-auth-github/issues/62", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 634112607, "label": "Ability to customize what happens when a view permission fails"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/823#issuecomment-641353186", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/823", "id": 641353186, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MTM1MzE4Ng==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-09T14:58:36Z", "updated_at": "2020-06-09T14:58:36Z", "author_association": "OWNER", "body": "Docs now say:\r\n> The actor dictionary can be any shape - the design of that data structure is left up to the plugins. A useful convention is to include an `\"id\"` string, as demonstrated by the \"root\" actor below.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 635107393, "label": "Documentation is inconsistent about \"id\" as required field on actor"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/825#issuecomment-641320947", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/825", "id": 641320947, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MTMyMDk0Nw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-09T14:06:46Z", "updated_at": "2020-06-09T14:06:46Z", "author_association": "OWNER", "body": "I'm torn between `anonymous` and `anon` - because the latter is less typing, and I envisage people writing a lot of code like this:\r\n\r\n```python\r\n if actor.get(\"anonymous\"):\r\n # ...\r\n```\r\n\r\nI'm going with `anonymous` because it's that tiny bit clearer than `anon`.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 635147716, "label": "Way to enable a default=False permission for anonymous users"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/825#issuecomment-641062164", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/825", "id": 641062164, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MTA2MjE2NA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-09T06:30:24Z", "updated_at": "2020-06-09T14:05:33Z", "author_association": "OWNER", "body": "Idea: the anonymous actor could be passed to `actor_matches_allow()` as:\r\n\r\n```json\r\n{\"anonymous\": true}\r\n```\r\n\r\nThen allow blocks like this could be used to allow them:\r\n\r\n```json\r\n{\r\n \"plugins\": {\r\n \"datasette-upload-csvs\": {\r\n \"allow\": {\r\n \"anonymous\": true\r\n }\r\n }\r\n }\r\n}\r\n```", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 635147716, "label": "Way to enable a default=False permission for anonymous users"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/823#issuecomment-641059221", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/823", "id": 641059221, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MTA1OTIyMQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-09T06:23:51Z", "updated_at": "2020-06-09T06:24:09Z", "author_association": "OWNER", "body": "I don't like the \"id\" requirement.\r\n\r\nI can think of plenty of situations where a unique ID might not be available:\r\n\r\n- auth against an external token - an email address or a phone number for example\r\n- auth using encrypted tokens - where decrypting the token tells you exactly what permissions that token should have, like in https://blog.thea.codes/building-a-stateless-api-proxy/", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 635107393, "label": "Documentation is inconsistent about \"id\" as required field on actor"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/806#issuecomment-641026726", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/806", "id": 641026726, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MTAyNjcyNg==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-09T04:52:07Z", "updated_at": "2020-06-09T04:52:07Z", "author_association": "OWNER", "body": "Changelog for this is going to be huge - 96 commits since 0.43 already! https://github.com/simonw/datasette/compare/0.43...master", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 632753851, "label": "Release Datasette 0.44"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/818#issuecomment-641026230", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/818", "id": 641026230, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MTAyNjIzMA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-09T04:50:24Z", "updated_at": "2020-06-09T04:50:24Z", "author_association": "OWNER", "body": "I'm dropping this from the 0.44 milestone.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 634917088, "label": "Example permissions plugin"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/823#issuecomment-641025760", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/823", "id": 641025760, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MTAyNTc2MA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-09T04:48:40Z", "updated_at": "2020-06-09T04:48:40Z", "author_association": "OWNER", "body": "I should assert that `\"id\"` exists and is a string in the code that calls the `actor_from_request` hook.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 635107393, "label": "Documentation is inconsistent about \"id\" as required field on actor"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/805#issuecomment-641017851", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/805", "id": 641017851, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MTAxNzg1MQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-09T04:17:00Z", "updated_at": "2020-06-09T04:17:00Z", "author_association": "OWNER", "body": "I can't get Datasette working on Glitch installed from a URL - I'm going to try this on Glitch once I've shipped the 0.44 release in #806.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 632724154, "label": "Writable canned queries live demo on Glitch"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/805#issuecomment-641017721", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/805", "id": 641017721, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MTAxNzcyMQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-09T04:16:28Z", "updated_at": "2020-06-09T04:16:28Z", "author_association": "OWNER", "body": "Create `data.db` with:\r\n```\r\necho '{\"emoji\": \"\ud83d\udc2f\", \"score\": 0}' | sqlite-utils insert data.db emojis --pk=emoji -\r\necho '{\"emoji\": \"\ud83d\udc3a\", \"score\": 0}' | sqlite-utils insert data.db emojis --pk=emoji -\r\n```\r\nThen run Datasette with this `metadata.yaml`:\r\n```yaml\r\ntitle: Datasette Poll\r\ndatabases:\r\n data:\r\n queries:\r\n vote:\r\n sql: |-\r\n update emojis set score = score + 1 where emoji = :emoji\r\n write: true\r\n```", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 632724154, "label": "Writable canned queries live demo on Glitch"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/797#issuecomment-638301073", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/797", "id": 638301073, "node_id": "MDEyOklzc3VlQ29tbWVudDYzODMwMTA3Mw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-03T16:14:54Z", "updated_at": "2020-06-09T04:00:40Z", "author_association": "OWNER", "body": "I want a unit test that exercises this for both writable and regular canned queries.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 630120235, "label": "Documentation for new \"params\" setting for canned queries"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/818#issuecomment-641013524", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/818", "id": 641013524, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MTAxMzUyNA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-09T03:57:38Z", "updated_at": "2020-06-09T04:00:24Z", "author_association": "OWNER", "body": "Problem with that is it's more of a `actor_from_request` opportunity than `permission_allowed`. You could use `actor_from_request` to authenticate API clients from their `Authorization:` header, then use the regular `\"allow\"` blocks in `metadata.json` to actually assign their permissions.\r\n\r\nThe most interesting permissions plugin would be one that implements permissions against some kind of database schema, hence allowing admins to edit permissions through writable canned queries.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 634917088, "label": "Example permissions plugin"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/818#issuecomment-641009744", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/818", "id": 641009744, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MTAwOTc0NA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-09T03:43:18Z", "updated_at": "2020-06-09T03:43:18Z", "author_association": "OWNER", "body": "`datasette-auth-bearer` perhaps?", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 634917088, "label": "Example permissions plugin"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/818#issuecomment-641009442", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/818", "id": 641009442, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MTAwOTQ0Mg==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-09T03:41:55Z", "updated_at": "2020-06-09T03:41:55Z", "author_association": "OWNER", "body": "I want to build a plugin that does `Authorization: Bearer xxx` API key authentication.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 634917088, "label": "Example permissions plugin"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/822#issuecomment-641003291", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/822", "id": 641003291, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MTAwMzI5MQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-09T03:17:43Z", "updated_at": "2020-06-09T03:17:43Z", "author_association": "OWNER", "body": "I'm leaning towards `request.url_vars`.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 635077656, "label": "request.url_vars helper property"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/822#issuecomment-641003237", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/822", "id": 641003237, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MTAwMzIzNw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-09T03:17:32Z", "updated_at": "2020-06-09T03:17:32Z", "author_association": "OWNER", "body": "Currently querystring parameters are accessed through `request.args` and POST variables through `request.post_vars()`. Would be good to have a name that was somewhat consistent with those.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 635077656, "label": "request.url_vars helper property"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/215#issuecomment-641002504", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/215", "id": 641002504, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MTAwMjUwNA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-09T03:14:32Z", "updated_at": "2020-06-09T03:14:32Z", "author_association": "OWNER", "body": "Documentation: https://datasette.readthedocs.io/en/latest/plugins.html#register-routes", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 314506669, "label": "Allow plugins to define additional URL routes and views"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/820#issuecomment-640982533", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/820", "id": 640982533, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MDk4MjUzMw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-09T02:00:21Z", "updated_at": "2020-06-09T02:00:21Z", "author_association": "OWNER", "body": "In the case of registering API tokens it would be useful if the plugin could call a writable canned query which knows how to insert a randomly generated value. This could be achieved using a custom SQL function.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 635049296, "label": "Idea: Plugin hook for registering canned queries"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/215#issuecomment-640972952", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/215", "id": 640972952, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MDk3Mjk1Mg==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-09T01:24:52Z", "updated_at": "2020-06-09T01:25:33Z", "author_association": "OWNER", "body": "WIP documentation: https://github.com/simonw/datasette/blob/770dedb21adfc706592e6b5cdf5e751a8720fdf9/docs/plugins.rst#register_routes", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 314506669, "label": "Allow plugins to define additional URL routes and views"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/215#issuecomment-640971470", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/215", "id": 640971470, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MDk3MTQ3MA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-09T01:19:44Z", "updated_at": "2020-06-09T01:19:44Z", "author_association": "OWNER", "body": "I'll need to add documentation of the `Response` object (and `Response.html()` and `Response.text()` class methods - I should add `Response.json()` too) to the internals page https://datasette.readthedocs.io/en/stable/internals.html", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 314506669, "label": "Allow plugins to define additional URL routes and views"}, "performed_via_github_app": null}