diff --git a/.env.example b/.env.example index ff738bf0f4..bdb593a99e 100644 --- a/.env.example +++ b/.env.example @@ -98,8 +98,6 @@ GCS_SIGNED_URL_LIFETIME_IN_MINUTES=1440 # GCP Research Environments ENABLE_CLOUD_RESEARCH_ENVIRONMENTS="False" CLOUD_RESEARCH_ENVIRONMENTS_API_URL="https://example.api" -CLOUD_RESEARCH_ENVIRONMENTS_API_JWT_SERVICE_ACCOUNT_PATH="environment/api/tests/service_account.json" -CLOUD_RESEARCH_ENVIRONMENTS_API_JWT_AUDIENCE="https://example.com" # Site-specific content SITE_NAME="DataShare" @@ -187,7 +185,7 @@ MIN_WORDS_RESEARCH_SUMMARY_CREDENTIALING = 20 # CITISOAPService API # This is the WebServices username and password to access the CITI SOAP Service to obtain users training report details # The account can be created at https://webservices.citiprogram.org/login/CreateAccount.aspx -# The SOAP Service Access can be tested at https://webservices.citiprogram.org/Client/CITISOAPClient_Simple.aspx +# The SOAP Service Access can be tested at https://webservices.citiprogram.org/Client/CITISOAPClient_Simple.aspx CITI_USERNAME= CITI_PASSWORD= CITI_SOAP_URL="https://webservices.citiprogram.org/SOAP/CITISOAPService.asmx" diff --git a/.github/workflows/physionet-build-test.yml b/.github/workflows/physionet-build-test.yml index f24cf2ca0a..8f0bc193b5 100644 --- a/.github/workflows/physionet-build-test.yml +++ b/.github/workflows/physionet-build-test.yml @@ -14,7 +14,7 @@ jobs: test: name: Test runs-on: ubuntu-latest - container: debian:11 + container: ${{ matrix.container }} env: DJANGO_SETTINGS_MODULE: physionet.settings.settings TEST_GCS_INTEGRATION: false @@ -26,6 +26,7 @@ jobs: fail-fast: false matrix: pip3: ['poetry', 'requirements.txt'] + container: ['debian:11', 'debian:12'] steps: - name: Update packages diff --git a/.github/workflows/physionet-upgrade-test.yml b/.github/workflows/physionet-upgrade-test.yml index 0f7468f9b4..3fbca0fc3e 100644 --- a/.github/workflows/physionet-upgrade-test.yml +++ b/.github/workflows/physionet-upgrade-test.yml @@ -12,7 +12,10 @@ jobs: testupgrade: name: Upgrade Test runs-on: ubuntu-latest - container: debian:11 + container: ${{ matrix.container }} + strategy: + matrix: + container: ['debian:11', 'debian:12'] steps: - name: Install dependencies run: | diff --git a/deploy/README.md b/deploy/README.md index 3860114ab6..c381fc3dd2 100644 --- a/deploy/README.md +++ b/deploy/README.md @@ -100,8 +100,8 @@ cd /physionet # Copy over the .env file into /physionet/physionet-build scp /.env /physionet/physionet-build/ # The software folder should be owned by the dedicated user. The socket file directory should be accessible by nginx. -chown -R pn.pn /physionet -chown pn.www-data /physionet/deploy +chown -R pn:pn /physionet +chown pn:www-data /physionet/deploy chmod g+w /physionet/deploy # Make the static and media roots mkdir /data @@ -109,7 +109,7 @@ mkdir /data/pn-static mkdir /data/pn-static/published-projects mkdir /data/pn-media mkdir /data/pn-media/{active-projects,archived-projects,credential-applications,published-projects,users} -chown -R pn.pn /data/{pn-media,pn-static} +chown -R pn:pn /data/{pn-media,pn-static} ``` The directory structure for the site's software and files will be: diff --git a/deploy/test-server/install-pn-test-server b/deploy/test-server/install-pn-test-server index 87a43ac253..68e9c9d23c 100755 --- a/deploy/test-server/install-pn-test-server +++ b/deploy/test-server/install-pn-test-server @@ -90,7 +90,7 @@ printf '%s\n%s\n' "$DBPASSWORD" "$DBPASSWORD" | su postgres -c 'createdb physionet -O physionet' mkdir -p /physionet /data/pn-static /data/pn-media -chown pn.pn /physionet /data/pn-static /data/pn-media +chown pn:pn /physionet /data/pn-static /data/pn-media su pn -c ' set -e umask 0002 @@ -153,17 +153,17 @@ su pn -c ' yes | python3 manage.py loaddemo ' -chown www-data.www-data -R /physionet/deploy -chown www-data.www-data -R /data/pn-media -chown www-data.www-data -R /data/pn-static/published-projects +chown www-data:www-data -R /physionet/deploy +chown www-data:www-data -R /data/pn-media +chown www-data:www-data -R /data/pn-static/published-projects rm /etc/nginx/sites-enabled/default ln -s ../sites-available/physionet_nginx.conf \ /etc/nginx/sites-enabled/physionet_nginx.conf mkdir /data/log /data/log/nginx /data/log/uwsgi /data/log/pn -chown www-data.root /data/log/uwsgi -chown pn.root /data/log/pn +chown www-data:root /data/log/uwsgi +chown pn:root /data/log/pn ( cd /physionet/physionet-build/deploy/common diff --git a/physionet-django/console/forms.py b/physionet-django/console/forms.py index 74f86d7923..c085efaf12 100644 --- a/physionet-django/console/forms.py +++ b/physionet-django/console/forms.py @@ -1,10 +1,5 @@ -import pdb import re -from django.forms.widgets import RadioSelect - -from django.forms.widgets import RadioSelect - from console.utility import generate_doi_payload, register_doi from dal import autocomplete from django import forms @@ -27,9 +22,10 @@ PublishedAffiliation, PublishedAuthor, PublishedProject, + PublishedPublication, + SubmissionStatus, exists_project_slug, ) -from project.projectfiles import ProjectFiles from project.validators import MAX_PROJECT_SLUG_LENGTH, validate_doi, validate_slug from user.models import CodeOfConduct, CredentialApplication, CredentialReview, User, TrainingQuestion @@ -91,10 +87,12 @@ def __init__(self, *args, **kwargs): .order_by('username') def clean_project(self): - pid = self.cleaned_data['project'] + pid = self.cleaned_data["project"] validate_integer(pid) - if ActiveProject.objects.get(id=pid) not in ActiveProject.objects.filter(submission_status=10): - raise forms.ValidationError('Incorrect project selected.') + if ActiveProject.objects.get(id=pid) not in ActiveProject.objects.filter( + submission_status=SubmissionStatus.NEEDS_ASSIGNMENT + ): + raise forms.ValidationError("Incorrect project selected.") return pid @@ -230,13 +228,13 @@ def save(self): edit_log = EditLog.objects.get(id=edit_log.id) # Resubmit with revisions elif edit_log.decision == 1: - project.submission_status = 30 + project.submission_status = SubmissionStatus.NEEDS_RESUBMISSION project.revision_request_datetime = now project.latest_reminder = now project.save() # Accept else: - project.submission_status = 40 + project.submission_status = SubmissionStatus.NEEDS_COPYEDIT project.editor_accept_datetime = now project.latest_reminder = now @@ -289,7 +287,7 @@ def save(self): project = copyedit_log.project now = timezone.now() copyedit_log.complete_datetime = now - project.submission_status = 50 + project.submission_status = SubmissionStatus.NEEDS_APPROVAL project.copyedit_completion_datetime = now project.latest_reminder = now copyedit_log.save() @@ -310,12 +308,12 @@ def __init__(self, project, *args, **kwargs): super().__init__(*args, **kwargs) self.project = project # No option to set slug if publishing new version - if self.project.version_order: + if self.project.is_new_version: del(self.fields['slug']) else: self.fields['slug'].initial = project.slug - if not ProjectFiles().can_make_zip(): + if not project.files.can_make_zip(): self.fields['make_zip'].disabled = True self.fields['make_zip'].required = False self.fields['make_zip'].initial = 0 @@ -705,6 +703,32 @@ def save(self): return contact +class AddPublishedPublicationForm(forms.ModelForm): + class Meta: + model = PublishedPublication + fields = ('citation', 'url') + + def __init__(self, project, *args, **kwargs): + super().__init__(*args, **kwargs) + self.project = project + + def clean(self): + cleaned_data = super().clean() + existing_publication = PublishedPublication.objects.filter(project=self.project).first() + + if existing_publication: + raise forms.ValidationError("A publication already exists for this project.") + + return cleaned_data + + def save(self, commit=True): + publication = super().save(commit=False) + publication.project = self.project + if commit: + publication.save() + return publication + + class CreateLegacyAuthorForm(forms.ModelForm): """ Create an author for a legacy project. diff --git a/physionet-django/console/templates/console/console_navbar.html b/physionet-django/console/templates/console/console_navbar.html index 119ec20b83..3ffd116272 100644 --- a/physionet-django/console/templates/console/console_navbar.html +++ b/physionet-django/console/templates/console/console_navbar.html @@ -123,13 +123,16 @@ Events - {% if events_nav %} + {% if nav_event_active or nav_event_archive %} - - {% endif %} - {% endfor %} +

Submit evidence of a completed Training

Please use the form below to submit a new completion report.

For CITI training, please refer to our step-by-step instructions and @@ -70,7 +31,7 @@