X-Git-Url: https://git.ralfj.de/git-mirror.git/blobdiff_plain/5e4cc8e8aed90a3f5464cbdd1656e47bf3fc810e..HEAD:/webhook-core.py diff --git a/webhook-core.py b/webhook-core.py index d4c1ab7..90432c8 100755 --- a/webhook-core.py +++ b/webhook-core.py @@ -24,25 +24,38 @@ #============================================================================== # This is the hook called by GitHub as webhook. It updats the local repository, and then all the other mirrors. -import sys, traceback +import sys, traceback, json from git_mirror import * +def get_github_payload(repo, signature): + '''Return the github-style JSON encoded payload (as if we were called as a github webhook)''' + data = sys.stdin.buffer.read() + verify_signature = repo.compute_hmac(data) + if signature != "sha1="+verify_signature: + raise Exception("You are not GitHub!") + try: + data = json.loads(data.decode('utf-8')) + return data + except ValueError: + return {} # nothing read + + if __name__ == "__main__": # call this with: repo = None # we will try to use this during exception handling try: repos = load_repos() if len(sys.argv) < 4: - raise Exception("Usage: {0} ".format(os.path.basename(sys.argv[0]))) + raise Exception("Usage: {} ".format(os.path.basename(sys.argv[0]))) reponame = sys.argv[1] githubEvent = sys.argv[2] githubSignature = sys.argv[3] if reponame not in repos: - raise Exception("Repository missing or not found.") + raise Exception("Repository {} missing or not found.".format(reponame)) repo = repos[reponame] # now sync this repository - data = get_github_payload() + data = get_github_payload(repo, githubSignature) if githubEvent == 'ping': # github sends this initially print("Content-Type: text/plain") @@ -55,7 +68,7 @@ if __name__ == "__main__": newsha = data["after"] # validate the ref name if re.match('refs/[a-z/]+', ref) is None: - raise Exception("Invalid ref name {0}".format(ref)) + raise Exception("Invalid ref name {}".format(ref)) # collect URLs of this repository, to find the mirror name urls = [] for key in ("git_url", "ssh_url", "clone_url"): @@ -63,18 +76,19 @@ if __name__ == "__main__": mirror = repo.find_mirror_by_url(urls) if mirror is None: raise Exception("Could not find the mirror.") - repo.update_ref_from_mirror(ref, oldsha, newsha, mirror, suppress_stderr = True) + stdout = repo.update_ref_from_mirror(ref, oldsha, newsha, mirror, suppress_stderr = True) # print an answer print("Content-Type: text/plain") print() - print("Updated {0}:{1} from mirror {2} from {3} to {4}".format(reponame, ref, mirror, oldsha, newsha)) + print("Updated {}:{} from mirror {} from {} to {}".format(reponame, ref, mirror, oldsha, newsha)) + print(stdout) else: - raise Exception("Unexpected github event {0}.".format(githubEvent)) + raise Exception("Unexpected github event {}.".format(githubEvent)) except Exception as e: if repo is not None: - repo.mail_owner("There was a problem running the git-mirror webhook:\n\n{0}".format(traceback.format_exc())) + repo.mail_owner("There was a problem running the git-mirror webhook:\n\n{}".format(traceback.format_exc())) # do not print all the details print("Status: 500 Internal Server Error") print("Content-Type: text/plain") print() - print("We have a problem:\n{0}".format('\n'.join(traceback.format_exception_only(type(e), e)))) + print("git-mirror: We have a problem:\n{}".format('\n'.join(traceback.format_exception_only(type(e), e))))