import base64 import hashlib import hmac from typing import Optional from .base_object import BaseObject class Webhook(BaseObject): """Represents a Box Webhook.""" _item_type = 'webhook' @staticmethod def validate_message( body: bytes, headers: dict, primary_signature_key: str, secondary_signature_key: str = None ) -> bool: """ Validates a `Webhook` message. :param body: The encoded webhook body. :param headers: The headers for the `Webhook` notification. :param primary_signature_key: The `Webhook` primary signature key for this application. :param secondary_signature_key: The `Webhook` secondary signature key for this application. :return: A `bool` indicating whether a webhook message was validated or not """ primary_signature = _compute_signature(body, headers, primary_signature_key) if primary_signature is not None and hmac.compare_digest(primary_signature, headers.get('box-signature-primary')): return True if secondary_signature_key: secondary_signature = _compute_signature(body, headers, secondary_signature_key) if secondary_signature is not None and hmac.compare_digest(secondary_signature, headers.get('box-signature-secondary')): return True return False return False def _compute_signature(body: bytes, headers: dict, signature_key: str) -> Optional[str]: """ Computes the Hmac for the webhook notification given one signature key. :param body: The encoded webhook body. :param headers: The headers for the `Webhook` notification. :param signature_key: The `Webhook` signature key for this application. :return: An Hmac signature. """ if signature_key is None: return None if headers.get('box-signature-version') != '1': return None if headers.get('box-signature-algorithm') != 'HmacSHA256': return None encoded_signature_key = signature_key.encode('utf-8') encoded_delivery_time_stamp = headers.get('box-delivery-timestamp').encode('utf-8') new_hmac = hmac.new(encoded_signature_key, digestmod=hashlib.sha256) new_hmac.update(body + encoded_delivery_time_stamp) signature = base64.b64encode(new_hmac.digest()).decode() return signature