| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273 |
- import pytest
- from app.runner.auth import (
- TaskTokenExpired,
- TaskTokenInvalid,
- TaskTokenIssuer,
- TaskTokenVerifier,
- node_digest,
- )
- NODE = {
- "id": "read_orders",
- "type": "sql.query",
- "data_source_uid": "01900000-0000-7000-8000-000000000010",
- "purpose": "read",
- "config": {
- "statement": "SELECT * FROM orders WHERE day = :day",
- "parameters": {"day": "${parameters.day}"},
- },
- }
- def test_task_token_is_short_lived_and_bound_to_one_node():
- clock = lambda: 1_000
- issuer = TaskTokenIssuer("x" * 32, clock=clock, ttl_seconds=60)
- verifier = TaskTokenVerifier("x" * 32, clock=clock)
- token = issuer.issue(
- task_uid="01900000-0000-7000-8000-000000000011",
- dataflow_uid="01900000-0000-7000-8000-000000000012",
- workflow_version=7,
- correlation_id="01900000-0000-7000-8000-000000000013",
- node=NODE,
- )
- claims = verifier.verify(token, node=NODE)
- assert claims.node_id == "read_orders"
- assert claims.node_type == "sql.query"
- assert claims.purpose == "read"
- assert claims.node_digest == node_digest(NODE)
- assert claims.expires_at == 1_060
- assert claims.jti
- assert "password" not in token.lower()
- def test_task_token_rejects_expiry_tampering_and_other_node():
- now = [1_000]
- issuer = TaskTokenIssuer("x" * 32, clock=lambda: now[0], ttl_seconds=10)
- verifier = TaskTokenVerifier("x" * 32, clock=lambda: now[0])
- token = issuer.issue(
- task_uid="01900000-0000-7000-8000-000000000011",
- dataflow_uid="01900000-0000-7000-8000-000000000012",
- workflow_version=7,
- correlation_id="01900000-0000-7000-8000-000000000013",
- node=NODE,
- )
- changed = {**NODE, "config": {"statement": "DELETE FROM orders"}}
- with pytest.raises(TaskTokenInvalid, match="node binding"):
- verifier.verify(token, node=changed)
- with pytest.raises(TaskTokenInvalid):
- verifier.verify(token[:-1] + ("a" if token[-1] != "a" else "b"), node=NODE)
- now[0] = 1_011
- with pytest.raises(TaskTokenExpired):
- verifier.verify(token, node=NODE)
- def test_task_token_secret_has_a_minimum_strength():
- with pytest.raises(ValueError, match="at least 32"):
- TaskTokenIssuer("too-short")
|