Skip to content

Commit

Permalink
Subclass AccessMixin directly in VerificationRequiredMixin
Browse files Browse the repository at this point in the history
  • Loading branch information
amickan committed Dec 18, 2024
1 parent c1c4c35 commit 44df626
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 94 deletions.
121 changes: 58 additions & 63 deletions app/grandchallenge/evaluation/views/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,70 +97,65 @@ class UserCanSubmitAlgorithmToPhaseMixin(VerificationRequiredMixin):
is open for submissions.
"""

def test_func(self):
response = super().test_func()
if response:
if not (
self.phase.challenge.is_admin(self.request.user)
or self.phase.challenge.is_participant(self.request.user)
):
error_message = (
"You need to be either an admin or a participant of "
"the challenge in order to create an algorithm for this phase."
)
messages.error(
self.request,
error_message,
)
return False
elif (
self.phase.challenge.is_participant(self.request.user)
and not self.phase.challenge.is_admin(self.request.user)
and not self.phase.open_for_submissions
):
error_message = "The phase is currently not open for submissions. Please come back later."
messages.error(
self.request,
error_message,
)
return False
elif (
self.phase.challenge.is_admin(self.request.user)
and not self.phase.challenge.logo
):
error_message = (
"You need to first upload a logo for your challenge "
"before you can create algorithms for its phases."
)
messages.error(
self.request,
error_message,
)
return False
elif (
not self.phase.submission_kind
== SubmissionKindChoices.ALGORITHM
or not self.phase.algorithm_inputs
or not self.phase.algorithm_outputs
or not self.phase.archive
):
error_message = (
"This phase is not configured for algorithm submission. "
)
if self.phase.challenge.is_admin(self.request.user):
error_message += "You need to link an archive containing the secret test data to this phase and define the inputs and outputs that algorithms need to read/write. Please get in touch with [email protected] to configure these settings."
else:
error_message += "Please come back later."

messages.error(
self.request,
error_message,
)
return False
def dispatch(self, request, *args, **kwargs):
if not (
self.phase.challenge.is_admin(self.request.user)
or self.phase.challenge.is_participant(self.request.user)
):
error_message = (
"You need to be either an admin or a participant of "
"the challenge in order to create an algorithm for this phase."
)
messages.error(
request,
error_message,
)
return self.handle_no_permission()
elif (
self.phase.challenge.is_participant(self.request.user)
and not self.phase.challenge.is_admin(self.request.user)
and not self.phase.open_for_submissions
):
error_message = "The phase is currently not open for submissions. Please come back later."
messages.error(
request,
error_message,
)
return self.handle_no_permission()
elif (
self.phase.challenge.is_admin(request.user)
and not self.phase.challenge.logo
):
error_message = (
"You need to first upload a logo for your challenge "
"before you can create algorithms for its phases."
)
messages.error(
request,
error_message,
)
return self.handle_no_permission()
elif (
not self.phase.submission_kind == SubmissionKindChoices.ALGORITHM
or not self.phase.algorithm_inputs
or not self.phase.algorithm_outputs
or not self.phase.archive
):
error_message = (
"This phase is not configured for algorithm submission. "
)
if self.phase.challenge.is_admin(request.user):
error_message += "You need to link an archive containing the secret test data to this phase and define the inputs and outputs that algorithms need to read/write. Please get in touch with [email protected] to configure these settings."
else:
error_message += "Please come back later."

messages.error(
request,
error_message,
)
return self.handle_no_permission()

return True
else:
return False
return super().dispatch(request, *args, **kwargs)


class PhaseCreate(
Expand Down
18 changes: 8 additions & 10 deletions app/grandchallenge/verifications/views.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
from django.contrib import messages
from django.contrib.auth.mixins import (
PermissionRequiredMixin,
UserPassesTestMixin,
)
from django.contrib.auth.mixins import AccessMixin, PermissionRequiredMixin
from django.core.exceptions import ObjectDoesNotExist
from django.http import Http404
from django.utils.html import format_html
Expand All @@ -22,26 +19,27 @@
)


class VerificationRequiredMixin(UserPassesTestMixin):
class VerificationRequiredMixin(AccessMixin):
"""Mixin for views that require verification"""

def test_func(self):
def dispatch(self, request, *args, **kwargs):
try:
verified = self.request.user.verification.is_verified
verified = request.user.verification.is_verified
except ObjectDoesNotExist:
verified = False

if not verified:
messages.error(
self.request,
request,
format_html(
"You need to verify your account before you can do this, "
"you can request this <a href='{}'>on this page</a>.",
reverse("verifications:create"),
),
)

return verified
return self.handle_no_permission()
else:
return super().dispatch(request, *args, **kwargs)


class VerificationCreate(LoginRequiredMixin, CreateView):
Expand Down
42 changes: 21 additions & 21 deletions app/tests/evaluation_tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -682,21 +682,6 @@ def test_create_algorithm_for_phase_permission(client, uploaded_image):
user=admin,
)
assert response.status_code == 403
assert "You need to verify your account before you can do this" in str(
response.content
)

VerificationFactory(user=admin, is_verified=True)
response = get_view_for_user(
viewname="evaluation:phase-algorithm-create",
reverse_kwargs={
"slug": phase.slug,
"challenge_short_name": phase.challenge.short_name,
},
client=client,
user=admin,
)
assert response.status_code == 403
assert (
"You need to first upload a logo for your challenge before you can create algorithms for its phases."
in str(response.content)
Expand Down Expand Up @@ -724,6 +709,21 @@ def test_create_algorithm_for_phase_permission(client, uploaded_image):
phase.algorithm_inputs.set([ComponentInterfaceFactory()])
phase.algorithm_outputs.set([ComponentInterfaceFactory()])
phase.save()

response = get_view_for_user(
viewname="evaluation:phase-algorithm-create",
reverse_kwargs={
"slug": phase.slug,
"challenge_short_name": phase.challenge.short_name,
},
client=client,
user=admin,
)
assert "You need to verify your account before you can do this" in str(
response.content
)

VerificationFactory(user=admin, is_verified=True)
response = get_view_for_user(
viewname="evaluation:phase-algorithm-create",
reverse_kwargs={
Expand All @@ -748,11 +748,13 @@ def test_create_algorithm_for_phase_permission(client, uploaded_image):
user=participant,
)
assert response.status_code == 403
assert "You need to verify your account before you can do this" in str(
assert "The phase is currently not open for submissions." in str(
response.content
)

VerificationFactory(user=participant, is_verified=True)
phase.submissions_limit_per_user_per_period = 1
phase.save()

response = get_view_for_user(
viewname="evaluation:phase-algorithm-create",
reverse_kwargs={
Expand All @@ -763,13 +765,11 @@ def test_create_algorithm_for_phase_permission(client, uploaded_image):
user=participant,
)
assert response.status_code == 403
assert "The phase is currently not open for submissions." in str(
assert "You need to verify your account before you can do this" in str(
response.content
)

phase.submissions_limit_per_user_per_period = 1
phase.save()

VerificationFactory(user=participant, is_verified=True)
response = get_view_for_user(
viewname="evaluation:phase-algorithm-create",
reverse_kwargs={
Expand Down

0 comments on commit 44df626

Please sign in to comment.