From 87e5d19fe5e6f96c5f256e6410ffe3cbc19526e1 Mon Sep 17 00:00:00 2001 From: gbrodman Date: Mon, 15 Aug 2022 12:42:16 -0400 Subject: [PATCH] Allow anchor tenant creation via allocation token behavior (#1735) * Allow anchor tenant creation via allocation token behavior This also enforces that non-superusers cannot create registrations on trademarked names prior to the sunrise period, even if they have an allocation token with ANCHOR_TENANT behavior. --- .../flows/domain/DomainCreateFlow.java | 32 +- .../flows/domain/DomainFlowUtils.java | 9 +- .../flows/domain/DomainCreateFlowTest.java | 286 +++++++++++++++++- ...on_encoded_signed_mark_allocationtoken.xml | 36 +++ docs/flows.md | 1 + 5 files changed, 355 insertions(+), 9 deletions(-) create mode 100644 core/src/test/resources/google/registry/flows/domain/domain_create_registration_encoded_signed_mark_allocationtoken.xml diff --git a/core/src/main/java/google/registry/flows/domain/DomainCreateFlow.java b/core/src/main/java/google/registry/flows/domain/DomainCreateFlow.java index 09b7260d8..f1355985b 100644 --- a/core/src/main/java/google/registry/flows/domain/DomainCreateFlow.java +++ b/core/src/main/java/google/registry/flows/domain/DomainCreateFlow.java @@ -153,6 +153,7 @@ import org.joda.time.Duration; * @error {@link DomainCreateFlow.AnchorTenantCreatePeriodException} * @error {@link DomainCreateFlow.MustHaveSignedMarksInCurrentPhaseException} * @error {@link DomainCreateFlow.NoGeneralRegistrationsInCurrentPhaseException} + * @error {@link DomainCreateFlow.NoTrademarkedRegistrationsBeforeSunriseException} * @error {@link DomainCreateFlow.SignedMarksOnlyDuringSunriseException} * @error {@link DomainFlowTmchUtils.NoMarksFoundMatchingDomainException} * @error {@link DomainFlowTmchUtils.FoundMarkNotYetValidException} @@ -481,7 +482,8 @@ public final class DomainCreateFlow implements TransactionalFlow { boolean isValidReservedCreate, boolean hasSignedMarks) throws NoGeneralRegistrationsInCurrentPhaseException, - MustHaveSignedMarksInCurrentPhaseException { + MustHaveSignedMarksInCurrentPhaseException, + NoTrademarkedRegistrationsBeforeSunriseException { // We allow general registration during GA. TldState currentState = registry.getTldState(now); if (currentState.equals(GENERAL_AVAILABILITY)) { @@ -496,16 +498,23 @@ public final class DomainCreateFlow implements TransactionalFlow { // Bypass most TLD state checks if that behavior is specified by the token if (behavior.equals(RegistrationBehavior.BYPASS_TLD_STATE) || behavior.equals(RegistrationBehavior.ANCHOR_TENANT)) { - // If bypassing TLD state checks, a post-sunrise state is always fine - if (!currentState.equals(START_DATE_SUNRISE) - && registry.getTldStateTransitions().headMap(now).containsValue(START_DATE_SUNRISE)) { - return; - } // Non-trademarked names with the state check bypassed are always available if (!claimsList.getClaimKey(domainLabel).isPresent()) { return; } + if (!currentState.equals(START_DATE_SUNRISE)) { + // Trademarked domains cannot be registered until after the sunrise period has ended, unless + // a valid signed mark is provided. Signed marks can only be provided during sunrise. + // Thus, when bypassing TLD state checks, a post-sunrise state is always fine. + if (registry.getTldStateTransitions().headMap(now).containsValue(START_DATE_SUNRISE)) { + return; + } else { + // If sunrise hasn't happened yet, trademarked domains are unavailable + throw new NoTrademarkedRegistrationsBeforeSunriseException(domainLabel); + } + } } + // Otherwise, signed marks are necessary and sufficient in the sunrise period if (currentState.equals(START_DATE_SUNRISE)) { if (!hasSignedMarks) { @@ -724,6 +733,17 @@ public final class DomainCreateFlow implements TransactionalFlow { } } + /** Trademarked domains cannot be registered before the sunrise period. */ + static class NoTrademarkedRegistrationsBeforeSunriseException + extends ParameterValuePolicyErrorException { + public NoTrademarkedRegistrationsBeforeSunriseException(String domainLabel) { + super( + String.format( + "The trademarked label %s cannot be registered before the sunrise period.", + domainLabel)); + } + } + /** Anchor tenant domain create is for the wrong number of years. */ static class AnchorTenantCreatePeriodException extends ParameterValuePolicyErrorException { public AnchorTenantCreatePeriodException(int invalidYears) { diff --git a/core/src/main/java/google/registry/flows/domain/DomainFlowUtils.java b/core/src/main/java/google/registry/flows/domain/DomainFlowUtils.java index e9f95582e..c920463cf 100644 --- a/core/src/main/java/google/registry/flows/domain/DomainFlowUtils.java +++ b/core/src/main/java/google/registry/flows/domain/DomainFlowUtils.java @@ -112,6 +112,7 @@ import google.registry.model.domain.secdns.SecDnsUpdateExtension; import google.registry.model.domain.secdns.SecDnsUpdateExtension.Add; import google.registry.model.domain.secdns.SecDnsUpdateExtension.Remove; import google.registry.model.domain.token.AllocationToken; +import google.registry.model.domain.token.AllocationToken.RegistrationBehavior; import google.registry.model.eppcommon.StatusValue; import google.registry.model.eppoutput.EppResponse.ResponseExtension; import google.registry.model.host.Host; @@ -270,7 +271,13 @@ public class DomainFlowUtils { && token.get().getDomainName().get().equals(domainName.toString())) { return true; } - // Otherwise check whether the metadata extension is being used by a superuser to specify that + // Otherwise, check to see if we're using the specialized anchor tenant registration behavior on + // the allocation token + if (token.isPresent() + && token.get().getRegistrationBehavior().equals(RegistrationBehavior.ANCHOR_TENANT)) { + return true; + } + // Otherwise, check whether the metadata extension is being used by a superuser to specify that // it's an anchor tenant creation. return metadataExtension.isPresent() && metadataExtension.get().getIsAnchorTenant(); } diff --git a/core/src/test/java/google/registry/flows/domain/DomainCreateFlowTest.java b/core/src/test/java/google/registry/flows/domain/DomainCreateFlowTest.java index 6837786ef..935e3100b 100644 --- a/core/src/test/java/google/registry/flows/domain/DomainCreateFlowTest.java +++ b/core/src/test/java/google/registry/flows/domain/DomainCreateFlowTest.java @@ -82,6 +82,7 @@ import google.registry.flows.ResourceFlowTestCase; import google.registry.flows.domain.DomainCreateFlow.AnchorTenantCreatePeriodException; import google.registry.flows.domain.DomainCreateFlow.MustHaveSignedMarksInCurrentPhaseException; import google.registry.flows.domain.DomainCreateFlow.NoGeneralRegistrationsInCurrentPhaseException; +import google.registry.flows.domain.DomainCreateFlow.NoTrademarkedRegistrationsBeforeSunriseException; import google.registry.flows.domain.DomainCreateFlow.RenewalPriceInfo; import google.registry.flows.domain.DomainCreateFlow.SignedMarksOnlyDuringSunriseException; import google.registry.flows.domain.DomainFlowTmchUtils.FoundMarkExpiredException; @@ -2734,7 +2735,7 @@ class DomainCreateFlowTest extends ResourceFlowTestCase + + + + + %DOMAIN% + 2 + + ns1.example.net + ns2.example.net + + jd1234 + sh8013 + sh8013 + + 2fooBAR + + + + + + abcDEF23456 + + + sunrise + +PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHNtZDpzaWduZWRNYXJrIHhtbG5zOnNtZD0idXJuOmlldGY6cGFyYW1zOnhtbDpuczpzaWduZWRNYXJrLTEuMCIgaWQ9Il8zOGFjNTg2ZC05OTg5LTQ4MTctYjcwOC1kOGU4MzQ0NzZkOTUiPgogIDxzbWQ6aWQ+MDAwMDAwMTc2MTM3NjA0Mjc1OTEzNi02NTUzNTwvc21kOmlkPgogIDxzbWQ6aXNzdWVySW5mbyBpc3N1ZXJJRD0iNjU1MzUiPgogICAgPHNtZDpvcmc+SUNBTk4gVE1DSCBURVNUSU5HIFRNVjwvc21kOm9yZz4KICAgIDxzbWQ6ZW1haWw+bm90YXZhaWxhYmxlQGV4YW1wbGUuY29tPC9zbWQ6ZW1haWw+CiAgICA8c21kOnVybD5odHRwOi8vd3d3LmV4YW1wbGUuY29tPC9zbWQ6dXJsPgogICAgPHNtZDp2b2ljZT4rMzIuMDAwMDAwPC9zbWQ6dm9pY2U+CiAgPC9zbWQ6aXNzdWVySW5mbz4KICA8c21kOm5vdEJlZm9yZT4yMDEzLTA4LTA5VDEwOjA1OjU5LjEzNlo8L3NtZDpub3RCZWZvcmU+CiAgPHNtZDpub3RBZnRlcj4yMDE3LTA3LTIzVDIyOjAwOjAwLjAwMFo8L3NtZDpub3RBZnRlcj4KICA8bWFyazptYXJrIHhtbG5zOm1hcms9InVybjppZXRmOnBhcmFtczp4bWw6bnM6bWFyay0xLjAiPgogICAgPG1hcms6Y291cnQ+CiAgICAgIDxtYXJrOmlkPjAwMDUyMDEzNzM0NjkxNjkxMzczNDY5MTY5LTY1NTM1PC9tYXJrOmlkPgogICAgICA8bWFyazptYXJrTmFtZT5UZXN0ICZhbXA7IFZhbGlkYXRlPC9tYXJrOm1hcmtOYW1lPgogICAgICA8bWFyazpob2xkZXIgZW50aXRsZW1lbnQ9Im93bmVyIj4KICAgICAgICA8bWFyazpvcmc+QWcgY29ycG9yYXRpb248L21hcms6b3JnPgogICAgICAgIDxtYXJrOmFkZHI+CiAgICAgICAgICA8bWFyazpzdHJlZXQ+MTMwNSBCcmlnaHQgQXZlbnVlPC9tYXJrOnN0cmVldD4KICAgICAgICAgIDxtYXJrOmNpdHk+QXJjYWRpYTwvbWFyazpjaXR5PgogICAgICAgICAgPG1hcms6c3A+Q0E8L21hcms6c3A+CiAgICAgICAgICA8bWFyazpwYz45MDAyODwvbWFyazpwYz4KICAgICAgICAgIDxtYXJrOmNjPlVTPC9tYXJrOmNjPgogICAgICAgIDwvbWFyazphZGRyPgogICAgICA8L21hcms6aG9sZGVyPgogICAgICA8bWFyazpjb250YWN0IHR5cGU9ImFnZW50Ij4KICAgICAgICA8bWFyazpuYW1lPlRvbnkgSG9sbGFuZDwvbWFyazpuYW1lPgogICAgICAgIDxtYXJrOm9yZz5BZyBjb3Jwb3JhdGlvbjwvbWFyazpvcmc+CiAgICAgICAgPG1hcms6YWRkcj4KICAgICAgICAgIDxtYXJrOnN0cmVldD4xMzA1IEJyaWdodCBBdmVudWU8L21hcms6c3RyZWV0PgogICAgICAgICAgPG1hcms6Y2l0eT5BcmNhZGlhPC9tYXJrOmNpdHk+CiAgICAgICAgICA8bWFyazpzcD5DQTwvbWFyazpzcD4KICAgICAgICAgIDxtYXJrOnBjPjkwMDI4PC9tYXJrOnBjPgogICAgICAgICAgPG1hcms6Y2M+VVM8L21hcms6Y2M+CiAgICAgICAgPC9tYXJrOmFkZHI+CiAgICAgICAgPG1hcms6dm9pY2U+KzEuMjAyNTU2MjMwMjwvbWFyazp2b2ljZT4KICAgICAgICA8bWFyazpmYXg+KzEuMjAyNTU2MjMwMTwvbWFyazpmYXg+CiAgICAgICAgPG1hcms6ZW1haWw+aW5mb0BhZ2NvcnBvcmF0aW9uLmNvbTwvbWFyazplbWFpbD4KICAgICAgPC9tYXJrOmNvbnRhY3Q+CiAgICAgIDxtYXJrOmxhYmVsPnRlc3RhbmR2YWxpZGF0ZTwvbWFyazpsYWJlbD4KICAgICAgPG1hcms6bGFiZWw+dGVzdC0tLXZhbGlkYXRlPC9tYXJrOmxhYmVsPgogICAgICA8bWFyazpsYWJlbD50ZXN0YW5kLXZhbGlkYXRlPC9tYXJrOmxhYmVsPgogICAgICA8bWFyazpsYWJlbD50ZXN0LXZhbGlkYXRlPC9tYXJrOmxhYmVsPgogICAgICA8bWFyazpsYWJlbD50ZXN0LWFuZHZhbGlkYXRlPC9tYXJrOmxhYmVsPgogICAgICA8bWFyazpsYWJlbD50ZXN0LS12YWxpZGF0ZTwvbWFyazpsYWJlbD4KICAgICAgPG1hcms6bGFiZWw+dGVzdHZhbGlkYXRlPC9tYXJrOmxhYmVsPgogICAgICA8bWFyazpsYWJlbD50ZXN0LWFuZC12YWxpZGF0ZTwvbWFyazpsYWJlbD4KICAgICAgPG1hcms6Z29vZHNBbmRTZXJ2aWNlcz5NdXNpY2FsIGluc3RydW1lbnRzPC9tYXJrOmdvb2RzQW5kU2VydmljZXM+CiAgICAgIDxtYXJrOnJlZk51bT4xMjM0PC9tYXJrOnJlZk51bT4KICAgICAgPG1hcms6cHJvRGF0ZT4yMDEyLTEyLTMxVDIzOjAwOjAwLjAwMFo8L21hcms6cHJvRGF0ZT4KICAgICAgPG1hcms6Y2M+VVM8L21hcms6Y2M+CiAgICAgIDxtYXJrOmNvdXJ0TmFtZT5Ib3ZlPC9tYXJrOmNvdXJ0TmFtZT4KICAgIDwvbWFyazpjb3VydD4KICA8L21hcms6bWFyaz4KPGRzOlNpZ25hdHVyZSB4bWxuczpkcz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC8wOS94bWxkc2lnIyIgSWQ9Il9mZDBmMTM0Ni03MTM4LTRiMGMtODRkNy0yZTdlYmY2YTExNmMiPjxkczpTaWduZWRJbmZvPjxkczpDYW5vbmljYWxpemF0aW9uTWV0aG9kIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS8xMC94bWwtZXhjLWMxNG4jIi8+PGRzOlNpZ25hdHVyZU1ldGhvZCBBbGdvcml0aG09Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvMDQveG1sZHNpZy1tb3JlI3JzYS1zaGEyNTYiLz48ZHM6UmVmZXJlbmNlIFVSST0iI18zOGFjNTg2ZC05OTg5LTQ4MTctYjcwOC1kOGU4MzQ0NzZkOTUiPjxkczpUcmFuc2Zvcm1zPjxkczpUcmFuc2Zvcm0gQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwLzA5L3htbGRzaWcjZW52ZWxvcGVkLXNpZ25hdHVyZSIvPjxkczpUcmFuc2Zvcm0gQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxLzEwL3htbC1leGMtYzE0biMiLz48L2RzOlRyYW5zZm9ybXM+PGRzOkRpZ2VzdE1ldGhvZCBBbGdvcml0aG09Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvMDQveG1sZW5jI3NoYTI1NiIvPjxkczpEaWdlc3RWYWx1ZT55WDRLTWgrUDJ2OVUxNnh0eTl2ZGU5S0JTZmZFTjRHbTVVa2tLblI5cDdZPTwvZHM6RGlnZXN0VmFsdWU+PC9kczpSZWZlcmVuY2U+PGRzOlJlZmVyZW5jZSBVUkk9IiNfYjg5MjI1NWItMWJjOC00MTdiLWE0NGYtZWE5OGJjMzQ5OWE0Ij48ZHM6VHJhbnNmb3Jtcz48ZHM6VHJhbnNmb3JtIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS8xMC94bWwtZXhjLWMxNG4jIi8+PC9kczpUcmFuc2Zvcm1zPjxkczpEaWdlc3RNZXRob2QgQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxLzA0L3htbGVuYyNzaGEyNTYiLz48ZHM6RGlnZXN0VmFsdWU+dDNuNkFBTHdiaUhNbGRyZkpEQjNYQ3FkSlFzOEhjeU5pK1lXT3ZoV1krdz08L2RzOkRpZ2VzdFZhbHVlPjwvZHM6UmVmZXJlbmNlPjwvZHM6U2lnbmVkSW5mbz48ZHM6U2lnbmF0dXJlVmFsdWUgSWQ9Il82OWQzMDRlNC04NzlmLTRmNzEtYmMxMi02ZjJhZDlmOTM5OGYiPmJSVFIzTzUxM0dnTkExS2pxb0g0VXE3cUlhN2NJaTljaXZmZmFyVmE0VVQyVEUzdzEzc2xsUDFXbkdYYjcyYUw0dXhkbDFUaTZZbFoKVnVjSC92ZU5zUnlWZFZwSFF0eEJNTDFLU0tZbXc3ZjdPNnVsYWtrYnFrTkdYVmFZdEVsa1dBZnZFSDBsNURkNkFZT0k2UGN5SzBCWgo2VEl3cWZhQ1luVk5DdTFpdDIzMm9EREtiWU9RNk02YnhmU3BvVFYvaTVVdEVyak0vZWFFanp4MXFxZzlFZmxOcm1obmRtZW42Q2JYCjVrNmZ4Y1o0V2NtWkM4V0Ruc0t0VWVjaGtmbko4L0Jwc2ppM1Foekg4YzFiL0RqTmR5UFFyOGlndXBqR2dlU0JmMHhRRUtoK3pRT2oKYTNvMEhRWjZ1UlUvejdWN2RoNU9qUEhmV2lLc0pqRjVwc2ppRlE9PTwvZHM6U2lnbmF0dXJlVmFsdWU+PGRzOktleUluZm8gSWQ9Il9iODkyMjU1Yi0xYmM4LTQxN2ItYTQ0Zi1lYTk4YmMzNDk5YTQiPjxkczpYNTA5RGF0YT48ZHM6WDUwOUNlcnRpZmljYXRlPk1JSUZMekNDQkJlZ0F3SUJBZ0lnTHJBYmV2b2FlNTJ5M2Y2QzJ0QjBTbjNwN1hKbTBUMDJGb2d4S0NmTmhYb3dEUVlKS29aSWh2Y04KQVFFTEJRQXdmREVMTUFrR0ExVUVCaE1DVlZNeFBEQTZCZ05WQkFvVE0wbHVkR1Z5Ym1WMElFTnZjbkJ2Y21GMGFXOXVJR1p2Y2lCQgpjM05wWjI1bFpDQk9ZVzFsY3lCaGJtUWdUblZ0WW1WeWN6RXZNQzBHQTFVRUF4TW1TVU5CVGs0Z1ZISmhaR1Z0WVhKcklFTnNaV0Z5CmFXNW5hRzkxYzJVZ1VHbHNiM1FnUTBFd0hoY05NVE13TmpJMk1EQXdNREF3V2hjTk1UZ3dOakkxTWpNMU9UVTVXakNCanpFTE1Ba0cKQTFVRUJoTUNRa1V4SURBZUJnTlZCQWdURjBKeWRYTnpaV3h6TFVOaGNHbDBZV3dnVW1WbmFXOXVNUkV3RHdZRFZRUUhFd2hDY25WegpjMlZzY3pFUk1BOEdBMVVFQ2hNSVJHVnNiMmwwZEdVeE9EQTJCZ05WQkFNVEwwbERRVTVPSUZSTlEwZ2dRWFYwYUc5eWFYcGxaQ0JVCmNtRmtaVzFoY21zZ1VHbHNiM1FnVm1Gc2FXUmhkRzl5TUlJQklqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FROEFNSUlCQ2dLQ0FRRUEKeGxwM0twWUhYM1d5QXNGaFNrM0x3V2ZuR2x4blVERnFGWkEzVW91TVlqL1hpZ2JNa05lRVhJamxrUk9LVDRPUEdmUngvTEF5UmxRUQpqQ012NHFoYmtjWDFwN2FyNjNmbHE0U1pOVmNsMTVsN2gwdVQ1OEZ6U2ZubHowdTVya0hmSkltRDQzK21hUC84Z3YzNkZSMjdqVzhSCjl3WTRoaytXczRJQjBpRlNkOFNYdjFLcjh3L0ptTVFTRGtpdUcrUmZJaXVid1EvZnk3RWtqNVFXaFBadyttTXhOS25IVUx5M3hZejIKTHdWZmZ0andVdWVhY3ZxTlJDa01YbENsT0FEcWZUOG9TWm9lRFhlaEh2bFBzTENlbUdCb1RLdXJza0lTNjlGMHlQRUg1Z3plMEgrZgo4RlJPc0lvS1NzVlEzNEI0Uy9qb0U2N25wc0pQVGRLc05QSlR5UUlEQVFBQm80SUJoekNDQVlNd0RBWURWUjBUQVFIL0JBSXdBREFkCkJnTlZIUTRFRmdRVW9GcFk3NnA1eW9ORFJHdFFwelZ1UjgxVVdRMHdnY1lHQTFVZEl3U0J2akNCdTRBVXc2MCtwdFlSQUVXQVhEcFgKU29wdDNERU5ubkdoZ1lDa2ZqQjhNUXN3Q1FZRFZRUUdFd0pWVXpFOE1Eb0dBMVVFQ2hNelNXNTBaWEp1WlhRZ1EyOXljRzl5WVhScApiMjRnWm05eUlFRnpjMmxuYm1Wa0lFNWhiV1Z6SUdGdVpDQk9kVzFpWlhKek1TOHdMUVlEVlFRREV5WkpRMEZPVGlCVWNtRmtaVzFoCmNtc2dRMnhsWVhKcGJtZG9iM1Z6WlNCUWFXeHZkQ0JEUVlJZ0xyQWJldm9hZTUyeTNmNkMydEIwU24zcDdYSm0wVDAyRm9neEtDZk4KaFhrd0RnWURWUjBQQVFIL0JBUURBZ2VBTURRR0ExVWRId1F0TUNzd0thQW5vQ1dHSTJoMGRIQTZMeTlqY213dWFXTmhibTR1YjNKbgpMM1J0WTJoZmNHbHNiM1F1WTNKc01FVUdBMVVkSUFRK01Ed3dPZ1lES2dNRU1ETXdNUVlJS3dZQkJRVUhBZ0VXSldoMGRIQTZMeTkzCmQzY3VhV05oYm00dWIzSm5MM0JwYkc5MFgzSmxjRzl6YVhSdmNua3dEUVlKS29aSWh2Y05BUUVMQlFBRGdnRUJBSWVEWVlKcjYwVzMKeTlRcyszelJWSTlrZWtLb201dmtIT2FsQjN3SGFaSWFBRllwSTk4dFkwYVZOOWFHT04wdjZXUUYrbnZ6MUtSWlFiQXowMUJYdGFSSgo0bVBrYXJoaHVMbjlOa0J4cDhIUjVxY2MrS0g3Z3Y2ci9jMGlHM2JDTkorUVNyN1FmKzVNbE1vNnpMNVVkZFUvVDJqaWJNWENqL2YyCjFRdzN4OVFnb3lYTEZKOW96YUxnUTlSTWtMbE9temtDQWlYTjVBYjQzYUo5ZjdOMmdFMk5uUmpOS21tQzlBQlEwVFJ3RUtWTGhWbDEKVUdxQ0hKM0FsQlhXSVhONXNqUFFjRC8rbkhlRVhNeFl2bEF5cXhYb0QzTVd0UVZqN2oyb3FsYWtPQk1nRzgrcTJxWWxtQnRzNEZOaQp3NzQ4SWw1ODZIS0JScXhIdFpkUktXMlZxYVE9PC9kczpYNTA5Q2VydGlmaWNhdGU+PC9kczpYNTA5RGF0YT48L2RzOktleUluZm8+PC9kczpTaWduYXR1cmU+PC9zbWQ6c2lnbmVkTWFyaz4= + + + + ABC-12345 + + diff --git a/docs/flows.md b/docs/flows.md index e3aa479af..5badced0c 100644 --- a/docs/flows.md +++ b/docs/flows.md @@ -374,6 +374,7 @@ An EPP flow that creates a new domain resource. * The allocation token was already redeemed. * 2306 * Anchor tenant domain create is for the wrong number of years. + * Trademarked domains cannot be registered before the sunrise period. * The provided mark is not yet valid. * The provided mark has expired. * Domain names can only contain a-z, 0-9, '.' and '-'.