8e817ec48d
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
50 lines
1.5 KiB
Python
50 lines
1.5 KiB
Python
# tests/test_operator_cookies.py
|
|
import time
|
|
import base64
|
|
import json
|
|
from backend.auth_cookies import sign, read
|
|
|
|
|
|
def test_sign_then_read_round_trips():
|
|
now = int(time.time())
|
|
raw = sign({"uid": "abc", "iat": now})
|
|
data = read(raw, max_age=3600)
|
|
assert data == {"uid": "abc", "iat": now}
|
|
|
|
|
|
def test_tampered_signature_is_rejected():
|
|
raw = sign({"uid": "abc", "iat": int(time.time())})
|
|
body, _sig = raw.rsplit(".", 1)
|
|
assert read(body + ".deadbeef", max_age=3600) is None
|
|
|
|
|
|
def test_tampered_body_is_rejected():
|
|
raw = sign({"uid": "abc", "iat": int(time.time())})
|
|
body, sig = raw.rsplit(".", 1)
|
|
forged = base64.urlsafe_b64encode(json.dumps({"uid": "evil", "iat": int(time.time())}).encode()).decode()
|
|
assert read(forged + "." + sig, max_age=3600) is None
|
|
|
|
|
|
def test_expired_by_iat_is_rejected():
|
|
raw = sign({"uid": "abc", "iat": int(time.time()) - 10_000})
|
|
assert read(raw, max_age=3600) is None
|
|
|
|
|
|
def test_garbage_input_is_none_not_raise():
|
|
assert read("not-a-cookie", max_age=3600) is None
|
|
assert read("", max_age=3600) is None
|
|
assert read(None, max_age=3600) is None
|
|
|
|
|
|
def test_wrong_secret_is_rejected(monkeypatch):
|
|
import backend.auth_cookies as ac
|
|
monkeypatch.setattr(ac, "SECRET_KEY", "secret-A")
|
|
raw = ac.sign({"uid": "x", "iat": int(time.time())})
|
|
monkeypatch.setattr(ac, "SECRET_KEY", "secret-B")
|
|
assert ac.read(raw, max_age=3600) is None
|
|
|
|
|
|
def test_future_dated_iat_is_rejected():
|
|
raw = sign({"uid": "x", "iat": int(time.time()) + 10_000})
|
|
assert read(raw, max_age=3600) is None
|