from __future__ import annotations import hashlib import hmac import secrets def verify_nextcloud_talk_signature( signature: str, random: str, body: str, secret: str, ) -> bool: expected = hmac.new( secret.encode("utf-8"), (random + body).encode("utf-8"), hashlib.sha256, ).hexdigest() return hmac.compare_digest(expected, signature) def generate_nextcloud_talk_signature( body: str, secret: str, ) -> tuple[str, str]: random = secrets.token_hex(32) signature = hmac.new( secret.encode("utf-8"), (random + body).encode("utf-8"), hashlib.sha256, ).hexdigest() return random, signature def extract_nextcloud_talk_headers( headers: dict, ) -> dict | None: signature = headers.get("X-Nextcloud-Talk-Signature") random = headers.get("X-Nextcloud-Talk-Random") backend = headers.get("X-Nextcloud-Talk-Backend") if not all([signature, random, backend]): return None return { "signature": signature, "random": random, "backend": backend, }