diff --git a/apps/course/views/webhook.py b/apps/course/views/webhook.py index 92339a2..699ee13 100644 --- a/apps/course/views/webhook.py +++ b/apps/course/views/webhook.py @@ -115,25 +115,53 @@ class PlugNMeetWebhookAPIView(APIView): return False body_bytes = request.data + auth_header = request.headers.get('Authorization') or request.META.get('HTTP_AUTHORIZATION', '') + + logger.info(f"🔍 [PlugNMeet Webhook] Verify Signature details:") + logger.info(f" - Hash-Token (first 30 chars): {hash_token[:30]}... (length: {len(hash_token)})") + logger.info(f" - Authorization (first 30 chars): {auth_header[:30]}... (length: {len(auth_header)})") + logger.info(f" - Body bytes length: {len(body_bytes)}") + if len(body_bytes) > 0: + logger.info(f" - Body preview (first 100 bytes): {body_bytes[:100]}") # 1. Try JWT verification (PlugNMeet production standard) try: # A JWT typically consists of three segments separated by dots if len(hash_token.split('.')) == 3: - decoded = jwt.decode(hash_token, api_secret, algorithms=['HS256']) + logger.info(" - Attempting JWT decode on Hash-Token...") + decoded = jwt.decode( + hash_token, + api_secret, + algorithms=['HS256'], + options={ + "verify_signature": True, + "verify_exp": False, + "verify_nbf": False, + "verify_iat": False, + "verify_aud": False, + "verify_iss": False + } + ) + logger.info(f" - Decoded JWT claims: {list(decoded.keys())}") token_sha256 = decoded.get('sha256') if token_sha256: hasher = hashlib.sha256() hasher.update(body_bytes) computed_sha256 = base64.b64encode(hasher.digest()).decode('utf-8') + logger.info(f" - Claim SHA256: {token_sha256}") + logger.info(f" - Computed SHA256: {computed_sha256}") if hmac.compare_digest(token_sha256, computed_sha256): + logger.info(" - JWT SHA256 signature verification successful!") return True else: logger.error(f"❌ [PlugNMeet Webhook] SHA256 mismatch! Token claim: {token_sha256}, Computed: {computed_sha256}") else: logger.error("❌ [PlugNMeet Webhook] JWT missing 'sha256' claim") + else: + logger.info(" - Hash-Token does not have 3 segments (not a JWT).") except jwt.PyJWTError as e: - logger.warning(f"⚠️ [PlugNMeet Webhook] JWT decoding failed: {e}. Falling back to HMAC-SHA256 check.") + logger.error(f"❌ [PlugNMeet Webhook] JWT decoding failed: {e.__class__.__name__}: {str(e)}") + logger.warning(f"⚠️ [PlugNMeet Webhook] JWT decoding failed. Falling back to HMAC-SHA256 check.") # 2. Fallback: HMAC-SHA256 verification (for backward compatibility with test_webhook.py) expected_signature = hmac.new( @@ -142,7 +170,9 @@ class PlugNMeetWebhookAPIView(APIView): hashlib.sha256 ).hexdigest() + logger.info(f" - Expected HMAC: {expected_signature}") if hmac.compare_digest(hash_token, expected_signature): + logger.info(" - Fallback HMAC verification successful!") return True logger.error(f"❌ [PlugNMeet Webhook] Signature mismatch! \nReceived: {hash_token[:10]}...\nExpected HMAC: {expected_signature[:10]}...")