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
# 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",
on_delete=models.CASCADE, # delete domain, then get rid of invitations
null=False,
related_name="invitations",
)
status = FSMField(

View file

@ -25,7 +25,7 @@
<tbody>
{% for permission in domain.permissions.all %}
<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 }}
</th>
<td data-label="Role">{{ permission.role|title }}</td>
@ -45,4 +45,29 @@
</svg><span class="margin-left-05">Add another user</span>
</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 #}

View file

@ -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(