Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
style: more informative comments for webhook verification responses
Co-Authored-By: dgw <dgw@technobabbl.es>
- Loading branch information
Showing
2 changed files
with
154 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,145 @@ | ||
#!/usr/bin/env python | ||
|
||
from __future__ import print_function | ||
|
||
import sys | ||
|
||
import hashlib | ||
import hmac | ||
from multiprocessing import Pool | ||
import random | ||
import requests | ||
|
||
|
||
# Helper constants | ||
class YAY_COLORS: | ||
GREEN = '\033[92m' | ||
RED = '\033[91m' | ||
RESET = '\033[0m' | ||
|
||
|
||
VALID_REQUEST = '.' | ||
INVALID_REQUEST = '*' | ||
|
||
CORRECT_RESPONSE = True | ||
INCORRECT_RESPONSE = False | ||
|
||
# Test constants | ||
TEST_URL = "http://localhost:3333/webhook" # Use this for local testing | ||
# TEST_URL = "http://bot.humorbaby.net:3333/webhook" # Use this for more realistic testing; replace humorbaby.net as needed. | ||
|
||
REAL_WEBHOOK_SECRET = "asdf" # Use to make valid request | ||
FAKE_WEBHOOK_SECRET = "asdff" # Use to make invalid request | ||
|
||
PAYLOAD = """{"event": "testing", "repository": {"full_name": "testing/123"}}""" | ||
"""Fake payload won't trigger any actual bot messages, but will still be recieved and processed as normal.""" | ||
|
||
# Get correct signature | ||
hash_ = hmac.new(REAL_WEBHOOK_SECRET, msg=PAYLOAD, digestmod=hashlib.sha1) | ||
CORRECT_SIGNATURE = 'sha1=' + hash_.hexdigest() | ||
|
||
# Make incorrect signature; yes, a random string could work, but let's be consistent, ey? | ||
hash_ = hmac.new(FAKE_WEBHOOK_SECRET, msg=PAYLOAD, digestmod=hashlib.sha1) | ||
INCORRECT_SIGNATURE = 'sha1=' + hash_.hexdigest() | ||
|
||
|
||
def send_valid_request(): | ||
headers_ = { | ||
'X-Hub-Signature': CORRECT_SIGNATURE, | ||
'content-type': 'application/json', | ||
} | ||
|
||
r = requests.post(TEST_URL, data=PAYLOAD, headers=headers_) | ||
return ( | ||
VALID_REQUEST, # Request type | ||
True if r.status_code == 200 else False, # Success status | ||
(YAY_COLORS.GREEN if r.status_code == 200 else YAY_COLORS.RED) + VALID_REQUEST + YAY_COLORS.RESET, | ||
) | ||
|
||
|
||
def send_invalid_request(): | ||
headers_ = { | ||
'X-Hub-Signature': INCORRECT_SIGNATURE, | ||
'content-type': 'application/json', | ||
} | ||
|
||
r = requests.post(TEST_URL, data=PAYLOAD, headers=headers_) | ||
return ( | ||
INVALID_REQUEST, # Request type | ||
False if r.status_code == 200 else True, # Success status | ||
(YAY_COLORS.RED if r.status_code == 200 else YAY_COLORS.GREEN) + INVALID_REQUEST + YAY_COLORS.RESET | ||
) | ||
|
||
|
||
def send_random_request(random_seed): | ||
random.seed(random_seed) | ||
request_ = random.choice([send_valid_request, send_invalid_request]) | ||
return request_() | ||
|
||
|
||
class Progress: | ||
def __init__(self): | ||
self.valid_requests = { | ||
CORRECT_RESPONSE: 0, | ||
INCORRECT_RESPONSE: 0, | ||
} | ||
self.invalid_requests = self.valid_requests.copy() | ||
|
||
def callback_(self, result): | ||
(request_type, status, msg) = result | ||
{ | ||
VALID_REQUEST: self.valid_requests, | ||
INVALID_REQUEST: self.invalid_requests, | ||
}[request_type][status] += 1 | ||
|
||
print(msg, end='') | ||
sys.stdout.flush() | ||
|
||
|
||
# Main | ||
NUM_PROCS = 32 | ||
NUM_REQUESTS = 1000 | ||
|
||
RANDOM_SEED = 12345 # For reproducability of # vaild/invalid reqeusts | ||
random.seed(RANDOM_SEED) | ||
|
||
pool = Pool(NUM_PROCS) | ||
progress = Progress() | ||
|
||
results_ = [] | ||
for i in range(NUM_REQUESTS): | ||
proc_random_seed = random.randint(1, 1e10 - 1) | ||
results_.append( | ||
pool.apply_async( | ||
send_random_request, | ||
(proc_random_seed, ), | ||
callback=progress.callback_ | ||
) | ||
) | ||
|
||
try: | ||
[x.get() for x in results_] | ||
pool.close() | ||
except Exception: | ||
pool.terminate() | ||
finally: | ||
pool.join() | ||
|
||
summary = """ | ||
Valid Requests --> {} sent | ||
{:>5d} correct response(s) | ||
{:>5d} incorrect response(s) | ||
Invalid requests --> {} sent | ||
{:>5d} correct response(s) | ||
{:>5d} incorrect response(s) | ||
""".format( | ||
sum(progress.valid_requests.values()), | ||
progress.valid_requests[CORRECT_RESPONSE], | ||
progress.valid_requests[INCORRECT_RESPONSE], | ||
sum(progress.invalid_requests.values()), | ||
progress.invalid_requests[CORRECT_RESPONSE], | ||
progress.invalid_requests[INCORRECT_RESPONSE], | ||
).strip() | ||
|
||
print('\n', summary, sep='') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters