ported over from old webhook script

This commit is contained in:
Morgan McMillian 2022-06-24 17:16:00 -07:00
parent 7dc7d2786a
commit e04b3ce3c6
3 changed files with 223 additions and 1 deletions

View file

@ -1,6 +1,6 @@
MIT License
Copyright (c) <year> <copyright holders>
Copyright (c) 2022 Morgan McMillian
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

5
requirements.txt Normal file
View file

@ -0,0 +1,5 @@
PyYAML
Flask
gunicorn
requests
cryptography

217
webhooks.py Normal file
View file

@ -0,0 +1,217 @@
import logging
import base64
import requests
import yaml
import os
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PublicKey
from flask import Flask, jsonify, request, abort
app = Flask(__name__)
# setup the environment
SNAP_USER_DATA = os.environ.get('SNAP_USER_DATA')
if SNAP_USER_DATA is None:
filename = 'config.yaml'
log_file = 'webhook.log'
else:
filename = SNAP_USER_DATA + '/config.yaml'
log_file = SNAP_USER_DATA + '/webhook.log'
logging.basicConfig(level=logging.DEBUG, filename=log_file)
with open(filename, "rb") as config_file:
config = yaml.load(config_file, Loader=yaml.SafeLoader)
srht_public_key = Ed25519PublicKey.from_public_bytes(
base64.b64decode(config['srht_payload_sig']))
@app.route('/gitlab/<gateway>', methods=['POST'])
def gitlab_event(gateway=None):
token = request.headers['X-Gitlab-Token']
event = request.headers['X-Gitlab-Event']
if gateway is None:
logging.info("MISSING GATEWAY")
abort(400)
if token != config['gitlab_token']:
logging.info("INVALID GITLAB TOKEN")
abort(401)
if event == "Push Hook":
logging.debug(f"GitLab - {event} >> {gateway} ")
gl_push_event(gateway, request.json)
elif event == "Issue Hook":
logging.debug(f"GitLab - {event} >> {gateway} ")
gl_issue_event(gateway, request.json)
elif event == "Note Hook":
logging.debug(f"GitLab - {event} >> {gateway} ")
gl_comment_event(gateway, request.json)
elif event == "Merge Request Hook":
logging.debug(f"GitLab - {event} >> {gateway} ")
gl_mr_event(gateway, request.json)
elif event == "Release Hook":
logging.debug(f"GitLab - {event} >> {gateway} ")
gl_release_event(gateway, request.json)
else:
logging.info("UNKNOWN GITLAB EVENT")
logging.debug(f"GitLab - {event} >> {gateway} ")
logging.debug(request.json)
return "", 200
def gl_push_event(gateway, data):
logging.debug(f">> {gateway}")
# logging.debug(data)
project = data["project"]["path_with_namespace"]
username = data["user_username"]
branch = data['ref'][len('refs/heads/'):]
count = data["total_commits_count"]
homepage = data["repository"]["homepage"]
s = "s" if count > 1 else ""
body = f"[{project}] {username} pushed {count} commit{s} to {branch}:\n"
for commit in data["commits"]:
cid = commit["id"][:8]
title = commit["title"]
url = commit["url"]
body += f"- [{cid}]({url}) {title}\n"
logging.debug(body)
mb_url = config["gitlab_gateway"]
payload = { 'gateway': gateway, 'username': "gitlab", 'text': body.rstrip() }
r = requests.post(mb_url, json=payload)
def gl_issue_event(gateway, data):
logging.debug(f">> {gateway}")
# logging.debug(data)
project = data["project"]["path_with_namespace"]
username = data["user"]["username"]
oid = data["object_attributes"]["iid"]
title = data["object_attributes"]["title"]
description = data['object_attributes']['description']
if "action" in data["object_attributes"]:
action = data["object_attributes"]["action"]
else:
action = "?"
body = f"[{project}] {username} {action}ed issue #{oid}: {title}\n"
body += f"{description}"
logging.debug(body)
mb_url = config["gitlab_gateway"]
payload = { 'gateway': gateway, 'username': "gitlab", 'text': body }
r = requests.post(mb_url, json=payload)
def gl_mr_event(gateway, data):
logging.debug(f">> {gateway}")
# logging.debug(data)
project = data["project"]["path_with_namespace"]
username = data["user"]["username"]
oid = data["object_attributes"]["iid"]
title = data["object_attributes"]["title"]
description = data['object_attributes']['description']
if "action" in data["object_attributes"]:
action = data["object_attributes"]["action"]
else:
action = "?"
body = f"[{project}] {username} {action} merge request !{oid}: {title}\n"
body += f"{description}"
logging.debug(body)
mb_url = config["gitlab_gateway"]
payload = { 'gateway': gateway, 'username': "gitlab", 'text': body }
r = requests.post(mb_url, json=payload)
def gl_release_event(gateway, data):
logging.debug(f">> {gateway}")
# logging.debug(data)
project = data["project"]["path_with_namespace"]
name = data["name"]
url = data["url"]
if data["action"] != "create":
return
body = f"[{project}] release {name}\n"
body += f"{url}"
logging.debug(body)
mb_url = config["gitlab_gateway"]
payload = { 'gateway': gateway, 'username': "gitlab", 'text': body }
r = requests.post(mb_url, json=payload)
def gl_comment_event(gateway, data):
logging.debug(f">> {gateway}")
logging.debug(data)
project = data["project"]["path_with_namespace"]
username = data["user"]["username"]
oid = data["object_attributes"]["id"]
note = data["object_attributes"]["note"]
ntype = data["object_attributes"]["noteable_type"]
if ntype == "Issue":
iid = data["issue"]["iid"]
title = data["issue"]["title"]
item = f"issue #{iid}: {title}"
elif ntype == "MergeRequest":
mid = data["merge_request"]["id"]
title = data["merge_request"]["title"]
item = f"merge request !{mid}: {title}"
elif ntype == "Commit":
cid = data["commit"]["id"][:8]
item = f"commit {cid}"
elif ntype == "Snippet":
sid = data["snippet"]["sid"]
title = data["snippet"]["title"]
item = f"snippet {sid}: {title}"
else:
item = "?"
body = f"[{project}] {username} commented on {item}\n"
body += f"> {note}"
logging.debug(body)
mb_url = config["gitlab_gateway"]
payload = { 'gateway': gateway, 'username': "gitlab", 'text': body }
r = requests.post(mb_url, json=payload)
@app.route('/srht/<user>/<repo>/<gateway>', methods=['POST'])
def srht_event(user, repo, gateway):
logging.debug(request.url)
logging.debug(request.headers)
payload = request.data
signature = request.headers["X-Payload-Signature"]
signature = base64.b64decode(signature)
nonce = request.headers["X-Payload-Nonce"].encode()
try:
srht_public_key.verify(signature, payload + nonce)
event = request.headers["X-Webhook-Event"]
if event == "repo:post-update":
logging.debug(f"SRHT - {event} >> {gateway}")
# __post_update(user, repo, gateway, request.json)
elif event == "ticket:create":
logging.debug(f"SRHT - {event} >> {gateway}")
# __ticket_create(user, repo, gateway, request.json)
elif event == "event:create":
logging.debug(f"SRHT - {event} >> {gateway}")
# __event_create(user, repo, gateway, request.json)
except Exception:
logging.exception('SRHT')
return '', 200