68 lines
1.7 KiB
Python
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'))
|