aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafael G. Martins <rafael@rafaelmartins.eng.br>2018-10-14 16:17:24 +0200
committerRafael G. Martins <rafael@rafaelmartins.eng.br>2018-10-14 16:17:24 +0200
commit216b814b4f2ade8f8a044a9e67ed31499d0d3be4 (patch)
tree8f0a8f5f23bf039ba0f560bdc12bfad05abb0f98
parent3cfe922ff326ccdfd765e524d337c2e1bcad3d90 (diff)
downloadblogc-216b814b4f2ade8f8a044a9e67ed31499d0d3be4.tar.gz
blogc-216b814b4f2ade8f8a044a9e67ed31499d0d3be4.tar.bz2
blogc-216b814b4f2ade8f8a044a9e67ed31499d0d3be4.zip
github-lambda: support signature
-rw-r--r--src/blogc-github-lambda/lambda_function.py.in43
1 files changed, 42 insertions, 1 deletions
diff --git a/src/blogc-github-lambda/lambda_function.py.in b/src/blogc-github-lambda/lambda_function.py.in
index 285a395..2883eff 100644
--- a/src/blogc-github-lambda/lambda_function.py.in
+++ b/src/blogc-github-lambda/lambda_function.py.in
@@ -12,6 +12,7 @@ from StringIO import StringIO
import base64
import boto3
+import hmac
import hashlib
import json
import mimetypes
@@ -33,6 +34,11 @@ if GITHUB_AUTH is not None and ':' not in GITHUB_AUTH:
GITHUB_AUTH = boto3.client('kms').decrypt(
CiphertextBlob=base64.b64decode(GITHUB_AUTH))['Plaintext']
+GITHUB_SECRET = os.environ.get('GITHUB_SECRET')
+if GITHUB_SECRET is not None:
+ GITHUB_SECRET = boto3.client('kms').decrypt(
+ CiphertextBlob=base64.b64decode(GITHUB_SECRET))['Plaintext']
+
def get_tarball(repo_name):
tarball_url = 'https://api.github.com/repos/%s/tarball/master' % repo_name
@@ -192,10 +198,45 @@ def blogc_handler(message):
print "Commit not for master branch, skipping: %s" % payload['ref']
+def api_gateway_response(code, message):
+ return {
+ 'statusCode': code,
+ 'body': json.dumps({'message': message}),
+ }
+
+
+def api_gateway_handler(event):
+ headers = event.get('headers')
+ if headers is None:
+ return api_gateway_response(400, 'NO_HEADERS')
+
+ if headers.get('X-GitHub-Event') != 'push':
+ return api_gateway_response(400, 'UNSUPPORTED_EVENT')
+
+ body = event.get('body', '')
+
+ if GITHUB_SECRET is not None:
+ sig = headers.get('X-Hub-Signature')
+ if sig is None:
+ return api_gateway_response(400, 'NO_SIGNATURE')
+
+ pieces = sig.split('=')
+ if len(pieces) != 2 or pieces[0] != 'sha1':
+ return api_gateway_response(400, 'INVALID_SIGNATURE')
+
+ digest = hmac.new(GITHUB_SECRET, body, hashlib.sha1)
+
+ if not hmac.compare_digest(digest.hexdigest(), pieces[1]):
+ return api_gateway_response(400, 'BAD_SIGNATURE')
+
+ blogc_handler(body)
+ return api_gateway_response(201, 'ACCEPTED')
+
+
def lambda_handler(event, context):
if 'Records' in event: # sns
for record in event['Records']:
if 'Sns' in record:
blogc_handler(record['Sns']['Message'])
elif 'body' in event: # api-gateway
- blogc_handler(event['body'])
+ return api_gateway_handler(event['body'])