|
| 1 | +from fastapi import APIRouter, status, HTTPException |
| 2 | +from fastapi.requests import Request |
| 3 | +from starlette.responses import Response |
| 4 | +import json |
| 5 | +from src.data.json_handler import update_json |
| 6 | +import src.utils.log as log |
| 7 | +from src.cfg.settings import security |
| 8 | +import hashlib |
| 9 | +import hmac |
| 10 | + |
| 11 | +router = APIRouter( |
| 12 | + prefix="/wh", |
| 13 | + tags=["webhook"], |
| 14 | + include_in_schema=False, |
| 15 | +) |
| 16 | + |
| 17 | + |
| 18 | +class Webhook: |
| 19 | + def __init__(self, token): |
| 20 | + self.token = token |
| 21 | + |
| 22 | + def github_verify(self, payload, headers): |
| 23 | + signature_header = headers.get("x-hub-signature-256", None) |
| 24 | + if not signature_header: |
| 25 | + raise HTTPException( |
| 26 | + status_code=status.HTTP_403_FORBIDDEN, |
| 27 | + detail="x-hub-signature-256 header missing", |
| 28 | + ) |
| 29 | + hash_object = hmac.new( |
| 30 | + self.token.encode("utf-8"), msg=payload, digestmod=hashlib.sha256 |
| 31 | + ) |
| 32 | + expected_signature = "sha256=" + hash_object.hexdigest() |
| 33 | + if not hmac.compare_digest(signature_header, expected_signature): |
| 34 | + raise HTTPException( |
| 35 | + status_code=status.HTTP_403_FORBIDDEN, |
| 36 | + detail="Request signatures invalid.", |
| 37 | + ) |
| 38 | + |
| 39 | + |
| 40 | +@router.post(path="/github", status_code=status.HTTP_204_NO_CONTENT) |
| 41 | +async def github_webhook(request: Request, response: Response): |
| 42 | + headers = request.headers |
| 43 | + payload = await request.body() |
| 44 | + json_payload = json.loads(payload) |
| 45 | + try: |
| 46 | + wh = Webhook(security["token"]) |
| 47 | + msg = wh.github_verify(payload, headers) |
| 48 | + except HTTPException as e: |
| 49 | + response.status_code = status.HTTP_400_BAD_REQUEST |
| 50 | + return |
| 51 | + |
| 52 | + if json_payload["action"] == "push": |
| 53 | + update_json() |
0 commit comments