From 818a6b24462597cdd6048a4d48398adee79788c1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jean-S=C3=A9bastien=20Caux?= <git@jscaux.org>
Date: Fri, 28 Jan 2022 20:24:35 +0100
Subject: [PATCH] Tweak permissions and search form

---
 scipost_django/colleges/forms.py             | 17 ++++++++++++++++-
 scipost_django/colleges/models/nomination.py |  2 +-
 scipost_django/colleges/permissions.py       | 20 +++++++++++++++++++-
 scipost_django/colleges/views.py             |  8 ++++++--
 scipost_django/submissions/permissions.py    | 14 --------------
 scipost_django/submissions/views.py          |  6 ++++--
 6 files changed, 46 insertions(+), 21 deletions(-)
 delete mode 100644 scipost_django/submissions/permissions.py

diff --git a/scipost_django/colleges/forms.py b/scipost_django/colleges/forms.py
index 6c04ab986..81f8ad6bc 100644
--- a/scipost_django/colleges/forms.py
+++ b/scipost_django/colleges/forms.py
@@ -12,6 +12,7 @@ from crispy_forms.layout import Layout, Div, Field
 from crispy_bootstrap5.bootstrap5 import FloatingField
 from dal import autocomplete
 
+from ontology.models import Specialty
 from proceedings.models import Proceedings
 from profiles.models import Profile
 from submissions.models import Submission
@@ -289,9 +290,19 @@ class FellowshipNominationSearchForm(forms.Form):
         queryset=College.objects.all(),
         required=False
     )
+    specialty = forms.ModelChoiceField(
+        queryset=Specialty.objects.all(),
+        widget=autocomplete.ModelSelect2(
+            url='/ontology/specialty-autocomplete',
+            attrs={'data-html': True}
+        ),
+        label='Specialty',
+        required=False
+    )
     profile = forms.ModelChoiceField(
         queryset=Profile.objects.all(),
         widget=autocomplete.ModelSelect2(url='/profiles/profile-autocomplete'),
+        label='Name (through Profile)',
         required=False
     )
 
@@ -301,9 +312,13 @@ class FellowshipNominationSearchForm(forms.Form):
         self.helper.layout = Layout(
             Div(
                 Div(FloatingField('college'), css_class='col-lg-6'),
+                Div(FloatingField('specialty'), css_class='col-lg-6'),
+                css_class='row'
+            ),
+            Div(
                 Div(FloatingField('profile'), css_class='col-lg-6'),
                 css_class='row'
-            )
+            ),
         )
 
     def search_results(self):
diff --git a/scipost_django/colleges/models/nomination.py b/scipost_django/colleges/models/nomination.py
index 7d95293ec..65f7be47a 100644
--- a/scipost_django/colleges/models/nomination.py
+++ b/scipost_django/colleges/models/nomination.py
@@ -43,7 +43,7 @@ class FellowshipNomination(models.Model):
         verbose_name_plural = 'Fellowship Nominations'
 
     def __str__(self):
-        return (f'Nomination of {self.profile} to {self.college} '
+        return (f'{self.profile} to {self.college} '
                 f'on {self.nominated_on.strftime("%Y-%m-%d")}')
 
 
diff --git a/scipost_django/colleges/permissions.py b/scipost_django/colleges/permissions.py
index f27cf1a4f..d61409bc5 100644
--- a/scipost_django/colleges/permissions.py
+++ b/scipost_django/colleges/permissions.py
@@ -6,6 +6,7 @@ from django.contrib.auth.decorators import user_passes_test
 from django.core.exceptions import PermissionDenied
 
 from scipost.permissions import is_in_group
+from colleges.models import Fellowship
 
 
 def fellowship_required():
@@ -20,7 +21,7 @@ def fellowship_required():
 
 
 def fellowship_or_admin_required():
-    """Require user to have any Fellowship or Administrational permissions."""
+    """Require user to have any Fellowship or Administrative permissions."""
     def test(u):
         if u.is_authenticated:
             if hasattr(u, 'contributor') and u.contributor.fellowships.exists():
@@ -32,3 +33,20 @@ def fellowship_or_admin_required():
                 return True
         raise PermissionDenied
     return user_passes_test(test)
+
+
+def is_edadmin_or_active_regular_or_senior_fellow(user):
+    if not user.has_perm('scipost.can_run_pre_screening'):
+        return Fellowship.objects.active().regular_or_senior(
+        ).filter(contributor__user=user).exists()
+    return True
+
+
+def is_edadmin_or_senior_fellow(user):
+    if not user.has_perm('scipost.can_run_pre_screening'):
+        try:
+            fellow = Fellowship.objects.active().get(contributor__user=user)
+            return fellow.senior
+        except:
+            return False
+    return True
diff --git a/scipost_django/colleges/views.py b/scipost_django/colleges/views.py
index 64b3b8224..df3c2e387 100644
--- a/scipost_django/colleges/views.py
+++ b/scipost_django/colleges/views.py
@@ -18,8 +18,10 @@ from django.views.generic.detail import DetailView
 from django.views.generic.edit import CreateView, UpdateView, DeleteView
 from django.views.generic.list import ListView
 
+from colleges.permissions import (
+    is_edadmin_or_senior_fellow, is_edadmin_or_active_regular_or_senior_fellow
+)
 from submissions.models import Submission
-from submissions.permissions import is_edadmin_or_senior_fellow
 
 from .constants import (
     POTENTIAL_FELLOWSHIP_STATUSES, POTENTIAL_FELLOWSHIP_EVENT_STATUSUPDATED,
@@ -526,7 +528,7 @@ class PotentialFellowshipEventCreateView(PermissionsMixin, CreateView):
 
 
 @login_required
-@user_passes_test(is_edadmin_or_senior_fellow)
+@user_passes_test(is_edadmin_or_active_regular_or_senior_fellow)
 def nominations(request):
     """
     List Nominations.
@@ -537,6 +539,8 @@ def nominations(request):
     return render(request, 'colleges/nominations.html', context)
 
 
+@login_required
+@user_passes_test(is_edadmin_or_active_regular_or_senior_fellow)
 def _hx_nominations(request):
     form = FellowshipNominationSearchForm(request.POST or None)
     if form.is_valid():
diff --git a/scipost_django/submissions/permissions.py b/scipost_django/submissions/permissions.py
deleted file mode 100644
index b9cd3d3f0..000000000
--- a/scipost_django/submissions/permissions.py
+++ /dev/null
@@ -1,14 +0,0 @@
-__copyright__ = "Copyright © Stichting SciPost (SciPost Foundation)"
-__license__ = "AGPL v3"
-
-
-from colleges.models import Fellowship
-
-def is_edadmin_or_senior_fellow(user):
-    if not user.has_perm('scipost.can_run_pre_screening'):
-        try:
-            fellow = Fellowship.objects.get(contributor__user=user)
-            return fellow.senior
-        except:
-            return False
-    return True
diff --git a/scipost_django/submissions/views.py b/scipost_django/submissions/views.py
index cb61a2649..7c414b900 100644
--- a/scipost_django/submissions/views.py
+++ b/scipost_django/submissions/views.py
@@ -60,11 +60,13 @@ from .forms import (
     SubmissionTargetJournalForm, SubmissionTargetProceedingsForm, SubmissionPreprintFileForm,
     SubmissionPrescreeningForm,
     PreassignEditorsFormSet, SubmissionReassignmentForm)
-from .permissions import is_edadmin_or_senior_fellow
 from .utils import SubmissionUtils
 
 from colleges.models import PotentialFellowship, Fellowship
-from colleges.permissions import fellowship_required, fellowship_or_admin_required
+from colleges.permissions import (
+    fellowship_required, fellowship_or_admin_required,
+    is_edadmin_or_senior_fellow
+)
 from comments.forms import CommentForm
 from common.helpers import get_new_secrets_key
 from common.utils import workdays_between
-- 
GitLab