Browse Source

Enhance PlugNMeetWebhookAPIView signature verification with debug logging

- Updated the _verify_webhook_signature method to include detailed debug logging for better traceability of signature verification issues.
- Improved error messages for missing headers and configuration settings.
- Added checks for empty request bodies to assist in identifying middleware issues.
- Adjusted logging to prevent sensitive information exposure while still providing useful debugging information.
master
Mohsen Taba 4 months ago
parent
commit
9790fcc0c9
  1. 55
      apps/course/views/webhook.py
  2. 6
      config/settings/base.py

55
apps/course/views/webhook.py

@ -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

6
config/settings/base.py

@ -279,9 +279,9 @@ ADMIN_INDEX_TITLE = 'Imam Javad Administration'
SITE_DOMAIN = "https://imamjavad.nwhco.ir"
ONLINE_CLASS_FRONTEND_DOMAIN = env('ONLINE_CLASS_FRONTEND_DOMAIN', default=SITE_DOMAIN)
ONLINE_CLASS_TOKEN_TTL = env.int('ONLINE_CLASS_TOKEN_TTL', default=3000)
PLUGNMEET_SERVER_URL = env('PLUGNMEET_SERVER_URL', default='https://meet.newhorizonco.uk')
PLUGNMEET_API_KEY = env('PLUGNMEET_API_KEY', default='habibmeet_api_key_2024')
PLUGNMEET_API_SECRET = env('PLUGNMEET_API_SECRET', default='habibmeet_secret_zumyyYWqv7KR2kUqvYdq4z4sXg7XTBD2ljT6_2024')
PLUGNMEET_SERVER_URL ='https://meet.newhorizonco.uk'
PLUGNMEET_API_KEY ='PLUGNMEET_API_KEY', default='habibmeet_api_key_2024'
PLUGNMEET_API_SECRET ='habibmeet_secret_zumyyYWqv7KR2kUqvYdq4z4sXg7XTBD2ljT6_2024'
PLUGNMEET_TIMEOUT = env.float('PLUGNMEET_TIMEOUT', default=10.0)

Loading…
Cancel
Save