mirror of
https://github.com/cisagov/manage.get.gov.git
synced 2025-07-22 10:46:06 +02:00
merge main
This commit is contained in:
commit
2a6f1720be
21 changed files with 694 additions and 6165 deletions
13
.github/workflows/deploy-development.yaml
vendored
13
.github/workflows/deploy-development.yaml
vendored
|
@ -22,16 +22,9 @@ jobs:
|
|||
- name: Compile USWDS assets
|
||||
working-directory: ./src
|
||||
run: |
|
||||
docker compose run node bash -c "\
|
||||
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash && \
|
||||
export NVM_DIR=\"\$HOME/.nvm\" && \
|
||||
[ -s \"\$NVM_DIR/nvm.sh\" ] && \. \"\$NVM_DIR/nvm.sh\" && \
|
||||
[ -s \"\$NVM_DIR/bash_completion\" ] && \. \"\$NVM_DIR/bash_completion\" && \
|
||||
nvm install 21.7.3 && \
|
||||
nvm use 21.7.3 && \
|
||||
npm install && \
|
||||
npx gulp copyAssets && \
|
||||
npx gulp compile"
|
||||
docker compose run node npm install &&
|
||||
docker compose run node npx gulp copyAssets &&
|
||||
docker compose run node npx gulp compile
|
||||
- name: Collect static assets
|
||||
working-directory: ./src
|
||||
run: docker compose run app python manage.py collectstatic --no-input
|
||||
|
|
13
.github/workflows/deploy-sandbox.yaml
vendored
13
.github/workflows/deploy-sandbox.yaml
vendored
|
@ -43,16 +43,9 @@ jobs:
|
|||
- name: Compile USWDS assets
|
||||
working-directory: ./src
|
||||
run: |
|
||||
docker compose run node bash -c "\
|
||||
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash && \
|
||||
export NVM_DIR=\"\$HOME/.nvm\" && \
|
||||
[ -s \"\$NVM_DIR/nvm.sh\" ] && \. \"\$NVM_DIR/nvm.sh\" && \
|
||||
[ -s \"\$NVM_DIR/bash_completion\" ] && \. \"\$NVM_DIR/bash_completion\" && \
|
||||
nvm install 21.7.3 && \
|
||||
nvm use 21.7.3 && \
|
||||
npm install && \
|
||||
npx gulp copyAssets && \
|
||||
npx gulp compile"
|
||||
docker compose run node npm install &&
|
||||
docker compose run node npx gulp copyAssets &&
|
||||
docker compose run node npx gulp compile
|
||||
- name: Collect static assets
|
||||
working-directory: ./src
|
||||
run: docker compose run app python manage.py collectstatic --no-input
|
||||
|
|
13
.github/workflows/deploy-stable.yaml
vendored
13
.github/workflows/deploy-stable.yaml
vendored
|
@ -23,16 +23,9 @@ jobs:
|
|||
- name: Compile USWDS assets
|
||||
working-directory: ./src
|
||||
run: |
|
||||
docker compose run node bash -c "\
|
||||
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash && \
|
||||
export NVM_DIR=\"\$HOME/.nvm\" && \
|
||||
[ -s \"\$NVM_DIR/nvm.sh\" ] && \. \"\$NVM_DIR/nvm.sh\" && \
|
||||
[ -s \"\$NVM_DIR/bash_completion\" ] && \. \"\$NVM_DIR/bash_completion\" && \
|
||||
nvm install 21.7.3 && \
|
||||
nvm use 21.7.3 && \
|
||||
npm install && \
|
||||
npx gulp copyAssets && \
|
||||
npx gulp compile"
|
||||
docker compose run node npm install &&
|
||||
docker compose run node npx gulp copyAssets &&
|
||||
docker compose run node npx gulp compile
|
||||
- name: Collect static assets
|
||||
working-directory: ./src
|
||||
run: docker compose run app python manage.py collectstatic --no-input
|
||||
|
|
13
.github/workflows/deploy-staging.yaml
vendored
13
.github/workflows/deploy-staging.yaml
vendored
|
@ -23,16 +23,9 @@ jobs:
|
|||
- name: Compile USWDS assets
|
||||
working-directory: ./src
|
||||
run: |
|
||||
docker compose run node bash -c "\
|
||||
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash && \
|
||||
export NVM_DIR=\"\$HOME/.nvm\" && \
|
||||
[ -s \"\$NVM_DIR/nvm.sh\" ] && \. \"\$NVM_DIR/nvm.sh\" && \
|
||||
[ -s \"\$NVM_DIR/bash_completion\" ] && \. \"\$NVM_DIR/bash_completion\" && \
|
||||
nvm install 21.7.3 && \
|
||||
nvm use 21.7.3 && \
|
||||
npm install && \
|
||||
npx gulp copyAssets && \
|
||||
npx gulp compile"
|
||||
docker compose run node npm install &&
|
||||
docker compose run node npx gulp copyAssets &&
|
||||
docker compose run node npx gulp compile
|
||||
- name: Collect static assets
|
||||
working-directory: ./src
|
||||
run: docker compose run app python manage.py collectstatic --no-input
|
||||
|
|
|
@ -33,4 +33,5 @@ exports.init = uswds.init;
|
|||
exports.compile = uswds.compile;
|
||||
exports.watch = uswds.watch;
|
||||
exports.copyAssets = uswds.copyAssets
|
||||
|
||||
exports.updateUswds = uswds.updateUswds
|
||||
|
|
@ -1,5 +1,4 @@
|
|||
FROM docker.io/cimg/node:current-browsers
|
||||
FROM node:21.7.3
|
||||
WORKDIR /app
|
||||
|
||||
# Install app dependencies
|
||||
|
@ -7,6 +6,4 @@ WORKDIR /app
|
|||
# where available (npm@5+)
|
||||
COPY --chown=circleci:circleci package*.json ./
|
||||
|
||||
|
||||
RUN npm install -g npm@10.5.0
|
||||
RUN npm install
|
6616
src/package-lock.json
generated
6616
src/package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -3,11 +3,6 @@
|
|||
"version": "1.0.0",
|
||||
"description": "========================",
|
||||
"main": "index.js",
|
||||
"engines": {
|
||||
"node": "21.7.3",
|
||||
"npm": "10.5.0"
|
||||
},
|
||||
"engineStrict": true,
|
||||
"scripts": {
|
||||
"pa11y-ci": "pa11y-ci",
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
|
@ -15,7 +10,7 @@
|
|||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@uswds/uswds": "^3.3.0",
|
||||
"@uswds/uswds": "^3.8.0",
|
||||
"pa11y-ci": "^3.0.1",
|
||||
"sass": "^1.54.8"
|
||||
},
|
||||
|
|
|
@ -594,7 +594,7 @@ class MyUserAdmin(BaseUserAdmin, ImportExportModelAdmin):
|
|||
None,
|
||||
{"fields": ("username", "password", "status", "verification_type")},
|
||||
),
|
||||
("Personal Info", {"fields": ("first_name", "last_name", "email")}),
|
||||
("Personal Info", {"fields": ("first_name", "middle_name", "last_name", "email", "title")}),
|
||||
(
|
||||
"Permissions",
|
||||
{
|
||||
|
@ -625,7 +625,7 @@ class MyUserAdmin(BaseUserAdmin, ImportExportModelAdmin):
|
|||
)
|
||||
},
|
||||
),
|
||||
("Personal Info", {"fields": ("first_name", "last_name", "email")}),
|
||||
("Personal Info", {"fields": ("first_name", "middle_name", "last_name", "email", "title")}),
|
||||
(
|
||||
"Permissions",
|
||||
{
|
||||
|
@ -651,7 +651,9 @@ class MyUserAdmin(BaseUserAdmin, ImportExportModelAdmin):
|
|||
analyst_readonly_fields = [
|
||||
"Personal Info",
|
||||
"first_name",
|
||||
"middle_name",
|
||||
"last_name",
|
||||
"title",
|
||||
"email",
|
||||
"Permissions",
|
||||
"is_active",
|
||||
|
@ -1124,7 +1126,6 @@ class DomainInformationAdmin(ListHeaderAdmin, ImportExportModelAdmin):
|
|||
"Type of organization",
|
||||
{
|
||||
"fields": [
|
||||
"generic_org_type",
|
||||
"is_election_board",
|
||||
"organization_type",
|
||||
]
|
||||
|
@ -1171,7 +1172,7 @@ class DomainInformationAdmin(ListHeaderAdmin, ImportExportModelAdmin):
|
|||
]
|
||||
|
||||
# Readonly fields for analysts and superusers
|
||||
readonly_fields = ("other_contacts", "generic_org_type", "is_election_board")
|
||||
readonly_fields = ("other_contacts", "is_election_board", "federal_agency")
|
||||
|
||||
# Read only that we'll leverage for CISA Analysts
|
||||
analyst_readonly_fields = [
|
||||
|
@ -1385,7 +1386,6 @@ class DomainRequestAdmin(ListHeaderAdmin, ImportExportModelAdmin):
|
|||
"Type of organization",
|
||||
{
|
||||
"fields": [
|
||||
"generic_org_type",
|
||||
"is_election_board",
|
||||
"organization_type",
|
||||
]
|
||||
|
@ -1436,8 +1436,8 @@ class DomainRequestAdmin(ListHeaderAdmin, ImportExportModelAdmin):
|
|||
"other_contacts",
|
||||
"current_websites",
|
||||
"alternative_domains",
|
||||
"generic_org_type",
|
||||
"is_election_board",
|
||||
"federal_agency",
|
||||
)
|
||||
|
||||
# Read only that we'll leverage for CISA Analysts
|
||||
|
@ -1879,7 +1879,7 @@ class DomainAdmin(ListHeaderAdmin, ImportExportModelAdmin):
|
|||
search_fields = ["name"]
|
||||
search_help_text = "Search by domain name."
|
||||
change_form_template = "django/admin/domain_change_form.html"
|
||||
readonly_fields = ["state", "expiration_date", "first_ready", "deleted"]
|
||||
readonly_fields = ("state", "expiration_date", "first_ready", "deleted", "federal_agency")
|
||||
|
||||
# Table ordering
|
||||
ordering = ["name"]
|
||||
|
|
|
@ -385,7 +385,6 @@ class DomainOrgNameAddressForm(forms.ModelForm):
|
|||
# because for this fields we are creating an individual
|
||||
# instance of the Select. For the other fields we use the for loop to set
|
||||
# the class's required attribute to true.
|
||||
"federal_agency": forms.TextInput,
|
||||
"organization_name": forms.TextInput,
|
||||
"address_line1": forms.TextInput,
|
||||
"address_line2": forms.TextInput,
|
||||
|
|
|
@ -43,7 +43,11 @@ class UserProfileForm(forms.ModelForm):
|
|||
self.fields[field_name].required = True
|
||||
|
||||
# Set custom form label
|
||||
self.fields["first_name"].label = "First name / given name"
|
||||
self.fields["middle_name"].label = "Middle name (optional)"
|
||||
self.fields["last_name"].label = "Last name / family name"
|
||||
self.fields["title"].label = "Title or role in your organization"
|
||||
self.fields["email"].label = "Organizational email"
|
||||
|
||||
# Set custom error messages
|
||||
self.fields["first_name"].error_messages = {"required": "Enter your first name / given name."}
|
||||
|
|
23
src/registrar/migrations/0095_user_middle_name_user_title.py
Normal file
23
src/registrar/migrations/0095_user_middle_name_user_title.py
Normal file
|
@ -0,0 +1,23 @@
|
|||
# Generated by Django 4.2.10 on 2024-05-22 14:54
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("registrar", "0094_create_groups_v12"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name="user",
|
||||
name="middle_name",
|
||||
field=models.CharField(blank=True, null=True),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="user",
|
||||
name="title",
|
||||
field=models.CharField(blank=True, null=True, verbose_name="title / role"),
|
||||
),
|
||||
]
|
|
@ -80,6 +80,17 @@ class User(AbstractUser):
|
|||
db_index=True,
|
||||
)
|
||||
|
||||
middle_name = models.CharField(
|
||||
null=True,
|
||||
blank=True,
|
||||
)
|
||||
|
||||
title = models.CharField(
|
||||
null=True,
|
||||
blank=True,
|
||||
verbose_name="title / role",
|
||||
)
|
||||
|
||||
verification_type = models.CharField(
|
||||
choices=VerificationTypeChoices.choices,
|
||||
null=True,
|
||||
|
|
|
@ -81,7 +81,7 @@
|
|||
<div class="grid-col-auto">
|
||||
<img class="usa-banner__header-flag" src="{% static 'img/us_flag_small.png' %}" alt="U.S. flag" />
|
||||
</div>
|
||||
<div class="grid-col-fill tablet:grid-col-auto">
|
||||
<div class="grid-col-fill tablet:grid-col-auto" aria-hidden="true">
|
||||
<p class="usa-banner__header-text">
|
||||
An official website of the United States government
|
||||
</p>
|
||||
|
|
|
@ -93,7 +93,7 @@
|
|||
</li>
|
||||
<li class="usa-identifier__required-links-item">
|
||||
<a rel="noopener noreferrer" target="_blank" href="https://www.dhs.gov/accessibility" class="usa-identifier__required-link usa-link usa-link--external"
|
||||
>Accessibility</a
|
||||
>Accessibility statement</a
|
||||
>
|
||||
</li>
|
||||
<li class="usa-identifier__required-links-item">
|
||||
|
|
|
@ -32,7 +32,7 @@ Edit your User Profile |
|
|||
{% include "includes/form_errors.html" with form=form %}
|
||||
|
||||
<h1>Your profile</h1>
|
||||
<p>We <a href="https://get.gov/domains/requirements/#what-.gov-domain-registrants-must-do" target="_blank">require</a> that you maintain accurate contact information. The details you provide will only be used to support the administration of .gov and won’t be made public.</p>
|
||||
<p>We <a href="{% public_site_url 'domains/requirements/#what-.gov-domain-registrants-must-do' %}" target="_blank">require</a> that you maintain accurate contact information. The details you provide will only be used to support the administration of .gov and won’t be made public.</p>
|
||||
|
||||
<h2>Contact information</h2>
|
||||
<p>Review the details below and update any required information. Note that editing this information won’t affect your Login.gov account information.</p>
|
||||
|
@ -41,35 +41,33 @@ Edit your User Profile |
|
|||
|
||||
<form class="usa-form usa-form--large" method="post" novalidate>
|
||||
{% csrf_token %}
|
||||
<fieldset class="usa-fieldset">
|
||||
|
||||
{% input_with_errors form.first_name %}
|
||||
{% input_with_errors form.first_name %}
|
||||
|
||||
{% input_with_errors form.middle_name %}
|
||||
|
||||
{% input_with_errors form.last_name %}
|
||||
|
||||
{% input_with_errors form.title %}
|
||||
{% input_with_errors form.middle_name %}
|
||||
|
||||
{% input_with_errors form.last_name %}
|
||||
|
||||
{% input_with_errors form.title %}
|
||||
|
||||
{% public_site_url "help/account-management/#get-help-with-login.gov" as login_help_url %}
|
||||
{% public_site_url "help/account-management/#get-help-with-login.gov" as login_help_url %}
|
||||
|
||||
{% with link_href=login_help_url %}
|
||||
{% with sublabel_text="We recommend using your work email for your .gov account. If the wrong email is displayed below, you’ll need to update your Login.gov account and log back in. Get help with your Login.gov account." %}
|
||||
{% with link_text="Get help with your Login.gov account" %}
|
||||
{% with target_blank=True %}
|
||||
{% with do_not_show_max_chars=True %}
|
||||
{% input_with_errors form.email %}
|
||||
{% endwith %}
|
||||
{% with link_href=login_help_url %}
|
||||
{% with sublabel_text="We recommend using your work email for your .gov account. If the wrong email is displayed below, you’ll need to update your Login.gov account and log back in. Get help with your Login.gov account." %}
|
||||
{% with link_text="Get help with your Login.gov account" %}
|
||||
{% with target_blank=True %}
|
||||
{% with do_not_show_max_chars=True %}
|
||||
{% input_with_errors form.email %}
|
||||
{% endwith %}
|
||||
{% endwith %}
|
||||
{% endwith %}
|
||||
{% endwith %}
|
||||
|
||||
{% with add_class="usa-input--medium" %}
|
||||
{% input_with_errors form.phone %}
|
||||
{% endwith %}
|
||||
{% endwith %}
|
||||
|
||||
{% with add_class="usa-input--medium" %}
|
||||
{% input_with_errors form.phone %}
|
||||
{% endwith %}
|
||||
|
||||
</fieldset>
|
||||
<button type="submit" class="usa-button">Save</button>
|
||||
</form>
|
||||
</main>
|
||||
|
|
|
@ -2230,8 +2230,8 @@ class TestDomainRequestAdmin(MockEppLib):
|
|||
"other_contacts",
|
||||
"current_websites",
|
||||
"alternative_domains",
|
||||
"generic_org_type",
|
||||
"is_election_board",
|
||||
"federal_agency",
|
||||
"id",
|
||||
"created_at",
|
||||
"updated_at",
|
||||
|
@ -2284,8 +2284,8 @@ class TestDomainRequestAdmin(MockEppLib):
|
|||
"other_contacts",
|
||||
"current_websites",
|
||||
"alternative_domains",
|
||||
"generic_org_type",
|
||||
"is_election_board",
|
||||
"federal_agency",
|
||||
"creator",
|
||||
"about_your_organization",
|
||||
"requested_domain",
|
||||
|
@ -2312,8 +2312,8 @@ class TestDomainRequestAdmin(MockEppLib):
|
|||
"other_contacts",
|
||||
"current_websites",
|
||||
"alternative_domains",
|
||||
"generic_org_type",
|
||||
"is_election_board",
|
||||
"federal_agency",
|
||||
]
|
||||
|
||||
self.assertEqual(readonly_fields, expected_fields)
|
||||
|
@ -3170,8 +3170,8 @@ class TestDomainInformationAdmin(TestCase):
|
|||
|
||||
expected_fields = [
|
||||
"other_contacts",
|
||||
"generic_org_type",
|
||||
"is_election_board",
|
||||
"federal_agency",
|
||||
"creator",
|
||||
"type_of_work",
|
||||
"more_organization_information",
|
||||
|
@ -3534,7 +3534,7 @@ class TestMyUserAdmin(TestCase):
|
|||
)
|
||||
},
|
||||
),
|
||||
("Personal Info", {"fields": ("first_name", "last_name", "email")}),
|
||||
("Personal Info", {"fields": ("first_name", "middle_name", "last_name", "email", "title")}),
|
||||
("Permissions", {"fields": ("is_active", "groups")}),
|
||||
("Important dates", {"fields": ("last_login", "date_joined")}),
|
||||
)
|
||||
|
|
|
@ -528,6 +528,8 @@ class UserProfileTests(TestWithUser, WebTest):
|
|||
self.role.delete()
|
||||
self.domain.delete()
|
||||
Contact.objects.all().delete()
|
||||
DraftDomain.objects.all().delete()
|
||||
DomainRequest.objects.all().delete()
|
||||
|
||||
@less_console_noise_decorator
|
||||
def error_500_main_nav_with_profile_feature_turned_on(self):
|
||||
|
@ -635,9 +637,6 @@ class UserProfileTests(TestWithUser, WebTest):
|
|||
self.assertContains(response, "Your profile")
|
||||
response = self.client.get(f"/domain-request/{domain_request.id}/withdraw")
|
||||
self.assertContains(response, "Your profile")
|
||||
# cleanup
|
||||
domain_request.delete()
|
||||
site.delete()
|
||||
|
||||
@less_console_noise_decorator
|
||||
def test_request_when_profile_feature_off(self):
|
||||
|
|
|
@ -1447,7 +1447,7 @@ class TestDomainOrganization(TestDomainOverview):
|
|||
|
||||
session_id = self.app.cookies[settings.SESSION_COOKIE_NAME]
|
||||
|
||||
org_name_page.form["federal_agency"] = "Department of State"
|
||||
org_name_page.form["federal_agency"] = FederalAgency.objects.filter(agency="Department of State").get().id
|
||||
org_name_page.form["city"] = "Faketown"
|
||||
|
||||
self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)
|
||||
|
@ -1456,9 +1456,8 @@ class TestDomainOrganization(TestDomainOverview):
|
|||
success_result_page = org_name_page.form.submit()
|
||||
self.assertEqual(success_result_page.status_code, 200)
|
||||
|
||||
# Check for the old and new value
|
||||
self.assertContains(success_result_page, federal_agency.id)
|
||||
self.assertNotContains(success_result_page, "Department of State")
|
||||
# Check that the agency has not changed
|
||||
self.assertEqual(self.domain_information.federal_agency.agency, "AMTRAK")
|
||||
|
||||
# Do another check on the form itself
|
||||
form = success_result_page.forms[0]
|
||||
|
|
|
@ -32,8 +32,9 @@ def send_templated_email(
|
|||
template_name and subject_template_name are relative to the same template
|
||||
context as Django's HTML templates. context gives additional information
|
||||
that the template may use.
|
||||
|
||||
Raises EmailSendingError if SES client could not be accessed
|
||||
"""
|
||||
logger.info(f"An email was sent! Template name: {template_name} to {to_address}")
|
||||
template = get_template(template_name)
|
||||
email_body = template.render(context=context)
|
||||
|
||||
|
@ -48,7 +49,9 @@ def send_templated_email(
|
|||
aws_secret_access_key=settings.AWS_SECRET_ACCESS_KEY,
|
||||
config=settings.BOTO_CONFIG,
|
||||
)
|
||||
logger.info(f"An email was sent! Template name: {template_name} to {to_address}")
|
||||
except Exception as exc:
|
||||
logger.debug("E-mail unable to send! Could not access the SES client.")
|
||||
raise EmailSendingError("Could not access the SES client.") from exc
|
||||
|
||||
destination = {"ToAddresses": [to_address]}
|
||||
|
|
|
@ -745,7 +745,10 @@ class DomainAddUserView(DomainFormBaseView):
|
|||
does not make a domain information object
|
||||
email: string- email to send to
|
||||
add_success: bool- default True indicates:
|
||||
adding a success message to the view if the email sending succeeds"""
|
||||
adding a success message to the view if the email sending succeeds
|
||||
|
||||
raises EmailSendingError
|
||||
"""
|
||||
|
||||
# Set a default email address to send to for staff
|
||||
requestor_email = settings.DEFAULT_FROM_EMAIL
|
||||
|
@ -773,33 +776,43 @@ class DomainAddUserView(DomainFormBaseView):
|
|||
"requestor_email": requestor_email,
|
||||
},
|
||||
)
|
||||
except EmailSendingError:
|
||||
messages.warning(self.request, "Could not send email invitation.")
|
||||
except EmailSendingError as exc:
|
||||
logger.warn(
|
||||
"Could not sent email invitation to %s for domain %s",
|
||||
email,
|
||||
self.object,
|
||||
exc_info=True,
|
||||
)
|
||||
raise EmailSendingError("Could not send email invitation.") from exc
|
||||
else:
|
||||
if add_success:
|
||||
messages.success(self.request, f"{email} has been invited to this domain.")
|
||||
|
||||
def _make_invitation(self, email_address: str, requestor: User):
|
||||
"""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:
|
||||
# Check to see if an invite has already been sent (NOTE: we do not want to create an invite just yet.)
|
||||
try:
|
||||
invite = DomainInvitation.objects.get(email=email_address, domain=self.object)
|
||||
# that invitation already existed
|
||||
messages.warning(
|
||||
self.request,
|
||||
f"{email_address} has already been invited to this domain.",
|
||||
)
|
||||
else:
|
||||
self._send_domain_invitation_email(email=email_address, requestor=requestor)
|
||||
if invite is not None:
|
||||
messages.warning(
|
||||
self.request,
|
||||
f"{email_address} has already been invited to this domain.",
|
||||
)
|
||||
except DomainInvitation.DoesNotExist:
|
||||
# Try to send the invitation. If it succeeds, add it to the DomainInvitation table.
|
||||
try:
|
||||
self._send_domain_invitation_email(email=email_address, requestor=requestor)
|
||||
except EmailSendingError:
|
||||
messages.warning(self.request, "Could not send email invitation.")
|
||||
else:
|
||||
# (NOTE: only create a domainInvitation if the e-mail sends correctly)
|
||||
DomainInvitation.objects.get_or_create(email=email_address, domain=self.object)
|
||||
return redirect(self.get_success_url())
|
||||
|
||||
def form_valid(self, form):
|
||||
"""Add the specified user on this domain."""
|
||||
"""Add the specified user on this domain.
|
||||
Throws EmailSendingError."""
|
||||
requested_email = form.cleaned_data["email"]
|
||||
requestor = self.request.user
|
||||
# look up a user with that email
|
||||
|
@ -810,7 +823,22 @@ class DomainAddUserView(DomainFormBaseView):
|
|||
return self._make_invitation(requested_email, requestor)
|
||||
else:
|
||||
# if user already exists then just send an email
|
||||
self._send_domain_invitation_email(requested_email, requestor, add_success=False)
|
||||
try:
|
||||
self._send_domain_invitation_email(requested_email, requestor, add_success=False)
|
||||
except EmailSendingError:
|
||||
logger.warn(
|
||||
"Could not send email invitation (EmailSendingError)",
|
||||
self.object,
|
||||
exc_info=True,
|
||||
)
|
||||
messages.warning(self.request, "Could not send email invitation.")
|
||||
except Exception:
|
||||
logger.warn(
|
||||
"Could not send email invitation (Other Exception)",
|
||||
self.object,
|
||||
exc_info=True,
|
||||
)
|
||||
messages.warning(self.request, "Could not send email invitation.")
|
||||
|
||||
try:
|
||||
UserDomainRole.objects.create(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue