File size: 2,747 Bytes
be9517e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31f389a
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
import pytest

pytest.importorskip("fastapi")
from fastapi.testclient import TestClient  # noqa: E402

from app.server import app  # noqa: E402


def test_no_site_passcode_means_open(monkeypatch):
    monkeypatch.delenv("CURATORBOT_SITE_PASSCODE", raising=False)
    c = TestClient(app)
    assert c.get("/").status_code == 200
    assert c.get("/api/interviews").status_code == 200


def test_site_passcode_gates_pages_and_api(monkeypatch):
    monkeypatch.setenv("CURATORBOT_SITE_PASSCODE", "open sesame")
    c = TestClient(app, follow_redirects=False)
    r = c.get("/")
    assert r.status_code == 303 and r.headers["location"] == "/login"
    r = c.get("/api/interviews/DEMO-0001")
    assert r.status_code == 401 and r.headers["x-login-required"] == "1"
    assert c.get("/static/app.js").status_code == 303
    assert c.get("/login").status_code == 200

    r = c.post("/login", data={"passcode": "wrong"})
    assert r.status_code == 401 and "not right" in r.text and "set-cookie" not in r.headers

    r = c.post("/login", data={"passcode": "open sesame"})
    assert r.status_code == 303 and "HttpOnly" in r.headers["set-cookie"]
    assert c.get("/").status_code == 200
    assert c.get("/api/interviews").status_code == 200

    # changing the passcode signs everyone out
    monkeypatch.setenv("CURATORBOT_SITE_PASSCODE", "new one")
    assert c.get("/api/interviews").status_code == 401

    c.get("/logout")
    monkeypatch.setenv("CURATORBOT_SITE_PASSCODE", "open sesame")
    assert c.get("/api/interviews").status_code == 401


def test_site_passcode_header_for_scripts(monkeypatch):
    monkeypatch.setenv("CURATORBOT_SITE_PASSCODE", "open sesame")
    c = TestClient(app)
    assert c.get("/api/health", headers={"X-Site-Passcode": "open sesame"}).status_code == 200
    assert c.get("/api/health", headers={"X-Site-Passcode": "nope"}).status_code == 401


def test_https_cookie_works_inside_the_space_frame(monkeypatch):
    monkeypatch.setenv("CURATORBOT_SITE_PASSCODE", "open sesame")
    c = TestClient(app, follow_redirects=False)
    r = c.post("/login", data={"passcode": "open sesame"}, headers={"X-Forwarded-Proto": "https"})
    cookie = r.headers["set-cookie"]
    assert "Secure" in cookie and "SameSite=None" in cookie and "Partitioned" in cookie


def test_tab_icon_is_served_without_signing_in(monkeypatch):
    from fastapi.testclient import TestClient
    monkeypatch.setenv("CURATORBOT_SITE_PASSCODE", "secret")
    from app.server import app
    c = TestClient(app)
    for path in ("/favicon.svg", "/favicon.ico"):
        r = c.get(path)
        assert r.status_code == 200 and r.headers["content-type"].startswith("image/svg+xml") and b"<svg" in r.content
    assert 'rel="icon"' in c.get("/login").text