Skip to content

Instantly share code, notes, and snippets.

@wonderstory
Last active June 11, 2017 16:03
Show Gist options
  • Save wonderstory/67b5918b53a3bfbf2225b464f2bbd94d to your computer and use it in GitHub Desktop.
Save wonderstory/67b5918b53a3bfbf2225b464f2bbd94d to your computer and use it in GitHub Desktop.
Validating payloads with secret token from GitHub on Flask app
import os
from flask import Flask, request, abort
import hashlib
import hmac
import subprocess
app = Flask(__name__)
SECRET = os.environ['GITHUB_SECRET_TOKEN'] # Never hardcode
SUBPROCESS_COMMAND = 'cd /PATH/TO/REPO && git fetch && git reset --hard origin/master && git clean -fdx'
@app.route('/')
def index():
return 'Hello'
@app.route('/_YOUR_ENTRYPOINT_TO_DEPLOY_', methods=['POST'])
def deploy():
if request.headers['Content-Type'] != 'application/json':
abort(415, {'message': 'application/json required'})
if 'X-GitHub-Event' not in request.headers:
abort(400, {'message': 'invalid event'})
if 'X-Hub-Signature' not in request.headers:
abort(401, {'message': 'signature required'})
sha_name, signature = request.headers['X-Hub-Signature'].split('=')
post_data = request.get_data()
digester = hmac.new(SECRET.encode('utf-8'), msg=post_data, digestmod=hashlib.sha1)
if not hmac.compare_digest(signature, digester.hexdigest()):
abort(401, {'message': 'invalid signature'})
data = {}
try:
data = request.get_json()
except:
abort(415, {'message': 'invalid json'})
if request.headers['X-GitHub-Event'] == 'push':
if data['ref'] == 'refs/heads/master':
try:
subprocess.run(SUBPROCESS_COMMAND, shell=True, check=True)
except subprocess.CalledProcessError:
return 'failed'
return str(data['repository']['id'])
return 'thru'
@app.errorhandler(400)
@app.errorhandler(401)
@app.errorhandler(415)
def error_handler(error):
response = error.description['message']
return response, error.code
if __name__ == '__main__':
app.debug = True
app.run()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment