Skip to content

Commit

Permalink
clean up the permissions checking for the answer view
Browse files Browse the repository at this point in the history
move common things in to the base view.
refactor the right of reply checking to be clearer
  • Loading branch information
struan committed Apr 30, 2024
1 parent 27adc39 commit 453feb6
Show file tree
Hide file tree
Showing 7 changed files with 238 additions and 55 deletions.
53 changes: 52 additions & 1 deletion crowdsourcer/tests/test_audit_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,14 @@
from django.test import TestCase
from django.urls import reverse

from crowdsourcer.models import Assigned, Marker, Question, Response, ResponseType
from crowdsourcer.models import (
Assigned,
Marker,
MarkingSession,
Question,
Response,
ResponseType,
)


class BaseTestCase(TestCase):
Expand Down Expand Up @@ -157,6 +164,50 @@ def test_permissions(self):
response = self.client.get(url)
self.assertEqual(response.status_code, 403)

def test_no_access_if_wrong_stage_assigned(self):
url = reverse("authority_audit", args=("Aberdeenshire Council", "Transport"))
response = self.client.get(url)
self.assertEqual(response.status_code, 200)

# delete this to avoid duplicate error
Assigned.objects.filter(response_type__type="First Mark").delete()
a = Assigned.objects.get(
user=self.user,
response_type=ResponseType.objects.get(type="Audit"),
section__title="Transport",
authority__name="Aberdeenshire Council",
)
a.response_type = ResponseType.objects.get(type="First Mark")
a.save()

response = self.client.get(url)
self.assertEqual(response.status_code, 403)

def test_no_access_if_wrong_session(self):
url = reverse("authority_audit", args=("Aberdeenshire Council", "Transport"))
response = self.client.get(url)
self.assertEqual(response.status_code, 200)

session = MarkingSession.objects.get(label="Second Session")
a = Assigned.objects.get(
user=self.user,
response_type=ResponseType.objects.get(type="Audit"),
section__title="Transport",
authority__name="Aberdeenshire Council",
)
a.marking_session = session
a.save()

response = self.client.get(url)
self.assertEqual(response.status_code, 403)

session = MarkingSession.objects.get(label="Default")
a.marking_session = session
a.save()

response = self.client.get(url)
self.assertEqual(response.status_code, 200)

def test_save(self):
url = reverse("authority_audit", args=("Aberdeenshire Council", "Transport"))
response = self.client.get(url)
Expand Down
93 changes: 92 additions & 1 deletion crowdsourcer/tests/test_right_of_reply_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,13 @@
from django.test import TestCase
from django.urls import reverse

from crowdsourcer.models import Assigned, MarkingSession, PublicAuthority, Response
from crowdsourcer.models import (
Assigned,
MarkingSession,
PublicAuthority,
Response,
ResponseType,
)


class BaseTestCase(TestCase):
Expand Down Expand Up @@ -97,16 +103,19 @@ def setUp(self):
u.marker.save()

auth2 = PublicAuthority.objects.get(name="Aberdeen City Council")
rt = ResponseType.objects.get(type="Right of Reply")

Assigned.objects.create(
marking_session=MarkingSession.objects.get(label="Default"),
user=u,
authority=auth1,
response_type=rt,
)
Assigned.objects.create(
marking_session=MarkingSession.objects.get(label="Default"),
user=u,
authority=auth2,
response_type=rt,
)

def test_homepage_redirect(self):
Expand Down Expand Up @@ -168,6 +177,88 @@ def test_no_access_unless_from_council(self):
response = self.client.get(url)
self.assertEqual(response.status_code, 200)

def test_no_access_if_wrong_stage_single_council(self):
url = reverse("authority_ror", args=("Aberdeenshire Council", "Transport"))
response = self.client.get(url)
self.assertEqual(response.status_code, 200)

rt = ResponseType.objects.get(type="Audit")
m = self.user.marker
m.response_type = rt
m.save()

response = self.client.get(url)
self.assertEqual(response.status_code, 403)

def test_no_access_if_wrong_stage_multi_council(self):
auth2 = PublicAuthority.objects.get(name="Aberdeen City Council")

a = Assigned.objects.create(
marking_session=MarkingSession.objects.get(label="Default"),
response_type=ResponseType.objects.get(type="Right of Reply"),
user=self.user,
authority=auth2,
)

url = reverse("authority_ror", args=("Aberdeen City Council", "Transport"))
response = self.client.get(url)
self.assertEqual(response.status_code, 200)

rt = ResponseType.objects.get(type="Audit")
a.response_type = rt
a.save()

response = self.client.get(url)
self.assertEqual(response.status_code, 403)

def test_no_access_if_wrong_marking_session_single_council(self):
url = reverse("authority_ror", args=("Aberdeenshire Council", "Transport"))
response = self.client.get(url)
self.assertEqual(response.status_code, 200)

session = MarkingSession.objects.get(label="Second Session")
m = self.user.marker
m.marking_session.clear()
m.marking_session.add(session)

response = self.client.get(url)
self.assertEqual(response.status_code, 403)

session = MarkingSession.objects.get(label="Default")
m.marking_session.clear()
m.marking_session.add(session)

response = self.client.get(url)
self.assertEqual(response.status_code, 200)

def test_no_access_if_wrong_marking_session_multi_council(self):
auth2 = PublicAuthority.objects.get(name="Aberdeen City Council")

a = Assigned.objects.create(
marking_session=MarkingSession.objects.get(label="Default"),
response_type=ResponseType.objects.get(type="Right of Reply"),
user=self.user,
authority=auth2,
)

url = reverse("authority_ror", args=("Aberdeen City Council", "Transport"))
response = self.client.get(url)
self.assertEqual(response.status_code, 200)

session = MarkingSession.objects.get(label="Second Session")
a.marking_session = session
a.save()

response = self.client.get(url)
self.assertEqual(response.status_code, 403)

session = MarkingSession.objects.get(label="Default")
a.marking_session = session
a.save()

response = self.client.get(url)
self.assertEqual(response.status_code, 200)

def test_display_option(self):
response = Response.objects.get(
authority_id=2,
Expand Down
43 changes: 43 additions & 0 deletions crowdsourcer/tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,7 @@ def test_no_access_unless_assigned(self):
user=self.user,
section=Section.objects.get(title="Biodiversity"),
authority=PublicAuthority.objects.get(name="Aberdeenshire Council"),
response_type=ResponseType.objects.get(type="First Mark"),
)

response = self.client.get(url)
Expand All @@ -255,6 +256,48 @@ def test_no_access_unless_assigned(self):
response = self.client.get(url)
self.assertEqual(response.status_code, 403)

def test_no_access_if_wrong_stage_assigned(self):
url = reverse(
"authority_question_edit", args=("Aberdeenshire Council", "Biodiversity")
)

Assigned.objects.create(
marking_session=MarkingSession.objects.get(label="Default"),
user=self.user,
response_type=ResponseType.objects.get(type="Audit"),
section=Section.objects.get(title="Biodiversity"),
authority=PublicAuthority.objects.get(name="Aberdeenshire Council"),
)

response = self.client.get(url)
self.assertEqual(response.status_code, 403)

def test_no_access_if_wrong_session(self):
url = reverse(
"authority_question_edit", args=("Aberdeenshire Council", "Biodiversity")
)
response = self.client.get(url)

session = MarkingSession.objects.get(label="Second Session")

a = Assigned.objects.create(
marking_session=session,
user=self.user,
section=Section.objects.get(title="Biodiversity"),
authority=PublicAuthority.objects.get(name="Aberdeenshire Council"),
response_type=ResponseType.objects.get(type="First Mark"),
)

response = self.client.get(url)
self.assertEqual(response.status_code, 403)

session = MarkingSession.objects.get(label="Default")
a.marking_session = session
a.save()

response = self.client.get(url)
self.assertEqual(response.status_code, 200)

def test_save(self):
url = reverse(
"authority_question_edit", args=("Aberdeenshire Council", "Transport")
Expand Down
32 changes: 9 additions & 23 deletions crowdsourcer/views/audit.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
import logging

from django.core.exceptions import PermissionDenied

from crowdsourcer.forms import AuditResponseFormset
from crowdsourcer.models import Assigned, Response, ResponseType
from crowdsourcer.models import Response, ResponseType
from crowdsourcer.views.base import BaseQuestionView, BaseSectionAuthorityList

logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -54,28 +52,16 @@ def get_initial_obj(self):

return initial

def check_permissions(self):
if self.request.user.is_anonymous:
raise PermissionDenied
def check_local_permissions(self):
permitted = False

rt = ResponseType.objects.get(type=self.response_type)
user = self.request.user
if user.has_perm("crowdsourcer.can_view_all_responses") is False:
if hasattr(user, "marker"):
marker = user.marker
if marker.response_type.type == "Audit":
if not Assigned.is_user_assigned(
user=user,
authority=self.kwargs["name"],
section=self.kwargs["section_title"],
current_stage=rt,
):
raise PermissionDenied
else:
raise PermissionDenied

else:
raise PermissionDenied
if user.has_perm("crowdsourcer.can_view_all_responses"):
permitted = True
elif hasattr(user, "marker") and user.marker.response_type.type == "Audit":
permitted = True

return permitted

def process_form(self, form):
cleaned_data = form.cleaned_data
Expand Down
20 changes: 20 additions & 0 deletions crowdsourcer/views/base.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import logging

from django.contrib.auth.mixins import UserPassesTestMixin
from django.core.exceptions import PermissionDenied
from django.db.models import Count, F, FloatField, OuterRef, Subquery
from django.db.models.functions import Cast
from django.views.generic import ListView, TemplateView
Expand Down Expand Up @@ -34,6 +35,25 @@ def setup(self, request, *args, **kwargs):
except ResponseType.DoesNotExist:
self.rt = None

def check_local_permissions(self):
return True

def check_permissions(self):
if self.request.user.is_anonymous:
raise PermissionDenied

if self.check_local_permissions() is False:
raise PermissionDenied

if not Assigned.is_user_assigned(
self.request.user,
authority=self.kwargs["name"],
section=self.kwargs["section_title"],
marking_session=self.current_session,
current_stage=self.rt,
):
raise PermissionDenied

def get_initial_obj(self):
self.authority = PublicAuthority.objects.get(name=self.kwargs["name"])
self.questions = Question.objects.filter(
Expand Down
12 changes: 0 additions & 12 deletions crowdsourcer/views/marking.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import logging

from django.core.exceptions import PermissionDenied
from django.shortcuts import redirect
from django.urls import reverse
from django.views.generic import ListView, TemplateView
Expand Down Expand Up @@ -204,17 +203,6 @@ class SectionAuthorityList(BaseSectionAuthorityList):
class AuthoritySectionQuestions(BaseQuestionView):
template_name = "crowdsourcer/authority_questions.html"

def check_permissions(self):
if self.request.user.is_anonymous:
raise PermissionDenied

if not Assigned.is_user_assigned(
self.request.user,
authority=self.kwargs["name"],
section=self.kwargs["section_title"],
):
raise PermissionDenied

def get_initial_obj(self):
if self.kwargs["name"] == "Isles of Scilly":
self.how_marked_in = [
Expand Down
Loading

0 comments on commit 453feb6

Please sign in to comment.