Source code for officiumdivinum.api.update_server
"""
Re-used from.
https://github.com/SwagLyrics/swaglyrics-backend/blob/35d23d0ba416e742e381da931d592ce6f58fc13f/issue_maker.py
which is under the MIT license.
"""
import hashlib
import hmac
import json
import os
from subprocess import run
import git
from flask import Blueprint
from flask import abort
from flask import request
update_server = Blueprint("update_server", __name__, url_prefix="/update_server")
try:
w_secret = os.environ["WEBHOOK_SECRET"]
except KeyError:
pass
[docs]def is_valid_signature(x_hub_signature, data, private_key):
hash_algorithm, github_signature = x_hub_signature.split("=", 1)
algorithm = hashlib.__dict__.get(hash_algorithm)
encoded_key = bytes(private_key, "latin-1")
mac = hmac.new(encoded_key, msg=data, digestmod=algorithm)
return hmac.compare_digest(mac.hexdigest(), github_signature)
[docs]@update_server.route("/", methods=["POST"])
def webhook():
if request.method != "POST":
return "OK"
else:
abort_code = 418
# Do initial validations on required headers
if "X-Github-Event" not in request.headers:
abort(abort_code)
if "X-Github-Delivery" not in request.headers:
abort(abort_code)
if "X-Hub-Signature" not in request.headers:
abort(abort_code)
if not request.is_json:
abort(abort_code)
if "User-Agent" not in request.headers:
abort(abort_code)
ua = request.headers.get("User-Agent")
if not ua.startswith("GitHub-Hookshot/"):
abort(abort_code)
event = request.headers.get("X-GitHub-Event")
if event == "ping":
return json.dumps({"msg": "Hi!"})
if event != "push":
return json.dumps({"msg": "Wrong event type"})
x_hub_signature = request.headers.get("X-Hub-Signature")
if not is_valid_signature(x_hub_signature, request.get_data(), w_secret):
print("Deploy signature failed: {sig}".format(sig=x_hub_signature))
abort(abort_code)
payload = request.get_json()
if payload is None:
print("Deploy payload is empty: {payload}".format(payload=payload))
abort(abort_code)
if payload["ref"] != "refs/heads/master":
return json.dumps({"msg": "Not master; ignoring"})
repo = git.Repo("~/OfficiumDivinum")
origin = repo.remotes.origin
pull_info = origin.pull()
if len(pull_info) == 0:
return json.dumps({"msg": "Didn't pull any information from remote!"})
if pull_info[0].flags > 128:
return json.dumps({"msg": "Didn't pull any information from remote!"})
run(["pip3", "install", "-e", "~/OfficiumDivinum"])
commit_hash = pull_info[0].commit.hexsha
build_commit = f'build_commit = "{commit_hash}"'
print(f"{build_commit}")
return "Updated PythonAnywhere server to commit {commit}".format(
commit=commit_hash
)