diff --git a/core/src/main/java/google/registry/model/registrar/Registrar.java b/core/src/main/java/google/registry/model/registrar/Registrar.java index 262bc18e1..ffe2abfc7 100644 --- a/core/src/main/java/google/registry/model/registrar/Registrar.java +++ b/core/src/main/java/google/registry/model/registrar/Registrar.java @@ -403,6 +403,9 @@ public class Registrar extends UpdateAutoTimestampEntity implements Buildable, J */ DateTime lastExpiringFailoverCertNotificationSentDate = START_OF_TIME; + /** The time that the POCs have been reviewed last. */ + @Expose DateTime lastPocVerificationDate = START_OF_TIME; + /** Telephone support passcode (5-digit numeric) */ String phonePasscode; @@ -461,6 +464,10 @@ public class Registrar extends UpdateAutoTimestampEntity implements Buildable, J return registrarName; } + public DateTime getLastPocVerificationDate() { + return lastPocVerificationDate; + } + public Type getType() { return type; } @@ -614,6 +621,7 @@ public class Registrar extends UpdateAutoTimestampEntity implements Buildable, J .putString( "lastExpiringFailoverCertNotificationSentDate", lastExpiringFailoverCertNotificationSentDate) + .putString("lastPocVerificationDate", lastPocVerificationDate) .put("registrarName", registrarName) .put("type", type) .put("state", state) @@ -802,6 +810,12 @@ public class Registrar extends UpdateAutoTimestampEntity implements Buildable, J return thisCastToDerived(); } + public B setLastPocVerificationDate(DateTime now) { + checkArgumentNotNull(now, "Registrar lastPocVerificationDate cannot be null"); + getInstance().lastPocVerificationDate = now; + return thisCastToDerived(); + } + private static String calculateHash(String clientCertificate) { if (clientCertificate == null) { return null; diff --git a/core/src/main/java/google/registry/ui/server/console/ConsoleUpdateRegistrarAction.java b/core/src/main/java/google/registry/ui/server/console/ConsoleUpdateRegistrarAction.java index 413625d0d..c3d5cfdba 100644 --- a/core/src/main/java/google/registry/ui/server/console/ConsoleUpdateRegistrarAction.java +++ b/core/src/main/java/google/registry/ui/server/console/ConsoleUpdateRegistrarAction.java @@ -97,6 +97,7 @@ public class ConsoleUpdateRegistrarAction extends ConsoleApiAction { .map(DomainNameUtils::canonicalizeHostname) .collect(Collectors.toSet())) .setRegistryLockAllowed(registrarParam.isRegistryLockAllowed()) + .setLastPocVerificationDate(registrarParam.getLastPocVerificationDate()) .build(); tm().put(updatedRegistrar); diff --git a/core/src/test/java/google/registry/model/registrar/RegistrarTest.java b/core/src/test/java/google/registry/model/registrar/RegistrarTest.java index ee4757b16..f12ab8c5d 100644 --- a/core/src/test/java/google/registry/model/registrar/RegistrarTest.java +++ b/core/src/test/java/google/registry/model/registrar/RegistrarTest.java @@ -496,6 +496,28 @@ class RegistrarTest extends EntityTestCase { .isEqualTo(fakeClock.nowUtc()); } + @Test + void testSuccess_setLastPocVerificationDate() { + assertThat( + registrar + .asBuilder() + .setLastPocVerificationDate(fakeClock.nowUtc()) + .build() + .getLastPocVerificationDate()) + .isEqualTo(fakeClock.nowUtc()); + } + + @Test + void testFailure_setLastPocVerificationDate_nullDate() { + IllegalArgumentException thrown = + assertThrows( + IllegalArgumentException.class, + () -> new Registrar.Builder().setLastPocVerificationDate(null).build()); + assertThat(thrown) + .hasMessageThat() + .isEqualTo("Registrar lastPocVerificationDate cannot be null"); + } + @Test void testFailure_setLastExpiringFailoverCertNotificationSentDate_nullDate() { IllegalArgumentException thrown = diff --git a/core/src/test/java/google/registry/ui/server/console/ConsoleUpdateRegistrarActionTest.java b/core/src/test/java/google/registry/ui/server/console/ConsoleUpdateRegistrarActionTest.java index c398ef964..56f125772 100644 --- a/core/src/test/java/google/registry/ui/server/console/ConsoleUpdateRegistrarActionTest.java +++ b/core/src/test/java/google/registry/ui/server/console/ConsoleUpdateRegistrarActionTest.java @@ -68,7 +68,8 @@ class ConsoleUpdateRegistrarActionTest { private User user; private static String registrarPostData = - "{\"registrarId\":\"%s\",\"allowedTlds\":[%s],\"registryLockAllowed\":%s}"; + "{\"registrarId\":\"%s\",\"allowedTlds\":[%s],\"registryLockAllowed\":%s," + + " \"lastPocVerificationDate\":%s }"; @RegisterExtension @Order(Integer.MAX_VALUE) @@ -100,7 +101,14 @@ class ConsoleUpdateRegistrarActionTest { @Test void testSuccess_updatesRegistrar() throws IOException { - var action = createAction(String.format(registrarPostData, "TheRegistrar", "app, dev", false)); + var action = + createAction( + String.format( + registrarPostData, + "TheRegistrar", + "app, dev", + false, + "\"2025-01-01T00:00:00.000Z\"")); action.run(); Registrar newRegistrar = Registrar.loadByRegistrarId("TheRegistrar").get(); assertThat(newRegistrar.getAllowedTlds()).containsExactly("app", "dev"); @@ -114,7 +122,14 @@ class ConsoleUpdateRegistrarActionTest { @Test void testFails_missingWhoisContact() throws IOException { RegistryEnvironment.PRODUCTION.setup(systemPropertyExtension); - var action = createAction(String.format(registrarPostData, "TheRegistrar", "app, dev", false)); + var action = + createAction( + String.format( + registrarPostData, + "TheRegistrar", + "app, dev", + false, + "\"2025-01-01T00:00:00.000Z\"")); action.run(); assertThat(((FakeResponse) consoleApiParams.response()).getStatus()).isEqualTo(SC_BAD_REQUEST); assertThat((String) ((FakeResponse) consoleApiParams.response()).getPayload()) @@ -137,7 +152,14 @@ class ConsoleUpdateRegistrarActionTest { .setVisibleInDomainWhoisAsAbuse(true) .build(); persistResource(contact); - var action = createAction(String.format(registrarPostData, "TheRegistrar", "app, dev", false)); + var action = + createAction( + String.format( + registrarPostData, + "TheRegistrar", + "app, dev", + false, + "\"2025-01-01T00:00:00.000Z\"")); action.run(); Registrar newRegistrar = Registrar.loadByRegistrarId("TheRegistrar").get(); assertThat(newRegistrar.getAllowedTlds()).containsExactly("app", "dev"); @@ -147,7 +169,14 @@ class ConsoleUpdateRegistrarActionTest { @Test void testSuccess_sendsEmail() throws AddressException, IOException { - var action = createAction(String.format(registrarPostData, "TheRegistrar", "app, dev", false)); + var action = + createAction( + String.format( + registrarPostData, + "TheRegistrar", + "app, dev", + false, + "\"2025-01-01T00:00:00.000Z\"")); action.run(); verify(consoleApiParams.sendEmailUtils().gmailClient, times(1)) .sendEmail( @@ -159,7 +188,9 @@ class ConsoleUpdateRegistrarActionTest { "The following changes were made in registry unittest environment to the" + " registrar TheRegistrar by user user@registrarId.com:\n" + "\n" - + "allowedTlds: null -> [app, dev]\n") + + "allowedTlds: null -> [app, dev]\n" + + "lastPocVerificationDate: 1970-01-01T00:00:00.000Z ->" + + " 2025-01-01T00:00:00.000Z\n") .setRecipients(ImmutableList.of(new InternetAddress("notification@test.example"))) .build()); } diff --git a/db/src/main/resources/sql/schema/db-schema.sql.generated b/db/src/main/resources/sql/schema/db-schema.sql.generated index 5e9674828..e766b22a5 100644 --- a/db/src/main/resources/sql/schema/db-schema.sql.generated +++ b/db/src/main/resources/sql/schema/db-schema.sql.generated @@ -646,6 +646,7 @@ last_certificate_update_time timestamp(6) with time zone, last_expiring_cert_notification_sent_date timestamp(6) with time zone, last_expiring_failover_cert_notification_sent_date timestamp(6) with time zone, + last_poc_verification_date timestamp(6) with time zone, localized_address_city text, localized_address_country_code text, localized_address_state text,