From 7c87718e2d21e310443d1482113e060d6d7f47b4 Mon Sep 17 00:00:00 2001 From: Erin <121973038+erinysong@users.noreply.github.com> Date: Tue, 9 Jan 2024 11:15:54 -0800 Subject: [PATCH 01/23] Save initial script --- src/epplibwrapper/tests/test_pool.py | 13 +++++ src/migrationdata/README.md | 8 --- .../update_security_email_disclose.py | 53 +++++++++++++++++++ src/registrar/models/domain.py | 2 +- 4 files changed, 67 insertions(+), 9 deletions(-) delete mode 100644 src/migrationdata/README.md create mode 100644 src/registrar/management/commands/update_security_email_disclose.py diff --git a/src/epplibwrapper/tests/test_pool.py b/src/epplibwrapper/tests/test_pool.py index 1c36d26da..916015980 100644 --- a/src/epplibwrapper/tests/test_pool.py +++ b/src/epplibwrapper/tests/test_pool.py @@ -246,3 +246,16 @@ class TestConnectionPool(TestCase): expected = "InfoDomain failed to execute due to a connection error." result = registry.send(commands.InfoDomain(name="test.gov"), cleaned=True) self.assertEqual(result, expected) + + @patch.object(EPPLibWrapper, "_test_registry_connection_success", patch_success) + def test_retries_on_transport_error(self): + """A .send is invoked on the pool, but transport error occurs and EPP + retries connection.""" + + with ExitStack() as stack: + stack.enter_context(patch.object(EPPConnectionPool, "_create_socket", self.fake_socket)) + stack.enter_context(patch.object(Socket, "connect", self.fake_client)) + + # Pool should be running + self.assertEqual(registry.pool_status.connection_success, True) + self.assertEqual(registry.pool_status.pool_running, True) diff --git a/src/migrationdata/README.md b/src/migrationdata/README.md deleted file mode 100644 index 81190ee3f..000000000 --- a/src/migrationdata/README.md +++ /dev/null @@ -1,8 +0,0 @@ -## Purpose -Use this folder for storing files for the migration process. Should otherwise be empty on local dev environments unless necessary. This folder must exist due to the nature of how data is stored on cloud.gov and the nature of the data we want to send. - -## How do I migrate registrar data? -This process is detailed in [data_migration.md](../../docs/operations/data_migration.md) - -## What kind of files can I store here? -The intent is for PII data or otherwise, but this can exist in any format. Do note that the data contained in this file will be temporary, so after the app is restaged it will lose it. This is ideal for migration files as they write to our DB, but not for something you need to permanently hold onto. \ No newline at end of file diff --git a/src/registrar/management/commands/update_security_email_disclose.py b/src/registrar/management/commands/update_security_email_disclose.py new file mode 100644 index 000000000..13627e220 --- /dev/null +++ b/src/registrar/management/commands/update_security_email_disclose.py @@ -0,0 +1,53 @@ +""""Script description""" + +import logging + +from django.core.management import BaseCommand +from registrar.models import Domain + +logger = logging.getLogger(__name__) + +class Command(BaseCommand): + # TODO: write script description here + help = "Description" + + def __init__(self): + """Sets global variables for code tidyness""" + super().__init__() + # this array is used to store domains with errors, which are not + # successfully updated to disclose + domains_with_errors: List[str] = [] + + def handle(self, **options): + """ + Description for what update_security_email_disclose does + """ + logger.info("Updating security emails to public") + + domains = Domain.objects.filter() + + # Call security_contact on all domains to trigger saving contact information + for domain in domains: + contact = domain.security_contact + + domains_with_contact = Domain.objects.filter( + security_contact_registry_id=True + ) + logger.info("Found %d domains with security contact.", len(domains_with_contact)) + + # Update EPP contact for domains with a security contact + for domain in domains_with_contact: + try: + domain._update_epp_contact(contact=domain.security_contact_registry_id) + logger.info("Updated EPP contact for domain %d to disclose: %d", domain, domain.security_contact.disclose) + except Exception as err: + # error condition if domain not in database + self.domains_with_errors.append(copy.deepcopy(domain.domain_name)) + logger.error(f"error retrieving domain {domain.domain_name}: {err}") + + domains_disclosed = Domain.objects.filter( + security_contact_registry_id=True, + ) + logger.info("Updated %d domains to disclosed.", len(domains_disclosed)) + + diff --git a/src/registrar/models/domain.py b/src/registrar/models/domain.py index 001937b89..b3791d4b9 100644 --- a/src/registrar/models/domain.py +++ b/src/registrar/models/domain.py @@ -1400,7 +1400,7 @@ class Domain(TimeStampedModel, DomainHelper): is_security = contact.contact_type == contact.ContactTypeChoices.SECURITY DF = epp.DiscloseField fields = {DF.EMAIL} - disclose = is_security and contact.email != PublicContact.get_default_security().email + disclose = is_security # Will only disclose DF.EMAIL if its not the default return epp.Disclose( flag=disclose, From 683a2f46292d025cc2dd56c21972695bc4405854 Mon Sep 17 00:00:00 2001 From: Erin <121973038+erinysong@users.noreply.github.com> Date: Tue, 9 Jan 2024 17:13:48 -0800 Subject: [PATCH 02/23] Update initial disclose script --- .../update_security_email_disclose.py | 32 +++++++++++-------- src/registrar/models/domain.py | 2 ++ 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/src/registrar/management/commands/update_security_email_disclose.py b/src/registrar/management/commands/update_security_email_disclose.py index 13627e220..9ba1c58b7 100644 --- a/src/registrar/management/commands/update_security_email_disclose.py +++ b/src/registrar/management/commands/update_security_email_disclose.py @@ -1,6 +1,7 @@ """"Script description""" import logging +import copy from django.core.management import BaseCommand from registrar.models import Domain @@ -14,16 +15,20 @@ class Command(BaseCommand): def __init__(self): """Sets global variables for code tidyness""" super().__init__() - # this array is used to store domains with errors, which are not - # successfully updated to disclose - domains_with_errors: List[str] = [] + # domains and transition domains that must be disclosed to true + self.domains_to_disclose: List[str] = [] + # domains with errors, which are not successfully updated to disclose + self.domains_with_errors: List[str] = [] + # domains that are successfully disclosed + self.disclosed_domain_contacts: List[str] = [] def handle(self, **options): """ Description for what update_security_email_disclose does """ logger.info("Updating security emails to public") - + + # Initializes domains that need to be disclosed domains = Domain.objects.filter() # Call security_contact on all domains to trigger saving contact information @@ -31,23 +36,24 @@ class Command(BaseCommand): contact = domain.security_contact domains_with_contact = Domain.objects.filter( - security_contact_registry_id=True + security_contact_registry_id__isnull=False ) logger.info("Found %d domains with security contact.", len(domains_with_contact)) # Update EPP contact for domains with a security contact for domain in domains_with_contact: try: - domain._update_epp_contact(contact=domain.security_contact_registry_id) - logger.info("Updated EPP contact for domain %d to disclose: %d", domain, domain.security_contact.disclose) + logger.info("Domain %s security contact: %s", domain, domain.security_contact) + domain._update_epp_contact(contact=domain.security_contact) + self.disclosed_domain_contacts.append(copy.deepcopy(domain.security_contact)) except Exception as err: # error condition if domain not in database - self.domains_with_errors.append(copy.deepcopy(domain.domain_name)) - logger.error(f"error retrieving domain {domain.domain_name}: {err}") + self.domains_with_errors.append(copy.deepcopy(domain.domain_info)) + logger.error(f"error retrieving domain {domain.domain_info}: {err}") - domains_disclosed = Domain.objects.filter( - security_contact_registry_id=True, - ) - logger.info("Updated %d domains to disclosed.", len(domains_disclosed)) + # Update transition domains to disclose + + # Inform user how many contacts were disclosed + logger.info("Updated %d contacts to disclosed.", len(self.disclosed_domain_contacts)) diff --git a/src/registrar/models/domain.py b/src/registrar/models/domain.py index b3791d4b9..bdca1d4ef 100644 --- a/src/registrar/models/domain.py +++ b/src/registrar/models/domain.py @@ -1401,6 +1401,8 @@ class Domain(TimeStampedModel, DomainHelper): DF = epp.DiscloseField fields = {DF.EMAIL} disclose = is_security + # Delete after testing + logger.info("Updated domain contact to disclose: %s", disclose) # Will only disclose DF.EMAIL if its not the default return epp.Disclose( flag=disclose, From 0a13ff99766e3eca6705d1fc520314637e463823 Mon Sep 17 00:00:00 2001 From: Erin <121973038+erinysong@users.noreply.github.com> Date: Wed, 10 Jan 2024 10:38:17 -0800 Subject: [PATCH 03/23] Readd default email check for email disclose --- .../update_security_email_disclose.py | 24 ++++++++++--------- src/registrar/models/domain.py | 2 +- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/src/registrar/management/commands/update_security_email_disclose.py b/src/registrar/management/commands/update_security_email_disclose.py index 9ba1c58b7..ffefc815b 100644 --- a/src/registrar/management/commands/update_security_email_disclose.py +++ b/src/registrar/management/commands/update_security_email_disclose.py @@ -29,30 +29,32 @@ class Command(BaseCommand): logger.info("Updating security emails to public") # Initializes domains that need to be disclosed - domains = Domain.objects.filter() + statuses=["ready", "dns needed"] + domains = Domain.objects.filter( + state__in=statuses + ) # Call security_contact on all domains to trigger saving contact information for domain in domains: contact = domain.security_contact - domains_with_contact = Domain.objects.filter( - security_contact_registry_id__isnull=False - ) - logger.info("Found %d domains with security contact.", len(domains_with_contact)) + logger.info("Found %d domains with status Ready or DNS Needed.", len(domains)) # Update EPP contact for domains with a security contact - for domain in domains_with_contact: + for domain in domains: try: - logger.info("Domain %s security contact: %s", domain, domain.security_contact) - domain._update_epp_contact(contact=domain.security_contact) - self.disclosed_domain_contacts.append(copy.deepcopy(domain.security_contact)) + logger.info("Domain %s security contact: %s", domain.domain_info, domain.security_contact.email) + if domain.security_contact.email != "registrar@dotgov.gov": + domain._update_epp_contact(contact=domain.security_contact) + self.disclosed_domain_contacts.append(copy.deepcopy(domain.security_contact)) + else: + logger.info("Skipping disclose for %s security contact.", + domain.domain_info, domain.security_contact.email) except Exception as err: # error condition if domain not in database self.domains_with_errors.append(copy.deepcopy(domain.domain_info)) logger.error(f"error retrieving domain {domain.domain_info}: {err}") - # Update transition domains to disclose - # Inform user how many contacts were disclosed logger.info("Updated %d contacts to disclosed.", len(self.disclosed_domain_contacts)) diff --git a/src/registrar/models/domain.py b/src/registrar/models/domain.py index bdca1d4ef..7f052a581 100644 --- a/src/registrar/models/domain.py +++ b/src/registrar/models/domain.py @@ -1400,7 +1400,7 @@ class Domain(TimeStampedModel, DomainHelper): is_security = contact.contact_type == contact.ContactTypeChoices.SECURITY DF = epp.DiscloseField fields = {DF.EMAIL} - disclose = is_security + disclose = is_security and contact.email != PublicContact.get_default_security().email # Delete after testing logger.info("Updated domain contact to disclose: %s", disclose) # Will only disclose DF.EMAIL if its not the default From f87be48c474dd2a2ceac103ae9eb78822bd6888c Mon Sep 17 00:00:00 2001 From: Erin <121973038+erinysong@users.noreply.github.com> Date: Wed, 10 Jan 2024 14:35:59 -0800 Subject: [PATCH 04/23] Add logs for skipped disclose contacts --- .../commands/update_security_email_disclose.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/registrar/management/commands/update_security_email_disclose.py b/src/registrar/management/commands/update_security_email_disclose.py index ffefc815b..7bf2c2533 100644 --- a/src/registrar/management/commands/update_security_email_disclose.py +++ b/src/registrar/management/commands/update_security_email_disclose.py @@ -21,6 +21,8 @@ class Command(BaseCommand): self.domains_with_errors: List[str] = [] # domains that are successfully disclosed self.disclosed_domain_contacts: List[str] = [] + # domains that skip disclose due to having contact registrar@dotgov.gov + self.skipped_domain_contacts: List[str] = [] def handle(self, **options): """ @@ -48,14 +50,17 @@ class Command(BaseCommand): domain._update_epp_contact(contact=domain.security_contact) self.disclosed_domain_contacts.append(copy.deepcopy(domain.security_contact)) else: - logger.info("Skipping disclose for %s security contact.", + logger.info("Skipping disclose for %s security contact %s.", domain.domain_info, domain.security_contact.email) + self.skipped_domain_contacts.append(copy.deepcopy(domain.security_contact)) except Exception as err: # error condition if domain not in database self.domains_with_errors.append(copy.deepcopy(domain.domain_info)) logger.error(f"error retrieving domain {domain.domain_info}: {err}") - # Inform user how many contacts were disclosed + # Inform user how many contacts were disclosed and skipped logger.info("Updated %d contacts to disclosed.", len(self.disclosed_domain_contacts)) + logger.info("Skipped disclosing %d contacts with security email registrar@dotgov.gov.", + len(self.skipped_domain_contacts)) From e3bb4afbb12d5c92213e091b143f83d1b9490604 Mon Sep 17 00:00:00 2001 From: Erin <121973038+erinysong@users.noreply.github.com> Date: Wed, 10 Jan 2024 16:12:08 -0800 Subject: [PATCH 05/23] Add test for disclose_security_emails making EPP calls --- ...isclose.py => disclose_security_emails.py} | 0 src/registrar/tests/test_models_domain.py | 30 +++++++++++++++++++ 2 files changed, 30 insertions(+) rename src/registrar/management/commands/{update_security_email_disclose.py => disclose_security_emails.py} (100%) diff --git a/src/registrar/management/commands/update_security_email_disclose.py b/src/registrar/management/commands/disclose_security_emails.py similarity index 100% rename from src/registrar/management/commands/update_security_email_disclose.py rename to src/registrar/management/commands/disclose_security_emails.py diff --git a/src/registrar/tests/test_models_domain.py b/src/registrar/tests/test_models_domain.py index 9026832cd..6b3a7ba05 100644 --- a/src/registrar/tests/test_models_domain.py +++ b/src/registrar/tests/test_models_domain.py @@ -5,6 +5,7 @@ This file tests the various ways in which the registrar interacts with the regis """ from django.test import TestCase from django.db.utils import IntegrityError +from django.core.management import call_command from unittest.mock import MagicMock, patch, call import datetime from registrar.models import Domain, Host, HostIP @@ -548,6 +549,19 @@ class TestRegistrantContacts(MockEppLib): self.domain_contact._invalidate_cache() PublicContact.objects.all().delete() Domain.objects.all().delete() + + def run_disclose_security_emails(self): + """ + This method executes the disclose_security_emails command. + + The 'call_command' function from Django's management framework is then used to + execute the disclose_security_emails command. + """ + with patch( + "registrar.management.commands.utility.terminal_helper.TerminalHelper.query_yes_no_exit", # noqa + return_value=True, + ): + call_command("extend_expiration_dates") def test_no_security_email(self): """ @@ -963,6 +977,22 @@ class TestRegistrantContacts(MockEppLib): self.mockedSendFunction.assert_any_call(expectedCreateCommand, cleaned=True) # Confirm that we are getting the desired email self.assertEqual(domain.security_contact.email, expectedSecContact.email) + + def test_disclose_security_emails(self): + """ + Tests that command disclose_security_emails runs successfully with + appropriate logs. + """ + domain, _ = Domain.objects.get_or_create(name="igorville.gov") + expectedSecContact = PublicContact.get_default_security() + expectedSecContact.domain = domain + expectedSecContact.email = "123@mail.gov" + domain.security_contact = expectedSecContact + self.run_disclose_security_emails() + + # running disclose_security_emails makes EPP calls + expectedUpdateCommand = self._convertPublicContactToEpp(expectedSecContact, disclose_email=True) + self.mockedSendFunction.assert_any_call(expectedUpdateCommand, cleaned=True) @skip("not implemented yet") def test_update_is_unsuccessful(self): From 273d457ac611eb58910c813605a449cac2e0fecc Mon Sep 17 00:00:00 2001 From: Erin <121973038+erinysong@users.noreply.github.com> Date: Wed, 10 Jan 2024 16:12:55 -0800 Subject: [PATCH 06/23] Reword test description --- src/registrar/tests/test_models_domain.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/registrar/tests/test_models_domain.py b/src/registrar/tests/test_models_domain.py index 6b3a7ba05..9c0a73a0a 100644 --- a/src/registrar/tests/test_models_domain.py +++ b/src/registrar/tests/test_models_domain.py @@ -981,7 +981,7 @@ class TestRegistrantContacts(MockEppLib): def test_disclose_security_emails(self): """ Tests that command disclose_security_emails runs successfully with - appropriate logs. + appropriate EPP calll to UpdateContact. """ domain, _ = Domain.objects.get_or_create(name="igorville.gov") expectedSecContact = PublicContact.get_default_security() From 4ddf96aed4a684aa0fb997994461368d764e6c4d Mon Sep 17 00:00:00 2001 From: Erin <121973038+erinysong@users.noreply.github.com> Date: Wed, 10 Jan 2024 16:15:40 -0800 Subject: [PATCH 07/23] Add description to disclose_security_emails script --- .../management/commands/disclose_security_emails.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/registrar/management/commands/disclose_security_emails.py b/src/registrar/management/commands/disclose_security_emails.py index 7bf2c2533..ff26e4882 100644 --- a/src/registrar/management/commands/disclose_security_emails.py +++ b/src/registrar/management/commands/disclose_security_emails.py @@ -1,4 +1,8 @@ -""""Script description""" +"""" +Converts all ready and DNS needed domains with a non-default public contact +to disclose their public contact. Created for Issue#1535 to resolve + disclose issue of domains with missing security emails. +""" import logging import copy @@ -9,8 +13,7 @@ from registrar.models import Domain logger = logging.getLogger(__name__) class Command(BaseCommand): - # TODO: write script description here - help = "Description" + help = "Disclose all nondefault domain security emails." def __init__(self): """Sets global variables for code tidyness""" @@ -26,7 +29,8 @@ class Command(BaseCommand): def handle(self, **options): """ - Description for what update_security_email_disclose does + Converts all ready and DNS needed domains with a non-default public contact + to disclose their public contact. """ logger.info("Updating security emails to public") From d34b49c685ce63b625c8525d40f65393299db032 Mon Sep 17 00:00:00 2001 From: Erin <121973038+erinysong@users.noreply.github.com> Date: Wed, 10 Jan 2024 16:34:30 -0800 Subject: [PATCH 08/23] Fix lint errors --- .../commands/disclose_security_emails.py | 40 +++++++++++-------- src/registrar/tests/test_models_domain.py | 4 +- 2 files changed, 25 insertions(+), 19 deletions(-) diff --git a/src/registrar/management/commands/disclose_security_emails.py b/src/registrar/management/commands/disclose_security_emails.py index ff26e4882..a7ea0d2dd 100644 --- a/src/registrar/management/commands/disclose_security_emails.py +++ b/src/registrar/management/commands/disclose_security_emails.py @@ -12,6 +12,7 @@ from registrar.models import Domain logger = logging.getLogger(__name__) + class Command(BaseCommand): help = "Disclose all nondefault domain security emails." @@ -19,13 +20,13 @@ class Command(BaseCommand): """Sets global variables for code tidyness""" super().__init__() # domains and transition domains that must be disclosed to true - self.domains_to_disclose: List[str] = [] + self.contacts_saved: list[str] = [] # domains with errors, which are not successfully updated to disclose - self.domains_with_errors: List[str] = [] + self.domains_with_errors: list[str] = [] # domains that are successfully disclosed - self.disclosed_domain_contacts: List[str] = [] + self.disclosed_domain_contacts: list[str] = [] # domains that skip disclose due to having contact registrar@dotgov.gov - self.skipped_domain_contacts: List[str] = [] + self.skipped_domain_contacts: list[str] = [] def handle(self, **options): """ @@ -33,18 +34,20 @@ class Command(BaseCommand): to disclose their public contact. """ logger.info("Updating security emails to public") - + # Initializes domains that need to be disclosed - statuses=["ready", "dns needed"] - domains = Domain.objects.filter( - state__in=statuses - ) - + + statuses = ["ready", "dns needed"] + domains = Domain.objects.filter(state__in=statuses) + + logger.info("Found %d domains with status Ready or DNS Needed.", len(domains)) + # Call security_contact on all domains to trigger saving contact information for domain in domains: contact = domain.security_contact + self.contacts_saved.append(copy.deepcopy(contact)) - logger.info("Found %d domains with status Ready or DNS Needed.", len(domains)) + logger.info("Found %d security contacts.", len(self.contacts_saved)) # Update EPP contact for domains with a security contact for domain in domains: @@ -54,8 +57,11 @@ class Command(BaseCommand): domain._update_epp_contact(contact=domain.security_contact) self.disclosed_domain_contacts.append(copy.deepcopy(domain.security_contact)) else: - logger.info("Skipping disclose for %s security contact %s.", - domain.domain_info, domain.security_contact.email) + logger.info( + "Skipping disclose for %s security contact %s.", + domain.domain_info, + domain.security_contact.email, + ) self.skipped_domain_contacts.append(copy.deepcopy(domain.security_contact)) except Exception as err: # error condition if domain not in database @@ -64,7 +70,7 @@ class Command(BaseCommand): # Inform user how many contacts were disclosed and skipped logger.info("Updated %d contacts to disclosed.", len(self.disclosed_domain_contacts)) - logger.info("Skipped disclosing %d contacts with security email registrar@dotgov.gov.", - len(self.skipped_domain_contacts)) - - + logger.info( + "Skipped disclosing %d contacts with security email registrar@dotgov.gov.", + len(self.skipped_domain_contacts), + ) diff --git a/src/registrar/tests/test_models_domain.py b/src/registrar/tests/test_models_domain.py index 9c0a73a0a..81b63e3f6 100644 --- a/src/registrar/tests/test_models_domain.py +++ b/src/registrar/tests/test_models_domain.py @@ -549,7 +549,7 @@ class TestRegistrantContacts(MockEppLib): self.domain_contact._invalidate_cache() PublicContact.objects.all().delete() Domain.objects.all().delete() - + def run_disclose_security_emails(self): """ This method executes the disclose_security_emails command. @@ -977,7 +977,7 @@ class TestRegistrantContacts(MockEppLib): self.mockedSendFunction.assert_any_call(expectedCreateCommand, cleaned=True) # Confirm that we are getting the desired email self.assertEqual(domain.security_contact.email, expectedSecContact.email) - + def test_disclose_security_emails(self): """ Tests that command disclose_security_emails runs successfully with From 79870a5616e2795328d788c0dc012e3fa8b9f256 Mon Sep 17 00:00:00 2001 From: Erin <121973038+erinysong@users.noreply.github.com> Date: Tue, 16 Jan 2024 16:02:35 -0800 Subject: [PATCH 09/23] Remove unused files in git diff --- src/epplibwrapper/tests/test_pool.py | 13 ------------- src/migrationdata/README.md | 8 ++++++++ .../management/commands/disclose_security_emails.py | 5 +++-- src/registrar/models/domain.py | 4 ++-- src/registrar/tests/test_models_domain.py | 2 +- 5 files changed, 14 insertions(+), 18 deletions(-) create mode 100644 src/migrationdata/README.md diff --git a/src/epplibwrapper/tests/test_pool.py b/src/epplibwrapper/tests/test_pool.py index 916015980..1c36d26da 100644 --- a/src/epplibwrapper/tests/test_pool.py +++ b/src/epplibwrapper/tests/test_pool.py @@ -246,16 +246,3 @@ class TestConnectionPool(TestCase): expected = "InfoDomain failed to execute due to a connection error." result = registry.send(commands.InfoDomain(name="test.gov"), cleaned=True) self.assertEqual(result, expected) - - @patch.object(EPPLibWrapper, "_test_registry_connection_success", patch_success) - def test_retries_on_transport_error(self): - """A .send is invoked on the pool, but transport error occurs and EPP - retries connection.""" - - with ExitStack() as stack: - stack.enter_context(patch.object(EPPConnectionPool, "_create_socket", self.fake_socket)) - stack.enter_context(patch.object(Socket, "connect", self.fake_client)) - - # Pool should be running - self.assertEqual(registry.pool_status.connection_success, True) - self.assertEqual(registry.pool_status.pool_running, True) diff --git a/src/migrationdata/README.md b/src/migrationdata/README.md new file mode 100644 index 000000000..81190ee3f --- /dev/null +++ b/src/migrationdata/README.md @@ -0,0 +1,8 @@ +## Purpose +Use this folder for storing files for the migration process. Should otherwise be empty on local dev environments unless necessary. This folder must exist due to the nature of how data is stored on cloud.gov and the nature of the data we want to send. + +## How do I migrate registrar data? +This process is detailed in [data_migration.md](../../docs/operations/data_migration.md) + +## What kind of files can I store here? +The intent is for PII data or otherwise, but this can exist in any format. Do note that the data contained in this file will be temporary, so after the app is restaged it will lose it. This is ideal for migration files as they write to our DB, but not for something you need to permanently hold onto. \ No newline at end of file diff --git a/src/registrar/management/commands/disclose_security_emails.py b/src/registrar/management/commands/disclose_security_emails.py index a7ea0d2dd..cdbac2a41 100644 --- a/src/registrar/management/commands/disclose_security_emails.py +++ b/src/registrar/management/commands/disclose_security_emails.py @@ -68,9 +68,10 @@ class Command(BaseCommand): self.domains_with_errors.append(copy.deepcopy(domain.domain_info)) logger.error(f"error retrieving domain {domain.domain_info}: {err}") - # Inform user how many contacts were disclosed and skipped + # Inform user how many contacts were disclosed, skipped, and errored logger.info("Updated %d contacts to disclosed.", len(self.disclosed_domain_contacts)) logger.info( "Skipped disclosing %d contacts with security email registrar@dotgov.gov.", - len(self.skipped_domain_contacts), + len(self.skipped_domain_contacts) ) + logger.info("Error disclosing %d contacts.", len(self.domains_with_errors)) \ No newline at end of file diff --git a/src/registrar/models/domain.py b/src/registrar/models/domain.py index 7f052a581..4d455d320 100644 --- a/src/registrar/models/domain.py +++ b/src/registrar/models/domain.py @@ -1401,8 +1401,8 @@ class Domain(TimeStampedModel, DomainHelper): DF = epp.DiscloseField fields = {DF.EMAIL} disclose = is_security and contact.email != PublicContact.get_default_security().email - # Delete after testing - logger.info("Updated domain contact to disclose: %s", disclose) + # Delete after testing on other devices + logger.info("Updated domain contact %s to disclose: %s", contact.email, disclose) # Will only disclose DF.EMAIL if its not the default return epp.Disclose( flag=disclose, diff --git a/src/registrar/tests/test_models_domain.py b/src/registrar/tests/test_models_domain.py index 81b63e3f6..af9c7b053 100644 --- a/src/registrar/tests/test_models_domain.py +++ b/src/registrar/tests/test_models_domain.py @@ -561,7 +561,7 @@ class TestRegistrantContacts(MockEppLib): "registrar.management.commands.utility.terminal_helper.TerminalHelper.query_yes_no_exit", # noqa return_value=True, ): - call_command("extend_expiration_dates") + call_command("disclose_security_emails") def test_no_security_email(self): """ From 39a5875b87a743a0cdd0b4114fe5ee642b710399 Mon Sep 17 00:00:00 2001 From: Erin <121973038+erinysong@users.noreply.github.com> Date: Tue, 16 Jan 2024 16:04:30 -0800 Subject: [PATCH 10/23] Update disclose_security_emails to use Domain constants --- src/registrar/management/commands/disclose_security_emails.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/registrar/management/commands/disclose_security_emails.py b/src/registrar/management/commands/disclose_security_emails.py index cdbac2a41..339a34f9a 100644 --- a/src/registrar/management/commands/disclose_security_emails.py +++ b/src/registrar/management/commands/disclose_security_emails.py @@ -37,7 +37,7 @@ class Command(BaseCommand): # Initializes domains that need to be disclosed - statuses = ["ready", "dns needed"] + statuses = [Domain.State.READY, Domain.State.DNS_NEEDED] domains = Domain.objects.filter(state__in=statuses) logger.info("Found %d domains with status Ready or DNS Needed.", len(domains)) From 22ace8aee9ed1c0732a0e3645c8e2ba0e450797f Mon Sep 17 00:00:00 2001 From: Erin <121973038+erinysong@users.noreply.github.com> Date: Tue, 16 Jan 2024 16:23:05 -0800 Subject: [PATCH 11/23] Convert domain lists to counters --- .../commands/disclose_security_emails.py | 28 +++++++++++-------- 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/src/registrar/management/commands/disclose_security_emails.py b/src/registrar/management/commands/disclose_security_emails.py index 339a34f9a..c7a202a2e 100644 --- a/src/registrar/management/commands/disclose_security_emails.py +++ b/src/registrar/management/commands/disclose_security_emails.py @@ -20,13 +20,13 @@ class Command(BaseCommand): """Sets global variables for code tidyness""" super().__init__() # domains and transition domains that must be disclosed to true - self.contacts_saved: list[str] = [] + self.contacts_saved_count = 0 # domains with errors, which are not successfully updated to disclose self.domains_with_errors: list[str] = [] # domains that are successfully disclosed - self.disclosed_domain_contacts: list[str] = [] + self.disclosed_domain_contacts_counter = 0 # domains that skip disclose due to having contact registrar@dotgov.gov - self.skipped_domain_contacts: list[str] = [] + self.skipped_domain_contacts_counter = 0 def handle(self, **options): """ @@ -45,33 +45,37 @@ class Command(BaseCommand): # Call security_contact on all domains to trigger saving contact information for domain in domains: contact = domain.security_contact - self.contacts_saved.append(copy.deepcopy(contact)) + self.contacts_saved_count++ - logger.info("Found %d security contacts.", len(self.contacts_saved)) + logger.info("Found %d security contacts.", self.contacts_saved) # Update EPP contact for domains with a security contact for domain in domains: try: - logger.info("Domain %s security contact: %s", domain.domain_info, domain.security_contact.email) + logger.info("Domain %s security contact: %s", domain.domain_name, domain.security_contact.email) if domain.security_contact.email != "registrar@dotgov.gov": domain._update_epp_contact(contact=domain.security_contact) - self.disclosed_domain_contacts.append(copy.deepcopy(domain.security_contact)) + self.disclosed_domain_contacts++ else: logger.info( "Skipping disclose for %s security contact %s.", - domain.domain_info, + domain.domain_name, domain.security_contact.email, ) - self.skipped_domain_contacts.append(copy.deepcopy(domain.security_contact)) + self.skipped_domain_contacts++ except Exception as err: # error condition if domain not in database self.domains_with_errors.append(copy.deepcopy(domain.domain_info)) logger.error(f"error retrieving domain {domain.domain_info}: {err}") # Inform user how many contacts were disclosed, skipped, and errored - logger.info("Updated %d contacts to disclosed.", len(self.disclosed_domain_contacts)) + logger.info("Updated %d contacts to disclosed.", self.disclosed_domain_contacts) logger.info( "Skipped disclosing %d contacts with security email registrar@dotgov.gov.", - len(self.skipped_domain_contacts) + self.skipped_domain_contacts ) - logger.info("Error disclosing %d contacts.", len(self.domains_with_errors)) \ No newline at end of file + logger.info( + "Error disclosing the following %d contacts: s", + len(self.domains_with_errors), + self.domains_with_errors + ) \ No newline at end of file From 7da1d81369683118ba661f15d82fa9d5d0a12905 Mon Sep 17 00:00:00 2001 From: Erin <121973038+erinysong@users.noreply.github.com> Date: Tue, 16 Jan 2024 17:26:42 -0800 Subject: [PATCH 12/23] Log list of domains that failed to disclose --- .../commands/disclose_security_emails.py | 35 +++++++++---------- 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/src/registrar/management/commands/disclose_security_emails.py b/src/registrar/management/commands/disclose_security_emails.py index c7a202a2e..f8847a9e5 100644 --- a/src/registrar/management/commands/disclose_security_emails.py +++ b/src/registrar/management/commands/disclose_security_emails.py @@ -24,9 +24,9 @@ class Command(BaseCommand): # domains with errors, which are not successfully updated to disclose self.domains_with_errors: list[str] = [] # domains that are successfully disclosed - self.disclosed_domain_contacts_counter = 0 + self.disclosed_domain_contacts_count = 0 # domains that skip disclose due to having contact registrar@dotgov.gov - self.skipped_domain_contacts_counter = 0 + self.skipped_domain_contacts_count = 0 def handle(self, **options): """ @@ -40,42 +40,41 @@ class Command(BaseCommand): statuses = [Domain.State.READY, Domain.State.DNS_NEEDED] domains = Domain.objects.filter(state__in=statuses) - logger.info("Found %d domains with status Ready or DNS Needed.", len(domains)) + logger.info(f"Found {len(domains)} domains with status Ready or DNS Needed.") # Call security_contact on all domains to trigger saving contact information for domain in domains: contact = domain.security_contact - self.contacts_saved_count++ + self.contacts_saved_count+=1 - logger.info("Found %d security contacts.", self.contacts_saved) + logger.info(f"Found {self.contacts_saved_count} security contacts.") # Update EPP contact for domains with a security contact for domain in domains: try: - logger.info("Domain %s security contact: %s", domain.domain_name, domain.security_contact.email) + logger.info( + f"Domain {domain.domain_info} security contact: {domain.security_contact.email}" + ) if domain.security_contact.email != "registrar@dotgov.gov": domain._update_epp_contact(contact=domain.security_contact) - self.disclosed_domain_contacts++ + self.disclosed_domain_contacts_count+=1 else: logger.info( - "Skipping disclose for %s security contact %s.", - domain.domain_name, - domain.security_contact.email, + f"Skipping disclose for {domain.domain_info} security contact {domain.security_contact.email}." ) - self.skipped_domain_contacts++ + self.skipped_domain_contacts_count+=1 except Exception as err: # error condition if domain not in database self.domains_with_errors.append(copy.deepcopy(domain.domain_info)) - logger.error(f"error retrieving domain {domain.domain_info}: {err}") + logger.error( + f"error retrieving domain {domain.domaidomain_infon_name} contact {domain.security_contact}: {err}" + ) # Inform user how many contacts were disclosed, skipped, and errored - logger.info("Updated %d contacts to disclosed.", self.disclosed_domain_contacts) + logger.info(f"Updated {self.disclosed_domain_contacts_count} contacts to disclosed.") logger.info( - "Skipped disclosing %d contacts with security email registrar@dotgov.gov.", - self.skipped_domain_contacts + f"Skipped disclosing {self.skipped_domain_contacts_count} contacts with security email registrar@dotgov.gov." ) logger.info( - "Error disclosing the following %d contacts: s", - len(self.domains_with_errors), - self.domains_with_errors + f"Error disclosing the following {len(self.domains_with_errors)} contacts: {self.domains_with_errors}" ) \ No newline at end of file From a1ec157dbbe7a9e6f7fcaffd1af907bc72634789 Mon Sep 17 00:00:00 2001 From: Erin <121973038+erinysong@users.noreply.github.com> Date: Wed, 17 Jan 2024 09:03:36 -0800 Subject: [PATCH 13/23] Fix spelling error --- src/registrar/management/commands/disclose_security_emails.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/registrar/management/commands/disclose_security_emails.py b/src/registrar/management/commands/disclose_security_emails.py index f8847a9e5..97769158e 100644 --- a/src/registrar/management/commands/disclose_security_emails.py +++ b/src/registrar/management/commands/disclose_security_emails.py @@ -67,7 +67,7 @@ class Command(BaseCommand): # error condition if domain not in database self.domains_with_errors.append(copy.deepcopy(domain.domain_info)) logger.error( - f"error retrieving domain {domain.domaidomain_infon_name} contact {domain.security_contact}: {err}" + f"error retrieving domain {domain.domain_info} contact {domain.security_contact}: {err}" ) # Inform user how many contacts were disclosed, skipped, and errored From d68e82a130b0892416fd861104daf1ffa28e332f Mon Sep 17 00:00:00 2001 From: Erin <121973038+erinysong@users.noreply.github.com> Date: Wed, 17 Jan 2024 09:13:19 -0800 Subject: [PATCH 14/23] Fix linting --- .../commands/disclose_security_emails.py | 21 ++++++++----------- 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/src/registrar/management/commands/disclose_security_emails.py b/src/registrar/management/commands/disclose_security_emails.py index 97769158e..3e0c06bbc 100644 --- a/src/registrar/management/commands/disclose_security_emails.py +++ b/src/registrar/management/commands/disclose_security_emails.py @@ -44,37 +44,34 @@ class Command(BaseCommand): # Call security_contact on all domains to trigger saving contact information for domain in domains: - contact = domain.security_contact - self.contacts_saved_count+=1 + contact = domain.security_contact # noqa on these items as we only want to call security_contact + self.contacts_saved_count += 1 logger.info(f"Found {self.contacts_saved_count} security contacts.") # Update EPP contact for domains with a security contact for domain in domains: try: - logger.info( - f"Domain {domain.domain_info} security contact: {domain.security_contact.email}" - ) + logger.info(f"Domain {domain.domain_info} security contact: {domain.security_contact.email}") if domain.security_contact.email != "registrar@dotgov.gov": domain._update_epp_contact(contact=domain.security_contact) - self.disclosed_domain_contacts_count+=1 + self.disclosed_domain_contacts_count += 1 else: logger.info( f"Skipping disclose for {domain.domain_info} security contact {domain.security_contact.email}." ) - self.skipped_domain_contacts_count+=1 + self.skipped_domain_contacts_count += 1 except Exception as err: # error condition if domain not in database self.domains_with_errors.append(copy.deepcopy(domain.domain_info)) - logger.error( - f"error retrieving domain {domain.domain_info} contact {domain.security_contact}: {err}" - ) + logger.error(f"error retrieving domain {domain.domain_info} contact {domain.security_contact}: {err}") # Inform user how many contacts were disclosed, skipped, and errored logger.info(f"Updated {self.disclosed_domain_contacts_count} contacts to disclosed.") logger.info( - f"Skipped disclosing {self.skipped_domain_contacts_count} contacts with security email registrar@dotgov.gov." + f"Skipped disclosing {self.skipped_domain_contacts_count} contacts with security \ + email registrar@dotgov.gov." ) logger.info( f"Error disclosing the following {len(self.domains_with_errors)} contacts: {self.domains_with_errors}" - ) \ No newline at end of file + ) From 267ba5130867228e609b43204db8adc57f6abc97 Mon Sep 17 00:00:00 2001 From: Erin <121973038+erinysong@users.noreply.github.com> Date: Wed, 17 Jan 2024 15:00:42 -0800 Subject: [PATCH 15/23] Fix linting --- .../commands/disclose_security_emails.py | 8 +++---- src/registrar/tests/test_models_domain.py | 23 +++++++++++++++---- 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/src/registrar/management/commands/disclose_security_emails.py b/src/registrar/management/commands/disclose_security_emails.py index 3e0c06bbc..4e40dda20 100644 --- a/src/registrar/management/commands/disclose_security_emails.py +++ b/src/registrar/management/commands/disclose_security_emails.py @@ -52,19 +52,19 @@ class Command(BaseCommand): # Update EPP contact for domains with a security contact for domain in domains: try: - logger.info(f"Domain {domain.domain_info} security contact: {domain.security_contact.email}") + logger.info(f"Domain {domain.name} security contact: {domain.security_contact.email}") if domain.security_contact.email != "registrar@dotgov.gov": domain._update_epp_contact(contact=domain.security_contact) self.disclosed_domain_contacts_count += 1 else: logger.info( - f"Skipping disclose for {domain.domain_info} security contact {domain.security_contact.email}." + f"Skipping disclose for {domain.name} security contact {domain.security_contact.email}." ) self.skipped_domain_contacts_count += 1 except Exception as err: # error condition if domain not in database - self.domains_with_errors.append(copy.deepcopy(domain.domain_info)) - logger.error(f"error retrieving domain {domain.domain_info} contact {domain.security_contact}: {err}") + self.domains_with_errors.append(copy.deepcopy(domain.name)) + logger.error(f"error retrieving domain {domain.name} contact {domain.security_contact}: {err}") # Inform user how many contacts were disclosed, skipped, and errored logger.info(f"Updated {self.disclosed_domain_contacts_count} contacts to disclosed.") diff --git a/src/registrar/tests/test_models_domain.py b/src/registrar/tests/test_models_domain.py index af9c7b053..02346b907 100644 --- a/src/registrar/tests/test_models_domain.py +++ b/src/registrar/tests/test_models_domain.py @@ -983,16 +983,31 @@ class TestRegistrantContacts(MockEppLib): Tests that command disclose_security_emails runs successfully with appropriate EPP calll to UpdateContact. """ - domain, _ = Domain.objects.get_or_create(name="igorville.gov") + domain, _ = Domain.objects.get_or_create(name="testdisclose.gov", state=Domain.State.READY) expectedSecContact = PublicContact.get_default_security() expectedSecContact.domain = domain expectedSecContact.email = "123@mail.gov" + # set domain security email to 123@mail.gov instead of default email domain.security_contact = expectedSecContact self.run_disclose_security_emails() - # running disclose_security_emails makes EPP calls - expectedUpdateCommand = self._convertPublicContactToEpp(expectedSecContact, disclose_email=True) - self.mockedSendFunction.assert_any_call(expectedUpdateCommand, cleaned=True) + # running disclose_security_emails sends EPP call UpdateContact with disclose + self.mockedSendFunction.assert_has_calls( + [ + call( + commands.UpdateContact( + id=domain.security_contact.registry_id, + postal_info=domain._make_epp_contact_postal_info(contact=domain.security_contact), + email=domain.security_contact.email, + voice=domain.security_contact.voice, + fax=domain.security_contact.fax, + auth_info=common.ContactAuthInfo(pw="2fooBAR123fooBaz"), + disclose=domain._disclose_fields(contact=domain.security_contact), + ), + cleaned=True, + ) + ] + ) @skip("not implemented yet") def test_update_is_unsuccessful(self): From 08c6803cf03d1891769c51cd7aca608cdd215e28 Mon Sep 17 00:00:00 2001 From: Erin <121973038+erinysong@users.noreply.github.com> Date: Wed, 17 Jan 2024 15:10:11 -0800 Subject: [PATCH 16/23] Fix whitespace issue in logs --- src/registrar/management/commands/disclose_security_emails.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/registrar/management/commands/disclose_security_emails.py b/src/registrar/management/commands/disclose_security_emails.py index 4e40dda20..56f77dc13 100644 --- a/src/registrar/management/commands/disclose_security_emails.py +++ b/src/registrar/management/commands/disclose_security_emails.py @@ -69,7 +69,7 @@ class Command(BaseCommand): # Inform user how many contacts were disclosed, skipped, and errored logger.info(f"Updated {self.disclosed_domain_contacts_count} contacts to disclosed.") logger.info( - f"Skipped disclosing {self.skipped_domain_contacts_count} contacts with security \ + f"Skipped disclosing {self.skipped_domain_contacts_count} contacts with security email registrar@dotgov.gov." ) logger.info( From 595c2f8d80836d6459f24708975e405e78bda9c9 Mon Sep 17 00:00:00 2001 From: Erin <121973038+erinysong@users.noreply.github.com> Date: Wed, 17 Jan 2024 15:27:19 -0800 Subject: [PATCH 17/23] Fix whitespace issue in logs --- src/registrar/management/commands/disclose_security_emails.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/registrar/management/commands/disclose_security_emails.py b/src/registrar/management/commands/disclose_security_emails.py index 56f77dc13..1fdd297a9 100644 --- a/src/registrar/management/commands/disclose_security_emails.py +++ b/src/registrar/management/commands/disclose_security_emails.py @@ -69,8 +69,8 @@ class Command(BaseCommand): # Inform user how many contacts were disclosed, skipped, and errored logger.info(f"Updated {self.disclosed_domain_contacts_count} contacts to disclosed.") logger.info( - f"Skipped disclosing {self.skipped_domain_contacts_count} contacts with security - email registrar@dotgov.gov." + f"Skipped disclosing {self.skipped_domain_contacts_count} contacts with security email " + f"registrar@dotgov.gov." ) logger.info( f"Error disclosing the following {len(self.domains_with_errors)} contacts: {self.domains_with_errors}" From 71f6c8e3ae74decfdde6a8b337952f6bb1cfc255 Mon Sep 17 00:00:00 2001 From: Erin <121973038+erinysong@users.noreply.github.com> Date: Wed, 17 Jan 2024 15:31:57 -0800 Subject: [PATCH 18/23] Fix typo in comment in domain --- src/registrar/models/domain.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/registrar/models/domain.py b/src/registrar/models/domain.py index 4d455d320..1a581a4ec 100644 --- a/src/registrar/models/domain.py +++ b/src/registrar/models/domain.py @@ -1396,7 +1396,7 @@ class Domain(TimeStampedModel, DomainHelper): def _disclose_fields(self, contact: PublicContact): """creates a disclose object that can be added to a contact Create using .disclose= on the command before sending. - if item is security email then make sure email is visable""" + if item is security email then make sure email is visible""" is_security = contact.contact_type == contact.ContactTypeChoices.SECURITY DF = epp.DiscloseField fields = {DF.EMAIL} From 7194b2748f440e9450ac47da75497c566c910537 Mon Sep 17 00:00:00 2001 From: Erin <121973038+erinysong@users.noreply.github.com> Date: Thu, 18 Jan 2024 11:02:36 -0800 Subject: [PATCH 19/23] Merge iterations of domains in disclose_emails script --- .../management/commands/disclose_security_emails.py | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/src/registrar/management/commands/disclose_security_emails.py b/src/registrar/management/commands/disclose_security_emails.py index 1fdd297a9..f44f9bf85 100644 --- a/src/registrar/management/commands/disclose_security_emails.py +++ b/src/registrar/management/commands/disclose_security_emails.py @@ -19,8 +19,6 @@ class Command(BaseCommand): def __init__(self): """Sets global variables for code tidyness""" super().__init__() - # domains and transition domains that must be disclosed to true - self.contacts_saved_count = 0 # domains with errors, which are not successfully updated to disclose self.domains_with_errors: list[str] = [] # domains that are successfully disclosed @@ -42,16 +40,10 @@ class Command(BaseCommand): logger.info(f"Found {len(domains)} domains with status Ready or DNS Needed.") - # Call security_contact on all domains to trigger saving contact information - for domain in domains: - contact = domain.security_contact # noqa on these items as we only want to call security_contact - self.contacts_saved_count += 1 - - logger.info(f"Found {self.contacts_saved_count} security contacts.") - # Update EPP contact for domains with a security contact for domain in domains: try: + contact = domain.security_contact # noqa on these items as we only want to call security_contact logger.info(f"Domain {domain.name} security contact: {domain.security_contact.email}") if domain.security_contact.email != "registrar@dotgov.gov": domain._update_epp_contact(contact=domain.security_contact) From 7c68f8803f35f4fbfc105b0831f440bf3fbe6ba8 Mon Sep 17 00:00:00 2001 From: Erin <121973038+erinysong@users.noreply.github.com> Date: Thu, 18 Jan 2024 16:28:32 -0800 Subject: [PATCH 20/23] Move disclose script tests to test_management_scripts --- .../tests/test_management_scripts.py | 58 ++++++++++++++++++- src/registrar/tests/test_models_domain.py | 44 -------------- 2 files changed, 57 insertions(+), 45 deletions(-) diff --git a/src/registrar/tests/test_management_scripts.py b/src/registrar/tests/test_management_scripts.py index e557eed45..06886ba66 100644 --- a/src/registrar/tests/test_management_scripts.py +++ b/src/registrar/tests/test_management_scripts.py @@ -11,9 +11,11 @@ from registrar.models import ( DomainInformation, UserDomainRole, ) +from registrar.models.public_contact import PublicContact from django.core.management import call_command -from unittest.mock import patch +from unittest.mock import patch, call +from epplibwrapper import commands, common from .common import MockEppLib @@ -441,3 +443,57 @@ class TestExtendExpirationDates(MockEppLib): # Explicitly test the expiration date - should be the same self.assertEqual(desired_domain.expiration_date, datetime.date(2024, 11, 15)) + + +class TestDiscloseEmails(MockEppLib): + def setUp(self): + super().setUp() + + def tearDown(self): + super().tearDown() + PublicContact.objects.all().delete() + Domain.objects.all().delete() + + def run_disclose_security_emails(self): + """ + This method executes the disclose_security_emails command. + + The 'call_command' function from Django's management framework is then used to + execute the disclose_security_emails command. + """ + with patch( + "registrar.management.commands.utility.terminal_helper.TerminalHelper.query_yes_no_exit", # noqa + return_value=True, + ): + call_command("disclose_security_emails") + + def test_disclose_security_emails(self): + """ + Tests that command disclose_security_emails runs successfully with + appropriate EPP calll to UpdateContact. + """ + domain, _ = Domain.objects.get_or_create(name="testdisclose.gov", state=Domain.State.READY) + expectedSecContact = PublicContact.get_default_security() + expectedSecContact.domain = domain + expectedSecContact.email = "123@mail.gov" + # set domain security email to 123@mail.gov instead of default email + domain.security_contact = expectedSecContact + self.run_disclose_security_emails() + + # running disclose_security_emails sends EPP call UpdateContact with disclose + self.mockedSendFunction.assert_has_calls( + [ + call( + commands.UpdateContact( + id=domain.security_contact.registry_id, + postal_info=domain._make_epp_contact_postal_info(contact=domain.security_contact), + email=domain.security_contact.email, + voice=domain.security_contact.voice, + fax=domain.security_contact.fax, + auth_info=common.ContactAuthInfo(pw="2fooBAR123fooBaz"), + disclose=domain._disclose_fields(contact=domain.security_contact), + ), + cleaned=True, + ) + ] + ) diff --git a/src/registrar/tests/test_models_domain.py b/src/registrar/tests/test_models_domain.py index 02346b907..b54b06589 100644 --- a/src/registrar/tests/test_models_domain.py +++ b/src/registrar/tests/test_models_domain.py @@ -550,19 +550,6 @@ class TestRegistrantContacts(MockEppLib): PublicContact.objects.all().delete() Domain.objects.all().delete() - def run_disclose_security_emails(self): - """ - This method executes the disclose_security_emails command. - - The 'call_command' function from Django's management framework is then used to - execute the disclose_security_emails command. - """ - with patch( - "registrar.management.commands.utility.terminal_helper.TerminalHelper.query_yes_no_exit", # noqa - return_value=True, - ): - call_command("disclose_security_emails") - def test_no_security_email(self): """ Scenario: Registrant has not added a security contact email @@ -978,37 +965,6 @@ class TestRegistrantContacts(MockEppLib): # Confirm that we are getting the desired email self.assertEqual(domain.security_contact.email, expectedSecContact.email) - def test_disclose_security_emails(self): - """ - Tests that command disclose_security_emails runs successfully with - appropriate EPP calll to UpdateContact. - """ - domain, _ = Domain.objects.get_or_create(name="testdisclose.gov", state=Domain.State.READY) - expectedSecContact = PublicContact.get_default_security() - expectedSecContact.domain = domain - expectedSecContact.email = "123@mail.gov" - # set domain security email to 123@mail.gov instead of default email - domain.security_contact = expectedSecContact - self.run_disclose_security_emails() - - # running disclose_security_emails sends EPP call UpdateContact with disclose - self.mockedSendFunction.assert_has_calls( - [ - call( - commands.UpdateContact( - id=domain.security_contact.registry_id, - postal_info=domain._make_epp_contact_postal_info(contact=domain.security_contact), - email=domain.security_contact.email, - voice=domain.security_contact.voice, - fax=domain.security_contact.fax, - auth_info=common.ContactAuthInfo(pw="2fooBAR123fooBaz"), - disclose=domain._disclose_fields(contact=domain.security_contact), - ), - cleaned=True, - ) - ] - ) - @skip("not implemented yet") def test_update_is_unsuccessful(self): """ From 3cafc9d3f202a06e2caf30103c68988555c2c94d Mon Sep 17 00:00:00 2001 From: Erin <121973038+erinysong@users.noreply.github.com> Date: Thu, 18 Jan 2024 16:29:04 -0800 Subject: [PATCH 21/23] Fix spelling error --- src/registrar/management/commands/disclose_security_emails.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/registrar/management/commands/disclose_security_emails.py b/src/registrar/management/commands/disclose_security_emails.py index f44f9bf85..62989e4c0 100644 --- a/src/registrar/management/commands/disclose_security_emails.py +++ b/src/registrar/management/commands/disclose_security_emails.py @@ -17,7 +17,7 @@ class Command(BaseCommand): help = "Disclose all nondefault domain security emails." def __init__(self): - """Sets global variables for code tidyness""" + """Sets global variables for code tidiness""" super().__init__() # domains with errors, which are not successfully updated to disclose self.domains_with_errors: list[str] = [] From 2bbd5c4282bc6ed59ee61224254d71e4616d9100 Mon Sep 17 00:00:00 2001 From: Erin <121973038+erinysong@users.noreply.github.com> Date: Thu, 18 Jan 2024 16:33:52 -0800 Subject: [PATCH 22/23] Remove unused import --- src/registrar/tests/test_management_scripts.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/registrar/tests/test_management_scripts.py b/src/registrar/tests/test_management_scripts.py index 06886ba66..b67e3ca3b 100644 --- a/src/registrar/tests/test_management_scripts.py +++ b/src/registrar/tests/test_management_scripts.py @@ -13,7 +13,6 @@ from registrar.models import ( ) from registrar.models.public_contact import PublicContact -from django.core.management import call_command from unittest.mock import patch, call from epplibwrapper import commands, common From d27cf623f58b1dff930009b6008f5c0750abd6e6 Mon Sep 17 00:00:00 2001 From: Erin <121973038+erinysong@users.noreply.github.com> Date: Thu, 18 Jan 2024 16:37:34 -0800 Subject: [PATCH 23/23] Correct imports --- src/registrar/tests/test_management_scripts.py | 1 + src/registrar/tests/test_models_domain.py | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/src/registrar/tests/test_management_scripts.py b/src/registrar/tests/test_management_scripts.py index b67e3ca3b..06886ba66 100644 --- a/src/registrar/tests/test_management_scripts.py +++ b/src/registrar/tests/test_management_scripts.py @@ -13,6 +13,7 @@ from registrar.models import ( ) from registrar.models.public_contact import PublicContact +from django.core.management import call_command from unittest.mock import patch, call from epplibwrapper import commands, common diff --git a/src/registrar/tests/test_models_domain.py b/src/registrar/tests/test_models_domain.py index b54b06589..9026832cd 100644 --- a/src/registrar/tests/test_models_domain.py +++ b/src/registrar/tests/test_models_domain.py @@ -5,7 +5,6 @@ This file tests the various ways in which the registrar interacts with the regis """ from django.test import TestCase from django.db.utils import IntegrityError -from django.core.management import call_command from unittest.mock import MagicMock, patch, call import datetime from registrar.models import Domain, Host, HostIP