From 355e8ba423273a37fc5e81252c17596fbc3e6a3f Mon Sep 17 00:00:00 2001 From: gbrodman Date: Fri, 24 Jul 2026 13:01:09 -0400 Subject: [PATCH] Don't claim that only one abuse contact is allowed (#3173) nowhere in the RFCs does it say that only one contact is allowed, and indeed there are many situations where it's actually an array of contacts. We have a bunch of registrars that already have multiple abuse contacts. I'm not sure why the comment originally claimed this, but it's from years and years ago. b/534931561 --- .../registry/model/registrar/Registrar.java | 2 +- .../console/settings/ContactAction.java | 40 ++++++++----------- 2 files changed, 17 insertions(+), 25 deletions(-) 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 e1f5d0e96..3ecaacdf6 100644 --- a/core/src/main/java/google/registry/model/registrar/Registrar.java +++ b/core/src/main/java/google/registry/model/registrar/Registrar.java @@ -631,7 +631,7 @@ public class Registrar extends UpdateAutoTimestampEntity implements Buildable, J } /** - * Returns the {@link RegistrarPoc} that is the RDAP abuse contact for this registrar, or empty if + * Returns a {@link RegistrarPoc} that is the RDAP abuse contact for this registrar, or empty if * one does not exist. */ public Optional getRdapAbuseContact() { diff --git a/core/src/main/java/google/registry/ui/server/console/settings/ContactAction.java b/core/src/main/java/google/registry/ui/server/console/settings/ContactAction.java index 53e1b5d0d..cbd221644 100644 --- a/core/src/main/java/google/registry/ui/server/console/settings/ContactAction.java +++ b/core/src/main/java/google/registry/ui/server/console/settings/ContactAction.java @@ -228,17 +228,23 @@ public class ContactAction extends ConsoleApiAction { enforcePrimaryContactRestrictions(oldContactsByType, newContactsByType); ensurePhoneNumberNotRemovedForContactTypes(oldContactsByType, newContactsByType, Type.TECH); - Optional domainRdapAbuseContact = - getDomainRdapVisibleAbuseContact(updatedContacts); - // If the new set has a domain RDAP abuse contact, it must have a phone number. - if (domainRdapAbuseContact.isPresent() - && domainRdapAbuseContact.get().getPhoneNumber() == null) { - throw new ContactRequirementException( - "The abuse contact visible in domain RDAP query must have a phone number"); - } + + ImmutableSet abusePocs = + updatedContacts.stream() + .filter(RegistrarPoc::getVisibleInDomainRdapAsAbuse) + .collect(toImmutableSet()); + + // All abuse POCs must have a phone number attached + abusePocs.forEach( + poc -> { + if (poc.getPhoneNumber() == null) { + throw new ContactRequirementException( + "The abuse contact visible in domain RDAP query must have a phone number"); + } + }); // If there was a domain RDAP abuse contact in the old set, the new set must have one. - if (getDomainRdapVisibleAbuseContact(existingContacts).isPresent() - && domainRdapAbuseContact.isEmpty()) { + if (existingContacts.stream().anyMatch(RegistrarPoc::getVisibleInDomainRdapAsAbuse) + && abusePocs.isEmpty()) { throw new ContactRequirementException( "An abuse contact visible in domain RDAP query must be designated"); } @@ -263,20 +269,6 @@ public class ContactAction extends ConsoleApiAction { } } - /** - * Retrieves the registrar contact whose phone number and email address is visible in domain RDAP - * query as abuse contact (if any). - * - *

Frontend processing ensures that only one contact can be set as abuse contact in domain RDAP - * record. - * - *

Therefore, it is possible to return inside the loop once one such contact is found. - */ - private static Optional getDomainRdapVisibleAbuseContact( - Set contacts) { - return contacts.stream().filter(RegistrarPoc::getVisibleInDomainRdapAsAbuse).findFirst(); - } - /** * Ensure that for each given registrar type, a phone number is present after update, if there was * one before.