Commit 19ed1af1 authored by Tom Pillot's avatar Tom Pillot
Browse files

Test webhook

parent 98e0631e
import hashlib
import hmac
from pathlib import Path
from unittest import mock
from django.conf import settings
from django.test import TestCase
from django.urls import reverse
from django.utils.encoding import force_bytes
from rainboard.models import Project, Namespace, Forge
class GhTests(TestCase):
def post_github_event(self, event):
signature = 'sha1=' + hmac.new(force_bytes(settings.GITHUB_WEBHOOK_KEY),
digestmod=hashlib.sha1).hexdigest()
response = self.client.get(reverse('webhook'), HTTP_X_FORWARDED_FOR='140.82.112.1',
HTTP_X_HUB_SIGNATURE=signature, HTTP_X_GITHUB_EVENT=event)
return response
def test_webhook(self):
# Not from github IP
response = self.client.get(reverse('webhook'), HTTP_X_FORWARDED_FOR='5.5.5.5')
self.assertEqual(response.status_code, 302)
# No signature
response = self.client.get(reverse('webhook'), HTTP_X_FORWARDED_FOR='140.82.112.1')
self.assertEqual(response.status_code, 302)
# Signature not sha1
response = self.client.get(reverse('webhook'), HTTP_X_FORWARDED_FOR='140.82.112.1',
HTTP_X_HUB_SIGNATURE='sha256=foo')
self.assertEqual(response.status_code, 501)
# Wrong signature
response = self.client.get(reverse('webhook'), HTTP_X_FORWARDED_FOR='140.82.112.1',
HTTP_X_HUB_SIGNATURE='sha1=foo')
self.assertEqual(response.status_code, 403)
# Ping
response = self.post_github_event('ping')
self.assertEqual(response.status_code, 200)
def test_gl_webhook(self):
# Not from gitlab IP
response = self.client.get(reverse('gl-webhook'), HTTP_X_FORWARDED_FOR='5.5.5.5')
self.assertEqual(response.status_code, 302)
# No token
response = self.client.get(reverse('gl-webhook'), HTTP_X_FORWARDED_FOR='140.93.0.1')
self.assertEqual(response.status_code, 302)
# Wrong token
response = self.client.get(reverse('gl-webhook'), HTTP_X_FORWARDED_FOR='140.93.0.1',
HTTP_X_GITLAB_TOKEN='foo')
self.assertEqual(response.status_code, 403)
# Ping
response = self.client.get(reverse('gl-webhook'), HTTP_X_FORWARDED_FOR='140.93.0.1',
HTTP_X_GITLAB_TOKEN=settings.GITLAB_WEBHOOK_KEY, HTTP_X_GITLAB_EVENT='ping')
self.assertEqual(response.status_code, 200)
@mock.patch.object(Project, 'git_path')
def test_push(self, git_path):
git_path.return_value = Path('tmp')
# Create your tests here.
namespace = Namespace.objects.get_or_create(name='tpillot')
project, _ = Project.objects.get_or_create(name='example-adder',
main_namespace=Namespace.objects.get(name='tpillot'),
main_forge=Forge.objects.get(name='Gitlab'))
......@@ -5,6 +5,6 @@ from django.urls import path
from . import views
urlpatterns = [
path('webhook', views.webhook),
path('gl-webhook', views.gl_webhook),
path('webhook', views.webhook, name='webhook'),
path('gl-webhook', views.gl_webhook, name='gl-webhook'),
]
......@@ -6,11 +6,9 @@ import traceback
from hashlib import sha1
from ipaddress import ip_address, ip_network
from json import loads
from pprint import pprint
import git
import github
import requests
from autoslug.utils import slugify
from django.conf import settings
from django.core.mail import mail_admins
......@@ -211,7 +209,8 @@ def webhook(request: HttpRequest) -> HttpResponse:
"""
# validate ip source
forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR').split(', ')[0]
networks = requests.get('https://api.github.com/meta').json()['hooks']
# networks = requests.get('https://api.github.com/meta').json()['hooks'] # Fails if API rate limit exceeded
networks = ['185.199.108.0/22', '140.82.112.0/20']
if not any(ip_address(forwarded_for) in ip_network(net) for net in networks):
logger.warning('not from github IP')
return HttpResponseRedirect(reverse('login'))
......@@ -234,7 +233,6 @@ def webhook(request: HttpRequest) -> HttpResponse:
# process event
event = request.META.get('HTTP_X_GITHUB_EVENT', 'ping')
if event == 'ping':
pprint(loads(request.body.decode()))
return HttpResponse('pong')
if event == 'push':
return push(request, SOURCES.github, 'push event detected')
......@@ -264,9 +262,8 @@ def gl_webhook(request: HttpRequest) -> HttpResponse:
logger.warning('wrong token')
return HttpResponseForbidden('wrong token.')
event = request.META.get('HTTP_X_GITLAB_EVENT', 'ping')
event = request.META.get('HTTP_X_GITLAB_EVENT')
if event == 'ping':
pprint(loads(request.body.decode()))
return HttpResponse('pong')
elif event == 'Pipeline Hook':
return pipeline(request, 'pipeline event detected')
......
......@@ -26,5 +26,5 @@ class Migration(migrations.Migration):
]
operations = [
migrations.RunPython(add_robotpkg),
# migrations.RunPython(add_robotpkg),
]
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment