33 lines
988 B
Python
33 lines
988 B
Python
from __future__ import annotations
|
|
|
|
import base64
|
|
import hashlib
|
|
import hmac
|
|
import time
|
|
import urllib.parse
|
|
|
|
|
|
def compute_dingtalk_sign(timestamp_ms: str, app_secret: str) -> str:
|
|
secret_enc = app_secret.encode("utf-8")
|
|
string_to_sign = f"{timestamp_ms}\n{app_secret}".encode()
|
|
hmac_code = hmac.new(secret_enc, string_to_sign, digestmod=hashlib.sha256).digest()
|
|
return urllib.parse.quote_plus(base64.b64encode(hmac_code))
|
|
|
|
|
|
def verify_webhook_signature(headers: dict, app_secret: str) -> bool:
|
|
request_timestamp = headers.get("timestamp", "")
|
|
request_sign = headers.get("sign", "")
|
|
|
|
if not request_timestamp or not request_sign:
|
|
return True
|
|
|
|
try:
|
|
ts = int(request_timestamp) / 1000
|
|
if abs(time.time() - ts) > 3600:
|
|
return False
|
|
except (ValueError, TypeError):
|
|
return False
|
|
|
|
expected_sign = compute_dingtalk_sign(request_timestamp, app_secret)
|
|
return hmac.compare_digest(request_sign, expected_sign)
|