"""ITs for the WebRTC mesh TURN-credentials endpoint — Phase C of [[my-sea-invite-voice-blueprint]]. Verifies the coturn `use-auth-secret` REST scheme (HMAC-SHA1 username/credential) + auth gating. """ import base64 import hashlib import hmac from django.test import TestCase, override_settings from django.urls import reverse from apps.lyric.models import User @override_settings( COTURN_SHARED_SECRET="testsecret", COTURN_TURN_HOST="turn.test", COTURN_TTL=86400, ) class TURNCredentialsTest(TestCase): def setUp(self): self.user = User.objects.create(email="turn@test.io", username="turner") self.url = reverse("api_turn_credentials") def test_requires_authentication(self): resp = self.client.get(self.url) self.assertIn(resp.status_code, (401, 403)) def test_returns_ice_servers_and_ttl(self): self.client.force_login(self.user) data = self.client.get(self.url).json() self.assertEqual(data["ttl"], 86400) urls = [s for srv in data["iceServers"] for s in srv["urls"]] self.assertTrue(any(u.startswith("stun:turn.test") for u in urls)) self.assertTrue(any("turn:turn.test" in u and "transport=udp" in u for u in urls)) self.assertTrue(any("turn:turn.test" in u and "transport=tcp" in u for u in urls)) def test_username_is_expiry_colon_user_id(self): self.client.force_login(self.user) data = self.client.get(self.url).json() expiry_str, _, uid = data["username"].partition(":") self.assertTrue(expiry_str.isdigit()) self.assertEqual(uid, str(self.user.id)) def test_credential_is_hmac_sha1_of_username(self): self.client.force_login(self.user) data = self.client.get(self.url).json() expected = base64.b64encode( hmac.new(b"testsecret", data["username"].encode(), hashlib.sha1).digest() ).decode() self.assertEqual(data["credential"], expected) # The TURN iceServer entry carries the same credential. turn = [s for s in data["iceServers"] if "credential" in s][0] self.assertEqual(turn["credential"], expected)