Skip to content

Commit

Permalink
Add default tokens to TLD using nomulus tool (#1888)
Browse files Browse the repository at this point in the history
* Add defualt tokens to TLD using nomulus tool

* add test
  • Loading branch information
sarahcaseybot authored Jan 4, 2023
1 parent db95259 commit 1864132
Show file tree
Hide file tree
Showing 6 changed files with 214 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@
package google.registry.tools;

import static com.google.common.base.Preconditions.checkArgument;
import static google.registry.tools.UpdateOrDeleteAllocationTokensCommand.getTokenKeys;
import static google.registry.util.CollectionUtils.findDuplicates;
import static google.registry.util.CollectionUtils.isNullOrEmpty;
import static google.registry.util.DomainNameUtils.canonicalizeHostname;

import com.beust.jcommander.Parameter;
Expand Down Expand Up @@ -232,6 +234,16 @@ abstract class CreateOrUpdateTldCommand extends MutatingCommand {
)
Integer numDnsPublishShards;

@Nullable
@Parameter(
names = "--default_tokens",
description =
"A comma-separated list of default allocation tokens to be applied to the TLD. The"
+ " ordering of this list will determine which token is used in the case where"
+ " multiple tokens are valid for a registration. Use an empty string to clear all"
+ " present default tokens.")
List<String> defaultTokens;

/** Returns the existing registry (for update) or null (for creates). */
@Nullable
abstract Registry getOldRegistry(String tld);
Expand Down Expand Up @@ -373,6 +385,13 @@ protected final void init() {

builder.setAllowedFullyQualifiedHostNames(getAllowedNameservers(oldRegistry));

if (!isNullOrEmpty(defaultTokens)) {
if (defaultTokens.equals(ImmutableList.of(""))) {
builder.setDefaultPromoTokens(ImmutableList.of());
} else {
builder.setDefaultPromoTokens(getTokenKeys(defaultTokens, null));
}
}
// Update the Registry object.
setCommandSpecificProperties(builder);
stageEntityChange(oldRegistry, builder.build());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import com.beust.jcommander.Parameter;
import com.beust.jcommander.Parameters;
import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import google.registry.model.domain.token.AllocationToken;
import google.registry.persistence.VKey;
Expand All @@ -48,11 +49,11 @@ final class DeleteAllocationTokensCommand extends UpdateOrDeleteAllocationTokens
private static final int BATCH_SIZE = 20;
private static final Joiner JOINER = Joiner.on(", ");

private ImmutableSet<VKey<AllocationToken>> tokensToDelete;
private ImmutableList<VKey<AllocationToken>> tokensToDelete;

@Override
public void init() {
tokensToDelete = getTokenKeys();
tokensToDelete = getTokenKeys(tokens, prefix);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ public void init() {
tokensToSave =
tm().transact(
() ->
tm().loadByKeys(getTokenKeys()).values().stream()
tm().loadByKeys(getTokenKeys(tokens, prefix)).values().stream()
.collect(toImmutableMap(Function.identity(), this::updateToken))
.entrySet()
.stream()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,15 @@

import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkState;
import static com.google.common.collect.ImmutableSet.toImmutableSet;
import static com.google.common.collect.ImmutableList.toImmutableList;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;

import com.beust.jcommander.Parameter;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableList;
import google.registry.model.domain.token.AllocationToken;
import google.registry.persistence.VKey;
import java.util.List;
import javax.annotation.Nullable;

/** Shared base class for commands to update or delete allocation tokens. */
abstract class UpdateOrDeleteAllocationTokensCommand extends ConfirmingCommand {
Expand All @@ -47,19 +48,20 @@ abstract class UpdateOrDeleteAllocationTokensCommand extends ConfirmingCommand {
description = "Do not actually update or delete the tokens; defaults to false")
protected boolean dryRun;

protected ImmutableSet<VKey<AllocationToken>> getTokenKeys() {
public static ImmutableList<VKey<AllocationToken>> getTokenKeys(
@Nullable List<String> tokens, @Nullable String prefix) {
checkArgument(
tokens == null ^ prefix == null,
"Must provide one of --tokens or --prefix, not both / neither");
if (tokens != null) {
ImmutableSet<VKey<AllocationToken>> keys =
ImmutableList<VKey<AllocationToken>> keys =
tokens.stream()
.map(token -> VKey.create(AllocationToken.class, token))
.collect(toImmutableSet());
ImmutableSet<VKey<AllocationToken>> nonexistentKeys =
.collect(toImmutableList());
ImmutableList<VKey<AllocationToken>> nonexistentKeys =
tm().transact(
() -> keys.stream().filter(key -> !tm().exists(key)).collect(toImmutableSet()));
checkState(nonexistentKeys.isEmpty(), "Tokens with keys %s did not exist.", nonexistentKeys);
() -> keys.stream().filter(key -> !tm().exists(key)).collect(toImmutableList()));
checkState(nonexistentKeys.isEmpty(), "Tokens with keys %s did not exist", nonexistentKeys);
return keys;
} else {
checkArgument(!prefix.isEmpty(), "Provided prefix should not be blank");
Expand All @@ -68,7 +70,7 @@ protected ImmutableSet<VKey<AllocationToken>> getTokenKeys() {
tm().loadAllOf(AllocationToken.class).stream()
.filter(token -> token.getToken().startsWith(prefix))
.map(AllocationToken::createVKey)
.collect(toImmutableSet()));
.collect(toImmutableList()));
}
}
}
65 changes: 65 additions & 0 deletions core/src/test/java/google/registry/tools/CreateTldCommandTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,13 @@

import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth8.assertThat;
import static google.registry.model.domain.token.AllocationToken.TokenType.DEFAULT_PROMO;
import static google.registry.model.tld.Registry.TldState.GENERAL_AVAILABILITY;
import static google.registry.model.tld.Registry.TldState.PREDELEGATION;
import static google.registry.testing.DatabaseHelper.createTld;
import static google.registry.testing.DatabaseHelper.persistPremiumList;
import static google.registry.testing.DatabaseHelper.persistReservedList;
import static google.registry.testing.DatabaseHelper.persistResource;
import static google.registry.util.DateTimeUtils.START_OF_TIME;
import static java.math.BigDecimal.ROUND_UNNECESSARY;
import static org.joda.money.CurrencyUnit.JPY;
Expand All @@ -32,6 +34,7 @@
import com.beust.jcommander.ParameterException;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Range;
import google.registry.model.domain.token.AllocationToken;
import google.registry.model.tld.Registry;
import java.math.BigDecimal;
import org.joda.money.Money;
Expand Down Expand Up @@ -568,6 +571,68 @@ void testFailure_specifiedDnsWriters_dontExist() {
.contains("Invalid DNS writer name(s) specified: [Deadbeef, Invalid]");
}

@Test
void testSuccess_defaultToken() throws Exception {
AllocationToken token =
persistResource(
new AllocationToken()
.asBuilder()
.setToken("abc123")
.setTokenType(DEFAULT_PROMO)
.setAllowedTlds(ImmutableSet.of("xn--q9jyb4c"))
.build());
runCommandForced(
"--default_tokens=abc123",
"--roid_suffix=Q9JYB4C",
"--dns_writers=FooDnsWriter",
"xn--q9jyb4c");
assertThat(Registry.get("xn--q9jyb4c").getDefaultPromoTokens())
.containsExactly(token.createVKey());
}

@Test
void testSuccess_multipleDefaultTokens() throws Exception {
AllocationToken token =
persistResource(
new AllocationToken()
.asBuilder()
.setToken("abc123")
.setTokenType(DEFAULT_PROMO)
.setAllowedTlds(ImmutableSet.of("xn--q9jyb4c"))
.build());
AllocationToken token2 =
persistResource(
new AllocationToken()
.asBuilder()
.setToken("token")
.setTokenType(DEFAULT_PROMO)
.setAllowedTlds(ImmutableSet.of("xn--q9jyb4c"))
.build());
runCommandForced(
"--default_tokens=abc123,token",
"--roid_suffix=Q9JYB4C",
"--dns_writers=FooDnsWriter",
"xn--q9jyb4c");
assertThat(Registry.get("xn--q9jyb4c").getDefaultPromoTokens())
.containsExactly(token.createVKey(), token2.createVKey());
}

@Test
void testFailure_specifiedDefaultToken_doesntExist() {
IllegalStateException thrown =
assertThrows(
IllegalStateException.class,
() ->
runCommandForced(
"xn--q9jyb4c",
"--default_tokens=InvalidToken",
"--roid_suffix=Q9JYB4C",
"--dns_writers=FooDnsWriter"));
assertThat(thrown)
.hasMessageThat()
.contains("Tokens with keys [VKey<AllocationToken>(sql:InvalidToken)] did not exist");
}

private void runSuccessfulReservedListsTest(String reservedLists) throws Exception {
runCommandForced(
"--reserved_lists",
Expand Down
115 changes: 115 additions & 0 deletions core/src/test/java/google/registry/tools/UpdateTldCommandTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth8.assertThat;
import static google.registry.model.domain.token.AllocationToken.TokenType.DEFAULT_PROMO;
import static google.registry.model.tld.Registry.TldState.GENERAL_AVAILABILITY;
import static google.registry.model.tld.Registry.TldState.PREDELEGATION;
import static google.registry.model.tld.Registry.TldState.QUIET_PERIOD;
Expand All @@ -33,8 +34,10 @@
import static org.junit.jupiter.api.Assertions.assertThrows;

import com.beust.jcommander.ParameterException;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSortedMap;
import google.registry.model.domain.token.AllocationToken;
import google.registry.model.tld.Registry;
import java.util.Optional;
import org.joda.money.Money;
Expand Down Expand Up @@ -174,6 +177,118 @@ void testSuccess_multipleDnsWriters() throws Exception {
.containsExactly("FooDnsWriter", "VoidDnsWriter");
}

@Test
void testSuccess_defaultToken() throws Exception {
AllocationToken token =
persistResource(
new AllocationToken()
.asBuilder()
.setToken("abc123")
.setTokenType(DEFAULT_PROMO)
.setAllowedTlds(ImmutableSet.of("xn--q9jyb4c"))
.build());
assertThat(Registry.get("xn--q9jyb4c").getDefaultPromoTokens()).isEmpty();
runCommandForced("--default_tokens=abc123", "xn--q9jyb4c");
assertThat(Registry.get("xn--q9jyb4c").getDefaultPromoTokens())
.containsExactly(token.createVKey());
}

@Test
void testSuccess_multipleDefaultTokens() throws Exception {
AllocationToken token =
persistResource(
new AllocationToken()
.asBuilder()
.setToken("abc123")
.setTokenType(DEFAULT_PROMO)
.setAllowedTlds(ImmutableSet.of("xn--q9jyb4c"))
.build());
AllocationToken token2 =
persistResource(
new AllocationToken()
.asBuilder()
.setToken("token")
.setTokenType(DEFAULT_PROMO)
.setAllowedTlds(ImmutableSet.of("xn--q9jyb4c"))
.build());
assertThat(Registry.get("xn--q9jyb4c").getDefaultPromoTokens()).isEmpty();
runCommandForced("--default_tokens=abc123,token", "xn--q9jyb4c");
assertThat(Registry.get("xn--q9jyb4c").getDefaultPromoTokens())
.containsExactly(token.createVKey(), token2.createVKey());
}

@Test
void testSuccess_emptyTokenList() throws Exception {
AllocationToken token =
persistResource(
new AllocationToken()
.asBuilder()
.setToken("abc123")
.setTokenType(DEFAULT_PROMO)
.setAllowedTlds(ImmutableSet.of("xn--q9jyb4c"))
.build());
assertThat(Registry.get("xn--q9jyb4c").getDefaultPromoTokens()).isEmpty();
persistResource(
Registry.get("xn--q9jyb4c")
.asBuilder()
.setDefaultPromoTokens(ImmutableList.of(token.createVKey()))
.build());
assertThat(Registry.get("xn--q9jyb4c").getDefaultPromoTokens())
.containsExactly(token.createVKey());
runCommandForced("--default_tokens=", "xn--q9jyb4c");
assertThat(Registry.get("xn--q9jyb4c").getDefaultPromoTokens()).isEmpty();
}

@Test
void testSuccess_replaceExistingDefaultTokensListOrder() throws Exception {
AllocationToken token =
persistResource(
new AllocationToken()
.asBuilder()
.setToken("abc123")
.setTokenType(DEFAULT_PROMO)
.setAllowedTlds(ImmutableSet.of("xn--q9jyb4c"))
.build());
AllocationToken token2 =
persistResource(
new AllocationToken()
.asBuilder()
.setToken("token")
.setTokenType(DEFAULT_PROMO)
.setAllowedTlds(ImmutableSet.of("xn--q9jyb4c"))
.build());
AllocationToken token3 =
persistResource(
new AllocationToken()
.asBuilder()
.setToken("othertoken")
.setTokenType(DEFAULT_PROMO)
.setAllowedTlds(ImmutableSet.of("xn--q9jyb4c"))
.build());
assertThat(Registry.get("xn--q9jyb4c").getDefaultPromoTokens()).isEmpty();
persistResource(
Registry.get("xn--q9jyb4c")
.asBuilder()
.setDefaultPromoTokens(ImmutableList.of(token.createVKey(), token2.createVKey()))
.build());
assertThat(Registry.get("xn--q9jyb4c").getDefaultPromoTokens())
.containsExactly(token.createVKey(), token2.createVKey());
runCommandForced("--default_tokens=token,othertoken", "xn--q9jyb4c");
assertThat(Registry.get("xn--q9jyb4c").getDefaultPromoTokens())
.containsExactly(token2.createVKey(), token3.createVKey());
}

@Test
void testFailure_specifiedDefaultToken_doesntExist() {
IllegalStateException thrown =
assertThrows(
IllegalStateException.class,
() -> runCommandForced("xn--q9jyb4c", "--default_tokens=InvalidToken"));
assertThat(thrown)
.hasMessageThat()
.contains("Tokens with keys [VKey<AllocationToken>(sql:InvalidToken)] did not exist");
}

@Test
void testSuccess_escrow() throws Exception {
runCommandForced("--escrow=true", "xn--q9jyb4c");
Expand Down

0 comments on commit 1864132

Please sign in to comment.