diff --git a/src/registrar/admin.py b/src/registrar/admin.py index 48e033919..174500f28 100644 --- a/src/registrar/admin.py +++ b/src/registrar/admin.py @@ -138,24 +138,12 @@ class MyUserAdmin(BaseUserAdmin): "email", "first_name", "last_name", + # Group is a custom property defined within this file, + # rather than in a model like the other properties "group", "status", ) - list_filter = ( - "is_active", - "groups", - ) - - # Let's define First group - # (which should in theory be the ONLY group) - def group(self, obj): - if obj.groups.filter(name="full_access_group").exists(): - return "Full access" - elif obj.groups.filter(name="cisa_analysts_group").exists(): - return "Analyst" - return "" - fieldsets = ( ( None, @@ -222,6 +210,20 @@ class MyUserAdmin(BaseUserAdmin): "date_joined", ] + list_filter = ( + "is_active", + "groups", + ) + + # Let's define First group + # (which should in theory be the ONLY group) + def group(self, obj): + if obj.groups.filter(name="full_access_group").exists(): + return "Full access" + elif obj.groups.filter(name="cisa_analysts_group").exists(): + return "Analyst" + return "" + def get_list_display(self, request): # The full_access_permission perm will load onto the full_access_group # which is equivalent to superuser. The other group we use to manage diff --git a/src/registrar/forms/domain.py b/src/registrar/forms/domain.py index f14448bcf..2f9aa1976 100644 --- a/src/registrar/forms/domain.py +++ b/src/registrar/forms/domain.py @@ -64,7 +64,7 @@ class DomainSecurityEmailForm(forms.Form): """Form for adding or editing a security email to a domain.""" - security_email = forms.EmailField(label="Security email") + security_email = forms.EmailField(label="Security email", required=False) class DomainOrgNameAddressForm(forms.ModelForm): diff --git a/src/registrar/models/domain.py b/src/registrar/models/domain.py index f7b91e96b..82b573d32 100644 --- a/src/registrar/models/domain.py +++ b/src/registrar/models/domain.py @@ -15,7 +15,7 @@ from epplibwrapper import ( RegistryError, ErrorCode, ) -from registrar.models.utility.contact_error import ContactError +from registrar.models.utility.contact_error import ContactError, ContactErrorCodes from .utility.domain_field import DomainField from .utility.domain_helper import DomainHelper @@ -625,7 +625,10 @@ class Domain(TimeStampedModel, DomainHelper): def get_security_email(self): logger.info("get_security_email-> getting the contact ") secContact = self.security_contact - return secContact.email + if secContact is not None: + return secContact.email + else: + return None def clientHoldStatus(self): return epp.Status(state=self.Status.CLIENT_HOLD, description="", lang="en") @@ -698,10 +701,10 @@ class Domain(TimeStampedModel, DomainHelper): return None if contact_type is None: - raise ContactError("contact_type is None") + raise ContactError(code=ContactErrorCodes.CONTACT_TYPE_NONE) if contact_id is None: - raise ContactError("contact_id is None") + raise ContactError(code=ContactErrorCodes.CONTACT_ID_NONE) # Since contact_id is registry_id, # check that its the right length @@ -710,14 +713,11 @@ class Domain(TimeStampedModel, DomainHelper): contact_id_length > PublicContact.get_max_id_length() or contact_id_length < 1 ): - raise ContactError( - "contact_id is of invalid length. " - "Cannot exceed 16 characters, " - f"got {contact_id} with a length of {contact_id_length}" - ) + raise ContactError(code=ContactErrorCodes.CONTACT_ID_INVALID_LENGTH) if not isinstance(contact, eppInfo.InfoContactResultData): - raise ContactError("Contact must be of type InfoContactResultData") + raise ContactError(code=ContactErrorCodes.CONTACT_INVALID_TYPE) + auth_info = contact.auth_info postal_info = contact.postal_info addr = postal_info.addr @@ -880,8 +880,8 @@ class Domain(TimeStampedModel, DomainHelper): return self._handle_registrant_contact(desired_contact) - _registry_id: str - if contact_type in contacts: + _registry_id: str = "" + if contacts is not None and contact_type in contacts: _registry_id = contacts.get(contact_type) desired = PublicContact.objects.filter( diff --git a/src/registrar/models/utility/contact_error.py b/src/registrar/models/utility/contact_error.py index 93084eca2..cf392cb6e 100644 --- a/src/registrar/models/utility/contact_error.py +++ b/src/registrar/models/utility/contact_error.py @@ -1,2 +1,51 @@ +from enum import IntEnum + + +class ContactErrorCodes(IntEnum): + """Used in the ContactError class for + error mapping. + + Overview of contact error codes: + - 2000 CONTACT_TYPE_NONE + - 2001 CONTACT_ID_NONE + - 2002 CONTACT_ID_INVALID_LENGTH + - 2003 CONTACT_INVALID_TYPE + """ + + CONTACT_TYPE_NONE = 2000 + CONTACT_ID_NONE = 2001 + CONTACT_ID_INVALID_LENGTH = 2002 + CONTACT_INVALID_TYPE = 2003 + CONTACT_NOT_FOUND = 2004 + + class ContactError(Exception): - ... + """ + Overview of contact error codes: + - 2000 CONTACT_TYPE_NONE + - 2001 CONTACT_ID_NONE + - 2002 CONTACT_ID_INVALID_LENGTH + - 2003 CONTACT_INVALID_TYPE + - 2004 CONTACT_NOT_FOUND + """ + + # For linter + _contact_id_error = "contact_id has an invalid length. Cannot exceed 16 characters." + _contact_invalid_error = "Contact must be of type InfoContactResultData" + _contact_not_found_error = "No contact was found in cache or the registry" + _error_mapping = { + ContactErrorCodes.CONTACT_TYPE_NONE: "contact_type is None", + ContactErrorCodes.CONTACT_ID_NONE: "contact_id is None", + ContactErrorCodes.CONTACT_ID_INVALID_LENGTH: _contact_id_error, + ContactErrorCodes.CONTACT_INVALID_TYPE: _contact_invalid_error, + ContactErrorCodes.CONTACT_NOT_FOUND: _contact_not_found_error, + } + + def __init__(self, *args, code=None, **kwargs): + super().__init__(*args, **kwargs) + self.code = code + if self.code in self._error_mapping: + self.message = self._error_mapping.get(self.code) + + def __str__(self): + return f"{self.message}" diff --git a/src/registrar/templates/domain_detail.html b/src/registrar/templates/domain_detail.html index 6a700b393..bcf775fe5 100644 --- a/src/registrar/templates/domain_detail.html +++ b/src/registrar/templates/domain_detail.html @@ -46,8 +46,11 @@ {% include "includes/summary_item.html" with title='Your contact information' value=request.user.contact contact='true' edit_link=url %} {% url 'domain-security-email' pk=domain.id as url %} - {% include "includes/summary_item.html" with title='Security email' value=domain.security_email edit_link=url %} - + {% if security_email is not None and security_email != default_security_email%} + {% include "includes/summary_item.html" with title='Security email' value=security_email edit_link=url %} + {% else %} + {% include "includes/summary_item.html" with title='Security email' value='None provided' edit_link=url %} + {% endif %} {% url 'domain-users' pk=domain.id as url %} {% include "includes/summary_item.html" with title='User management' users='true' list=True value=domain.permissions.all edit_link=url %} diff --git a/src/registrar/templates/domain_security_email.html b/src/registrar/templates/domain_security_email.html index cb3af5725..8fb0ccfb0 100644 --- a/src/registrar/templates/domain_security_email.html +++ b/src/registrar/templates/domain_security_email.html @@ -11,8 +11,6 @@
A security contact should be capable of evaluating or triaging security reports for your entire domain. Use a team email address, not an individual’s email. We recommend using an alias, like security@domain.gov.
- {% include "includes/required_fields.html" %} -