-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add party document streaming endpoint
- Loading branch information
1 parent
b874f40
commit 1b8e582
Showing
6 changed files
with
188 additions
and
1 deletion.
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,8 @@ | ||
from rest_framework import permissions | ||
|
||
from api.organisations.libraries.get_organisation import get_request_user_organisation_id | ||
|
||
|
||
class IsPartyDocumentInOrganisation(permissions.BasePermission): | ||
def has_object_permission(self, request, view, obj): | ||
return obj.party.organisation_id == get_request_user_organisation_id(request) |
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,38 @@ | ||
from django.contrib.auth.models import User | ||
from django.test import RequestFactory, TestCase | ||
from rest_framework.permissions import IsAdminUser | ||
|
||
from test_helpers.clients import DataTestClient | ||
from api.core.authentication import ORGANISATION_ID | ||
from api.parties.tests.factories import PartyDocumentFactory, PartyFactory | ||
from api.organisations.tests.factories import OrganisationFactory | ||
from api.applications.permissions import IsPartyDocumentInOrganisation | ||
|
||
|
||
class IsPartyDocumentInOrganisationTest(DataTestClient): | ||
def test_permissions_success(self): | ||
organisation = OrganisationFactory() | ||
party = PartyFactory(organisation=organisation) | ||
party_document = PartyDocumentFactory(party=party, s3_key="somekey") | ||
factory = RequestFactory() | ||
|
||
request = factory.get("/") | ||
request.META[ORGANISATION_ID] = organisation.id | ||
|
||
authorised = IsPartyDocumentInOrganisation().has_object_permission(request, None, party_document) | ||
|
||
self.assertTrue(authorised) | ||
|
||
def test_permissions_failure(self): | ||
organisation = OrganisationFactory() | ||
other_organisation = OrganisationFactory() | ||
party = PartyFactory(organisation=organisation) | ||
party_document = PartyDocumentFactory(party=party, s3_key="somekey") | ||
factory = RequestFactory() | ||
|
||
request = factory.get("/") | ||
request.META[ORGANISATION_ID] = other_organisation.id | ||
|
||
authorised = IsPartyDocumentInOrganisation().has_object_permission(request, None, party_document) | ||
|
||
self.assertFalse(authorised) |
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
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
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,114 @@ | ||
from moto import mock_aws | ||
from parameterized import parameterized | ||
|
||
from django.http import FileResponse | ||
from django.urls import reverse | ||
from rest_framework import status | ||
|
||
from api.applications.tests.factories import PartyOnApplicationFactory, StandardApplicationFactory | ||
from api.parties.tests.factories import PartyFactory, PartyDocumentFactory | ||
from test_helpers.clients import DataTestClient | ||
|
||
|
||
@mock_aws | ||
class PartyDocumentStreamTests(DataTestClient): | ||
def setUp(self): | ||
super().setUp() | ||
self.party = PartyFactory( | ||
organisation=self.organisation, | ||
) | ||
self.party_on_application = PartyOnApplicationFactory(party=self.party) | ||
self.application = self.party_on_application.application | ||
self.create_default_bucket() | ||
self.put_object_in_default_bucket("thisisakey", b"test") | ||
|
||
def test_get_party_document_stream(self): | ||
party_document = PartyDocumentFactory( | ||
party=self.party, | ||
s3_key="thisisakey", | ||
name="doc1.pdf", | ||
safe=True, | ||
) | ||
|
||
url = reverse( | ||
"applications:party_document_stream", | ||
kwargs={ | ||
"pk": str(self.application.pk), | ||
"party_pk": str(self.party.pk), | ||
"document_pk": str(party_document.pk), | ||
}, | ||
) | ||
response = self.client.get(url, **self.exporter_headers) | ||
|
||
self.assertEqual(response.status_code, status.HTTP_200_OK) | ||
self.assertIsInstance(response, FileResponse) | ||
self.assertEqual(b"".join(response.streaming_content), b"test") | ||
|
||
def test_get_party_document_stream_invalid_document_pk(self): | ||
another_party = PartyFactory( | ||
organisation=self.organisation, | ||
) | ||
party_document = PartyDocumentFactory( | ||
party=self.party, | ||
s3_key="thisisakey", | ||
name="doc1.pdf", | ||
safe=True, | ||
) | ||
|
||
url = reverse( | ||
"applications:party_document_stream", | ||
kwargs={ | ||
"pk": str(self.application.pk), | ||
"party_pk": str(another_party.pk), | ||
"document_pk": str(party_document.pk), | ||
}, | ||
) | ||
response = self.client.get(url, **self.exporter_headers) | ||
|
||
self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) | ||
|
||
def test_get_party_document_stream_invalid_application_pk(self): | ||
another_application = StandardApplicationFactory() | ||
party_document = PartyDocumentFactory( | ||
party=self.party, | ||
s3_key="thisisakey", | ||
name="doc1.pdf", | ||
safe=True, | ||
) | ||
|
||
url = reverse( | ||
"applications:party_document_stream", | ||
kwargs={ | ||
"pk": str(another_application.pk), | ||
"party_pk": str(self.party.pk), | ||
"document_pk": str(party_document.pk), | ||
}, | ||
) | ||
response = self.client.get(url, **self.exporter_headers) | ||
|
||
self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) | ||
|
||
def test_get_party_document_stream_forbidden_organisation(self): | ||
other_organisation = self.create_organisation_with_exporter_user()[0] | ||
self.party.organisation = other_organisation | ||
self.party.save() | ||
self.application.organisation = other_organisation | ||
self.application.save() | ||
party_document = PartyDocumentFactory( | ||
party=self.party, | ||
s3_key="thisisakey", | ||
name="doc1.pdf", | ||
safe=True, | ||
) | ||
|
||
url = reverse( | ||
"applications:party_document_stream", | ||
kwargs={ | ||
"pk": str(self.application.pk), | ||
"party_pk": str(self.party.pk), | ||
"document_pk": str(party_document.pk), | ||
}, | ||
) | ||
response = self.client.get(url, **self.exporter_headers) | ||
|
||
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) |
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