mirror of
https://github.com/cisagov/manage.get.gov.git
synced 2025-07-23 19:20:47 +02:00
Merge branch 'main' into nmb/nameservers
This commit is contained in:
commit
d60fca1c7f
19 changed files with 899 additions and 44 deletions
4
.github/workflows/deploy-sandbox.yaml
vendored
4
.github/workflows/deploy-sandbox.yaml
vendored
|
@ -40,7 +40,7 @@ jobs:
|
||||||
docker compose run node npx gulp compile
|
docker compose run node npx gulp compile
|
||||||
- name: Collect static assets
|
- name: Collect static assets
|
||||||
working-directory: ./src
|
working-directory: ./src
|
||||||
run: docker compose run app python manage.py collectstatic
|
run: docker compose run app python manage.py collectstatic --no-input
|
||||||
- name: Deploy to cloud.gov sandbox
|
- name: Deploy to cloud.gov sandbox
|
||||||
uses: 18f/cg-deploy-action@main
|
uses: 18f/cg-deploy-action@main
|
||||||
env:
|
env:
|
||||||
|
@ -69,4 +69,4 @@ jobs:
|
||||||
owner: context.repo.owner,
|
owner: context.repo.owner,
|
||||||
repo: context.repo.repo,
|
repo: context.repo.repo,
|
||||||
body: '🥳 Successfully deployed to developer sandbox **[${{ env.ENVIRONMENT }}](https://getgov-${{ env.ENVIRONMENT }}.app.cloud.gov/)**.'
|
body: '🥳 Successfully deployed to developer sandbox **[${{ env.ENVIRONMENT }}](https://getgov-${{ env.ENVIRONMENT }}.app.cloud.gov/)**.'
|
||||||
})
|
})
|
||||||
|
|
|
@ -49,7 +49,7 @@ class ViewsTest(TestCase):
|
||||||
# assert
|
# assert
|
||||||
self.assertEqual(response.status_code, 500)
|
self.assertEqual(response.status_code, 500)
|
||||||
self.assertTemplateUsed(response, "500.html")
|
self.assertTemplateUsed(response, "500.html")
|
||||||
self.assertIn("Server Error", response.content.decode("utf-8"))
|
self.assertIn("server error", response.content.decode("utf-8"))
|
||||||
|
|
||||||
def test_login_callback_reads_next(self, mock_client):
|
def test_login_callback_reads_next(self, mock_client):
|
||||||
# setup
|
# setup
|
||||||
|
|
|
@ -55,6 +55,7 @@ admin.site.register(models.UserDomainRole, AuditedAdmin)
|
||||||
admin.site.register(models.Contact, AuditedAdmin)
|
admin.site.register(models.Contact, AuditedAdmin)
|
||||||
admin.site.register(models.DomainInvitation, AuditedAdmin)
|
admin.site.register(models.DomainInvitation, AuditedAdmin)
|
||||||
admin.site.register(models.DomainApplication, AuditedAdmin)
|
admin.site.register(models.DomainApplication, AuditedAdmin)
|
||||||
|
admin.site.register(models.DomainInformation, AuditedAdmin)
|
||||||
admin.site.register(models.Domain, AuditedAdmin)
|
admin.site.register(models.Domain, AuditedAdmin)
|
||||||
admin.site.register(models.Host, MyHostAdmin)
|
admin.site.register(models.Host, MyHostAdmin)
|
||||||
admin.site.register(models.Nameserver, MyHostAdmin)
|
admin.site.register(models.Nameserver, MyHostAdmin)
|
||||||
|
|
|
@ -417,6 +417,10 @@ footer {
|
||||||
color: color('primary');
|
color: color('primary');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.usa-identifier__logo {
|
||||||
|
height: units(7);
|
||||||
|
}
|
||||||
|
|
||||||
abbr[title] {
|
abbr[title] {
|
||||||
// workaround for underlining abbr element
|
// workaround for underlining abbr element
|
||||||
border-bottom: none;
|
border-bottom: none;
|
||||||
|
|
|
@ -44,6 +44,21 @@ class UserFixture:
|
||||||
"first_name": "Neil",
|
"first_name": "Neil",
|
||||||
"last_name": "Martinsen-Burrell",
|
"last_name": "Martinsen-Burrell",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"username": "7185e6cd-d3c8-4adc-90a3-ceddba71d24f",
|
||||||
|
"first_name": "Jon",
|
||||||
|
"last_name": "Roberts",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"username": "5f283494-31bd-49b5-b024-a7e7cae00848",
|
||||||
|
"first_name": "Rachid",
|
||||||
|
"last_name": "Mrad",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"username": "eb2214cd-fc0c-48c0-9dbd-bc4cd6820c74",
|
||||||
|
"first_name": "Alysia",
|
||||||
|
"last_name": "Broddrick",
|
||||||
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
|
|
273
src/registrar/migrations/0018_domaininformation.py
Normal file
273
src/registrar/migrations/0018_domaininformation.py
Normal file
|
@ -0,0 +1,273 @@
|
||||||
|
# Generated by Django 4.1.6 on 2023-05-08 15:30
|
||||||
|
|
||||||
|
from django.conf import settings
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
dependencies = [
|
||||||
|
("registrar", "0017_alter_domainapplication_status_and_more"),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name="DomainInformation",
|
||||||
|
fields=[
|
||||||
|
(
|
||||||
|
"id",
|
||||||
|
models.BigAutoField(
|
||||||
|
auto_created=True,
|
||||||
|
primary_key=True,
|
||||||
|
serialize=False,
|
||||||
|
verbose_name="ID",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
("created_at", models.DateTimeField(auto_now_add=True)),
|
||||||
|
("updated_at", models.DateTimeField(auto_now=True)),
|
||||||
|
(
|
||||||
|
"organization_type",
|
||||||
|
models.CharField(
|
||||||
|
blank=True,
|
||||||
|
choices=[
|
||||||
|
(
|
||||||
|
"federal",
|
||||||
|
"Federal: an agency of the U.S. government's executive, legislative, or judicial branches",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"interstate",
|
||||||
|
"Interstate: an organization of two or more states",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"state_or_territory",
|
||||||
|
"State or territory: one of the 50 U.S. states, the District of Columbia, American Samoa, Guam, Northern Mariana Islands, Puerto Rico, or the U.S. Virgin Islands",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"tribal",
|
||||||
|
"Tribal: a tribal government recognized by the federal or a state government",
|
||||||
|
),
|
||||||
|
("county", "County: a county, parish, or borough"),
|
||||||
|
("city", "City: a city, town, township, village, etc."),
|
||||||
|
(
|
||||||
|
"special_district",
|
||||||
|
"Special district: an independent organization within a single state",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"school_district",
|
||||||
|
"School district: a school district that is not part of a local government",
|
||||||
|
),
|
||||||
|
],
|
||||||
|
help_text="Type of Organization",
|
||||||
|
max_length=255,
|
||||||
|
null=True,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"federally_recognized_tribe",
|
||||||
|
models.BooleanField(
|
||||||
|
help_text="Is the tribe federally recognized", null=True
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"state_recognized_tribe",
|
||||||
|
models.BooleanField(
|
||||||
|
help_text="Is the tribe recognized by a state", null=True
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"tribe_name",
|
||||||
|
models.TextField(blank=True, help_text="Name of tribe", null=True),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"federal_agency",
|
||||||
|
models.TextField(blank=True, help_text="Federal agency", null=True),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"federal_type",
|
||||||
|
models.CharField(
|
||||||
|
blank=True,
|
||||||
|
choices=[
|
||||||
|
("executive", "Executive"),
|
||||||
|
("judicial", "Judicial"),
|
||||||
|
("legislative", "Legislative"),
|
||||||
|
],
|
||||||
|
help_text="Federal government branch",
|
||||||
|
max_length=50,
|
||||||
|
null=True,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"is_election_board",
|
||||||
|
models.BooleanField(
|
||||||
|
blank=True,
|
||||||
|
help_text="Is your organization an election office?",
|
||||||
|
null=True,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"organization_name",
|
||||||
|
models.TextField(
|
||||||
|
blank=True,
|
||||||
|
db_index=True,
|
||||||
|
help_text="Organization name",
|
||||||
|
null=True,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"address_line1",
|
||||||
|
models.TextField(blank=True, help_text="Street address", null=True),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"address_line2",
|
||||||
|
models.CharField(
|
||||||
|
blank=True,
|
||||||
|
help_text="Street address line 2",
|
||||||
|
max_length=15,
|
||||||
|
null=True,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
("city", models.TextField(blank=True, help_text="City", null=True)),
|
||||||
|
(
|
||||||
|
"state_territory",
|
||||||
|
models.CharField(
|
||||||
|
blank=True,
|
||||||
|
help_text="State, territory, or military post",
|
||||||
|
max_length=2,
|
||||||
|
null=True,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"zipcode",
|
||||||
|
models.CharField(
|
||||||
|
blank=True,
|
||||||
|
db_index=True,
|
||||||
|
help_text="Zip code",
|
||||||
|
max_length=10,
|
||||||
|
null=True,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"urbanization",
|
||||||
|
models.TextField(
|
||||||
|
blank=True,
|
||||||
|
help_text="Urbanization (Puerto Rico only)",
|
||||||
|
null=True,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"type_of_work",
|
||||||
|
models.TextField(
|
||||||
|
blank=True,
|
||||||
|
help_text="Type of work of the organization",
|
||||||
|
null=True,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"more_organization_information",
|
||||||
|
models.TextField(
|
||||||
|
blank=True,
|
||||||
|
help_text="Further information about the government organization",
|
||||||
|
null=True,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"purpose",
|
||||||
|
models.TextField(
|
||||||
|
blank=True, help_text="Purpose of your domain", null=True
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"no_other_contacts_rationale",
|
||||||
|
models.TextField(
|
||||||
|
blank=True,
|
||||||
|
help_text="Reason for listing no additional contacts",
|
||||||
|
null=True,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"anything_else",
|
||||||
|
models.TextField(
|
||||||
|
blank=True, help_text="Anything else we should know?", null=True
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"is_policy_acknowledged",
|
||||||
|
models.BooleanField(
|
||||||
|
blank=True,
|
||||||
|
help_text="Acknowledged .gov acceptable use policy",
|
||||||
|
null=True,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"security_email",
|
||||||
|
models.EmailField(
|
||||||
|
blank=True,
|
||||||
|
help_text="Security email for public use",
|
||||||
|
max_length=320,
|
||||||
|
null=True,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"authorizing_official",
|
||||||
|
models.ForeignKey(
|
||||||
|
blank=True,
|
||||||
|
null=True,
|
||||||
|
on_delete=django.db.models.deletion.PROTECT,
|
||||||
|
related_name="information_authorizing_official",
|
||||||
|
to="registrar.contact",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"creator",
|
||||||
|
models.ForeignKey(
|
||||||
|
on_delete=django.db.models.deletion.PROTECT,
|
||||||
|
related_name="information_created",
|
||||||
|
to=settings.AUTH_USER_MODEL,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"domain",
|
||||||
|
models.OneToOneField(
|
||||||
|
blank=True,
|
||||||
|
help_text="Domain to which this information belongs",
|
||||||
|
null=True,
|
||||||
|
on_delete=django.db.models.deletion.PROTECT,
|
||||||
|
related_name="domain_info",
|
||||||
|
to="registrar.domain",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"domain_application",
|
||||||
|
models.OneToOneField(
|
||||||
|
blank=True,
|
||||||
|
help_text="Associated domain application",
|
||||||
|
null=True,
|
||||||
|
on_delete=django.db.models.deletion.PROTECT,
|
||||||
|
related_name="domainapplication_info",
|
||||||
|
to="registrar.domainapplication",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"other_contacts",
|
||||||
|
models.ManyToManyField(
|
||||||
|
blank=True,
|
||||||
|
related_name="contact_applications_information",
|
||||||
|
to="registrar.contact",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"submitter",
|
||||||
|
models.ForeignKey(
|
||||||
|
blank=True,
|
||||||
|
null=True,
|
||||||
|
on_delete=django.db.models.deletion.PROTECT,
|
||||||
|
related_name="submitted_applications_information",
|
||||||
|
to="registrar.contact",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
"verbose_name_plural": "Domain Information",
|
||||||
|
},
|
||||||
|
),
|
||||||
|
]
|
|
@ -0,0 +1,47 @@
|
||||||
|
# Generated by Django 4.1.6 on 2023-05-09 19:50
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
dependencies = [
|
||||||
|
("registrar", "0018_domaininformation"),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name="domainapplication",
|
||||||
|
name="organization_type",
|
||||||
|
field=models.CharField(
|
||||||
|
blank=True,
|
||||||
|
choices=[
|
||||||
|
(
|
||||||
|
"federal",
|
||||||
|
"Federal: an agency of the U.S. government's executive, legislative, or judicial branches",
|
||||||
|
),
|
||||||
|
("interstate", "Interstate: an organization of two or more states"),
|
||||||
|
(
|
||||||
|
"state_or_territory",
|
||||||
|
"State or territory: one of the 50 U.S. states, the District of Columbia, American Samoa, Guam, Northern Mariana Islands, Puerto Rico, or the U.S. Virgin Islands",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"tribal",
|
||||||
|
"Tribal: a tribal government recognized by the federal or a state government",
|
||||||
|
),
|
||||||
|
("county", "County: a county, parish, or borough"),
|
||||||
|
("city", "City: a city, town, township, village, etc."),
|
||||||
|
(
|
||||||
|
"special_district",
|
||||||
|
"Special district: an independent organization within a single state",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"school_district",
|
||||||
|
"School district: a school district that is not part of a local government",
|
||||||
|
),
|
||||||
|
],
|
||||||
|
help_text="Type of organization",
|
||||||
|
max_length=255,
|
||||||
|
null=True,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
]
|
|
@ -2,6 +2,7 @@ from auditlog.registry import auditlog # type: ignore
|
||||||
|
|
||||||
from .contact import Contact
|
from .contact import Contact
|
||||||
from .domain_application import DomainApplication
|
from .domain_application import DomainApplication
|
||||||
|
from .domain_information import DomainInformation
|
||||||
from .domain import Domain
|
from .domain import Domain
|
||||||
from .host_ip import HostIP
|
from .host_ip import HostIP
|
||||||
from .host import Host
|
from .host import Host
|
||||||
|
@ -15,6 +16,7 @@ from .website import Website
|
||||||
__all__ = [
|
__all__ = [
|
||||||
"Contact",
|
"Contact",
|
||||||
"DomainApplication",
|
"DomainApplication",
|
||||||
|
"DomainInformation",
|
||||||
"Domain",
|
"Domain",
|
||||||
"DomainInvitation",
|
"DomainInvitation",
|
||||||
"HostIP",
|
"HostIP",
|
||||||
|
|
|
@ -9,7 +9,7 @@ from django_fsm import FSMField, transition # type: ignore
|
||||||
|
|
||||||
from .utility.time_stamped_model import TimeStampedModel
|
from .utility.time_stamped_model import TimeStampedModel
|
||||||
from ..utility.email import send_templated_email, EmailSendingError
|
from ..utility.email import send_templated_email, EmailSendingError
|
||||||
|
from itertools import chain
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -520,6 +520,10 @@ class DomainApplication(TimeStampedModel):
|
||||||
Domain = apps.get_model("registrar.Domain")
|
Domain = apps.get_model("registrar.Domain")
|
||||||
created_domain, _ = Domain.objects.get_or_create(name=self.requested_domain)
|
created_domain, _ = Domain.objects.get_or_create(name=self.requested_domain)
|
||||||
|
|
||||||
|
# copy the information from domainapplication into domaininformation
|
||||||
|
DomainInformation = apps.get_model("registrar.DomainInformation")
|
||||||
|
DomainInformation.create_from_da(self)
|
||||||
|
|
||||||
# create the permission for the user
|
# create the permission for the user
|
||||||
UserDomainRole = apps.get_model("registrar.UserDomainRole")
|
UserDomainRole = apps.get_model("registrar.UserDomainRole")
|
||||||
UserDomainRole.objects.get_or_create(
|
UserDomainRole.objects.get_or_create(
|
||||||
|
@ -577,3 +581,26 @@ class DomainApplication(TimeStampedModel):
|
||||||
if self.organization_type == DomainApplication.OrganizationChoices.FEDERAL:
|
if self.organization_type == DomainApplication.OrganizationChoices.FEDERAL:
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
def to_dict(self):
|
||||||
|
"""This is to process to_dict for Domain Information, making it friendly
|
||||||
|
to "copy" it
|
||||||
|
|
||||||
|
More information can be found at this- (This used #5)
|
||||||
|
https://stackoverflow.com/questions/21925671/convert-django-model-object-to-dict-with-all-of-the-fields-intact/29088221#29088221
|
||||||
|
""" # noqa 590
|
||||||
|
opts = self._meta
|
||||||
|
data = {}
|
||||||
|
for field in chain(opts.concrete_fields, opts.private_fields):
|
||||||
|
if field.get_internal_type() in ("ForeignKey", "OneToOneField"):
|
||||||
|
# get the related instance of the FK value
|
||||||
|
fk_id = field.value_from_object(self)
|
||||||
|
if fk_id:
|
||||||
|
data[field.name] = field.related_model.objects.get(id=fk_id)
|
||||||
|
else:
|
||||||
|
data[field.name] = None
|
||||||
|
else:
|
||||||
|
data[field.name] = field.value_from_object(self)
|
||||||
|
for field in opts.many_to_many:
|
||||||
|
data[field.name] = field.value_from_object(self)
|
||||||
|
return data
|
||||||
|
|
250
src/registrar/models/domain_information.py
Normal file
250
src/registrar/models/domain_information.py
Normal file
|
@ -0,0 +1,250 @@
|
||||||
|
from __future__ import annotations
|
||||||
|
from .domain_application import DomainApplication
|
||||||
|
from .utility.time_stamped_model import TimeStampedModel
|
||||||
|
|
||||||
|
import logging
|
||||||
|
|
||||||
|
from django.db import models
|
||||||
|
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class DomainInformation(TimeStampedModel):
|
||||||
|
|
||||||
|
"""A registrant's domain information for that domain, exported from
|
||||||
|
DomainApplication. We use these field from DomainApplication with few exceptation
|
||||||
|
which are 'removed' via pop at the bottom of this file. Most of design for domain
|
||||||
|
management's user information are based on application, but we cannot change
|
||||||
|
the application once approved, so copying them that way we can make changes
|
||||||
|
after its approved. Most fields here are copied from Application."""
|
||||||
|
|
||||||
|
StateTerritoryChoices = DomainApplication.StateTerritoryChoices
|
||||||
|
|
||||||
|
OrganizationChoices = DomainApplication.OrganizationChoices
|
||||||
|
|
||||||
|
BranchChoices = DomainApplication.BranchChoices
|
||||||
|
|
||||||
|
AGENCY_CHOICES = DomainApplication.AGENCY_CHOICES
|
||||||
|
|
||||||
|
# This is the application user who created this application. The contact
|
||||||
|
# information that they gave is in the `submitter` field
|
||||||
|
creator = models.ForeignKey(
|
||||||
|
"registrar.User",
|
||||||
|
on_delete=models.PROTECT,
|
||||||
|
related_name="information_created",
|
||||||
|
)
|
||||||
|
|
||||||
|
domain_application = models.OneToOneField(
|
||||||
|
"registrar.DomainApplication",
|
||||||
|
on_delete=models.PROTECT,
|
||||||
|
blank=True,
|
||||||
|
null=True,
|
||||||
|
related_name="domainapplication_info",
|
||||||
|
help_text="Associated domain application",
|
||||||
|
unique=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
# ##### data fields from the initial form #####
|
||||||
|
organization_type = models.CharField(
|
||||||
|
max_length=255,
|
||||||
|
choices=OrganizationChoices.choices,
|
||||||
|
null=True,
|
||||||
|
blank=True,
|
||||||
|
help_text="Type of Organization",
|
||||||
|
)
|
||||||
|
|
||||||
|
federally_recognized_tribe = models.BooleanField(
|
||||||
|
null=True,
|
||||||
|
help_text="Is the tribe federally recognized",
|
||||||
|
)
|
||||||
|
|
||||||
|
state_recognized_tribe = models.BooleanField(
|
||||||
|
null=True,
|
||||||
|
help_text="Is the tribe recognized by a state",
|
||||||
|
)
|
||||||
|
|
||||||
|
tribe_name = models.TextField(
|
||||||
|
null=True,
|
||||||
|
blank=True,
|
||||||
|
help_text="Name of tribe",
|
||||||
|
)
|
||||||
|
|
||||||
|
federal_agency = models.TextField(
|
||||||
|
null=True,
|
||||||
|
blank=True,
|
||||||
|
help_text="Federal agency",
|
||||||
|
)
|
||||||
|
|
||||||
|
federal_type = models.CharField(
|
||||||
|
max_length=50,
|
||||||
|
choices=BranchChoices.choices,
|
||||||
|
null=True,
|
||||||
|
blank=True,
|
||||||
|
help_text="Federal government branch",
|
||||||
|
)
|
||||||
|
|
||||||
|
is_election_board = models.BooleanField(
|
||||||
|
null=True,
|
||||||
|
blank=True,
|
||||||
|
help_text="Is your organization an election office?",
|
||||||
|
)
|
||||||
|
|
||||||
|
organization_name = models.TextField(
|
||||||
|
null=True,
|
||||||
|
blank=True,
|
||||||
|
help_text="Organization name",
|
||||||
|
db_index=True,
|
||||||
|
)
|
||||||
|
address_line1 = models.TextField(
|
||||||
|
null=True,
|
||||||
|
blank=True,
|
||||||
|
help_text="Street address",
|
||||||
|
)
|
||||||
|
address_line2 = models.CharField(
|
||||||
|
max_length=15,
|
||||||
|
null=True,
|
||||||
|
blank=True,
|
||||||
|
help_text="Street address line 2",
|
||||||
|
)
|
||||||
|
city = models.TextField(
|
||||||
|
null=True,
|
||||||
|
blank=True,
|
||||||
|
help_text="City",
|
||||||
|
)
|
||||||
|
state_territory = models.CharField(
|
||||||
|
max_length=2,
|
||||||
|
null=True,
|
||||||
|
blank=True,
|
||||||
|
help_text="State, territory, or military post",
|
||||||
|
)
|
||||||
|
zipcode = models.CharField(
|
||||||
|
max_length=10,
|
||||||
|
null=True,
|
||||||
|
blank=True,
|
||||||
|
help_text="Zip code",
|
||||||
|
db_index=True,
|
||||||
|
)
|
||||||
|
urbanization = models.TextField(
|
||||||
|
null=True,
|
||||||
|
blank=True,
|
||||||
|
help_text="Urbanization (Puerto Rico only)",
|
||||||
|
)
|
||||||
|
|
||||||
|
type_of_work = models.TextField(
|
||||||
|
null=True,
|
||||||
|
blank=True,
|
||||||
|
help_text="Type of work of the organization",
|
||||||
|
)
|
||||||
|
|
||||||
|
more_organization_information = models.TextField(
|
||||||
|
null=True,
|
||||||
|
blank=True,
|
||||||
|
help_text="Further information about the government organization",
|
||||||
|
)
|
||||||
|
|
||||||
|
authorizing_official = models.ForeignKey(
|
||||||
|
"registrar.Contact",
|
||||||
|
null=True,
|
||||||
|
blank=True,
|
||||||
|
related_name="information_authorizing_official",
|
||||||
|
on_delete=models.PROTECT,
|
||||||
|
)
|
||||||
|
|
||||||
|
domain = models.OneToOneField(
|
||||||
|
"registrar.Domain",
|
||||||
|
on_delete=models.PROTECT,
|
||||||
|
blank=True,
|
||||||
|
null=True,
|
||||||
|
# Access this information via Domain as "domain.domain_info"
|
||||||
|
related_name="domain_info",
|
||||||
|
help_text="Domain to which this information belongs",
|
||||||
|
)
|
||||||
|
|
||||||
|
# This is the contact information provided by the applicant. The
|
||||||
|
# application user who created it is in the `creator` field.
|
||||||
|
submitter = models.ForeignKey(
|
||||||
|
"registrar.Contact",
|
||||||
|
null=True,
|
||||||
|
blank=True,
|
||||||
|
related_name="submitted_applications_information",
|
||||||
|
on_delete=models.PROTECT,
|
||||||
|
)
|
||||||
|
|
||||||
|
purpose = models.TextField(
|
||||||
|
null=True,
|
||||||
|
blank=True,
|
||||||
|
help_text="Purpose of your domain",
|
||||||
|
)
|
||||||
|
|
||||||
|
other_contacts = models.ManyToManyField(
|
||||||
|
"registrar.Contact",
|
||||||
|
blank=True,
|
||||||
|
related_name="contact_applications_information",
|
||||||
|
)
|
||||||
|
|
||||||
|
no_other_contacts_rationale = models.TextField(
|
||||||
|
null=True,
|
||||||
|
blank=True,
|
||||||
|
help_text="Reason for listing no additional contacts",
|
||||||
|
)
|
||||||
|
|
||||||
|
anything_else = models.TextField(
|
||||||
|
null=True,
|
||||||
|
blank=True,
|
||||||
|
help_text="Anything else we should know?",
|
||||||
|
)
|
||||||
|
|
||||||
|
is_policy_acknowledged = models.BooleanField(
|
||||||
|
null=True,
|
||||||
|
blank=True,
|
||||||
|
help_text="Acknowledged .gov acceptable use policy",
|
||||||
|
)
|
||||||
|
security_email = models.EmailField(
|
||||||
|
max_length=320,
|
||||||
|
null=True,
|
||||||
|
blank=True,
|
||||||
|
help_text="Security email for public use",
|
||||||
|
)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
try:
|
||||||
|
if self.domain and self.domain.name:
|
||||||
|
return self.domain.name
|
||||||
|
else:
|
||||||
|
return f"domain info set up and created by {self.creator}"
|
||||||
|
except Exception:
|
||||||
|
return ""
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def create_from_da(cls, domain_application):
|
||||||
|
"""Takes in a DomainApplication dict and converts it into DomainInformation"""
|
||||||
|
da_dict = domain_application.to_dict()
|
||||||
|
# remove the id so one can be assinged on creation
|
||||||
|
da_id = da_dict.pop("id")
|
||||||
|
# check if we have a record that corresponds with the domain
|
||||||
|
# application, if so short circuit the create
|
||||||
|
domain_info = cls.objects.filter(domain_application__id=da_id).first()
|
||||||
|
if domain_info:
|
||||||
|
return domain_info
|
||||||
|
# the following information below is not needed in the domain information:
|
||||||
|
da_dict.pop("status")
|
||||||
|
da_dict.pop("current_websites")
|
||||||
|
da_dict.pop("investigator")
|
||||||
|
da_dict.pop("alternative_domains")
|
||||||
|
# use the requested_domain to create information for this domain
|
||||||
|
da_dict["domain"] = da_dict.pop("requested_domain")
|
||||||
|
other_contacts = da_dict.pop("other_contacts")
|
||||||
|
domain_info = cls(**da_dict)
|
||||||
|
domain_info.domain_application = domain_application
|
||||||
|
# Save so the object now have PK
|
||||||
|
# (needed to process the manytomany below before, first)
|
||||||
|
domain_info.save()
|
||||||
|
|
||||||
|
# Process the remaining "many to many" stuff
|
||||||
|
domain_info.other_contacts.add(*other_contacts)
|
||||||
|
domain_info.save()
|
||||||
|
return domain_info
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
verbose_name_plural = "Domain Information"
|
20
src/registrar/public/img/registrar/dotgov_401_illo.svg
Normal file
20
src/registrar/public/img/registrar/dotgov_401_illo.svg
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
<svg width="404" height="409" viewBox="0 0 404 409" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M291.707 328.743C240.024 358.583 133.444 374.87 78.8899 280.379C14.3648 168.618 78.2559 99.3488 140.956 63.1491C203.655 26.9495 296.801 80.4848 337.226 150.503C377.652 220.522 343.391 298.903 291.707 328.743Z" fill="#F5F8FA"/>
|
||||||
|
<circle cx="276.88" cy="130.594" r="8" transform="rotate(135 276.88 130.594)" fill="#7AA5C1"/>
|
||||||
|
<circle cx="288.196" cy="119.279" r="8" transform="rotate(135 288.196 119.279)" fill="#7AA5C1"/>
|
||||||
|
<circle cx="231.626" cy="175.849" r="8" transform="rotate(135 231.626 175.849)" fill="#7AA5C1"/>
|
||||||
|
<circle cx="186.371" cy="221.104" r="8" transform="rotate(135 186.371 221.104)" fill="#7AA5C1"/>
|
||||||
|
<circle cx="242.939" cy="164.535" r="8" transform="rotate(135 242.939 164.535)" fill="#7AA5C1"/>
|
||||||
|
<circle cx="197.686" cy="209.788" r="8" transform="rotate(135 197.686 209.788)" fill="#7AA5C1"/>
|
||||||
|
<circle cx="220.312" cy="187.163" r="8" transform="rotate(135 220.312 187.163)" fill="#7AA5C1"/>
|
||||||
|
<circle cx="175.057" cy="232.417" r="8" transform="rotate(135 175.057 232.417)" fill="#7AA5C1"/>
|
||||||
|
<circle cx="163.743" cy="243.731" r="8" transform="rotate(135 163.743 243.731)" fill="#7AA5C1"/>
|
||||||
|
<circle cx="152.43" cy="255.045" r="8" transform="rotate(135 152.43 255.045)" fill="#7AA5C1"/>
|
||||||
|
<circle cx="141.116" cy="266.358" r="8" transform="rotate(135 141.116 266.358)" fill="#7AA5C1"/>
|
||||||
|
<circle cx="129.802" cy="277.672" r="8" transform="rotate(135 129.802 277.672)" fill="#7AA5C1"/>
|
||||||
|
<circle cx="118.489" cy="288.986" r="8" transform="rotate(135 118.489 288.986)" fill="#7AA5C1"/>
|
||||||
|
<circle cx="254.253" cy="153.221" r="8" transform="rotate(135 254.253 153.221)" fill="#7AA5C1"/>
|
||||||
|
<circle cx="265.566" cy="141.908" r="8" transform="rotate(135 265.566 141.908)" fill="#7AA5C1"/>
|
||||||
|
<circle cx="208.998" cy="198.476" r="8" transform="rotate(135 208.998 198.476)" fill="#7AA5C1"/>
|
||||||
|
<circle cx="203.342" cy="203.999" r="120.001" stroke="#7AA5C1" stroke-width="16"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.9 KiB |
18
src/registrar/public/img/registrar/dotgov_404_illo.svg
Normal file
18
src/registrar/public/img/registrar/dotgov_404_illo.svg
Normal file
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 53 KiB |
59
src/registrar/public/img/registrar/dotgov_500_illo.svg
Normal file
59
src/registrar/public/img/registrar/dotgov_500_illo.svg
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
<svg width="409" height="214" viewBox="0 0 409 214" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M366.004 90.4612C372.017 135.603 322.608 199.102 196.168 205.902C-32.9139 218.22 19.0655 18.8457 205.511 8.81994C299.204 3.78172 359.99 45.3195 366.004 90.4612Z" fill="#F5F8FA"/>
|
||||||
|
<circle cx="213.873" cy="37.4943" r="6.56803" fill="#7AA5C1"/>
|
||||||
|
<circle cx="212.214" cy="58.4272" r="6.56803" fill="#7AA5C1"/>
|
||||||
|
<circle cx="231.089" cy="66.2297" r="6.56803" fill="#7AA5C1"/>
|
||||||
|
<circle cx="235.451" cy="85.568" r="6.56803" fill="#7AA5C1"/>
|
||||||
|
<circle cx="252.535" cy="99.7787" r="6.56803" fill="#7AA5C1"/>
|
||||||
|
<circle cx="273.981" cy="115.121" r="6.56803" fill="#7AA5C1"/>
|
||||||
|
<circle cx="372.072" cy="182.568" r="6.56803" fill="#7AA5C1"/>
|
||||||
|
<circle cx="402.423" cy="189.642" r="6.56803" fill="#7AA5C1"/>
|
||||||
|
<circle cx="220.441" cy="99.6379" r="6.56803" fill="#7AA5C1"/>
|
||||||
|
<circle cx="231.089" cy="118.336" r="6.56803" fill="#7AA5C1"/>
|
||||||
|
<circle cx="262.722" cy="143.568" r="6.56803" fill="#7AA5C1"/>
|
||||||
|
<circle cx="248.722" cy="125.568" r="6.56803" fill="#7AA5C1"/>
|
||||||
|
<circle cx="288.537" cy="138.04" r="6.56803" fill="#7AA5C1"/>
|
||||||
|
<circle cx="300.051" cy="160.304" r="6.56803" fill="#7AA5C1"/>
|
||||||
|
<circle cx="338.722" cy="170.568" r="6.56803" fill="#7AA5C1"/>
|
||||||
|
<circle cx="349.914" cy="189.575" r="6.56803" fill="#7AA5C1"/>
|
||||||
|
<circle cx="330.21" cy="189.575" r="6.56803" fill="#7AA5C1"/>
|
||||||
|
<circle cx="316.722" cy="173.568" r="6.56803" fill="#7AA5C1"/>
|
||||||
|
<circle cx="305.722" cy="190.568" r="6.56803" fill="#7AA5C1"/>
|
||||||
|
<circle cx="287.722" cy="184.568" r="6.56803" fill="#7AA5C1"/>
|
||||||
|
<circle cx="269.894" cy="183.007" r="6.56803" fill="#7AA5C1"/>
|
||||||
|
<circle cx="250.19" cy="189.575" r="6.56803" fill="#7AA5C1"/>
|
||||||
|
<circle cx="220.722" cy="192.568" r="6.56803" fill="#7AA5C1"/>
|
||||||
|
<circle cx="233.722" cy="173.568" r="6.56803" fill="#7AA5C1"/>
|
||||||
|
<circle cx="252.722" cy="165.568" r="6.56803" fill="#7AA5C1"/>
|
||||||
|
<circle cx="180.203" cy="189.575" r="6.56803" fill="#7AA5C1"/>
|
||||||
|
<circle cx="161.329" cy="196.143" r="6.56803" fill="#7AA5C1"/>
|
||||||
|
<circle cx="140.795" cy="189.575" r="6.56803" fill="#7AA5C1"/>
|
||||||
|
<path d="M122.733 189.575C122.733 193.203 119.793 196.143 116.165 196.143C112.538 196.143 109.597 193.203 109.597 189.575C109.597 185.948 112.538 183.007 116.165 183.007C119.793 183.007 122.733 185.948 122.733 189.575Z" fill="#7AA5C1"/>
|
||||||
|
<circle cx="91.5343" cy="189.642" r="6.56803" fill="#7AA5C1"/>
|
||||||
|
<circle cx="57.8852" cy="185.432" r="6.56803" fill="#7AA5C1"/>
|
||||||
|
<circle cx="198.722" cy="195.568" r="6.56803" fill="#7AA5C1"/>
|
||||||
|
<circle cx="193.34" cy="70.2917" r="6.56803" fill="#7AA5C1"/>
|
||||||
|
<circle cx="98.9323" cy="156.735" r="6.56803" fill="#7AA5C1"/>
|
||||||
|
<circle cx="25.247" cy="189.642" r="6.56803" fill="#7AA5C1"/>
|
||||||
|
<circle cx="7.26164" cy="190.584" r="6.56803" fill="#7AA5C1"/>
|
||||||
|
<circle cx="76.7592" cy="173.44" r="6.56803" fill="#7AA5C1"/>
|
||||||
|
<circle cx="129.722" cy="172.568" r="6.56803" fill="#7AA5C1"/>
|
||||||
|
<circle cx="147.722" cy="164.568" r="6.56803" fill="#7AA5C1"/>
|
||||||
|
<circle cx="164.722" cy="173.568" r="6.56803" fill="#7AA5C1"/>
|
||||||
|
<circle cx="174.465" cy="150.167" r="6.56803" fill="#7AA5C1"/>
|
||||||
|
<circle cx="186.771" cy="169.871" r="6.56803" fill="#7AA5C1"/>
|
||||||
|
<circle cx="198.266" cy="150.167" r="6.56803" fill="#7AA5C1"/>
|
||||||
|
<circle cx="232.747" cy="151.176" r="6.56803" fill="#7AA5C1"/>
|
||||||
|
<circle cx="273.722" cy="162.568" r="6.56803" fill="#7AA5C1"/>
|
||||||
|
<circle cx="210.589" cy="163.303" r="6.56803" fill="#7AA5C1"/>
|
||||||
|
<circle cx="204.834" cy="124.904" r="6.56803" fill="#7AA5C1"/>
|
||||||
|
<circle cx="193.34" cy="108.553" r="6.56803" fill="#7AA5C1"/>
|
||||||
|
<circle cx="171.181" cy="119.345" r="6.56803" fill="#7AA5C1"/>
|
||||||
|
<circle cx="160.499" cy="138.04" r="6.56803" fill="#7AA5C1"/>
|
||||||
|
<circle cx="139.153" cy="144.608" r="6.56803" fill="#7AA5C1"/>
|
||||||
|
<circle cx="170.351" cy="95.4167" r="6.56803" fill="#7AA5C1"/>
|
||||||
|
<circle cx="151.477" cy="115.121" r="6.56803" fill="#7AA5C1"/>
|
||||||
|
<circle cx="125.204" cy="137.031" r="6.56803" fill="#7AA5C1"/>
|
||||||
|
<circle cx="112.881" cy="163.303" r="6.56803" fill="#7AA5C1"/>
|
||||||
|
<circle cx="204.834" cy="86.6427" r="6.56803" fill="#7AA5C1"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 3.9 KiB |
|
@ -1,28 +1,45 @@
|
||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
{% load i18n %}
|
{% load i18n static %}
|
||||||
|
|
||||||
{% block title %}{% translate "Unauthorized" %}{% endblock %}
|
{% block title %}{% translate "Unauthorized | " %}{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<main id="main-content" class="grid-container">
|
<main id="main-content" class="grid-container">
|
||||||
<h1>{% translate "Unauthorized" %}</h1>
|
<div class="grid-row grow-gap">
|
||||||
|
<div class="tablet:grid-col-6 usa-prose margin-bottom-3">
|
||||||
|
<h1>
|
||||||
|
{% translate "You are not authorized to view this page" %}
|
||||||
|
</h1>
|
||||||
|
<h2>
|
||||||
|
{% translate "Status 401" %}
|
||||||
|
</h2>
|
||||||
|
|
||||||
{% if friendly_message %}
|
|
||||||
<p>{{ friendly_message }}</p>
|
|
||||||
{% else %}
|
|
||||||
<p>{% translate "Authorization failed." %}</p>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
<p><a href="{% url 'login' %}">
|
{% if friendly_message %}
|
||||||
{% translate "Would you like to try logging in again?" %}
|
<p>{{ friendly_message }}</p>
|
||||||
</a></p>
|
{% else %}
|
||||||
|
<p>{% translate "Authorization failed." %}</p>
|
||||||
|
{% endif %}
|
||||||
|
<p>
|
||||||
|
You must be an authorized user and need to be signed in to view this page.
|
||||||
|
Would you like to <a href="{% url 'login' %}"> try logging in again?</a>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
If you would like help with this error <a href="https://federalist-877ab29f-16f6-4f12-961c-96cf064cf070.sites.pages.cloud.gov/site/cisagov/getgov-home/contact/"> contact us </a>
|
||||||
|
</p>
|
||||||
|
|
||||||
{% if log_identifier %}
|
{% if log_identifier %}
|
||||||
<p>Here's a unique identifier for this error.</p>
|
<p>Here's a unique identifier for this error.</p>
|
||||||
<blockquote>{{ log_identifier }}</blockquote>
|
<p class="text-semibold">{{ log_identifier }}</p>
|
||||||
<p>{% translate "Please include it if you contact us." %}</p>
|
<p>{% translate "Please include it if you contact us." %}</p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
</div>
|
||||||
TODO: Content team to create a "how to contact us" footer for the error pages
|
<div class="tablet:grid-col-4">
|
||||||
|
<img
|
||||||
|
src="{% static 'img/registrar/dotgov_401_illo.svg' %}"
|
||||||
|
alt=""
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</main>
|
</main>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
45
src/registrar/templates/403.html
Normal file
45
src/registrar/templates/403.html
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
{% extends "base.html" %}
|
||||||
|
{% load i18n static %}
|
||||||
|
|
||||||
|
{% block title %}{% translate "Forbidden | " %}{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<main id="main-content" class="grid-container">
|
||||||
|
<div class="grid-row grow-gap">
|
||||||
|
<div class="tablet:grid-col-6 usa-prose margin-bottom-3">
|
||||||
|
<h1>
|
||||||
|
{% translate "You do not have the right permissions to view this page." %}
|
||||||
|
</h1>
|
||||||
|
<h2>
|
||||||
|
{% translate "Status 403" %}
|
||||||
|
</h2>
|
||||||
|
|
||||||
|
|
||||||
|
{% if friendly_message %}
|
||||||
|
<p>{{ friendly_message }}</p>
|
||||||
|
{% else %}
|
||||||
|
<p>{% translate "Forbidden." %}</p>
|
||||||
|
{% endif %}
|
||||||
|
<p>
|
||||||
|
You must be an authorized user and need to be signed in to view this page.
|
||||||
|
Would you like to <a href="{% url 'login' %}"> try logging in again?</a>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
If you would like help with this error <a href="https://federalist-877ab29f-16f6-4f12-961c-96cf064cf070.sites.pages.cloud.gov/site/cisagov/getgov-home/contact/"> contact us </a>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
{% if log_identifier %}
|
||||||
|
<p>Here's a unique identifier for this error.</p>
|
||||||
|
<p class="text-semibold">{{ log_identifier }}</p>
|
||||||
|
<p>{% translate "Please include it if you contact us." %}</p>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
<div class="tablet:grid-col-4">
|
||||||
|
<img
|
||||||
|
src="{% static 'img/registrar/dotgov_401_illo.svg' %}"
|
||||||
|
alt=""
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
{% endblock %}
|
|
@ -1,15 +1,31 @@
|
||||||
|
|
||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
{% load i18n %}
|
{% load i18n static %}
|
||||||
|
|
||||||
{% block title %}{% translate "Page not found" %}{% endblock %}
|
{% block title %}{% translate "Page not found | " %}{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<main id="main-content" class="grid-container">
|
<main id="main-content" class="grid-container">
|
||||||
|
<div class="grid-row grid-gap">
|
||||||
|
<div class="tablet:grid-col-6 usa-prose margin-bottom-3">
|
||||||
|
<h1>
|
||||||
|
{% translate "We couldn’t find that page" %}
|
||||||
|
</h1>
|
||||||
|
<h2>
|
||||||
|
{% translate "Status 404" %}
|
||||||
|
</h2>
|
||||||
|
|
||||||
<h1>{% translate "Page not found" %}</h1>
|
<p> Try going to the <a href="/">homepage</a>. If you can’t find what you’re looking for, <a href= "https://federalist-877ab29f-16f6-4f12-961c-96cf064cf070.sites.pages.cloud.gov/site/cisagov/getgov-home/contact/">contact us.</a>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="tablet:grid-col-4">
|
||||||
|
<img
|
||||||
|
src="{% static 'img/registrar/dotgov_404_illo.svg' %}"
|
||||||
|
alt=""
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<p>{% translate "The requested page could not be found." %}</p>
|
|
||||||
|
|
||||||
</main>
|
</main>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -1,24 +1,39 @@
|
||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
{% load i18n %}
|
{% load i18n static %}
|
||||||
|
|
||||||
{% block title %}{% translate "Server error" %}{% endblock %}
|
{% block title %}{% translate "Server error | " %}{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<main id="main-content" class="grid-container">
|
<main id="main-content" class="grid-container">
|
||||||
<h1>{% translate "Server Error" %}</h1>
|
<div class="grid-row grid-gap">
|
||||||
|
<div class="tablet:grid-col-6 usa-prose margin-bottom-3">
|
||||||
|
<h1>
|
||||||
|
{% translate "We're having some trouble" %}
|
||||||
|
</h1>
|
||||||
|
<h2>
|
||||||
|
{% translate "Status 500 – server error" %}
|
||||||
|
</h2>
|
||||||
|
{% if friendly_message %}
|
||||||
|
<p>{{ friendly_message }}</p>
|
||||||
|
{% else %}
|
||||||
|
<p>
|
||||||
|
Sorry! Try waiting a few minutes and then reloading the page.
|
||||||
|
<a href="https://federalist-877ab29f-16f6-4f12-961c-96cf064cf070.sites.pages.cloud.gov/site/cisagov/getgov-home/contact/"> Contact us </a> if you need help.
|
||||||
|
</p>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
{% if friendly_message %}
|
{% if log_identifier %}
|
||||||
<p>{{ friendly_message }}</p>
|
<p>Here's a unique identifier for this error.</p>
|
||||||
{% else %}
|
<p class="text-semibold">{{ log_identifier }}</p>
|
||||||
<p>{% translate "An internal server error occurred." %}</p>
|
<p>{% translate "Please include it if you contact us." %}</p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
</div>
|
||||||
{% if log_identifier %}
|
<div class="tablet:grid-col-4 flex-align-self-end">
|
||||||
<p>Here's a unique identifier for this error.</p>
|
<img
|
||||||
<blockquote>{{ log_identifier }}</blockquote>
|
src="{%static 'img/registrar/dotgov_500_illo.svg' %}"
|
||||||
<p>{% translate "Please include it if you contact us." %}</p>
|
alt=""
|
||||||
{% endif %}
|
/>
|
||||||
|
</div>
|
||||||
TODO: Content team to create a "how to contact us" footer for the error pages
|
</div>
|
||||||
</main>
|
</main>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -52,7 +52,7 @@
|
||||||
src="{% static 'img/CISA_logo.png' %}"
|
src="{% static 'img/CISA_logo.png' %}"
|
||||||
alt="CISA logo"
|
alt="CISA logo"
|
||||||
role="img"
|
role="img"
|
||||||
width="48px"
|
width="56px"
|
||||||
/></a>
|
/></a>
|
||||||
</div>
|
</div>
|
||||||
<section
|
<section
|
||||||
|
|
|
@ -4,6 +4,7 @@ from django.db.utils import IntegrityError
|
||||||
from registrar.models import (
|
from registrar.models import (
|
||||||
Contact,
|
Contact,
|
||||||
DomainApplication,
|
DomainApplication,
|
||||||
|
DomainInformation,
|
||||||
User,
|
User,
|
||||||
Website,
|
Website,
|
||||||
Domain,
|
Domain,
|
||||||
|
@ -63,6 +64,33 @@ class TestDomainApplication(TestCase):
|
||||||
application.other_contacts.add(contact)
|
application.other_contacts.add(contact)
|
||||||
application.save()
|
application.save()
|
||||||
|
|
||||||
|
def test_domain_info(self):
|
||||||
|
"""Can create domain info with all fields."""
|
||||||
|
user, _ = User.objects.get_or_create()
|
||||||
|
contact = Contact.objects.create()
|
||||||
|
domain, _ = Domain.objects.get_or_create(name="igorville.gov")
|
||||||
|
information = DomainInformation.objects.create(
|
||||||
|
creator=user,
|
||||||
|
organization_type=DomainInformation.OrganizationChoices.FEDERAL,
|
||||||
|
federal_type=DomainInformation.BranchChoices.EXECUTIVE,
|
||||||
|
is_election_board=False,
|
||||||
|
organization_name="Test",
|
||||||
|
address_line1="100 Main St.",
|
||||||
|
address_line2="APT 1A",
|
||||||
|
state_territory="CA",
|
||||||
|
zipcode="12345-6789",
|
||||||
|
authorizing_official=contact,
|
||||||
|
submitter=contact,
|
||||||
|
purpose="Igorville rules!",
|
||||||
|
anything_else="All of Igorville loves the dotgov program.",
|
||||||
|
is_policy_acknowledged=True,
|
||||||
|
domain=domain,
|
||||||
|
)
|
||||||
|
information.other_contacts.add(contact)
|
||||||
|
information.save()
|
||||||
|
self.assertEqual(information.domain.id, domain.id)
|
||||||
|
self.assertEqual(information.id, domain.domain_info.id)
|
||||||
|
|
||||||
def test_status_fsm_submit_fail(self):
|
def test_status_fsm_submit_fail(self):
|
||||||
user, _ = User.objects.get_or_create()
|
user, _ = User.objects.get_or_create()
|
||||||
application = DomainApplication.objects.create(creator=user)
|
application = DomainApplication.objects.create(creator=user)
|
||||||
|
@ -166,6 +194,24 @@ class TestPermissions(TestCase):
|
||||||
self.assertTrue(UserDomainRole.objects.get(user=user, domain=domain))
|
self.assertTrue(UserDomainRole.objects.get(user=user, domain=domain))
|
||||||
|
|
||||||
|
|
||||||
|
class TestDomainInfo(TestCase):
|
||||||
|
|
||||||
|
"""Test creation of Domain Information when approved."""
|
||||||
|
|
||||||
|
def test_approval_creates_info(self):
|
||||||
|
domain, _ = Domain.objects.get_or_create(name="igorville.gov")
|
||||||
|
user, _ = User.objects.get_or_create()
|
||||||
|
application = DomainApplication.objects.create(
|
||||||
|
creator=user, requested_domain=domain
|
||||||
|
)
|
||||||
|
# skip using the submit method
|
||||||
|
application.status = DomainApplication.SUBMITTED
|
||||||
|
application.approve()
|
||||||
|
|
||||||
|
# should be an information present for this domain
|
||||||
|
self.assertTrue(DomainInformation.objects.get(domain=domain))
|
||||||
|
|
||||||
|
|
||||||
class TestInvitations(TestCase):
|
class TestInvitations(TestCase):
|
||||||
|
|
||||||
"""Test the retrieval of invitations."""
|
"""Test the retrieval of invitations."""
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue