Last active
June 25, 2022 14:51
-
-
Save vitorfs/145a8b8f0865cb65ee915e0c846fc303 to your computer and use it in GitHub Desktop.
Handling GitHub Webhooks Using Django
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
import hmac | |
from hashlib import sha1 | |
from django.conf import settings | |
from django.http import HttpResponse, HttpResponseForbidden, HttpResponseServerError | |
from django.views.decorators.csrf import csrf_exempt | |
from django.views.decorators.http import require_POST | |
from django.utils.encoding import force_bytes | |
import requests | |
from ipaddress import ip_address, ip_network | |
@require_POST | |
@csrf_exempt | |
def hello(request): | |
# Verify if request came from GitHub | |
forwarded_for = u'{}'.format(request.META.get('HTTP_X_FORWARDED_FOR')) | |
client_ip_address = ip_address(forwarded_for) | |
whitelist = requests.get('https://api.github.com/meta').json()['hooks'] | |
for valid_ip in whitelist: | |
if client_ip_address in ip_network(valid_ip): | |
break | |
else: | |
return HttpResponseForbidden('Permission denied.') | |
# Verify the request signature | |
header_signature = request.META.get('HTTP_X_HUB_SIGNATURE') | |
if header_signature is None: | |
return HttpResponseForbidden('Permission denied.') | |
sha_name, signature = header_signature.split('=') | |
if sha_name != 'sha1': | |
return HttpResponseServerError('Operation not supported.', status=501) | |
mac = hmac.new(force_bytes(settings.GITHUB_WEBHOOK_KEY), msg=force_bytes(request.body), digestmod=sha1) | |
if not hmac.compare_digest(force_bytes(mac.hexdigest()), force_bytes(signature)): | |
return HttpResponseForbidden('Permission denied.') | |
# If request reached this point we are in a good shape | |
# Process the GitHub events | |
event = request.META.get('HTTP_X_GITHUB_EVENT', 'ping') | |
if event == 'ping': | |
return HttpResponse('pong') | |
elif event == 'push': | |
# Deploy some code for example | |
return HttpResponse('success') | |
# In case we receive an event that's not ping or push | |
return HttpResponse(status=204) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
oi, amigo eu preciso de integrar com typeform, dessa maneira eu posso fazer isso o que ?