Merge pull request #654 from cisagov/sspj/public-contact-update

Update fields and help text for Public Contact
This commit is contained in:
Seamus Johnston 2023-05-30 18:55:27 +00:00 committed by GitHub
commit 265e506643
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 259 additions and 30 deletions

View file

@ -0,0 +1,122 @@
# Generated by Django 4.2.1 on 2023-05-25 15:03
from django.db import migrations, models
import django.db.models.deletion
import registrar.models.public_contact
class Migration(migrations.Migration):
dependencies = [
("registrar", "0020_remove_domaininformation_security_email"),
]
operations = [
migrations.AddField(
model_name="publiccontact",
name="domain",
field=models.ForeignKey(
default=1,
on_delete=django.db.models.deletion.PROTECT,
related_name="contacts",
to="registrar.domain",
),
preserve_default=False,
),
migrations.AddField(
model_name="publiccontact",
name="registry_id",
field=models.CharField(
default=registrar.models.public_contact.get_id,
help_text="Auto generated ID to track this contact in the registry",
max_length=16,
),
),
migrations.AlterField(
model_name="publiccontact",
name="cc",
field=models.TextField(help_text="Contact's country code"),
),
migrations.AlterField(
model_name="publiccontact",
name="city",
field=models.TextField(help_text="Contact's city"),
),
migrations.AlterField(
model_name="publiccontact",
name="contact_type",
field=models.CharField(
choices=[
("registrant", "Registrant"),
("administrative", "Administrative"),
("technical", "Technical"),
("security", "Security"),
],
help_text="For which type of WHOIS contact",
max_length=14,
),
),
migrations.AlterField(
model_name="publiccontact",
name="email",
field=models.TextField(help_text="Contact's email address"),
),
migrations.AlterField(
model_name="publiccontact",
name="fax",
field=models.TextField(
help_text="Contact's fax number (null ok). Must be in ITU.E164.2005 format.",
null=True,
),
),
migrations.AlterField(
model_name="publiccontact",
name="name",
field=models.TextField(help_text="Contact's full name"),
),
migrations.AlterField(
model_name="publiccontact",
name="org",
field=models.TextField(
help_text="Contact's organization (null ok)", null=True
),
),
migrations.AlterField(
model_name="publiccontact",
name="pc",
field=models.TextField(help_text="Contact's postal code"),
),
migrations.AlterField(
model_name="publiccontact",
name="pw",
field=models.TextField(
help_text="Contact's authorization code. 16 characters minimum."
),
),
migrations.AlterField(
model_name="publiccontact",
name="sp",
field=models.TextField(help_text="Contact's state or province"),
),
migrations.AlterField(
model_name="publiccontact",
name="street1",
field=models.TextField(help_text="Contact's street"),
),
migrations.AlterField(
model_name="publiccontact",
name="street2",
field=models.TextField(help_text="Contact's street (null ok)", null=True),
),
migrations.AlterField(
model_name="publiccontact",
name="street3",
field=models.TextField(help_text="Contact's street (null ok)", null=True),
),
migrations.AlterField(
model_name="publiccontact",
name="voice",
field=models.TextField(
help_text="Contact's phone number. Must be in ITU.E164.2005 format"
),
),
]

View file

@ -1,8 +1,21 @@
from datetime import datetime
from random import choices
from string import ascii_uppercase, ascii_lowercase, digits
from django.db import models
from .utility.time_stamped_model import TimeStampedModel
def get_id():
"""Generate a 16 character registry ID with a low probability of collision."""
day = datetime.today().strftime("%A")[:2]
rand = "".join(
choices(ascii_uppercase + ascii_lowercase + digits, k=14) # nosec B311
)
return f"{day}{rand}"
class PublicContact(TimeStampedModel):
"""Contact information intended to be published in WHOIS."""
@ -14,37 +27,126 @@ class PublicContact(TimeStampedModel):
TECHNICAL = "technical", "Technical"
SECURITY = "security", "Security"
contact_type = models.CharField(max_length=14, choices=ContactTypeChoices.choices)
def save(self, *args, **kwargs):
"""Save to the registry and also locally in the registrar database."""
if hasattr(self, "domain"):
match self.contact_type:
case PublicContact.ContactTypeChoices.REGISTRANT:
self.domain.registrant = self
case PublicContact.ContactTypeChoices.ADMINISTRATIVE:
self.domain.administrative_contact = self
case PublicContact.ContactTypeChoices.TECHNICAL:
self.domain.technical_contact = self
case PublicContact.ContactTypeChoices.SECURITY:
self.domain.security_contact = self
super().save(*args, **kwargs)
# contact's full name
name = models.TextField(null=False)
# contact's organization (null ok)
org = models.TextField(null=True)
# contact's street
street1 = models.TextField(null=False)
# contact's street (null ok)
street2 = models.TextField(null=True)
# contact's street (null ok)
street3 = models.TextField(null=True)
# contact's city
city = models.TextField(null=False)
# contact's state or province
sp = models.TextField(null=False)
# contact's postal code
pc = models.TextField(null=False)
# contact's country code
cc = models.TextField(null=False)
# contact's email address
email = models.TextField(null=False)
# contact's phone number
# Must be in ITU.E164.2005 format
voice = models.TextField(null=False)
# contact's fax number (null ok)
# Must be in ITU.E164.2005 format
fax = models.TextField(null=True)
# contact's authorization code
# 16 characters minium
pw = models.TextField(null=False)
contact_type = models.CharField(
max_length=14,
choices=ContactTypeChoices.choices,
help_text="For which type of WHOIS contact",
)
registry_id = models.CharField(
max_length=16,
default=get_id,
null=False,
help_text="Auto generated ID to track this contact in the registry",
)
domain = models.ForeignKey(
"registrar.Domain",
on_delete=models.PROTECT,
related_name="contacts",
)
name = models.TextField(null=False, help_text="Contact's full name")
org = models.TextField(null=True, help_text="Contact's organization (null ok)")
street1 = models.TextField(null=False, help_text="Contact's street")
street2 = models.TextField(null=True, help_text="Contact's street (null ok)")
street3 = models.TextField(null=True, help_text="Contact's street (null ok)")
city = models.TextField(null=False, help_text="Contact's city")
sp = models.TextField(null=False, help_text="Contact's state or province")
pc = models.TextField(null=False, help_text="Contact's postal code")
cc = models.TextField(null=False, help_text="Contact's country code")
email = models.TextField(null=False, help_text="Contact's email address")
voice = models.TextField(
null=False, help_text="Contact's phone number. Must be in ITU.E164.2005 format"
)
fax = models.TextField(
null=True,
help_text="Contact's fax number (null ok). Must be in ITU.E164.2005 format.",
)
pw = models.TextField(
null=False, help_text="Contact's authorization code. 16 characters minimum."
)
@classmethod
def get_default_registrant(cls):
return cls(
contact_type=PublicContact.ContactTypeChoices.REGISTRANT,
registry_id=get_id(),
name="CSD/CB Attn: Cameron Dixon",
org="Cybersecurity and Infrastructure Security Agency",
street1="CISA NGR STOP 0645",
street2="1110 N. Glebe Rd.",
city="Arlington",
sp="VA",
pc="20598-0645",
cc="US",
email="dotgov@cisa.dhs.gov",
voice="+1.8882820870",
pw="thisisnotapassword",
)
@classmethod
def get_default_administrative(cls):
return cls(
contact_type=PublicContact.ContactTypeChoices.ADMINISTRATIVE,
registry_id=get_id(),
name="Program Manager",
org="Cybersecurity and Infrastructure Security Agency",
street1="4200 Wilson Blvd.",
city="Arlington",
sp="VA",
pc="22201",
cc="US",
email="dotgov@cisa.dhs.gov",
voice="+1.8882820870",
pw="thisisnotapassword",
)
@classmethod
def get_default_technical(cls):
return cls(
contact_type=PublicContact.ContactTypeChoices.TECHNICAL,
registry_id=get_id(),
name="Registry Customer Service",
org="Cybersecurity and Infrastructure Security Agency",
street1="4200 Wilson Blvd.",
city="Arlington",
sp="VA",
pc="22201",
cc="US",
email="dotgov@cisa.dhs.gov",
voice="+1.8882820870",
pw="thisisnotapassword",
)
@classmethod
def get_default_security(cls):
return cls(
contact_type=PublicContact.ContactTypeChoices.SECURITY,
registry_id=get_id(),
name="Registry Customer Service",
org="Cybersecurity and Infrastructure Security Agency",
street1="4200 Wilson Blvd.",
city="Arlington",
sp="VA",
pc="22201",
cc="US",
email="dotgov@cisa.dhs.gov",
voice="+1.8882820870",
pw="thisisnotapassword",
)
def __str__(self):
return f"{self.name} <{self.email}>"