From 0985e569408df64fcdcc5419cb4bd81aeaba722b Mon Sep 17 00:00:00 2001 From: Kent Brockman Date: Mon, 4 Jul 2022 20:43:06 -0600 Subject: [PATCH 1/2] implement registration API tests add some comments --- apiserver/apiserver/api/test_api.py | 46 ++++++++++++++++++++++++++++ apiserver/apiserver/api/throttles.py | 5 ++- apiserver/apiserver/api/utils.py | 3 ++ 3 files changed, 53 insertions(+), 1 deletion(-) create mode 100644 apiserver/apiserver/api/test_api.py diff --git a/apiserver/apiserver/api/test_api.py b/apiserver/apiserver/api/test_api.py new file mode 100644 index 0000000..7fa14ea --- /dev/null +++ b/apiserver/apiserver/api/test_api.py @@ -0,0 +1,46 @@ +from django.urls import reverse +from rest_framework import status +from rest_framework.test import APITestCase +from apiserver.api.models import Member, User +import json + +class RegistrationTests(APITestCase): + def setUp(self): + self.url = reverse('rest_name_register') + # TODO: expose data to be used for E2E testing from a webclient + self.data = { + "username": "registrationtc", + "email": "unittest@email.com", + "password1": "unittest", + "password2": "unittest", + "first_name": "John", + "last_name": "Doe", + + # need to fake this for updating progress + "request_id": "lol" + } + # TODO: match with config + self.allowed_ip = '24.66.110.96' + + def test_success(self): + """Ensure we can create a new account object.""" + response = self.client.post( + self.url, + self.data, + format='json', + HTTP_X_REAL_IP=self.allowed_ip + ) + self.assertEqual(response.status_code, status.HTTP_201_CREATED) + user = User.objects.get(username=self.data['username']) + assert user is not None + assert Member.objects.get(user=user) is not None + + def test_allowed_ip_wrong(self): + """Ensure creation only allowed when HTTP_X_REAL_IP header matched IP in whitelist""" + response = self.client.post( + self.url, + self.data, + format='json', + HTTP_X_REAL_IP="0.0.0.0" + ) + self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) diff --git a/apiserver/apiserver/api/throttles.py b/apiserver/apiserver/api/throttles.py index c2d0b4f..e2aeb57 100644 --- a/apiserver/apiserver/api/throttles.py +++ b/apiserver/apiserver/api/throttles.py @@ -26,7 +26,10 @@ class LoggingThrottle(throttling.BaseThrottle): return True if request.data: - data = request.data.dict() + if type(request.data) is not dict: + data = request.data.dict() + else: + data = request.data for key in ['password', 'password1', 'password2', 'old_password', 'new_password1', 'new_password2']: if key in data: data[key] = '[CENSORED]' diff --git a/apiserver/apiserver/api/utils.py b/apiserver/apiserver/api/utils.py index 87605d7..deffe25 100644 --- a/apiserver/apiserver/api/utils.py +++ b/apiserver/apiserver/api/utils.py @@ -294,6 +294,7 @@ clean = Cleaner(tags=ALLOWED_TAGS).clean def is_request_from_protospace(request): + # TODO: pull to config whitelist = ['24.66.110.96', '205.233.15.76', '205.233.15.69'] if settings.DEBUG: @@ -346,6 +347,8 @@ def register_user(data, user): data['first_name'] = data['first_name'].title().strip() data['last_name'] = data['last_name'].title().strip() + # Sometimes during demos, a user makes a fake account then then has to be cleaned out + # Notify me that this has happened so I can go clean out the database if 'test' in data['username']: msg = 'Someone created a test account: {} {} {} {}'.format( data['username'], From c8422e9ba56fc379d32e300985a448814ed36d64 Mon Sep 17 00:00:00 2001 From: Kent Brockman Date: Mon, 4 Jul 2022 20:55:53 -0600 Subject: [PATCH 2/2] add unhappy day registration test cases --- apiserver/apiserver/api/test_api.py | 27 ++++++++++++++++++++++----- apiserver/requirements.txt | 1 + 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/apiserver/apiserver/api/test_api.py b/apiserver/apiserver/api/test_api.py index 7fa14ea..e1e807d 100644 --- a/apiserver/apiserver/api/test_api.py +++ b/apiserver/apiserver/api/test_api.py @@ -3,12 +3,9 @@ from rest_framework import status from rest_framework.test import APITestCase from apiserver.api.models import Member, User import json +from parameterized import parameterized -class RegistrationTests(APITestCase): - def setUp(self): - self.url = reverse('rest_name_register') - # TODO: expose data to be used for E2E testing from a webclient - self.data = { +data = { "username": "registrationtc", "email": "unittest@email.com", "password1": "unittest", @@ -19,6 +16,13 @@ class RegistrationTests(APITestCase): # need to fake this for updating progress "request_id": "lol" } + + +class RegistrationTests(APITestCase): + def setUp(self): + self.url = reverse('rest_name_register') + # TODO: expose data to be used for E2E testing from a webclient + self.data = data # TODO: match with config self.allowed_ip = '24.66.110.96' @@ -44,3 +48,16 @@ class RegistrationTests(APITestCase): HTTP_X_REAL_IP="0.0.0.0" ) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) + + @parameterized.expand([(f"{key} is missing", key, status.HTTP_400_BAD_REQUEST) for key in data.keys() if key is not 'request_id']) + def test_malformed_data(self, name, inp, expected): + """Delete specific properties from data and confirm it is not accepted by API""" + copy = self.data.copy() + del copy[inp] + response = self.client.post( + self.url, + copy, + format='json', + HTTP_X_REAL_IP=self.allowed_ip + ) + self.assertEqual(response.status_code, expected) diff --git a/apiserver/requirements.txt b/apiserver/requirements.txt index 48433e7..69a3d99 100644 --- a/apiserver/requirements.txt +++ b/apiserver/requirements.txt @@ -31,6 +31,7 @@ MarkupSafe==1.1.1 matplotlib-inline==0.1.3 oauthlib==3.1.0 packaging==20.0 +parameterized==0.8.1 parso==0.8.3 pexpect==4.8.0 pickleshare==0.7.5