From 886c178ff052a73d22c352b6e802e60e0a0088f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-S=C3=A9bastien=20Caux?= <git@jscaux.org> Date: Tue, 22 Nov 2022 05:54:44 +0100 Subject: [PATCH] Initiate edadmin app --- scipost_django/SciPost_v1/settings/base.py | 22 ++++++---- scipost_django/SciPost_v1/urls.py | 1 + scipost_django/edadmin/__init__.py | 0 scipost_django/edadmin/admin.py | 3 ++ scipost_django/edadmin/apps.py | 10 +++++ scipost_django/edadmin/migrations/__init__.py | 0 scipost_django/edadmin/models.py | 3 ++ .../edadmin/templates/edadmin/edadmin.html | 27 ++++++++++++ scipost_django/edadmin/tests.py | 3 ++ scipost_django/edadmin/urls.py | 15 +++++++ scipost_django/edadmin/views.py | 21 +++++++++ .../0115_alter_submission_options.py | 17 ++++++++ ...rmission_submissionuserobjectpermission.py | 43 +++++++++++++++++++ .../submissions/models/submission.py | 19 ++++++++ scipost_django/submissions/urls.py | 5 ++- 15 files changed, 178 insertions(+), 11 deletions(-) create mode 100644 scipost_django/edadmin/__init__.py create mode 100644 scipost_django/edadmin/admin.py create mode 100644 scipost_django/edadmin/apps.py create mode 100644 scipost_django/edadmin/migrations/__init__.py create mode 100644 scipost_django/edadmin/models.py create mode 100644 scipost_django/edadmin/templates/edadmin/edadmin.html create mode 100644 scipost_django/edadmin/tests.py create mode 100644 scipost_django/edadmin/urls.py create mode 100644 scipost_django/edadmin/views.py create mode 100644 scipost_django/submissions/migrations/0115_alter_submission_options.py create mode 100644 scipost_django/submissions/migrations/0116_submissiongroupobjectpermission_submissionuserobjectpermission.py diff --git a/scipost_django/SciPost_v1/settings/base.py b/scipost_django/SciPost_v1/settings/base.py index 8f0e006de..f2177804a 100644 --- a/scipost_django/SciPost_v1/settings/base.py +++ b/scipost_django/SciPost_v1/settings/base.py @@ -73,6 +73,7 @@ os.environ["wsgi.url_scheme"] = "https" INSTALLED_APPS = [ "dal", # django-autocomplete-light "dal_select2", # dal with Select2 + # Django "django.contrib.admin", "django.contrib.admindocs", "django.contrib.auth", @@ -82,12 +83,23 @@ INSTALLED_APPS = [ "django.contrib.messages", "django.contrib.staticfiles", "django.contrib.sites", + # external + "corsheaders", "crispy_forms", "crispy_bootstrap5", + "django_celery_results", + "django_celery_beat", "django_countries", "django_extensions", "django_filters", + "guardian", "haystack", + "maintenancemode", + "oauth2_provider", + "rest_framework", + "sitesserved", + "webpack_loader", + # own apps "affiliates", "api", "apimail", @@ -97,14 +109,11 @@ INSTALLED_APPS = [ "comments", "common", "conflicts", - "corsheaders", - "django_celery_results", - "django_celery_beat", + "edadmin", "finances", "forums", "funders", "guides", - "guardian", "helpdesk", "invitations", "journals", @@ -112,7 +121,6 @@ INSTALLED_APPS = [ "mails", "markup", "news", - "oauth2_provider", "ontology", "organizations", "petitions", @@ -120,7 +128,6 @@ INSTALLED_APPS = [ "proceedings", "production", "profiles", - "rest_framework", "scipost", "security", "series", @@ -128,10 +135,7 @@ INSTALLED_APPS = [ "stats", "submissions", "theses", - "sitesserved", "webinars", - "webpack_loader", - "maintenancemode", ] SITE_ID = 1 diff --git a/scipost_django/SciPost_v1/urls.py b/scipost_django/SciPost_v1/urls.py index 8c60cfb21..709938678 100644 --- a/scipost_django/SciPost_v1/urls.py +++ b/scipost_django/SciPost_v1/urls.py @@ -92,6 +92,7 @@ urlpatterns = [ path("commentaries/", include("commentaries.urls", namespace="commentaries")), path("commentary/", include("commentaries.urls", namespace="_commentaries")), path("comments/", include("comments.urls", namespace="comments")), + path("edadmin/", include("edadmin.urls", namespace="edadmin")), path("forums/", include("forums.urls", namespace="forums")), path("funders/", include("funders.urls", namespace="funders")), path("finances/", include("finances.urls", namespace="finances")), diff --git a/scipost_django/edadmin/__init__.py b/scipost_django/edadmin/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/scipost_django/edadmin/admin.py b/scipost_django/edadmin/admin.py new file mode 100644 index 000000000..8c38f3f3d --- /dev/null +++ b/scipost_django/edadmin/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/scipost_django/edadmin/apps.py b/scipost_django/edadmin/apps.py new file mode 100644 index 000000000..8edea9546 --- /dev/null +++ b/scipost_django/edadmin/apps.py @@ -0,0 +1,10 @@ +__copyright__ = "Copyright © Stichting SciPost (SciPost Foundation)" +__license__ = "AGPL v3" + + +from django.apps import AppConfig + + +class EdadminConfig(AppConfig): + default_auto_field = 'django.db.models.BigAutoField' + name = 'edadmin' diff --git a/scipost_django/edadmin/migrations/__init__.py b/scipost_django/edadmin/migrations/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/scipost_django/edadmin/models.py b/scipost_django/edadmin/models.py new file mode 100644 index 000000000..71a836239 --- /dev/null +++ b/scipost_django/edadmin/models.py @@ -0,0 +1,3 @@ +from django.db import models + +# Create your models here. diff --git a/scipost_django/edadmin/templates/edadmin/edadmin.html b/scipost_django/edadmin/templates/edadmin/edadmin.html new file mode 100644 index 000000000..75ccdabd3 --- /dev/null +++ b/scipost_django/edadmin/templates/edadmin/edadmin.html @@ -0,0 +1,27 @@ +{% extends 'scipost/base.html' %} + +{% block breadcrumb %} + <div class="breadcrumb-container"> + <div class="container"> + <nav class="breadcrumb hidden-sm-down"> + {% block breadcrumb_items %} + <a href="{% url 'submissions:pool' %}" class="breadcrumb-item">EdAdmin</a> + {% endblock %} + </nav> + </div> + </div> +{% endblock %} + +{% block pagetitle %}: EdAdmin{% endblock pagetitle %} + +{% block content %} + + <h2 class="highlight">Prescreening</h2> + {% for submission in prescreening %} + <details> + <summary>{{ submission }}</summary> + {{ submission }} + </details> + {% endfor %} + +{% endblock content %} diff --git a/scipost_django/edadmin/tests.py b/scipost_django/edadmin/tests.py new file mode 100644 index 000000000..7ce503c2d --- /dev/null +++ b/scipost_django/edadmin/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/scipost_django/edadmin/urls.py b/scipost_django/edadmin/urls.py new file mode 100644 index 000000000..9caf5624b --- /dev/null +++ b/scipost_django/edadmin/urls.py @@ -0,0 +1,15 @@ +__copyright__ = "Copyright © Stichting SciPost (SciPost Foundation)" +__license__ = "AGPL v3" + + +from django.urls import path, re_path +from django.views.generic import TemplateView + +from . import views + +app_name = "edadmin" + + +urlpatterns = [ + path("", views.edadmin, name="edadmin"), +] diff --git a/scipost_django/edadmin/views.py b/scipost_django/edadmin/views.py new file mode 100644 index 000000000..92ab47aee --- /dev/null +++ b/scipost_django/edadmin/views.py @@ -0,0 +1,21 @@ +__copyright__ = "Copyright © Stichting SciPost (SciPost Foundation)" +__license__ = "AGPL v3" + + +from django.contrib.auth.decorators import login_required, user_passes_test +from django.shortcuts import render + +from guardian.shortcuts import get_objects_for_user + +from scipost.permissions import is_edadmin + + +@login_required +@user_passes_test(is_edadmin) +def edadmin(request): + """ + Editorial administration page. + """ + submissions = get_objects_for_user(request.user, "submissions.take_edadmin_actions") + context = { "prescreening": submissions.prescreening() } + return render(request, "edadmin/edadmin.html", context) diff --git a/scipost_django/submissions/migrations/0115_alter_submission_options.py b/scipost_django/submissions/migrations/0115_alter_submission_options.py new file mode 100644 index 000000000..28d73f0f6 --- /dev/null +++ b/scipost_django/submissions/migrations/0115_alter_submission_options.py @@ -0,0 +1,17 @@ +# Generated by Django 3.2.16 on 2022-11-22 04:39 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('submissions', '0114_submission_internal_plagiarism_matches'), + ] + + operations = [ + migrations.AlterModelOptions( + name='submission', + options={'ordering': ['-submission_date'], 'permissions': [('take_edadmin_actions', 'Take editorial admin actions'), ('view_edadmin_info', 'View editorial admin information')]}, + ), + ] diff --git a/scipost_django/submissions/migrations/0116_submissiongroupobjectpermission_submissionuserobjectpermission.py b/scipost_django/submissions/migrations/0116_submissiongroupobjectpermission_submissionuserobjectpermission.py new file mode 100644 index 000000000..95d8123ff --- /dev/null +++ b/scipost_django/submissions/migrations/0116_submissiongroupobjectpermission_submissionuserobjectpermission.py @@ -0,0 +1,43 @@ +# Generated by Django 3.2.16 on 2022-11-22 04:44 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('auth', '0012_alter_user_first_name_max_length'), + ('submissions', '0115_alter_submission_options'), + ] + + operations = [ + migrations.CreateModel( + name='SubmissionUserObjectPermission', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('content_object', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='submissions.submission')), + ('permission', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='auth.permission')), + ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ], + options={ + 'abstract': False, + 'unique_together': {('user', 'permission', 'content_object')}, + }, + ), + migrations.CreateModel( + name='SubmissionGroupObjectPermission', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('content_object', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='submissions.submission')), + ('group', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='auth.group')), + ('permission', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='auth.permission')), + ], + options={ + 'abstract': False, + 'unique_together': {('group', 'permission', 'content_object')}, + }, + ), + ] diff --git a/scipost_django/submissions/models/submission.py b/scipost_django/submissions/models/submission.py index ad344779d..12af62b23 100644 --- a/scipost_django/submissions/models/submission.py +++ b/scipost_django/submissions/models/submission.py @@ -13,6 +13,9 @@ from django.urls import reverse from django.utils import timezone from django.utils.functional import cached_property +from guardian.models import UserObjectPermissionBase +from guardian.models import GroupObjectPermissionBase + from scipost.behaviors import TimeStampedModel from scipost.constants import SCIPOST_APPROACHES from scipost.fields import ChoiceArrayField @@ -196,6 +199,10 @@ class Submission(models.Model): class Meta: app_label = "submissions" ordering = ["-submission_date"] + permissions = [ + ("take_edadmin_actions", "Take editorial admin actions"), + ("view_edadmin_info", "View editorial admin information"), + ] def save(self, *args, **kwargs): """Prefill some fields before saving.""" @@ -537,6 +544,18 @@ class Submission(models.Model): return None +# The next two models are for optimization of django guardian object-level permissions +# using direct foreign keys instead of generic ones +# (see https://django-guardian.readthedocs.io/en/stable/userguide/performance.html) + +class SubmissionUserObjectPermission(UserObjectPermissionBase): + content_object = models.ForeignKey(Submission, on_delete=models.CASCADE) + +class SubmissionGroupObjectPermission(GroupObjectPermissionBase): + content_object = models.ForeignKey(Submission, on_delete=models.CASCADE) + + + class SubmissionEvent(SubmissionRelatedObjectMixin, TimeStampedModel): """Private message directly related to a Submission. diff --git a/scipost_django/submissions/urls.py b/scipost_django/submissions/urls.py index 4594db967..7e6c93078 100644 --- a/scipost_django/submissions/urls.py +++ b/scipost_django/submissions/urls.py @@ -17,8 +17,7 @@ urlpatterns = [ views.SubmissionAutocompleteView.as_view(), name="submission-autocomplete", ), - # Submissions - path("", views.SubmissionListView.as_view(), name="submissions"), + # Information path( "author_guidelines", TemplateView.as_view(template_name="submissions/author_guidelines.html"), @@ -34,6 +33,8 @@ urlpatterns = [ TemplateView.as_view(template_name="submissions/referee_guidelines.html"), name="referee_guidelines", ), + # Submissions + path("", views.SubmissionListView.as_view(), name="submissions"), path( "<identifier_wo_vn_nr:identifier_wo_vn_nr>/", views.submission_detail_wo_vn_nr, -- GitLab