-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Search: Permissioned tribal audit access (#2807)
* checkpoint * add search view tests, refactor search fn * lint * first pass * clean up is_public clause
- Loading branch information
1 parent
1b8e05a
commit 11eea7f
Showing
11 changed files
with
696 additions
and
136 deletions.
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,43 @@ | ||
import logging | ||
|
||
from django.core.exceptions import PermissionDenied | ||
from django.http import Http404 | ||
|
||
from dissemination.models import General | ||
from users.permissions import can_read_tribal | ||
|
||
|
||
logger = logging.getLogger(__name__) | ||
|
||
|
||
class ReportAccessRequiredMixin: | ||
def dispatch(self, request, *args, **kwargs): | ||
report_id = kwargs["report_id"] | ||
try: | ||
general = General.objects.get(report_id=report_id) | ||
|
||
if general.is_public: | ||
return super().dispatch(request, *args, **kwargs) | ||
|
||
if not request.user: | ||
logger.debug( | ||
f"denying anonymous user access to non-public report {report_id}" | ||
) | ||
raise PermissionDenied | ||
|
||
if not request.user.is_authenticated: | ||
logger.debug( | ||
f"denying anonymous user access to non-public report {report_id}" | ||
) | ||
raise PermissionDenied | ||
|
||
if not can_read_tribal(request.user): | ||
logger.debug( | ||
f"denying user {request.user.email} access to non-public report {report_id}" | ||
) | ||
raise PermissionDenied | ||
|
||
return super().dispatch(request, *args, **kwargs) | ||
|
||
except General.DoesNotExist: | ||
raise Http404() |
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,107 @@ | ||
from django.contrib.auth import get_user_model | ||
from django.core.exceptions import PermissionDenied | ||
from django.http.response import Http404 | ||
from django.test import TestCase | ||
from django.test.client import RequestFactory | ||
from django.views.generic import View | ||
|
||
from dissemination.models import General | ||
from dissemination.mixins import ReportAccessRequiredMixin | ||
|
||
from users.models import Permission, UserPermission | ||
|
||
from model_bakery import baker | ||
|
||
User = get_user_model() | ||
|
||
|
||
class ReportAccessRequiredMixinTests(TestCase): | ||
class ViewStub(ReportAccessRequiredMixin, View): | ||
def get(self, request, *args, **kwargs): | ||
pass | ||
|
||
def test_missing_report_id_raises(self): | ||
request = RequestFactory().get("/") | ||
|
||
self.assertRaises(KeyError, self.ViewStub().dispatch, request) | ||
|
||
def test_nonexistent_report_raises(self): | ||
request = RequestFactory().get("/") | ||
|
||
self.assertRaises( | ||
Http404, | ||
self.ViewStub().dispatch, | ||
request, | ||
report_id="not-a-real-report-id", | ||
) | ||
|
||
def test_public_report_passes(self): | ||
request = RequestFactory().get("/") | ||
|
||
general = baker.make(General, is_public=True) | ||
|
||
self.ViewStub().dispatch(request, report_id=general.report_id) | ||
|
||
def test_non_public_raises_for_anonymous(self): | ||
request = RequestFactory().get("/") | ||
request.user = None | ||
|
||
general = baker.make(General, is_public=False) | ||
|
||
self.assertRaises( | ||
PermissionDenied, | ||
self.ViewStub().dispatch, | ||
request, | ||
report_id=general.report_id, | ||
) | ||
|
||
def test_non_public_raises_for_unpermissioned(self): | ||
request = RequestFactory().get("/") | ||
|
||
user = baker.make(User) | ||
request.user = user | ||
|
||
general = baker.make(General, is_public=False) | ||
|
||
self.assertRaises( | ||
PermissionDenied, | ||
self.ViewStub().dispatch, | ||
request, | ||
report_id=general.report_id, | ||
) | ||
|
||
def test_non_public_passes_for_permissioned(self): | ||
request = RequestFactory().get("/") | ||
|
||
user = baker.make(User) | ||
request.user = user | ||
|
||
permission = Permission.objects.get(slug=Permission.PermissionType.READ_TRIBAL) | ||
baker.make(UserPermission, user=user, email=user.email, permission=permission) | ||
|
||
general = baker.make(General, is_public=False) | ||
|
||
self.ViewStub().dispatch(request, report_id=general.report_id) | ||
|
||
def test_public_passes_for_unpermissioned(self): | ||
request = RequestFactory().get("/") | ||
|
||
user = baker.make(User) | ||
request.user = user | ||
|
||
general = baker.make(General, is_public=True) | ||
|
||
self.ViewStub().dispatch(request, report_id=general.report_id) | ||
|
||
def test_public_passes_for_permissioned(self): | ||
request = RequestFactory().get("/") | ||
|
||
user = baker.make(User) | ||
request.user = user | ||
|
||
permission = Permission.objects.get(slug=Permission.PermissionType.READ_TRIBAL) | ||
baker.make(UserPermission, user=user, email=user.email, permission=permission) | ||
|
||
general = baker.make(General, is_public=True) | ||
|
||
self.ViewStub().dispatch(request, report_id=general.report_id) |
Oops, something went wrong.