File size: 1,618 Bytes
da8fcf1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
"""Webhook HMAC verification smoke test."""

from __future__ import annotations

import hashlib
import hmac
import json
import os

import pytest


def _signature(secret: str, body: bytes) -> str:
    return "sha256=" + hmac.new(secret.encode(), body, hashlib.sha256).hexdigest()


def test_hmac_verify_accepts_valid(monkeypatch):
    secret = "supersecret"
    monkeypatch.setenv("GITHUB_WEBHOOK_SECRET", secret)
    monkeypatch.setenv("WEBHOOK_HMAC_SECRET", secret)

    import importlib
    import webhook_server
    importlib.reload(webhook_server)

    body = json.dumps({"action": "ping"}).encode()
    sig = _signature(secret, body)

    verifier = (
        getattr(webhook_server, "verify_hmac", None)
        or getattr(webhook_server, "verify_signature", None)
        or getattr(webhook_server, "_verify_signature", None)
    )
    if verifier is None:
        pytest.skip("webhook_server exposes no public HMAC verifier")
    assert verifier(body, sig) is True


def test_hmac_verify_rejects_bogus(monkeypatch):
    secret = "supersecret"
    monkeypatch.setenv("GITHUB_WEBHOOK_SECRET", secret)
    monkeypatch.setenv("WEBHOOK_HMAC_SECRET", secret)

    import importlib
    import webhook_server
    importlib.reload(webhook_server)

    verifier = (
        getattr(webhook_server, "verify_hmac", None)
        or getattr(webhook_server, "verify_signature", None)
        or getattr(webhook_server, "_verify_signature", None)
    )
    if verifier is None:
        pytest.skip("webhook_server exposes no public HMAC verifier")
    body = b'{"x": 1}'
    assert verifier(body, "sha256=deadbeef") is False