diff --git a/java/google/registry/model/OteAccountBuilder.java b/java/google/registry/model/OteAccountBuilder.java index 8ce511a87..5c10742df 100644 --- a/java/google/registry/model/OteAccountBuilder.java +++ b/java/google/registry/model/OteAccountBuilder.java @@ -72,8 +72,18 @@ import org.joda.time.Duration; */ public final class OteAccountBuilder { - // Regex: 3-14 lower-case alphanumeric characters or hyphens, the first of which must be a letter. - private static final Pattern REGISTRAR_PATTERN = Pattern.compile("^[a-z][-a-z0-9]{2,13}$"); + /** + * Validation regex for registrar base client IDs (3-14 lowercase alphanumeric characters). + * + *

The base client ID is appended with numbers to create four different test registrar accounts + * (e.g. reg-1, reg-3, reg-4, reg-5). Registrar client IDs are of type clIDType in eppcom.xsd + * which is limited to 16 characters, hence the limit of 14 here to account for the dash and + * numbers. + * + *

The base client ID is also used to generate the OT&E TLDs, hence the restriction to + * lowercase alphanumeric characters. + */ + private static final Pattern REGISTRAR_PATTERN = Pattern.compile("^[a-z0-9]{3,14}$"); // Durations are short so that registrars can test with quick transfer (etc.) turnaround. private static final Duration SHORT_ADD_GRACE_PERIOD = Duration.standardMinutes(60); diff --git a/java/google/registry/tools/SetupOteCommand.java b/java/google/registry/tools/SetupOteCommand.java index b53bfcc7c..31197cd4f 100644 --- a/java/google/registry/tools/SetupOteCommand.java +++ b/java/google/registry/tools/SetupOteCommand.java @@ -40,51 +40,41 @@ final class SetupOteCommand extends ConfirmingCommand implements CommandWithRemo private static final int PASSWORD_LENGTH = 16; @Parameter( - names = {"-r", "--registrar"}, - description = - "must 1) consist of only lowercase letters, numbers, or hyphens, " - + "2) start with a letter, and 3) be between 3 and 14 characters (inclusive). " - + "We require 1 and 2 since the registrar name will be used to create TLDs," - + "and we require 3 since we append \"-[1234]\" to the name to create client" - + "IDs which are required by the EPP XML schema to be between 3-16 chars.", - required = true - ) + names = {"-r", "--registrar"}, + description = "The registrar client ID, consisting of 3-14 lowercase letters and numbers.", + required = true) private String registrar; @Parameter( - names = {"-w", "--ip_whitelist"}, - description = "comma separated list of IP addreses or CIDR ranges", - required = true - ) + names = {"-w", "--ip_whitelist"}, + description = "Comma-separated list of IP addreses or CIDR ranges.", + required = true) private List ipWhitelist = new ArrayList<>(); @Parameter( names = {"--email"}, description = - "the registrar's account to use for console access. " + "The registrar's account to use for console access. " + "Must be on the registry's G Suite domain.", required = true) private String email; @Parameter( - names = {"-c", "--certfile"}, - description = "full path to cert file in PEM format (best if on local storage)", - validateWith = PathParameter.InputFile.class - ) + names = {"-c", "--certfile"}, + description = "Full path to cert file in PEM format (best if on local storage).", + validateWith = PathParameter.InputFile.class) private Path certFile; @Parameter( - names = {"-h", "--certhash"}, - description = - "Hash of client certificate (SHA256 base64 no padding). Do not use this unless " - + "you want to store ONLY the hash and not the full certificate" - ) + names = {"-h", "--certhash"}, + description = + "Hash of client certificate (SHA256 base64 no padding). Do not use this unless " + + "you want to store ONLY the hash and not the full certificate.") private String certHash; @Parameter( - names = {"--overwrite"}, - description = "whether to replace existing entities if we encounter any, instead of failing" - ) + names = {"--overwrite"}, + description = "Whether to replace existing entities if we encounter any, instead of failing.") private boolean overwrite = false; @Inject diff --git a/java/google/registry/ui/soy/otesetup/Console.soy b/java/google/registry/ui/soy/otesetup/Console.soy index 3a1f41789..81e306aa3 100644 --- a/java/google/registry/ui/soy/otesetup/Console.soy +++ b/java/google/registry/ui/soy/otesetup/Console.soy @@ -116,15 +116,7 @@ {param required: true /} {/call} - Must: -

    -
  1. consist of only lowercase letters, numbers, or hyphens,
  2. -
  3. start with a letter, and
  4. -
  5. be between 3 and 14 characters (inclusive).
  6. -
- We require 1 and 2 since the registrar name will be used to create TLDs, and we - require 3 since we append "-[12345]" to the name to create client IDs which are - required by the EPP XML schema to be between 3-16 chars. + Must consist of 3-14 lower-case letters and numbers. diff --git a/javatests/google/registry/model/OteAccountBuilderTest.java b/javatests/google/registry/model/OteAccountBuilderTest.java index f022df3cd..94347a62d 100644 --- a/javatests/google/registry/model/OteAccountBuilderTest.java +++ b/javatests/google/registry/model/OteAccountBuilderTest.java @@ -192,9 +192,9 @@ public final class OteAccountBuilderTest { public void testCreateOteEntities_invalidClientId_fails() { assertThat( assertThrows( - IllegalArgumentException.class, () -> OteAccountBuilder.forClientId("3blobio"))) + IllegalArgumentException.class, () -> OteAccountBuilder.forClientId("3blo-bio"))) .hasMessageThat() - .isEqualTo("Invalid registrar name: 3blobio"); + .isEqualTo("Invalid registrar name: 3blo-bio"); } @Test @@ -319,11 +319,6 @@ public final class OteAccountBuilderTest { assertThat(OteAccountBuilder.getBaseClientId("myclientid-4")).isEqualTo("myclientid"); } - @Test - public void testGetBaseClientId_multipleDashesValid() { - assertThat(OteAccountBuilder.getBaseClientId("two-dashes-3")).isEqualTo("two-dashes"); - } - @Test public void testGetBaseClientId_invalidInput_malformed() { assertThat( diff --git a/javatests/google/registry/tools/SetupOteCommandTest.java b/javatests/google/registry/tools/SetupOteCommandTest.java index ff4a3f2dc..f544930ef 100644 --- a/javatests/google/registry/tools/SetupOteCommandTest.java +++ b/javatests/google/registry/tools/SetupOteCommandTest.java @@ -324,10 +324,10 @@ public class SetupOteCommandTest extends CommandTestCase { () -> runCommandForced( "--ip_whitelist=1.1.1.1", - "--registrar=3blobio", + "--registrar=3blo-bio", "--email=contact@email.com", "--certfile=" + getCertFilename())); - assertThat(thrown).hasMessageThat().contains("Invalid registrar name: 3blobio"); + assertThat(thrown).hasMessageThat().contains("Invalid registrar name: 3blo-bio"); } @Test diff --git a/javatests/google/registry/ui/server/registrar/OteStatusActionTest.java b/javatests/google/registry/ui/server/registrar/OteStatusActionTest.java index 1e876bf82..29c6ce6fb 100644 --- a/javatests/google/registry/ui/server/registrar/OteStatusActionTest.java +++ b/javatests/google/registry/ui/server/registrar/OteStatusActionTest.java @@ -105,9 +105,9 @@ public final class OteStatusActionTest { @Test public void testFailure_noRegistrar() { - assertThat(action.handleJsonRequest(ImmutableMap.of("clientId", "nonexistent-id-3"))) + assertThat(action.handleJsonRequest(ImmutableMap.of("clientId", "nonexistent-3"))) .containsExactlyEntriesIn( - errorResultWithMessage("TestUserId doesn't have access to registrar nonexistent-id-3")); + errorResultWithMessage("TestUserId doesn't have access to registrar nonexistent-3")); } @Test @@ -121,10 +121,10 @@ public final class OteStatusActionTest { @Test public void testFailure_malformedRegistrarName() { - assertThat(action.handleJsonRequest(ImmutableMap.of("clientId", "bad-client-id"))) + assertThat(action.handleJsonRequest(ImmutableMap.of("clientId", "badclient-id"))) .containsExactlyEntriesIn( errorResultWithMessage( - "ID bad-client-id is not one of the OT&E client IDs for base bad-client")); + "ID badclient-id is not one of the OT&E client IDs for base badclient")); } @Test