sigil/tests/helpers.py

54 lines
1.8 KiB
Python

"""Shared test helpers.
issue_code() requires a live agent session, so tests that mint codes have to
prove key possession the same way production does rather than reaching past the
boundary. These helpers do that so the tests stay readable.
"""
import base64
from sigil import identity, keys, viewcodes
from sigil.store import Store
def enrol(store, agent="bigpickle"):
"""Enrol agent with a fresh key. Returns (private, public)."""
private, public = keys.generate()
secret = identity.seed_bootstrap(store, agent)
identity.enrol(store, agent, keys.export_public_b64(public), secret)
return private, public
def sign(private, nonce):
return base64.b64encode(private.sign(nonce.encode())).decode()
def agent_token(store, private, agent="bigpickle", limit=5000, window=60):
"""Full challenge-response, ending in a live agent session token.
The rate limit is opened wide by default: tests that legitimately mint many
codes should not trip the production quota. The quota itself is asserted in
test_hardening.TestRateLimits.
"""
chal = identity.challenge(store, agent, limit=limit, window=window)
sig = sign(private, chal["nonce"])
return identity.verify(
store, chal["nonce"], sig, limit=limit, window=window
)["token"]
def issue(store, private, agent="bigpickle", **kw):
"""Mint a view code the way production does: authenticate, then ask.
`limit`/`window` tune both the challenge quota and the code quota, since a
test that mints many codes trips both.
"""
quota = {k: kw[k] for k in ("limit", "window") if k in kw}
token = agent_token(store, private, agent, **quota)
return viewcodes.issue_code(store, token, **kw)
def fresh(agent="bigpickle"):
store = Store(":memory:")
private, _ = enrol(store, agent)
return store, private