From de87f0c7730634f9449cad64d1d3648fbec822d2 Mon Sep 17 00:00:00 2001 From: Erin <121973038+erinysong@users.noreply.github.com> Date: Wed, 11 Oct 2023 11:59:52 -0700 Subject: [PATCH 1/5] Add domain invitation permissions to analyst --- docs/django-admin/roles.md | 5 +-- .../migrations/0038_create_groups_v02.py | 36 +++++++++++++++++++ src/registrar/models/user_group.py | 5 +++ src/registrar/tests/test_migrations.py | 4 ++- 4 files changed, 47 insertions(+), 3 deletions(-) create mode 100644 src/registrar/migrations/0038_create_groups_v02.py diff --git a/docs/django-admin/roles.md b/docs/django-admin/roles.md index 91c2949eb..458029e07 100644 --- a/docs/django-admin/roles.md +++ b/docs/django-admin/roles.md @@ -13,7 +13,8 @@ For more details, refer to the [user group model](../../src/registrar/models/use We can edit and deploy new group permissions by: -1. editing `user_group` then: +1. Editing `user_group` then: 2. Duplicating migration `0036_create_groups_01` and running migrations (append the name with a version number -to help django detect the migration eg 0037_create_groups_02) \ No newline at end of file +to help django detect the migration eg 0037_create_groups_02) +3. Making sure to update the dependency on the new migration with the previous migration \ No newline at end of file diff --git a/src/registrar/migrations/0038_create_groups_v02.py b/src/registrar/migrations/0038_create_groups_v02.py new file mode 100644 index 000000000..80752f31a --- /dev/null +++ b/src/registrar/migrations/0038_create_groups_v02.py @@ -0,0 +1,36 @@ +# This migration creates the create_full_access_group and create_cisa_analyst_group groups +# It is dependent on 0035 (which populates ContentType and Permissions) +# If permissions on the groups need changing, edit CISA_ANALYST_GROUP_PERMISSIONS +# in the user_group model then: +# [NOT RECOMMENDED] +# step 1: docker-compose exec app ./manage.py migrate --fake registrar 0035_contenttypes_permissions +# step 2: docker-compose exec app ./manage.py migrate registrar 0036_create_groups +# step 3: fake run the latest migration in the migrations list +# [RECOMMENDED] +# Alternatively: +# Only step: duplicate the migration that loads data and run: docker-compose exec app ./manage.py migrate + +from django.db import migrations +from registrar.models import UserGroup +from typing import Any + + +# For linting: RunPython expects a function reference, +# so let's give it one +def create_groups(apps, schema_editor) -> Any: + UserGroup.create_cisa_analyst_group(apps, schema_editor) + UserGroup.create_full_access_group(apps, schema_editor) + + +class Migration(migrations.Migration): + dependencies = [ + ("registrar", "0037_create_groups_v01"), + ] + + operations = [ + migrations.RunPython( + create_groups, + reverse_code=migrations.RunPython.noop, + atomic=True, + ), + ] diff --git a/src/registrar/models/user_group.py b/src/registrar/models/user_group.py index b6f5b41b2..5cdb1f2ec 100644 --- a/src/registrar/models/user_group.py +++ b/src/registrar/models/user_group.py @@ -51,6 +51,11 @@ class UserGroup(Group): "model": "user", "permissions": ["analyst_access_permission", "change_user"], }, + { + "app_label": "registrar", + "model": "domaininvitation", + "permissions": ["add_domaininvitation", "view_domaininvitation"], + }, ] # Avoid error: You can't execute queries until the end diff --git a/src/registrar/tests/test_migrations.py b/src/registrar/tests/test_migrations.py index f98e876d7..14ab36e70 100644 --- a/src/registrar/tests/test_migrations.py +++ b/src/registrar/tests/test_migrations.py @@ -31,7 +31,7 @@ class TestGroups(TestCase): UserGroup.objects.filter(name="full_access_group"), [full_access_group] ) - # Test permissions for cisa_analysts_group + # Test permissions data migrations for cisa_analysts_group ran as expected # Define the expected permission codenames expected_permissions = [ "view_logentry", @@ -42,6 +42,8 @@ class TestGroups(TestCase): "change_draftdomain", "analyst_access_permission", "change_user", + "add_domaininvitation", + "view_domaininvitation" ] # Get the codenames of actual permissions associated with the group From 67dacffa9f3bdf51dd51c040da944d5f53ec90b9 Mon Sep 17 00:00:00 2001 From: Erin <121973038+erinysong@users.noreply.github.com> Date: Wed, 11 Oct 2023 12:01:06 -0700 Subject: [PATCH 2/5] Update 0037_create_groups_v01 migration documentation --- src/registrar/migrations/0037_create_groups_v01.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/registrar/migrations/0037_create_groups_v01.py b/src/registrar/migrations/0037_create_groups_v01.py index 27a14f8b9..69a4c02aa 100644 --- a/src/registrar/migrations/0037_create_groups_v01.py +++ b/src/registrar/migrations/0037_create_groups_v01.py @@ -2,11 +2,13 @@ # It is dependent on 0035 (which populates ContentType and Permissions) # If permissions on the groups need changing, edit CISA_ANALYST_GROUP_PERMISSIONS # in the user_group model then: +# [NOT RECOMMENDED] # step 1: docker-compose exec app ./manage.py migrate --fake registrar 0035_contenttypes_permissions # step 2: docker-compose exec app ./manage.py migrate registrar 0036_create_groups # step 3: fake run the latest migration in the migrations list +# [RECOMMENDED] # Alternatively: -# Only step: duplicate the migtation that loads data and run: docker-compose exec app ./manage.py migrate +# Only step: duplicate the migration that loads data and run: docker-compose exec app ./manage.py migrate from django.db import migrations from registrar.models import UserGroup From ecc4d6c89eaaeb7a87ba1d87c66e6369f034effb Mon Sep 17 00:00:00 2001 From: Erin <121973038+erinysong@users.noreply.github.com> Date: Thu, 12 Oct 2023 09:56:18 -0700 Subject: [PATCH 3/5] Run linter and formatting changes --- src/registrar/admin.py | 6 ++++++ src/registrar/migrations/0037_create_groups_v01.py | 3 ++- src/registrar/migrations/0038_create_groups_v02.py | 3 ++- src/registrar/tests/test_migrations.py | 5 +++-- 4 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/registrar/admin.py b/src/registrar/admin.py index 174500f28..8d0ed8c2e 100644 --- a/src/registrar/admin.py +++ b/src/registrar/admin.py @@ -342,6 +342,12 @@ class DomainInvitationAdmin(ListHeaderAdmin): ] search_help_text = "Search by email or domain." + # Mark the FSM field 'status' as readonly + # to allow admin users to create Domain Invitations + # without triggering the FSM Transition Not Allowed + # error. + readonly_fields = ["status"] + class DomainInformationAdmin(ListHeaderAdmin): """Customize domain information admin class.""" diff --git a/src/registrar/migrations/0037_create_groups_v01.py b/src/registrar/migrations/0037_create_groups_v01.py index 69a4c02aa..3540ea2f3 100644 --- a/src/registrar/migrations/0037_create_groups_v01.py +++ b/src/registrar/migrations/0037_create_groups_v01.py @@ -8,7 +8,8 @@ # step 3: fake run the latest migration in the migrations list # [RECOMMENDED] # Alternatively: -# Only step: duplicate the migration that loads data and run: docker-compose exec app ./manage.py migrate +# step 1: duplicate the migration that loads data +# step 2: docker-compose exec app ./manage.py migrate from django.db import migrations from registrar.models import UserGroup diff --git a/src/registrar/migrations/0038_create_groups_v02.py b/src/registrar/migrations/0038_create_groups_v02.py index 80752f31a..fc61db3c0 100644 --- a/src/registrar/migrations/0038_create_groups_v02.py +++ b/src/registrar/migrations/0038_create_groups_v02.py @@ -8,7 +8,8 @@ # step 3: fake run the latest migration in the migrations list # [RECOMMENDED] # Alternatively: -# Only step: duplicate the migration that loads data and run: docker-compose exec app ./manage.py migrate +# step 1: duplicate the migration that loads data +# step 2: docker-compose exec app ./manage.py migrate from django.db import migrations from registrar.models import UserGroup diff --git a/src/registrar/tests/test_migrations.py b/src/registrar/tests/test_migrations.py index 14ab36e70..2ea1962a1 100644 --- a/src/registrar/tests/test_migrations.py +++ b/src/registrar/tests/test_migrations.py @@ -31,7 +31,8 @@ class TestGroups(TestCase): UserGroup.objects.filter(name="full_access_group"), [full_access_group] ) - # Test permissions data migrations for cisa_analysts_group ran as expected + # Test data migrations for cisa_analysts_group permission + # ran as expected. # Define the expected permission codenames expected_permissions = [ "view_logentry", @@ -43,7 +44,7 @@ class TestGroups(TestCase): "analyst_access_permission", "change_user", "add_domaininvitation", - "view_domaininvitation" + "view_domaininvitation", ] # Get the codenames of actual permissions associated with the group From bd1b5654ef0d6a8d328a338c46b480184198b358 Mon Sep 17 00:00:00 2001 From: Erin <121973038+erinysong@users.noreply.github.com> Date: Thu, 12 Oct 2023 10:25:54 -0700 Subject: [PATCH 4/5] Modify test case to reflect order of expected permissions --- src/registrar/tests/test_migrations.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/registrar/tests/test_migrations.py b/src/registrar/tests/test_migrations.py index 2ea1962a1..0b71f3bf6 100644 --- a/src/registrar/tests/test_migrations.py +++ b/src/registrar/tests/test_migrations.py @@ -40,11 +40,11 @@ class TestGroups(TestCase): "view_domain", "change_domainapplication", "change_domaininformation", + "add_domaininvitation", + "view_domaininvitation", "change_draftdomain", "analyst_access_permission", "change_user", - "add_domaininvitation", - "view_domaininvitation", ] # Get the codenames of actual permissions associated with the group From 02c929ddd391b357a5fbb608e5ae087b68d5ecc4 Mon Sep 17 00:00:00 2001 From: Erin <121973038+erinysong@users.noreply.github.com> Date: Thu, 12 Oct 2023 10:34:08 -0700 Subject: [PATCH 5/5] Implement format feedback --- src/registrar/tests/test_migrations.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/registrar/tests/test_migrations.py b/src/registrar/tests/test_migrations.py index 0b71f3bf6..95e5853ff 100644 --- a/src/registrar/tests/test_migrations.py +++ b/src/registrar/tests/test_migrations.py @@ -31,8 +31,8 @@ class TestGroups(TestCase): UserGroup.objects.filter(name="full_access_group"), [full_access_group] ) - # Test data migrations for cisa_analysts_group permission - # ran as expected. + # Test permissions for cisa_analysts_group + # Verifies permission data migrations ran as expected. # Define the expected permission codenames expected_permissions = [ "view_logentry",