Make invitation and show on user management page

This commit is contained in:
Neil Martinsen-Burrell 2023-03-22 16:14:52 -05:00
parent 8650351ffe
commit 69706fbbb7
No known key found for this signature in database
GPG key ID: 6A3C818CC10D0184
4 changed files with 47 additions and 13 deletions

View file

@ -281,3 +281,6 @@ class Domain(TimeStampedModel):
# ManyToManyField on User creates a "users" member for all of the # ManyToManyField on User creates a "users" member for all of the
# users who have some role on this domain # 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

View file

@ -22,6 +22,7 @@ class DomainInvitation(TimeStampedModel):
"registrar.Domain", "registrar.Domain",
on_delete=models.CASCADE, # delete domain, then get rid of invitations on_delete=models.CASCADE, # delete domain, then get rid of invitations
null=False, null=False,
related_name="invitations",
) )
status = FSMField( status = FSMField(

View file

@ -25,7 +25,7 @@
<tbody> <tbody>
{% for permission in domain.permissions.all %} {% for permission in domain.permissions.all %}
<tr> <tr>
<th scope="row" role="rowheader" data-sort-value="{{ user.email }}" data-label="Domain name"> <th scope="row" role="rowheader" data-sort-value="{{ user.email }}" data-label="Email">
{{ permission.user.email }} {{ permission.user.email }}
</th> </th>
<td data-label="Role">{{ permission.role|title }}</td> <td data-label="Role">{{ permission.role|title }}</td>
@ -45,4 +45,29 @@
</svg><span class="margin-left-05">Add another user</span> </svg><span class="margin-left-05">Add another user</span>
</a> </a>
{% if domain.invitations.all %}
<h2>Invitations</h2>
<table class="usa-table usa-table--borderless usa-table--stacked dotgov-table--stacked dotgov-table">
<caption class="sr-only">Domain invitations</caption>
<thead>
<tr>
<th data-sortable scope="col" role="columnheader">Email</th>
<th data-sortable scope="col" role="columnheader">Date created</th>
<th data-sortable scope="col" role="columnheader">Status</th>
</tr>
</thead>
<tbody>
{% for invitation in domain.invitations.all %}
<tr>
<th scope="row" role="rowheader" data-sort-value="{{ user.email }}" data-label="Email">
{{ invitation.email }}
</th>
<td data-sort-value="{{ invitation.created_at|date:"U" }}" data-label="Date created">{{ invitation.created_at|date }} </td>
<td data-label="Status">{{ invitation.status|title }}</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endif %}
{% endblock %} {# domain_content #} {% endblock %} {# domain_content #}

View file

@ -8,7 +8,7 @@ from django.urls import reverse
from django.views.generic import DetailView from django.views.generic import DetailView
from django.views.generic.edit import FormMixin 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 from .utility import DomainPermission
@ -31,15 +31,6 @@ class DomainAddUserForm(DomainPermission, forms.Form):
email = forms.EmailField(label="Email") 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): class DomainAddUserView(DomainPermission, FormMixin, DetailView):
template_name = "domain_add_user.html" template_name = "domain_add_user.html"
@ -53,16 +44,30 @@ class DomainAddUserView(DomainPermission, FormMixin, DetailView):
self.object = self.get_object() self.object = self.get_object()
form = self.get_form() form = self.get_form()
if form.is_valid(): if form.is_valid():
# there is a valid email address in the form
return self.form_valid(form) return self.form_valid(form)
else: else:
return self.form_invalid(form) 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): def form_valid(self, form):
"""Add the specified user on this domain.""" """Add the specified user on this domain."""
requested_email = form.cleaned_data["email"] requested_email = form.cleaned_data["email"]
# look up a user with that email # look up a user with that email
# they should exist because we checked in clean_email try:
requested_user = User.objects.get(email=requested_email) 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: try:
UserDomainRole.objects.create( UserDomainRole.objects.create(