"""A stand-in portal: its key, its JWKS, and the tokens it would mint. Shared by the remote-access tests and the panel ones, since a screen paired through a portal is a portal token that happens to name a panel. """ from __future__ import annotations import json from datetime import UTC, datetime, timedelta from typing import Any import jwt from cryptography.hazmat.primitives import serialization from cryptography.hazmat.primitives.asymmetric import rsa INSTALLATION_ID = "6f1c2d3e-4a5b-4c6d-8e9f-0a1b2c3d4e5f" ISSUER = "https://hub.example.test" def jwks(key: rsa.RSAPrivateKey) -> dict[str, Any]: jwk = json.loads(jwt.algorithms.RSAAlgorithm.to_jwk(key.public_key())) jwk.update({"use": "sig", "alg": "RS256", "kid": "test-portal"}) return {"keys": [jwk]} def portal_token( key: rsa.RSAPrivateKey, *, subject: str = "portal-user-1", audience: str = INSTALLATION_ID, issuer: str = ISSUER, scope: str = "proxy", ) -> str: now = datetime.now(UTC) pem = key.private_bytes( encoding=serialization.Encoding.PEM, format=serialization.PrivateFormat.PKCS8, encryption_algorithm=serialization.NoEncryption(), ) return jwt.encode( { "sub": subject, "iss": issuer, "aud": audience, "iat": now, "exp": now + timedelta(hours=1), "scope": scope, }, pem, algorithm="RS256", headers={"kid": "test-portal"}, )