mirror of
https://github.com/cisagov/manage.get.gov.git
synced 2025-05-17 18:09:25 +02:00
Merge branch 'main' into nl/1895-CISA-regions-questions-domain-req
This commit is contained in:
commit
1eb9b080a6
17 changed files with 683 additions and 46 deletions
|
@ -290,6 +290,13 @@ class CustomLogEntryAdmin(LogEntryAdmin):
|
||||||
# Return the field value without a link
|
# Return the field value without a link
|
||||||
return f"{obj.content_type} - {obj.object_repr}"
|
return f"{obj.content_type} - {obj.object_repr}"
|
||||||
|
|
||||||
|
# We name the custom prop 'created_at' because linter
|
||||||
|
# is not allowing a short_description attr on it
|
||||||
|
# This gets around the linter limitation, for now.
|
||||||
|
@admin.display(description=_("Created at"))
|
||||||
|
def created(self, obj):
|
||||||
|
return obj.timestamp
|
||||||
|
|
||||||
search_help_text = "Search by resource, changes, or user."
|
search_help_text = "Search by resource, changes, or user."
|
||||||
|
|
||||||
change_form_template = "admin/change_form_no_submit.html"
|
change_form_template = "admin/change_form_no_submit.html"
|
||||||
|
@ -478,7 +485,7 @@ class MyUserAdmin(BaseUserAdmin):
|
||||||
|
|
||||||
list_display = (
|
list_display = (
|
||||||
"username",
|
"username",
|
||||||
"email",
|
"overridden_email_field",
|
||||||
"first_name",
|
"first_name",
|
||||||
"last_name",
|
"last_name",
|
||||||
# Group is a custom property defined within this file,
|
# Group is a custom property defined within this file,
|
||||||
|
@ -487,6 +494,18 @@ class MyUserAdmin(BaseUserAdmin):
|
||||||
"status",
|
"status",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Renames inherited AbstractUser label 'email_address to 'email'
|
||||||
|
def formfield_for_dbfield(self, dbfield, **kwargs):
|
||||||
|
field = super().formfield_for_dbfield(dbfield, **kwargs)
|
||||||
|
if dbfield.name == "email":
|
||||||
|
field.label = "Email"
|
||||||
|
return field
|
||||||
|
|
||||||
|
# Renames inherited AbstractUser column name 'email_address to 'email'
|
||||||
|
@admin.display(description=_("Email"))
|
||||||
|
def overridden_email_field(self, obj):
|
||||||
|
return obj.email
|
||||||
|
|
||||||
fieldsets = (
|
fieldsets = (
|
||||||
(
|
(
|
||||||
None,
|
None,
|
||||||
|
@ -561,6 +580,7 @@ class MyUserAdmin(BaseUserAdmin):
|
||||||
# this ordering effects the ordering of results
|
# this ordering effects the ordering of results
|
||||||
# in autocomplete_fields for user
|
# in autocomplete_fields for user
|
||||||
ordering = ["first_name", "last_name", "email"]
|
ordering = ["first_name", "last_name", "email"]
|
||||||
|
search_help_text = "Search by first name, last name, or email."
|
||||||
|
|
||||||
change_form_template = "django/admin/email_clipboard_change_form.html"
|
change_form_template = "django/admin/email_clipboard_change_form.html"
|
||||||
|
|
||||||
|
@ -651,7 +671,7 @@ class MyHostAdmin(AuditedAdmin):
|
||||||
"""Custom host admin class to use our inlines."""
|
"""Custom host admin class to use our inlines."""
|
||||||
|
|
||||||
search_fields = ["name", "domain__name"]
|
search_fields = ["name", "domain__name"]
|
||||||
search_help_text = "Search by domain or hostname."
|
search_help_text = "Search by domain or host name."
|
||||||
inlines = [HostIPInline]
|
inlines = [HostIPInline]
|
||||||
|
|
||||||
|
|
||||||
|
@ -659,9 +679,9 @@ class ContactAdmin(ListHeaderAdmin):
|
||||||
"""Custom contact admin class to add search."""
|
"""Custom contact admin class to add search."""
|
||||||
|
|
||||||
search_fields = ["email", "first_name", "last_name"]
|
search_fields = ["email", "first_name", "last_name"]
|
||||||
search_help_text = "Search by firstname, lastname or email."
|
search_help_text = "Search by first name, last name or email."
|
||||||
list_display = [
|
list_display = [
|
||||||
"contact",
|
"name",
|
||||||
"email",
|
"email",
|
||||||
"user_exists",
|
"user_exists",
|
||||||
]
|
]
|
||||||
|
@ -690,7 +710,7 @@ class ContactAdmin(ListHeaderAdmin):
|
||||||
# We name the custom prop 'contact' because linter
|
# We name the custom prop 'contact' because linter
|
||||||
# is not allowing a short_description attr on it
|
# is not allowing a short_description attr on it
|
||||||
# This gets around the linter limitation, for now.
|
# This gets around the linter limitation, for now.
|
||||||
def contact(self, obj: models.Contact):
|
def name(self, obj: models.Contact):
|
||||||
"""Duplicate the contact _str_"""
|
"""Duplicate the contact _str_"""
|
||||||
if obj.first_name or obj.last_name:
|
if obj.first_name or obj.last_name:
|
||||||
return obj.get_formatted_name()
|
return obj.get_formatted_name()
|
||||||
|
@ -701,7 +721,7 @@ class ContactAdmin(ListHeaderAdmin):
|
||||||
else:
|
else:
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
contact.admin_order_field = "first_name" # type: ignore
|
name.admin_order_field = "first_name" # type: ignore
|
||||||
|
|
||||||
# Read only that we'll leverage for CISA Analysts
|
# Read only that we'll leverage for CISA Analysts
|
||||||
analyst_readonly_fields = [
|
analyst_readonly_fields = [
|
||||||
|
@ -859,7 +879,7 @@ class UserDomainRoleAdmin(ListHeaderAdmin):
|
||||||
"domain__name",
|
"domain__name",
|
||||||
"role",
|
"role",
|
||||||
]
|
]
|
||||||
search_help_text = "Search by firstname, lastname, email, domain, or role."
|
search_help_text = "Search by first name, last name, email, or domain."
|
||||||
|
|
||||||
autocomplete_fields = ["user", "domain"]
|
autocomplete_fields = ["user", "domain"]
|
||||||
|
|
||||||
|
@ -959,7 +979,9 @@ class DomainInformationAdmin(ListHeaderAdmin):
|
||||||
"classes": ["collapse"],
|
"classes": ["collapse"],
|
||||||
"fields": [
|
"fields": [
|
||||||
"federal_type",
|
"federal_type",
|
||||||
"federal_agency",
|
# "updated_federal_agency",
|
||||||
|
# Above field commented out so it won't display
|
||||||
|
"federal_agency", # TODO: remove later
|
||||||
"tribe_name",
|
"tribe_name",
|
||||||
"federally_recognized_tribe",
|
"federally_recognized_tribe",
|
||||||
"state_recognized_tribe",
|
"state_recognized_tribe",
|
||||||
|
@ -1208,7 +1230,9 @@ class DomainRequestAdmin(ListHeaderAdmin):
|
||||||
"classes": ["collapse"],
|
"classes": ["collapse"],
|
||||||
"fields": [
|
"fields": [
|
||||||
"federal_type",
|
"federal_type",
|
||||||
"federal_agency",
|
# "updated_federal_agency",
|
||||||
|
# Above field commented out so it won't display
|
||||||
|
"federal_agency", # TODO: remove later
|
||||||
"tribe_name",
|
"tribe_name",
|
||||||
"federally_recognized_tribe",
|
"federally_recognized_tribe",
|
||||||
"state_recognized_tribe",
|
"state_recognized_tribe",
|
||||||
|
@ -1665,6 +1689,7 @@ class DomainAdmin(ListHeaderAdmin):
|
||||||
|
|
||||||
city.admin_order_field = "domain_info__city" # type: ignore
|
city.admin_order_field = "domain_info__city" # type: ignore
|
||||||
|
|
||||||
|
@admin.display(description=_("State / territory"))
|
||||||
def state_territory(self, obj):
|
def state_territory(self, obj):
|
||||||
return obj.domain_info.state_territory if obj.domain_info else None
|
return obj.domain_info.state_territory if obj.domain_info else None
|
||||||
|
|
||||||
|
@ -1979,6 +2004,11 @@ class DraftDomainAdmin(ListHeaderAdmin):
|
||||||
# this ordering effects the ordering of results
|
# this ordering effects the ordering of results
|
||||||
# in autocomplete_fields for user
|
# in autocomplete_fields for user
|
||||||
ordering = ["name"]
|
ordering = ["name"]
|
||||||
|
list_display = ["name"]
|
||||||
|
|
||||||
|
@admin.display(description=_("Requested domain"))
|
||||||
|
def name(self, obj):
|
||||||
|
return obj.name
|
||||||
|
|
||||||
def get_model_perms(self, request):
|
def get_model_perms(self, request):
|
||||||
"""
|
"""
|
||||||
|
@ -2057,13 +2087,36 @@ class FederalAgencyAdmin(ListHeaderAdmin):
|
||||||
ordering = ["agency"]
|
ordering = ["agency"]
|
||||||
|
|
||||||
|
|
||||||
|
class UserGroupAdmin(AuditedAdmin):
|
||||||
|
"""Overwrite the generated UserGroup admin class"""
|
||||||
|
|
||||||
|
list_display = ["user_group"]
|
||||||
|
|
||||||
|
fieldsets = ((None, {"fields": ("name", "permissions")}),)
|
||||||
|
|
||||||
|
def formfield_for_dbfield(self, dbfield, **kwargs):
|
||||||
|
field = super().formfield_for_dbfield(dbfield, **kwargs)
|
||||||
|
if dbfield.name == "name":
|
||||||
|
field.label = "Group name"
|
||||||
|
if dbfield.name == "permissions":
|
||||||
|
field.label = "User permissions"
|
||||||
|
return field
|
||||||
|
|
||||||
|
# We name the custom prop 'Group' because linter
|
||||||
|
# is not allowing a short_description attr on it
|
||||||
|
# This gets around the linter limitation, for now.
|
||||||
|
@admin.display(description=_("Group"))
|
||||||
|
def user_group(self, obj):
|
||||||
|
return obj.name
|
||||||
|
|
||||||
|
|
||||||
admin.site.unregister(LogEntry) # Unregister the default registration
|
admin.site.unregister(LogEntry) # Unregister the default registration
|
||||||
admin.site.register(LogEntry, CustomLogEntryAdmin)
|
admin.site.register(LogEntry, CustomLogEntryAdmin)
|
||||||
admin.site.register(models.User, MyUserAdmin)
|
admin.site.register(models.User, MyUserAdmin)
|
||||||
# Unregister the built-in Group model
|
# Unregister the built-in Group model
|
||||||
admin.site.unregister(Group)
|
admin.site.unregister(Group)
|
||||||
# Register UserGroup
|
# Register UserGroup
|
||||||
admin.site.register(models.UserGroup)
|
admin.site.register(models.UserGroup, UserGroupAdmin)
|
||||||
admin.site.register(models.UserDomainRole, UserDomainRoleAdmin)
|
admin.site.register(models.UserDomainRole, UserDomainRoleAdmin)
|
||||||
admin.site.register(models.Contact, ContactAdmin)
|
admin.site.register(models.Contact, ContactAdmin)
|
||||||
admin.site.register(models.DomainInvitation, DomainInvitationAdmin)
|
admin.site.register(models.DomainInvitation, DomainInvitationAdmin)
|
||||||
|
|
|
@ -0,0 +1,382 @@
|
||||||
|
# Generated by Django 4.2.10 on 2024-04-18 18:01
|
||||||
|
|
||||||
|
import django.core.validators
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django_fsm
|
||||||
|
import registrar.models.utility.domain_field
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
("registrar", "0084_create_groups_v11"),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name="contact",
|
||||||
|
name="first_name",
|
||||||
|
field=models.CharField(blank=True, db_index=True, null=True, verbose_name="first name"),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name="contact",
|
||||||
|
name="last_name",
|
||||||
|
field=models.CharField(blank=True, db_index=True, null=True, verbose_name="last name"),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name="contact",
|
||||||
|
name="title",
|
||||||
|
field=models.CharField(blank=True, null=True, verbose_name="title / role"),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name="domain",
|
||||||
|
name="deleted",
|
||||||
|
field=models.DateField(editable=False, help_text="Deleted at date", null=True, verbose_name="deleted on"),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name="domain",
|
||||||
|
name="first_ready",
|
||||||
|
field=models.DateField(
|
||||||
|
editable=False,
|
||||||
|
help_text="The last time this domain moved into the READY state",
|
||||||
|
null=True,
|
||||||
|
verbose_name="first ready on",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name="domain",
|
||||||
|
name="name",
|
||||||
|
field=registrar.models.utility.domain_field.DomainField(
|
||||||
|
default=None,
|
||||||
|
help_text="Fully qualified domain name",
|
||||||
|
max_length=253,
|
||||||
|
unique=True,
|
||||||
|
verbose_name="domain",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name="domain",
|
||||||
|
name="state",
|
||||||
|
field=django_fsm.FSMField(
|
||||||
|
choices=[
|
||||||
|
("unknown", "Unknown"),
|
||||||
|
("dns needed", "Dns needed"),
|
||||||
|
("ready", "Ready"),
|
||||||
|
("on hold", "On hold"),
|
||||||
|
("deleted", "Deleted"),
|
||||||
|
],
|
||||||
|
default="unknown",
|
||||||
|
help_text="Very basic info about the lifecycle of this domain object",
|
||||||
|
max_length=21,
|
||||||
|
protected=True,
|
||||||
|
verbose_name="domain state",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name="domaininformation",
|
||||||
|
name="address_line1",
|
||||||
|
field=models.CharField(blank=True, help_text="Street address", null=True, verbose_name="address line 1"),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name="domaininformation",
|
||||||
|
name="address_line2",
|
||||||
|
field=models.CharField(
|
||||||
|
blank=True, help_text="Street address line 2 (optional)", null=True, verbose_name="address line 2"
|
||||||
|
),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name="domaininformation",
|
||||||
|
name="is_election_board",
|
||||||
|
field=models.BooleanField(
|
||||||
|
blank=True,
|
||||||
|
help_text="Is your organization an election office?",
|
||||||
|
null=True,
|
||||||
|
verbose_name="election office",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name="domaininformation",
|
||||||
|
name="state_territory",
|
||||||
|
field=models.CharField(
|
||||||
|
blank=True,
|
||||||
|
choices=[
|
||||||
|
("AL", "Alabama (AL)"),
|
||||||
|
("AK", "Alaska (AK)"),
|
||||||
|
("AS", "American Samoa (AS)"),
|
||||||
|
("AZ", "Arizona (AZ)"),
|
||||||
|
("AR", "Arkansas (AR)"),
|
||||||
|
("CA", "California (CA)"),
|
||||||
|
("CO", "Colorado (CO)"),
|
||||||
|
("CT", "Connecticut (CT)"),
|
||||||
|
("DE", "Delaware (DE)"),
|
||||||
|
("DC", "District of Columbia (DC)"),
|
||||||
|
("FL", "Florida (FL)"),
|
||||||
|
("GA", "Georgia (GA)"),
|
||||||
|
("GU", "Guam (GU)"),
|
||||||
|
("HI", "Hawaii (HI)"),
|
||||||
|
("ID", "Idaho (ID)"),
|
||||||
|
("IL", "Illinois (IL)"),
|
||||||
|
("IN", "Indiana (IN)"),
|
||||||
|
("IA", "Iowa (IA)"),
|
||||||
|
("KS", "Kansas (KS)"),
|
||||||
|
("KY", "Kentucky (KY)"),
|
||||||
|
("LA", "Louisiana (LA)"),
|
||||||
|
("ME", "Maine (ME)"),
|
||||||
|
("MD", "Maryland (MD)"),
|
||||||
|
("MA", "Massachusetts (MA)"),
|
||||||
|
("MI", "Michigan (MI)"),
|
||||||
|
("MN", "Minnesota (MN)"),
|
||||||
|
("MS", "Mississippi (MS)"),
|
||||||
|
("MO", "Missouri (MO)"),
|
||||||
|
("MT", "Montana (MT)"),
|
||||||
|
("NE", "Nebraska (NE)"),
|
||||||
|
("NV", "Nevada (NV)"),
|
||||||
|
("NH", "New Hampshire (NH)"),
|
||||||
|
("NJ", "New Jersey (NJ)"),
|
||||||
|
("NM", "New Mexico (NM)"),
|
||||||
|
("NY", "New York (NY)"),
|
||||||
|
("NC", "North Carolina (NC)"),
|
||||||
|
("ND", "North Dakota (ND)"),
|
||||||
|
("MP", "Northern Mariana Islands (MP)"),
|
||||||
|
("OH", "Ohio (OH)"),
|
||||||
|
("OK", "Oklahoma (OK)"),
|
||||||
|
("OR", "Oregon (OR)"),
|
||||||
|
("PA", "Pennsylvania (PA)"),
|
||||||
|
("PR", "Puerto Rico (PR)"),
|
||||||
|
("RI", "Rhode Island (RI)"),
|
||||||
|
("SC", "South Carolina (SC)"),
|
||||||
|
("SD", "South Dakota (SD)"),
|
||||||
|
("TN", "Tennessee (TN)"),
|
||||||
|
("TX", "Texas (TX)"),
|
||||||
|
("UM", "United States Minor Outlying Islands (UM)"),
|
||||||
|
("UT", "Utah (UT)"),
|
||||||
|
("VT", "Vermont (VT)"),
|
||||||
|
("VI", "Virgin Islands (VI)"),
|
||||||
|
("VA", "Virginia (VA)"),
|
||||||
|
("WA", "Washington (WA)"),
|
||||||
|
("WV", "West Virginia (WV)"),
|
||||||
|
("WI", "Wisconsin (WI)"),
|
||||||
|
("WY", "Wyoming (WY)"),
|
||||||
|
("AA", "Armed Forces Americas (AA)"),
|
||||||
|
("AE", "Armed Forces Africa, Canada, Europe, Middle East (AE)"),
|
||||||
|
("AP", "Armed Forces Pacific (AP)"),
|
||||||
|
],
|
||||||
|
help_text="State, territory, or military post",
|
||||||
|
max_length=2,
|
||||||
|
null=True,
|
||||||
|
verbose_name="state / territory",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name="domaininformation",
|
||||||
|
name="urbanization",
|
||||||
|
field=models.CharField(
|
||||||
|
blank=True,
|
||||||
|
help_text="Urbanization (required for Puerto Rico only)",
|
||||||
|
null=True,
|
||||||
|
verbose_name="urbanization",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name="domaininformation",
|
||||||
|
name="zipcode",
|
||||||
|
field=models.CharField(
|
||||||
|
blank=True, db_index=True, help_text="Zip code", max_length=10, null=True, verbose_name="zip code"
|
||||||
|
),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name="domainrequest",
|
||||||
|
name="is_election_board",
|
||||||
|
field=models.BooleanField(
|
||||||
|
blank=True,
|
||||||
|
help_text="Is your organization an election office?",
|
||||||
|
null=True,
|
||||||
|
verbose_name="election office",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name="domainrequest",
|
||||||
|
name="state_territory",
|
||||||
|
field=models.CharField(
|
||||||
|
blank=True,
|
||||||
|
choices=[
|
||||||
|
("AL", "Alabama (AL)"),
|
||||||
|
("AK", "Alaska (AK)"),
|
||||||
|
("AS", "American Samoa (AS)"),
|
||||||
|
("AZ", "Arizona (AZ)"),
|
||||||
|
("AR", "Arkansas (AR)"),
|
||||||
|
("CA", "California (CA)"),
|
||||||
|
("CO", "Colorado (CO)"),
|
||||||
|
("CT", "Connecticut (CT)"),
|
||||||
|
("DE", "Delaware (DE)"),
|
||||||
|
("DC", "District of Columbia (DC)"),
|
||||||
|
("FL", "Florida (FL)"),
|
||||||
|
("GA", "Georgia (GA)"),
|
||||||
|
("GU", "Guam (GU)"),
|
||||||
|
("HI", "Hawaii (HI)"),
|
||||||
|
("ID", "Idaho (ID)"),
|
||||||
|
("IL", "Illinois (IL)"),
|
||||||
|
("IN", "Indiana (IN)"),
|
||||||
|
("IA", "Iowa (IA)"),
|
||||||
|
("KS", "Kansas (KS)"),
|
||||||
|
("KY", "Kentucky (KY)"),
|
||||||
|
("LA", "Louisiana (LA)"),
|
||||||
|
("ME", "Maine (ME)"),
|
||||||
|
("MD", "Maryland (MD)"),
|
||||||
|
("MA", "Massachusetts (MA)"),
|
||||||
|
("MI", "Michigan (MI)"),
|
||||||
|
("MN", "Minnesota (MN)"),
|
||||||
|
("MS", "Mississippi (MS)"),
|
||||||
|
("MO", "Missouri (MO)"),
|
||||||
|
("MT", "Montana (MT)"),
|
||||||
|
("NE", "Nebraska (NE)"),
|
||||||
|
("NV", "Nevada (NV)"),
|
||||||
|
("NH", "New Hampshire (NH)"),
|
||||||
|
("NJ", "New Jersey (NJ)"),
|
||||||
|
("NM", "New Mexico (NM)"),
|
||||||
|
("NY", "New York (NY)"),
|
||||||
|
("NC", "North Carolina (NC)"),
|
||||||
|
("ND", "North Dakota (ND)"),
|
||||||
|
("MP", "Northern Mariana Islands (MP)"),
|
||||||
|
("OH", "Ohio (OH)"),
|
||||||
|
("OK", "Oklahoma (OK)"),
|
||||||
|
("OR", "Oregon (OR)"),
|
||||||
|
("PA", "Pennsylvania (PA)"),
|
||||||
|
("PR", "Puerto Rico (PR)"),
|
||||||
|
("RI", "Rhode Island (RI)"),
|
||||||
|
("SC", "South Carolina (SC)"),
|
||||||
|
("SD", "South Dakota (SD)"),
|
||||||
|
("TN", "Tennessee (TN)"),
|
||||||
|
("TX", "Texas (TX)"),
|
||||||
|
("UM", "United States Minor Outlying Islands (UM)"),
|
||||||
|
("UT", "Utah (UT)"),
|
||||||
|
("VT", "Vermont (VT)"),
|
||||||
|
("VI", "Virgin Islands (VI)"),
|
||||||
|
("VA", "Virginia (VA)"),
|
||||||
|
("WA", "Washington (WA)"),
|
||||||
|
("WV", "West Virginia (WV)"),
|
||||||
|
("WI", "Wisconsin (WI)"),
|
||||||
|
("WY", "Wyoming (WY)"),
|
||||||
|
("AA", "Armed Forces Americas (AA)"),
|
||||||
|
("AE", "Armed Forces Africa, Canada, Europe, Middle East (AE)"),
|
||||||
|
("AP", "Armed Forces Pacific (AP)"),
|
||||||
|
],
|
||||||
|
help_text="State, territory, or military post",
|
||||||
|
max_length=2,
|
||||||
|
null=True,
|
||||||
|
verbose_name="state / territory",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name="domainrequest",
|
||||||
|
name="submission_date",
|
||||||
|
field=models.DateField(
|
||||||
|
blank=True, default=None, help_text="Date submitted", null=True, verbose_name="submitted at"
|
||||||
|
),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name="domainrequest",
|
||||||
|
name="zipcode",
|
||||||
|
field=models.CharField(
|
||||||
|
blank=True, db_index=True, help_text="Zip code", max_length=10, null=True, verbose_name="zip code"
|
||||||
|
),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name="draftdomain",
|
||||||
|
name="name",
|
||||||
|
field=models.CharField(
|
||||||
|
default=None, help_text="Fully qualified domain name", max_length=253, verbose_name="requested domain"
|
||||||
|
),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name="host",
|
||||||
|
name="name",
|
||||||
|
field=models.CharField(
|
||||||
|
default=None, help_text="Fully qualified domain name", max_length=253, verbose_name="host name"
|
||||||
|
),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name="hostip",
|
||||||
|
name="address",
|
||||||
|
field=models.CharField(
|
||||||
|
default=None,
|
||||||
|
help_text="IP address",
|
||||||
|
max_length=46,
|
||||||
|
validators=[django.core.validators.validate_ipv46_address],
|
||||||
|
verbose_name="IP address",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name="transitiondomain",
|
||||||
|
name="domain_name",
|
||||||
|
field=models.CharField(blank=True, null=True, verbose_name="domain"),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name="transitiondomain",
|
||||||
|
name="first_name",
|
||||||
|
field=models.CharField(
|
||||||
|
blank=True, db_index=True, help_text="First name / given name", null=True, verbose_name="first name"
|
||||||
|
),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name="transitiondomain",
|
||||||
|
name="processed",
|
||||||
|
field=models.BooleanField(
|
||||||
|
default=True,
|
||||||
|
help_text="Indicates whether this TransitionDomain was already processed",
|
||||||
|
verbose_name="processed",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name="transitiondomain",
|
||||||
|
name="state_territory",
|
||||||
|
field=models.CharField(
|
||||||
|
blank=True,
|
||||||
|
help_text="State, territory, or military post",
|
||||||
|
max_length=2,
|
||||||
|
null=True,
|
||||||
|
verbose_name="state / territory",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name="transitiondomain",
|
||||||
|
name="status",
|
||||||
|
field=models.CharField(
|
||||||
|
blank=True,
|
||||||
|
choices=[("ready", "Ready"), ("on hold", "On hold"), ("unknown", "Unknown")],
|
||||||
|
default="ready",
|
||||||
|
help_text="domain status during the transfer",
|
||||||
|
max_length=255,
|
||||||
|
verbose_name="status",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name="transitiondomain",
|
||||||
|
name="title",
|
||||||
|
field=models.CharField(blank=True, help_text="Title", null=True, verbose_name="title / role"),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name="transitiondomain",
|
||||||
|
name="username",
|
||||||
|
field=models.CharField(help_text="Username - this will be an email address", verbose_name="username"),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name="transitiondomain",
|
||||||
|
name="zipcode",
|
||||||
|
field=models.CharField(
|
||||||
|
blank=True, db_index=True, help_text="Zip code", max_length=10, null=True, verbose_name="zip code"
|
||||||
|
),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name="user",
|
||||||
|
name="status",
|
||||||
|
field=models.CharField(
|
||||||
|
blank=True,
|
||||||
|
choices=[("restricted", "restricted")],
|
||||||
|
default=None,
|
||||||
|
max_length=10,
|
||||||
|
null=True,
|
||||||
|
verbose_name="user status",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
]
|
|
@ -0,0 +1,36 @@
|
||||||
|
# Generated by Django 4.2.10 on 2024-04-18 22:45
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
("registrar", "0085_alter_contact_first_name_alter_contact_last_name_and_more"),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name="domaininformation",
|
||||||
|
name="updated_federal_agency",
|
||||||
|
field=models.ForeignKey(
|
||||||
|
blank=True,
|
||||||
|
help_text="Associated federal agency",
|
||||||
|
null=True,
|
||||||
|
on_delete=django.db.models.deletion.PROTECT,
|
||||||
|
to="registrar.federalagency",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name="domainrequest",
|
||||||
|
name="updated_federal_agency",
|
||||||
|
field=models.ForeignKey(
|
||||||
|
blank=True,
|
||||||
|
help_text="Associated federal agency",
|
||||||
|
null=True,
|
||||||
|
on_delete=django.db.models.deletion.PROTECT,
|
||||||
|
to="registrar.federalagency",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
]
|
|
@ -18,7 +18,7 @@ class Contact(TimeStampedModel):
|
||||||
first_name = models.CharField(
|
first_name = models.CharField(
|
||||||
null=True,
|
null=True,
|
||||||
blank=True,
|
blank=True,
|
||||||
verbose_name="first name / given name",
|
verbose_name="first name",
|
||||||
db_index=True,
|
db_index=True,
|
||||||
)
|
)
|
||||||
middle_name = models.CharField(
|
middle_name = models.CharField(
|
||||||
|
@ -28,13 +28,13 @@ class Contact(TimeStampedModel):
|
||||||
last_name = models.CharField(
|
last_name = models.CharField(
|
||||||
null=True,
|
null=True,
|
||||||
blank=True,
|
blank=True,
|
||||||
verbose_name="last name / family name",
|
verbose_name="last name",
|
||||||
db_index=True,
|
db_index=True,
|
||||||
)
|
)
|
||||||
title = models.CharField(
|
title = models.CharField(
|
||||||
null=True,
|
null=True,
|
||||||
blank=True,
|
blank=True,
|
||||||
verbose_name="title or role in your organization",
|
verbose_name="title / role",
|
||||||
)
|
)
|
||||||
email = models.EmailField(
|
email = models.EmailField(
|
||||||
null=True,
|
null=True,
|
||||||
|
|
|
@ -992,6 +992,7 @@ class Domain(TimeStampedModel, DomainHelper):
|
||||||
blank=False,
|
blank=False,
|
||||||
default=None, # prevent saving without a value
|
default=None, # prevent saving without a value
|
||||||
unique=True,
|
unique=True,
|
||||||
|
verbose_name="domain",
|
||||||
help_text="Fully qualified domain name",
|
help_text="Fully qualified domain name",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -1000,6 +1001,7 @@ class Domain(TimeStampedModel, DomainHelper):
|
||||||
choices=State.choices,
|
choices=State.choices,
|
||||||
default=State.UNKNOWN,
|
default=State.UNKNOWN,
|
||||||
protected=True, # cannot change state directly, particularly in Django admin
|
protected=True, # cannot change state directly, particularly in Django admin
|
||||||
|
verbose_name="domain state",
|
||||||
help_text="Very basic info about the lifecycle of this domain object",
|
help_text="Very basic info about the lifecycle of this domain object",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -1017,12 +1019,14 @@ class Domain(TimeStampedModel, DomainHelper):
|
||||||
deleted = DateField(
|
deleted = DateField(
|
||||||
null=True,
|
null=True,
|
||||||
editable=False,
|
editable=False,
|
||||||
|
verbose_name="deleted on",
|
||||||
help_text="Deleted at date",
|
help_text="Deleted at date",
|
||||||
)
|
)
|
||||||
|
|
||||||
first_ready = DateField(
|
first_ready = DateField(
|
||||||
null=True,
|
null=True,
|
||||||
editable=False,
|
editable=False,
|
||||||
|
verbose_name="first ready on",
|
||||||
help_text="The last time this domain moved into the READY state",
|
help_text="The last time this domain moved into the READY state",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -1685,6 +1689,59 @@ class Domain(TimeStampedModel, DomainHelper):
|
||||||
else:
|
else:
|
||||||
logger.error("Error _delete_hosts_if_not_used, code was %s error was %s" % (e.code, e))
|
logger.error("Error _delete_hosts_if_not_used, code was %s error was %s" % (e.code, e))
|
||||||
|
|
||||||
|
def _fix_unknown_state(self, cleaned):
|
||||||
|
"""
|
||||||
|
_fix_unknown_state: Calls _add_missing_contacts_if_unknown
|
||||||
|
to add contacts in as needed (or return an error). Otherwise
|
||||||
|
if we are able to add contacts and the state is out of UNKNOWN
|
||||||
|
and (and should be into DNS_NEEDED), we double check the
|
||||||
|
current state and # of nameservers and update the state from there
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
self._add_missing_contacts_if_unknown(cleaned)
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(
|
||||||
|
"%s couldn't _add_missing_contacts_if_unknown, error was %s."
|
||||||
|
"Domain will still be in UNKNOWN state." % (self.name, e)
|
||||||
|
)
|
||||||
|
if len(self.nameservers) >= 2 and (self.state != self.State.READY):
|
||||||
|
self.ready()
|
||||||
|
self.save()
|
||||||
|
|
||||||
|
@transition(field="state", source=State.UNKNOWN, target=State.DNS_NEEDED)
|
||||||
|
def _add_missing_contacts_if_unknown(self, cleaned):
|
||||||
|
"""
|
||||||
|
_add_missing_contacts_if_unknown: Add contacts (SECURITY, TECHNICAL, and/or ADMINISTRATIVE)
|
||||||
|
if they are missing, AND switch the state to DNS_NEEDED from UNKNOWN (if it
|
||||||
|
is in an UNKNOWN state, that is an error state)
|
||||||
|
Note: The transition state change happens at the end of the function
|
||||||
|
"""
|
||||||
|
|
||||||
|
missingAdmin = True
|
||||||
|
missingSecurity = True
|
||||||
|
missingTech = True
|
||||||
|
|
||||||
|
if len(cleaned.get("_contacts")) < 3:
|
||||||
|
for contact in cleaned.get("_contacts"):
|
||||||
|
if contact.type == PublicContact.ContactTypeChoices.ADMINISTRATIVE:
|
||||||
|
missingAdmin = False
|
||||||
|
if contact.type == PublicContact.ContactTypeChoices.SECURITY:
|
||||||
|
missingSecurity = False
|
||||||
|
if contact.type == PublicContact.ContactTypeChoices.TECHNICAL:
|
||||||
|
missingTech = False
|
||||||
|
|
||||||
|
# We are only creating if it doesn't exist so we don't overwrite
|
||||||
|
if missingAdmin:
|
||||||
|
administrative_contact = self.get_default_administrative_contact()
|
||||||
|
administrative_contact.save()
|
||||||
|
if missingSecurity:
|
||||||
|
security_contact = self.get_default_security_contact()
|
||||||
|
security_contact.save()
|
||||||
|
if missingTech:
|
||||||
|
technical_contact = self.get_default_technical_contact()
|
||||||
|
technical_contact.save()
|
||||||
|
|
||||||
def _fetch_cache(self, fetch_hosts=False, fetch_contacts=False):
|
def _fetch_cache(self, fetch_hosts=False, fetch_contacts=False):
|
||||||
"""Contact registry for info about a domain."""
|
"""Contact registry for info about a domain."""
|
||||||
try:
|
try:
|
||||||
|
@ -1692,6 +1749,9 @@ class Domain(TimeStampedModel, DomainHelper):
|
||||||
cache = self._extract_data_from_response(data_response)
|
cache = self._extract_data_from_response(data_response)
|
||||||
cleaned = self._clean_cache(cache, data_response)
|
cleaned = self._clean_cache(cache, data_response)
|
||||||
self._update_hosts_and_contacts(cleaned, fetch_hosts, fetch_contacts)
|
self._update_hosts_and_contacts(cleaned, fetch_hosts, fetch_contacts)
|
||||||
|
|
||||||
|
if self.state == self.State.UNKNOWN:
|
||||||
|
self._fix_unknown_state(cleaned)
|
||||||
if fetch_hosts:
|
if fetch_hosts:
|
||||||
self._update_hosts_and_ips_in_db(cleaned)
|
self._update_hosts_and_ips_in_db(cleaned)
|
||||||
if fetch_contacts:
|
if fetch_contacts:
|
||||||
|
|
|
@ -29,8 +29,18 @@ class DomainInformation(TimeStampedModel):
|
||||||
|
|
||||||
BranchChoices = DomainRequest.BranchChoices
|
BranchChoices = DomainRequest.BranchChoices
|
||||||
|
|
||||||
|
# TODO for #1975: Delete this after we run the new migration
|
||||||
AGENCY_CHOICES = DomainRequest.AGENCY_CHOICES
|
AGENCY_CHOICES = DomainRequest.AGENCY_CHOICES
|
||||||
|
|
||||||
|
updated_federal_agency = models.ForeignKey(
|
||||||
|
"registrar.FederalAgency",
|
||||||
|
on_delete=models.PROTECT,
|
||||||
|
help_text="Associated federal agency",
|
||||||
|
unique=False,
|
||||||
|
blank=True,
|
||||||
|
null=True,
|
||||||
|
)
|
||||||
|
|
||||||
# This is the domain request user who created this domain request. The contact
|
# This is the domain request user who created this domain request. The contact
|
||||||
# information that they gave is in the `submitter` field
|
# information that they gave is in the `submitter` field
|
||||||
creator = models.ForeignKey(
|
creator = models.ForeignKey(
|
||||||
|
@ -62,6 +72,7 @@ class DomainInformation(TimeStampedModel):
|
||||||
is_election_board = models.BooleanField(
|
is_election_board = models.BooleanField(
|
||||||
null=True,
|
null=True,
|
||||||
blank=True,
|
blank=True,
|
||||||
|
verbose_name="election office",
|
||||||
help_text="Is your organization an election office?",
|
help_text="Is your organization an election office?",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -108,6 +119,7 @@ class DomainInformation(TimeStampedModel):
|
||||||
is_election_board = models.BooleanField(
|
is_election_board = models.BooleanField(
|
||||||
null=True,
|
null=True,
|
||||||
blank=True,
|
blank=True,
|
||||||
|
verbose_name="election office",
|
||||||
help_text="Is your organization an election office?",
|
help_text="Is your organization an election office?",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -121,13 +133,13 @@ class DomainInformation(TimeStampedModel):
|
||||||
null=True,
|
null=True,
|
||||||
blank=True,
|
blank=True,
|
||||||
help_text="Street address",
|
help_text="Street address",
|
||||||
verbose_name="Street address",
|
verbose_name="address line 1",
|
||||||
)
|
)
|
||||||
address_line2 = models.CharField(
|
address_line2 = models.CharField(
|
||||||
null=True,
|
null=True,
|
||||||
blank=True,
|
blank=True,
|
||||||
help_text="Street address line 2 (optional)",
|
help_text="Street address line 2 (optional)",
|
||||||
verbose_name="Street address line 2 (optional)",
|
verbose_name="address line 2",
|
||||||
)
|
)
|
||||||
city = models.CharField(
|
city = models.CharField(
|
||||||
null=True,
|
null=True,
|
||||||
|
@ -139,21 +151,22 @@ class DomainInformation(TimeStampedModel):
|
||||||
choices=StateTerritoryChoices.choices,
|
choices=StateTerritoryChoices.choices,
|
||||||
null=True,
|
null=True,
|
||||||
blank=True,
|
blank=True,
|
||||||
|
verbose_name="state / territory",
|
||||||
help_text="State, territory, or military post",
|
help_text="State, territory, or military post",
|
||||||
verbose_name="State, territory, or military post",
|
|
||||||
)
|
)
|
||||||
zipcode = models.CharField(
|
zipcode = models.CharField(
|
||||||
max_length=10,
|
max_length=10,
|
||||||
null=True,
|
null=True,
|
||||||
blank=True,
|
blank=True,
|
||||||
help_text="Zip code",
|
help_text="Zip code",
|
||||||
|
verbose_name="zip code",
|
||||||
db_index=True,
|
db_index=True,
|
||||||
)
|
)
|
||||||
urbanization = models.CharField(
|
urbanization = models.CharField(
|
||||||
null=True,
|
null=True,
|
||||||
blank=True,
|
blank=True,
|
||||||
help_text="Urbanization (required for Puerto Rico only)",
|
help_text="Urbanization (required for Puerto Rico only)",
|
||||||
verbose_name="Urbanization (required for Puerto Rico only)",
|
verbose_name="urbanization",
|
||||||
)
|
)
|
||||||
|
|
||||||
about_your_organization = models.TextField(
|
about_your_organization = models.TextField(
|
||||||
|
|
|
@ -449,6 +449,15 @@ class DomainRequest(TimeStampedModel):
|
||||||
blank=True,
|
blank=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
updated_federal_agency = models.ForeignKey(
|
||||||
|
"registrar.FederalAgency",
|
||||||
|
on_delete=models.PROTECT,
|
||||||
|
help_text="Associated federal agency",
|
||||||
|
unique=False,
|
||||||
|
blank=True,
|
||||||
|
null=True,
|
||||||
|
)
|
||||||
|
|
||||||
# This is the domain request user who created this domain request. The contact
|
# This is the domain request user who created this domain request. The contact
|
||||||
# information that they gave is in the `submitter` field
|
# information that they gave is in the `submitter` field
|
||||||
creator = models.ForeignKey(
|
creator = models.ForeignKey(
|
||||||
|
@ -478,6 +487,7 @@ class DomainRequest(TimeStampedModel):
|
||||||
is_election_board = models.BooleanField(
|
is_election_board = models.BooleanField(
|
||||||
null=True,
|
null=True,
|
||||||
blank=True,
|
blank=True,
|
||||||
|
verbose_name="election office",
|
||||||
help_text="Is your organization an election office?",
|
help_text="Is your organization an election office?",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -550,12 +560,14 @@ class DomainRequest(TimeStampedModel):
|
||||||
choices=StateTerritoryChoices.choices,
|
choices=StateTerritoryChoices.choices,
|
||||||
null=True,
|
null=True,
|
||||||
blank=True,
|
blank=True,
|
||||||
|
verbose_name="state / territory",
|
||||||
help_text="State, territory, or military post",
|
help_text="State, territory, or military post",
|
||||||
)
|
)
|
||||||
zipcode = models.CharField(
|
zipcode = models.CharField(
|
||||||
max_length=10,
|
max_length=10,
|
||||||
null=True,
|
null=True,
|
||||||
blank=True,
|
blank=True,
|
||||||
|
verbose_name="zip code",
|
||||||
help_text="Zip code",
|
help_text="Zip code",
|
||||||
db_index=True,
|
db_index=True,
|
||||||
)
|
)
|
||||||
|
@ -683,6 +695,7 @@ class DomainRequest(TimeStampedModel):
|
||||||
null=True,
|
null=True,
|
||||||
blank=True,
|
blank=True,
|
||||||
default=None,
|
default=None,
|
||||||
|
verbose_name="submitted at",
|
||||||
help_text="Date submitted",
|
help_text="Date submitted",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -18,5 +18,6 @@ class DraftDomain(TimeStampedModel, DomainHelper):
|
||||||
max_length=253,
|
max_length=253,
|
||||||
blank=False,
|
blank=False,
|
||||||
default=None, # prevent saving without a value
|
default=None, # prevent saving without a value
|
||||||
|
verbose_name="requested domain",
|
||||||
help_text="Fully qualified domain name",
|
help_text="Fully qualified domain name",
|
||||||
)
|
)
|
||||||
|
|
|
@ -21,6 +21,7 @@ class Host(TimeStampedModel):
|
||||||
blank=False,
|
blank=False,
|
||||||
default=None, # prevent saving without a value
|
default=None, # prevent saving without a value
|
||||||
unique=False,
|
unique=False,
|
||||||
|
verbose_name="host name",
|
||||||
help_text="Fully qualified domain name",
|
help_text="Fully qualified domain name",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,7 @@ class HostIP(TimeStampedModel):
|
||||||
blank=False,
|
blank=False,
|
||||||
default=None, # prevent saving without a value
|
default=None, # prevent saving without a value
|
||||||
validators=[validate_ipv46_address],
|
validators=[validate_ipv46_address],
|
||||||
|
verbose_name="IP address",
|
||||||
help_text="IP address",
|
help_text="IP address",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -20,13 +20,13 @@ class TransitionDomain(TimeStampedModel):
|
||||||
username = models.CharField(
|
username = models.CharField(
|
||||||
null=False,
|
null=False,
|
||||||
blank=False,
|
blank=False,
|
||||||
verbose_name="Username",
|
verbose_name="username",
|
||||||
help_text="Username - this will be an email address",
|
help_text="Username - this will be an email address",
|
||||||
)
|
)
|
||||||
domain_name = models.CharField(
|
domain_name = models.CharField(
|
||||||
null=True,
|
null=True,
|
||||||
blank=True,
|
blank=True,
|
||||||
verbose_name="Domain name",
|
verbose_name="domain",
|
||||||
)
|
)
|
||||||
status = models.CharField(
|
status = models.CharField(
|
||||||
max_length=255,
|
max_length=255,
|
||||||
|
@ -34,7 +34,7 @@ class TransitionDomain(TimeStampedModel):
|
||||||
blank=True,
|
blank=True,
|
||||||
default=StatusChoices.READY,
|
default=StatusChoices.READY,
|
||||||
choices=StatusChoices.choices,
|
choices=StatusChoices.choices,
|
||||||
verbose_name="Status",
|
verbose_name="status",
|
||||||
help_text="domain status during the transfer",
|
help_text="domain status during the transfer",
|
||||||
)
|
)
|
||||||
email_sent = models.BooleanField(
|
email_sent = models.BooleanField(
|
||||||
|
@ -46,7 +46,7 @@ class TransitionDomain(TimeStampedModel):
|
||||||
processed = models.BooleanField(
|
processed = models.BooleanField(
|
||||||
null=False,
|
null=False,
|
||||||
default=True,
|
default=True,
|
||||||
verbose_name="Processed",
|
verbose_name="processed",
|
||||||
help_text="Indicates whether this TransitionDomain was already processed",
|
help_text="Indicates whether this TransitionDomain was already processed",
|
||||||
)
|
)
|
||||||
generic_org_type = models.CharField(
|
generic_org_type = models.CharField(
|
||||||
|
@ -83,8 +83,8 @@ class TransitionDomain(TimeStampedModel):
|
||||||
first_name = models.CharField(
|
first_name = models.CharField(
|
||||||
null=True,
|
null=True,
|
||||||
blank=True,
|
blank=True,
|
||||||
help_text="First name",
|
help_text="First name / given name",
|
||||||
verbose_name="first name / given name",
|
verbose_name="first name",
|
||||||
db_index=True,
|
db_index=True,
|
||||||
)
|
)
|
||||||
middle_name = models.CharField(
|
middle_name = models.CharField(
|
||||||
|
@ -100,6 +100,7 @@ class TransitionDomain(TimeStampedModel):
|
||||||
title = models.CharField(
|
title = models.CharField(
|
||||||
null=True,
|
null=True,
|
||||||
blank=True,
|
blank=True,
|
||||||
|
verbose_name="title / role",
|
||||||
help_text="Title",
|
help_text="Title",
|
||||||
)
|
)
|
||||||
email = models.EmailField(
|
email = models.EmailField(
|
||||||
|
@ -126,12 +127,14 @@ class TransitionDomain(TimeStampedModel):
|
||||||
max_length=2,
|
max_length=2,
|
||||||
null=True,
|
null=True,
|
||||||
blank=True,
|
blank=True,
|
||||||
|
verbose_name="state / territory",
|
||||||
help_text="State, territory, or military post",
|
help_text="State, territory, or military post",
|
||||||
)
|
)
|
||||||
zipcode = models.CharField(
|
zipcode = models.CharField(
|
||||||
max_length=10,
|
max_length=10,
|
||||||
null=True,
|
null=True,
|
||||||
blank=True,
|
blank=True,
|
||||||
|
verbose_name="zip code",
|
||||||
help_text="Zip code",
|
help_text="Zip code",
|
||||||
db_index=True,
|
db_index=True,
|
||||||
)
|
)
|
||||||
|
|
|
@ -33,6 +33,7 @@ class User(AbstractUser):
|
||||||
default=None, # Set the default value to None
|
default=None, # Set the default value to None
|
||||||
null=True, # Allow the field to be null
|
null=True, # Allow the field to be null
|
||||||
blank=True, # Allow the field to be blank
|
blank=True, # Allow the field to be blank
|
||||||
|
verbose_name="user status",
|
||||||
)
|
)
|
||||||
|
|
||||||
domains = models.ManyToManyField(
|
domains = models.ManyToManyField(
|
||||||
|
|
|
@ -545,7 +545,6 @@ class MockDb(TestCase):
|
||||||
self.domain_2, _ = Domain.objects.get_or_create(name="adomain2.gov", state=Domain.State.DNS_NEEDED)
|
self.domain_2, _ = Domain.objects.get_or_create(name="adomain2.gov", state=Domain.State.DNS_NEEDED)
|
||||||
self.domain_3, _ = Domain.objects.get_or_create(name="ddomain3.gov", state=Domain.State.ON_HOLD)
|
self.domain_3, _ = Domain.objects.get_or_create(name="ddomain3.gov", state=Domain.State.ON_HOLD)
|
||||||
self.domain_4, _ = Domain.objects.get_or_create(name="bdomain4.gov", state=Domain.State.UNKNOWN)
|
self.domain_4, _ = Domain.objects.get_or_create(name="bdomain4.gov", state=Domain.State.UNKNOWN)
|
||||||
self.domain_4, _ = Domain.objects.get_or_create(name="bdomain4.gov", state=Domain.State.UNKNOWN)
|
|
||||||
self.domain_5, _ = Domain.objects.get_or_create(
|
self.domain_5, _ = Domain.objects.get_or_create(
|
||||||
name="bdomain5.gov", state=Domain.State.DELETED, deleted=timezone.make_aware(datetime(2023, 11, 1))
|
name="bdomain5.gov", state=Domain.State.DELETED, deleted=timezone.make_aware(datetime(2023, 11, 1))
|
||||||
)
|
)
|
||||||
|
@ -979,7 +978,20 @@ class MockEppLib(TestCase):
|
||||||
mockDataInfoDomain = fakedEppObject(
|
mockDataInfoDomain = fakedEppObject(
|
||||||
"fakePw",
|
"fakePw",
|
||||||
cr_date=make_aware(datetime(2023, 5, 25, 19, 45, 35)),
|
cr_date=make_aware(datetime(2023, 5, 25, 19, 45, 35)),
|
||||||
contacts=[common.DomainContact(contact="123", type=PublicContact.ContactTypeChoices.SECURITY)],
|
contacts=[
|
||||||
|
common.DomainContact(
|
||||||
|
contact="securityContact",
|
||||||
|
type=PublicContact.ContactTypeChoices.SECURITY,
|
||||||
|
),
|
||||||
|
common.DomainContact(
|
||||||
|
contact="technicalContact",
|
||||||
|
type=PublicContact.ContactTypeChoices.TECHNICAL,
|
||||||
|
),
|
||||||
|
common.DomainContact(
|
||||||
|
contact="adminContact",
|
||||||
|
type=PublicContact.ContactTypeChoices.ADMINISTRATIVE,
|
||||||
|
),
|
||||||
|
],
|
||||||
hosts=["fake.host.com"],
|
hosts=["fake.host.com"],
|
||||||
statuses=[
|
statuses=[
|
||||||
common.Status(state="serverTransferProhibited", description="", lang="en"),
|
common.Status(state="serverTransferProhibited", description="", lang="en"),
|
||||||
|
@ -1049,10 +1061,13 @@ class MockEppLib(TestCase):
|
||||||
ex_date=date(2023, 11, 15),
|
ex_date=date(2023, 11, 15),
|
||||||
)
|
)
|
||||||
mockDataInfoContact = mockDataInfoDomain.dummyInfoContactResultData(
|
mockDataInfoContact = mockDataInfoDomain.dummyInfoContactResultData(
|
||||||
"123", "123@mail.gov", datetime(2023, 5, 25, 19, 45, 35), "lastPw"
|
id="123", email="123@mail.gov", cr_date=datetime(2023, 5, 25, 19, 45, 35), pw="lastPw"
|
||||||
|
)
|
||||||
|
mockDataSecurityContact = mockDataInfoDomain.dummyInfoContactResultData(
|
||||||
|
id="securityContact", email="security@mail.gov", cr_date=datetime(2023, 5, 25, 19, 45, 35), pw="lastPw"
|
||||||
)
|
)
|
||||||
InfoDomainWithContacts = fakedEppObject(
|
InfoDomainWithContacts = fakedEppObject(
|
||||||
"fakepw",
|
"fakePw",
|
||||||
cr_date=make_aware(datetime(2023, 5, 25, 19, 45, 35)),
|
cr_date=make_aware(datetime(2023, 5, 25, 19, 45, 35)),
|
||||||
contacts=[
|
contacts=[
|
||||||
common.DomainContact(
|
common.DomainContact(
|
||||||
|
@ -1074,6 +1089,7 @@ class MockEppLib(TestCase):
|
||||||
common.Status(state="inactive", description="", lang="en"),
|
common.Status(state="inactive", description="", lang="en"),
|
||||||
],
|
],
|
||||||
registrant="regContact",
|
registrant="regContact",
|
||||||
|
ex_date=date(2023, 11, 15),
|
||||||
)
|
)
|
||||||
|
|
||||||
InfoDomainWithDefaultSecurityContact = fakedEppObject(
|
InfoDomainWithDefaultSecurityContact = fakedEppObject(
|
||||||
|
@ -1500,6 +1516,8 @@ class MockEppLib(TestCase):
|
||||||
"meow.gov": (self.mockDataInfoDomainSubdomainAndIPAddress, None),
|
"meow.gov": (self.mockDataInfoDomainSubdomainAndIPAddress, None),
|
||||||
"fakemeow.gov": (self.mockDataInfoDomainNotSubdomainNoIP, None),
|
"fakemeow.gov": (self.mockDataInfoDomainNotSubdomainNoIP, None),
|
||||||
"subdomainwoip.gov": (self.mockDataInfoDomainSubdomainNoIP, None),
|
"subdomainwoip.gov": (self.mockDataInfoDomainSubdomainNoIP, None),
|
||||||
|
"ddomain3.gov": (self.InfoDomainWithContacts, None),
|
||||||
|
"igorville.gov": (self.InfoDomainWithContacts, None),
|
||||||
}
|
}
|
||||||
|
|
||||||
# Retrieve the corresponding values from the dictionary
|
# Retrieve the corresponding values from the dictionary
|
||||||
|
|
|
@ -25,11 +25,13 @@ from registrar.models import (
|
||||||
Domain,
|
Domain,
|
||||||
DomainRequest,
|
DomainRequest,
|
||||||
DomainInformation,
|
DomainInformation,
|
||||||
|
DraftDomain,
|
||||||
User,
|
User,
|
||||||
DomainInvitation,
|
DomainInvitation,
|
||||||
Contact,
|
Contact,
|
||||||
|
PublicContact,
|
||||||
|
Host,
|
||||||
Website,
|
Website,
|
||||||
DraftDomain,
|
|
||||||
)
|
)
|
||||||
from registrar.models.user_domain_role import UserDomainRole
|
from registrar.models.user_domain_role import UserDomainRole
|
||||||
from registrar.models.verified_by_staff import VerifiedByStaff
|
from registrar.models.verified_by_staff import VerifiedByStaff
|
||||||
|
@ -690,6 +692,8 @@ class TestDomainAdmin(MockEppLib, WebTest):
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
super().tearDown()
|
super().tearDown()
|
||||||
|
PublicContact.objects.all().delete()
|
||||||
|
Host.objects.all().delete()
|
||||||
Domain.objects.all().delete()
|
Domain.objects.all().delete()
|
||||||
DomainInformation.objects.all().delete()
|
DomainInformation.objects.all().delete()
|
||||||
DomainRequest.objects.all().delete()
|
DomainRequest.objects.all().delete()
|
||||||
|
@ -1858,6 +1862,8 @@ class TestDomainRequestAdmin(MockEppLib):
|
||||||
"updated_at",
|
"updated_at",
|
||||||
"status",
|
"status",
|
||||||
"rejection_reason",
|
"rejection_reason",
|
||||||
|
"updated_federal_agency",
|
||||||
|
# TODO: once approved, we'll have to remove above from test
|
||||||
"creator",
|
"creator",
|
||||||
"investigator",
|
"investigator",
|
||||||
"generic_org_type",
|
"generic_org_type",
|
||||||
|
|
|
@ -107,9 +107,9 @@ class TestDomainCache(MockEppLib):
|
||||||
common.DomainContact(contact="123", type="security"),
|
common.DomainContact(contact="123", type="security"),
|
||||||
]
|
]
|
||||||
expectedContactsDict = {
|
expectedContactsDict = {
|
||||||
PublicContact.ContactTypeChoices.ADMINISTRATIVE: None,
|
PublicContact.ContactTypeChoices.ADMINISTRATIVE: "adminContact",
|
||||||
PublicContact.ContactTypeChoices.SECURITY: "123",
|
PublicContact.ContactTypeChoices.SECURITY: "securityContact",
|
||||||
PublicContact.ContactTypeChoices.TECHNICAL: None,
|
PublicContact.ContactTypeChoices.TECHNICAL: "technicalContact",
|
||||||
}
|
}
|
||||||
expectedHostsDict = {
|
expectedHostsDict = {
|
||||||
"name": self.mockDataInfoDomain.hosts[0],
|
"name": self.mockDataInfoDomain.hosts[0],
|
||||||
|
@ -129,6 +129,7 @@ class TestDomainCache(MockEppLib):
|
||||||
# The contact list should not contain what is sent by the registry by default,
|
# The contact list should not contain what is sent by the registry by default,
|
||||||
# as _fetch_cache will transform the type to PublicContact
|
# as _fetch_cache will transform the type to PublicContact
|
||||||
self.assertNotEqual(domain._cache["contacts"], expectedUnfurledContactsList)
|
self.assertNotEqual(domain._cache["contacts"], expectedUnfurledContactsList)
|
||||||
|
|
||||||
self.assertEqual(domain._cache["contacts"], expectedContactsDict)
|
self.assertEqual(domain._cache["contacts"], expectedContactsDict)
|
||||||
|
|
||||||
# get and check hosts is set correctly
|
# get and check hosts is set correctly
|
||||||
|
@ -203,19 +204,20 @@ class TestDomainCache(MockEppLib):
|
||||||
def test_map_epp_contact_to_public_contact(self):
|
def test_map_epp_contact_to_public_contact(self):
|
||||||
# Tests that the mapper is working how we expect
|
# Tests that the mapper is working how we expect
|
||||||
with less_console_noise():
|
with less_console_noise():
|
||||||
domain, _ = Domain.objects.get_or_create(name="registry.gov")
|
domain, _ = Domain.objects.get_or_create(name="registry.gov", state=Domain.State.DNS_NEEDED)
|
||||||
security = PublicContact.ContactTypeChoices.SECURITY
|
security = PublicContact.ContactTypeChoices.SECURITY
|
||||||
mapped = domain.map_epp_contact_to_public_contact(
|
mapped = domain.map_epp_contact_to_public_contact(
|
||||||
self.mockDataInfoContact,
|
self.mockDataSecurityContact,
|
||||||
self.mockDataInfoContact.id,
|
self.mockDataSecurityContact.id,
|
||||||
security,
|
security,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# id, registry_id, and contact are the same thing
|
||||||
expected_contact = PublicContact(
|
expected_contact = PublicContact(
|
||||||
domain=domain,
|
domain=domain,
|
||||||
contact_type=security,
|
contact_type=security,
|
||||||
registry_id="123",
|
registry_id="securityContact",
|
||||||
email="123@mail.gov",
|
email="security@mail.gov",
|
||||||
voice="+1.8882820870",
|
voice="+1.8882820870",
|
||||||
fax="+1-212-9876543",
|
fax="+1-212-9876543",
|
||||||
pw="lastPw",
|
pw="lastPw",
|
||||||
|
@ -232,7 +234,6 @@ class TestDomainCache(MockEppLib):
|
||||||
# two duplicate objects. We would expect
|
# two duplicate objects. We would expect
|
||||||
# these not to have the same state.
|
# these not to have the same state.
|
||||||
expected_contact._state = mapped._state
|
expected_contact._state = mapped._state
|
||||||
|
|
||||||
# Mapped object is what we expect
|
# Mapped object is what we expect
|
||||||
self.assertEqual(mapped.__dict__, expected_contact.__dict__)
|
self.assertEqual(mapped.__dict__, expected_contact.__dict__)
|
||||||
|
|
||||||
|
@ -243,9 +244,9 @@ class TestDomainCache(MockEppLib):
|
||||||
registry_id=domain.security_contact.registry_id,
|
registry_id=domain.security_contact.registry_id,
|
||||||
contact_type=security,
|
contact_type=security,
|
||||||
).get()
|
).get()
|
||||||
|
|
||||||
# DB Object is the same as the mapped object
|
# DB Object is the same as the mapped object
|
||||||
self.assertEqual(db_object, in_db)
|
self.assertEqual(db_object, in_db)
|
||||||
|
|
||||||
domain.security_contact = in_db
|
domain.security_contact = in_db
|
||||||
# Trigger the getter
|
# Trigger the getter
|
||||||
_ = domain.security_contact
|
_ = domain.security_contact
|
||||||
|
@ -309,6 +310,40 @@ class TestDomainCache(MockEppLib):
|
||||||
)
|
)
|
||||||
self.assertEqual(context.exception.code, desired_error)
|
self.assertEqual(context.exception.code, desired_error)
|
||||||
|
|
||||||
|
def test_fix_unknown_to_ready_state(self):
|
||||||
|
"""
|
||||||
|
Scenario: A error occurred and the domain's state is in UNKONWN
|
||||||
|
which shouldn't happen. The biz logic and test is to make sure
|
||||||
|
we resolve that UNKNOWN state to READY because it has 2 nameservers.
|
||||||
|
Note:
|
||||||
|
* Default state when you do get_or_create is UNKNOWN
|
||||||
|
* justnameserver.com has 2 nameservers which is why we are using it
|
||||||
|
* justnameserver.com also has all 3 contacts hence 0 count
|
||||||
|
"""
|
||||||
|
with less_console_noise():
|
||||||
|
domain, _ = Domain.objects.get_or_create(name="justnameserver.com")
|
||||||
|
# trigger the getter
|
||||||
|
_ = domain.nameservers
|
||||||
|
self.assertEqual(domain.state, Domain.State.READY)
|
||||||
|
self.assertEqual(PublicContact.objects.filter(domain=domain.id).count(), 0)
|
||||||
|
|
||||||
|
def test_fix_unknown_to_dns_needed_state(self):
|
||||||
|
"""
|
||||||
|
Scenario: A error occurred and the domain's state is in UNKONWN
|
||||||
|
which shouldn't happen. The biz logic and test is to make sure
|
||||||
|
we resolve that UNKNOWN state to DNS_NEEDED because it has 1 nameserver.
|
||||||
|
Note:
|
||||||
|
* Default state when you do get_or_create is UNKNOWN
|
||||||
|
* defaulttechnical.gov has 1 nameservers which is why we are using it
|
||||||
|
* defaulttechnical.gov already has a security contact (1) hence 2 count
|
||||||
|
"""
|
||||||
|
with less_console_noise():
|
||||||
|
domain, _ = Domain.objects.get_or_create(name="defaulttechnical.gov")
|
||||||
|
# trigger the getter
|
||||||
|
_ = domain.nameservers
|
||||||
|
self.assertEqual(domain.state, Domain.State.DNS_NEEDED)
|
||||||
|
self.assertEqual(PublicContact.objects.filter(domain=domain.id).count(), 2)
|
||||||
|
|
||||||
|
|
||||||
class TestDomainCreation(MockEppLib):
|
class TestDomainCreation(MockEppLib):
|
||||||
"""Rule: An approved domain request must result in a domain"""
|
"""Rule: An approved domain request must result in a domain"""
|
||||||
|
@ -346,7 +381,7 @@ class TestDomainCreation(MockEppLib):
|
||||||
Given that no domain object exists in the registry
|
Given that no domain object exists in the registry
|
||||||
When a property is accessed
|
When a property is accessed
|
||||||
Then Domain sends `commands.CreateDomain` to the registry
|
Then Domain sends `commands.CreateDomain` to the registry
|
||||||
And `domain.state` is set to `UNKNOWN`
|
And `domain.state` is set to `DNS_NEEDED`
|
||||||
And `domain.is_active()` returns False
|
And `domain.is_active()` returns False
|
||||||
"""
|
"""
|
||||||
with less_console_noise():
|
with less_console_noise():
|
||||||
|
@ -375,7 +410,7 @@ class TestDomainCreation(MockEppLib):
|
||||||
any_order=False, # Ensure calls are in the specified order
|
any_order=False, # Ensure calls are in the specified order
|
||||||
)
|
)
|
||||||
|
|
||||||
self.assertEqual(domain.state, Domain.State.UNKNOWN)
|
self.assertEqual(domain.state, Domain.State.DNS_NEEDED)
|
||||||
self.assertEqual(domain.is_active(), False)
|
self.assertEqual(domain.is_active(), False)
|
||||||
|
|
||||||
@skip("assertion broken with mock addition")
|
@skip("assertion broken with mock addition")
|
||||||
|
@ -400,6 +435,7 @@ class TestDomainCreation(MockEppLib):
|
||||||
DomainInformation.objects.all().delete()
|
DomainInformation.objects.all().delete()
|
||||||
DomainRequest.objects.all().delete()
|
DomainRequest.objects.all().delete()
|
||||||
PublicContact.objects.all().delete()
|
PublicContact.objects.all().delete()
|
||||||
|
Host.objects.all().delete()
|
||||||
Domain.objects.all().delete()
|
Domain.objects.all().delete()
|
||||||
User.objects.all().delete()
|
User.objects.all().delete()
|
||||||
DraftDomain.objects.all().delete()
|
DraftDomain.objects.all().delete()
|
||||||
|
@ -485,6 +521,7 @@ class TestDomainStatuses(MockEppLib):
|
||||||
|
|
||||||
def tearDown(self) -> None:
|
def tearDown(self) -> None:
|
||||||
PublicContact.objects.all().delete()
|
PublicContact.objects.all().delete()
|
||||||
|
Host.objects.all().delete()
|
||||||
Domain.objects.all().delete()
|
Domain.objects.all().delete()
|
||||||
super().tearDown()
|
super().tearDown()
|
||||||
|
|
||||||
|
@ -624,6 +661,7 @@ class TestRegistrantContacts(MockEppLib):
|
||||||
self.domain._invalidate_cache()
|
self.domain._invalidate_cache()
|
||||||
self.domain_contact._invalidate_cache()
|
self.domain_contact._invalidate_cache()
|
||||||
PublicContact.objects.all().delete()
|
PublicContact.objects.all().delete()
|
||||||
|
Host.objects.all().delete()
|
||||||
Domain.objects.all().delete()
|
Domain.objects.all().delete()
|
||||||
|
|
||||||
def test_no_security_email(self):
|
def test_no_security_email(self):
|
||||||
|
@ -998,10 +1036,10 @@ class TestRegistrantContacts(MockEppLib):
|
||||||
And the field `disclose` is set to true for DF.EMAIL
|
And the field `disclose` is set to true for DF.EMAIL
|
||||||
"""
|
"""
|
||||||
with less_console_noise():
|
with less_console_noise():
|
||||||
domain, _ = Domain.objects.get_or_create(name="igorville.gov")
|
domain, _ = Domain.objects.get_or_create(name="igorville.gov", state=Domain.State.DNS_NEEDED)
|
||||||
expectedSecContact = PublicContact.get_default_security()
|
expectedSecContact = PublicContact.get_default_security()
|
||||||
expectedSecContact.domain = domain
|
expectedSecContact.domain = domain
|
||||||
expectedSecContact.email = "123@mail.gov"
|
expectedSecContact.email = "security@mail.gov"
|
||||||
domain.security_contact = expectedSecContact
|
domain.security_contact = expectedSecContact
|
||||||
expectedCreateCommand = self._convertPublicContactToEpp(expectedSecContact, disclose_email=True)
|
expectedCreateCommand = self._convertPublicContactToEpp(expectedSecContact, disclose_email=True)
|
||||||
self.mockedSendFunction.assert_any_call(expectedCreateCommand, cleaned=True)
|
self.mockedSendFunction.assert_any_call(expectedCreateCommand, cleaned=True)
|
||||||
|
@ -1847,6 +1885,8 @@ class TestRegistrantDNSSEC(MockEppLib):
|
||||||
self.domain, _ = Domain.objects.get_or_create(name="fake.gov")
|
self.domain, _ = Domain.objects.get_or_create(name="fake.gov")
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
|
PublicContact.objects.all().delete()
|
||||||
|
Host.objects.all().delete()
|
||||||
Domain.objects.all().delete()
|
Domain.objects.all().delete()
|
||||||
super().tearDown()
|
super().tearDown()
|
||||||
|
|
||||||
|
@ -1904,6 +1944,7 @@ class TestRegistrantDNSSEC(MockEppLib):
|
||||||
),
|
),
|
||||||
cleaned=True,
|
cleaned=True,
|
||||||
),
|
),
|
||||||
|
call(commands.InfoHost(name="fake.host.com"), cleaned=True),
|
||||||
call(
|
call(
|
||||||
commands.UpdateDomain(
|
commands.UpdateDomain(
|
||||||
name="dnssec-dsdata.gov",
|
name="dnssec-dsdata.gov",
|
||||||
|
@ -1976,6 +2017,13 @@ class TestRegistrantDNSSEC(MockEppLib):
|
||||||
),
|
),
|
||||||
cleaned=True,
|
cleaned=True,
|
||||||
),
|
),
|
||||||
|
call(
|
||||||
|
commands.InfoDomain(
|
||||||
|
name="dnssec-dsdata.gov",
|
||||||
|
),
|
||||||
|
cleaned=True,
|
||||||
|
),
|
||||||
|
call(commands.InfoHost(name="fake.host.com"), cleaned=True),
|
||||||
call(
|
call(
|
||||||
commands.UpdateDomain(
|
commands.UpdateDomain(
|
||||||
name="dnssec-dsdata.gov",
|
name="dnssec-dsdata.gov",
|
||||||
|
@ -2129,6 +2177,7 @@ class TestRegistrantDNSSEC(MockEppLib):
|
||||||
),
|
),
|
||||||
cleaned=True,
|
cleaned=True,
|
||||||
),
|
),
|
||||||
|
call(commands.InfoHost(name="fake.host.com"), cleaned=True),
|
||||||
call(
|
call(
|
||||||
commands.UpdateDomain(
|
commands.UpdateDomain(
|
||||||
name="dnssec-dsdata.gov",
|
name="dnssec-dsdata.gov",
|
||||||
|
|
|
@ -263,7 +263,7 @@ class ExportDataTest(MockDb, MockEppLib):
|
||||||
"adomain10.gov,Federal,Armed Forces Retirement Home,Ready\n"
|
"adomain10.gov,Federal,Armed Forces Retirement Home,Ready\n"
|
||||||
"adomain2.gov,Interstate,(blank),Dns needed\n"
|
"adomain2.gov,Interstate,(blank),Dns needed\n"
|
||||||
"cdomain11.govFederal-ExecutiveWorldWarICentennialCommissionReady\n"
|
"cdomain11.govFederal-ExecutiveWorldWarICentennialCommissionReady\n"
|
||||||
"ddomain3.gov,Federal,Armed Forces Retirement Home,123@mail.gov,On hold,2023-05-25\n"
|
"ddomain3.gov,Federal,Armed Forces Retirement Home,security@mail.gov,On hold,2023-11-15\n"
|
||||||
"defaultsecurity.gov,Federal - Executive,World War I Centennial Commission,(blank),Ready\n"
|
"defaultsecurity.gov,Federal - Executive,World War I Centennial Commission,(blank),Ready\n"
|
||||||
"zdomain12.govInterstateReady\n"
|
"zdomain12.govInterstateReady\n"
|
||||||
)
|
)
|
||||||
|
|
|
@ -243,7 +243,7 @@ class TestDomainDetail(TestDomainOverview):
|
||||||
self.assertContains(home_page, "DNS needed")
|
self.assertContains(home_page, "DNS needed")
|
||||||
|
|
||||||
def test_unknown_domain_does_not_show_as_expired_on_detail_page(self):
|
def test_unknown_domain_does_not_show_as_expired_on_detail_page(self):
|
||||||
"""An UNKNOWN domain does not show as expired on the detail page.
|
"""An UNKNOWN domain should not exist on the detail_page anymore.
|
||||||
It shows as 'DNS needed'"""
|
It shows as 'DNS needed'"""
|
||||||
# At the time of this test's writing, there are 6 UNKNOWN domains inherited
|
# At the time of this test's writing, there are 6 UNKNOWN domains inherited
|
||||||
# from constructors. Let's reset.
|
# from constructors. Let's reset.
|
||||||
|
@ -262,9 +262,9 @@ class TestDomainDetail(TestDomainOverview):
|
||||||
igorville = Domain.objects.get(name="igorville.gov")
|
igorville = Domain.objects.get(name="igorville.gov")
|
||||||
self.assertEquals(igorville.state, Domain.State.UNKNOWN)
|
self.assertEquals(igorville.state, Domain.State.UNKNOWN)
|
||||||
detail_page = home_page.click("Manage", index=0)
|
detail_page = home_page.click("Manage", index=0)
|
||||||
self.assertNotContains(detail_page, "Expired")
|
self.assertContains(detail_page, "Expired")
|
||||||
|
|
||||||
self.assertContains(detail_page, "DNS needed")
|
self.assertNotContains(detail_page, "DNS needed")
|
||||||
|
|
||||||
def test_domain_detail_blocked_for_ineligible_user(self):
|
def test_domain_detail_blocked_for_ineligible_user(self):
|
||||||
"""We could easily duplicate this test for all domain management
|
"""We could easily duplicate this test for all domain management
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue