Skip to content

Commit

Permalink
Fix for datasette.client.get auth problem, refs #13
Browse files Browse the repository at this point in the history
  • Loading branch information
simonw committed Nov 16, 2023
1 parent 96cbf51 commit 2d6464e
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 7 deletions.
20 changes: 18 additions & 2 deletions datasette_enrichments/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@
from datasette import hookimpl
from datasette.database import Database
import json
import secrets
from datasette.plugins import pm
from .views import enrichment_picker, enrichment_view
from .utils import get_with_auth
from . import hookspecs

from datasette.utils import await_me_maybe
Expand Down Expand Up @@ -76,7 +78,8 @@ async def enqueue(
qs += "&"
qs += "_size=0&_extra=count"
table_path = datasette.urls.table(db.name, table)
response = await datasette.client.get(table_path + ".json" + "?" + qs)

response = await get_with_auth(datasette, table_path + ".json" + "?" + qs)
row_count = response.json()["count"]
await db.execute_write(CREATE_JOB_TABLE_SQL)

Expand Down Expand Up @@ -130,7 +133,7 @@ async def run_enrichment():
if next_cursor:
qs += "&_next={}".format(next_cursor)
qs += "&_size={}".format(self.batch_size)
response = await datasette.client.get(table_path + "?" + qs)
response = await get_with_auth(datasette, table_path + "?" + qs)
rows = response.json()["rows"]
if not rows:
break
Expand Down Expand Up @@ -207,6 +210,19 @@ async def inner():

@hookimpl
def permission_allowed(actor, action):
# Special actor used for internal datasette.client.get() calls
if actor == {"_datasette_enrichments": True}:
return True
# Root user can always use enrichments
if action == "enrichments" and actor and actor.get("id") == "root":
return True


@hookimpl(tryfirst=True)
def actor_from_request(datasette, request):
secret_token = request.headers.get("x-datasette-enrichments") or ""
expected_token = getattr(datasette, "_secret_enrichments_token", None)
if expected_token and secrets.compare_digest(
secret_token, datasette._secret_enrichments_token
):
return {"_datasette_enrichments": True}
10 changes: 10 additions & 0 deletions datasette_enrichments/utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import secrets


async def get_with_auth(datasette, *args, **kwargs):
if not hasattr(datasette, "_secret_enrichments_token"):
datasette._secret_enrichments_token = secrets.token_hex(16)
headers = kwargs.pop("headers", None) or {}
headers["x-datasette-enrichments"] = datasette._secret_enrichments_token
kwargs["headers"] = headers
return await datasette.client.get(*args, **kwargs)
11 changes: 7 additions & 4 deletions datasette_enrichments/views.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from datasette import Response, NotFound, Forbidden
from datasette.utils import path_with_added_args, MultiParams
from .utils import get_with_auth
import urllib.parse


Expand Down Expand Up @@ -36,8 +37,9 @@ async def enrichment_view(datasette, request):
# re-encode
query_string = urllib.parse.urlencode(bits)
stuff = (
await datasette.client.get(
datasette.urls.table(database, table, "json") + "?" + query_string
await get_with_auth(
datasette,
datasette.urls.table(database, table, "json") + "?" + query_string,
)
).json()

Expand Down Expand Up @@ -85,8 +87,9 @@ async def enrichment_picker(datasette, request):
# re-encode
query_string = urllib.parse.urlencode(bits)
stuff = (
await datasette.client.get(
datasette.urls.table(database, table, "json") + "?" + query_string
await get_with_auth(
datasette,
datasette.urls.table(database, table, "json") + "?" + query_string,
)
).json()

Expand Down
11 changes: 10 additions & 1 deletion tests/test_enrichments.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,16 @@ async def test_uppercase_plugin(tmpdir, is_root):
db.execute("create table t (id integer primary key, s text)")
db.execute("insert into t (s) values ('hello')")
db.execute("insert into t (s) values ('goodbye')")
datasette = Datasette([data])
datasette = Datasette(
[data],
metadata={
"databases": {
# Lock down permissions to test
# https://github.com/datasette/datasette-enrichments/issues/13
"data": {"allow": {"id": "root"}}
}
},
)

if not is_root:
response1 = await datasette.client.get("/-/enrich/data/t")
Expand Down

0 comments on commit 2d6464e

Please sign in to comment.