mirror of
https://github.com/google/nomulus.git
synced 2025-06-29 07:43:37 +02:00
Support multiple versions of the EPP Fee Extension
We want to support multiple versions of the fee extension, to allow new features while maintaining backward compatibility. This CL extends the framework and adds one new version, 0.11 (spec version 7), to the existing version 0.6 (spec version 3). A follow-on CL will add version 0.12 (spec version 8). ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=127849044
This commit is contained in:
parent
f75bb65fd3
commit
8443da5c5c
170 changed files with 4376 additions and 586 deletions
|
@ -18,6 +18,8 @@ import static com.google.common.base.MoreObjects.firstNonNull;
|
|||
import static com.google.common.base.Strings.nullToEmpty;
|
||||
import static com.google.common.io.Resources.getResource;
|
||||
import static com.google.common.net.HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN;
|
||||
import static google.registry.model.domain.fee.Fee.FEE_EXTENSION_URIS;
|
||||
import static google.registry.model.eppcommon.ProtocolDefinition.ServiceExtension.FEE_0_11;
|
||||
import static google.registry.model.eppcommon.ProtocolDefinition.ServiceExtension.FEE_0_6;
|
||||
import static google.registry.model.registry.Registries.findTldForNameOrThrow;
|
||||
import static google.registry.util.DomainNameUtils.canonicalizeDomainName;
|
||||
|
@ -25,7 +27,7 @@ import static java.nio.charset.StandardCharsets.UTF_8;
|
|||
import static org.json.simple.JSONValue.toJSONString;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.net.InternetDomainName;
|
||||
import com.google.common.net.MediaType;
|
||||
import com.google.template.soy.SoyFileSet;
|
||||
|
@ -35,7 +37,6 @@ import dagger.Provides;
|
|||
import google.registry.config.RegistryConfig;
|
||||
import google.registry.flows.soy.DomainCheckFeeEppSoyInfo;
|
||||
import google.registry.model.domain.fee.FeeCheckResponseExtension;
|
||||
import google.registry.model.domain.fee.FeeCheckResponseExtension.FeeCheck;
|
||||
import google.registry.model.eppoutput.CheckData.DomainCheck;
|
||||
import google.registry.model.eppoutput.CheckData.DomainCheckData;
|
||||
import google.registry.model.eppoutput.EppResponse;
|
||||
|
@ -96,7 +97,7 @@ public class CheckApiAction implements Runnable {
|
|||
.getBytes(UTF_8);
|
||||
SessionMetadata sessionMetadata = new StatelessRequestSessionMetadata(
|
||||
config.getCheckApiServletRegistrarClientId(),
|
||||
ImmutableSet.of(FEE_0_6.getUri()));
|
||||
FEE_EXTENSION_URIS);
|
||||
EppResponse response = eppController
|
||||
.handleEppCommand(
|
||||
sessionMetadata,
|
||||
|
@ -117,10 +118,16 @@ public class CheckApiAction implements Runnable {
|
|||
.put("status", "success")
|
||||
.put("available", available);
|
||||
if (available) {
|
||||
FeeCheckResponseExtension feeCheckResponse =
|
||||
(FeeCheckResponseExtension) response.getExtensions().get(0);
|
||||
FeeCheck feeCheck = feeCheckResponse.getChecks().get(0);
|
||||
builder.put("tier", firstNonNull(feeCheck.getFeeClass(), "standard"));
|
||||
FeeCheckResponseExtension<?> feeCheckResponseExtension =
|
||||
(FeeCheckResponseExtension<?>) response.getFirstExtensionOfType(
|
||||
FEE_0_11.getResponseExtensionClass(),
|
||||
FEE_0_6.getResponseExtensionClass());
|
||||
if (feeCheckResponseExtension != null) {
|
||||
builder.put("tier",
|
||||
firstNonNull(
|
||||
Iterables.getOnlyElement(feeCheckResponseExtension.getItems()).getFeeClass(),
|
||||
"standard"));
|
||||
}
|
||||
} else {
|
||||
builder.put("reason", check.getReason());
|
||||
}
|
||||
|
|
|
@ -55,7 +55,8 @@ public class EppXmlTransformer {
|
|||
"domain.xsd",
|
||||
"rgp.xsd",
|
||||
"secdns.xsd",
|
||||
"fee.xsd",
|
||||
"fee06.xsd",
|
||||
"fee11.xsd",
|
||||
"metadata.xsd",
|
||||
"mark.xsd",
|
||||
"dsig.xsd",
|
||||
|
|
|
@ -26,6 +26,7 @@ import google.registry.model.eppoutput.EppResponse.ResponseExtension;
|
|||
import google.registry.model.eppoutput.Result;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import javax.annotation.Nullable;
|
||||
import org.joda.time.DateTime;
|
||||
|
@ -123,6 +124,11 @@ public abstract class Flow {
|
|||
Collections.addAll(validExtensions, extensions);
|
||||
}
|
||||
|
||||
protected final <E extends CommandExtension>
|
||||
void registerExtensions(List<Class<? extends E>> extensions) {
|
||||
validExtensions.addAll(extensions);
|
||||
}
|
||||
|
||||
/** Get the legal command extension types for this flow. */
|
||||
protected final Set<Class<? extends CommandExtension>> getValidRequestExtensions() {
|
||||
return ImmutableSet.copyOf(validExtensions);
|
||||
|
|
|
@ -44,7 +44,9 @@ public abstract class LoggedInFlow extends Flow {
|
|||
* declared on login.
|
||||
*/
|
||||
private static final ImmutableSet<String> UNDECLARED_URIS_BLACKLIST =
|
||||
ImmutableSet.of(ServiceExtension.FEE_0_6.getUri());
|
||||
ImmutableSet.of(
|
||||
ServiceExtension.FEE_0_6.getUri(),
|
||||
ServiceExtension.FEE_0_11.getUri());
|
||||
|
||||
/**
|
||||
* The TLDs on which the logged-in registrar is allowed access domains.
|
||||
|
|
|
@ -33,6 +33,7 @@ import static google.registry.flows.domain.DomainFlowUtils.verifySignedMarks;
|
|||
import static google.registry.flows.domain.DomainFlowUtils.verifyUnitIsYears;
|
||||
import static google.registry.model.EppResourceUtils.createDomainRoid;
|
||||
import static google.registry.model.EppResourceUtils.loadByUniqueId;
|
||||
import static google.registry.model.domain.fee.Fee.FEE_CREATE_COMMAND_EXTENSIONS_IN_PREFERENCE_ORDER;
|
||||
import static google.registry.model.ofy.ObjectifyService.ofy;
|
||||
import static google.registry.model.registry.Registries.findTldForName;
|
||||
import static google.registry.model.registry.label.ReservedList.matchesAnchorTenantReservation;
|
||||
|
@ -52,7 +53,7 @@ import google.registry.model.domain.DomainBase;
|
|||
import google.registry.model.domain.DomainBase.Builder;
|
||||
import google.registry.model.domain.DomainCommand.Create;
|
||||
import google.registry.model.domain.DomainResource;
|
||||
import google.registry.model.domain.fee.FeeCreateExtension;
|
||||
import google.registry.model.domain.fee.FeeTransformCommandExtension;
|
||||
import google.registry.model.domain.launch.LaunchCreateExtension;
|
||||
import google.registry.model.domain.launch.LaunchNotice;
|
||||
import google.registry.model.domain.launch.LaunchNotice.InvalidChecksumException;
|
||||
|
@ -83,7 +84,7 @@ public abstract class BaseDomainCreateFlow<R extends DomainBase, B extends Build
|
|||
protected String domainLabel;
|
||||
protected InternetDomainName domainName;
|
||||
protected String idnTableName;
|
||||
protected FeeCreateExtension feeCreate;
|
||||
protected FeeTransformCommandExtension feeCreate;
|
||||
protected EppCommandOperations commandOperations;
|
||||
protected boolean hasSignedMarks;
|
||||
protected SignedMark signedMark;
|
||||
|
@ -96,7 +97,8 @@ public abstract class BaseDomainCreateFlow<R extends DomainBase, B extends Build
|
|||
registerExtensions(SecDnsCreateExtension.class);
|
||||
secDnsCreate = eppInput.getSingleExtension(SecDnsCreateExtension.class);
|
||||
launchCreate = eppInput.getSingleExtension(LaunchCreateExtension.class);
|
||||
feeCreate = eppInput.getSingleExtension(FeeCreateExtension.class);
|
||||
feeCreate =
|
||||
eppInput.getFirstExtensionOfClasses(FEE_CREATE_COMMAND_EXTENSIONS_IN_PREFERENCE_ORDER);
|
||||
hasSignedMarks = launchCreate != null && !launchCreate.getSignedMarks().isEmpty();
|
||||
initDomainCreateFlow();
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@ package google.registry.flows.domain;
|
|||
|
||||
import static google.registry.flows.domain.DomainFlowUtils.DISALLOWED_TLD_STATES_FOR_LAUNCH_FLOWS;
|
||||
import static google.registry.flows.domain.DomainFlowUtils.validateFeeChallenge;
|
||||
import static google.registry.model.domain.fee.Fee.FEE_CREATE_COMMAND_EXTENSIONS_IN_PREFERENCE_ORDER;
|
||||
import static google.registry.model.eppoutput.Result.Code.Success;
|
||||
import static google.registry.model.index.DomainApplicationIndex.loadActiveApplicationsByDomainName;
|
||||
import static google.registry.model.index.ForeignKeyIndex.loadAndGetReference;
|
||||
|
@ -32,8 +33,6 @@ import google.registry.model.domain.DomainApplication;
|
|||
import google.registry.model.domain.DomainApplication.Builder;
|
||||
import google.registry.model.domain.DomainResource;
|
||||
import google.registry.model.domain.Period;
|
||||
import google.registry.model.domain.fee.FeeCreateExtension;
|
||||
import google.registry.model.domain.fee.FeeCreateResponseExtension;
|
||||
import google.registry.model.domain.launch.ApplicationStatus;
|
||||
import google.registry.model.domain.launch.LaunchCreateExtension;
|
||||
import google.registry.model.domain.launch.LaunchCreateResponseExtension;
|
||||
|
@ -117,7 +116,8 @@ public class DomainApplicationCreateFlow extends BaseDomainCreateFlow<DomainAppl
|
|||
|
||||
@Override
|
||||
protected void initDomainCreateFlow() {
|
||||
registerExtensions(FeeCreateExtension.class, LaunchCreateExtension.class);
|
||||
registerExtensions(LaunchCreateExtension.class);
|
||||
registerExtensions(FEE_CREATE_COMMAND_EXTENSIONS_IN_PREFERENCE_ORDER);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -211,9 +211,9 @@ public class DomainApplicationCreateFlow extends BaseDomainCreateFlow<DomainAppl
|
|||
.setApplicationId(newResource.getForeignKey())
|
||||
.build());
|
||||
if (feeCreate != null) {
|
||||
responseExtensionsBuilder.add(new FeeCreateResponseExtension.Builder()
|
||||
responseExtensionsBuilder.add(feeCreate.createResponseBuilder()
|
||||
.setCurrency(commandOperations.getCurrency())
|
||||
.setFee(commandOperations.getFees())
|
||||
.setFees(commandOperations.getFees())
|
||||
.build());
|
||||
}
|
||||
|
||||
|
|
|
@ -17,6 +17,8 @@ package google.registry.flows.domain;
|
|||
import static google.registry.flows.domain.DomainFlowUtils.getReservationType;
|
||||
import static google.registry.flows.domain.DomainFlowUtils.handleFeeRequest;
|
||||
import static google.registry.model.EppResourceUtils.checkResourcesExist;
|
||||
import static google.registry.model.domain.fee.Fee.FEE_CHECK_COMMAND_EXTENSIONS_IN_PREFERENCE_ORDER;
|
||||
import static google.registry.model.domain.fee.Fee.FEE_EXTENSION_URIS;
|
||||
import static google.registry.model.index.DomainApplicationIndex.loadActiveApplicationsByDomainName;
|
||||
import static google.registry.model.registry.label.ReservationType.UNRESERVED;
|
||||
import static google.registry.pricing.PricingEngineProxy.getPricesForDomainName;
|
||||
|
@ -26,16 +28,17 @@ import static google.registry.util.DomainNameUtils.getTldFromDomainName;
|
|||
import com.google.common.base.Predicate;
|
||||
import com.google.common.collect.FluentIterable;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.common.net.InternetDomainName;
|
||||
import google.registry.flows.EppException;
|
||||
import google.registry.flows.EppException.ParameterValuePolicyErrorException;
|
||||
import google.registry.model.domain.DomainApplication;
|
||||
import google.registry.model.domain.fee.FeeCheckExtension;
|
||||
import google.registry.model.domain.fee.FeeCheckCommandExtension;
|
||||
import google.registry.model.domain.fee.FeeCheckCommandExtensionItem;
|
||||
import google.registry.model.domain.fee.FeeCheckResponseExtension;
|
||||
import google.registry.model.domain.fee.FeeCheckResponseExtension.FeeCheck;
|
||||
import google.registry.model.domain.fee.FeeCheckResponseExtensionItem;
|
||||
import google.registry.model.domain.launch.LaunchCheckExtension;
|
||||
import google.registry.model.eppcommon.ProtocolDefinition.ServiceExtension;
|
||||
import google.registry.model.eppoutput.CheckData;
|
||||
import google.registry.model.eppoutput.CheckData.DomainCheck;
|
||||
import google.registry.model.eppoutput.CheckData.DomainCheckData;
|
||||
|
@ -43,8 +46,10 @@ import google.registry.model.eppoutput.EppResponse.ResponseExtension;
|
|||
import google.registry.model.registry.Registry;
|
||||
import google.registry.model.registry.Registry.TldState;
|
||||
import google.registry.model.registry.label.ReservationType;
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
import javax.inject.Inject;
|
||||
import org.joda.money.CurrencyUnit;
|
||||
|
||||
/**
|
||||
* An EPP flow that checks whether a domain can be provisioned.
|
||||
|
@ -81,7 +86,8 @@ public class DomainCheckFlow extends BaseDomainCheckFlow {
|
|||
|
||||
@Override
|
||||
protected void initDomainCheckFlow() throws EppException {
|
||||
registerExtensions(LaunchCheckExtension.class, FeeCheckExtension.class);
|
||||
registerExtensions(LaunchCheckExtension.class);
|
||||
registerExtensions(FEE_CHECK_COMMAND_EXTENSIONS_IN_PREFERENCE_ORDER);
|
||||
}
|
||||
|
||||
private String getMessageForCheck(String targetId, Set<String> existingIds) {
|
||||
|
@ -103,8 +109,9 @@ public class DomainCheckFlow extends BaseDomainCheckFlow {
|
|||
if (reservationType == UNRESERVED
|
||||
&& getPricesForDomainName(domainName.toString(), now).isPremium()
|
||||
&& registry.getPremiumPriceAckRequired()
|
||||
&& !nullToEmpty(sessionMetadata.getServiceExtensionUris()).contains(
|
||||
ServiceExtension.FEE_0_6.getUri())) {
|
||||
&& Collections.disjoint(
|
||||
nullToEmpty(sessionMetadata.getServiceExtensionUris()),
|
||||
FEE_EXTENSION_URIS)) {
|
||||
return "Premium names require EPP ext.";
|
||||
}
|
||||
return reservationType.getMessageForCheck();
|
||||
|
@ -121,30 +128,59 @@ public class DomainCheckFlow extends BaseDomainCheckFlow {
|
|||
return DomainCheckData.create(checks.build());
|
||||
}
|
||||
|
||||
/** Handle the fee check extension. */
|
||||
@Override
|
||||
protected ImmutableList<? extends ResponseExtension> getResponseExtensions() throws EppException {
|
||||
FeeCheckExtension feeCheck = eppInput.getSingleExtension(FeeCheckExtension.class);
|
||||
if (feeCheck == null) {
|
||||
return null; // No fee checks were requested.
|
||||
}
|
||||
ImmutableList.Builder<FeeCheck> feeChecksBuilder = new ImmutableList.Builder<>();
|
||||
for (FeeCheckExtension.DomainCheck domainCheck : feeCheck.getDomains()) {
|
||||
String domainName = domainCheck.getName();
|
||||
if (!domainNames.containsKey(domainName)) {
|
||||
/**
|
||||
* Return the domains to be checked for a particular fee check item. Some versions of the fee
|
||||
* extension specify the domain name in the extension item, while others use the list of domain
|
||||
* names from the regular check domain availability list.
|
||||
*/
|
||||
private Set<String> getDomainNamesToCheck(FeeCheckCommandExtensionItem feeCheckItem)
|
||||
throws OnlyCheckedNamesCanBeFeeCheckedException {
|
||||
if (feeCheckItem.isDomainNameSupported()) {
|
||||
String domainNameInExtension = feeCheckItem.getDomainName();
|
||||
if (!domainNames.containsKey(domainNameInExtension)) {
|
||||
// Although the fee extension explicitly says it's ok to fee check a domain name that you
|
||||
// aren't also availability checking, we forbid it. This makes the experience simpler and
|
||||
// also means we can assume any domain names in the fee checks have been validated.
|
||||
throw new OnlyCheckedNamesCanBeFeeCheckedException();
|
||||
}
|
||||
FeeCheck.Builder builder = new FeeCheck.Builder();
|
||||
handleFeeRequest(
|
||||
domainCheck, builder, domainName, getTldFromDomainName(domainName), now);
|
||||
feeChecksBuilder.add(builder.setName(domainName).build());
|
||||
return ImmutableSet.of(domainNameInExtension);
|
||||
} else {
|
||||
// If this version of the fee extension is nameless, use the full list of domains.
|
||||
return domainNames.keySet();
|
||||
}
|
||||
return ImmutableList.of(FeeCheckResponseExtension.create(feeChecksBuilder.build()));
|
||||
}
|
||||
}
|
||||
|
||||
/** Handle the fee check extension. */
|
||||
@Override
|
||||
protected ImmutableList<ResponseExtension> getResponseExtensions() throws EppException {
|
||||
FeeCheckCommandExtension<
|
||||
? extends FeeCheckCommandExtensionItem, ? extends FeeCheckResponseExtension<?>>
|
||||
feeCheck = eppInput.getFirstExtensionOfClasses(
|
||||
FEE_CHECK_COMMAND_EXTENSIONS_IN_PREFERENCE_ORDER);
|
||||
if (feeCheck == null) {
|
||||
return null; // No fee checks were requested.
|
||||
}
|
||||
CurrencyUnit topLevelCurrency = feeCheck.isCurrencySupported() ? feeCheck.getCurrency() : null;
|
||||
ImmutableList.Builder<FeeCheckResponseExtensionItem> feeCheckResponseItemsBuilder =
|
||||
new ImmutableList.Builder<>();
|
||||
for (FeeCheckCommandExtensionItem feeCheckItem : feeCheck.getItems()) {
|
||||
for (String domainName : getDomainNamesToCheck(feeCheckItem)) {
|
||||
FeeCheckResponseExtensionItem.Builder builder = feeCheckItem.createResponseBuilder();
|
||||
handleFeeRequest(
|
||||
feeCheckItem,
|
||||
builder,
|
||||
domainName,
|
||||
getTldFromDomainName(domainName),
|
||||
topLevelCurrency,
|
||||
now);
|
||||
feeCheckResponseItemsBuilder
|
||||
.add(builder.setDomainNameIfSupported(domainName).build());
|
||||
}
|
||||
}
|
||||
return ImmutableList.<ResponseExtension>of(
|
||||
feeCheck.createResponse(feeCheckResponseItemsBuilder.build()));
|
||||
}
|
||||
|
||||
/** By server policy, fee check names must be listed in the availability check. */
|
||||
static class OnlyCheckedNamesCanBeFeeCheckedException extends ParameterValuePolicyErrorException {
|
||||
OnlyCheckedNamesCanBeFeeCheckedException() {
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
package google.registry.flows.domain;
|
||||
|
||||
import static google.registry.flows.domain.DomainFlowUtils.validateFeeChallenge;
|
||||
import static google.registry.model.domain.fee.Fee.FEE_CREATE_COMMAND_EXTENSIONS_IN_PREFERENCE_ORDER;
|
||||
import static google.registry.model.index.DomainApplicationIndex.loadActiveApplicationsByDomainName;
|
||||
import static google.registry.model.ofy.ObjectifyService.ofy;
|
||||
|
||||
|
@ -28,7 +29,6 @@ import google.registry.model.billing.BillingEvent.Reason;
|
|||
import google.registry.model.domain.DomainApplication;
|
||||
import google.registry.model.domain.DomainResource.Builder;
|
||||
import google.registry.model.domain.GracePeriod;
|
||||
import google.registry.model.domain.fee.FeeCreateExtension;
|
||||
import google.registry.model.domain.launch.LaunchCreateExtension;
|
||||
import google.registry.model.domain.rgp.GracePeriodStatus;
|
||||
import google.registry.model.registry.Registry;
|
||||
|
@ -124,7 +124,8 @@ public class DomainCreateFlow extends DomainCreateOrAllocateFlow {
|
|||
|
||||
@Override
|
||||
protected final void initDomainCreateOrAllocateFlow() {
|
||||
registerExtensions(FeeCreateExtension.class, LaunchCreateExtension.class);
|
||||
registerExtensions(LaunchCreateExtension.class);
|
||||
registerExtensions(FEE_CREATE_COMMAND_EXTENSIONS_IN_PREFERENCE_ORDER);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -29,7 +29,6 @@ import google.registry.model.billing.BillingEvent.Reason;
|
|||
import google.registry.model.domain.DomainResource;
|
||||
import google.registry.model.domain.DomainResource.Builder;
|
||||
import google.registry.model.domain.Period;
|
||||
import google.registry.model.domain.fee.FeeCreateResponseExtension;
|
||||
import google.registry.model.eppoutput.CreateData.DomainCreateData;
|
||||
import google.registry.model.eppoutput.EppOutput;
|
||||
import google.registry.model.eppoutput.Result;
|
||||
|
@ -108,9 +107,9 @@ public abstract class DomainCreateOrAllocateFlow
|
|||
now,
|
||||
newResource.getRegistrationExpirationTime()),
|
||||
(feeCreate == null) ? null : ImmutableList.of(
|
||||
new FeeCreateResponseExtension.Builder()
|
||||
feeCreate.createResponseBuilder()
|
||||
.setCurrency(commandOperations.getCurrency())
|
||||
.setFee(commandOperations.getFees())
|
||||
.setFees(commandOperations.getFees())
|
||||
.build()));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,7 +37,9 @@ import google.registry.model.domain.DomainResource;
|
|||
import google.registry.model.domain.DomainResource.Builder;
|
||||
import google.registry.model.domain.GracePeriod;
|
||||
import google.registry.model.domain.fee.Credit;
|
||||
import google.registry.model.domain.fee.FeeDeleteResponseExtension;
|
||||
import google.registry.model.domain.fee.FeeTransformResponseExtension;
|
||||
import google.registry.model.domain.fee06.FeeDeleteResponseExtensionV06;
|
||||
import google.registry.model.domain.fee11.FeeDeleteResponseExtensionV11;
|
||||
import google.registry.model.domain.rgp.GracePeriodStatus;
|
||||
import google.registry.model.domain.secdns.SecDnsUpdateExtension;
|
||||
import google.registry.model.eppcommon.ProtocolDefinition.ServiceExtension;
|
||||
|
@ -48,6 +50,8 @@ import google.registry.model.poll.PendingActionNotificationResponse.DomainPendin
|
|||
import google.registry.model.poll.PollMessage;
|
||||
import google.registry.model.registry.Registry;
|
||||
import google.registry.model.reporting.HistoryEntry;
|
||||
import java.util.Set;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.inject.Inject;
|
||||
import org.joda.money.CurrencyUnit;
|
||||
import org.joda.money.Money;
|
||||
|
@ -169,18 +173,32 @@ public class DomainDeleteFlow extends ResourceSyncDeleteFlow<DomainResource, Bui
|
|||
? SuccessWithActionPending : Success;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private FeeTransformResponseExtension.Builder getDeleteResponseBuilder() {
|
||||
Set<String> uris = nullToEmpty(sessionMetadata.getServiceExtensionUris());
|
||||
if (uris.contains(ServiceExtension.FEE_0_11.getUri())) {
|
||||
return new FeeDeleteResponseExtensionV11.Builder();
|
||||
}
|
||||
if (uris.contains(ServiceExtension.FEE_0_6.getUri())) {
|
||||
return new FeeDeleteResponseExtensionV06.Builder();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
protected final ImmutableList<? extends ResponseExtension> getDeleteResponseExtensions() {
|
||||
if (!credits.isEmpty()
|
||||
&& nullToEmpty(sessionMetadata.getServiceExtensionUris()).contains(
|
||||
ServiceExtension.FEE_0_6.getUri())) {
|
||||
return ImmutableList.of(new FeeDeleteResponseExtension.Builder()
|
||||
.setCurrency(checkNotNull(creditsCurrencyUnit))
|
||||
.setCredits(credits)
|
||||
.build());
|
||||
} else {
|
||||
if (credits.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
FeeTransformResponseExtension.Builder feeResponseBuilder = getDeleteResponseBuilder();
|
||||
if (feeResponseBuilder == null) {
|
||||
return null;
|
||||
}
|
||||
return ImmutableList.of(feeResponseBuilder
|
||||
.setCurrency(checkNotNull(creditsCurrencyUnit))
|
||||
.setCredits(credits)
|
||||
.build());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -62,11 +62,12 @@ import google.registry.model.domain.DomainCommand.CreateOrUpdate;
|
|||
import google.registry.model.domain.DomainCommand.InvalidReferencesException;
|
||||
import google.registry.model.domain.DomainResource;
|
||||
import google.registry.model.domain.Period;
|
||||
import google.registry.model.domain.fee.BaseFeeCommand;
|
||||
import google.registry.model.domain.fee.BaseFeeRequest;
|
||||
import google.registry.model.domain.fee.BaseFeeResponse;
|
||||
import google.registry.model.domain.fee.Fee;
|
||||
import google.registry.model.domain.fee.FeeCommandDescriptor;
|
||||
import google.registry.model.domain.fee.FeeCheckCommandExtensionItem;
|
||||
import google.registry.model.domain.fee.FeeCheckResponseExtensionItem;
|
||||
import google.registry.model.domain.fee.FeeQueryCommandExtensionItem;
|
||||
import google.registry.model.domain.fee.FeeQueryResponseExtensionItem;
|
||||
import google.registry.model.domain.fee.FeeTransformCommandExtension;
|
||||
import google.registry.model.domain.launch.LaunchExtension;
|
||||
import google.registry.model.domain.launch.LaunchPhase;
|
||||
import google.registry.model.domain.secdns.DelegationSignerData;
|
||||
|
@ -101,9 +102,11 @@ import java.util.HashSet;
|
|||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.xml.crypto.MarshalException;
|
||||
import javax.xml.crypto.dsig.XMLSignatureException;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
import org.joda.money.CurrencyUnit;
|
||||
import org.joda.money.Money;
|
||||
import org.joda.time.DateTime;
|
||||
import org.xml.sax.SAXException;
|
||||
|
@ -555,42 +558,47 @@ public class DomainFlowUtils {
|
|||
}
|
||||
|
||||
/**
|
||||
* Validates a {@link BaseFeeRequest} and sets the appropriate fields on a {@link BaseFeeResponse}
|
||||
* builder.
|
||||
* Validates a {@link FeeCheckCommandExtensionItem} and sets the appropriate fields on a
|
||||
* {@link FeeCheckResponseExtensionItem} builder.
|
||||
*/
|
||||
static void handleFeeRequest(
|
||||
BaseFeeRequest feeRequest,
|
||||
BaseFeeResponse.Builder<?, ?> builder,
|
||||
FeeQueryCommandExtensionItem feeRequest,
|
||||
FeeQueryResponseExtensionItem.Builder builder,
|
||||
String domainName,
|
||||
String tld,
|
||||
@Nullable CurrencyUnit topLevelCurrency,
|
||||
DateTime now) throws EppException {
|
||||
InternetDomainName domain = InternetDomainName.from(domainName);
|
||||
FeeCommandDescriptor feeCommand = feeRequest.getCommand();
|
||||
Registry registry = Registry.get(tld);
|
||||
int years = verifyUnitIsYears(feeRequest.getPeriod()).getValue();
|
||||
boolean isSunrise = registry.getTldState(now).equals(TldState.SUNRISE);
|
||||
|
||||
if (feeCommand.getPhase() != null || feeCommand.getSubphase() != null) {
|
||||
if (feeRequest.getPhase() != null || feeRequest.getSubphase() != null) {
|
||||
throw new FeeChecksDontSupportPhasesException();
|
||||
}
|
||||
if (feeRequest.getCurrency() != null
|
||||
&& !feeRequest.getCurrency().equals(registry.getCurrency())) {
|
||||
|
||||
CurrencyUnit currency =
|
||||
feeRequest.isCurrencySupported() ? feeRequest.getCurrency() : topLevelCurrency;
|
||||
if ((currency != null) && !currency.equals(registry.getCurrency())) {
|
||||
throw new CurrencyUnitMismatchException();
|
||||
}
|
||||
|
||||
builder
|
||||
.setCommand(feeCommand)
|
||||
.setCurrency(registry.getCurrency())
|
||||
.setCommand(feeRequest.getCommandName(), feeRequest.getPhase(), feeRequest.getSubphase())
|
||||
.setCurrencyIfSupported(registry.getCurrency())
|
||||
.setPeriod(feeRequest.getPeriod())
|
||||
.setClass(TldSpecificLogicProxy.getFeeClass(domainName, now).orNull());
|
||||
|
||||
switch (feeCommand.getCommand()) {
|
||||
switch (feeRequest.getCommandName()) {
|
||||
case UNKNOWN:
|
||||
throw new UnknownFeeCommandException(feeCommand.getUnparsedCommandName());
|
||||
throw new UnknownFeeCommandException(feeRequest.getUnparsedCommandName());
|
||||
case CREATE:
|
||||
if (isReserved(domain, isSunrise)) { // Don't return a create price for reserved names.
|
||||
builder.setClass("reserved"); // Override whatever class we've set above.
|
||||
builder.setAvailIfSupported(false);
|
||||
builder.setReasonIfSupported("reserved");
|
||||
} else {
|
||||
builder.setAvailIfSupported(true);
|
||||
builder.setFees(
|
||||
TldSpecificLogicProxy.getCreatePrice(registry, domainName, now, years).getFees());
|
||||
}
|
||||
|
@ -599,11 +607,14 @@ public class DomainFlowUtils {
|
|||
if (years != 1) {
|
||||
throw new RestoresAreAlwaysForOneYearException();
|
||||
}
|
||||
builder.setAvailIfSupported(true);
|
||||
builder.setFees(
|
||||
TldSpecificLogicProxy.getRestorePrice(registry, domainName, now, years).getFees());
|
||||
break;
|
||||
// TODO(mountford): handle UPDATE
|
||||
default:
|
||||
// Anything else (transfer|renew) will have a "renew" fee.
|
||||
builder.setAvailIfSupported(true);
|
||||
builder.setFees(
|
||||
TldSpecificLogicProxy.getRenewPrice(registry, domainName, now, years).getFees());
|
||||
}
|
||||
|
@ -613,7 +624,7 @@ public class DomainFlowUtils {
|
|||
String domainName,
|
||||
String tld,
|
||||
DateTime priceTime,
|
||||
final BaseFeeCommand feeCommand,
|
||||
final FeeTransformCommandExtension feeCommand,
|
||||
Money cost,
|
||||
Money... otherCosts)
|
||||
throws EppException {
|
||||
|
@ -1014,3 +1025,4 @@ public class DomainFlowUtils {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -21,8 +21,8 @@ import com.google.common.collect.ImmutableSet;
|
|||
import google.registry.flows.EppException;
|
||||
import google.registry.model.domain.DomainResource;
|
||||
import google.registry.model.domain.DomainResource.Builder;
|
||||
import google.registry.model.domain.fee.FeeInfoExtension;
|
||||
import google.registry.model.domain.fee.FeeInfoResponseExtension;
|
||||
import google.registry.model.domain.fee06.FeeInfoCommandExtensionV06;
|
||||
import google.registry.model.domain.fee06.FeeInfoResponseExtensionV06;
|
||||
import google.registry.model.domain.rgp.GracePeriodStatus;
|
||||
import google.registry.model.domain.rgp.RgpInfoExtension;
|
||||
import google.registry.model.eppoutput.EppResponse.ResponseExtension;
|
||||
|
@ -44,7 +44,7 @@ public class DomainInfoFlow extends BaseDomainInfoFlow<DomainResource, Builder>
|
|||
|
||||
@Override
|
||||
protected void initSingleResourceFlow() throws EppException {
|
||||
registerExtensions(FeeInfoExtension.class);
|
||||
registerExtensions(FeeInfoCommandExtensionV06.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -87,11 +87,17 @@ public class DomainInfoFlow extends BaseDomainInfoFlow<DomainResource, Builder>
|
|||
if (!gracePeriodStatuses.isEmpty()) {
|
||||
extensions.add(RgpInfoExtension.create(gracePeriodStatuses));
|
||||
}
|
||||
FeeInfoExtension feeInfo = eppInput.getSingleExtension(FeeInfoExtension.class);
|
||||
FeeInfoCommandExtensionV06 feeInfo =
|
||||
eppInput.getSingleExtension(FeeInfoCommandExtensionV06.class);
|
||||
if (feeInfo != null) { // Fee check was requested.
|
||||
FeeInfoResponseExtension.Builder builder = new FeeInfoResponseExtension.Builder();
|
||||
FeeInfoResponseExtensionV06.Builder builder = new FeeInfoResponseExtensionV06.Builder();
|
||||
handleFeeRequest(
|
||||
feeInfo, builder, getTargetId(), existingResource.getTld(), now);
|
||||
feeInfo,
|
||||
builder,
|
||||
getTargetId(),
|
||||
existingResource.getTld(),
|
||||
null,
|
||||
now);
|
||||
extensions.add(builder.build());
|
||||
}
|
||||
return extensions.build();
|
||||
|
|
|
@ -22,6 +22,7 @@ import static google.registry.flows.domain.DomainFlowUtils.updateAutorenewRecurr
|
|||
import static google.registry.flows.domain.DomainFlowUtils.validateFeeChallenge;
|
||||
import static google.registry.flows.domain.DomainFlowUtils.verifyUnitIsYears;
|
||||
import static google.registry.model.domain.DomainResource.MAX_REGISTRATION_YEARS;
|
||||
import static google.registry.model.domain.fee.Fee.FEE_RENEW_COMMAND_EXTENSIONS_IN_PREFERENCE_ORDER;
|
||||
import static google.registry.model.eppoutput.Result.Code.Success;
|
||||
import static google.registry.model.ofy.ObjectifyService.ofy;
|
||||
import static google.registry.pricing.PricingEngineProxy.getDomainRenewCost;
|
||||
|
@ -42,8 +43,7 @@ import google.registry.model.domain.DomainResource;
|
|||
import google.registry.model.domain.GracePeriod;
|
||||
import google.registry.model.domain.Period;
|
||||
import google.registry.model.domain.fee.Fee;
|
||||
import google.registry.model.domain.fee.FeeRenewExtension;
|
||||
import google.registry.model.domain.fee.FeeRenewResponseExtension;
|
||||
import google.registry.model.domain.fee.FeeTransformCommandExtension;
|
||||
import google.registry.model.domain.rgp.GracePeriodStatus;
|
||||
import google.registry.model.eppcommon.StatusValue;
|
||||
import google.registry.model.eppoutput.EppOutput;
|
||||
|
@ -80,7 +80,7 @@ public class DomainRenewFlow extends OwnedResourceMutateFlow<DomainResource, Ren
|
|||
StatusValue.PENDING_DELETE,
|
||||
StatusValue.SERVER_RENEW_PROHIBITED);
|
||||
|
||||
protected FeeRenewExtension feeRenew;
|
||||
protected FeeTransformCommandExtension feeRenew;
|
||||
protected Money renewCost;
|
||||
|
||||
@Inject DomainRenewFlow() {}
|
||||
|
@ -92,8 +92,9 @@ public class DomainRenewFlow extends OwnedResourceMutateFlow<DomainResource, Ren
|
|||
|
||||
@Override
|
||||
public final void initResourceCreateOrMutateFlow() throws EppException {
|
||||
registerExtensions(FeeRenewExtension.class);
|
||||
feeRenew = eppInput.getSingleExtension(FeeRenewExtension.class);
|
||||
registerExtensions(FEE_RENEW_COMMAND_EXTENSIONS_IN_PREFERENCE_ORDER);
|
||||
feeRenew =
|
||||
eppInput.getFirstExtensionOfClasses(FEE_RENEW_COMMAND_EXTENSIONS_IN_PREFERENCE_ORDER);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -176,9 +177,9 @@ public class DomainRenewFlow extends OwnedResourceMutateFlow<DomainResource, Ren
|
|||
newResource.getFullyQualifiedDomainName(),
|
||||
newResource.getRegistrationExpirationTime()),
|
||||
(feeRenew == null) ? null : ImmutableList.of(
|
||||
new FeeRenewResponseExtension.Builder()
|
||||
feeRenew.createResponseBuilder()
|
||||
.setCurrency(renewCost.getCurrencyUnit())
|
||||
.setFee(ImmutableList.of(Fee.create(renewCost.getAmount(), "renew")))
|
||||
.setFees(ImmutableList.of(Fee.create(renewCost.getAmount(), "renew")))
|
||||
.build()));
|
||||
}
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@ import static google.registry.flows.domain.DomainFlowUtils.newAutorenewPollMessa
|
|||
import static google.registry.flows.domain.DomainFlowUtils.validateFeeChallenge;
|
||||
import static google.registry.flows.domain.DomainFlowUtils.verifyNotReserved;
|
||||
import static google.registry.flows.domain.DomainFlowUtils.verifyPremiumNameIsNotBlocked;
|
||||
import static google.registry.model.domain.fee.Fee.FEE_UPDATE_COMMAND_EXTENSIONS_IN_PREFERENCE_ORDER;
|
||||
import static google.registry.model.eppoutput.Result.Code.Success;
|
||||
import static google.registry.model.ofy.ObjectifyService.ofy;
|
||||
import static google.registry.pricing.PricingEngineProxy.getDomainRenewCost;
|
||||
|
@ -38,8 +39,7 @@ import google.registry.model.billing.BillingEvent.Reason;
|
|||
import google.registry.model.domain.DomainCommand.Update;
|
||||
import google.registry.model.domain.DomainResource;
|
||||
import google.registry.model.domain.fee.Fee;
|
||||
import google.registry.model.domain.fee.FeeUpdateExtension;
|
||||
import google.registry.model.domain.fee.FeeUpdateResponseExtension;
|
||||
import google.registry.model.domain.fee.FeeTransformCommandExtension;
|
||||
import google.registry.model.domain.rgp.GracePeriodStatus;
|
||||
import google.registry.model.domain.rgp.RgpUpdateExtension;
|
||||
import google.registry.model.eppcommon.StatusValue;
|
||||
|
@ -71,7 +71,7 @@ import org.joda.time.DateTime;
|
|||
*/
|
||||
public class DomainRestoreRequestFlow extends OwnedResourceMutateFlow<DomainResource, Update> {
|
||||
|
||||
protected FeeUpdateExtension feeUpdate;
|
||||
protected FeeTransformCommandExtension feeUpdate;
|
||||
protected Money restoreCost;
|
||||
protected Money renewCost;
|
||||
|
||||
|
@ -79,7 +79,8 @@ public class DomainRestoreRequestFlow extends OwnedResourceMutateFlow<DomainReso
|
|||
|
||||
@Override
|
||||
protected final void initResourceCreateOrMutateFlow() throws EppException {
|
||||
registerExtensions(FeeUpdateExtension.class, RgpUpdateExtension.class);
|
||||
registerExtensions(RgpUpdateExtension.class);
|
||||
registerExtensions(FEE_UPDATE_COMMAND_EXTENSIONS_IN_PREFERENCE_ORDER);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -101,7 +102,8 @@ public class DomainRestoreRequestFlow extends OwnedResourceMutateFlow<DomainReso
|
|||
verifyNotReserved(InternetDomainName.from(targetId), false);
|
||||
verifyPremiumNameIsNotBlocked(targetId, now, getClientId());
|
||||
}
|
||||
feeUpdate = eppInput.getSingleExtension(FeeUpdateExtension.class);
|
||||
feeUpdate = eppInput.getFirstExtensionOfClasses(
|
||||
FEE_UPDATE_COMMAND_EXTENSIONS_IN_PREFERENCE_ORDER);
|
||||
restoreCost = Registry.get(tld).getStandardRestoreCost();
|
||||
renewCost = getDomainRenewCost(targetId, now, 1);
|
||||
validateFeeChallenge(targetId, tld, now, feeUpdate, restoreCost, renewCost);
|
||||
|
@ -186,9 +188,9 @@ public class DomainRestoreRequestFlow extends OwnedResourceMutateFlow<DomainReso
|
|||
Success,
|
||||
null,
|
||||
(feeUpdate == null) ? null : ImmutableList.of(
|
||||
new FeeUpdateResponseExtension.Builder()
|
||||
feeUpdate.createResponseBuilder()
|
||||
.setCurrency(restoreCost.getCurrencyUnit())
|
||||
.setFee(ImmutableList.of(
|
||||
.setFees(ImmutableList.of(
|
||||
Fee.create(restoreCost.getAmount(), "restore"),
|
||||
Fee.create(renewCost.getAmount(), "renew")))
|
||||
.build()));
|
||||
|
|
|
@ -14,13 +14,13 @@
|
|||
|
||||
package google.registry.flows.domain;
|
||||
|
||||
|
||||
import static google.registry.flows.domain.DomainFlowUtils.checkAllowedAccessToTld;
|
||||
import static google.registry.flows.domain.DomainFlowUtils.updateAutorenewRecurrenceEndTime;
|
||||
import static google.registry.flows.domain.DomainFlowUtils.validateFeeChallenge;
|
||||
import static google.registry.flows.domain.DomainFlowUtils.verifyPremiumNameIsNotBlocked;
|
||||
import static google.registry.flows.domain.DomainFlowUtils.verifyUnitIsYears;
|
||||
import static google.registry.model.domain.DomainResource.extendRegistrationWithCap;
|
||||
import static google.registry.model.domain.fee.Fee.FEE_TRANSFER_COMMAND_EXTENSIONS_IN_PREFERENCE_ORDER;
|
||||
import static google.registry.model.ofy.ObjectifyService.ofy;
|
||||
import static google.registry.pricing.PricingEngineProxy.getDomainRenewCost;
|
||||
import static google.registry.util.DateTimeUtils.END_OF_TIME;
|
||||
|
@ -38,8 +38,7 @@ import google.registry.model.domain.DomainCommand.Transfer;
|
|||
import google.registry.model.domain.DomainResource;
|
||||
import google.registry.model.domain.Period;
|
||||
import google.registry.model.domain.fee.Fee;
|
||||
import google.registry.model.domain.fee.FeeTransferExtension;
|
||||
import google.registry.model.domain.fee.FeeTransferResponseExtension;
|
||||
import google.registry.model.domain.fee.FeeTransformCommandExtension;
|
||||
import google.registry.model.eppoutput.EppResponse.ResponseExtension;
|
||||
import google.registry.model.poll.PollMessage;
|
||||
import google.registry.model.registry.Registry;
|
||||
|
@ -92,7 +91,7 @@ public class DomainTransferRequestFlow
|
|||
/**
|
||||
* An optional extension from the client specifying how much they think the transfer should cost.
|
||||
*/
|
||||
private FeeTransferExtension feeTransfer;
|
||||
private FeeTransformCommandExtension feeTransfer;
|
||||
|
||||
@Inject DomainTransferRequestFlow() {}
|
||||
|
||||
|
@ -103,8 +102,9 @@ public class DomainTransferRequestFlow
|
|||
|
||||
@Override
|
||||
protected final void initResourceTransferRequestFlow() {
|
||||
registerExtensions(FeeTransferExtension.class);
|
||||
feeTransfer = eppInput.getSingleExtension(FeeTransferExtension.class);
|
||||
registerExtensions(FEE_TRANSFER_COMMAND_EXTENSIONS_IN_PREFERENCE_ORDER);
|
||||
feeTransfer = eppInput.getFirstExtensionOfClasses(
|
||||
FEE_TRANSFER_COMMAND_EXTENSIONS_IN_PREFERENCE_ORDER);
|
||||
// The "existingResource" field is loaded before this function is called, but it may be null if
|
||||
// the domain name specified is invalid or doesn't exist. If that's the case, simply exit
|
||||
// early, and ResourceMutateFlow will later throw ResourceToMutateDoesNotExistException.
|
||||
|
@ -162,9 +162,9 @@ public class DomainTransferRequestFlow
|
|||
@Override
|
||||
protected ImmutableList<? extends ResponseExtension> getTransferResponseExtensions() {
|
||||
if (feeTransfer != null) {
|
||||
return ImmutableList.of(new FeeTransferResponseExtension.Builder()
|
||||
return ImmutableList.of(feeTransfer.createResponseBuilder()
|
||||
.setCurrency(renewCost.getCurrencyUnit())
|
||||
.setFee(ImmutableList.of(Fee.create(renewCost.getAmount(), "renew")))
|
||||
.setFees(ImmutableList.of(Fee.create(renewCost.getAmount(), "renew")))
|
||||
.build());
|
||||
} else {
|
||||
return null;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue