@ -100,35 +100,78 @@ class PlugNMeetWebhookAPIView(APIView):
status = status . HTTP_500_INTERNAL_SERVER_ERROR
)
# def _verify_webhook_signature(self, request) -> bool:
# """
# Verify webhook signature using SHA256 HMAC.
# Expects Hash-Token header with SHA256 signature of request body.
# """
# hash_token = request.headers.get('Hash-Token')
# if not hash_token:
# logger.warning(f"[PlugNMeet Webhook] Missing Hash-Token header")
# return False
# # Get API secret from settings
# api_secret = getattr(settings, 'PLUGNMEET_API_SECRET', None)
# if not api_secret:
# logger.error(f"[PlugNMeet Webhook] PLUGNMEET_API_SECRET not configured")
# raise ImproperlyConfigured("PLUGNMEET_API_SECRET is not configured")
# # Calculate expected signature
# body = request.body
# expected_signature = hmac.new(
# api_secret.encode('utf-8'),
# body,
# hashlib.sha256
# ).hexdigest()
# # Compare signatures (constant time comparison)
# is_valid = hmac.compare_digest(hash_token, expected_signature)
# if not is_valid:
# logger.warning(f"[PlugNMeet Webhook] Signature mismatch - expected={expected_signature[:10]}... got={hash_token[:10]}...")
# return is_valid
def _verify_webhook_signature ( self , request ) - > bool :
"""
Verify webhook signature using SHA256 HMAC .
Expects Hash - Token header with SHA256 signature of request body .
DEBUG VERSION : Prints details to find the mismatch .
"""
hash_token = request . headers . get ( ' Hash-Token ' )
if not hash_token :
logger . warning ( f " [PlugNMeet Webhook] Missing Hash-Token header " )
logger . error ( " [PlugNMeet Webhook] MISSING Hash-Token header" )
return False
# Get API secret from settings
api_secret = getattr ( settings , ' PLUGNMEET_API_SECRET ' , None )
if not api_secret :
logger . error ( f " [PlugNMeet Webhook] PLUGNMEET_API_SECRET not configured " )
logger . error ( " [PlugNMeet Webhook] PLUGNMEET_API_SECRET is missing in settings.py " )
raise ImproperlyConfigured ( " PLUGNMEET_API_SECRET is not configured " )
# DEBUG: Print the first/last few chars of the secret to ensure it's loaded correctly
# DO NOT log the whole secret in production!
logger . info ( f " [DEBUG] Secret in Django: {api_secret[:4]}...{api_secret[-4:]} " )
# Calculate expected signature
body = request . body
# DEBUG: Check if body is empty (common middleware issue)
if len ( body ) == 0 :
logger . error ( " [DEBUG] Request Body is EMPTY! Middleware might have consumed it. " )
expected_signature = hmac . new (
api_secret . encode ( ' utf-8 ' ) ,
body ,
hashlib . sha256
) . hexdigest ( )
# Compare signatures (constant time comparison)
# DEBUG: Compare them visually in logs
logger . info ( f " [DEBUG] Received Token: {hash_token} " )
logger . info ( f " [DEBUG] Calculated: {expected_signature} " )
is_valid = hmac . compare_digest ( hash_token , expected_signature )
if not is_valid :
logger . warning ( f " [PlugNMeet Webhook] Signature mismatch - expected={expected_signature[:10]}... got={hash_token[:10]}... " )
logger . error ( " [PlugNMeet Webhook] Signature MISMATCH " )
return is_valid