{"html_url": "https://github.com/simonw/datasette/issues/699#issuecomment-626991001", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/699", "id": 626991001, "node_id": "MDEyOklzc3VlQ29tbWVudDYyNjk5MTAwMQ==", "user": {"value": 8431341, "label": "zeluspudding"}, "created_at": "2020-05-11T22:06:34Z", "updated_at": "2020-05-11T22:06:34Z", "author_association": "NONE", "body": "Very nice! Thank you for sharing that :+1: :) Will try it out!", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 582526961, "label": "Authentication (and permissions) as a core concept"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/699#issuecomment-626945281", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/699", "id": 626945281, "node_id": "MDEyOklzc3VlQ29tbWVudDYyNjk0NTI4MQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-05-11T20:32:33Z", "updated_at": "2020-05-11T20:32:33Z", "author_association": "OWNER", "body": "I did have a bit of trouble with this one-off plugin getting it to load in the correct order - since I need authentication to work if EITHER the one-off plugin spots a token or my `datasette-auth-github` plugin authenticates the user.\r\n\r\nThat's why I want authentication as a core Datasette concept - so plugins like these can easily play together in a predictable manner.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 582526961, "label": "Authentication (and permissions) as a core concept"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/699#issuecomment-626943809", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/699", "id": 626943809, "node_id": "MDEyOklzc3VlQ29tbWVudDYyNjk0MzgwOQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-05-11T20:30:07Z", "updated_at": "2020-05-11T20:31:18Z", "author_association": "OWNER", "body": "I implemented bearer tokens in a private project of mine as a one-off plugin. I'm going to extract that out into a installable plugin soon. For the moment, my `plugins/token_auth.py` file looks like this:\r\n```python\r\nfrom datasette import hookimpl\r\nimport secrets\r\n\r\n\r\nclass TokenAuth:\r\n def __init__(\r\n self, app, secret, auth,\r\n ):\r\n self.app = app\r\n self.secret = secret\r\n self.auth = auth\r\n\r\n async def __call__(self, scope, receive, send):\r\n if scope.get(\"type\") != \"http\":\r\n return await self.app(scope, receive, send)\r\n\r\n authorization = dict(scope.get(\"headers\") or {}).get(b\"authorization\") or b\"\"\r\n expected = \"Bearer {}\".format(self.secret).encode(\"utf8\")\r\n\r\n if secrets.compare_digest(authorization, expected):\r\n scope = dict(scope, auth=self.auth)\r\n\r\n return await self.app(scope, receive, send)\r\n\r\n\r\n@hookimpl(trylast=True)\r\ndef asgi_wrapper(datasette):\r\n config = datasette.plugin_config(\"token-auth\") or {}\r\n secret = config.get(\"secret\")\r\n auth = config.get(\"auth\")\r\n\r\n def wrap_with_asgi_auth(app):\r\n return TokenAuth(app, secret=secret, auth=auth,)\r\n\r\n return wrap_with_asgi_auth\r\n```\r\nThen I have the following in `metadata.json`:\r\n```json\r\n{\r\n \"plugins\": {\r\n \"token-auth\": {\r\n \"auth\": {\r\n \"name\": \"token-bot\"\r\n },\r\n \"secret\": {\r\n \"$env\": \"TOKEN_SECRET\"\r\n }\r\n }\r\n }\r\n}\r\n```\r\nAnd a `TOKEN_SECRET` environment variable.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 582526961, "label": "Authentication (and permissions) as a core concept"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/699#issuecomment-626807487", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/699", "id": 626807487, "node_id": "MDEyOklzc3VlQ29tbWVudDYyNjgwNzQ4Nw==", "user": {"value": 8431341, "label": "zeluspudding"}, "created_at": "2020-05-11T16:23:57Z", "updated_at": "2020-05-11T16:24:59Z", "author_association": "NONE", "body": "`Authorization: bearer xxx` auth for API keys is a plus plus for me. Looked into just adding this into your `Flask` logic but learned this project doesn't use flask. Interesting \ud83e\udd14", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 582526961, "label": "Authentication (and permissions) as a core concept"}, "performed_via_github_app": null}