From 4d8d6b2a062a14603b1d36c09fee2c288af91ca6 Mon Sep 17 00:00:00 2001 From: Ross Date: Sat, 7 Sep 2024 11:03:44 +0100 Subject: [PATCH] fix question edit permissions --- anatomy/views.py | 2 +- generic/views.py | 15 ++++++++- longs/tests/test_longs_question.py | 49 ++++++++++++++++++++++++++++++ longs/views.py | 2 +- rad/tests/test_questions.py | 6 ++++ rapids/views.py | 2 +- sbas/views.py | 2 +- 7 files changed, 73 insertions(+), 5 deletions(-) create mode 100644 longs/tests/test_longs_question.py create mode 100644 rad/tests/test_questions.py diff --git a/anatomy/views.py b/anatomy/views.py index c15ab7ec..4450e5be 100644 --- a/anatomy/views.py +++ b/anatomy/views.py @@ -598,7 +598,7 @@ class AnatomyQuestionAnswerUpdate(RevisionMixin, AuthorOrCheckerRequiredMixin, U return super().form_invalid(form) # class AnatomyQuestionUpdate(LoginRequiredMixin, AuthorOrCheckerRequiredMixin, -class AnatomyQuestionUpdate(UpdateQuestionMixin,AuthorOrCheckerRequiredMixin): +class AnatomyQuestionUpdate(UpdateQuestionMixin): model = AnatomyQuestion form_class = AnatomyQuestionForm diff --git a/generic/views.py b/generic/views.py index 32c42700..ce4f8493 100644 --- a/generic/views.py +++ b/generic/views.py @@ -3625,9 +3625,22 @@ class UpdateQuestionMixin(RedirectMixin, RevisionMixin, UpdateView): def get_form_kwargs(self): kwargs = super().get_form_kwargs() kwargs.update({"user": self.request.user}) + return kwargs def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) context["question"] = context["object"] - return context + + # Do permission checks here + + obj = context["object"] + if ( + self.request.user.groups.filter(name="long_checker").exists() + or self.request.user.is_superuser + ): + return context + if self.request.user in obj.get_author_objects(): + return context + raise PermissionDenied() # or Http404 + diff --git a/longs/tests/test_longs_question.py b/longs/tests/test_longs_question.py new file mode 100644 index 00000000..143425ca --- /dev/null +++ b/longs/tests/test_longs_question.py @@ -0,0 +1,49 @@ + +from django.urls import reverse +import pytest + +from longs.models import Long + + +def create_question(): + return Long.objects.create( + description="Test Question", + ) + +def create_user(db, django_user_model): + return django_user_model.objects.create_user( + "user1", "user1@user.com", "password" + ) + +@pytest.mark.django_db +def test_question_creation(client, db, django_user_model): + question = create_question() + assert question.description == "Test Question" + assert question.get_absolute_url() == f"/longs/question/{question.pk}/" + + # Test access + user = create_user(db, django_user_model) + client.force_login(user) + + # View access + response = client.get(reverse("longs:question_detail", kwargs={"pk": question.pk}), follow=True) + assert response.status_code == 403 + + response = client.get(reverse("longs:long_update", kwargs={"pk": question.pk}), follow=True) + assert response.status_code == 403 + + + # Add author + question.add_author(user) + + # Test author access + response = client.get(reverse("longs:question_detail", kwargs={"pk": question.pk}), follow=True) + assert response.status_code == 200 + + response = client.get(reverse("longs:long_update", kwargs={"pk": question.pk}), follow=True) + assert response.status_code == 200 + + + + + diff --git a/longs/views.py b/longs/views.py index 6faad123..73064f1d 100755 --- a/longs/views.py +++ b/longs/views.py @@ -506,7 +506,7 @@ class LongCreate(LongCreateBase): class LongUpdate( - UpdateQuestionMixin,AuthorOrCheckerRequiredMixin + UpdateQuestionMixin ): model = Long form_class = LongForm diff --git a/rad/tests/test_questions.py b/rad/tests/test_questions.py new file mode 100644 index 00000000..2202f66c --- /dev/null +++ b/rad/tests/test_questions.py @@ -0,0 +1,6 @@ + +import pytest + +from longs.models import Long + + diff --git a/rapids/views.py b/rapids/views.py index 086cd0eb..61ef822c 100755 --- a/rapids/views.py +++ b/rapids/views.py @@ -376,7 +376,7 @@ class RapidAnswerUpdate(RevisionMixin, AuthorOrCheckerRequiredMixin, UpdateView) class RapidUpdate( - UpdateQuestionMixin,AuthorOrCheckerRequiredMixin + UpdateQuestionMixin ): model = Rapid form_class = RapidForm diff --git a/sbas/views.py b/sbas/views.py index 4a5b95c8..f7246e07 100644 --- a/sbas/views.py +++ b/sbas/views.py @@ -318,7 +318,7 @@ class QuestionCreate(QuestionCreateBase): return initial -class QuestionUpdate(AuthorOrCheckerRequiredMixin, UpdateQuestionMixin): +class QuestionUpdate(UpdateQuestionMixin): model = Question form_class = QuestionForm