mirror of
https://github.com/khornberg/octokit.py
synced 2026-05-18 20:09:06 +03:00
Enhancement: Option to return app id from webhook
This commit is contained in:
@@ -0,0 +1,47 @@
|
||||
import hashlib
|
||||
import hmac
|
||||
import json
|
||||
from uuid import UUID
|
||||
|
||||
from octokit import utils
|
||||
|
||||
|
||||
def valid_signature(headers, payload, secret):
|
||||
encoding = 'utf-8'
|
||||
algo, sig = headers.get('X-Hub-Signature').split('=')
|
||||
digest = hmac.new(secret.encode(encoding), json.dumps(payload).encode(encoding), getattr(hashlib, algo)).hexdigest()
|
||||
return hmac.compare_digest(sig.encode(encoding), digest.encode(encoding))
|
||||
|
||||
|
||||
def valid_guid(guid):
|
||||
try:
|
||||
return str(UUID(guid)) == guid
|
||||
except ValueError:
|
||||
return False
|
||||
|
||||
|
||||
def valid_event(event, events):
|
||||
return event in utils.get_json_data('events.json') and (event in events or '*' in events)
|
||||
|
||||
|
||||
def valid_user_agent(ua):
|
||||
return ua.startswith('GitHub-Hookshot/')
|
||||
|
||||
|
||||
def valid_headers(headers, events, verify_user_agent):
|
||||
if not valid_guid(headers.get('X-GitHub-Delivery')):
|
||||
return False
|
||||
if not valid_event(headers.get('X-GitHub-Event'), events):
|
||||
return False
|
||||
if verify_user_agent and not valid_user_agent(headers.get('User-Agent', '')):
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def verify(headers, payload, secret, events=[], verify_user_agent=False, return_app_id=False):
|
||||
if not valid_headers(headers, events, verify_user_agent):
|
||||
return False
|
||||
validity = valid_signature(headers, payload, secret)
|
||||
if validity and return_app_id and headers.get('X-GitHub-Event') == 'ping':
|
||||
return payload.get('hook').get('app_id')
|
||||
return validity
|
||||
@@ -1,41 +0,0 @@
|
||||
import hashlib
|
||||
import hmac
|
||||
import json
|
||||
from uuid import UUID
|
||||
|
||||
from octokit import utils
|
||||
|
||||
|
||||
def _compare(headers, payload, secret):
|
||||
encoding = 'utf-8'
|
||||
algo, sig = headers.get('X-Hub-Signature').split('=')
|
||||
digest = hmac.new(secret.encode(encoding), json.dumps(payload).encode(encoding), getattr(hashlib, algo)).hexdigest()
|
||||
return hmac.compare_digest(sig.encode(encoding), digest.encode(encoding))
|
||||
|
||||
|
||||
def invalid_guid(guid):
|
||||
try:
|
||||
return str(UUID(guid)) != guid
|
||||
except ValueError:
|
||||
return True
|
||||
|
||||
|
||||
def invalid_event(event, events):
|
||||
if event not in utils.get_json_data('events.json'):
|
||||
return True
|
||||
if event not in events and '*' not in events:
|
||||
return True
|
||||
|
||||
|
||||
def valid_user_agent(ua):
|
||||
return ua.startswith('GitHub-Hookshot/')
|
||||
|
||||
|
||||
def verify(headers, payload, secret, events=[], verify_user_agent=False):
|
||||
if invalid_guid(headers.get('X-GitHub-Delivery')):
|
||||
return False
|
||||
if invalid_event(headers.get('X-GitHub-Event'), events):
|
||||
return False
|
||||
if verify_user_agent and not valid_user_agent(headers.get('User-Agent', '')):
|
||||
return False
|
||||
return _compare(headers, payload, secret)
|
||||
@@ -89,3 +89,33 @@ class TestWebhook(object):
|
||||
secret = 'secret'
|
||||
events = ['push']
|
||||
assert webhook.verify(headers, payload, secret, events=events, verify_user_agent=True) is False
|
||||
|
||||
def test_verify_ping_event(self):
|
||||
headers = {
|
||||
'X-Hub-Signature': 'sha1=02ad50e35622a4cf597de5fb86f4d59520f5adda',
|
||||
'X-GitHub-Event': 'ping',
|
||||
'X-GitHub-Delivery': '72d3162f-cc78-11e3-81ab-4c9367dc0958',
|
||||
'User-Agent': 'GitHub-Hookshot/',
|
||||
}
|
||||
payload = {
|
||||
'hook': {
|
||||
'type': 'App',
|
||||
'id': 11,
|
||||
'active': True,
|
||||
'events': ['pull_request'],
|
||||
'app_id': 42,
|
||||
}
|
||||
}
|
||||
secret = 'secret'
|
||||
assert webhook.verify(headers, payload, secret, events=['*'], return_app_id=True) == 42
|
||||
|
||||
def test_can_request_app_id_be_returned_on_non_ping_events(self):
|
||||
headers = {
|
||||
'X-Hub-Signature': 'sha1=5d61605c3feea9799210ddcb71307d4ba264225f',
|
||||
'X-GitHub-Event': 'push',
|
||||
'X-GitHub-Delivery': '72d3162f-cc78-11e3-81ab-4c9367dc0958',
|
||||
'User-Agent': 'GitHub-Hookshot/',
|
||||
}
|
||||
payload = {}
|
||||
secret = 'secret'
|
||||
assert webhook.verify(headers, payload, secret, events=['*'], return_app_id=True)
|
||||
|
||||
Reference in New Issue
Block a user