mirror of
https://github.com/google/nomulus.git
synced 2025-05-12 22:38:16 +02:00
Delete all Limited Release Program (LRP) code
We never used it and don't have any plans to use it going forward. All conceivable parts of its functionality that we might use going forward have already been subsumed into allocation tokens, which are a simpler way of handling the same use case that are also standards-compliant. Also gets rid of the hideous ANCHOR_ prefix on anchor tenant EPP authcodes that was only ever necessary because of overloading the authcode for anchor tenant creation. Going forward it'll be based on allocation tokens, so there's no risk of conflicts. ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=209418194
This commit is contained in:
parent
f7bc17fbe8
commit
7b87ba41c7
34 changed files with 12 additions and 1601 deletions
|
@ -23,7 +23,6 @@ import static google.registry.flows.domain.DomainFlowUtils.checkAllowedAccessToT
|
|||
import static google.registry.flows.domain.DomainFlowUtils.cloneAndLinkReferences;
|
||||
import static google.registry.flows.domain.DomainFlowUtils.createFeeCreateResponse;
|
||||
import static google.registry.flows.domain.DomainFlowUtils.isAnchorTenant;
|
||||
import static google.registry.flows.domain.DomainFlowUtils.prepareMarkedLrpTokenEntity;
|
||||
import static google.registry.flows.domain.DomainFlowUtils.validateCreateCommandContactsAndNameservers;
|
||||
import static google.registry.flows.domain.DomainFlowUtils.validateDomainName;
|
||||
import static google.registry.flows.domain.DomainFlowUtils.validateDomainNameWithIdnTables;
|
||||
|
@ -128,7 +127,6 @@ import org.joda.time.DateTime;
|
|||
* @error {@link DomainFlowUtils.FeesMismatchException}
|
||||
* @error {@link DomainFlowUtils.FeesRequiredForPremiumNameException}
|
||||
* @error {@link DomainFlowUtils.InvalidIdnDomainLabelException}
|
||||
* @error {@link DomainFlowUtils.InvalidLrpTokenException}
|
||||
* @error {@link DomainFlowUtils.InvalidPunycodeException}
|
||||
* @error {@link DomainFlowUtils.InvalidTcnIdChecksumException}
|
||||
* @error {@link DomainFlowUtils.InvalidTrademarkValidatorException}
|
||||
|
@ -277,12 +275,7 @@ public final class DomainApplicationCreateFlow implements TransactionalFlow {
|
|||
historyEntry,
|
||||
DomainApplicationIndex.createUpdatedInstance(newApplication),
|
||||
EppResourceIndex.create(Key.create(newApplication)));
|
||||
// Anchor tenant registrations override LRP, and landrush applications can skip it.
|
||||
// If a token is passed in outside of an LRP phase, it is simply ignored (i.e. never redeemed).
|
||||
if (registry.getLrpPeriod().contains(now) && !isAnchorTenant) {
|
||||
entitiesToSave.add(
|
||||
prepareMarkedLrpTokenEntity(authInfo.getPw().getValue(), domainName, historyEntry));
|
||||
}
|
||||
|
||||
EntityChanges entityChanges =
|
||||
flowCustomLogic.beforeSave(
|
||||
DomainApplicationCreateFlowCustomLogic.BeforeSaveParameters.newBuilder()
|
||||
|
|
|
@ -23,7 +23,6 @@ import static google.registry.flows.domain.DomainFlowUtils.cloneAndLinkReference
|
|||
import static google.registry.flows.domain.DomainFlowUtils.createFeeCreateResponse;
|
||||
import static google.registry.flows.domain.DomainFlowUtils.getReservationTypes;
|
||||
import static google.registry.flows.domain.DomainFlowUtils.isAnchorTenant;
|
||||
import static google.registry.flows.domain.DomainFlowUtils.prepareMarkedLrpTokenEntity;
|
||||
import static google.registry.flows.domain.DomainFlowUtils.validateCreateCommandContactsAndNameservers;
|
||||
import static google.registry.flows.domain.DomainFlowUtils.validateDomainAllowedOnCreateRestrictedTld;
|
||||
import static google.registry.flows.domain.DomainFlowUtils.validateDomainName;
|
||||
|
@ -159,7 +158,6 @@ import org.joda.time.Duration;
|
|||
* @error {@link DomainFlowUtils.FeesRequiredDuringEarlyAccessProgramException}
|
||||
* @error {@link DomainFlowUtils.FeesRequiredForPremiumNameException}
|
||||
* @error {@link DomainFlowUtils.InvalidIdnDomainLabelException}
|
||||
* @error {@link DomainFlowUtils.InvalidLrpTokenException}
|
||||
* @error {@link DomainFlowUtils.InvalidPunycodeException}
|
||||
* @error {@link DomainFlowUtils.InvalidTcnIdChecksumException}
|
||||
* @error {@link DomainFlowUtils.InvalidTrademarkValidatorException}
|
||||
|
@ -371,15 +369,8 @@ public class DomainCreateFlow implements TransactionalFlow {
|
|||
newDomain,
|
||||
ForeignKeyIndex.create(newDomain, newDomain.getDeletionTime()),
|
||||
EppResourceIndex.create(Key.create(newDomain)));
|
||||
|
||||
allocationToken.ifPresent(
|
||||
t -> entitiesToSave.add(allocationTokenFlowUtils.redeemToken(t, Key.create(historyEntry))));
|
||||
// Anchor tenant registrations override LRP, and landrush applications can skip it.
|
||||
// If a token is passed in outside of an LRP phase, it is simply ignored (i.e. never redeemed).
|
||||
if (isLrpCreate(registry, isAnchorTenant, now)) {
|
||||
entitiesToSave.add(
|
||||
prepareMarkedLrpTokenEntity(authInfo.getPw().getValue(), domainName, historyEntry));
|
||||
}
|
||||
enqueueTasks(newDomain, hasSignedMarks, hasClaimsNotice);
|
||||
|
||||
EntityChanges entityChanges =
|
||||
|
@ -596,10 +587,6 @@ public class DomainCreateFlow implements TransactionalFlow {
|
|||
.build();
|
||||
}
|
||||
|
||||
private boolean isLrpCreate(Registry registry, boolean isAnchorTenant, DateTime now) {
|
||||
return registry.getLrpPeriod().contains(now) && !isAnchorTenant;
|
||||
}
|
||||
|
||||
private void enqueueTasks(
|
||||
DomainResource newDomain, boolean hasSignedMarks, boolean hasClaimsNotice) {
|
||||
if (newDomain.shouldPublishToDns()) {
|
||||
|
|
|
@ -22,7 +22,6 @@ import static com.google.common.collect.Iterables.any;
|
|||
import static com.google.common.collect.Sets.difference;
|
||||
import static com.google.common.collect.Sets.intersection;
|
||||
import static com.google.common.collect.Sets.union;
|
||||
import static google.registry.flows.domain.DomainPricingLogic.getMatchingLrpToken;
|
||||
import static google.registry.model.domain.DomainResource.MAX_REGISTRATION_YEARS;
|
||||
import static google.registry.model.ofy.ObjectifyService.ofy;
|
||||
import static google.registry.model.registry.Registries.findTldForName;
|
||||
|
@ -55,7 +54,6 @@ import com.googlecode.objectify.Key;
|
|||
import google.registry.flows.EppException;
|
||||
import google.registry.flows.EppException.AuthorizationErrorException;
|
||||
import google.registry.flows.EppException.CommandUseErrorException;
|
||||
import google.registry.flows.EppException.InvalidAuthorizationInformationErrorException;
|
||||
import google.registry.flows.EppException.ObjectDoesNotExistException;
|
||||
import google.registry.flows.EppException.ParameterValuePolicyErrorException;
|
||||
import google.registry.flows.EppException.ParameterValueRangeErrorException;
|
||||
|
@ -80,7 +78,6 @@ import google.registry.model.domain.DomainCommand.InvalidReferencesException;
|
|||
import google.registry.model.domain.DomainCommand.Update;
|
||||
import google.registry.model.domain.DomainResource;
|
||||
import google.registry.model.domain.ForeignKeyedDesignatedContact;
|
||||
import google.registry.model.domain.LrpTokenEntity;
|
||||
import google.registry.model.domain.Period;
|
||||
import google.registry.model.domain.fee.BaseFee.FeeType;
|
||||
import google.registry.model.domain.fee.Credit;
|
||||
|
@ -992,17 +989,6 @@ public class DomainFlowUtils {
|
|||
}
|
||||
}
|
||||
|
||||
/** Create a {@link LrpTokenEntity} object that records this LRP registration. */
|
||||
static LrpTokenEntity prepareMarkedLrpTokenEntity(
|
||||
String lrpTokenString, InternetDomainName domainName, HistoryEntry historyEntry)
|
||||
throws InvalidLrpTokenException {
|
||||
Optional<LrpTokenEntity> lrpToken = getMatchingLrpToken(lrpTokenString, domainName);
|
||||
if (!lrpToken.isPresent()) {
|
||||
throw new InvalidLrpTokenException();
|
||||
}
|
||||
return lrpToken.get().asBuilder().setRedemptionHistoryEntry(Key.create(historyEntry)).build();
|
||||
}
|
||||
|
||||
/** Check that there are no code marks, which is a type of mark we don't support. */
|
||||
static void verifyNoCodeMarks(LaunchCreateExtension launchCreate)
|
||||
throws UnsupportedMarkTypeException {
|
||||
|
@ -1587,13 +1573,6 @@ public class DomainFlowUtils {
|
|||
}
|
||||
}
|
||||
|
||||
/** Invalid limited registration period token. */
|
||||
static class InvalidLrpTokenException extends InvalidAuthorizationInformationErrorException {
|
||||
public InvalidLrpTokenException() {
|
||||
super("Invalid limited registration period token");
|
||||
}
|
||||
}
|
||||
|
||||
/** Only encoded signed marks are supported. */
|
||||
static class UnsupportedMarkTypeException extends ParameterValuePolicyErrorException {
|
||||
public UnsupportedMarkTypeException() {
|
||||
|
|
|
@ -14,13 +14,11 @@
|
|||
|
||||
package google.registry.flows.domain;
|
||||
|
||||
import static google.registry.model.ofy.ObjectifyService.ofy;
|
||||
import static google.registry.pricing.PricingEngineProxy.getDomainCreateCost;
|
||||
import static google.registry.pricing.PricingEngineProxy.getDomainFeeClass;
|
||||
import static google.registry.pricing.PricingEngineProxy.getDomainRenewCost;
|
||||
|
||||
import com.google.common.net.InternetDomainName;
|
||||
import com.googlecode.objectify.Key;
|
||||
import google.registry.flows.EppException;
|
||||
import google.registry.flows.FlowScope;
|
||||
import google.registry.flows.custom.DomainPricingCustomLogic;
|
||||
|
@ -31,7 +29,6 @@ import google.registry.flows.custom.DomainPricingCustomLogic.RestorePriceParamet
|
|||
import google.registry.flows.custom.DomainPricingCustomLogic.TransferPriceParameters;
|
||||
import google.registry.flows.custom.DomainPricingCustomLogic.UpdatePriceParameters;
|
||||
import google.registry.model.domain.DomainApplication;
|
||||
import google.registry.model.domain.LrpTokenEntity;
|
||||
import google.registry.model.domain.fee.BaseFee;
|
||||
import google.registry.model.domain.fee.BaseFee.FeeType;
|
||||
import google.registry.model.domain.fee.Fee;
|
||||
|
@ -186,28 +183,4 @@ public final class DomainPricingLogic {
|
|||
public Optional<String> getFeeClass(String domainName, DateTime date) {
|
||||
return getDomainFeeClass(domainName, date);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether an LRP token String maps to a valid {@link LrpTokenEntity} for the domain name's
|
||||
* TLD, and return that entity (wrapped in an {@link Optional}) if one exists.
|
||||
*
|
||||
* <p>This method has no knowledge of whether or not an auth code (interpreted here as an LRP
|
||||
* token) has already been checked against the reserved list for QLP (anchor tenant), as auth
|
||||
* codes are used for both types of registrations.
|
||||
*/
|
||||
public static Optional<LrpTokenEntity> getMatchingLrpToken(
|
||||
String lrpToken, InternetDomainName domainName) {
|
||||
// Note that until the actual per-TLD logic is built out, what's being done here is a basic
|
||||
// domain-name-to-assignee match.
|
||||
if (!lrpToken.isEmpty()) {
|
||||
LrpTokenEntity token = ofy().load().key(Key.create(LrpTokenEntity.class, lrpToken)).now();
|
||||
if (token != null
|
||||
&& token.getAssignee().equalsIgnoreCase(domainName.toString())
|
||||
&& token.getRedemptionHistoryEntry() == null
|
||||
&& token.getValidTlds().contains(domainName.parent().toString())) {
|
||||
return Optional.of(token);
|
||||
}
|
||||
}
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,7 +23,6 @@ import google.registry.model.contact.ContactResource;
|
|||
import google.registry.model.domain.DomainApplication;
|
||||
import google.registry.model.domain.DomainBase;
|
||||
import google.registry.model.domain.DomainResource;
|
||||
import google.registry.model.domain.LrpTokenEntity;
|
||||
import google.registry.model.domain.token.AllocationToken;
|
||||
import google.registry.model.host.HostResource;
|
||||
import google.registry.model.index.DomainApplicationIndex;
|
||||
|
@ -91,7 +90,6 @@ public final class EntityClasses {
|
|||
KmsSecret.class,
|
||||
KmsSecretRevision.class,
|
||||
Lock.class,
|
||||
LrpTokenEntity.class,
|
||||
PollMessage.class,
|
||||
PollMessage.Autorenew.class,
|
||||
PollMessage.OneTime.class,
|
||||
|
|
|
@ -1,130 +0,0 @@
|
|||
// Copyright 2017 The Nomulus Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package google.registry.model.domain;
|
||||
|
||||
import static google.registry.util.CollectionUtils.nullToEmptyImmutableCopy;
|
||||
import static google.registry.util.PreconditionsUtils.checkArgumentNotNull;
|
||||
|
||||
import com.googlecode.objectify.Key;
|
||||
import com.googlecode.objectify.annotation.EmbedMap;
|
||||
import com.googlecode.objectify.annotation.Entity;
|
||||
import com.googlecode.objectify.annotation.Id;
|
||||
import com.googlecode.objectify.annotation.Index;
|
||||
import google.registry.model.BackupGroupRoot;
|
||||
import google.registry.model.Buildable;
|
||||
import google.registry.model.annotations.ReportedOn;
|
||||
import google.registry.model.reporting.HistoryEntry;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/** An entity representing a token distributed to eligible LRP registrants. */
|
||||
@ReportedOn
|
||||
@Entity
|
||||
public class LrpTokenEntity extends BackupGroupRoot implements Buildable {
|
||||
|
||||
/**
|
||||
* The secret token assigned to a registrant for the purposes of LRP registration.
|
||||
*/
|
||||
@Id
|
||||
String token;
|
||||
|
||||
/**
|
||||
* The token's assignee (additional metadata for identifying the owner of the token, the details
|
||||
* of which might differ from TLD to TLD).
|
||||
*/
|
||||
@Index
|
||||
String assignee;
|
||||
|
||||
/**
|
||||
* A list of TLDs for which this LRP token is valid.
|
||||
*/
|
||||
Set<String> validTlds;
|
||||
|
||||
/**
|
||||
* The key of the history entry for which the token was used.
|
||||
*/
|
||||
Key<HistoryEntry> redemptionHistoryEntry;
|
||||
|
||||
/**
|
||||
* A set of key-value properties associated with the LRP token. This map can be used to store
|
||||
* additional metadata about the assignee or space of domain names for which this token can be
|
||||
* valid.
|
||||
*/
|
||||
@EmbedMap
|
||||
Map<String, String> metadata;
|
||||
|
||||
public String getToken() {
|
||||
return token;
|
||||
}
|
||||
|
||||
public String getAssignee() {
|
||||
return assignee;
|
||||
}
|
||||
|
||||
public Key<HistoryEntry> getRedemptionHistoryEntry() {
|
||||
return redemptionHistoryEntry;
|
||||
}
|
||||
|
||||
public boolean isRedeemed() {
|
||||
return redemptionHistoryEntry != null;
|
||||
}
|
||||
|
||||
public Set<String> getValidTlds() {
|
||||
return nullToEmptyImmutableCopy(validTlds);
|
||||
}
|
||||
|
||||
public Map<String, String> getMetadata() {
|
||||
return nullToEmptyImmutableCopy(metadata);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder asBuilder() {
|
||||
return new Builder(clone(this));
|
||||
}
|
||||
|
||||
/** A builder for constructing {@link LrpTokenEntity} objects, since they are immutable. */
|
||||
public static class Builder extends Buildable.Builder<LrpTokenEntity> {
|
||||
public Builder() {}
|
||||
|
||||
private Builder(LrpTokenEntity instance) {
|
||||
super(instance);
|
||||
}
|
||||
|
||||
public Builder setAssignee(String assignee) {
|
||||
getInstance().assignee = assignee;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setToken(String token) {
|
||||
getInstance().token = checkArgumentNotNull(token);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setRedemptionHistoryEntry(Key<HistoryEntry> redemptionHistoryEntry) {
|
||||
getInstance().redemptionHistoryEntry = checkArgumentNotNull(redemptionHistoryEntry);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setValidTlds(Set<String> validTlds) {
|
||||
getInstance().validTlds = validTlds;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setMetadata(Map<String, String> metadata) {
|
||||
getInstance().metadata = metadata;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -68,7 +68,6 @@ import org.joda.money.CurrencyUnit;
|
|||
import org.joda.money.Money;
|
||||
import org.joda.time.DateTime;
|
||||
import org.joda.time.Duration;
|
||||
import org.joda.time.Interval;
|
||||
|
||||
/** Persisted per-TLD configuration data. */
|
||||
@ReportedOn
|
||||
|
@ -430,20 +429,6 @@ public class Registry extends ImmutableObject implements Buildable {
|
|||
/** The end of the claims period (at or after this time, claims no longer applies). */
|
||||
DateTime claimsPeriodEnd = END_OF_TIME;
|
||||
|
||||
/**
|
||||
* The (inclusive) start {@link DateTime} of LRP. This (and lrpPeriodEnd) exist for serialization
|
||||
* purposes, though everything else that interacts with the LRP period should use getLrpPeriod()
|
||||
* and setLrpPeriod(), which uses an {@link Interval}.
|
||||
*/
|
||||
DateTime lrpPeriodStart;
|
||||
|
||||
/**
|
||||
* The (exclusive) end {@link DateTime} of LRP. This (and lrpPeriodStart) exist for serialization
|
||||
* purposes, though everything else that interacts with the LRP period should use getLrpPeriod()
|
||||
* and setLrpPeriod(), which uses an {@link Interval}.
|
||||
*/
|
||||
DateTime lrpPeriodEnd;
|
||||
|
||||
/** A whitelist of clients allowed to be used on domains on this TLD (ignored if empty). */
|
||||
Set<String> allowedRegistrantContactIds;
|
||||
|
||||
|
@ -646,12 +631,6 @@ public class Registry extends ImmutableObject implements Buildable {
|
|||
return nullToEmptyImmutableCopy(allowedFullyQualifiedHostNames);
|
||||
}
|
||||
|
||||
public Interval getLrpPeriod() {
|
||||
return (lrpPeriodStart == null && lrpPeriodEnd == null)
|
||||
? new Interval(START_OF_TIME, Duration.ZERO) // An empty duration.
|
||||
: new Interval(lrpPeriodStart, lrpPeriodEnd);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder asBuilder() {
|
||||
return new Builder(clone(this));
|
||||
|
@ -920,12 +899,6 @@ public class Registry extends ImmutableObject implements Buildable {
|
|||
return this;
|
||||
}
|
||||
|
||||
public Builder setLrpPeriod(@Nullable Interval lrpPeriod) {
|
||||
getInstance().lrpPeriodStart = (lrpPeriod == null ? null : lrpPeriod.getStart());
|
||||
getInstance().lrpPeriodEnd = (lrpPeriod == null ? null : lrpPeriod.getEnd());
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Registry build() {
|
||||
final Registry instance = getInstance();
|
||||
|
|
|
@ -18,8 +18,7 @@ import static com.google.common.base.Preconditions.checkArgument;
|
|||
import static com.google.common.base.Strings.isNullOrEmpty;
|
||||
import static google.registry.model.registry.Registries.findTldForNameOrThrow;
|
||||
import static google.registry.pricing.PricingEngineProxy.getDomainCreateCost;
|
||||
import static google.registry.util.TokenUtils.TokenType.ANCHOR_TENANT;
|
||||
import static google.registry.util.TokenUtils.createToken;
|
||||
import static google.registry.util.StringGenerator.DEFAULT_PASSWORD_LENGTH;
|
||||
import static org.joda.time.DateTimeZone.UTC;
|
||||
|
||||
import com.beust.jcommander.Parameter;
|
||||
|
@ -80,7 +79,7 @@ final class CreateAnchorTenantCommand extends MutatingEppToolCommand {
|
|||
checkArgument(superuser, "This command must be run as a superuser.");
|
||||
findTldForNameOrThrow(InternetDomainName.from(domainName)); // Check that the tld exists.
|
||||
if (isNullOrEmpty(password)) {
|
||||
password = createToken(ANCHOR_TENANT, passwordGenerator);
|
||||
password = passwordGenerator.createString(DEFAULT_PASSWORD_LENGTH);
|
||||
}
|
||||
|
||||
Money cost = null;
|
||||
|
|
|
@ -1,202 +0,0 @@
|
|||
// Copyright 2017 The Nomulus Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package google.registry.tools;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Strings.isNullOrEmpty;
|
||||
import static com.google.common.collect.ImmutableSet.toImmutableSet;
|
||||
import static com.google.common.collect.Sets.difference;
|
||||
import static google.registry.model.ofy.ObjectifyService.ofy;
|
||||
import static google.registry.model.registry.Registries.assertTldsExist;
|
||||
import static google.registry.util.TokenUtils.TokenType.LRP;
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
|
||||
import com.beust.jcommander.Parameter;
|
||||
import com.beust.jcommander.Parameters;
|
||||
import com.google.appengine.tools.remoteapi.RemoteApiException;
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.base.CharMatcher;
|
||||
import com.google.common.base.Splitter;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.io.Files;
|
||||
import com.google.common.io.LineReader;
|
||||
import com.googlecode.objectify.Key;
|
||||
import google.registry.model.domain.LrpTokenEntity;
|
||||
import google.registry.tools.Command.RemoteApiCommand;
|
||||
import google.registry.tools.params.KeyValueMapParameter.StringToIntegerMap;
|
||||
import google.registry.tools.params.KeyValueMapParameter.StringToStringMap;
|
||||
import google.registry.tools.params.PathParameter;
|
||||
import google.registry.util.NonFinalForTesting;
|
||||
import google.registry.util.Retrier;
|
||||
import google.registry.util.StringGenerator;
|
||||
import google.registry.util.TokenUtils;
|
||||
import java.io.StringReader;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import javax.inject.Inject;
|
||||
|
||||
/**
|
||||
* Command to create one or more LRP tokens, given assignee(s) as either a parameter or a text file.
|
||||
*/
|
||||
@NonFinalForTesting
|
||||
@Parameters(
|
||||
separators = " =",
|
||||
commandDescription = "Create an LRP token for a given assignee (using -a) or import a text"
|
||||
+ " file of assignees for bulk token creation (using -i). Assignee/token pairs are printed"
|
||||
+ " to stdout, and should be piped to a file for distribution to assignees or for cleanup"
|
||||
+ " in the event of a command interruption.")
|
||||
public class CreateLrpTokensCommand implements RemoteApiCommand {
|
||||
|
||||
@Parameter(
|
||||
names = {"-a", "--assignee"},
|
||||
description = "LRP token assignee")
|
||||
private String assignee;
|
||||
|
||||
@Parameter(
|
||||
names = {"-t", "--tlds"},
|
||||
description = "Comma-delimited list of TLDs that the tokens to create will be valid on",
|
||||
required = true)
|
||||
private List<String> tlds;
|
||||
|
||||
@Parameter(
|
||||
names = {"-i", "--input"},
|
||||
description = "Filename containing a list of assignees, newline-delimited",
|
||||
validateWith = PathParameter.InputFile.class)
|
||||
private Path assigneesFile;
|
||||
|
||||
@Parameter(
|
||||
names = {"-m", "--metadata"},
|
||||
description = "Token metadata key-value pairs (formatted as key=value[,key=value...]). Used"
|
||||
+ " only in conjunction with -a/--assignee when creating a single token.",
|
||||
converter = StringToStringMap.class,
|
||||
validateWith = StringToStringMap.class)
|
||||
private ImmutableMap<String, String> metadata;
|
||||
|
||||
@Parameter(
|
||||
names = {"-c", "--metadata_columns"},
|
||||
description = "Token metadata columns (formatted as key=index[,key=index...], columns are"
|
||||
+ " zero-indexed). Used only in conjunction with -i/--input to map additional fields in"
|
||||
+ " the CSV file to metadata stored on the LRP token. The index corresponds to the column"
|
||||
+ " number in the CSV file (where the assignee is assigned column 0).",
|
||||
converter = StringToIntegerMap.class,
|
||||
validateWith = StringToIntegerMap.class)
|
||||
private ImmutableMap<String, Integer> metadataColumns;
|
||||
|
||||
@Inject StringGenerator stringGenerator;
|
||||
@Inject Retrier retrier;
|
||||
|
||||
private static final int BATCH_SIZE = 20;
|
||||
|
||||
// Ensures that all of the double quotes to the right of a comma are balanced. In a well-formed
|
||||
// CSV line, there can be no leading double quote preceding the comma.
|
||||
private static final String COMMA_EXCEPT_WHEN_QUOTED_REGEX =
|
||||
",(?=([^\\\"]*\\\"[^\\\"]*\\\")*[^\\\"]*$)";
|
||||
|
||||
@Override
|
||||
public void run() throws Exception {
|
||||
checkArgument(
|
||||
(assignee == null) == (assigneesFile != null),
|
||||
"Exactly one of either assignee or filename must be specified.");
|
||||
checkArgument(
|
||||
(assigneesFile == null) || (metadata == null),
|
||||
"Metadata cannot be specified along with a filename.");
|
||||
checkArgument(
|
||||
(assignee == null) || (metadataColumns == null),
|
||||
"Metadata columns cannot be specified along with an assignee.");
|
||||
ImmutableSet<String> validTlds = ImmutableSet.copyOf(assertTldsExist(tlds));
|
||||
|
||||
LineReader reader = new LineReader(
|
||||
(assigneesFile != null)
|
||||
? Files.newReader(assigneesFile.toFile(), UTF_8)
|
||||
: new StringReader(assignee));
|
||||
|
||||
String line = null;
|
||||
do {
|
||||
ImmutableSet.Builder<LrpTokenEntity> tokensToSaveBuilder = new ImmutableSet.Builder<>();
|
||||
for (String token : generateTokens(BATCH_SIZE)) {
|
||||
line = reader.readLine();
|
||||
if (!isNullOrEmpty(line)) {
|
||||
ImmutableList<String> values =
|
||||
ImmutableList.copyOf(
|
||||
Splitter.onPattern(COMMA_EXCEPT_WHEN_QUOTED_REGEX)
|
||||
// Results should not be surrounded in double quotes.
|
||||
.trimResults(CharMatcher.is('\"'))
|
||||
.split(line));
|
||||
LrpTokenEntity.Builder tokenBuilder = new LrpTokenEntity.Builder()
|
||||
.setAssignee(values.get(0))
|
||||
.setToken(token)
|
||||
.setValidTlds(validTlds);
|
||||
if (metadata != null) {
|
||||
tokenBuilder.setMetadata(metadata);
|
||||
} else if (metadataColumns != null) {
|
||||
ImmutableMap.Builder<String, String> metadataBuilder = ImmutableMap.builder();
|
||||
for (ImmutableMap.Entry<String, Integer> entry : metadataColumns.entrySet()) {
|
||||
checkArgument(
|
||||
values.size() > entry.getValue(),
|
||||
"Entry for %s does not have a value for %s (index %s)",
|
||||
values.get(0),
|
||||
entry.getKey(),
|
||||
entry.getValue());
|
||||
metadataBuilder.put(entry.getKey(), values.get(entry.getValue()));
|
||||
}
|
||||
tokenBuilder.setMetadata(metadataBuilder.build());
|
||||
}
|
||||
tokensToSaveBuilder.add(tokenBuilder.build());
|
||||
}
|
||||
}
|
||||
final ImmutableSet<LrpTokenEntity> tokensToSave = tokensToSaveBuilder.build();
|
||||
// Wrap in a retrier to deal with transient 404 errors (thrown as RemoteApiExceptions).
|
||||
retrier.callWithRetry(() -> saveTokens(tokensToSave), RemoteApiException.class);
|
||||
} while (line != null);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void saveTokens(final ImmutableSet<LrpTokenEntity> tokens) {
|
||||
Collection<LrpTokenEntity> savedTokens =
|
||||
ofy().transact(() -> ofy().save().entities(tokens).now().values());
|
||||
for (LrpTokenEntity token : savedTokens) {
|
||||
System.out.printf("%s,%s%n", token.getAssignee(), token.getToken());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function generates at MOST {@code count} tokens, after filtering out any token strings
|
||||
* that already exist.
|
||||
*
|
||||
* <p>Note that in the incredibly rare case that all generated tokens already exist, this function
|
||||
* may return an empty set.
|
||||
*/
|
||||
private ImmutableSet<String> generateTokens(int count) {
|
||||
final ImmutableSet<String> candidates =
|
||||
ImmutableSet.copyOf(TokenUtils.createTokens(LRP, stringGenerator, count));
|
||||
ImmutableSet<Key<LrpTokenEntity>> existingTokenKeys =
|
||||
candidates
|
||||
.stream()
|
||||
.map(input -> Key.create(LrpTokenEntity.class, input))
|
||||
.collect(toImmutableSet());
|
||||
ImmutableSet<String> existingTokenStrings =
|
||||
ofy()
|
||||
.load()
|
||||
.keys(existingTokenKeys)
|
||||
.values()
|
||||
.stream()
|
||||
.map(LrpTokenEntity::getToken)
|
||||
.collect(toImmutableSet());
|
||||
return ImmutableSet.copyOf(difference(candidates, existingTokenStrings));
|
||||
}
|
||||
}
|
|
@ -32,7 +32,6 @@ import google.registry.model.registry.Registry;
|
|||
import google.registry.model.registry.Registry.TldState;
|
||||
import google.registry.model.registry.Registry.TldType;
|
||||
import google.registry.model.registry.label.PremiumList;
|
||||
import google.registry.tools.params.OptionalIntervalParameter;
|
||||
import google.registry.tools.params.OptionalStringParameter;
|
||||
import google.registry.tools.params.TransitionListParameter.BillingCostTransitions;
|
||||
import google.registry.tools.params.TransitionListParameter.TldStateTransitions;
|
||||
|
@ -46,7 +45,6 @@ import javax.inject.Named;
|
|||
import org.joda.money.Money;
|
||||
import org.joda.time.DateTime;
|
||||
import org.joda.time.Duration;
|
||||
import org.joda.time.Interval;
|
||||
|
||||
/** Shared base class for commands to create or update a TLD. */
|
||||
abstract class CreateOrUpdateTldCommand extends MutatingCommand {
|
||||
|
@ -242,15 +240,6 @@ abstract class CreateOrUpdateTldCommand extends MutatingCommand {
|
|||
)
|
||||
Integer numDnsPublishShards;
|
||||
|
||||
@Nullable
|
||||
@Parameter(
|
||||
names = "--lrp_period",
|
||||
description =
|
||||
"LRP period (in ISO-8601 format, e.g. 2004-06-09T12:30:00Z/2004-07-10T13:30:00Z",
|
||||
converter = OptionalIntervalParameter.class,
|
||||
validateWith = OptionalIntervalParameter.class)
|
||||
private Optional<Interval> lrpPeriod;
|
||||
|
||||
/** Returns the existing registry (for update) or null (for creates). */
|
||||
@Nullable
|
||||
abstract Registry getOldRegistry(String tld);
|
||||
|
@ -358,7 +347,6 @@ abstract class CreateOrUpdateTldCommand extends MutatingCommand {
|
|||
Optional.ofNullable(claimsPeriodEnd).ifPresent(builder::setClaimsPeriodEnd);
|
||||
Optional.ofNullable(domainCreateRestricted).ifPresent(builder::setDomainCreateRestricted);
|
||||
Optional.ofNullable(numDnsPublishShards).ifPresent(builder::setNumDnsPublishLocks);
|
||||
Optional.ofNullable(lrpPeriod).ifPresent(p -> builder.setLrpPeriod(p.orElse(null)));
|
||||
|
||||
if (premiumListName != null) {
|
||||
if (premiumListName.isPresent()) {
|
||||
|
|
|
@ -19,6 +19,7 @@ import static com.google.common.collect.ImmutableSet.toImmutableSet;
|
|||
import static com.google.common.collect.Queues.newArrayDeque;
|
||||
import static com.google.common.collect.Sets.difference;
|
||||
import static google.registry.model.ofy.ObjectifyService.ofy;
|
||||
import static google.registry.util.StringGenerator.DEFAULT_PASSWORD_LENGTH;
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
|
||||
import com.beust.jcommander.Parameter;
|
||||
|
@ -73,7 +74,7 @@ public class GenerateAllocationTokensCommand implements RemoteApiCommand {
|
|||
names = {"-l", "--length"},
|
||||
description = "The length of each token, exclusive of the prefix (if specified); defaults to 16"
|
||||
)
|
||||
private int tokenLength = 16;
|
||||
private int tokenLength = DEFAULT_PASSWORD_LENGTH;
|
||||
|
||||
@Parameter(
|
||||
names = {"--dry_run"},
|
||||
|
|
|
@ -1,79 +0,0 @@
|
|||
// Copyright 2017 The Nomulus Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package google.registry.tools;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static google.registry.model.ofy.ObjectifyService.ofy;
|
||||
|
||||
import com.beust.jcommander.Parameter;
|
||||
import com.beust.jcommander.Parameters;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.googlecode.objectify.Key;
|
||||
import google.registry.model.domain.LrpTokenEntity;
|
||||
import google.registry.tools.Command.RemoteApiCommand;
|
||||
|
||||
/** Command to show token information for LRP participants. */
|
||||
@Parameters(
|
||||
separators = " =",
|
||||
commandDescription = "Show token information for LRP participants by matching on a "
|
||||
+ "known token or a unique ID (assignee).")
|
||||
public final class GetLrpTokenCommand implements RemoteApiCommand {
|
||||
|
||||
@Parameter(
|
||||
names = {"-t", "--token"},
|
||||
description = "LRP access token (auth code) to check")
|
||||
private String tokenString;
|
||||
|
||||
@Parameter(
|
||||
names = {"-a", "--assignee"},
|
||||
description = "LRP token assignee")
|
||||
private String assignee;
|
||||
|
||||
@Parameter(
|
||||
names = {"-h", "--history"},
|
||||
description = "Return expanded history entry (including domain application)")
|
||||
private boolean includeHistory = false;
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
checkArgument(
|
||||
(tokenString == null) == (assignee != null),
|
||||
"Exactly one of either token or assignee must be specified.");
|
||||
ImmutableSet.Builder<LrpTokenEntity> tokensBuilder = new ImmutableSet.Builder<>();
|
||||
if (tokenString != null) {
|
||||
LrpTokenEntity token =
|
||||
ofy().load().key(Key.create(LrpTokenEntity.class, tokenString)).now();
|
||||
if (token != null) {
|
||||
tokensBuilder.add(token);
|
||||
}
|
||||
} else {
|
||||
tokensBuilder.addAll(ofy().load().type(LrpTokenEntity.class).filter("assignee", assignee));
|
||||
}
|
||||
|
||||
ImmutableSet<LrpTokenEntity> tokens = tokensBuilder.build();
|
||||
if (!tokens.isEmpty()) {
|
||||
for (LrpTokenEntity token : tokens) {
|
||||
System.out.println(token);
|
||||
if (includeHistory && token.getRedemptionHistoryEntry() != null) {
|
||||
System.out.println(
|
||||
ofy().load().key(token.getRedemptionHistoryEntry()).now().toHydratedString());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
System.out.println("Token not found.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -41,7 +41,6 @@ public final class RegistryTool {
|
|||
.put("create_contact", CreateContactCommand.class)
|
||||
.put("create_domain", CreateDomainCommand.class)
|
||||
.put("create_host", CreateHostCommand.class)
|
||||
.put("create_lrp_tokens", CreateLrpTokensCommand.class)
|
||||
.put("create_premium_list", CreatePremiumListCommand.class)
|
||||
.put("create_registrar", CreateRegistrarCommand.class)
|
||||
.put("create_registrar_groups", CreateRegistrarGroupsCommand.class)
|
||||
|
@ -74,7 +73,6 @@ public final class RegistryTool {
|
|||
.put("get_history_entries", GetHistoryEntriesCommand.class)
|
||||
.put("get_host", GetHostCommand.class)
|
||||
.put("get_keyring_secret", GetKeyringSecretCommand.class)
|
||||
.put("get_lrp_token", GetLrpTokenCommand.class)
|
||||
.put("get_registrar", GetRegistrarCommand.class)
|
||||
.put("get_resource_by_key", GetResourceByKeyCommand.class)
|
||||
.put("get_routing_map", GetRoutingMapCommand.class)
|
||||
|
|
|
@ -80,7 +80,6 @@ interface RegistryToolComponent {
|
|||
void inject(CreateCdnsTld command);
|
||||
void inject(CreateContactCommand command);
|
||||
void inject(CreateDomainCommand command);
|
||||
void inject(CreateLrpTokensCommand command);
|
||||
void inject(CreateTldCommand command);
|
||||
void inject(DeployInvoicingPipelineCommand command);
|
||||
void inject(DeploySpec11PipelineCommand command);
|
||||
|
|
|
@ -23,6 +23,8 @@ import java.util.Collection;
|
|||
/** String generator. */
|
||||
public abstract class StringGenerator {
|
||||
|
||||
public static final int DEFAULT_PASSWORD_LENGTH = 16;
|
||||
|
||||
/** A class containing different alphabets used to generate strings. */
|
||||
public static class Alphabets {
|
||||
|
||||
|
|
|
@ -1,71 +0,0 @@
|
|||
// Copyright 2017 The Nomulus Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package google.registry.util;
|
||||
|
||||
import static com.google.common.collect.ImmutableSet.toImmutableSet;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Iterables;
|
||||
|
||||
/**
|
||||
* A utility class for generating various auth tokens using a common prefixed-based format.
|
||||
* These tokens are generally of the form [TYPE]_[randomstring].
|
||||
*/
|
||||
public final class TokenUtils {
|
||||
|
||||
/** An enum containing definitions (prefix and length) for token types. */
|
||||
public enum TokenType {
|
||||
ANCHOR_TENANT("ANCHOR", 16),
|
||||
LRP("LRP", 16);
|
||||
|
||||
private final String prefix;
|
||||
private final int length;
|
||||
|
||||
TokenType(String prefix, int length) {
|
||||
this.prefix = prefix;
|
||||
this.length = length;
|
||||
}
|
||||
|
||||
/** Returns the prefix for a given type. */
|
||||
public String getPrefix() {
|
||||
return prefix;
|
||||
}
|
||||
|
||||
/** Returns the set token length for a given type (not including the prefix). */
|
||||
public int getLength() {
|
||||
return length;
|
||||
}
|
||||
}
|
||||
|
||||
/** Generates a single token of a given {@link TokenType}. */
|
||||
public static String createToken(TokenType type, StringGenerator generator) {
|
||||
return Iterables.getOnlyElement(createTokens(type, generator, 1));
|
||||
}
|
||||
|
||||
/** Generates an {@link ImmutableSet} of tokens of a given {@link TokenType}. */
|
||||
public static ImmutableSet<String> createTokens(
|
||||
final TokenType type,
|
||||
StringGenerator generator,
|
||||
int count) {
|
||||
return generator
|
||||
.createStrings(type.getLength(), count)
|
||||
.stream()
|
||||
.map(token -> String.format("%s_%s", type.getPrefix(), token))
|
||||
.collect(toImmutableSet());
|
||||
}
|
||||
|
||||
private TokenUtils() {}
|
||||
}
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue