webhooks/server.py

118 lines
3.8 KiB
Python
Raw Normal View History

import os
2019-02-05 20:51:40 +01:00
import hmac
import hashlib
import subprocess
2019-02-05 20:51:40 +01:00
from sanic import Sanic
from sanic.response import text
from sanic.exceptions import abort
app = Sanic()
secret = open("./github_webhook_secret", "r").read().strip()
2019-02-06 00:58:50 +01:00
gitbot_password = open("./gitbot_password", "r").read().strip()
2019-02-05 20:51:40 +01:00
other_chans = {
"doc": "doc",
}
# TODO
# * choper tous les templates de notification
# * choper tous les evenements à suivre
# * fusionner les 2
# * déployer
def notify(message, chan="dev"):
print(f"{chan} -> {message}")
2019-02-06 01:06:36 +01:00
subprocess.check_call(["python", "./to_room.py", gitbot_password, message, chan])
2019-02-05 20:51:40 +01:00
@app.route("/github", methods=['POST'])
async def github(request):
# Only SHA1 is supported
header_signature = request.headers.get('X-Hub-Signature')
if header_signature is None:
print("no header X-Hub-Signature")
abort(403)
sha_name, signature = header_signature.split('=')
if sha_name != 'sha1':
print("signing algo isn't sha1, it's '%s'" % sha_name)
abort(501)
# HMAC requires the key to be bytes, but data is string
2019-02-05 23:17:23 +01:00
mac = hmac.new(secret.encode(), msg=request.body, digestmod=hashlib.sha1)
2019-02-05 20:51:40 +01:00
if not hmac.compare_digest(str(mac.hexdigest()), str(signature)):
abort(403)
hook_type = request.headers.get("X-Github-Event")
print(f"Hook type: {hook_type}")
2019-02-06 00:52:42 +01:00
# https://developer.github.com/v3/activity/events/types/#pushevent
2019-02-05 20:51:40 +01:00
if hook_type == "push":
repository = request.json["repository"]["name"]
commits = request.json["commits"]
user = request.json["pusher"]["name"]
branch = request.json["ref"].split("/", 2)[2]
if len(commits) == 1:
url = commits[0]["url"]
notify(f"[{repository}] @{user} pushed {len(commits)} commit to {branch}: {url}")
2019-02-05 20:51:40 +01:00
else:
url = request.json["compare"]
notify(f"[{repository}] @{user} pushed {len(commits)} commits to {branch}: {url}")
2019-02-05 20:51:40 +01:00
for commit in commits:
2019-02-06 00:58:01 +01:00
author = commit["author"]["name"]
2019-02-05 20:51:40 +01:00
commit_message = commit["message"]
notify(f"[{repository}/{branch}] {commit_message} - {author}")
2019-02-06 00:52:50 +01:00
# https://developer.github.com/v3/activity/events/types/#commitcommentevent
elif hook_type == "commit_comment":
repository = request.json["repository"]["name"]
user = request.json["comment"]["user"]["login"]
commit_short_id = request.json["comment"]["commit_id"][:7]
comment = request.json["comment"]["body"]
notify(f"[{repository}] @{user} comment on commit {commit_short_id}: {comment} {url}")
2019-02-06 01:18:57 +01:00
# https://developer.github.com/v3/activity/events/types/#createevent
elif hook_type == "create":
kind = request.json["ref_type"]
user = request.json["sender"]["login"]
repository = request.json["repository"]["name"]
if kind == "repository":
notify(f"@{user} created new repository {repository}: {url}")
2019-02-06 01:18:57 +01:00
elif kind == "branch":
branch = request.json["ref"]
notify(f"[{repository}] @{user} created new branch {branch}")
2019-02-06 01:18:57 +01:00
elif kind == "tag":
tag = request.json["ref"]
notify(f"[{repository}] @{user} created new tag {tag}")
2019-02-06 01:18:57 +01:00
else:
print(f"WARNING: unknown 'create' even kind: {kind}")
2019-02-06 01:23:33 +01:00
# https://developer.github.com/v3/activity/events/types/#createevent
elif hook_type == "delete":
kind = request.json["ref_type"]
user = request.json["sender"]["login"]
repository = request.json["repository"]["name"]
ref = request.json["ref"]
notify(f"[{repository}] @{user} deleted {kind} {ref}")
2019-02-05 23:03:59 +01:00
return text("ok")
2019-02-05 20:51:40 +01:00
@app.route("/")
async def index(request):
return text("Webhooks server.")
if __name__ == '__main__':
app.run('localhost', port="4567", debug=True)