From 69706fbbb78524d7de72d4ee455d8ba411e8c183 Mon Sep 17 00:00:00 2001 From: Neil Martinsen-Burrell Date: Wed, 22 Mar 2023 16:14:52 -0500 Subject: [PATCH] Make invitation and show on user management page --- src/registrar/models/domain.py | 3 +++ src/registrar/models/domain_invitation.py | 1 + src/registrar/templates/domain_users.html | 27 ++++++++++++++++++++- src/registrar/views/domain.py | 29 +++++++++++++---------- 4 files changed, 47 insertions(+), 13 deletions(-) diff --git a/src/registrar/models/domain.py b/src/registrar/models/domain.py index 6697e2e64..09b0fd211 100644 --- a/src/registrar/models/domain.py +++ b/src/registrar/models/domain.py @@ -281,3 +281,6 @@ class Domain(TimeStampedModel): # ManyToManyField on User creates a "users" member for all of the # users who have some role on this domain + + # ForeignKey on DomainInvitation creates an "invitations" member for + # all of the invitations that have been sent for this domain diff --git a/src/registrar/models/domain_invitation.py b/src/registrar/models/domain_invitation.py index a1598e54e..80fed0486 100644 --- a/src/registrar/models/domain_invitation.py +++ b/src/registrar/models/domain_invitation.py @@ -22,6 +22,7 @@ class DomainInvitation(TimeStampedModel): "registrar.Domain", on_delete=models.CASCADE, # delete domain, then get rid of invitations null=False, + related_name="invitations", ) status = FSMField( diff --git a/src/registrar/templates/domain_users.html b/src/registrar/templates/domain_users.html index a8091fa1c..9b30e7923 100644 --- a/src/registrar/templates/domain_users.html +++ b/src/registrar/templates/domain_users.html @@ -25,7 +25,7 @@ {% for permission in domain.permissions.all %} - + {{ permission.user.email }} {{ permission.role|title }} @@ -45,4 +45,29 @@ Add another user + {% if domain.invitations.all %} +

Invitations

+ + + + + + + + + + + {% for invitation in domain.invitations.all %} + + + + + + {% endfor %} + +
Domain invitations
EmailDate createdStatus
+ {{ invitation.email }} + {{ invitation.created_at|date }} {{ invitation.status|title }}
+ {% endif %} + {% endblock %} {# domain_content #} diff --git a/src/registrar/views/domain.py b/src/registrar/views/domain.py index dc8ccc369..db46b163d 100644 --- a/src/registrar/views/domain.py +++ b/src/registrar/views/domain.py @@ -8,7 +8,7 @@ from django.urls import reverse from django.views.generic import DetailView from django.views.generic.edit import FormMixin -from registrar.models import Domain, User, UserDomainRole +from registrar.models import Domain, DomainInvitation, User, UserDomainRole from .utility import DomainPermission @@ -31,15 +31,6 @@ class DomainAddUserForm(DomainPermission, forms.Form): email = forms.EmailField(label="Email") - def clean_email(self): - requested_email = self.cleaned_data["email"] - try: - User.objects.get(email=requested_email) - except User.DoesNotExist: - # TODO: send an invitation email to a non-existent user - raise forms.ValidationError("That user does not exist in this system.") - return requested_email - class DomainAddUserView(DomainPermission, FormMixin, DetailView): template_name = "domain_add_user.html" @@ -53,16 +44,30 @@ class DomainAddUserView(DomainPermission, FormMixin, DetailView): self.object = self.get_object() form = self.get_form() if form.is_valid(): + # there is a valid email address in the form return self.form_valid(form) else: return self.form_invalid(form) + def _make_invitation(self, email_address): + """Make a Domain invitation for this email and redirect with a message.""" + invitation, created = DomainInvitation.objects.get_or_create(email=email_address, domain=self.object) + if not created: + # that invitation already existed + messages.warning(self.request, f"{email_address} has already been invited to this domain.") + else: + messages.success(self.request, f"Invited {email_address} to this domain.") + return redirect(self.get_success_url()) + def form_valid(self, form): """Add the specified user on this domain.""" requested_email = form.cleaned_data["email"] # look up a user with that email - # they should exist because we checked in clean_email - requested_user = User.objects.get(email=requested_email) + try: + requested_user = User.objects.get(email=requested_email) + except User.DoesNotExist: + # no matching user, go make an invitation + return self._make_invitation(requested_email) try: UserDomainRole.objects.create(