diff --git a/src/registrar/admin.py b/src/registrar/admin.py index 9514c569d..e4990ed60 100644 --- a/src/registrar/admin.py +++ b/src/registrar/admin.py @@ -1909,6 +1909,43 @@ class DraftDomainAdmin(ListHeaderAdmin): # in autocomplete_fields for user ordering = ["name"] + def get_model_perms(self, request): + """ + Return empty perms dict thus hiding the model from admin index. + """ + superuser_perm = request.user.has_perm("registrar.full_access_permission") + analyst_perm = request.user.has_perm("registrar.analyst_access_permission") + if analyst_perm and not superuser_perm: + return {} + return super().get_model_perms(request) + + def has_change_permission(self, request, obj=None): + """ + Allow analysts to access the change form directly via URL. + """ + superuser_perm = request.user.has_perm("registrar.full_access_permission") + analyst_perm = request.user.has_perm("registrar.analyst_access_permission") + if analyst_perm and not superuser_perm: + return True + return super().has_change_permission(request, obj) + + def response_change(self, request, obj): + """ + Override to redirect users back to the same page after saving. + """ + superuser_perm = request.user.has_perm("registrar.full_access_permission") + analyst_perm = request.user.has_perm("registrar.analyst_access_permission") + + # Don't redirect to the website page on save if the user is an analyst. + # Rather, just redirect back to the same change page. + if analyst_perm and not superuser_perm: + opts = obj._meta + pk_value = obj._get_pk_val() + return HttpResponseRedirect( + reverse("admin:%s_%s_change" % (opts.app_label, opts.model_name), args=(pk_value,)) + ) + return super().response_change(request, obj) + class VerifiedByStaffAdmin(ListHeaderAdmin): list_display = ("email", "requestor", "truncated_notes", "created_at") diff --git a/src/registrar/tests/test_admin.py b/src/registrar/tests/test_admin.py index 81bf2736b..74f4ba60e 100644 --- a/src/registrar/tests/test_admin.py +++ b/src/registrar/tests/test_admin.py @@ -19,7 +19,16 @@ from registrar.admin import ( UserDomainRoleAdmin, VerifiedByStaffAdmin, ) -from registrar.models import Domain, DomainRequest, DomainInformation, User, DomainInvitation, Contact, Website +from registrar.models import ( + Domain, + DomainRequest, + DomainInformation, + User, + DomainInvitation, + Contact, + Website, + DraftDomain, +) from registrar.models.user_domain_role import UserDomainRole from registrar.models.verified_by_staff import VerifiedByStaff from .common import ( @@ -702,8 +711,8 @@ class TestDomainRequestAdmin(MockEppLib): self.mock_client = MockSESClient() @less_console_noise_decorator - def test_analyst_can_see_alternative_domain(self): - """Tests if an analyst can still see the alternative domain field""" + def test_analyst_can_see_and_edit_alternative_domain(self): + """Tests if an analyst can still see and edit the alternative domain field""" # Create fake creator _creator = User.objects.create( @@ -747,6 +756,48 @@ class TestDomainRequestAdmin(MockEppLib): self.assertEqual(response.status_code, 200) self.assertContains(response, "thisisatest.gov") + @less_console_noise_decorator + def test_analyst_can_see_and_edit_requested_domain(self): + """Tests if an analyst can still see and edit the requested domain field""" + + # Create fake creator + _creator = User.objects.create( + username="MrMeoward", + first_name="Meoward", + last_name="Jones", + ) + + # Create a fake domain request + _domain_request = completed_domain_request(status=DomainRequest.DomainRequestStatus.IN_REVIEW, user=_creator) + + p = "userpass" + self.client.login(username="staffuser", password=p) + response = self.client.get( + "/admin/registrar/domainrequest/{}/change/".format(_domain_request.pk), + follow=True, + ) + + # Filter to get the latest from the DB (rather than direct assignment) + requested_domain = DraftDomain.objects.filter(name=_domain_request.requested_domain.name).get() + + # Make sure the page loaded, and that we're on the right page + self.assertEqual(response.status_code, 200) + self.assertContains(response, requested_domain.name) + + # Check that the page contains the url we expect + expected_href = reverse("admin:registrar_draftdomain_change", args=[requested_domain.id]) + self.assertContains(response, expected_href) + + # Navigate to the website to ensure that we can still edit it + response = self.client.get( + "/admin/registrar/draftdomain/{}/change/".format(requested_domain.pk), + follow=True, + ) + + # Make sure the page loaded, and that we're on the right page + self.assertEqual(response.status_code, 200) + self.assertContains(response, "city.gov") + @less_console_noise_decorator def test_analyst_can_see_current_websites(self): """Tests if an analyst can still see current website field"""