webhook/app.py
2023-03-16 12:25:40 +01:00

68 lines
1.7 KiB
Python

"""
A WSGI-based application to handle webhooks specifically written for Forgejo platforms.
Copyright © 2023 Benjamin Stadlbauer
"""
import json
import hashlib
import hmac
from backend import handle_data
from settings import *
def app(environ, start_response):
try:
data: dict = get_data(environ.copy())
except Exception as e:
start_response('400', [
('Content-Type', 'text/plain')
])
return iter([str(e).encode()])
try:
logging: str = handle_data(data)
except Exception as e:
start_response('500', [
('Content-Type', 'text/plain')
])
return iter([str(e).encode()])
start_response('200 OK', [
('Content-Type', 'text/plain')
])
return iter([logging.encode()])
def get_data(environ):
if environ['REQUEST_METHOD'] == 'POST':
if 'application/json' != environ.get('CONTENT_TYPE'):
raise Exception('Error: Content-Type is not application/json: ' + environ.get('CONTENT_TYPE'))
try:
request_body_size = int(environ.get('CONTENT_LENGTH', 0))
except (ValueError):
request_body_size = 0
if 0 == request_body_size:
raise Exception('Error: Content-Length is 0')
request_body = environ.get('wsgi.input').read(request_body_size)
signature = environ.get('HTTP_X_GITEA_SIGNATURE')
if not signature:
raise Exception('Error: Missing signature')
signature_actual = hmac.new(SECRET_KEY.encode(), request_body, hashlib.sha256).hexdigest()
if signature_actual != signature:
raise Exception('Error: Signature could not be validated')
try:
data = json.loads(request_body)
except json.decoder.JSONDecodeError as e:
raise Exception('Error: Could not parse the JSON body: %s' % e)
return data
else:
raise Exception('Error: Request is not POST: ' + environ.get('REQUEST_METHOD'))