Always require acknowledgment of premium fees

This removes the configuration ability on both Registry and Registrar entities
to allow operations on premium domains to succeed without acking the fees using
the fee extension. We only ever used this ability during the minna launch, and
it was a fiasco. We have no intention of ever allowing creation, renewal,
transfer, restoring, etc. of premium domains without acking the fees ever again,
and haven't done so since 2013, so removing this ability allows us to simplify
our code, data model, and tests.

Note that all TLDs in our production system currently require price ACKing
anyway, so from an external partner perspective this commit is a noop.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=229423650
This commit is contained in:
mcilwain 2019-01-15 12:56:32 -08:00 committed by jianglai
parent 3e0eaecc9b
commit 37aa1d1815
33 changed files with 81 additions and 257 deletions

View file

@ -290,7 +290,7 @@ public class DomainCreateFlow implements TransactionalFlow {
eppInput.getSingleExtension(FeeCreateCommandExtension.class);
FeesAndCredits feesAndCredits =
pricingLogic.getCreatePrice(registry, targetId, now, years, isAnchorTenant);
validateFeeChallenge(targetId, registry.getTldStr(), clientId, now, feeCreate, feesAndCredits);
validateFeeChallenge(targetId, now, feeCreate, feesAndCredits);
Optional<SecDnsCreateExtension> secDnsCreate =
validateSecDnsExtension(eppInput.getSingleExtension(SecDnsCreateExtension.class));
String repoId = createDomainRepoId(ObjectifyService.allocateId(), registry.getTldStr());

View file

@ -672,18 +672,11 @@ public class DomainFlowUtils {
*/
public static void validateFeeChallenge(
String domainName,
String tld,
String clientId,
DateTime priceTime,
final Optional<? extends FeeTransformCommandExtension> feeCommand,
FeesAndCredits feesAndCredits)
throws EppException {
Registry registry = Registry.get(tld);
Registrar registrar = Registrar.loadByClientIdCached(clientId).get();
boolean premiumAckRequired =
registry.getPremiumPriceAckRequired() || registrar.getPremiumPriceAckRequired();
if (premiumAckRequired && isDomainPremium(domainName, priceTime) && !feeCommand.isPresent()) {
if (isDomainPremium(domainName, priceTime) && !feeCommand.isPresent()) {
throw new FeesRequiredForPremiumNameException();
}
validateFeesAckedIfPresent(feeCommand, feesAndCredits);

View file

@ -149,8 +149,7 @@ public final class DomainRenewFlow implements TransactionalFlow {
eppInput.getSingleExtension(FeeRenewCommandExtension.class);
FeesAndCredits feesAndCredits =
pricingLogic.getRenewPrice(Registry.get(existingDomain.getTld()), targetId, now, years);
validateFeeChallenge(
targetId, existingDomain.getTld(), clientId, now, feeRenew, feesAndCredits);
validateFeeChallenge(targetId, now, feeRenew, feesAndCredits);
flowCustomLogic.afterValidation(
AfterValidationParameters.newBuilder()
.setExistingDomain(existingDomain)

View file

@ -208,8 +208,7 @@ public final class DomainRestoreRequestFlow implements TransactionalFlow {
if (!existingDomain.getGracePeriodStatuses().contains(GracePeriodStatus.REDEMPTION)) {
throw new DomainNotEligibleForRestoreException();
}
validateFeeChallenge(
targetId, existingDomain.getTld(), clientId, now, feeUpdate, feesAndCredits);
validateFeeChallenge(targetId, now, feeUpdate, feesAndCredits);
}
private ImmutableSet<BillingEvent.OneTime> createRestoreAndRenewBillingEvents(

View file

@ -167,7 +167,7 @@ public final class DomainTransferRequestFlow implements TransactionalFlow {
? Optional.empty()
: Optional.of(pricingLogic.getTransferPrice(registry, targetId, now));
if (feesAndCredits.isPresent()) {
validateFeeChallenge(targetId, tld, gainingClientId, now, feeTransfer, feesAndCredits.get());
validateFeeChallenge(targetId, now, feeTransfer, feesAndCredits.get());
}
HistoryEntry historyEntry = buildHistoryEntry(existingDomain, registry, now, period);
DateTime automaticTransferTime =

View file

@ -394,13 +394,6 @@ public class Registrar extends ImmutableObject implements Buildable, Jsonifiable
*/
boolean contactsRequireSyncing = true;
/** Whether the registrar must acknowledge the price to register non-standard-priced domains. */
boolean premiumPriceAckRequired;
public boolean getPremiumPriceAckRequired() {
return premiumPriceAckRequired;
}
@NonFinalForTesting
private static Supplier<byte[]> saltSupplier =
() -> {
@ -593,7 +586,6 @@ public class Registrar extends ImmutableObject implements Buildable, Jsonifiable
.put("emailAddress", emailAddress)
.put("whoisServer", getWhoisServer())
.put("blockPremiumNames", blockPremiumNames)
.put("premiumPriceAckRequired", premiumPriceAckRequired)
.put("url", url)
.put("icannReferralEmail", getIcannReferralEmail())
.put("driveFolderId", driveFolderId)
@ -866,11 +858,6 @@ public class Registrar extends ImmutableObject implements Buildable, Jsonifiable
return this;
}
public Builder setPremiumPriceAckRequired(boolean premiumPriceAckRequired) {
getInstance().premiumPriceAckRequired = premiumPriceAckRequired;
return this;
}
/** Build the registrar, nullifying empty fields. */
@Override
public Registrar build() {

View file

@ -334,9 +334,6 @@ public class Registry extends ImmutableObject implements Buildable {
/** Whether the pull queue that writes to authoritative DNS is paused for this TLD. */
boolean dnsPaused = DEFAULT_DNS_PAUSED;
/** Whether the price must be acknowledged to register premium names on this TLD. */
boolean premiumPriceAckRequired = true;
/**
* Whether only domains with {@link ReservationType#NAMESERVER_RESTRICTED} reservation type in a
* reserved list can be registered on this TLD.
@ -462,10 +459,6 @@ public class Registry extends ImmutableObject implements Buildable {
return driveFolderId;
}
public boolean getPremiumPriceAckRequired() {
return premiumPriceAckRequired;
}
/**
* Returns true if only domains with nameserver restricted reservation on this TLD can be created.
*/
@ -658,11 +651,6 @@ public class Registry extends ImmutableObject implements Buildable {
return this;
}
public Builder setPremiumPriceAckRequired(boolean premiumPriceAckRequired) {
getInstance().premiumPriceAckRequired = premiumPriceAckRequired;
return this;
}
public Builder setDomainCreateRestricted(boolean domainCreateRestricted) {
getInstance().domainCreateRestricted = domainCreateRestricted;
return this;

View file

@ -259,13 +259,6 @@ abstract class CreateOrUpdateRegistrarCommand extends MutatingCommand {
description = "Hostname of registrar WHOIS server. (Default: whois.nic.google)")
String whoisServer;
@Nullable
@Parameter(
names = "--premium_price_ack_required",
description = "Whether operations on premium domains require explicit ack of prices",
arity = 1)
private Boolean premiumPriceAckRequired;
/** Returns the existing registrar (for update) or null (for creates). */
@Nullable
abstract Registrar getOldRegistrar(String clientId);
@ -392,7 +385,6 @@ abstract class CreateOrUpdateRegistrarCommand extends MutatingCommand {
Optional.ofNullable(phonePasscode).ifPresent(builder::setPhonePasscode);
Optional.ofNullable(icannReferralEmail).ifPresent(builder::setIcannReferralEmail);
Optional.ofNullable(whoisServer).ifPresent(builder::setWhoisServer);
Optional.ofNullable(premiumPriceAckRequired).ifPresent(builder::setPremiumPriceAckRequired);
// If the registrarName is being set, verify that it is either null or it normalizes uniquely.
String oldRegistrarName = (oldRegistrar == null) ? null : oldRegistrar.getRegistrarName();

View file

@ -117,13 +117,6 @@ abstract class CreateOrUpdateTldCommand extends MutatingCommand {
description = "Tld type (REAL or TEST)")
private TldType tldType;
@Nullable
@Parameter(
names = "--premium_price_ack_required",
description = "Whether operations on premium domains require explicit ack of prices",
arity = 1)
private Boolean premiumPriceAckRequired;
@Nullable
@Parameter(
names = "--create_billing_cost",
@ -335,7 +328,6 @@ abstract class CreateOrUpdateTldCommand extends MutatingCommand {
Optional.ofNullable(serverStatusChangeCost)
.ifPresent(builder::setServerStatusChangeBillingCost);
Optional.ofNullable(tldType).ifPresent(builder::setTldType);
Optional.ofNullable(premiumPriceAckRequired).ifPresent(builder::setPremiumPriceAckRequired);
Optional.ofNullable(lordnUsername).ifPresent(u -> builder.setLordnUsername(u.orElse(null)));
Optional.ofNullable(claimsPeriodEnd).ifPresent(builder::setClaimsPeriodEnd);
Optional.ofNullable(domainCreateRestricted).ifPresent(builder::setDomainCreateRestricted);

View file

@ -57,8 +57,7 @@ public final class ListTldsAction extends ListObjectsAction<Registry> {
return ImmutableBiMap.of(
"TLD", "tldStr",
"dns", "dnsPaused",
"escrow", "escrowEnabled",
"premiumPricing", "premiumPriceAckRequired");
"escrow", "escrowEnabled");
}
@Override
@ -67,7 +66,6 @@ public final class ListTldsAction extends ListObjectsAction<Registry> {
return new ImmutableMap.Builder<String, String>()
.put("dnsPaused", registry.getDnsPaused() ? "paused" : "-")
.put("escrowEnabled", registry.getEscrowEnabled() ? "enabled" : "-")
.put("premiumPriceAckRequired", registry.getPremiumPriceAckRequired() ? "ack req'd" : "-")
.put("tldState", registry.isPdt(now) ? "PDT" : registry.getTldState(now).toString())
.put("tldStateTransitions", registry.getTldStateTransitions().toString())
.put("renewBillingCost", registry.getStandardRenewCost(now).toString())

View file

@ -87,8 +87,7 @@ registry.json.Response.prototype.results;
* localizedAddress: registry.json.RegistrarAddress,
* whoisServer: (string?|undefined),
* referralUrl: (string?|undefined),
* contacts: !Array.<registry.json.RegistrarContact>,
* premiumPriceAckRequired: boolean
* contacts: !Array.<registry.json.RegistrarContact>
* }}
*/
registry.json.Registrar;

View file

@ -279,9 +279,6 @@ public final class RegistrarFormFields {
args, L10N_STREET_FIELD, L10N_CITY_FIELD, L10N_STATE_FIELD, L10N_ZIP_FIELD))
.build();
public static final FormField<Boolean, Boolean> PREMIUM_PRICE_ACK_REQUIRED =
FormField.named("premiumPriceAckRequired", Boolean.class).build();
private static @Nullable RegistrarAddress toNewAddress(
@Nullable Map<String, ?> args,
final FormField<List<String>, List<String>> streetField,

View file

@ -35,7 +35,6 @@ import com.google.template.soy.data.SoyMapData;
import com.google.template.soy.shared.SoyCssRenamingMap;
import com.google.template.soy.tofu.SoyTofu;
import google.registry.config.RegistryConfig.Config;
import google.registry.model.registrar.Registrar;
import google.registry.request.Action;
import google.registry.request.Parameter;
import google.registry.request.Response;
@ -149,8 +148,7 @@ public final class ConsoleUiAction implements Runnable {
// since we double check the access to the registrar on any read / update request. We have to
// - since the access might get revoked between the initial page load and the request! (also
// because the requests come from the browser, and can easily be faked)
Registrar registrar = registrarAccessor.getRegistrar(clientId);
data.put("requireFeeExtension", registrar.getPremiumPriceAckRequired());
registrarAccessor.getRegistrar(clientId);
} catch (RegistrarAccessDeniedException e) {
logger.atWarning().withCause(e).log(
"User %s doesn't have access to registrar console.", authResult.userIdForLogging());

View file

@ -260,11 +260,6 @@ public class RegistrarSettingsAction implements Runnable, JsonActionRunner.JsonA
Registrar.Builder builder = initialRegistrar.asBuilder();
// BILLING
RegistrarFormFields.PREMIUM_PRICE_ACK_REQUIRED
.extractUntyped(args)
.ifPresent(builder::setPremiumPriceAckRequired);
// WHOIS
//
// Because of how whoisServer handles "default value", it's possible that setting the existing

View file

@ -315,8 +315,6 @@
{template .resources}
{@param? driveFolderId: string}
{@param technicalDocsUrl: string}
{@param premiumPriceAckRequired: bool}
{@param readonly: bool}
<div id="domain-registrar-resources">
<h1>Resources &amp; billing</h1>
<p>
@ -341,15 +339,6 @@
{else}
<em>Your billing folder is pending allocation.</em>
{/if}
<h2><img src="/assets/images/folder.png">EPP Settings</h2>
<p>Use the 'Edit' button above to switch to enable editing the information
below. <i>Updates may require up to 10 minutes to take effect.</i>
<form name="item" class="{css('item')} {css('registrar')}">
<input type="checkbox" id="premiumPriceAckRequired" name="premiumPriceAckRequired"
{if $premiumPriceAckRequired} checked{/if}
{if $readonly} disabled{/if}>
Require use of fee extension to acknowledge all premium domain prices.
</form>
</div>
{/template}