diff --git a/.build.yml b/.build.yml new file mode 100644 index 0000000..0061d73 --- /dev/null +++ b/.build.yml @@ -0,0 +1,17 @@ +kind: pipeline +type: docker +name: default + +image: +tasks: + - +steps: +- name: backend + image: python:alpine + commands: + - cd backend + - apk add --no-cache gcc musl-dev python3-dev + - pip install --upgrade pip && pip install -r requirements.txt + - python3 configure.py + - coverage run manage.py test + - coverage report diff --git a/backend/.coveragerc b/backend/.coveragerc new file mode 100644 index 0000000..9cd1bb2 --- /dev/null +++ b/backend/.coveragerc @@ -0,0 +1,14 @@ +[run] +source = . + +[report] +fail_under = 100 +show_missing = True +skip_covered = True +omit = + */tests/* + backend/asgi.py + backend/wsgi.py + backend/settings.py + manage.py + configure.py \ No newline at end of file diff --git a/backend/authentication/tests/test_auth.py b/backend/authentication/tests/test_auth.py index 1f01c1d..e1da5b5 100644 --- a/backend/authentication/tests/test_auth.py +++ b/backend/authentication/tests/test_auth.py @@ -1,4 +1,6 @@ -from django.test import TestCase, Client +import json + +from django.test import TestCase, Client, RequestFactory from nacl.encoding import HexEncoder from nacl.signing import SigningKey @@ -7,6 +9,85 @@ from authentication.tests import UserTestCase, SignatureAuthClient from hostadmin.models import Domain +class AuthorizationTestCase(TestCase): + + def setUp(self): + self.client = Client() + self.factory = RequestFactory() + from nacl.signing import SigningKey + self.key = SigningKey.generate() + self.signature = self.key.sign("test".encode('utf-8'), encoder=HexEncoder).signature.decode('utf-8') + self.data = json.dumps({'a': 'b'}) + self.signature_with_data = self.key.sign( + ("test" + self.data).encode('utf-8'), encoder=HexEncoder).signature.decode('utf-8') + + def test_parse_auth_header(self): + request = self.factory.get('/test') + from authentication.signature_auth import verify_request + with self.assertRaises(ValueError): + verify_request(request, "") + + def test_parse_auth_header2(self): + request = self.factory.get('/test', HTTP_AUTHORIZATION="Signature ") + from authentication.signature_auth import verify_request + with self.assertRaises(ValueError): + verify_request(request, "") + + def test_parse_auth_header3(self): + request = self.factory.get('/test', HTTP_AUTHORIZATION="Signature author@domain") + from authentication.signature_auth import verify_request + with self.assertRaises(ValueError): + verify_request(request, "") + + def test_parse_auth_header4(self): + from authentication.signature_auth import verify_request + request = self.factory.get('/test', HTTP_AUTHORIZATION="Signature author@domain:" + self.signature) + username, domain, signed_data, signature_bytes_hex = verify_request(request, "") + self.assertEqual(username, "author") + self.assertEqual(domain, "domain") + self.assertEqual(signed_data, "http://testserver/test") + self.assertEqual(signature_bytes_hex, self.signature) + + def test_parse_auth_header5(self): + from authentication.signature_auth import verify_request + request = self.factory.post('/test', self.data, content_type="application/json", + HTTP_AUTHORIZATION="Signature author@domain:" + self.signature_with_data) + username, domain, signed_data, signature_bytes_hex = verify_request(request, request.body.decode('utf-8')) + self.assertEqual(username, "author") + self.assertEqual(domain, "domain") + self.assertEqual(signed_data, "http://testserver/test" + self.data) + self.assertEqual(signature_bytes_hex, self.signature_with_data) + + def test_parse_auth_header6(self): + from authentication.signature_auth import verify_request + request = self.factory.put('/test', self.data, content_type="application/json", + HTTP_AUTHORIZATION="Signature author@domain:" + self.signature_with_data) + username, domain, signed_data, signature_bytes_hex = verify_request(request, request.body.decode('utf-8')) + self.assertEqual(username, "author") + self.assertEqual(domain, "domain") + self.assertEqual(signed_data, "http://testserver/test" + self.data) + self.assertEqual(signature_bytes_hex, self.signature_with_data) + + def test_parse_auth_header7(self): + from authentication.signature_auth import verify_request + request = self.factory.delete('/test', HTTP_AUTHORIZATION="Signature author@domain:" + self.signature) + username, domain, signed_data, signature_bytes_hex = verify_request(request, request.body.decode('utf-8')) + self.assertEqual(username, "author") + self.assertEqual(domain, "domain") + self.assertEqual(signed_data, "http://testserver/test") + self.assertEqual(signature_bytes_hex, self.signature) + + def test_parse_auth_header8(self): + from authentication.signature_auth import verify_request + request = self.factory.patch('/test', self.data, content_type="application/json", + HTTP_AUTHORIZATION="Signature author@domain:" + self.signature_with_data) + username, domain, signed_data, signature_bytes_hex = verify_request(request, request.body.decode('utf-8')) + self.assertEqual(username, "author") + self.assertEqual(domain, "domain") + self.assertEqual(signed_data, "http://testserver/test" + self.data) + self.assertEqual(signature_bytes_hex, self.signature_with_data) + + class KnownIdentityTestCase(TestCase): key = None diff --git a/backend/requirements.txt b/backend/requirements.txt index e6c7131..1b2aed0 100644 --- a/backend/requirements.txt +++ b/backend/requirements.txt @@ -4,6 +4,7 @@ cffi==1.15.1 charset-normalizer==3.1.0 coreapi==2.3.3 coreschema==0.0.4 +coverage==7.2.7 Django==4.2.2 django-annoying==0.10.6 django-cors-headers==4.1.0