Skip to content

Commit 9521287

Browse files
committed
Initial commit of working lambda function
0 parents  commit 9521287

File tree

8 files changed

+246
-0
lines changed

8 files changed

+246
-0
lines changed

.gitignore

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
# Byte-compiled / optimized / DLL files
2+
__pycache__/
3+
*.py[cod]
4+
*$py.class
5+
6+
# C extensions
7+
*.so
8+
9+
# Distribution / packaging
10+
.Python
11+
env/
12+
build/
13+
develop-eggs/
14+
dist/
15+
downloads/
16+
eggs/
17+
.eggs/
18+
lib/
19+
lib64/
20+
parts/
21+
sdist/
22+
var/
23+
*.egg-info/
24+
.installed.cfg
25+
*.egg
26+
27+
# PyInstaller
28+
# Usually these files are written by a python script from a template
29+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
30+
*.manifest
31+
*.spec
32+
33+
# Installer logs
34+
pip-log.txt
35+
pip-delete-this-directory.txt
36+
37+
# Unit test / coverage reports
38+
htmlcov/
39+
.tox/
40+
.coverage
41+
.coverage.*
42+
.cache
43+
nosetests.xml
44+
coverage.xml
45+
*,cover
46+
.hypothesis/
47+
48+
# Translations
49+
*.mo
50+
*.pot
51+
52+
# Django stuff:
53+
*.log
54+
local_settings.py
55+
56+
# Flask instance folder
57+
instance/
58+
59+
# Scrapy stuff:
60+
.scrapy
61+
62+
# Sphinx documentation
63+
docs/_build/
64+
65+
# PyBuilder
66+
target/
67+
68+
# IPython Notebook
69+
.ipynb_checkpoints
70+
71+
# pyenv
72+
.python-version
73+
74+
# celery beat schedule file
75+
celerybeat-schedule
76+
77+
# dotenv
78+
.env
79+
80+
# Spyder project settings
81+
.spyderproject
82+
83+
site-packages/
84+
lambdawebhook.zip

lambdawebhook/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# -*- coding: utf-8 -*-

lambdawebhook/hook.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
#!/usr/bin/env python
2+
import os
3+
import sys
4+
import hashlib
5+
6+
# Add the ./site-packages directory to the path for Lambda to load our libs
7+
sys.path.append(os.path.join(os.path.dirname(__file__), 'lib'))
8+
import requests # NOQA
9+
import hmac # NOQA
10+
11+
12+
def verify_signature(secret, signature, payload):
13+
computed_hash = hmac.new(str(secret), payload, hashlib.sha1)
14+
computed_signature = '='.join(['sha1', computed_hash.hexdigest()])
15+
return hmac.compare_digest(computed_signature, str(signature))
16+
17+
18+
def lambda_handler(event, context):
19+
print 'Webhook received'
20+
print event['secret']
21+
verified = verify_signature(event['secret'],
22+
event['x_hub_signature'],
23+
event['payload'])
24+
print 'Signature verified: ' + str(verified)
25+
if verified:
26+
response = requests.post(event['jenkins_url'],
27+
headers={
28+
'X-GitHub-Delivery': event['x_github_delivery'],
29+
'X-GitHub-Event': event['x_github_event'],
30+
'X-Hub-Signature': event['x_hub_signature']
31+
},
32+
json=event['payload'])
33+
return {'status': {response.status_code: response.reason}}
34+
else:
35+
return {'status': {403: 'Forbidden'}}
36+
37+
38+
if __name__ == "__main__":
39+
pass

requirements.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
tox
2+
nose
3+
httpretty
4+
requests

setup.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
"""
2+
3+
"""
4+
from setuptools import find_packages, setup
5+
6+
dependencies = ['requests', 'httpretty']
7+
8+
setup(
9+
name='lambda-webhook',
10+
version='0.1.0',
11+
url='https://github.com/pristineio/lambda-webhook',
12+
license='MIT',
13+
author='John Schwinghammer',
14+
author_email='[email protected]',
15+
description='',
16+
long_description=__doc__,
17+
packages=find_packages(exclude=['tests']),
18+
include_package_data=True,
19+
zip_safe=False,
20+
platforms='any',
21+
install_requires=dependencies,
22+
classifiers=[
23+
# As from http://pypi.python.org/pypi?%3Aaction=list_classifiers
24+
# 'Development Status :: 1 - Planning',
25+
'Development Status :: 2 - Pre-Alpha',
26+
# 'Development Status :: 3 - Alpha',
27+
# 'Development Status :: 4 - Beta',
28+
# 'Development Status :: 5 - Production/Stable',
29+
# 'Development Status :: 6 - Mature',
30+
# 'Development Status :: 7 - Inactive',
31+
'Environment :: Console',
32+
'Intended Audience :: System Administrators',
33+
'License :: OSI Approved :: MIT License',
34+
'Operating System :: POSIX',
35+
'Operating System :: MacOS',
36+
'Operating System :: Unix',
37+
'Programming Language :: Python',
38+
'Programming Language :: Python :: 2',
39+
'Topic :: Utilities',
40+
]
41+
)

test/data/testevent.json

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"x_github_delivery": "dafdsfs",
3+
"x_github_event": "push",
4+
"x_hub_signature": "sha1=952548c8f23303f4925411b09b0c5d0c13d0cfb5",
5+
"jenkins_url": "https://localhost/github-webhook/",
6+
"secret": "testsecret",
7+
"payload": {
8+
"ref": "refs/heads/master",
9+
"created": false,
10+
"deleted": false,
11+
"forced": false,
12+
"base_ref": null
13+
}
14+
}

test/unit_test.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import unittest
2+
import lambdawebhook.hook
3+
import os
4+
import json
5+
import httpretty
6+
7+
8+
def load_test_event():
9+
mypath = os.path.dirname(os.path.abspath(__file__))
10+
with open(os.path.join(mypath, 'data/testevent.json'), 'r') as eventfile:
11+
githubevent = json.load(eventfile)
12+
githubevent['payload'] = json.dumps(githubevent['payload'])
13+
return githubevent
14+
15+
16+
githubevent = load_test_event()
17+
18+
19+
class VerifySignatureTestCase(unittest.TestCase):
20+
def runTest(self):
21+
# This signature is missing the 'sha1=' prefix and will fail validation
22+
self.assertFalse(lambdawebhook.hook.verify_signature(str(githubevent['secret']),
23+
'952548c8f23303f4925411b09b0c5d0c13d0cfb5',
24+
githubevent['payload']))
25+
# This signature should validate the payload
26+
self.assertTrue(lambdawebhook.hook.verify_signature(str(githubevent['secret']),
27+
githubevent['x_hub_signature'],
28+
githubevent['payload']))
29+
30+
31+
class LambdaHandlerTestCase(unittest.TestCase):
32+
@httpretty.activate
33+
def runTest(self):
34+
# Check return codes
35+
httpretty.register_uri(httpretty.POST, 'https://localhost/github-webhook/',
36+
status=200)
37+
self.assertEqual(lambdawebhook.hook.lambda_handler(githubevent, ''), {'status': {200: 'OK'}})
38+
39+
httpretty.register_uri(httpretty.POST, 'https://localhost/github-webhook/',
40+
status=403)
41+
self.assertEqual(lambdawebhook.hook.lambda_handler(githubevent, ''), {'status': {403: 'Forbidden'}})

tox.ini

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# Tox (http://tox.testrun.org/) is a tool for running tests
2+
# in multiple virtualenvs. This configuration file will run the
3+
# test suite on all supported python versions. To use it, "pip install tox"
4+
# and then run "tox" from this directory.
5+
6+
[tox]
7+
envlist = py27, flake8
8+
9+
[testenv]
10+
commands=nosetests
11+
setenv =
12+
PYTHONHASHSEED = 0
13+
deps=
14+
nose
15+
httpretty
16+
17+
[testenv:flake8]
18+
basepython = python2.7
19+
deps =
20+
flake8
21+
commands =
22+
flake8 lambdawebhook test --max-line-length=120

0 commit comments

Comments
 (0)