mirror of
https://github.com/cisagov/manage.get.gov.git
synced 2025-07-25 12:08:40 +02:00
Merge branch 'main' into nl/3275-slowness-admin-tables
This commit is contained in:
commit
0881cf2fc6
13 changed files with 99 additions and 5 deletions
|
@ -9,6 +9,7 @@ from django.utils import timezone
|
|||
from registrar.models.domain import Domain
|
||||
from registrar.models.federal_agency import FederalAgency
|
||||
from registrar.models.utility.generic_helper import CreateOrUpdateOrganizationTypeHelper
|
||||
from registrar.models.utility.portfolio_helper import UserPortfolioPermissionChoices
|
||||
from registrar.utility.errors import FSMDomainRequestError, FSMErrorCodes
|
||||
from registrar.utility.constants import BranchChoices
|
||||
from auditlog.models import LogEntry
|
||||
|
@ -903,6 +904,7 @@ class DomainRequest(TimeStampedModel):
|
|||
email_template,
|
||||
email_template_subject,
|
||||
bcc_address="",
|
||||
cc_addresses: list[str] = [],
|
||||
context=None,
|
||||
send_email=True,
|
||||
wrap_email=False,
|
||||
|
@ -955,12 +957,20 @@ class DomainRequest(TimeStampedModel):
|
|||
|
||||
if custom_email_content:
|
||||
context["custom_email_content"] = custom_email_content
|
||||
|
||||
if self.requesting_entity_is_portfolio() or self.requesting_entity_is_suborganization():
|
||||
portfolio_view_requests_users = self.portfolio.portfolio_users_with_permissions( # type: ignore
|
||||
permissions=[UserPortfolioPermissionChoices.VIEW_ALL_REQUESTS], include_admin=True
|
||||
)
|
||||
cc_addresses = list(portfolio_view_requests_users.values_list("email", flat=True))
|
||||
|
||||
send_templated_email(
|
||||
email_template,
|
||||
email_template_subject,
|
||||
recipient.email,
|
||||
context=context,
|
||||
bcc_address=bcc_address,
|
||||
cc_addresses=cc_addresses,
|
||||
wrap_email=wrap_email,
|
||||
)
|
||||
logger.info(f"The {new_status} email sent to: {recipient.email}")
|
||||
|
|
|
@ -4,6 +4,7 @@ from registrar.models.domain_request import DomainRequest
|
|||
from registrar.models.federal_agency import FederalAgency
|
||||
from registrar.models.user import User
|
||||
from registrar.models.utility.portfolio_helper import UserPortfolioRoleChoices
|
||||
from django.db.models import Q
|
||||
|
||||
from .utility.time_stamped_model import TimeStampedModel
|
||||
|
||||
|
@ -144,6 +145,25 @@ class Portfolio(TimeStampedModel):
|
|||
).values_list("user__id", flat=True)
|
||||
return User.objects.filter(id__in=admin_ids)
|
||||
|
||||
def portfolio_users_with_permissions(self, permissions=[], include_admin=False):
|
||||
"""Gets all users with specified additional permissions for this particular portfolio.
|
||||
Returns a queryset of User."""
|
||||
portfolio_users = self.portfolio_users
|
||||
if permissions:
|
||||
if include_admin:
|
||||
portfolio_users = portfolio_users.filter(
|
||||
Q(additional_permissions__overlap=permissions)
|
||||
| Q(
|
||||
roles__overlap=[
|
||||
UserPortfolioRoleChoices.ORGANIZATION_ADMIN,
|
||||
]
|
||||
),
|
||||
)
|
||||
else:
|
||||
portfolio_users = portfolio_users.filter(additional_permissions__overlap=permissions)
|
||||
user_ids = portfolio_users.values_list("user__id", flat=True)
|
||||
return User.objects.filter(id__in=user_ids)
|
||||
|
||||
# == Getters for domains == #
|
||||
def get_domains(self, order_by=None):
|
||||
"""Returns all DomainInformations associated with this portfolio"""
|
||||
|
|
|
@ -4,6 +4,7 @@ Hi, {{ recipient.first_name }}.
|
|||
We've identified an action that you’ll need to complete before we continue reviewing your .gov domain request.
|
||||
|
||||
DOMAIN REQUESTED: {{ domain_request.requested_domain.name }}
|
||||
REQUESTED BY: {{ domain_request.creator.email }}
|
||||
REQUEST RECEIVED ON: {{ domain_request.last_submitted_date|date }}
|
||||
STATUS: Action needed
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ Hi, {{ recipient.first_name }}.
|
|||
We've identified an action that you’ll need to complete before we continue reviewing your .gov domain request.
|
||||
|
||||
DOMAIN REQUESTED: {{ domain_request.requested_domain.name }}
|
||||
REQUESTED BY: {{ domain_request.creator.email }}
|
||||
REQUEST RECEIVED ON: {{ domain_request.last_submitted_date|date }}
|
||||
STATUS: Action needed
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ Hi, {{ recipient.first_name }}.
|
|||
We've identified an action that you’ll need to complete before we continue reviewing your .gov domain request.
|
||||
|
||||
DOMAIN REQUESTED: {{ domain_request.requested_domain.name }}
|
||||
REQUESTED BY: {{ domain_request.creator.email }}
|
||||
REQUEST RECEIVED ON: {{ domain_request.last_submitted_date|date }}
|
||||
STATUS: Action needed
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ Hi, {{ recipient.first_name }}.
|
|||
We've identified an action that you’ll need to complete before we continue reviewing your .gov domain request.
|
||||
|
||||
DOMAIN REQUESTED: {{ domain_request.requested_domain.name }}
|
||||
REQUESTED BY: {{ domain_request.creator.email }}
|
||||
REQUEST RECEIVED ON: {{ domain_request.last_submitted_date|date }}
|
||||
STATUS: Action needed
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ Hi, {{ recipient.first_name }}.
|
|||
Your .gov domain request has been withdrawn and will not be reviewed by our team.
|
||||
|
||||
DOMAIN REQUESTED: {{ domain_request.requested_domain.name }}
|
||||
REQUESTED BY: {{ domain_request.creator.email }}
|
||||
REQUEST RECEIVED ON: {{ domain_request.last_submitted_date|date }}
|
||||
STATUS: Withdrawn
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ Hi, {{ recipient.first_name }}.
|
|||
Congratulations! Your .gov domain request has been approved.
|
||||
|
||||
DOMAIN REQUESTED: {{ domain_request.requested_domain.name }}
|
||||
REQUESTED BY: {{ domain_request.creator.email }}
|
||||
REQUEST RECEIVED ON: {{ domain_request.last_submitted_date|date }}
|
||||
STATUS: Approved
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ Hi, {{ recipient.first_name }}.
|
|||
Your .gov domain request has been rejected.
|
||||
|
||||
DOMAIN REQUESTED: {{ domain_request.requested_domain.name }}
|
||||
REQUESTED BY: {{ domain_request.creator.email }}
|
||||
REQUEST RECEIVED ON: {{ domain_request.last_submitted_date|date }}
|
||||
STATUS: Rejected
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ Hi, {{ recipient.first_name }}.
|
|||
We received your .gov domain request.
|
||||
|
||||
DOMAIN REQUESTED: {{ domain_request.requested_domain.name }}
|
||||
REQUESTED BY: {{ domain_request.creator.email }}
|
||||
REQUEST RECEIVED ON: {{ domain_request.last_submitted_date|date }}
|
||||
STATUS: Submitted
|
||||
|
||||
|
@ -11,13 +12,15 @@ STATUS: Submitted
|
|||
|
||||
NEXT STEPS
|
||||
We’ll review your request. This review period can take 30 business days. Due to the volume of requests, the wait time is longer than usual. We appreciate your patience.
|
||||
|
||||
{% if is_org_user %}
|
||||
During our review we’ll verify that your requested domain meets our naming requirements.
|
||||
{% else %}
|
||||
During our review, we’ll verify that:
|
||||
- Your organization is eligible for a .gov domain
|
||||
- You work at the organization and/or can make requests on its behalf
|
||||
- Your requested domain meets our naming requirements
|
||||
|
||||
We’ll email you if we have questions. We’ll also email you as soon as we complete our review. You can check the status of your request at any time on the registrar. <https://manage.get.gov>
|
||||
{% endif %}
|
||||
We’ll email you if we have questions. We’ll also email you as soon as we complete our review. You can check the status of your request at any time on the registrar. <https://manage.get.gov>.
|
||||
|
||||
|
||||
NEED TO MAKE CHANGES?
|
||||
|
|
|
@ -16,7 +16,9 @@ from registrar.models import (
|
|||
AllowedEmail,
|
||||
Portfolio,
|
||||
Suborganization,
|
||||
UserPortfolioPermission,
|
||||
)
|
||||
from registrar.models.utility.portfolio_helper import UserPortfolioRoleChoices
|
||||
|
||||
import boto3_mocking
|
||||
from registrar.utility.constants import BranchChoices
|
||||
|
@ -46,6 +48,14 @@ class TestDomainRequest(TestCase):
|
|||
self.dummy_user_2, _ = User.objects.get_or_create(
|
||||
username="intern@igorville.com", email="intern@igorville.com", first_name="Lava", last_name="World"
|
||||
)
|
||||
|
||||
self.dummy_user_3, _ = User.objects.get_or_create(
|
||||
username="portfolioadmin@igorville.com",
|
||||
email="portfolioadmin@igorville.com",
|
||||
first_name="Portfolio",
|
||||
last_name="Admin",
|
||||
)
|
||||
|
||||
self.started_domain_request = completed_domain_request(
|
||||
status=DomainRequest.DomainRequestStatus.STARTED,
|
||||
name="started.gov",
|
||||
|
@ -273,7 +283,14 @@ class TestDomainRequest(TestCase):
|
|||
self.assertEqual(domain_request.status, domain_request.DomainRequestStatus.SUBMITTED)
|
||||
|
||||
def check_email_sent(
|
||||
self, domain_request, msg, action, expected_count, expected_content=None, expected_email="mayor@igorville.com"
|
||||
self,
|
||||
domain_request,
|
||||
msg,
|
||||
action,
|
||||
expected_count,
|
||||
expected_content=None,
|
||||
expected_email="mayor@igorville.com",
|
||||
expected_cc=[],
|
||||
):
|
||||
"""Check if an email was sent after performing an action."""
|
||||
email_allowed, _ = AllowedEmail.objects.get_or_create(email=expected_email)
|
||||
|
@ -292,6 +309,11 @@ class TestDomainRequest(TestCase):
|
|||
]
|
||||
self.assertEqual(len(sent_emails), expected_count)
|
||||
|
||||
if expected_cc:
|
||||
sent_cc_adddresses = sent_emails[0]["kwargs"]["Destination"]["CcAddresses"]
|
||||
for cc_address in expected_cc:
|
||||
self.assertIn(cc_address, sent_cc_adddresses)
|
||||
|
||||
if expected_content:
|
||||
email_content = sent_emails[0]["kwargs"]["Content"]["Simple"]["Body"]["Text"]["Data"]
|
||||
self.assertIn(expected_content, email_content)
|
||||
|
@ -1074,6 +1096,36 @@ class TestDomainRequest(TestCase):
|
|||
self.assertEqual(domain_request2.generic_org_type, domain_request2.converted_generic_org_type)
|
||||
self.assertEqual(domain_request2.federal_agency, domain_request2.converted_federal_agency)
|
||||
|
||||
@less_console_noise_decorator
|
||||
def test_portfolio_domain_requests_cc_requests_viewers(self):
|
||||
"""test that portfolio domain request emails cc portfolio members who have read requests access"""
|
||||
fed_agency = FederalAgency.objects.filter(agency="Non-Federal Agency").first()
|
||||
portfolio = Portfolio.objects.create(
|
||||
organization_name="Test Portfolio",
|
||||
creator=self.dummy_user_2,
|
||||
federal_agency=fed_agency,
|
||||
organization_type=DomainRequest.OrganizationChoices.FEDERAL,
|
||||
)
|
||||
user_portfolio_permission = UserPortfolioPermission.objects.create( # noqa: F841
|
||||
user=self.dummy_user_3, portfolio=portfolio, roles=[UserPortfolioRoleChoices.ORGANIZATION_ADMIN]
|
||||
)
|
||||
# Adds cc'ed email in this test's allow list
|
||||
AllowedEmail.objects.create(email="portfolioadmin@igorville.com")
|
||||
|
||||
msg = "Create a domain request and submit it and see if email cc's portfolio admin and members who can view \
|
||||
requests."
|
||||
domain_request = completed_domain_request(
|
||||
name="test.gov", user=self.dummy_user_2, portfolio=portfolio, organization_name="Test Portfolio"
|
||||
)
|
||||
self.check_email_sent(
|
||||
domain_request,
|
||||
msg,
|
||||
"submit",
|
||||
1,
|
||||
expected_email="intern@igorville.com",
|
||||
expected_cc=["portfolioadmin@igorville.com"],
|
||||
)
|
||||
|
||||
|
||||
class TestDomainRequestSuborganization(TestCase):
|
||||
"""Tests for the suborganization fields on domain requests"""
|
||||
|
|
|
@ -36,7 +36,7 @@ def send_templated_email( # noqa
|
|||
|
||||
to_address and bcc_address currently only support single addresses.
|
||||
|
||||
cc_address is a list and can contain many addresses. Emails not in the
|
||||
cc_addresses is a list and can contain many addresses. Emails not in the
|
||||
whitelist (if applicable) will be filtered out before sending.
|
||||
|
||||
template_name and subject_template_name are relative to the same template
|
||||
|
|
|
@ -1336,6 +1336,8 @@ class DomainDeleteUserView(UserDomainRolePermissionDeleteView):
|
|||
# Is the user deleting themselves? If so, display a different message
|
||||
delete_self = self.request.user == self.object.user
|
||||
|
||||
# Email domain managers
|
||||
|
||||
# Add a success message
|
||||
messages.success(self.request, self.get_success_message(delete_self))
|
||||
return redirect(self.get_success_url())
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue