exercise the host/origin field in build tokens
Origin is preferred when present, but not always present
"""Test main handlers"""
+import time
+from urllib.parse import quote
from urllib.parse import urlparse
-from bs4 import BeautifulSoup
+import jwt
import pytest
+from bs4 import BeautifulSoup
from binderhub import __version__ as binder_version
@@ -123,3 +126,43 @@ async def test_loading_page(app, provider_prefix, repo, ref, path, path_type, st
nbviewer_url = soup.find(id='nbviewer-preview').find('iframe').attrs['src']
r = await async_requests.get(nbviewer_url)
assert r.status_code == 200, f"{r.status_code} {nbviewer_url}"
+
+
+@pytest.mark.parametrize(
+ "origin,host,expected_origin",
+ [
+ ("https://my.host", "my.host", "my.host"),
+ ("https://my.origin", "my.host", "my.origin"),
+ (None, "my.host", "my.host"),
+ ],
+)
+async def test_build_token_origin(app, origin, host, expected_origin):
+ provider_spec = "git/{}/HEAD".format(
+ quote(
+ "https://github.com/binderhub-ci-repos/cached-minimal-dockerfile",
+ safe="",
+ )
+ )
+ uri = f"/v2/{provider_spec}"
+ headers = {}
+ if origin:
+ headers["Origin"] = origin
+ if host:
+ headers["Host"] = host
+
+ r = await async_requests.get(app.url + uri, headers=headers)
+
+ soup = BeautifulSoup(r.text, "html5lib")
+ assert soup.find(id="build-token")
+ token_element = soup.find(id="build-token")
+ assert token_element
+ assert "data-token" in token_element.attrs
+ build_token = token_element["data-token"]
+ payload = jwt.decode(
+ build_token,
+ audience=provider_spec,
+ options=dict(verify_signature=False),
+ )
+ assert payload["aud"] == provider_spec
+ assert payload["origin"] == expected_origin
+ assert time.time() < payload["exp"] < time.time() + 7200
