mirror of
https://github.com/google/nomulus.git
synced 2025-05-03 05:27:52 +02:00
This creates a specified number of tokens of a given schema, with a dryrun option to not persist them. ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=181403775
271 lines
12 KiB
Java
271 lines
12 KiB
Java
// 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.rde.imports;
|
|
|
|
import static com.google.common.base.Preconditions.checkArgument;
|
|
import static com.google.common.base.Preconditions.checkState;
|
|
import static com.google.common.collect.ImmutableSet.toImmutableSet;
|
|
import static google.registry.util.DomainNameUtils.canonicalizeDomainName;
|
|
import static google.registry.util.PreconditionsUtils.checkArgumentNotNull;
|
|
import static org.joda.time.DateTimeZone.UTC;
|
|
|
|
import com.google.common.base.Ascii;
|
|
import com.google.common.collect.ImmutableSet;
|
|
import com.google.common.net.InternetDomainName;
|
|
import com.googlecode.objectify.Key;
|
|
import google.registry.model.billing.BillingEvent;
|
|
import google.registry.model.contact.ContactResource;
|
|
import google.registry.model.domain.DesignatedContact;
|
|
import google.registry.model.domain.DomainAuthInfo;
|
|
import google.registry.model.domain.DomainResource;
|
|
import google.registry.model.domain.GracePeriod;
|
|
import google.registry.model.domain.rgp.GracePeriodStatus;
|
|
import google.registry.model.domain.secdns.DelegationSignerData;
|
|
import google.registry.model.eppcommon.AuthInfo.PasswordAuth;
|
|
import google.registry.model.eppcommon.StatusValue;
|
|
import google.registry.model.host.HostResource;
|
|
import google.registry.model.index.ForeignKeyIndex;
|
|
import google.registry.model.poll.PollMessage;
|
|
import google.registry.model.registry.Registries;
|
|
import google.registry.model.registry.Registry;
|
|
import google.registry.model.transfer.TransferData;
|
|
import google.registry.model.transfer.TransferStatus;
|
|
import google.registry.util.NonFinalForTesting;
|
|
import google.registry.util.RandomStringGenerator;
|
|
import google.registry.util.StringGenerator;
|
|
import google.registry.util.XmlToEnumMapper;
|
|
import google.registry.xjc.domain.XjcDomainContactType;
|
|
import google.registry.xjc.domain.XjcDomainNsType;
|
|
import google.registry.xjc.domain.XjcDomainStatusType;
|
|
import google.registry.xjc.rdedomain.XjcRdeDomain;
|
|
import google.registry.xjc.rdedomain.XjcRdeDomainElement;
|
|
import google.registry.xjc.rdedomain.XjcRdeDomainTransferDataType;
|
|
import google.registry.xjc.rgp.XjcRgpStatusType;
|
|
import google.registry.xjc.secdns.XjcSecdnsDsDataType;
|
|
import java.security.NoSuchAlgorithmException;
|
|
import java.security.ProviderException;
|
|
import java.security.SecureRandom;
|
|
import java.util.function.Function;
|
|
import org.joda.time.DateTime;
|
|
|
|
/** Utility class that converts an {@link XjcRdeDomainElement} into a {@link DomainResource}. */
|
|
final class XjcToDomainResourceConverter extends XjcToEppResourceConverter {
|
|
|
|
@NonFinalForTesting
|
|
static StringGenerator stringGenerator =
|
|
new RandomStringGenerator(StringGenerator.Alphabets.BASE_64, getRandom());
|
|
|
|
static SecureRandom getRandom() {
|
|
try {
|
|
return SecureRandom.getInstance("NativePRNG");
|
|
} catch (NoSuchAlgorithmException e) {
|
|
throw new ProviderException(e);
|
|
}
|
|
}
|
|
|
|
private static final XmlToEnumMapper<TransferStatus> TRANSFER_STATUS_MAPPER =
|
|
XmlToEnumMapper.create(TransferStatus.values());
|
|
|
|
private static final Function<String, Key<HostResource>> HOST_OBJ_CONVERTER =
|
|
fullyQualifiedHostName -> {
|
|
// host names are always lower case
|
|
fullyQualifiedHostName = canonicalizeDomainName(fullyQualifiedHostName);
|
|
Key<HostResource> key =
|
|
ForeignKeyIndex.loadAndGetKey(
|
|
HostResource.class, fullyQualifiedHostName, DateTime.now(UTC));
|
|
checkState(
|
|
key != null,
|
|
String.format("HostResource not found with name '%s'", fullyQualifiedHostName));
|
|
return key;
|
|
};
|
|
|
|
/** Converts {@link XjcRgpStatusType} to {@link GracePeriod} */
|
|
private static class GracePeriodConverter implements Function<XjcRgpStatusType, GracePeriod> {
|
|
|
|
private final XjcRdeDomain domain;
|
|
private final Key<BillingEvent.Recurring> autoRenewBillingEvent;
|
|
private final Registry tld;
|
|
|
|
GracePeriodConverter(XjcRdeDomain domain, Key<BillingEvent.Recurring> autoRenewBillingEvent) {
|
|
this.domain = domain;
|
|
this.autoRenewBillingEvent = autoRenewBillingEvent;
|
|
this.tld =
|
|
Registry.get(
|
|
Registries.findTldForNameOrThrow(InternetDomainName.from(domain.getName()))
|
|
.toString());
|
|
}
|
|
|
|
@Override
|
|
public GracePeriod apply(XjcRgpStatusType gracePeriodStatus) {
|
|
switch (gracePeriodStatus.getS()) {
|
|
case ADD_PERIOD:
|
|
return GracePeriod.createWithoutBillingEvent(
|
|
GracePeriodStatus.ADD,
|
|
domain.getCrDate().plus(this.tld.getAddGracePeriodLength()),
|
|
domain.getCrRr().getValue());
|
|
case AUTO_RENEW_PERIOD:
|
|
return GracePeriod.createForRecurring(
|
|
GracePeriodStatus.AUTO_RENEW,
|
|
domain.getUpDate().plus(this.tld.getAutoRenewGracePeriodLength()),
|
|
domain.getClID(),
|
|
autoRenewBillingEvent);
|
|
case PENDING_DELETE:
|
|
return GracePeriod.createWithoutBillingEvent(
|
|
GracePeriodStatus.PENDING_DELETE,
|
|
domain.getUpDate().plus(this.tld.getPendingDeleteLength()),
|
|
domain.getClID());
|
|
case REDEMPTION_PERIOD:
|
|
return GracePeriod.createWithoutBillingEvent(
|
|
GracePeriodStatus.REDEMPTION,
|
|
domain.getUpDate().plus(this.tld.getRedemptionGracePeriodLength()),
|
|
domain.getClID());
|
|
case RENEW_PERIOD:
|
|
return GracePeriod.createWithoutBillingEvent(
|
|
GracePeriodStatus.RENEW,
|
|
domain.getUpDate().plus(this.tld.getRenewGracePeriodLength()),
|
|
domain.getClID());
|
|
case TRANSFER_PERIOD:
|
|
return GracePeriod.createWithoutBillingEvent(
|
|
GracePeriodStatus.TRANSFER,
|
|
domain.getUpDate().plus(this.tld.getTransferGracePeriodLength()),
|
|
domain.getTrnData().getReRr().getValue());
|
|
default:
|
|
throw new IllegalArgumentException(
|
|
"Unsupported grace period status: " + gracePeriodStatus.getS());
|
|
}
|
|
}
|
|
}
|
|
|
|
/** Converts {@link XjcRdeDomain} to {@link DomainResource}. */
|
|
static DomainResource convertDomain(
|
|
XjcRdeDomain domain,
|
|
BillingEvent.Recurring autoRenewBillingEvent,
|
|
PollMessage.Autorenew autoRenewPollMessage) {
|
|
GracePeriodConverter gracePeriodConverter =
|
|
new GracePeriodConverter(domain, Key.create(autoRenewBillingEvent));
|
|
DomainResource.Builder builder =
|
|
new DomainResource.Builder()
|
|
.setFullyQualifiedDomainName(canonicalizeDomainName(domain.getName()))
|
|
.setRepoId(domain.getRoid())
|
|
.setIdnTableName(domain.getIdnTableId())
|
|
.setPersistedCurrentSponsorClientId(domain.getClID())
|
|
.setCreationClientId(domain.getCrRr().getValue())
|
|
.setCreationTime(domain.getCrDate())
|
|
.setAutorenewPollMessage(Key.create(autoRenewPollMessage))
|
|
.setAutorenewBillingEvent(Key.create(autoRenewBillingEvent))
|
|
.setRegistrationExpirationTime(domain.getExDate())
|
|
.setLastEppUpdateTime(domain.getUpDate())
|
|
.setLastEppUpdateClientId(domain.getUpRr() == null ? null : domain.getUpRr().getValue())
|
|
.setLastTransferTime(domain.getTrDate())
|
|
.setStatusValues(
|
|
domain
|
|
.getStatuses()
|
|
.stream()
|
|
.map(XjcToDomainResourceConverter::convertStatusType)
|
|
.collect(toImmutableSet()))
|
|
.setNameservers(convertNameservers(domain.getNs()))
|
|
.setGracePeriods(
|
|
domain
|
|
.getRgpStatuses()
|
|
.stream()
|
|
.map(gracePeriodConverter)
|
|
.collect(toImmutableSet()))
|
|
.setContacts(
|
|
domain
|
|
.getContacts()
|
|
.stream()
|
|
.map(XjcToDomainResourceConverter::convertContactType)
|
|
.collect(toImmutableSet()))
|
|
.setDsData(
|
|
domain.getSecDNS() == null
|
|
? ImmutableSet.of()
|
|
: domain
|
|
.getSecDNS()
|
|
.getDsDatas()
|
|
.stream()
|
|
.map(XjcToDomainResourceConverter::convertSecdnsDsDataType)
|
|
.collect(toImmutableSet()))
|
|
.setTransferData(convertDomainTransferData(domain.getTrnData()))
|
|
// authInfo pw must be a token between 6 and 16 characters in length
|
|
// generate a token of 16 characters as the default authInfo pw
|
|
.setAuthInfo(
|
|
DomainAuthInfo.create(
|
|
PasswordAuth.create(stringGenerator.createString(16), domain.getRoid())));
|
|
checkArgumentNotNull(
|
|
domain.getRegistrant(), "Registrant is missing for domain '%s'", domain.getName());
|
|
builder = builder.setRegistrant(convertRegistrant(domain.getRegistrant()));
|
|
return builder.build();
|
|
}
|
|
|
|
/** Returns {@link Key} for registrant from foreign key */
|
|
private static Key<ContactResource> convertRegistrant(String contactId) {
|
|
Key<ContactResource> key =
|
|
ForeignKeyIndex.loadAndGetKey(ContactResource.class, contactId, DateTime.now(UTC));
|
|
checkState(key != null, "Registrant not found: '%s'", contactId);
|
|
return key;
|
|
}
|
|
|
|
/** Converts {@link XjcDomainNsType} to <code>ImmutableSet<Key<HostResource>></code>. */
|
|
private static ImmutableSet<Key<HostResource>> convertNameservers(XjcDomainNsType ns) {
|
|
// If no hosts are specified, return an empty set
|
|
if (ns == null || (ns.getHostAttrs() == null && ns.getHostObjs() == null)) {
|
|
return ImmutableSet.of();
|
|
}
|
|
// Domain linked hosts must be specified by host object, not host attributes.
|
|
checkArgument(
|
|
ns.getHostAttrs() == null || ns.getHostAttrs().isEmpty(),
|
|
"Host attributes are not yet supported");
|
|
return ns.getHostObjs().stream().map(HOST_OBJ_CONVERTER).collect(toImmutableSet());
|
|
}
|
|
|
|
/** Converts {@link XjcRdeDomainTransferDataType} to {@link TransferData}. */
|
|
private static TransferData convertDomainTransferData(XjcRdeDomainTransferDataType data) {
|
|
if (data == null) {
|
|
return TransferData.EMPTY;
|
|
}
|
|
return new TransferData.Builder()
|
|
.setTransferStatus(TRANSFER_STATUS_MAPPER.xmlToEnum(data.getTrStatus().value()))
|
|
.setGainingClientId(data.getReRr().getValue())
|
|
.setLosingClientId(data.getAcRr().getValue())
|
|
.setTransferRequestTime(data.getReDate())
|
|
.setPendingTransferExpirationTime(data.getAcDate())
|
|
.setTransferredRegistrationExpirationTime(data.getExDate())
|
|
.build();
|
|
}
|
|
|
|
/** Converts {@link XjcDomainStatusType} to {@link StatusValue}. */
|
|
private static StatusValue convertStatusType(XjcDomainStatusType type) {
|
|
return StatusValue.fromXmlName(type.getS().value());
|
|
}
|
|
|
|
/** Converts {@link XjcSecdnsDsDataType} to {@link DelegationSignerData}. */
|
|
private static DelegationSignerData convertSecdnsDsDataType(XjcSecdnsDsDataType secdns) {
|
|
return DelegationSignerData.create(
|
|
secdns.getKeyTag(), secdns.getAlg(), secdns.getDigestType(), secdns.getDigest());
|
|
}
|
|
|
|
/** Converts {@link XjcDomainContactType} to {@link DesignatedContact}. */
|
|
private static DesignatedContact convertContactType(XjcDomainContactType contact) {
|
|
String contactId = contact.getValue();
|
|
Key<ContactResource> key =
|
|
ForeignKeyIndex.loadAndGetKey(ContactResource.class, contactId, DateTime.now(UTC));
|
|
checkState(key != null, "Contact not found: '%s'", contactId);
|
|
DesignatedContact.Type type =
|
|
DesignatedContact.Type.valueOf(Ascii.toUpperCase(contact.getType().toString()));
|
|
return DesignatedContact.create(type, key);
|
|
}
|
|
|
|
private XjcToDomainResourceConverter() {}
|
|
}
|