{"html_url": "https://github.com/simonw/datasette/issues/335#issuecomment-670999860", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/335", "id": 670999860, "node_id": "MDEyOklzc3VlQ29tbWVudDY3MDk5OTg2MA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-08-09T03:12:44Z", "updated_at": "2020-08-09T03:12:44Z", "author_association": "OWNER", "body": "How would plugin installation work if Datasette was installed via homebrew?", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 339505204, "label": "Package datasette for installation using homebrew"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/335#issuecomment-670999832", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/335", "id": 670999832, "node_id": "MDEyOklzc3VlQ29tbWVudDY3MDk5OTgzMg==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-08-09T03:12:14Z", "updated_at": "2020-08-09T03:12:14Z", "author_association": "OWNER", "body": "Another useful example: https://github.com/Homebrew/homebrew-core/blob/master/Formula/trailscraper.rb", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 339505204, "label": "Package datasette for installation using homebrew"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/918#issuecomment-671070486", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/918", "id": 671070486, "node_id": "MDEyOklzc3VlQ29tbWVudDY3MTA3MDQ4Ng==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-08-09T16:11:59Z", "updated_at": "2020-08-09T16:11:59Z", "author_association": "OWNER", "body": "Fix has been released in Datasette 0.46: https://datasette.readthedocs.io/en/latest/changelog.html#v0-46", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 675724951, "label": "Security issue: read-only canned queries leak CSRF token in URL"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/918#issuecomment-671070528", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/918", "id": 671070528, "node_id": "MDEyOklzc3VlQ29tbWVudDY3MTA3MDUyOA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-08-09T16:12:16Z", "updated_at": "2020-08-09T16:12:16Z", "author_association": "OWNER", "body": "It's worth noting that in order to exploit this issue the following would all need to be true:\r\n\r\n- A user is running a copy of Datasette protected by a cookie-based authentication plugin AND configured with at least one writable canned query\r\n- An attacker is in control of a URL that could concievably be returned on a page that is displayed as the result of submitting a read-only canned query\r\n- An authenticated user of that Datasette instance, who is running a browser that doesn't support the `SameSite=lax` cookie parameter (which is [widely supported](https://caniuse.com/#feat=same-site-cookie-attribute) by modern browsers), submits the read-only canned query form and then clicks a link to the attacker's off-site page, exposing their CSRFToken in the attacker's HTTP referer logs\r\n- The attacker then tricks that user into visiting their own malicious web page which includes a POST form that auto-submits against the writable canned query that the attacker wishes to exploit, including the CSRF token as a hidden field\r\n\r\nThe attacker would need full knowledge of the URL and form layout of the Datasette instance that they are exploiting.\r\n", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 675724951, "label": "Security issue: read-only canned queries leak CSRF token in URL"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/919#issuecomment-671071461", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/919", "id": 671071461, "node_id": "MDEyOklzc3VlQ29tbWVudDY3MTA3MTQ2MQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-08-09T16:19:37Z", "updated_at": "2020-08-09T16:19:37Z", "author_association": "OWNER", "body": "That appears to have worked.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 675727366, "label": "Travis should not build the master branch, only the main branch"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/918#issuecomment-671071710", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/918", "id": 671071710, "node_id": "MDEyOklzc3VlQ29tbWVudDY3MTA3MTcxMA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-08-09T16:21:41Z", "updated_at": "2020-08-09T16:21:41Z", "author_association": "OWNER", "body": "Submitting the form on https://latest.datasette.io/fixtures/neighborhood_search demonstrates that this is fixed.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 675724951, "label": "Security issue: read-only canned queries leak CSRF token in URL"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/919#issuecomment-671072084", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/919", "id": 671072084, "node_id": "MDEyOklzc3VlQ29tbWVudDY3MTA3MjA4NA==", "user": {"value": 4312421, "label": "stonebig"}, "created_at": "2020-08-09T16:25:01Z", "updated_at": "2020-08-09T16:26:03Z", "author_association": "NONE", "body": "don't forget the pypi wheel (still on datasette-0.45)", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 675727366, "label": "Travis should not build the master branch, only the main branch"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/919#issuecomment-671072223", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/919", "id": 671072223, "node_id": "MDEyOklzc3VlQ29tbWVudDY3MTA3MjIyMw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-08-09T16:26:17Z", "updated_at": "2020-08-09T16:26:17Z", "author_association": "OWNER", "body": "Should be released in a couple of minutes: https://travis-ci.org/github/simonw/datasette/builds/716328883", "reactions": "{\"total_count\": 1, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 1, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 675727366, "label": "Travis should not build the master branch, only the main branch"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/915#issuecomment-671073223", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/915", "id": 671073223, "node_id": "MDEyOklzc3VlQ29tbWVudDY3MTA3MzIyMw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-08-09T16:35:20Z", "updated_at": "2020-08-09T16:36:10Z", "author_association": "OWNER", "body": "`datasette-graphql` uses the logic from `TableView` right now. It wasn't too unpleasant, but I do worry about the two of them being coupled together in this way.\r\n\r\nhttps://github.com/simonw/datasette-graphql/blob/cc65ec294b0bf8e26213fc68bb5487066de9caab/datasette_graphql/utils.py#L412-L417\r\n\r\n```python\r\n request = Request.fake(path_with_query_string)\r\n\r\n view = TableView(DatasetteSpecialConfig(datasette))\r\n data, _, _ = await view.data(\r\n request, database=database_name, hash=None, table=table_name, _next=after\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": 671763164, "label": "Refactor TableView class so things like datasette-graphql can reuse the logic"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/918#issuecomment-671075764", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/918", "id": 671075764, "node_id": "MDEyOklzc3VlQ29tbWVudDY3MTA3NTc2NA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-08-09T16:56:48Z", "updated_at": "2020-08-09T16:56:48Z", "author_association": "OWNER", "body": "GitHub security advisory: https://github.com/simonw/datasette/security/advisories/GHSA-q6j3-c4wc-63vw", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 675724951, "label": "Security issue: read-only canned queries leak CSRF token in URL"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/335#issuecomment-671076975", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/335", "id": 671076975, "node_id": "MDEyOklzc3VlQ29tbWVudDY3MTA3Njk3NQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-08-09T17:08:34Z", "updated_at": "2020-08-09T17:09:21Z", "author_association": "OWNER", "body": "Quick prototype of `datasette install`:\r\n```diff\r\ndiff --git a/datasette/cli.py b/datasette/cli.py\r\nindex 287195a..95b6eb7 100644\r\n--- a/datasette/cli.py\r\n+++ b/datasette/cli.py\r\n@@ -231,6 +231,18 @@ def package(\r\n call(args)\r\n \r\n \r\n+@cli.command()\r\n+@click.argument(\"packages\", nargs=-1, required=True)\r\n+def install(packages):\r\n+ \"Install Python packages - e.g. Datasette plugins - into the same environment as Datasett\"\r\n+ import pip\r\n+\r\n+ try:\r\n+ pip.main([\"install\"] + list(packages))\r\n+ except SystemExit as e:\r\n+ pass\r\n+\r\n+\r\n @cli.command()\r\n @click.argument(\"files\", type=click.Path(exists=True), nargs=-1)\r\n @click.option(\r\n```\r\n\r\n```\r\n$ datasette install\r\nUsage: datasette install [OPTIONS] PACKAGES...\r\nTry 'datasette install --help' for help.\r\n\r\nError: Missing argument 'PACKAGES...'.\r\n$ datasette install datasette-vega\r\nWARNING: pip is being invoked by an old script wrapper. This will fail in a future version of pip.\r\nPlease see https://github.com/pypa/pip/issues/5599 for advice on fixing the underlying issue.\r\nTo avoid this problem you can invoke Python with '-m pip' instead of running pip directly.\r\nCollecting datasette-vega\r\n Using cached datasette_vega-0.6.2-py3-none-any.whl (1.8 MB)\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": 339505204, "label": "Package datasette for installation using homebrew"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/335#issuecomment-671077168", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/335", "id": 671077168, "node_id": "MDEyOklzc3VlQ29tbWVudDY3MTA3NzE2OA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-08-09T17:10:15Z", "updated_at": "2020-08-09T18:13:39Z", "author_association": "OWNER", "body": "Here's the issue that explains that warning: https://github.com/pypa/pip/issues/5599\r\n\r\nThis should fix it (risky):\r\n\r\n from pip._internal.cli.main import main", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 339505204, "label": "Package datasette for installation using homebrew"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/sqlite-utils/issues/131#issuecomment-671088832", "issue_url": "https://api.github.com/repos/simonw/sqlite-utils/issues/131", "id": 671088832, "node_id": "MDEyOklzc3VlQ29tbWVudDY3MTA4ODgzMg==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-08-09T19:00:41Z", "updated_at": "2020-08-09T19:00:41Z", "author_association": "OWNER", "body": "Should be consistent with the `create-table` command as much as possible:\r\n```\r\n$ sqlite-utils create-table mydb.db mytable \\\r\n id integer \\\r\n name text \\\r\n age integer \\\r\n is_good integer \\\r\n --not-null name \\\r\n --not-null age \\\r\n --default is_good 1 \\\r\n --pk=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": 675753042, "label": "sqlite-utils insert: options for column types"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/335#issuecomment-671001457", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/335", "id": 671001457, "node_id": "MDEyOklzc3VlQ29tbWVudDY3MTAwMTQ1Nw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-08-09T03:37:39Z", "updated_at": "2020-08-09T03:37:39Z", "author_association": "OWNER", "body": "Here's what happened when I installed `homebrew-vd`: https://gist.github.com/simonw/7bfd971a62743d7ca248e6b5e696c240\r\n\r\nIt worked! And from digging around, it has a virtual environment at `/usr/local/Cellar/visidata/1.5.2/libexec/`\r\n\r\nWhich means `/usr/local/Cellar/visidata/1.5.2/libexec/bin/pip` is a working `pip`\r\n\r\nAnd I tried running these commands and confirmed that I get a `datasette` with an additional plugin:\r\n\r\n```\r\n/usr/local/Cellar/visidata/1.5.2/libexec/bin/pip install datasette\r\n/usr/local/Cellar/visidata/1.5.2/libexec/bin/pip install datasette-graphql\r\n/usr/local/Cellar/visidata/1.5.2/libexec/bin/datasette plugins\r\n[\r\n {\r\n \"name\": \"datasette-graphql\",\r\n \"static\": false,\r\n \"templates\": true,\r\n \"version\": \"0.11\",\r\n \"hooks\": [\r\n \"register_routes\",\r\n \"startup\"\r\n ]\r\n }\r\n]\r\n```\r\nSo I can package Datasette as a homebrew package AND I can give people instructions for installing plugins.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 339505204, "label": "Package datasette for installation using homebrew"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/335#issuecomment-671005731", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/335", "id": 671005731, "node_id": "MDEyOklzc3VlQ29tbWVudDY3MTAwNTczMQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-08-09T04:44:13Z", "updated_at": "2020-08-09T17:04:21Z", "author_association": "OWNER", "body": "Telling people how to figure out that `pip` location is going to be pretty unpleasant.\r\n\r\nHow about instead providing a `datasette plugins --install=datasette-graphql` command?\r\n\r\nOr `datasette install datasette-vega`\r\n\r\nIt would run `pip install` in the same virtualenv as Datasette itself.\r\n\r\nhttp://jelly.codes/articles/python-pip-module/ shows how to do this:\r\n\r\n```python\r\n\r\nimport pip\r\n\r\ntry:\r\n pip.main([\"install\", \"plumbum\"])\r\nexcept SystemExit as e:\r\n pass\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": 339505204, "label": "Package datasette for installation using homebrew"}, "performed_via_github_app": null}