mirror of
https://github.com/cisagov/manage.get.gov.git
synced 2025-08-12 12:39:43 +02:00
portfolio addition email send to admins on registrar invite
This commit is contained in:
parent
b4c697f32e
commit
37f52aa9d4
4 changed files with 107 additions and 3 deletions
|
@ -0,0 +1,40 @@
|
||||||
|
{% autoescape off %}{# In a text file, we don't want to have HTML entities escaped #}
|
||||||
|
Hi,{% if portfolio_admin and portfolio_admin.first_name %} {{ portfolio_admin.first_name }}.{% endif %}
|
||||||
|
|
||||||
|
An admin was invited to your .gov organization.
|
||||||
|
|
||||||
|
ORGANIZATION: {{ portfolio.organization_name }}
|
||||||
|
INVITED BY: {{ requestor_email }}
|
||||||
|
INVITED ON: {{date}}
|
||||||
|
ADMIN INVITED: {{ invited_email_address }}
|
||||||
|
|
||||||
|
----------------------------------------------------------------
|
||||||
|
|
||||||
|
NEXT STEPS
|
||||||
|
The person who received the invitation will become an admin once they log in to the
|
||||||
|
.gov registrar. They'll need to access the registrar using a Login.gov account that's
|
||||||
|
associated with the invited email address.
|
||||||
|
|
||||||
|
If you need to cancel this invitation or remove the admin, you can do that by going to
|
||||||
|
the Members section for your organization <https://manage.get.gov/>.
|
||||||
|
|
||||||
|
|
||||||
|
WHY DID YOU RECEIVE THIS EMAIL?
|
||||||
|
You’re listed as an admin for {{ portfolio.organization_name }}. That means you'll receive a notification
|
||||||
|
whenever a new admin is invited to that organization.
|
||||||
|
|
||||||
|
If you have questions or concerns, reach out to the person who sent the invitation or reply to this email.
|
||||||
|
|
||||||
|
|
||||||
|
THANK YOU
|
||||||
|
.Gov helps the public identify official, trusted information. Thank you for using a .gov domain.
|
||||||
|
|
||||||
|
----------------------------------------------------------------
|
||||||
|
|
||||||
|
The .gov team
|
||||||
|
Contact us: <https://get.gov/contact/>
|
||||||
|
Learn about .gov <https://get.gov>
|
||||||
|
|
||||||
|
The .gov registry is a part of the Cybersecurity and Infrastructure Security Agency
|
||||||
|
(CISA) <https://cisa.gov/>
|
||||||
|
{% endautoescape %}
|
|
@ -0,0 +1 @@
|
||||||
|
An admin was invited to your .gov organization
|
|
@ -1,6 +1,8 @@
|
||||||
from datetime import date
|
from datetime import date
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from registrar.models import Domain, DomainInvitation, UserDomainRole
|
from registrar.models import Domain, DomainInvitation, UserDomainRole
|
||||||
|
from registrar.models.user_portfolio_permission import UserPortfolioPermission
|
||||||
|
from registrar.models.utility.portfolio_helper import UserPortfolioRoleChoices
|
||||||
from registrar.utility.errors import (
|
from registrar.utility.errors import (
|
||||||
AlreadyDomainInvitedError,
|
AlreadyDomainInvitedError,
|
||||||
AlreadyDomainManagerError,
|
AlreadyDomainManagerError,
|
||||||
|
@ -169,7 +171,7 @@ def send_invitation_email(email, requestor_email, domains, requested_user):
|
||||||
raise EmailSendingError(f"Could not send email invitation to {email} for domains: {domain_names}") from err
|
raise EmailSendingError(f"Could not send email invitation to {email} for domains: {domain_names}") from err
|
||||||
|
|
||||||
|
|
||||||
def send_portfolio_invitation_email(email: str, requestor, portfolio):
|
def send_portfolio_invitation_email(email: str, requestor, portfolio, is_admin_invitation):
|
||||||
"""
|
"""
|
||||||
Sends a portfolio member invitation email to the specified address.
|
Sends a portfolio member invitation email to the specified address.
|
||||||
|
|
||||||
|
@ -179,6 +181,10 @@ def send_portfolio_invitation_email(email: str, requestor, portfolio):
|
||||||
email (str): Email address of the recipient
|
email (str): Email address of the recipient
|
||||||
requestor (User): The user initiating the invitation.
|
requestor (User): The user initiating the invitation.
|
||||||
portfolio (Portfolio): The portfolio object for which the invitation is being sent.
|
portfolio (Portfolio): The portfolio object for which the invitation is being sent.
|
||||||
|
is_admin_invitation (boolean): boolean indicating if the invitation is an admin invitation
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Boolean indicating if all messages were sent successfully.
|
||||||
|
|
||||||
Raises:
|
Raises:
|
||||||
MissingEmailError: If the requestor has no email associated with their account.
|
MissingEmailError: If the requestor has no email associated with their account.
|
||||||
|
@ -210,3 +216,53 @@ def send_portfolio_invitation_email(email: str, requestor, portfolio):
|
||||||
raise EmailSendingError(
|
raise EmailSendingError(
|
||||||
f"Could not sent email invitation to {email} for portfolio {portfolio}. Portfolio invitation not saved."
|
f"Could not sent email invitation to {email} for portfolio {portfolio}. Portfolio invitation not saved."
|
||||||
) from err
|
) from err
|
||||||
|
|
||||||
|
all_admin_emails_sent = True
|
||||||
|
# send emails to portfolio admins
|
||||||
|
if is_admin_invitation:
|
||||||
|
all_admin_emails_sent = send_portfolio_admin_addition_emails_to_portfolio_admins(
|
||||||
|
email=email,
|
||||||
|
requestor_email=requestor_email,
|
||||||
|
portfolio=portfolio,
|
||||||
|
requested_user=None,
|
||||||
|
)
|
||||||
|
return all_admin_emails_sent
|
||||||
|
|
||||||
|
|
||||||
|
def send_portfolio_admin_addition_emails_to_portfolio_admins(
|
||||||
|
email: str, requestor_email, portfolio: Domain, requested_user=None
|
||||||
|
):
|
||||||
|
"""
|
||||||
|
Notifies all portfolio admins of the provided portfolio of a newly invited portfolio admin
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Boolean indicating if all messages were sent successfully.
|
||||||
|
"""
|
||||||
|
all_emails_sent = True
|
||||||
|
# Get each portfolio admin from list
|
||||||
|
user_portfolio_permissions = UserPortfolioPermission.objects.filter(
|
||||||
|
portfolio=portfolio, roles__contains=[UserPortfolioRoleChoices.ORGANIZATION_ADMIN]
|
||||||
|
).exclude(user__email=email)
|
||||||
|
for user_portfolio_permission in user_portfolio_permissions:
|
||||||
|
# Send email to each portfolio_admin
|
||||||
|
user = user_portfolio_permission.user
|
||||||
|
try:
|
||||||
|
send_templated_email(
|
||||||
|
"emails/portfolio_admin_addition_notification.txt",
|
||||||
|
"emails/portfolio_admin_addition_notification_subject.txt",
|
||||||
|
to_address=user.email,
|
||||||
|
context={
|
||||||
|
"portfolio": portfolio,
|
||||||
|
"requestor_email": requestor_email,
|
||||||
|
"invited_email_address": email,
|
||||||
|
"portfolio_admin": user,
|
||||||
|
"date": date.today(),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
except EmailSendingError:
|
||||||
|
logger.warning(
|
||||||
|
f"Could not send email organization admin notification to {user.email} for portfolio: {portfolio.name}",
|
||||||
|
exc_info=True,
|
||||||
|
)
|
||||||
|
all_emails_sent = False
|
||||||
|
return all_emails_sent
|
||||||
|
|
|
@ -773,12 +773,19 @@ class PortfolioAddMemberView(PortfolioMembersPermissionView, FormMixin):
|
||||||
requested_email = form.cleaned_data["email"]
|
requested_email = form.cleaned_data["email"]
|
||||||
requestor = self.request.user
|
requestor = self.request.user
|
||||||
portfolio = form.cleaned_data["portfolio"]
|
portfolio = form.cleaned_data["portfolio"]
|
||||||
|
is_admin_invitation = UserPortfolioRoleChoices.ORGANIZATION_ADMIN in form.cleaned_data["roles"]
|
||||||
|
|
||||||
requested_user = User.objects.filter(email=requested_email).first()
|
requested_user = User.objects.filter(email=requested_email).first()
|
||||||
permission_exists = UserPortfolioPermission.objects.filter(user=requested_user, portfolio=portfolio).exists()
|
permission_exists = UserPortfolioPermission.objects.filter(user=requested_user, portfolio=portfolio).exists()
|
||||||
try:
|
try:
|
||||||
if not requested_user or not permission_exists:
|
if not requested_user or not permission_exists:
|
||||||
send_portfolio_invitation_email(email=requested_email, requestor=requestor, portfolio=portfolio)
|
if not send_portfolio_invitation_email(
|
||||||
|
email=requested_email,
|
||||||
|
requestor=requestor,
|
||||||
|
portfolio=portfolio,
|
||||||
|
is_admin_invitation=is_admin_invitation,
|
||||||
|
):
|
||||||
|
messages.warning(self.request, "Could not send email notification to existing organization admins.")
|
||||||
portfolio_invitation = form.save()
|
portfolio_invitation = form.save()
|
||||||
# if user exists for email, immediately retrieve portfolio invitation upon creation
|
# if user exists for email, immediately retrieve portfolio invitation upon creation
|
||||||
if requested_user is not None:
|
if requested_user is not None:
|
||||||
|
@ -801,7 +808,7 @@ class PortfolioAddMemberView(PortfolioMembersPermissionView, FormMixin):
|
||||||
portfolio,
|
portfolio,
|
||||||
exc_info=True,
|
exc_info=True,
|
||||||
)
|
)
|
||||||
messages.warning(self.request, "Could not send portfolio email invitation.")
|
messages.error(self.request, "Could not send organization invitation email.")
|
||||||
elif isinstance(exception, MissingEmailError):
|
elif isinstance(exception, MissingEmailError):
|
||||||
messages.error(self.request, str(exception))
|
messages.error(self.request, str(exception))
|
||||||
logger.error(
|
logger.error(
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue