From bdfe7718bc816cfae79a2d80d98ba27e22aac4cd Mon Sep 17 00:00:00 2001 From: Adrienne Stilp Date: Thu, 11 Jul 2024 11:45:48 -0700 Subject: [PATCH 01/36] Hide inactive users in study site table The UserAccountTable on the StudySite detail page was showing inactive users. Hide the users in the queryset and add a test for this case. --- primed/primed_anvil/tests/test_views.py | 13 +++++++++++++ primed/primed_anvil/views.py | 2 +- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/primed/primed_anvil/tests/test_views.py b/primed/primed_anvil/tests/test_views.py index f47e8717..03214bb1 100644 --- a/primed/primed_anvil/tests/test_views.py +++ b/primed/primed_anvil/tests/test_views.py @@ -910,6 +910,19 @@ def test_site_user_table_when_member_group_is_set(self): self.assertIsInstance(table, tables.UserAccountSingleGroupMembershipTable) self.assertEqual(table.managed_group, member_group) + def test_site_user_table_does_not_include_inactive_users(self): + """Site user table does not include inactive users.""" + obj = self.model_factory.create() + inactive_site_user = UserFactory.create() + inactive_site_user.study_sites.set([obj]) + inactive_site_user.is_active = False + inactive_site_user.save() + self.client.force_login(self.user) + response = self.client.get(self.get_url(obj.pk)) + table = response.context_data["tables"][0] + self.assertEqual(len(table.rows), 0) + self.assertNotIn(inactive_site_user, table.data) + def test_member_group_table(self): member_group = ManagedGroupFactory.create() obj = self.model_factory.create(member_group=member_group) diff --git a/primed/primed_anvil/views.py b/primed/primed_anvil/views.py index 7717e667..4e1c1340 100644 --- a/primed/primed_anvil/views.py +++ b/primed/primed_anvil/views.py @@ -125,7 +125,7 @@ class StudySiteDetail(AnVILConsortiumManagerStaffViewRequired, MultiTableMixin, model = models.StudySite def get_tables(self): - user_qs = User.objects.filter(study_sites=self.object) + user_qs = User.objects.filter(is_active=True, study_sites=self.object) if self.object.member_group: user_table = tables.UserAccountSingleGroupMembershipTable(user_qs, managed_group=self.object.member_group) else: From 25501e7d7324b02ad44b9218f4d2a83fdd8822c4 Mon Sep 17 00:00:00 2001 From: Adrienne Stilp Date: Thu, 11 Jul 2024 14:44:11 -0700 Subject: [PATCH 02/36] Add the crontab file to the activate script This way we can reference it using an environment variable when deploying. --- primed-apps-activate.sh | 1 + primed-apps-dev-activate.sh | 1 + 2 files changed, 2 insertions(+) diff --git a/primed-apps-activate.sh b/primed-apps-activate.sh index 92ff51f2..7daa6938 100644 --- a/primed-apps-activate.sh +++ b/primed-apps-activate.sh @@ -2,6 +2,7 @@ export DJANGO_SITE_DIR=/var/www/django/primed_apps/ export DJANGO_SITE_USER=primedweb export DJANGO_SETTINGS_MODULE=config.settings.apps export DJANGO_WSGI_FILE=config/primed_apps_wsgi.py +export DJANGO_CRONTAB=primed_apps.cron export GAC_ENV=primed_apps cd $DJANGO_SITE_DIR . venv/bin/activate diff --git a/primed-apps-dev-activate.sh b/primed-apps-dev-activate.sh index 25dc81c4..2c0be571 100644 --- a/primed-apps-dev-activate.sh +++ b/primed-apps-dev-activate.sh @@ -6,6 +6,7 @@ export DJANGO_SITE_DIR=/var/www/django/primed_apps_dev/ export DJANGO_SITE_USER=primedweb export DJANGO_SETTINGS_MODULE=config.settings.apps_dev export DJANGO_WSGI_FILE=config/primed_apps_dev_wsgi.py +export DJANGO_CRONTAB=primed_apps_dev.cron export GAC_ENV=primed_apps_dev cd $DJANGO_SITE_DIR . venv/bin/activate From e1ec777df47519f815fb1c3865e026f008d99ce5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 14 Jul 2024 03:52:17 +0000 Subject: [PATCH 03/36] Bump types-requests from 2.32.0.20240622 to 2.32.0.20240712 Bumps [types-requests](https://github.com/python/typeshed) from 2.32.0.20240622 to 2.32.0.20240712. - [Commits](https://github.com/python/typeshed/commits) --- updated-dependencies: - dependency-name: types-requests dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements/dev-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/dev-requirements.txt b/requirements/dev-requirements.txt index b0bf891b..9ec3bc1d 100644 --- a/requirements/dev-requirements.txt +++ b/requirements/dev-requirements.txt @@ -188,7 +188,7 @@ types-pytz==2024.1.0.20240203 # via django-stubs types-pyyaml==6.0.12.12 # via django-stubs -types-requests==2.32.0.20240622 +types-requests==2.32.0.20240712 # via -r requirements/dev-requirements.in typing-extensions==4.8.0 # via From e2e8f97439abbdea5258722584c4b1bf8152777e Mon Sep 17 00:00:00 2001 From: Adrienne Stilp Date: Mon, 22 Jul 2024 13:40:05 -0700 Subject: [PATCH 04/36] Fix failing test for mysql test_dbgap_project_id_does_not_match was failing only in mysql likely because in mysql tests, the pk field does not reset to 1 for each test. A (new) previous test likely created a dbGaP application, so when this test had the project_id hard-coded, it failed. Now, set the dbGaP application project_id using the application that the test created in the setup method. --- primed/dbgap/tests/test_forms.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/primed/dbgap/tests/test_forms.py b/primed/dbgap/tests/test_forms.py index 4cecc645..32113a7d 100644 --- a/primed/dbgap/tests/test_forms.py +++ b/primed/dbgap/tests/test_forms.py @@ -857,7 +857,9 @@ def test_dbgap_dar_data_missing_DAC_abbrev(self): def test_dbgap_project_id_does_not_match(self): """Form is not valid when the dbgap_project_id does not match.""" form_data = { - "dbgap_dar_data": json.dumps([factories.dbGaPJSONProjectFactory(Project_id=2)]), + "dbgap_dar_data": json.dumps( + [factories.dbGaPJSONProjectFactory(Project_id=self.dbgap_application.dbgap_project_id + 1)] + ), "dbgap_application": self.dbgap_application, } form = self.form_class(data=form_data) From 387a7f4ef25d373862cd18123ddf8d64f9c1785b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Jul 2024 21:11:11 +0000 Subject: [PATCH 05/36] Bump github/combine-prs from 5.0.0 to 5.1.0 Bumps [github/combine-prs](https://github.com/github/combine-prs) from 5.0.0 to 5.1.0. - [Release notes](https://github.com/github/combine-prs/releases) - [Commits](https://github.com/github/combine-prs/compare/v5.0.0...v5.1.0) --- updated-dependencies: - dependency-name: github/combine-prs dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/combine-prs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/combine-prs.yml b/.github/workflows/combine-prs.yml index c2f75a73..de7c331f 100644 --- a/.github/workflows/combine-prs.yml +++ b/.github/workflows/combine-prs.yml @@ -18,7 +18,7 @@ jobs: steps: - name: combine-prs id: combine-prs - uses: github/combine-prs@v5.0.0 + uses: github/combine-prs@v5.1.0 with: labels: combined-pr # Optional: add a label to the combined PR ci_required: true # require all checks to pass before combining From e654f7ccb34711f25d5b5bdbf256823f43200ee2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Jul 2024 21:11:35 +0000 Subject: [PATCH 06/36] Bump pytest from 8.2.2 to 8.3.1 Bumps [pytest](https://github.com/pytest-dev/pytest) from 8.2.2 to 8.3.1. - [Release notes](https://github.com/pytest-dev/pytest/releases) - [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst) - [Commits](https://github.com/pytest-dev/pytest/compare/8.2.2...8.3.1) --- updated-dependencies: - dependency-name: pytest dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements/test-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/test-requirements.txt b/requirements/test-requirements.txt index e321fb78..23e457af 100644 --- a/requirements/test-requirements.txt +++ b/requirements/test-requirements.txt @@ -53,7 +53,7 @@ pyparsing==3.1.1 # via # -c requirements/requirements.txt # packaging -pytest==8.2.2 +pytest==8.3.1 # via # -r requirements/test-requirements.in # pytest-cov From 813c7daaa9b246aac0bd8ecc0c9a75d7ca7809cf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Jul 2024 21:11:37 +0000 Subject: [PATCH 07/36] Bump django-debug-toolbar from 4.4.5 to 4.4.6 Bumps [django-debug-toolbar](https://github.com/jazzband/django-debug-toolbar) from 4.4.5 to 4.4.6. - [Release notes](https://github.com/jazzband/django-debug-toolbar/releases) - [Changelog](https://github.com/jazzband/django-debug-toolbar/blob/main/docs/changes.rst) - [Commits](https://github.com/jazzband/django-debug-toolbar/compare/4.4.5...4.4.6) --- updated-dependencies: - dependency-name: django-debug-toolbar dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements/dev-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/dev-requirements.txt b/requirements/dev-requirements.txt index b0bf891b..4f8106af 100644 --- a/requirements/dev-requirements.txt +++ b/requirements/dev-requirements.txt @@ -46,7 +46,7 @@ django==4.2.14 # django-debug-toolbar # django-stubs # django-stubs-ext -django-debug-toolbar==4.4.5 +django-debug-toolbar==4.4.6 # via -r requirements/dev-requirements.in django-stubs==4.2.7 # via -r requirements/dev-requirements.in From 0ba4d73699cb3b7c1804b6d4fa3300119087b45d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Jul 2024 21:11:43 +0000 Subject: [PATCH 08/36] Bump mypy from 1.10.1 to 1.11.0 Bumps [mypy](https://github.com/python/mypy) from 1.10.1 to 1.11.0. - [Changelog](https://github.com/python/mypy/blob/master/CHANGELOG.md) - [Commits](https://github.com/python/mypy/compare/v1.10.1...v1.11) --- updated-dependencies: - dependency-name: mypy dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements/dev-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/dev-requirements.txt b/requirements/dev-requirements.txt index b0bf891b..31e49978 100644 --- a/requirements/dev-requirements.txt +++ b/requirements/dev-requirements.txt @@ -87,7 +87,7 @@ markupsafe==2.1.5 # werkzeug matplotlib-inline==0.1.6 # via ipython -mypy==1.10.1 +mypy==1.11.0 # via -r requirements/dev-requirements.in mypy-extensions==1.0.0 # via mypy From 54598290a57925f6cd4a808532f255aea26e96b0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Jul 2024 21:11:50 +0000 Subject: [PATCH 09/36] Bump ruff from 0.5.1 to 0.5.4 Bumps [ruff](https://github.com/astral-sh/ruff) from 0.5.1 to 0.5.4. - [Release notes](https://github.com/astral-sh/ruff/releases) - [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md) - [Commits](https://github.com/astral-sh/ruff/compare/0.5.1...0.5.4) --- updated-dependencies: - dependency-name: ruff dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements/dev-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/dev-requirements.txt b/requirements/dev-requirements.txt index b0bf891b..0c3e5cad 100644 --- a/requirements/dev-requirements.txt +++ b/requirements/dev-requirements.txt @@ -136,7 +136,7 @@ requests==2.32.3 # -c requirements/requirements.txt # -c requirements/test-requirements.txt # sphinx -ruff==0.5.1 +ruff==0.5.4 # via -r requirements/dev-requirements.in six==1.16.0 # via From 1be2027cd62ed58275933cb759c1b4f3c59941bc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Jul 2024 21:11:54 +0000 Subject: [PATCH 10/36] Bump jsonschema from 4.22.0 to 4.23.0 Bumps [jsonschema](https://github.com/python-jsonschema/jsonschema) from 4.22.0 to 4.23.0. - [Release notes](https://github.com/python-jsonschema/jsonschema/releases) - [Changelog](https://github.com/python-jsonschema/jsonschema/blob/main/CHANGELOG.rst) - [Commits](https://github.com/python-jsonschema/jsonschema/compare/v4.22.0...v4.23.0) --- updated-dependencies: - dependency-name: jsonschema dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/requirements.txt b/requirements/requirements.txt index 51f09ee6..7ed52acd 100644 --- a/requirements/requirements.txt +++ b/requirements/requirements.txt @@ -121,7 +121,7 @@ importlib-resources==6.1.1 # jsonschema-specifications jsonapi-requests==0.7.0 # via -r requirements/requirements.in -jsonschema==4.22.0 +jsonschema==4.23.0 # via -r requirements/requirements.in jsonschema-specifications==2023.12.1 # via jsonschema From 3fec6d8e23e7b8e1d9aef598912e21800f27b9c8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Jul 2024 21:12:15 +0000 Subject: [PATCH 11/36] Bump django-crispy-forms from 2.2 to 2.3 Bumps [django-crispy-forms](https://github.com/django-crispy-forms/django-crispy-forms) from 2.2 to 2.3. - [Release notes](https://github.com/django-crispy-forms/django-crispy-forms/releases) - [Changelog](https://github.com/django-crispy-forms/django-crispy-forms/blob/main/CHANGELOG.md) - [Commits](https://github.com/django-crispy-forms/django-crispy-forms/compare/2.2...2.3) --- updated-dependencies: - dependency-name: django-crispy-forms dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/requirements.txt b/requirements/requirements.txt index 51f09ee6..357e60ef 100644 --- a/requirements/requirements.txt +++ b/requirements/requirements.txt @@ -68,7 +68,7 @@ django-autocomplete-light==3.11.0 # via django-anvil-consortium-manager django-constance==3.1.0 # via -r requirements/requirements.in -django-crispy-forms==2.2 +django-crispy-forms==2.3 # via # -r requirements/requirements.in # crispy-bootstrap5 From c4911a84f4e913d18fd846b7aafdf1be04572303 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Jul 2024 21:12:49 +0000 Subject: [PATCH 12/36] Bump sqlparse from 0.5.0 to 0.5.1 Bumps [sqlparse](https://github.com/andialbrecht/sqlparse) from 0.5.0 to 0.5.1. - [Changelog](https://github.com/andialbrecht/sqlparse/blob/master/CHANGELOG) - [Commits](https://github.com/andialbrecht/sqlparse/compare/0.5.0...0.5.1) --- updated-dependencies: - dependency-name: sqlparse dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements/dev-requirements.txt | 2 +- requirements/requirements.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/requirements/dev-requirements.txt b/requirements/dev-requirements.txt index b0bf891b..d67b398f 100644 --- a/requirements/dev-requirements.txt +++ b/requirements/dev-requirements.txt @@ -164,7 +164,7 @@ sphinxcontrib-qthelp==1.0.3 # via sphinx sphinxcontrib-serializinghtml==1.1.5 # via sphinx -sqlparse==0.5.0 +sqlparse==0.5.1 # via # -c requirements/requirements.txt # django diff --git a/requirements/requirements.txt b/requirements/requirements.txt index 51f09ee6..524c388e 100644 --- a/requirements/requirements.txt +++ b/requirements/requirements.txt @@ -203,7 +203,7 @@ rsa==4.9 # via google-auth six==1.16.0 # via python-dateutil -sqlparse==0.5.0 +sqlparse==0.5.1 # via # -r requirements/requirements.in # django From e813e0dc37e0ac1318a2fb66c78e389d9bea8273 Mon Sep 17 00:00:00 2001 From: Adrienne Stilp Date: Mon, 22 Jul 2024 16:14:32 -0700 Subject: [PATCH 13/36] Update certifi version in requirements file --- requirements/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/requirements.txt b/requirements/requirements.txt index e9b2e07a..62d86f02 100644 --- a/requirements/requirements.txt +++ b/requirements/requirements.txt @@ -22,7 +22,7 @@ build==1.0.3 # via pip-tools cachetools==5.3.2 # via google-auth -certifi==2023.11.17 +certifi==2024.07.04 # via # -r requirements/requirements.in # requests From 3e4ad4be63cc096af6a758e634b77bdc8aa9d88a Mon Sep 17 00:00:00 2001 From: Adrienne Stilp Date: Mon, 22 Jul 2024 16:14:55 -0700 Subject: [PATCH 14/36] Update zipp version in requirements file --- requirements/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/requirements.txt b/requirements/requirements.txt index 62d86f02..1e10ba5c 100644 --- a/requirements/requirements.txt +++ b/requirements/requirements.txt @@ -230,7 +230,7 @@ wheel==0.42.0 # via pip-tools whitenoise==6.7.0 # via -r requirements/requirements.in -zipp==3.17.0 +zipp==3.19.1 # via # importlib-metadata # importlib-resources From 8ada7c9d6f554d497f897b0849c1bc215be70f14 Mon Sep 17 00:00:00 2001 From: Adrienne Stilp Date: Mon, 22 Jul 2024 16:15:09 -0700 Subject: [PATCH 15/36] Remove temporary pinned versions from requirements.in file These were previously used to update packages for security requirements but are no longer necessary, because we can just update the requirements.txt file. --- requirements/requirements.in | 6 ------ 1 file changed, 6 deletions(-) diff --git a/requirements/requirements.in b/requirements/requirements.in index 5f17a1f3..1bfa2e34 100644 --- a/requirements/requirements.in +++ b/requirements/requirements.in @@ -67,12 +67,6 @@ tablib # for htmx django-htmx -# Temporary(?) pins to fix security alerts. -certifi>=2023.7.22 -urllib3>=2.2.2 -sqlparse>=0.4.4 -idna>=3.7 - # Dynamic settings django-constance django-picklefield # Required by django-constance for database backend From 4c16f3d487573b360a8ace2d868e71af509463aa Mon Sep 17 00:00:00 2001 From: Adrienne Stilp Date: Mon, 22 Jul 2024 16:39:14 -0700 Subject: [PATCH 16/36] Manually update .txt files For some reason, the github action to open a pull request is returning a 403 error. --- requirements/dev-requirements.txt | 4 ++-- requirements/test-requirements.txt | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/requirements/dev-requirements.txt b/requirements/dev-requirements.txt index 0363923c..cca12e52 100644 --- a/requirements/dev-requirements.txt +++ b/requirements/dev-requirements.txt @@ -20,7 +20,7 @@ backports-zoneinfo==0.2.1 # via # -c requirements/requirements.txt # django -certifi==2023.11.17 +certifi==2024.7.4 # via # -c requirements/requirements.txt # -c requirements/test-requirements.txt @@ -211,7 +211,7 @@ wcwidth==0.2.13 # via prompt-toolkit werkzeug==3.0.3 # via -r requirements/dev-requirements.in -zipp==3.17.0 +zipp==3.19.1 # via # -c requirements/requirements.txt # importlib-metadata diff --git a/requirements/test-requirements.txt b/requirements/test-requirements.txt index 23e457af..d9c8bd33 100644 --- a/requirements/test-requirements.txt +++ b/requirements/test-requirements.txt @@ -4,7 +4,7 @@ # # pip-compile requirements/test-requirements.in # -certifi==2023.11.17 +certifi==2024.7.4 # via # -c requirements/requirements.txt # requests From 1ac0bffb031a67c807082f37fec381a78d058693 Mon Sep 17 00:00:00 2001 From: Adrienne Stilp Date: Mon, 22 Jul 2024 16:44:23 -0700 Subject: [PATCH 17/36] Remove explicit permissions in workflow This is not needed in UW-GAC/gregor-django so something else must be going on. --- .github/workflows/pip-compile.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/pip-compile.yml b/.github/workflows/pip-compile.yml index 7391197f..131df4ff 100644 --- a/.github/workflows/pip-compile.yml +++ b/.github/workflows/pip-compile.yml @@ -6,8 +6,6 @@ on: jobs: update-requirements-files: - permissions: - pull-requests: write runs-on: ubuntu-latest steps: From 72576576b17cb2baaadf5856e90212a32451e2d7 Mon Sep 17 00:00:00 2001 From: Adrienne Stilp Date: Mon, 22 Jul 2024 16:46:41 -0700 Subject: [PATCH 18/36] More manual updates to requirements file --- requirements/requirements.txt | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/requirements/requirements.txt b/requirements/requirements.txt index 1e10ba5c..49710528 100644 --- a/requirements/requirements.txt +++ b/requirements/requirements.txt @@ -22,10 +22,8 @@ build==1.0.3 # via pip-tools cachetools==5.3.2 # via google-auth -certifi==2024.07.04 - # via - # -r requirements/requirements.in - # requests +certifi==2024.7.4 + # via requests cffi==1.16.0 # via # argon2-cffi-bindings @@ -110,9 +108,7 @@ fontawesomefree==6.5.1 google-auth==2.28.1 # via django-anvil-consortium-manager idna==3.7 - # via - # -r requirements/requirements.in - # requests + # via requests importlib-metadata==7.0.0 # via build importlib-resources==6.1.1 @@ -204,9 +200,7 @@ rsa==4.9 six==1.16.0 # via python-dateutil sqlparse==0.5.1 - # via - # -r requirements/requirements.in - # django + # via django tablib==3.6.1 # via -r requirements/requirements.in tenacity==8.2.3 @@ -223,9 +217,7 @@ typing-extensions==4.8.0 tzdata==2023.4 # via pandas urllib3==2.2.2 - # via - # -r requirements/requirements.in - # requests + # via requests wheel==0.42.0 # via pip-tools whitenoise==6.7.0 From eff28da06a0c4665511b2741303f00504c950141 Mon Sep 17 00:00:00 2001 From: Adrienne Stilp Date: Tue, 23 Jul 2024 10:38:56 -0700 Subject: [PATCH 19/36] Update CI for ubuntu-22.04 upgrade Change python version to 3.10 and mariadb version to 10.6. --- .github/workflows/ci.yml | 8 ++------ .github/workflows/pip-compile.yml | 4 ++-- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6062e39c..3d81f44b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -24,14 +24,10 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: [3.8] + python-version: [3.10] backend: ["sqlite", "mariadb"] - mariadb-version: ["10.4"] + mariadb-version: ["10.6"] include: - - python-version: "3.10" # Future ubuntu 22.04 upgrade. - backend: "mariadb" - mariadb-version: "10.6" - pip-recompile: true - python-version: 3.12 # Future ubuntu 24.04.01 upgrade. backend: "mariadb" mariadb-version: "10.11" diff --git a/.github/workflows/pip-compile.yml b/.github/workflows/pip-compile.yml index 131df4ff..cbca5c67 100644 --- a/.github/workflows/pip-compile.yml +++ b/.github/workflows/pip-compile.yml @@ -14,10 +14,10 @@ jobs: with: ref: ${{ github.head_ref }} - - name: Set up Python 3.8 + - name: Set up Python uses: actions/setup-python@v5 with: - python-version: 3.8 + python-version: 3.10 - name: Update requirements files uses: UW-GAC/pip-tools-actions/update-requirements-files@v0.1 From 87bef0ccf34ca351e20b876d885febcba9ee2be4 Mon Sep 17 00:00:00 2001 From: Adrienne Stilp Date: Tue, 23 Jul 2024 10:46:39 -0700 Subject: [PATCH 20/36] Add quotes around 3.10 in CI Otherwise, the python version is interested as 3.1 - not what we want. --- .github/workflows/ci.yml | 2 +- .github/workflows/pip-compile.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3d81f44b..8a71794b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -24,7 +24,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: [3.10] + python-version: ["3.10"] backend: ["sqlite", "mariadb"] mariadb-version: ["10.6"] include: diff --git a/.github/workflows/pip-compile.yml b/.github/workflows/pip-compile.yml index cbca5c67..24ef5430 100644 --- a/.github/workflows/pip-compile.yml +++ b/.github/workflows/pip-compile.yml @@ -17,7 +17,7 @@ jobs: - name: Set up Python uses: actions/setup-python@v5 with: - python-version: 3.10 + python-version: "3.10" - name: Update requirements files uses: UW-GAC/pip-tools-actions/update-requirements-files@v0.1 From 1f368e7d5b5176012166783ee3b16a0f808fe272 Mon Sep 17 00:00:00 2001 From: amstilp <3944584+amstilp@users.noreply.github.com> Date: Tue, 23 Jul 2024 17:47:55 +0000 Subject: [PATCH 21/36] Compile requirements files --- requirements/dev-requirements.txt | 19 +------------------ requirements/requirements.txt | 16 +--------------- requirements/test-requirements.txt | 3 +-- 3 files changed, 3 insertions(+), 35 deletions(-) diff --git a/requirements/dev-requirements.txt b/requirements/dev-requirements.txt index cca12e52..b22135a5 100644 --- a/requirements/dev-requirements.txt +++ b/requirements/dev-requirements.txt @@ -1,5 +1,5 @@ # -# This file is autogenerated by pip-compile with Python 3.8 +# This file is autogenerated by pip-compile with Python 3.10 # by the following command: # # pip-compile requirements/dev-requirements.in @@ -16,10 +16,6 @@ babel==2.14.0 # via sphinx backcall==0.2.0 # via ipython -backports-zoneinfo==0.2.1 - # via - # -c requirements/requirements.txt - # django certifi==2024.7.4 # via # -c requirements/requirements.txt @@ -67,10 +63,6 @@ idna==3.7 # requests imagesize==1.4.1 # via sphinx -importlib-metadata==7.0.0 - # via - # -c requirements/requirements.txt - # sphinx ipdb==0.13.13 # via -r requirements/dev-requirements.in ipython==8.12.3 @@ -123,10 +115,6 @@ pyparsing==3.1.1 # -c requirements/requirements.txt # -c requirements/test-requirements.txt # packaging -pytz==2023.3.post1 - # via - # -c requirements/requirements.txt - # babel pyyaml==6.0.1 # via # -c requirements/test-requirements.txt @@ -197,7 +185,6 @@ typing-extensions==4.8.0 # asgiref # django-stubs # django-stubs-ext - # ipython # mypy urllib3==2.2.2 # via @@ -211,10 +198,6 @@ wcwidth==0.2.13 # via prompt-toolkit werkzeug==3.0.3 # via -r requirements/dev-requirements.in -zipp==3.19.1 - # via - # -c requirements/requirements.txt - # importlib-metadata # The following packages are considered to be unsafe in a requirements file: # setuptools diff --git a/requirements/requirements.txt b/requirements/requirements.txt index 49710528..72c356d8 100644 --- a/requirements/requirements.txt +++ b/requirements/requirements.txt @@ -1,5 +1,5 @@ # -# This file is autogenerated by pip-compile with Python 3.8 +# This file is autogenerated by pip-compile with Python 3.10 # by the following command: # # pip-compile requirements/requirements.in @@ -16,8 +16,6 @@ attrs==23.2.0 # via # jsonschema # referencing -backports-zoneinfo==0.2.1 - # via django build==1.0.3 # via pip-tools cachetools==5.3.2 @@ -109,12 +107,6 @@ google-auth==2.28.1 # via django-anvil-consortium-manager idna==3.7 # via requests -importlib-metadata==7.0.0 - # via build -importlib-resources==6.1.1 - # via - # jsonschema - # jsonschema-specifications jsonapi-requests==0.7.0 # via -r requirements/requirements.in jsonschema==4.23.0 @@ -143,8 +135,6 @@ pandas==2.0.3 # via -r requirements/requirements.in pip-tools==7.4.1 # via -r requirements/requirements.in -pkgutil-resolve-name==1.3.10 - # via jsonschema plotly==5.19.0 # via django-anvil-consortium-manager pronto==2.5.7 @@ -222,10 +212,6 @@ wheel==0.42.0 # via pip-tools whitenoise==6.7.0 # via -r requirements/requirements.in -zipp==3.19.1 - # via - # importlib-metadata - # importlib-resources # The following packages are considered to be unsafe in a requirements file: # pip diff --git a/requirements/test-requirements.txt b/requirements/test-requirements.txt index d9c8bd33..d70de058 100644 --- a/requirements/test-requirements.txt +++ b/requirements/test-requirements.txt @@ -1,5 +1,5 @@ # -# This file is autogenerated by pip-compile with Python 3.8 +# This file is autogenerated by pip-compile with Python 3.10 # by the following command: # # pip-compile requirements/test-requirements.in @@ -96,7 +96,6 @@ typing-extensions==4.8.0 # via # -c requirements/requirements.txt # django-test-migrations - # faker urllib3==2.2.2 # via # -c requirements/requirements.txt From 3fc1bf188999a9c175e47cb15c441bbaa4ae49d2 Mon Sep 17 00:00:00 2001 From: Adrienne Stilp Date: Fri, 26 Jul 2024 09:23:08 -0700 Subject: [PATCH 22/36] Fix badge for consortium members with data access The badge next to the consortium members with data access is using the wrong table; use the correct table to calculate the count to show in the badge. --- primed/templates/primed_anvil/studysite_detail.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/primed/templates/primed_anvil/studysite_detail.html b/primed/templates/primed_anvil/studysite_detail.html index 5f702061..d0535516 100644 --- a/primed/templates/primed_anvil/studysite_detail.html +++ b/primed/templates/primed_anvil/studysite_detail.html @@ -60,7 +60,7 @@

From c4d34adb97007df2d4a71fccc5bc7e7f47db24be Mon Sep 17 00:00:00 2001 From: Adrienne Stilp Date: Fri, 26 Jul 2024 14:27:53 -0700 Subject: [PATCH 23/36] Only show active users in UserAutocomplete --- primed/users/tests/test_views.py | 11 +++++++++++ primed/users/views.py | 4 +++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/primed/users/tests/test_views.py b/primed/users/tests/test_views.py index 98e9d6b3..9e499f86 100644 --- a/primed/users/tests/test_views.py +++ b/primed/users/tests/test_views.py @@ -723,6 +723,17 @@ def test_get_selected_result_label(self): view.setup(request) self.assertEqual(view.get_selected_result_label(instance), "First Last (foo@bar.com)") + def test_excludes_inactive_users(self): + """Queryset excludes excludes inactive users.""" + UserFactory.create(is_active=False) + request = self.factory.get(self.get_url()) + request.user = self.user + response = self.get_view()(request) + returned_ids = [int(x["id"]) for x in json.loads(response.content.decode("utf-8"))["results"]] + # Only test user. + self.assertEqual(len(returned_ids), 1) + self.assertEqual(returned_ids, [self.user.pk]) + class UserLookup(TestCase): """Test for UserLookup view""" diff --git a/primed/users/views.py b/primed/users/views.py index 26458b59..606264b5 100644 --- a/primed/users/views.py +++ b/primed/users/views.py @@ -67,7 +67,9 @@ def get_result_label(self, result): def get_queryset(self): """Filter to users matching the query.""" - qs = User.objects.all().order_by("username") + qs = User.objects.filter( + is_active=True, + ).order_by("username") if self.q: # Filter to users whose name or email matches the query. From a26892fb708a312f80028983738adf242da2231a Mon Sep 17 00:00:00 2001 From: Adrienne Stilp Date: Fri, 26 Jul 2024 14:32:08 -0700 Subject: [PATCH 24/36] Use only active users for UserLookupForm queryset --- primed/users/forms.py | 2 +- primed/users/tests/test_forms.py | 13 +++++++++++++ primed/users/tests/test_views.py | 18 ++++++++++++++++++ 3 files changed, 32 insertions(+), 1 deletion(-) diff --git a/primed/users/forms.py b/primed/users/forms.py index 2ea6f0a3..b9431c62 100644 --- a/primed/users/forms.py +++ b/primed/users/forms.py @@ -24,7 +24,7 @@ class UserLookupForm(Bootstrap5MediaFormMixin, forms.Form): """Form for the user lookup""" user = forms.ModelChoiceField( - queryset=User.objects.all(), + queryset=User.objects.filter(is_active=True), widget=autocomplete.ModelSelect2( url="users:autocomplete", attrs={"data-theme": "bootstrap-5"}, diff --git a/primed/users/tests/test_forms.py b/primed/users/tests/test_forms.py index 81fe9d9b..0631302b 100644 --- a/primed/users/tests/test_forms.py +++ b/primed/users/tests/test_forms.py @@ -63,3 +63,16 @@ def test_invalid_missing_name(self): self.assertIn("user", form.errors) self.assertEqual(len(form.errors["user"]), 1) self.assertIn("required", form.errors["user"][0]) + + def test_inactive_user(self): + """Form is invalid when user is inactive.""" + user_obj = UserFactory.create(is_active=False) + form_data = { + "user": user_obj, + } + form = self.form_class(data=form_data) + self.assertFalse(form.is_valid()) + self.assertEqual(len(form.errors), 1) + self.assertIn("user", form.errors) + self.assertEqual(len(form.errors["user"]), 1) + self.assertIn("valid choice", form.errors["user"][0]) diff --git a/primed/users/tests/test_views.py b/primed/users/tests/test_views.py index 9e499f86..f92d64bf 100644 --- a/primed/users/tests/test_views.py +++ b/primed/users/tests/test_views.py @@ -810,3 +810,21 @@ def test_blank_user(self): self.assertIn("user", form.errors.keys()) self.assertEqual(len(form.errors["user"]), 1) self.assertIn("required", form.errors["user"][0]) + + def test_invalid_inactive_user(self): + """Form is invalid with an inactive user.""" + object = UserFactory.create( + username="user1", + password="passwd", + email="user1@example.com", + is_active=False, + ) + self.client.force_login(self.user) + response = self.client.post(self.get_url(), {"user": object.pk}) + self.assertEqual(response.status_code, 200) + form = response.context_data["form"] + self.assertFalse(form.is_valid()) + self.assertEqual(len(form.errors), 1) + self.assertIn("user", form.errors) + self.assertEqual(len(form.errors["user"]), 1) + self.assertIn("valid choice", form.errors["user"][0]) From 8879b325388760f5ad70a122f73779c8839be80f Mon Sep 17 00:00:00 2001 From: Adrienne Stilp Date: Fri, 26 Jul 2024 14:57:02 -0700 Subject: [PATCH 25/36] Show an alert on the User profile page if user is inactive --- primed/templates/users/user_detail.html | 9 +++++++++ primed/users/tests/test_views.py | 15 +++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/primed/templates/users/user_detail.html b/primed/templates/users/user_detail.html index 75163ead..010f15aa 100644 --- a/primed/templates/users/user_detail.html +++ b/primed/templates/users/user_detail.html @@ -6,6 +6,15 @@ {% block content %}
+ {% if not object.is_active %} + +

+ + This user is inactive. +

+ + {% endif %} +
diff --git a/primed/users/tests/test_views.py b/primed/users/tests/test_views.py index f92d64bf..a51a6c87 100644 --- a/primed/users/tests/test_views.py +++ b/primed/users/tests/test_views.py @@ -574,6 +574,21 @@ def test_acm_staff_view(self): self.assertIn(agreement_1.signed_agreement, response.context["signed_agreements"]) self.assertIn(agreement_2.signed_agreement, response.context["signed_agreements"]) + def test_inactive_user_inactive_message(self): + """Inactive user alert is shown for an inactive user.""" + user = UserFactory.create(is_active=False) + self.client.force_login(self.user) + response = self.client.get(user.get_absolute_url()) + self.assertEqual(response.status_code, 200) + self.assertContains(response, "This user is inactive.") + + def test_active_user_no_inactive_message(self): + """Inactive user alert is not shown for an active user.""" + self.client.force_login(self.user) + response = self.client.get(self.user.get_absolute_url()) + self.assertEqual(response.status_code, 200) + self.assertNotContains(response, "This user is inactive.") + class UserAutocompleteTest(TestCase): def setUp(self): From e62adf5e44510a232c08966e0207d73098841ead Mon Sep 17 00:00:00 2001 From: Adrienne Stilp Date: Fri, 26 Jul 2024 15:08:06 -0700 Subject: [PATCH 26/36] Show an alert if a user's AnVIL account is inactive --- primed/templates/users/user_detail.html | 6 ++++++ primed/users/tests/test_views.py | 18 ++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/primed/templates/users/user_detail.html b/primed/templates/users/user_detail.html index 010f15aa..8656778f 100644 --- a/primed/templates/users/user_detail.html +++ b/primed/templates/users/user_detail.html @@ -74,6 +74,12 @@
Account Email
{% else %} {{ object.account.email }} {% endif %} + {% if not object.account.status %} +

+ + This account is inactive. +

+ {% endif %} {% if object.account.verified_email_entry %}
  • diff --git a/primed/users/tests/test_views.py b/primed/users/tests/test_views.py index a51a6c87..a03da768 100644 --- a/primed/users/tests/test_views.py +++ b/primed/users/tests/test_views.py @@ -589,6 +589,24 @@ def test_active_user_no_inactive_message(self): self.assertEqual(response.status_code, 200) self.assertNotContains(response, "This user is inactive.") + def test_inactive_anvil_account_alert_is_inactive(self): + """Alert is shown when AnVIL account is inactive.""" + account = AccountFactory.create(email="foo@bar.com", user=self.user, verified=True) + account.status = account.INACTIVE_STATUS + account.save() + self.client.force_login(self.user) + response = self.client.get(self.user.get_absolute_url()) + self.assertEqual(response.status_code, 200) + self.assertContains(response, "This account is inactive.") + + def test_inactive_anvil_account_alert_is_active(self): + """Alert is not shown when AnVIL account is active.""" + AccountFactory.create(email="foo@bar.com", user=self.user, verified=True) + self.client.force_login(self.user) + response = self.client.get(self.user.get_absolute_url()) + self.assertEqual(response.status_code, 200) + self.assertNotContains(response, "This account is inactive.") + class UserAutocompleteTest(TestCase): def setUp(self): From 6b3c542889dec4c97e3a03b9ae92abcdb67cbcb4 Mon Sep 17 00:00:00 2001 From: Adrienne Stilp Date: Fri, 26 Jul 2024 15:16:51 -0700 Subject: [PATCH 27/36] Change inactive alerts to have a "danger" background They stand out a little more this way. --- primed/templates/users/user_detail.html | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/primed/templates/users/user_detail.html b/primed/templates/users/user_detail.html index 8656778f..54e2bf19 100644 --- a/primed/templates/users/user_detail.html +++ b/primed/templates/users/user_detail.html @@ -8,7 +8,7 @@ {% if not object.is_active %} -

    +

    This user is inactive.

    @@ -66,6 +66,14 @@

    {% if object == request.user %}My{% else %}
    {% if object.account %}

    Profile has a linked AnVIL account established

    + + {% if not object.account.status %} +

    + + This account is inactive. +

    + {% endif %} +
    • Account Email
      @@ -74,12 +82,6 @@
      Account Email
      {% else %} {{ object.account.email }} {% endif %} - {% if not object.account.status %} -

      - - This account is inactive. -

      - {% endif %}
    • {% if object.account.verified_email_entry %}
    • From 25bda1774ba31fac782e368ecfd975639ed19f24 Mon Sep 17 00:00:00 2001 From: Adrienne Stilp Date: Fri, 26 Jul 2024 15:24:51 -0700 Subject: [PATCH 28/36] Make the account link alert dismissable It will come back on the next page you load but that's ok. --- primed/templates/base.html | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/primed/templates/base.html b/primed/templates/base.html index 1789536c..946a0aa3 100644 --- a/primed/templates/base.html +++ b/primed/templates/base.html @@ -28,8 +28,8 @@ {# Placed at the top of the document so pages load faster with defer #} {% block javascript %} - + @@ -119,9 +119,10 @@ {% endif %} {% if request.user.is_authenticated and not request.user.account %} -
    • - Phenotype inventory + Inventory inputs
    • diff --git a/primed/templates/primed_anvil/phenotype_inventory_inputs.html b/primed/templates/primed_anvil/inventory_inputs.html similarity index 93% rename from primed/templates/primed_anvil/phenotype_inventory_inputs.html rename to primed/templates/primed_anvil/inventory_inputs.html index 7dc372ce..697b5cc6 100644 --- a/primed/templates/primed_anvil/phenotype_inventory_inputs.html +++ b/primed/templates/primed_anvil/inventory_inputs.html @@ -11,7 +11,7 @@

      Phenotype inventory workflow

      This page creates the input for the "workspaces" field in the - PRIMED phenotype inventory workflow. + PRIMED phenotype inventory workflow. Copy the text in the box below and paste it into the "workspaces" field when running the workflow on AnVIL.