mirror of
https://github.com/google/nomulus
synced 2026-02-23 13:29:06 +00:00
Compare commits
1 Commits
nomulus-20
...
nomulus-20
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ee8746c857 |
@@ -67,14 +67,11 @@ import google.registry.flows.EppException.ParameterValueSyntaxErrorException;
|
||||
import google.registry.flows.EppException.RequiredParameterMissingException;
|
||||
import google.registry.flows.EppException.StatusProhibitsOperationException;
|
||||
import google.registry.flows.EppException.UnimplementedOptionException;
|
||||
import google.registry.flows.exceptions.ContactsProhibitedException;
|
||||
import google.registry.flows.exceptions.ResourceHasClientUpdateProhibitedException;
|
||||
import google.registry.model.EppResource;
|
||||
import google.registry.model.billing.BillingBase.Flag;
|
||||
import google.registry.model.billing.BillingBase.Reason;
|
||||
import google.registry.model.billing.BillingRecurrence;
|
||||
import google.registry.model.contact.Contact;
|
||||
import google.registry.model.domain.DesignatedContact;
|
||||
import google.registry.model.domain.Domain;
|
||||
import google.registry.model.domain.DomainCommand.Create;
|
||||
import google.registry.model.domain.DomainCommand.CreateOrUpdate;
|
||||
@@ -421,33 +418,6 @@ public class DomainFlowUtils {
|
||||
}
|
||||
}
|
||||
|
||||
/** Enforces absence of contact data on creation as part of the Minimum Dataset requirements. */
|
||||
static void enforceContactAbsencesOnCreate(Create create)
|
||||
throws ParameterValuePolicyErrorException {
|
||||
enforceContactAbsences(create.getRegistrant(), create.getContacts());
|
||||
}
|
||||
|
||||
/** Enforces absence of contact data on update as part of the Minimum Dataset requirements. */
|
||||
static void enforceContactAbsencesOnUpdate(Update update)
|
||||
throws ParameterValuePolicyErrorException {
|
||||
Set<DesignatedContact> allDesignatedContacts =
|
||||
Sets.union(update.getInnerAdd().getContacts(), update.getInnerRemove().getContacts());
|
||||
enforceContactAbsences(update.getInnerChange().getRegistrant(), allDesignatedContacts);
|
||||
}
|
||||
|
||||
/** Enforces the absence of contact data as part of the Minimum Dataset requirements. */
|
||||
static void enforceContactAbsences(
|
||||
Optional<VKey<Contact>> registrant, Set<DesignatedContact> contacts)
|
||||
throws ParameterValuePolicyErrorException {
|
||||
if (registrant.isPresent()) {
|
||||
throw new RegistrantProhibitedException();
|
||||
}
|
||||
if (!contacts.isEmpty()) {
|
||||
throw new ContactsProhibitedException();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void validateNameserversAllowedOnTld(String tld, Set<String> fullyQualifiedHostNames)
|
||||
throws EppException {
|
||||
ImmutableSet<String> allowedHostNames = Tld.get(tld).getAllowedFullyQualifiedHostNames();
|
||||
@@ -971,7 +941,6 @@ public class DomainFlowUtils {
|
||||
Create command, Tld tld, InternetDomainName domainName) throws EppException {
|
||||
verifyNotInPendingDelete(command.getNameservers());
|
||||
String tldStr = tld.getTldStr();
|
||||
enforceContactAbsencesOnCreate(command);
|
||||
ImmutableSet<String> hostNames = command.getNameserverHostNames();
|
||||
validateNameserversCountForTld(tldStr, domainName, hostNames.size());
|
||||
validateNameserversAllowedOnTld(tldStr, hostNames);
|
||||
|
||||
@@ -29,7 +29,6 @@ import static google.registry.flows.ResourceFlowUtils.verifyOptionalAuthInfo;
|
||||
import static google.registry.flows.ResourceFlowUtils.verifyResourceOwnership;
|
||||
import static google.registry.flows.domain.DomainFlowUtils.checkAllowedAccessToTld;
|
||||
import static google.registry.flows.domain.DomainFlowUtils.cloneAndLinkReferences;
|
||||
import static google.registry.flows.domain.DomainFlowUtils.enforceContactAbsencesOnUpdate;
|
||||
import static google.registry.flows.domain.DomainFlowUtils.updateDsData;
|
||||
import static google.registry.flows.domain.DomainFlowUtils.validateDsData;
|
||||
import static google.registry.flows.domain.DomainFlowUtils.validateFeesAckedIfPresent;
|
||||
@@ -249,8 +248,6 @@ public final class DomainUpdateFlow implements MutatingFlow {
|
||||
ext.getRemove().map(Remove::getDsData).orElse(ImmutableSet.of()));
|
||||
}
|
||||
Change change = command.getInnerChange();
|
||||
enforceContactAbsencesOnUpdate(command);
|
||||
|
||||
Domain.Builder domainBuilder =
|
||||
domain
|
||||
.asBuilder()
|
||||
|
||||
@@ -29,7 +29,6 @@ import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Maps;
|
||||
import google.registry.config.RegistryConfig;
|
||||
import google.registry.model.contact.Contact;
|
||||
import google.registry.model.domain.Domain;
|
||||
import google.registry.model.host.Host;
|
||||
import google.registry.persistence.VKey;
|
||||
@@ -60,7 +59,6 @@ public final class ForeignKeyUtils {
|
||||
private static final ImmutableMap<Class<? extends EppResource>, String>
|
||||
RESOURCE_TYPE_TO_FK_PROPERTY =
|
||||
ImmutableMap.of(
|
||||
Contact.class, "contactId",
|
||||
Domain.class, "domainName",
|
||||
Host.class, "hostName");
|
||||
|
||||
|
||||
@@ -1,96 +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.contact;
|
||||
|
||||
import google.registry.model.EppResource.ForeignKeyedEppResource;
|
||||
import google.registry.model.annotations.ExternalMessagingName;
|
||||
import google.registry.persistence.VKey;
|
||||
import google.registry.persistence.WithVKey;
|
||||
import jakarta.persistence.Access;
|
||||
import jakarta.persistence.AccessType;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.Index;
|
||||
import jakarta.persistence.Table;
|
||||
|
||||
/**
|
||||
* A persistable contact resource including mutable and non-mutable fields.
|
||||
*
|
||||
* @see <a href="https://tools.ietf.org/html/rfc5733">RFC 5733</a>
|
||||
*/
|
||||
@Entity
|
||||
@Table(
|
||||
name = "Contact",
|
||||
indexes = {
|
||||
@Index(columnList = "creationTime"),
|
||||
@Index(columnList = "currentSponsorRegistrarId"),
|
||||
@Index(columnList = "deletionTime"),
|
||||
@Index(columnList = "contactId"),
|
||||
@Index(columnList = "searchName")
|
||||
})
|
||||
@ExternalMessagingName("contact")
|
||||
@WithVKey(String.class)
|
||||
@Access(AccessType.FIELD)
|
||||
public class Contact extends ContactBase implements ForeignKeyedEppResource {
|
||||
|
||||
@Override
|
||||
public VKey<Contact> createVKey() {
|
||||
return VKey.create(Contact.class, getRepoId());
|
||||
}
|
||||
|
||||
@Override
|
||||
@Id
|
||||
@Access(AccessType.PROPERTY)
|
||||
public String getRepoId() {
|
||||
return super.getRepoId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder asBuilder() {
|
||||
return new Builder(clone(this));
|
||||
}
|
||||
|
||||
/** A builder for constructing {@link Contact}, since it is immutable. */
|
||||
public static class Builder extends ContactBase.Builder<Contact, Builder> {
|
||||
|
||||
public Builder() {}
|
||||
|
||||
private Builder(Contact instance) {
|
||||
super(instance);
|
||||
}
|
||||
|
||||
public Builder copyFrom(ContactBase contactBase) {
|
||||
return this.setAuthInfo(contactBase.getAuthInfo())
|
||||
.setContactId(contactBase.getContactId())
|
||||
.setCreationRegistrarId(contactBase.getCreationRegistrarId())
|
||||
.setCreationTime(contactBase.getCreationTime())
|
||||
.setDeletionTime(contactBase.getDeletionTime())
|
||||
.setDisclose(contactBase.getDisclose())
|
||||
.setEmailAddress(contactBase.getEmailAddress())
|
||||
.setFaxNumber(contactBase.getFaxNumber())
|
||||
.setInternationalizedPostalInfo(contactBase.getInternationalizedPostalInfo())
|
||||
.setLastTransferTime(contactBase.getLastTransferTime())
|
||||
.setLastEppUpdateRegistrarId(contactBase.getLastEppUpdateRegistrarId())
|
||||
.setLastEppUpdateTime(contactBase.getLastEppUpdateTime())
|
||||
.setLocalizedPostalInfo(contactBase.getLocalizedPostalInfo())
|
||||
.setPersistedCurrentSponsorRegistrarId(
|
||||
contactBase.getPersistedCurrentSponsorRegistrarId())
|
||||
.setRepoId(contactBase.getRepoId())
|
||||
.setStatusValues(contactBase.getStatusValues())
|
||||
.setTransferData(contactBase.getTransferData())
|
||||
.setVoiceNumber(contactBase.getVoiceNumber());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,388 +0,0 @@
|
||||
// Copyright 2020 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.contact;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.collect.ImmutableList.toImmutableList;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import google.registry.model.EppResource;
|
||||
import google.registry.model.EppResource.ResourceWithTransferData;
|
||||
import google.registry.model.transfer.ContactTransferData;
|
||||
import google.registry.persistence.VKey;
|
||||
import jakarta.persistence.Access;
|
||||
import jakarta.persistence.AccessType;
|
||||
import jakarta.persistence.AttributeOverride;
|
||||
import jakarta.persistence.AttributeOverrides;
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Embeddable;
|
||||
import jakarta.persistence.Embedded;
|
||||
import jakarta.persistence.MappedSuperclass;
|
||||
import jakarta.xml.bind.annotation.XmlElement;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Stream;
|
||||
import org.joda.time.DateTime;
|
||||
|
||||
/**
|
||||
* A persistable contact resource including mutable and non-mutable fields.
|
||||
*
|
||||
* <p>This class deliberately does not include an {@link jakarta.persistence.Id} so that any
|
||||
* foreign-keyed fields can refer to the proper parent entity's ID, whether we're storing this in
|
||||
* the DB itself or as part of another entity
|
||||
*
|
||||
* @see <a href="https://tools.ietf.org/html/rfc5733">RFC 5733</a>
|
||||
*/
|
||||
@MappedSuperclass
|
||||
@Embeddable
|
||||
@Access(AccessType.FIELD)
|
||||
public class ContactBase extends EppResource
|
||||
implements ResourceWithTransferData<ContactTransferData> {
|
||||
|
||||
/**
|
||||
* Unique identifier for this contact.
|
||||
*
|
||||
* <p>This is only unique in the sense that for any given lifetime specified as the time range
|
||||
* from (creationTime, deletionTime) there can only be one contact in the database with this id.
|
||||
* However, there can be many contacts with the same id and non-overlapping lifetimes.
|
||||
*/
|
||||
String contactId;
|
||||
|
||||
/**
|
||||
* Localized postal info for the contact. All contained values must be representable in the 7-bit
|
||||
* US-ASCII character set. Personal info; cleared by {@link Contact.Builder#wipeOut}.
|
||||
*/
|
||||
@Embedded
|
||||
@AttributeOverrides({
|
||||
@AttributeOverride(name = "name", column = @Column(name = "addr_local_name")),
|
||||
@AttributeOverride(name = "org", column = @Column(name = "addr_local_org")),
|
||||
@AttributeOverride(name = "type", column = @Column(name = "addr_local_type")),
|
||||
@AttributeOverride(
|
||||
name = "address.streetLine1",
|
||||
column = @Column(name = "addr_local_street_line1")),
|
||||
@AttributeOverride(
|
||||
name = "address.streetLine2",
|
||||
column = @Column(name = "addr_local_street_line2")),
|
||||
@AttributeOverride(
|
||||
name = "address.streetLine3",
|
||||
column = @Column(name = "addr_local_street_line3")),
|
||||
@AttributeOverride(name = "address.city", column = @Column(name = "addr_local_city")),
|
||||
@AttributeOverride(name = "address.state", column = @Column(name = "addr_local_state")),
|
||||
@AttributeOverride(name = "address.zip", column = @Column(name = "addr_local_zip")),
|
||||
@AttributeOverride(
|
||||
name = "address.countryCode",
|
||||
column = @Column(name = "addr_local_country_code"))
|
||||
})
|
||||
PostalInfo localizedPostalInfo;
|
||||
|
||||
/**
|
||||
* Internationalized postal info for the contact. Personal info; cleared by {@link
|
||||
* Contact.Builder#wipeOut}.
|
||||
*/
|
||||
@Embedded
|
||||
@AttributeOverrides({
|
||||
@AttributeOverride(name = "name", column = @Column(name = "addr_i18n_name")),
|
||||
@AttributeOverride(name = "org", column = @Column(name = "addr_i18n_org")),
|
||||
@AttributeOverride(name = "type", column = @Column(name = "addr_i18n_type")),
|
||||
@AttributeOverride(
|
||||
name = "address.streetLine1",
|
||||
column = @Column(name = "addr_i18n_street_line1")),
|
||||
@AttributeOverride(
|
||||
name = "address.streetLine2",
|
||||
column = @Column(name = "addr_i18n_street_line2")),
|
||||
@AttributeOverride(
|
||||
name = "address.streetLine3",
|
||||
column = @Column(name = "addr_i18n_street_line3")),
|
||||
@AttributeOverride(name = "address.city", column = @Column(name = "addr_i18n_city")),
|
||||
@AttributeOverride(name = "address.state", column = @Column(name = "addr_i18n_state")),
|
||||
@AttributeOverride(name = "address.zip", column = @Column(name = "addr_i18n_zip")),
|
||||
@AttributeOverride(
|
||||
name = "address.countryCode",
|
||||
column = @Column(name = "addr_i18n_country_code"))
|
||||
})
|
||||
PostalInfo internationalizedPostalInfo;
|
||||
|
||||
/**
|
||||
* Contact name used for name searches. This is set automatically to be the internationalized
|
||||
* postal name, or if null, the localized postal name, or if that is null as well, null. Personal
|
||||
* info; cleared by {@link Contact.Builder#wipeOut}.
|
||||
*/
|
||||
String searchName;
|
||||
|
||||
/** Contact’s voice number. Personal info; cleared by {@link Contact.Builder#wipeOut}. */
|
||||
@Embedded
|
||||
@AttributeOverrides({
|
||||
@AttributeOverride(name = "phoneNumber", column = @Column(name = "voice_phone_number")),
|
||||
@AttributeOverride(name = "extension", column = @Column(name = "voice_phone_extension")),
|
||||
})
|
||||
ContactPhoneNumber voice;
|
||||
|
||||
/** Contact’s fax number. Personal info; cleared by {@link Contact.Builder#wipeOut}. */
|
||||
@Embedded
|
||||
@AttributeOverrides({
|
||||
@AttributeOverride(name = "phoneNumber", column = @Column(name = "fax_phone_number")),
|
||||
@AttributeOverride(name = "extension", column = @Column(name = "fax_phone_extension")),
|
||||
})
|
||||
ContactPhoneNumber fax;
|
||||
|
||||
/** Contact’s email address. Personal info; cleared by {@link Contact.Builder#wipeOut}. */
|
||||
String email;
|
||||
|
||||
/** Authorization info (aka transfer secret) of the contact. */
|
||||
@Embedded
|
||||
@AttributeOverrides({
|
||||
@AttributeOverride(name = "pw.value", column = @Column(name = "auth_info_value")),
|
||||
@AttributeOverride(name = "pw.repoId", column = @Column(name = "auth_info_repo_id")),
|
||||
})
|
||||
ContactAuthInfo authInfo;
|
||||
|
||||
/** Data about any pending or past transfers on this contact. */
|
||||
ContactTransferData transferData;
|
||||
|
||||
/**
|
||||
* The time that this resource was last transferred.
|
||||
*
|
||||
* <p>Can be null if the resource has never been transferred.
|
||||
*/
|
||||
DateTime lastTransferTime;
|
||||
|
||||
// If any new fields are added which contain personal information, make sure they are cleared by
|
||||
// the wipeOut() function, so that data is not kept around for deleted contacts.
|
||||
|
||||
/** Disclosure policy. */
|
||||
@Embedded
|
||||
@AttributeOverrides({
|
||||
@AttributeOverride(name = "name", column = @Column(name = "disclose_types_name")),
|
||||
@AttributeOverride(name = "org", column = @Column(name = "disclose_types_org")),
|
||||
@AttributeOverride(name = "addr", column = @Column(name = "disclose_types_addr")),
|
||||
@AttributeOverride(name = "flag", column = @Column(name = "disclose_mode_flag")),
|
||||
@AttributeOverride(name = "voice.marked", column = @Column(name = "disclose_show_voice")),
|
||||
@AttributeOverride(name = "fax.marked", column = @Column(name = "disclose_show_fax")),
|
||||
@AttributeOverride(name = "email.marked", column = @Column(name = "disclose_show_email"))
|
||||
})
|
||||
Disclose disclose;
|
||||
|
||||
@Override
|
||||
public VKey<? extends ContactBase> createVKey() {
|
||||
throw new UnsupportedOperationException(
|
||||
"ContactBase is not an actual persisted entity you can create a key to;"
|
||||
+ " use Contact instead");
|
||||
}
|
||||
|
||||
public String getContactId() {
|
||||
return contactId;
|
||||
}
|
||||
|
||||
public PostalInfo getLocalizedPostalInfo() {
|
||||
return localizedPostalInfo;
|
||||
}
|
||||
|
||||
public PostalInfo getInternationalizedPostalInfo() {
|
||||
return internationalizedPostalInfo;
|
||||
}
|
||||
|
||||
public String getSearchName() {
|
||||
return searchName;
|
||||
}
|
||||
|
||||
public ContactPhoneNumber getVoiceNumber() {
|
||||
return voice;
|
||||
}
|
||||
|
||||
public ContactPhoneNumber getFaxNumber() {
|
||||
return fax;
|
||||
}
|
||||
|
||||
public String getEmailAddress() {
|
||||
return email;
|
||||
}
|
||||
|
||||
public ContactAuthInfo getAuthInfo() {
|
||||
return authInfo;
|
||||
}
|
||||
|
||||
public Disclose getDisclose() {
|
||||
return disclose;
|
||||
}
|
||||
|
||||
public String getCurrentSponsorRegistrarId() {
|
||||
return getPersistedCurrentSponsorRegistrarId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ContactTransferData getTransferData() {
|
||||
return Optional.ofNullable(transferData).orElse(ContactTransferData.EMPTY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DateTime getLastTransferTime() {
|
||||
return lastTransferTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getForeignKey() {
|
||||
return contactId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Postal info for the contact.
|
||||
*
|
||||
* <p>The XML marshalling expects the {@link PostalInfo} objects in a list, but we can't actually
|
||||
* persist them directly due to legacy reasons (Objectify can't handle collections of embedded
|
||||
* objects that themselves contain collections, and there's a list of streets inside). This method
|
||||
* transforms the persisted format to the XML format for marshalling.
|
||||
*/
|
||||
@XmlElement(name = "postalInfo")
|
||||
public ImmutableList<PostalInfo> getPostalInfosAsList() {
|
||||
return Stream.of(localizedPostalInfo, internationalizedPostalInfo)
|
||||
.filter(Objects::nonNull)
|
||||
.collect(toImmutableList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ContactBase cloneProjectedAtTime(DateTime now) {
|
||||
// Contacts no longer exist and thus do not need to be projected
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder<? extends ContactBase, ?> asBuilder() {
|
||||
return new Builder<>(clone(this));
|
||||
}
|
||||
|
||||
/** A builder for constructing {@link Contact}, since it is immutable. */
|
||||
public static class Builder<T extends ContactBase, B extends Builder<T, B>>
|
||||
extends EppResource.Builder<T, B> implements BuilderWithTransferData<ContactTransferData, B> {
|
||||
|
||||
public Builder() {}
|
||||
|
||||
protected Builder(T instance) {
|
||||
super(instance);
|
||||
}
|
||||
|
||||
public B setContactId(String contactId) {
|
||||
getInstance().contactId = contactId;
|
||||
return thisCastToDerived();
|
||||
}
|
||||
|
||||
public B setLocalizedPostalInfo(PostalInfo localizedPostalInfo) {
|
||||
checkArgument(
|
||||
localizedPostalInfo == null
|
||||
|| PostalInfo.Type.LOCALIZED.equals(localizedPostalInfo.getType()));
|
||||
getInstance().localizedPostalInfo = localizedPostalInfo;
|
||||
return thisCastToDerived();
|
||||
}
|
||||
|
||||
public B setInternationalizedPostalInfo(PostalInfo internationalizedPostalInfo) {
|
||||
checkArgument(
|
||||
internationalizedPostalInfo == null
|
||||
|| PostalInfo.Type.INTERNATIONALIZED.equals(internationalizedPostalInfo.getType()));
|
||||
getInstance().internationalizedPostalInfo = internationalizedPostalInfo;
|
||||
return thisCastToDerived();
|
||||
}
|
||||
|
||||
public B overlayLocalizedPostalInfo(PostalInfo localizedPostalInfo) {
|
||||
return setLocalizedPostalInfo(
|
||||
getInstance().localizedPostalInfo == null
|
||||
? localizedPostalInfo
|
||||
: getInstance().localizedPostalInfo.overlay(localizedPostalInfo));
|
||||
}
|
||||
|
||||
public B overlayInternationalizedPostalInfo(PostalInfo internationalizedPostalInfo) {
|
||||
return setInternationalizedPostalInfo(
|
||||
getInstance().internationalizedPostalInfo == null
|
||||
? internationalizedPostalInfo
|
||||
: getInstance().internationalizedPostalInfo.overlay(internationalizedPostalInfo));
|
||||
}
|
||||
|
||||
public B setVoiceNumber(ContactPhoneNumber voiceNumber) {
|
||||
if (voiceNumber != null && voiceNumber.hasNullFields()) {
|
||||
voiceNumber = null;
|
||||
}
|
||||
getInstance().voice = voiceNumber;
|
||||
return thisCastToDerived();
|
||||
}
|
||||
|
||||
public B setFaxNumber(ContactPhoneNumber faxNumber) {
|
||||
if (faxNumber != null && faxNumber.hasNullFields()) {
|
||||
faxNumber = null;
|
||||
}
|
||||
getInstance().fax = faxNumber;
|
||||
return thisCastToDerived();
|
||||
}
|
||||
|
||||
public B setEmailAddress(String emailAddress) {
|
||||
getInstance().email = emailAddress;
|
||||
return thisCastToDerived();
|
||||
}
|
||||
|
||||
public B setAuthInfo(ContactAuthInfo authInfo) {
|
||||
getInstance().authInfo = authInfo;
|
||||
return thisCastToDerived();
|
||||
}
|
||||
|
||||
public B setDisclose(Disclose disclose) {
|
||||
getInstance().disclose = disclose;
|
||||
return thisCastToDerived();
|
||||
}
|
||||
|
||||
@Override
|
||||
public B setTransferData(ContactTransferData transferData) {
|
||||
getInstance().transferData = transferData;
|
||||
return thisCastToDerived();
|
||||
}
|
||||
|
||||
@Override
|
||||
public B setLastTransferTime(DateTime lastTransferTime) {
|
||||
getInstance().lastTransferTime = lastTransferTime;
|
||||
return thisCastToDerived();
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all personally identifying information about a contact.
|
||||
*
|
||||
* <p>This should be used when deleting a contact so that the soft-deleted entity doesn't
|
||||
* contain information that the registrant requested to be deleted.
|
||||
*/
|
||||
public B wipeOut() {
|
||||
setEmailAddress(null);
|
||||
setFaxNumber(null);
|
||||
setInternationalizedPostalInfo(null);
|
||||
setLocalizedPostalInfo(null);
|
||||
setVoiceNumber(null);
|
||||
return thisCastToDerived();
|
||||
}
|
||||
|
||||
@Override
|
||||
public T build() {
|
||||
T instance = getInstance();
|
||||
// If TransferData is totally empty, set it to null.
|
||||
if (ContactTransferData.EMPTY.equals(instance.transferData)) {
|
||||
setTransferData(null);
|
||||
}
|
||||
// Set the searchName using the internationalized and localized postal info names.
|
||||
if ((instance.internationalizedPostalInfo != null)
|
||||
&& (instance.internationalizedPostalInfo.getName() != null)) {
|
||||
instance.searchName = instance.internationalizedPostalInfo.getName();
|
||||
} else if ((instance.localizedPostalInfo != null)
|
||||
&& (instance.localizedPostalInfo.getName() != null)) {
|
||||
instance.searchName = instance.localizedPostalInfo.getName();
|
||||
} else {
|
||||
instance.searchName = null;
|
||||
}
|
||||
return super.build();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -18,6 +18,7 @@ import static com.google.common.base.Preconditions.checkState;
|
||||
import static google.registry.util.CollectionUtils.nullToEmpty;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import google.registry.model.EppResource;
|
||||
import google.registry.model.ImmutableObject;
|
||||
import google.registry.model.contact.PostalInfo.Type;
|
||||
import google.registry.model.eppinput.ResourceCommand.AbstractSingleResourceCommand;
|
||||
@@ -34,13 +35,13 @@ import jakarta.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/** A collection of {@link Contact} commands. */
|
||||
/** A collection of (vestigial) Contact commands. */
|
||||
public class ContactCommand {
|
||||
|
||||
/** The fields on "chgType" from <a href="http://tools.ietf.org/html/rfc5733">RFC5733</a>. */
|
||||
@XmlTransient
|
||||
public static class ContactCreateOrChange extends ImmutableObject
|
||||
implements ResourceCreateOrChange<Contact.Builder> {
|
||||
implements ResourceCreateOrChange<EppResource.Builder<?, ?>> {
|
||||
|
||||
/** Postal info for the contact. */
|
||||
List<PostalInfo> postalInfo;
|
||||
@@ -111,13 +112,13 @@ public class ContactCommand {
|
||||
}
|
||||
|
||||
/**
|
||||
* A create command for a {@link Contact}, mapping "createType" from <a
|
||||
* A create command for a (vestigial) Contact, mapping "createType" from <a
|
||||
* href="http://tools.ietf.org/html/rfc5733">RFC5733</a>}.
|
||||
*/
|
||||
@XmlType(propOrder = {"contactId", "postalInfo", "voice", "fax", "email", "authInfo", "disclose"})
|
||||
@XmlRootElement
|
||||
public static class Create extends ContactCreateOrChange
|
||||
implements SingleResourceCommand, ResourceCreateOrChange<Contact.Builder> {
|
||||
implements SingleResourceCommand, ResourceCreateOrChange<EppResource.Builder<?, ?>> {
|
||||
/**
|
||||
* Unique identifier for this contact.
|
||||
*
|
||||
@@ -139,29 +140,29 @@ public class ContactCommand {
|
||||
}
|
||||
}
|
||||
|
||||
/** A delete command for a {@link Contact}. */
|
||||
/** A delete command for a (vestigial) Contact. */
|
||||
@XmlRootElement
|
||||
public static class Delete extends AbstractSingleResourceCommand {}
|
||||
|
||||
/** An info request for a {@link Contact}. */
|
||||
/** An info request for a (vestigial) Contact. */
|
||||
@XmlRootElement
|
||||
@XmlType(propOrder = {"targetId", "authInfo"})
|
||||
public static class Info extends AbstractContactAuthCommand {}
|
||||
|
||||
/** A check request for {@link Contact}. */
|
||||
/** A check request for (vestigial) Contact. */
|
||||
@XmlRootElement
|
||||
public static class Check extends ResourceCheck {}
|
||||
|
||||
/** A transfer operation for a {@link Contact}. */
|
||||
/** A transfer operation for a (vestigial) Contact. */
|
||||
@XmlRootElement
|
||||
@XmlType(propOrder = {"targetId", "authInfo"})
|
||||
public static class Transfer extends AbstractContactAuthCommand {}
|
||||
|
||||
/** An update to a {@link Contact}. */
|
||||
/** An update to a (vestigial) Contact. */
|
||||
@XmlRootElement
|
||||
@XmlType(propOrder = {"targetId", "innerAdd", "innerRemove", "innerChange"})
|
||||
public static class Update
|
||||
extends ResourceUpdate<Update.AddRemove, Contact.Builder, Update.Change> {
|
||||
extends ResourceUpdate<Update.AddRemove, EppResource.Builder<?, ?>, Update.Change> {
|
||||
|
||||
@XmlElement(name = "chg")
|
||||
protected Change innerChange;
|
||||
|
||||
@@ -1,102 +0,0 @@
|
||||
// Copyright 2020 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.contact;
|
||||
|
||||
import google.registry.model.EppResource;
|
||||
import google.registry.model.reporting.HistoryEntry;
|
||||
import google.registry.persistence.VKey;
|
||||
import jakarta.persistence.Access;
|
||||
import jakarta.persistence.AccessType;
|
||||
import jakarta.persistence.AttributeOverride;
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.Index;
|
||||
import jakarta.persistence.Table;
|
||||
import java.util.Optional;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* A persisted history entry representing an EPP modification to a contact.
|
||||
*
|
||||
* <p>In addition to the general history fields (e.g. action time, registrar ID) we also persist a
|
||||
* copy of the contact entity at this point in time. We persist a raw {@link ContactBase} so that
|
||||
* the foreign-keyed fields in that class can refer to this object.
|
||||
*/
|
||||
@Entity
|
||||
@Table(
|
||||
indexes = {
|
||||
@Index(columnList = "creationTime"),
|
||||
@Index(columnList = "historyRegistrarId"),
|
||||
@Index(columnList = "historyType"),
|
||||
@Index(columnList = "historyModificationTime")
|
||||
})
|
||||
@AttributeOverride(name = "repoId", column = @Column(name = "contactRepoId"))
|
||||
@Access(AccessType.FIELD)
|
||||
public class ContactHistory extends HistoryEntry {
|
||||
|
||||
// Store ContactBase instead of Contact, so we don't pick up its @Id
|
||||
// @Nullable for the sake of pre-Registry-3.0 history objects
|
||||
@Nullable ContactBase resource;
|
||||
|
||||
@Override
|
||||
protected ContactBase getResource() {
|
||||
return resource;
|
||||
}
|
||||
|
||||
/**
|
||||
* The values of all the fields on the {@link ContactBase} object after the action represented by
|
||||
* this history object was executed.
|
||||
*
|
||||
* <p>Will be absent for objects created prior to the Registry 3.0 SQL migration.
|
||||
*/
|
||||
public Optional<ContactBase> getContactBase() {
|
||||
return Optional.ofNullable(resource);
|
||||
}
|
||||
|
||||
/** Creates a {@link VKey} instance for this entity. */
|
||||
@Override
|
||||
public VKey<ContactHistory> createVKey() {
|
||||
return VKey.create(ContactHistory.class, getHistoryEntryId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<? extends EppResource> getResourceAtPointInTime() {
|
||||
return getContactBase().map(contactBase -> new Contact.Builder().copyFrom(contactBase).build());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder asBuilder() {
|
||||
return new Builder(clone(this));
|
||||
}
|
||||
|
||||
public static class Builder extends HistoryEntry.Builder<ContactHistory, ContactHistory.Builder> {
|
||||
|
||||
public Builder() {}
|
||||
|
||||
public Builder(ContactHistory instance) {
|
||||
super(instance);
|
||||
}
|
||||
|
||||
public Builder setContact(ContactBase contactBase) {
|
||||
getInstance().resource = contactBase;
|
||||
return setRepoId(contactBase);
|
||||
}
|
||||
|
||||
public Builder wipeOutPii() {
|
||||
getInstance().resource = getInstance().resource.asBuilder().wipeOut().build();
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -20,11 +20,9 @@ import jakarta.persistence.Embeddable;
|
||||
/**
|
||||
* EPP Contact Phone Number
|
||||
*
|
||||
* <p>This class is embedded inside a {@link Contact} hold the phone number of an EPP contact. The
|
||||
* fields are all defined in the parent class {@link PhoneNumber}, but the subclass is still
|
||||
* necessary to pick up the contact namespace.
|
||||
*
|
||||
* @see Contact
|
||||
* <p>This class is embedded inside a (vestigial) Contact to hold the phone number of an EPP
|
||||
* contact. The fields are all defined in the parent class {@link PhoneNumber}, but the subclass is
|
||||
* still necessary to pick up the contact namespace.
|
||||
*/
|
||||
@Embeddable
|
||||
public class ContactPhoneNumber extends PhoneNumber {
|
||||
|
||||
@@ -1,80 +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.PreconditionsUtils.checkArgumentNotNull;
|
||||
|
||||
import google.registry.model.ImmutableObject;
|
||||
import google.registry.model.UnsafeSerializable;
|
||||
import google.registry.model.contact.Contact;
|
||||
import google.registry.persistence.VKey;
|
||||
import jakarta.persistence.Embeddable;
|
||||
import jakarta.xml.bind.annotation.XmlEnumValue;
|
||||
|
||||
/**
|
||||
* Persisted type for storing a domain's contact associations.
|
||||
*
|
||||
* <p>A contact association on a domain consists of the contact key and the contact "type", which is
|
||||
* the designated role of this contact with respect to this domain. When converting to and from EPP
|
||||
* XML, we use {@link ForeignKeyedDesignatedContact} to replace the contact's primary key with its
|
||||
* foreign key, since that is what EPP exposes.
|
||||
*
|
||||
* <p>Note one could in principle store contact foreign keys here in addition to keys, unlike the
|
||||
* situation with hosts where client-side renames would make that data stale. However, we sometimes
|
||||
* rename contacts internally ourselves, and it's easier to use the same model for both cases.
|
||||
*
|
||||
* <p>This entity type is not persisted in Cloud SQL. The different roles are represented as
|
||||
* separate fields in the Domain table.
|
||||
*
|
||||
* @see <a href="http://tools.ietf.org/html/rfc5731#section-2.2">RFC 5731 - EPP Domain Name Mapping
|
||||
* - Contact and Client Identifiers</a>
|
||||
*/
|
||||
@Embeddable
|
||||
public class DesignatedContact extends ImmutableObject implements UnsafeSerializable {
|
||||
|
||||
/**
|
||||
* XML type for contact types. This can be either: {@code "admin"}, {@code "billing"}, or
|
||||
* {@code "tech"} and corresponds to {@code contactAttrType} in {@code domain-1.0.xsd}.
|
||||
*/
|
||||
public enum Type {
|
||||
@XmlEnumValue("admin")
|
||||
ADMIN,
|
||||
@XmlEnumValue("billing")
|
||||
BILLING,
|
||||
@XmlEnumValue("tech")
|
||||
TECH,
|
||||
/** The registrant type is not reflected in XML and exists only for internal use. */
|
||||
REGISTRANT
|
||||
}
|
||||
|
||||
public static DesignatedContact create(Type type, VKey<Contact> contact) {
|
||||
DesignatedContact instance = new DesignatedContact();
|
||||
instance.type = type;
|
||||
instance.contactVKey = checkArgumentNotNull(contact, "Must specify contact key");
|
||||
return instance;
|
||||
}
|
||||
|
||||
Type type;
|
||||
|
||||
VKey<Contact> contactVKey;
|
||||
|
||||
public Type getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public VKey<Contact> getContactKey() {
|
||||
return contactVKey;
|
||||
}
|
||||
}
|
||||
@@ -178,7 +178,6 @@ public class Domain extends DomainBase implements ForeignKeyedEppResource {
|
||||
.setAutorenewPollMessage(domainBase.getAutorenewPollMessage())
|
||||
.setAutorenewBillingEvent(domainBase.getAutorenewBillingEvent())
|
||||
.setAutorenewEndTime(domainBase.getAutorenewEndTime())
|
||||
.setContacts(domainBase.getContacts())
|
||||
.setCreationRegistrarId(domainBase.getCreationRegistrarId())
|
||||
.setCreationTime(domainBase.getCreationTime())
|
||||
.setDomainName(domainBase.getDomainName())
|
||||
@@ -193,7 +192,6 @@ public class Domain extends DomainBase implements ForeignKeyedEppResource {
|
||||
.setLastEppUpdateTime(domainBase.getLastEppUpdateTime())
|
||||
.setNameservers(domainBase.getNameservers())
|
||||
.setPersistedCurrentSponsorRegistrarId(domainBase.getPersistedCurrentSponsorRegistrarId())
|
||||
.setRegistrant(domainBase.getRegistrant())
|
||||
.setRegistrationExpirationTime(domainBase.getRegistrationExpirationTime())
|
||||
.setRepoId(domainBase.getRepoId())
|
||||
.setSmdId(domainBase.getSmdId())
|
||||
|
||||
@@ -45,8 +45,6 @@ import google.registry.flows.ResourceFlowUtils;
|
||||
import google.registry.model.EppResource;
|
||||
import google.registry.model.EppResource.ResourceWithTransferData;
|
||||
import google.registry.model.billing.BillingRecurrence;
|
||||
import google.registry.model.contact.Contact;
|
||||
import google.registry.model.domain.DesignatedContact.Type;
|
||||
import google.registry.model.domain.launch.LaunchNotice;
|
||||
import google.registry.model.domain.rgp.GracePeriodStatus;
|
||||
import google.registry.model.domain.secdns.DomainDsData;
|
||||
@@ -79,10 +77,8 @@ import jakarta.persistence.Id;
|
||||
import jakarta.persistence.MappedSuperclass;
|
||||
import jakarta.persistence.Transient;
|
||||
import java.util.HashSet;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.function.Predicate;
|
||||
import javax.annotation.Nullable;
|
||||
import org.hibernate.collection.spi.PersistentSet;
|
||||
import org.joda.time.DateTime;
|
||||
@@ -131,12 +127,12 @@ public class DomainBase extends EppResource
|
||||
/** References to hosts that are the nameservers for the domain. */
|
||||
@Expose @Transient Set<VKey<Host>> nsHosts;
|
||||
|
||||
/** Contacts. */
|
||||
@Expose @Nullable VKey<Contact> adminContact;
|
||||
/** Contacts keys are kept around for vestigial purposes for now. */
|
||||
@Expose @Nullable String adminContact;
|
||||
|
||||
@Expose @Nullable VKey<Contact> billingContact;
|
||||
@Expose @Nullable VKey<Contact> techContact;
|
||||
@Expose @Nullable VKey<Contact> registrantContact;
|
||||
@Expose @Nullable String billingContact;
|
||||
@Expose @Nullable String techContact;
|
||||
@Expose @Nullable String registrantContact;
|
||||
|
||||
/** Authorization info (aka transfer secret) of the domain. */
|
||||
@Embedded
|
||||
@@ -586,120 +582,21 @@ public class DomainBase extends EppResource
|
||||
.collect(toImmutableSortedSet(Ordering.natural())));
|
||||
}
|
||||
|
||||
/** A key to the registrant who registered this domain. */
|
||||
public Optional<VKey<Contact>> getRegistrant() {
|
||||
return Optional.ofNullable(registrantContact);
|
||||
}
|
||||
|
||||
public Optional<VKey<Contact>> getAdminContact() {
|
||||
return Optional.ofNullable(adminContact);
|
||||
}
|
||||
|
||||
public Optional<VKey<Contact>> getBillingContact() {
|
||||
return Optional.ofNullable(billingContact);
|
||||
}
|
||||
|
||||
public Optional<VKey<Contact>> getTechContact() {
|
||||
return Optional.ofNullable(techContact);
|
||||
}
|
||||
|
||||
/**
|
||||
* Associated contacts for the domain (other than registrant).
|
||||
*
|
||||
* <p>Note: This can be an empty set if no contacts are present for the domain.
|
||||
*/
|
||||
public ImmutableSet<DesignatedContact> getContacts() {
|
||||
return getAllContacts(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all associated contacts for the domain, including the registrant.
|
||||
*
|
||||
* <p>Note: This can be an empty set if no contacts are present for the domain.
|
||||
*/
|
||||
public ImmutableSet<DesignatedContact> getAllContacts() {
|
||||
return getAllContacts(true);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public DomainAuthInfo getAuthInfo() {
|
||||
return authInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all referenced contacts from this domain.
|
||||
*
|
||||
* <p>Note: This can be an empty set if no contacts are present for the domain.
|
||||
*/
|
||||
public ImmutableSet<VKey<Contact>> getReferencedContacts() {
|
||||
return nullToEmptyImmutableCopy(getAllContacts(true)).stream()
|
||||
.map(DesignatedContact::getContactKey)
|
||||
.filter(Objects::nonNull)
|
||||
.collect(toImmutableSet());
|
||||
}
|
||||
|
||||
private ImmutableSet<DesignatedContact> getAllContacts(boolean includeRegistrant) {
|
||||
ImmutableSet.Builder<DesignatedContact> builder = new ImmutableSet.Builder<>();
|
||||
if (includeRegistrant) {
|
||||
getRegistrant().ifPresent(c -> builder.add(DesignatedContact.create(Type.REGISTRANT, c)));
|
||||
}
|
||||
getAdminContact().ifPresent(c -> builder.add(DesignatedContact.create(Type.ADMIN, c)));
|
||||
getBillingContact().ifPresent(c -> builder.add(DesignatedContact.create(Type.BILLING, c)));
|
||||
getTechContact().ifPresent(c -> builder.add(DesignatedContact.create(Type.TECH, c)));
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
public String getTld() {
|
||||
return tld;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the individual contact fields from {@code contacts}.
|
||||
*
|
||||
* <p>The registrant field is only set if {@code includeRegistrant} is true, as this field needs
|
||||
* to be set in some circumstances but not in others.
|
||||
*/
|
||||
void setContactFields(Set<DesignatedContact> contacts, boolean includeRegistrant) {
|
||||
// Set the individual contact fields.
|
||||
billingContact = null;
|
||||
techContact = null;
|
||||
adminContact = null;
|
||||
if (includeRegistrant) {
|
||||
registrantContact = null;
|
||||
}
|
||||
HashSet<Type> contactsDiscovered = new HashSet<>();
|
||||
for (DesignatedContact contact : contacts) {
|
||||
checkArgument(
|
||||
!contactsDiscovered.contains(contact.getType()),
|
||||
"Duplicate contact type %s in designated contact set.",
|
||||
contact.getType());
|
||||
contactsDiscovered.add(contact.getType());
|
||||
switch (contact.getType()) {
|
||||
case BILLING -> billingContact = contact.getContactKey();
|
||||
case TECH -> techContact = contact.getContactKey();
|
||||
case ADMIN -> adminContact = contact.getContactKey();
|
||||
case REGISTRANT -> {
|
||||
if (includeRegistrant) {
|
||||
registrantContact = contact.getContactKey();
|
||||
}
|
||||
}
|
||||
default ->
|
||||
throw new IllegalArgumentException(
|
||||
"Unknown contact resource type: " + contact.getType());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public VKey<Domain> createVKey() {
|
||||
throw new UnsupportedOperationException(
|
||||
"DomainBase is not an actual persisted entity you can create a key to; use Domain instead");
|
||||
}
|
||||
|
||||
/** Predicate to determine if a given {@link DesignatedContact} is the registrant. */
|
||||
static final Predicate<DesignatedContact> IS_REGISTRANT =
|
||||
(DesignatedContact contact) -> Type.REGISTRANT.equals(contact.type);
|
||||
|
||||
/** An override of {@link EppResource#asBuilder} with tighter typing. */
|
||||
@Override
|
||||
public Builder<? extends DomainBase, ?> asBuilder() {
|
||||
@@ -764,12 +661,6 @@ public class DomainBase extends EppResource
|
||||
return thisCastToDerived();
|
||||
}
|
||||
|
||||
public B setRegistrant(Optional<VKey<Contact>> registrant) {
|
||||
// Set the registrant field specifically.
|
||||
getInstance().registrantContact = registrant.orElse(null);
|
||||
return thisCastToDerived();
|
||||
}
|
||||
|
||||
public B setAuthInfo(DomainAuthInfo authInfo) {
|
||||
getInstance().authInfo = authInfo;
|
||||
return thisCastToDerived();
|
||||
@@ -805,26 +696,6 @@ public class DomainBase extends EppResource
|
||||
ImmutableSet.copyOf(difference(getInstance().getNameservers(), nameservers)));
|
||||
}
|
||||
|
||||
public B setContacts(DesignatedContact contact) {
|
||||
return setContacts(ImmutableSet.of(contact));
|
||||
}
|
||||
|
||||
public B setContacts(ImmutableSet<DesignatedContact> contacts) {
|
||||
checkArgument(contacts.stream().noneMatch(IS_REGISTRANT), "Registrant cannot be a contact");
|
||||
|
||||
// Set the individual fields.
|
||||
getInstance().setContactFields(contacts, false);
|
||||
return thisCastToDerived();
|
||||
}
|
||||
|
||||
public B addContacts(ImmutableSet<DesignatedContact> contacts) {
|
||||
return setContacts(ImmutableSet.copyOf(Sets.union(getInstance().getContacts(), contacts)));
|
||||
}
|
||||
|
||||
public B removeContacts(ImmutableSet<DesignatedContact> contacts) {
|
||||
return setContacts(ImmutableSet.copyOf(difference(getInstance().getContacts(), contacts)));
|
||||
}
|
||||
|
||||
public B setLaunchNotice(LaunchNotice launchNotice) {
|
||||
getInstance().launchNotice = launchNotice;
|
||||
return thisCastToDerived();
|
||||
|
||||
@@ -30,7 +30,6 @@ import google.registry.flows.domain.DomainFlowUtils.RegistrantProhibitedExceptio
|
||||
import google.registry.flows.exceptions.ContactsProhibitedException;
|
||||
import google.registry.model.ForeignKeyUtils;
|
||||
import google.registry.model.ImmutableObject;
|
||||
import google.registry.model.contact.Contact;
|
||||
import google.registry.model.eppinput.ResourceCommand.AbstractSingleResourceCommand;
|
||||
import google.registry.model.eppinput.ResourceCommand.ResourceCheck;
|
||||
import google.registry.model.eppinput.ResourceCommand.ResourceCreateOrChange;
|
||||
@@ -79,9 +78,6 @@ public class DomainCommand {
|
||||
@Nullable
|
||||
String registrantContactId;
|
||||
|
||||
/** A resolved key to the registrant who registered this domain. */
|
||||
@Nullable @XmlTransient VKey<Contact> registrant;
|
||||
|
||||
/** Authorization info (aka transfer secret) of the domain. */
|
||||
DomainAuthInfo authInfo;
|
||||
|
||||
@@ -89,10 +85,6 @@ public class DomainCommand {
|
||||
return Optional.ofNullable(registrantContactId);
|
||||
}
|
||||
|
||||
public Optional<VKey<Contact>> getRegistrant() {
|
||||
return Optional.ofNullable(registrant);
|
||||
}
|
||||
|
||||
public DomainAuthInfo getAuthInfo() {
|
||||
return authInfo;
|
||||
}
|
||||
@@ -131,10 +123,6 @@ public class DomainCommand {
|
||||
@XmlElement(name = "contact")
|
||||
Set<ForeignKeyedDesignatedContact> foreignKeyedDesignatedContacts;
|
||||
|
||||
/** Resolved keys to associated contacts for the domain (other than registrant). */
|
||||
@XmlTransient
|
||||
Set<DesignatedContact> contacts;
|
||||
|
||||
/** The period that this domain's state was set to last for (e.g. 1-10 years). */
|
||||
Period period;
|
||||
|
||||
@@ -159,10 +147,6 @@ public class DomainCommand {
|
||||
return nullToEmptyImmutableCopy(nameservers);
|
||||
}
|
||||
|
||||
public ImmutableSet<DesignatedContact> getContacts() {
|
||||
return nullToEmptyImmutableCopy(contacts);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DomainAuthInfo getAuthInfo() {
|
||||
return authInfo;
|
||||
@@ -340,10 +324,6 @@ public class DomainCommand {
|
||||
@XmlElement(name = "contact")
|
||||
Set<ForeignKeyedDesignatedContact> foreignKeyedDesignatedContacts;
|
||||
|
||||
/** Resolved keys to associated contacts for the domain (other than registrant). */
|
||||
@XmlTransient
|
||||
Set<DesignatedContact> contacts;
|
||||
|
||||
public ImmutableSet<String> getNameserverHostNames() {
|
||||
return nullSafeImmutableCopy(nameserverHostNames);
|
||||
}
|
||||
@@ -352,10 +332,6 @@ public class DomainCommand {
|
||||
return nullToEmptyImmutableCopy(nameservers);
|
||||
}
|
||||
|
||||
public ImmutableSet<DesignatedContact> getContacts() {
|
||||
return nullToEmptyImmutableCopy(contacts);
|
||||
}
|
||||
|
||||
/** Creates a copy of this {@link AddRemove} with hard links to hosts and contacts. */
|
||||
private AddRemove cloneAndLinkReferences(DateTime now)
|
||||
throws InvalidReferencesException, ContactsProhibitedException {
|
||||
|
||||
@@ -16,27 +16,42 @@ package google.registry.model.domain;
|
||||
|
||||
import google.registry.model.ImmutableObject;
|
||||
import jakarta.xml.bind.annotation.XmlAttribute;
|
||||
import jakarta.xml.bind.annotation.XmlEnumValue;
|
||||
import jakarta.xml.bind.annotation.XmlValue;
|
||||
|
||||
/**
|
||||
* EPP-XML-serializable equivalent of {@link DesignatedContact}.
|
||||
* Vestigial EPP-XML-serializable equivalent of a contact.
|
||||
*
|
||||
* <p>This type is used on the wire for EPP XML, where only the contact ID (foreign key) is exposed.
|
||||
* This is converted to and from the persisted type, {@link DesignatedContact}, which stores the
|
||||
* primary key instead of the foreign key.
|
||||
* <p>This type was used on the wire for EPP XML, where only the contact ID (foreign key) was
|
||||
* exposed.
|
||||
*
|
||||
* @see <a href="http://tools.ietf.org/html/rfc5731#section-2.2">RFC 5731 - EPP Domain Name Mapping
|
||||
* - Contact and Client Identifiers</a>
|
||||
*/
|
||||
public class ForeignKeyedDesignatedContact extends ImmutableObject {
|
||||
|
||||
/**
|
||||
* XML type for contact types. This can be either: {@code "admin"}, {@code "billing"}, or {@code
|
||||
* "tech"} and corresponds to {@code contactAttrType} in {@code domain-1.0.xsd}.
|
||||
*/
|
||||
public enum Type {
|
||||
@XmlEnumValue("admin")
|
||||
ADMIN,
|
||||
@XmlEnumValue("billing")
|
||||
BILLING,
|
||||
@XmlEnumValue("tech")
|
||||
TECH,
|
||||
/** The registrant type is not reflected in XML and exists only for internal use. */
|
||||
REGISTRANT
|
||||
}
|
||||
|
||||
@XmlAttribute(required = true)
|
||||
DesignatedContact.Type type;
|
||||
Type type;
|
||||
|
||||
@XmlValue
|
||||
String contactId;
|
||||
|
||||
public static ForeignKeyedDesignatedContact create(
|
||||
DesignatedContact.Type type, String contactId) {
|
||||
public static ForeignKeyedDesignatedContact create(Type type, String contactId) {
|
||||
ForeignKeyedDesignatedContact instance = new ForeignKeyedDesignatedContact();
|
||||
instance.type = type;
|
||||
instance.contactId = contactId;
|
||||
|
||||
@@ -22,8 +22,6 @@ import com.google.common.collect.ImmutableSet;
|
||||
import google.registry.model.EppResource;
|
||||
import google.registry.model.adapters.EnumToAttributeAdapter.EppEnum;
|
||||
import google.registry.model.adapters.StatusValueAdapter;
|
||||
import google.registry.model.contact.Contact;
|
||||
import google.registry.model.contact.ContactBase;
|
||||
import google.registry.model.domain.Domain;
|
||||
import google.registry.model.domain.DomainBase;
|
||||
import google.registry.model.host.Host;
|
||||
@@ -130,8 +128,6 @@ public enum StatusValue implements EppEnum {
|
||||
/** Enum to help clearly list which resource types a status value is allowed to be present on. */
|
||||
private enum AllowedOn {
|
||||
ALL(
|
||||
Contact.class,
|
||||
ContactBase.class,
|
||||
Domain.class,
|
||||
DomainBase.class,
|
||||
Host.class,
|
||||
|
||||
@@ -27,7 +27,6 @@ import com.google.common.collect.ImmutableMap;
|
||||
import com.google.gson.annotations.Expose;
|
||||
import google.registry.model.EppResource;
|
||||
import google.registry.model.ImmutableObject;
|
||||
import google.registry.model.contact.Contact;
|
||||
import google.registry.model.domain.Domain;
|
||||
import google.registry.model.host.Host;
|
||||
import google.registry.util.SerializeUtils;
|
||||
@@ -51,7 +50,7 @@ public class VKey<T> extends ImmutableObject implements Serializable {
|
||||
private static final String DELIMITER = "@";
|
||||
|
||||
private static final ImmutableMap<String, Class<? extends EppResource>> EPP_RESOURCE_CLASS_MAP =
|
||||
ImmutableList.of(Domain.class, Host.class, Contact.class).stream()
|
||||
ImmutableList.of(Domain.class, Host.class).stream()
|
||||
.collect(toImmutableMap(Class::getSimpleName, identity()));
|
||||
|
||||
// The primary key for the referenced entity.
|
||||
|
||||
@@ -44,7 +44,6 @@ import google.registry.gcs.GcsUtils;
|
||||
import google.registry.keyring.api.KeyModule.Key;
|
||||
import google.registry.model.common.Cursor;
|
||||
import google.registry.model.common.Cursor.CursorType;
|
||||
import google.registry.model.contact.Contact;
|
||||
import google.registry.model.domain.Domain;
|
||||
import google.registry.model.host.Host;
|
||||
import google.registry.model.rde.RdeMode;
|
||||
@@ -80,8 +79,8 @@ import org.joda.time.Duration;
|
||||
* type and loads the embedded resource from it, which is then projected to watermark time to
|
||||
* account for things like pending transfer.
|
||||
*
|
||||
* <p>Only {@link Contact}s and {@link Host}s that are referenced by an included {@link Domain} will
|
||||
* be included in the corresponding pending deposit.
|
||||
* <p>Only {@link Host}s that are referenced by an included {@link Domain} will be included in the
|
||||
* corresponding pending deposit.
|
||||
*
|
||||
* <p>{@link Registrar} entities, both active and inactive, are included in all deposits. They are
|
||||
* not rewound point-in-time.
|
||||
|
||||
@@ -19,7 +19,6 @@ import static com.google.common.base.Preconditions.checkState;
|
||||
import com.google.common.base.Ascii;
|
||||
import google.registry.model.EppResource;
|
||||
import google.registry.model.ForeignKeyUtils;
|
||||
import google.registry.model.contact.Contact;
|
||||
import google.registry.model.domain.Domain;
|
||||
import google.registry.model.host.Host;
|
||||
import google.registry.persistence.VKey;
|
||||
@@ -30,7 +29,6 @@ class CommandUtilities {
|
||||
|
||||
/** A useful parameter enum for commands that operate on {@link EppResource} objects. */
|
||||
public enum ResourceType {
|
||||
CONTACT(Contact.class),
|
||||
HOST(Host.class),
|
||||
DOMAIN(Domain.class);
|
||||
|
||||
|
||||
@@ -51,8 +51,6 @@
|
||||
<class>google.registry.model.console.ConsoleUpdateHistory</class>
|
||||
<class>google.registry.model.console.PasswordResetRequest</class>
|
||||
<class>google.registry.model.console.User</class>
|
||||
<class>google.registry.model.contact.ContactHistory</class>
|
||||
<class>google.registry.model.contact.Contact</class>
|
||||
<class>google.registry.model.domain.Domain</class>
|
||||
<class>google.registry.model.domain.DomainHistory</class>
|
||||
<class>google.registry.model.domain.GracePeriod</class>
|
||||
@@ -94,7 +92,6 @@
|
||||
<class>google.registry.model.billing.VKeyConverter_BillingCancellation</class>
|
||||
<class>google.registry.model.billing.VKeyConverter_BillingEvent</class>
|
||||
<class>google.registry.model.billing.VKeyConverter_BillingRecurrence</class>
|
||||
<class>google.registry.model.contact.VKeyConverter_Contact</class>
|
||||
<class>google.registry.model.domain.VKeyConverter_Domain</class>
|
||||
<class>google.registry.model.domain.token.VKeyConverter_AllocationToken</class>
|
||||
<class>google.registry.model.host.VKeyConverter_Host</class>
|
||||
|
||||
@@ -185,7 +185,6 @@ public class RegistryJpaReadTest {
|
||||
StatusValue.SERVER_UPDATE_PROHIBITED,
|
||||
StatusValue.SERVER_RENEW_PROHIBITED,
|
||||
StatusValue.SERVER_HOLD))
|
||||
.setContacts(ImmutableSet.of())
|
||||
.setSubordinateHosts(ImmutableSet.of("ns1.example.com"))
|
||||
.setPersistedCurrentSponsorRegistrarId(registrar.getRegistrarId())
|
||||
.setRegistrationExpirationTime(fakeClock.nowUtc().plusYears(1))
|
||||
|
||||
@@ -81,7 +81,6 @@ import google.registry.testing.CloudTasksHelper.TaskMatcher;
|
||||
import google.registry.testing.FakeClock;
|
||||
import google.registry.testing.FakeKeyringModule;
|
||||
import java.io.IOException;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Function;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
@@ -239,8 +238,6 @@ public class RdePipelineTest {
|
||||
newDomain("hello.soy")
|
||||
.asBuilder()
|
||||
.addNameserver(host1.createVKey())
|
||||
.setRegistrant(Optional.empty())
|
||||
.setContacts(ImmutableSet.of())
|
||||
.build());
|
||||
persistDomainHistory(helloDomain);
|
||||
persistHostHistory(persistActiveHost("not-used-subordinate.hello.soy"));
|
||||
@@ -253,8 +250,6 @@ public class RdePipelineTest {
|
||||
newDomain("kitty.fun")
|
||||
.asBuilder()
|
||||
.addNameservers(ImmutableSet.of(host1.createVKey(), host2.createVKey()))
|
||||
.setRegistrant(Optional.empty())
|
||||
.setContacts(ImmutableSet.of())
|
||||
.build());
|
||||
persistDomainHistory(kittyDomain);
|
||||
// Should not appear because the TLD is not included in a pending deposit.
|
||||
|
||||
@@ -50,7 +50,6 @@ import static google.registry.testing.DatabaseHelper.getHistoryEntries;
|
||||
import static google.registry.testing.DatabaseHelper.loadAllOf;
|
||||
import static google.registry.testing.DatabaseHelper.loadRegistrar;
|
||||
import static google.registry.testing.DatabaseHelper.newHost;
|
||||
import static google.registry.testing.DatabaseHelper.persistActiveContact;
|
||||
import static google.registry.testing.DatabaseHelper.persistActiveDomain;
|
||||
import static google.registry.testing.DatabaseHelper.persistActiveHost;
|
||||
import static google.registry.testing.DatabaseHelper.persistReservedList;
|
||||
@@ -1869,7 +1868,6 @@ class DomainCreateFlowTest extends ResourceFlowTestCase<DomainCreateFlow, Domain
|
||||
|
||||
@Test
|
||||
void testFailure_minimumDataset_noRegistrantButSomeOtherContactTypes() throws Exception {
|
||||
persistActiveContact("sh8013");
|
||||
setEppInput("domain_create_other_contact_types.xml");
|
||||
persistHosts();
|
||||
EppException thrown = assertThrows(ContactsProhibitedException.class, this::runFlow);
|
||||
@@ -1878,7 +1876,6 @@ class DomainCreateFlowTest extends ResourceFlowTestCase<DomainCreateFlow, Domain
|
||||
|
||||
@Test
|
||||
void testFailure_minimumDataset_registrantNotPermitted() throws Exception {
|
||||
persistActiveContact("jd1234");
|
||||
setEppInput("domain_create_has_registrant_contact.xml");
|
||||
persistHosts();
|
||||
EppException thrown = assertThrows(RegistrantProhibitedException.class, this::runFlow);
|
||||
|
||||
@@ -73,7 +73,6 @@ import google.registry.persistence.VKey;
|
||||
import google.registry.persistence.transaction.JpaTransactionManagerExtension;
|
||||
import google.registry.testing.DatabaseHelper;
|
||||
import google.registry.xml.ValidationMode;
|
||||
import java.util.Optional;
|
||||
import java.util.regex.Pattern;
|
||||
import javax.annotation.Nullable;
|
||||
import org.joda.money.Money;
|
||||
@@ -214,23 +213,9 @@ class DomainInfoFlowTest extends ResourceFlowTestCase<DomainInfoFlow, Domain> {
|
||||
doSuccessfulTest("domain_info_response.xml");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_noRegistrant() throws Exception {
|
||||
persistTestEntities(false);
|
||||
domain = persistResource(domain.asBuilder().setRegistrant(Optional.empty()).build());
|
||||
doSuccessfulTest("domain_info_response_no_registrant.xml", false);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_noContacts() throws Exception {
|
||||
persistTestEntities(false);
|
||||
domain =
|
||||
persistResource(
|
||||
domain
|
||||
.asBuilder()
|
||||
.setRegistrant(Optional.empty())
|
||||
.setContacts(ImmutableSet.of())
|
||||
.build());
|
||||
doSuccessfulTest("domain_info_response_no_contacts.xml", false);
|
||||
}
|
||||
|
||||
|
||||
@@ -42,7 +42,6 @@ import static google.registry.testing.DatabaseHelper.createTld;
|
||||
import static google.registry.testing.DatabaseHelper.getOnlyHistoryEntryOfType;
|
||||
import static google.registry.testing.DatabaseHelper.getPollMessages;
|
||||
import static google.registry.testing.DatabaseHelper.loadRegistrar;
|
||||
import static google.registry.testing.DatabaseHelper.persistActiveContact;
|
||||
import static google.registry.testing.DatabaseHelper.persistActiveDomain;
|
||||
import static google.registry.testing.DatabaseHelper.persistActiveHost;
|
||||
import static google.registry.testing.DatabaseHelper.persistActiveSubordinateHost;
|
||||
@@ -272,7 +271,6 @@ class DomainUpdateFlowTest extends ResourceFlowTestCase<DomainUpdateFlow, Domain
|
||||
|
||||
@Test
|
||||
void testFailure_minimumDataset_whenAddingNewContacts() throws Exception {
|
||||
persistActiveContact("mak21");
|
||||
// This EPP adds a new technical contact mak21 that wasn't already present.
|
||||
setEppInput("domain_update_empty_registrant.xml");
|
||||
persistReferencedEntities();
|
||||
@@ -1375,13 +1373,8 @@ class DomainUpdateFlowTest extends ResourceFlowTestCase<DomainUpdateFlow, Domain
|
||||
|
||||
@Test
|
||||
void testFailure_minimumDataset_addingNewRegistrantFails() throws Exception {
|
||||
persistActiveContact("sh8013");
|
||||
persistReferencedEntities();
|
||||
persistResource(
|
||||
DatabaseHelper.newDomain(getUniqueIdFromCommand())
|
||||
.asBuilder()
|
||||
.setRegistrant(Optional.empty())
|
||||
.build());
|
||||
persistResource(DatabaseHelper.newDomain(getUniqueIdFromCommand()));
|
||||
// This EPP sets the registrant to sh8013, whereas in our test setup it is absent.
|
||||
setEppInput("domain_update_registrant.xml");
|
||||
RegistrantProhibitedException thrown =
|
||||
|
||||
@@ -1,227 +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.contact;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static google.registry.model.ImmutableObjectSubject.assertAboutImmutableObjects;
|
||||
import static google.registry.testing.DatabaseHelper.cloneAndSetAutoTimestamps;
|
||||
import static google.registry.testing.DatabaseHelper.createTld;
|
||||
import static google.registry.testing.DatabaseHelper.loadByEntity;
|
||||
import static google.registry.testing.DatabaseHelper.persistResource;
|
||||
import static google.registry.testing.SqlHelper.assertThrowForeignKeyViolation;
|
||||
import static google.registry.util.DateTimeUtils.END_OF_TIME;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import google.registry.model.EntityTestCase;
|
||||
import google.registry.model.ForeignKeyUtils;
|
||||
import google.registry.model.contact.Disclose.PostalInfoChoice;
|
||||
import google.registry.model.contact.PostalInfo.Type;
|
||||
import google.registry.model.eppcommon.AuthInfo.PasswordAuth;
|
||||
import google.registry.model.eppcommon.PresenceMarker;
|
||||
import google.registry.model.eppcommon.StatusValue;
|
||||
import google.registry.model.eppcommon.Trid;
|
||||
import google.registry.model.transfer.ContactTransferData;
|
||||
import google.registry.model.transfer.TransferStatus;
|
||||
import google.registry.util.SerializeUtils;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/** Unit tests for {@link Contact}. */
|
||||
public class ContactTest extends EntityTestCase {
|
||||
|
||||
private Contact originalContact;
|
||||
private Contact contact;
|
||||
|
||||
ContactTest() {
|
||||
super(JpaEntityCoverageCheck.ENABLED);
|
||||
}
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
createTld("foobar");
|
||||
originalContact =
|
||||
new Contact.Builder()
|
||||
.setContactId("contact_id")
|
||||
.setRepoId("1-FOOBAR")
|
||||
.setCreationRegistrarId("TheRegistrar")
|
||||
.setLastEppUpdateTime(fakeClock.nowUtc())
|
||||
.setLastEppUpdateRegistrarId("NewRegistrar")
|
||||
.setLastTransferTime(fakeClock.nowUtc())
|
||||
.setPersistedCurrentSponsorRegistrarId("NewRegistrar")
|
||||
.setLocalizedPostalInfo(
|
||||
new PostalInfo.Builder()
|
||||
.setType(Type.LOCALIZED)
|
||||
.setAddress(
|
||||
new ContactAddress.Builder()
|
||||
.setStreet(ImmutableList.of("111 8th Ave", "4th Floor"))
|
||||
.setCity("New York")
|
||||
.setState("NY")
|
||||
.setZip("10011")
|
||||
.setCountryCode("US")
|
||||
.build())
|
||||
.build())
|
||||
.setInternationalizedPostalInfo(
|
||||
new PostalInfo.Builder()
|
||||
.setType(Type.INTERNATIONALIZED)
|
||||
.setAddress(
|
||||
new ContactAddress.Builder()
|
||||
.setStreet(ImmutableList.of("111 8th Ave", "4th Floor"))
|
||||
.setCity("New York")
|
||||
.setState("NY")
|
||||
.setZip("10011")
|
||||
.setCountryCode("US")
|
||||
.build())
|
||||
.build())
|
||||
.setVoiceNumber(new ContactPhoneNumber.Builder().setPhoneNumber("867-5309").build())
|
||||
.setFaxNumber(
|
||||
new ContactPhoneNumber.Builder()
|
||||
.setPhoneNumber("867-5309")
|
||||
.setExtension("1000")
|
||||
.build())
|
||||
.setEmailAddress("jenny@example.com")
|
||||
.setAuthInfo(ContactAuthInfo.create(PasswordAuth.create("passw0rd")))
|
||||
.setDisclose(
|
||||
new Disclose.Builder()
|
||||
.setVoice(new PresenceMarker())
|
||||
.setEmail(new PresenceMarker())
|
||||
.setFax(new PresenceMarker())
|
||||
.setFlag(true)
|
||||
.setAddrs(ImmutableList.of(PostalInfoChoice.create(Type.INTERNATIONALIZED)))
|
||||
.setNames(ImmutableList.of(PostalInfoChoice.create(Type.INTERNATIONALIZED)))
|
||||
.setOrgs(ImmutableList.of(PostalInfoChoice.create(Type.INTERNATIONALIZED)))
|
||||
.build())
|
||||
.setStatusValues(ImmutableSet.of(StatusValue.OK))
|
||||
.setTransferData(
|
||||
new ContactTransferData.Builder()
|
||||
.setGainingRegistrarId("TheRegistrar")
|
||||
.setLosingRegistrarId("NewRegistrar")
|
||||
.setPendingTransferExpirationTime(fakeClock.nowUtc())
|
||||
.setTransferRequestTime(fakeClock.nowUtc())
|
||||
.setTransferStatus(TransferStatus.SERVER_APPROVED)
|
||||
.setTransferRequestTrid(Trid.create("client-trid", "server-trid"))
|
||||
.build())
|
||||
.build();
|
||||
// Set up a new persisted Contact entity.
|
||||
contact = persistResource(cloneAndSetAutoTimestamps(originalContact));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testContactBaseToContact() {
|
||||
assertAboutImmutableObjects()
|
||||
.that(new Contact.Builder().copyFrom(contact).build())
|
||||
.isEqualExceptFields(contact, "updateTimestamp", "revisions");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCloudSqlPersistence_failWhenViolateForeignKeyConstraint() {
|
||||
assertThrowForeignKeyViolation(
|
||||
() ->
|
||||
persistResource(
|
||||
originalContact
|
||||
.asBuilder()
|
||||
.setRepoId("2-FOOBAR")
|
||||
.setCreationRegistrarId("nonexistent-registrar")
|
||||
.build()));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCloudSqlPersistence_succeed() {
|
||||
Contact persisted = loadByEntity(originalContact);
|
||||
Contact fixed =
|
||||
originalContact
|
||||
.asBuilder()
|
||||
.setCreationTime(persisted.getCreationTime())
|
||||
.setTransferData(
|
||||
originalContact
|
||||
.getTransferData()
|
||||
.asBuilder()
|
||||
.setServerApproveEntities(null, null, null)
|
||||
.build())
|
||||
.build();
|
||||
assertAboutImmutableObjects().that(persisted).isEqualExceptFields(fixed, "updateTimestamp");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testPersistence() {
|
||||
assertThat(
|
||||
ForeignKeyUtils.loadResource(
|
||||
Contact.class, contact.getForeignKey(), fakeClock.nowUtc()))
|
||||
.hasValue(contact);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSerializable() {
|
||||
Contact persisted =
|
||||
ForeignKeyUtils.loadResource(Contact.class, contact.getForeignKey(), fakeClock.nowUtc())
|
||||
.get();
|
||||
assertThat(SerializeUtils.serializeDeserialize(persisted)).isEqualTo(persisted);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testEmptyStringsBecomeNull() {
|
||||
assertThat(new Contact.Builder().setContactId(null).build().getContactId()).isNull();
|
||||
assertThat(new Contact.Builder().setContactId("").build().getContactId()).isNull();
|
||||
assertThat(new Contact.Builder().setContactId(" ").build().getContactId()).isNotNull();
|
||||
// Nested ImmutableObjects should also be fixed
|
||||
assertThat(
|
||||
new Contact.Builder()
|
||||
.setInternationalizedPostalInfo(
|
||||
new PostalInfo.Builder().setType(Type.INTERNATIONALIZED).setName(null).build())
|
||||
.build()
|
||||
.getInternationalizedPostalInfo()
|
||||
.getName())
|
||||
.isNull();
|
||||
assertThat(
|
||||
new Contact.Builder()
|
||||
.setInternationalizedPostalInfo(
|
||||
new PostalInfo.Builder().setType(Type.INTERNATIONALIZED).setName("").build())
|
||||
.build()
|
||||
.getInternationalizedPostalInfo()
|
||||
.getName())
|
||||
.isNull();
|
||||
assertThat(
|
||||
new Contact.Builder()
|
||||
.setInternationalizedPostalInfo(
|
||||
new PostalInfo.Builder().setType(Type.INTERNATIONALIZED).setName(" ").build())
|
||||
.build()
|
||||
.getInternationalizedPostalInfo()
|
||||
.getName())
|
||||
.isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testEmptyTransferDataBecomesNull() {
|
||||
Contact withNull = new Contact.Builder().setTransferData(null).build();
|
||||
Contact withEmpty = withNull.asBuilder().setTransferData(ContactTransferData.EMPTY).build();
|
||||
assertThat(withNull).isEqualTo(withEmpty);
|
||||
assertThat(withEmpty.transferData).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSetCreationTime_cantBeCalledTwice() {
|
||||
IllegalStateException thrown =
|
||||
assertThrows(
|
||||
IllegalStateException.class, () -> contact.asBuilder().setCreationTime(END_OF_TIME));
|
||||
assertThat(thrown).hasMessageThat().contains("creationTime can only be set once");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testToHydratedString_notCircular() {
|
||||
// If there are circular references, this will overflow the stack.
|
||||
contact.toHydratedString();
|
||||
}
|
||||
}
|
||||
@@ -236,17 +236,6 @@ public class DomainTest {
|
||||
.hasValue(domain);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testRegistrantNotRequired() {
|
||||
persistResource(domain.asBuilder().setRegistrant(Optional.empty()).build());
|
||||
String foreignKey = domain.getForeignKey();
|
||||
assertThat(
|
||||
ForeignKeyUtils.loadResource(Domain.class, foreignKey, fakeClock.nowUtc())
|
||||
.get()
|
||||
.getRegistrant())
|
||||
.isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testEmptyStringsBecomeNull() {
|
||||
assertThat(
|
||||
|
||||
@@ -19,7 +19,6 @@ import static google.registry.model.eppcommon.EppXmlTransformer.unmarshal;
|
||||
import static google.registry.testing.TestDataHelper.loadBytes;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
import google.registry.model.contact.ContactTest;
|
||||
import google.registry.model.domain.DomainTest;
|
||||
import google.registry.model.eppinput.EppInput.InnerCommand;
|
||||
import google.registry.model.eppinput.EppInput.Login;
|
||||
@@ -29,17 +28,6 @@ import org.junit.jupiter.api.Test;
|
||||
/** Unit tests for {@link EppInput}. */
|
||||
class EppInputTest {
|
||||
|
||||
@Test
|
||||
void testUnmarshalling_contactInfo() throws Exception {
|
||||
EppInput input =
|
||||
unmarshal(EppInput.class, loadBytes(ContactTest.class, "contact_info.xml").read());
|
||||
assertThat(input.getCommandWrapper().getClTrid()).hasValue("ABC-12345");
|
||||
assertThat(input.getCommandType()).isEqualTo("info");
|
||||
assertThat(input.getResourceType()).hasValue("contact");
|
||||
assertThat(input.getSingleTargetId()).hasValue("sh8013");
|
||||
assertThat(input.getTargetIds()).containsExactly("sh8013");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testUnmarshalling_domainCheck() throws Exception {
|
||||
EppInput input =
|
||||
|
||||
@@ -1,145 +0,0 @@
|
||||
// Copyright 2020 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.history;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static google.registry.model.ImmutableObjectSubject.assertAboutImmutableObjects;
|
||||
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
|
||||
import static google.registry.testing.DatabaseHelper.loadByEntity;
|
||||
import static google.registry.testing.DatabaseHelper.newContactWithRoid;
|
||||
import static google.registry.testing.DatabaseHelper.persistResource;
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import google.registry.model.EntityTestCase;
|
||||
import google.registry.model.contact.Contact;
|
||||
import google.registry.model.contact.ContactAddress;
|
||||
import google.registry.model.contact.ContactBase;
|
||||
import google.registry.model.contact.ContactHistory;
|
||||
import google.registry.model.contact.ContactPhoneNumber;
|
||||
import google.registry.model.contact.PostalInfo;
|
||||
import google.registry.model.eppcommon.Trid;
|
||||
import google.registry.model.reporting.HistoryEntry;
|
||||
import google.registry.util.SerializeUtils;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/** Tests for {@link ContactHistory}. */
|
||||
public class ContactHistoryTest extends EntityTestCase {
|
||||
|
||||
ContactHistoryTest() {
|
||||
super(JpaEntityCoverageCheck.ENABLED);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testPersistence() {
|
||||
Contact contact = newContactWithRoid("contactId", "contact1");
|
||||
persistResource(contact);
|
||||
Contact contactFromDb = loadByEntity(contact);
|
||||
ContactHistory contactHistory = createContactHistory(contactFromDb);
|
||||
persistResource(contactHistory);
|
||||
tm().transact(
|
||||
() -> {
|
||||
ContactHistory fromDatabase = tm().loadByKey(contactHistory.createVKey());
|
||||
assertContactHistoriesEqual(fromDatabase, contactHistory);
|
||||
assertThat(fromDatabase.getRepoId()).isEqualTo(contactHistory.getRepoId());
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSerializable() {
|
||||
Contact contact = newContactWithRoid("contactId", "contact1");
|
||||
persistResource(contact);
|
||||
Contact contactFromDb = loadByEntity(contact);
|
||||
ContactHistory contactHistory = createContactHistory(contactFromDb);
|
||||
persistResource(contactHistory);
|
||||
ContactHistory fromDatabase = tm().transact(() -> tm().loadByKey(contactHistory.createVKey()));
|
||||
assertThat(SerializeUtils.serializeDeserialize(fromDatabase)).isEqualTo(fromDatabase);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testWipeOutPii_assertsAllPiiFieldsAreNull() {
|
||||
ContactHistory originalEntity =
|
||||
createContactHistory(
|
||||
new Contact.Builder()
|
||||
.setRepoId("1-FOOBAR")
|
||||
.setLocalizedPostalInfo(
|
||||
new PostalInfo.Builder()
|
||||
.setType(PostalInfo.Type.LOCALIZED)
|
||||
.setAddress(
|
||||
new ContactAddress.Builder()
|
||||
.setStreet(ImmutableList.of("111 8th Ave", "4th Floor"))
|
||||
.setCity("New York")
|
||||
.setState("NY")
|
||||
.setZip("10011")
|
||||
.setCountryCode("US")
|
||||
.build())
|
||||
.build())
|
||||
.setInternationalizedPostalInfo(
|
||||
new PostalInfo.Builder()
|
||||
.setType(PostalInfo.Type.INTERNATIONALIZED)
|
||||
.setAddress(
|
||||
new ContactAddress.Builder()
|
||||
.setStreet(ImmutableList.of("111 8th Ave", "4th Floor"))
|
||||
.setCity("New York")
|
||||
.setState("NY")
|
||||
.setZip("10011")
|
||||
.setCountryCode("US")
|
||||
.build())
|
||||
.build())
|
||||
.setVoiceNumber(new ContactPhoneNumber.Builder().setPhoneNumber("867-5309").build())
|
||||
.setFaxNumber(
|
||||
new ContactPhoneNumber.Builder()
|
||||
.setPhoneNumber("867-5309")
|
||||
.setExtension("1000")
|
||||
.build())
|
||||
.setEmailAddress("test@example.com")
|
||||
.build());
|
||||
|
||||
assertThat(originalEntity.getContactBase().get().getEmailAddress()).isNotNull();
|
||||
assertThat(originalEntity.getContactBase().get().getLocalizedPostalInfo()).isNotNull();
|
||||
assertThat(originalEntity.getContactBase().get().getInternationalizedPostalInfo()).isNotNull();
|
||||
assertThat(originalEntity.getContactBase().get().getVoiceNumber()).isNotNull();
|
||||
assertThat(originalEntity.getContactBase().get().getFaxNumber()).isNotNull();
|
||||
|
||||
ContactHistory wipedEntity = originalEntity.asBuilder().wipeOutPii().build();
|
||||
|
||||
assertThat(wipedEntity.getContactBase().get().getEmailAddress()).isNull();
|
||||
assertThat(wipedEntity.getContactBase().get().getLocalizedPostalInfo()).isNull();
|
||||
assertThat(wipedEntity.getContactBase().get().getInternationalizedPostalInfo()).isNull();
|
||||
assertThat(wipedEntity.getContactBase().get().getVoiceNumber()).isNull();
|
||||
assertThat(wipedEntity.getContactBase().get().getFaxNumber()).isNull();
|
||||
}
|
||||
|
||||
private ContactHistory createContactHistory(ContactBase contact) {
|
||||
return new ContactHistory.Builder()
|
||||
.setType(HistoryEntry.Type.HOST_CREATE)
|
||||
.setXmlBytes("<xml></xml>".getBytes(UTF_8))
|
||||
.setModificationTime(fakeClock.nowUtc())
|
||||
.setRegistrarId("TheRegistrar")
|
||||
.setTrid(Trid.create("ABC-123", "server-trid"))
|
||||
.setBySuperuser(false)
|
||||
.setReason("reason")
|
||||
.setRequestedByRegistrar(true)
|
||||
.setContact(contact)
|
||||
.build();
|
||||
}
|
||||
|
||||
static void assertContactHistoriesEqual(ContactHistory one, ContactHistory two) {
|
||||
assertAboutImmutableObjects().that(one).isEqualExceptFields(two, "resource");
|
||||
assertAboutImmutableObjects()
|
||||
.that(one.getContactBase().get())
|
||||
.isEqualExceptFields(two.getContactBase().get());
|
||||
}
|
||||
}
|
||||
@@ -14,11 +14,9 @@
|
||||
|
||||
package google.registry.rde;
|
||||
|
||||
import static com.google.common.collect.ImmutableSet.toImmutableSet;
|
||||
import static com.google.common.io.BaseEncoding.base16;
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static com.google.common.truth.Truth.assertWithMessage;
|
||||
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
|
||||
import static google.registry.testing.DatabaseHelper.createTld;
|
||||
import static google.registry.testing.DatabaseHelper.persistEppResource;
|
||||
import static google.registry.testing.DatabaseHelper.persistResource;
|
||||
@@ -34,7 +32,6 @@ import google.registry.model.billing.BillingBase.Flag;
|
||||
import google.registry.model.billing.BillingBase.Reason;
|
||||
import google.registry.model.billing.BillingEvent;
|
||||
import google.registry.model.billing.BillingRecurrence;
|
||||
import google.registry.model.domain.DesignatedContact;
|
||||
import google.registry.model.domain.Domain;
|
||||
import google.registry.model.domain.DomainAuthInfo;
|
||||
import google.registry.model.domain.DomainHistory;
|
||||
@@ -198,12 +195,6 @@ public class DomainToXjcConverterTest {
|
||||
@Test
|
||||
void testConvertAbsentContacts() throws XmlException {
|
||||
Domain domain = makeDomain(clock);
|
||||
tm().transact(
|
||||
() ->
|
||||
tm().delete(
|
||||
domain.getAllContacts().stream()
|
||||
.map(DesignatedContact::getContactKey)
|
||||
.collect(toImmutableSet())));
|
||||
XjcRdeDomain bean = DomainToXjcConverter.convertDomain(domain, RdeMode.FULL);
|
||||
assertThat(bean.getRegistrant()).isNull();
|
||||
assertThat(bean.getContacts()).isEmpty();
|
||||
|
||||
@@ -27,11 +27,9 @@ import google.registry.model.common.FeatureFlagTest;
|
||||
import google.registry.model.console.ConsoleUpdateHistoryTest;
|
||||
import google.registry.model.console.PasswordResetRequestTest;
|
||||
import google.registry.model.console.UserTest;
|
||||
import google.registry.model.contact.ContactTest;
|
||||
import google.registry.model.domain.DomainSqlTest;
|
||||
import google.registry.model.domain.token.AllocationTokenTest;
|
||||
import google.registry.model.domain.token.BulkPricingPackageTest;
|
||||
import google.registry.model.history.ContactHistoryTest;
|
||||
import google.registry.model.history.DomainHistoryTest;
|
||||
import google.registry.model.history.HostHistoryTest;
|
||||
import google.registry.model.poll.PollMessageTest;
|
||||
@@ -96,8 +94,6 @@ import org.junit.runner.RunWith;
|
||||
BulkPricingPackageTest.class,
|
||||
ClaimsListDaoTest.class,
|
||||
ConsoleUpdateHistoryTest.class,
|
||||
ContactHistoryTest.class,
|
||||
ContactTest.class,
|
||||
CursorTest.class,
|
||||
DnsRefreshRequestTest.class,
|
||||
DomainSqlTest.class,
|
||||
|
||||
@@ -73,8 +73,6 @@ import google.registry.model.common.DnsRefreshRequest;
|
||||
import google.registry.model.console.GlobalRole;
|
||||
import google.registry.model.console.User;
|
||||
import google.registry.model.console.UserRoles;
|
||||
import google.registry.model.contact.Contact;
|
||||
import google.registry.model.contact.ContactAuthInfo;
|
||||
import google.registry.model.domain.Domain;
|
||||
import google.registry.model.domain.DomainAuthInfo;
|
||||
import google.registry.model.domain.DomainBase;
|
||||
@@ -182,17 +180,6 @@ public final class DatabaseHelper {
|
||||
.build();
|
||||
}
|
||||
|
||||
public static Contact newContactWithRoid(String contactId, String repoId) {
|
||||
return new Contact.Builder()
|
||||
.setRepoId(repoId)
|
||||
.setContactId(contactId)
|
||||
.setCreationRegistrarId("TheRegistrar")
|
||||
.setPersistedCurrentSponsorRegistrarId("TheRegistrar")
|
||||
.setAuthInfo(ContactAuthInfo.create(PasswordAuth.create("2fooBAR")))
|
||||
.setCreationTimeForTest(START_OF_TIME)
|
||||
.build();
|
||||
}
|
||||
|
||||
public static Tld newTld(String tld, String roidSuffix) {
|
||||
return newTld(tld, roidSuffix, ImmutableSortedMap.of(START_OF_TIME, GENERAL_AVAILABILITY));
|
||||
}
|
||||
@@ -232,10 +219,6 @@ public final class DatabaseHelper {
|
||||
.build();
|
||||
}
|
||||
|
||||
public static Contact persistActiveContact(String contactId) {
|
||||
return persistResource(newContactWithRoid(contactId, generateNewHostRoid()));
|
||||
}
|
||||
|
||||
public static Host persistActiveHost(String hostName) {
|
||||
return persistResource(newHost(hostName));
|
||||
}
|
||||
@@ -1019,11 +1002,7 @@ public final class DatabaseHelper {
|
||||
}
|
||||
|
||||
private static HistoryEntry.Type getHistoryEntryType(EppResource resource) {
|
||||
if (resource instanceof Contact) {
|
||||
return resource.getRepoId() != null
|
||||
? HistoryEntry.Type.CONTACT_CREATE
|
||||
: HistoryEntry.Type.CONTACT_UPDATE;
|
||||
} else if (resource instanceof Host) {
|
||||
if (resource instanceof Host) {
|
||||
return resource.getRepoId() != null
|
||||
? HistoryEntry.Type.HOST_CREATE
|
||||
: HistoryEntry.Type.HOST_UPDATE;
|
||||
|
||||
@@ -261,7 +261,7 @@ td.section {
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="property_name">generated on</td>
|
||||
<td class="property_value">2026-01-01 02:43:24</td>
|
||||
<td class="property_value">2026-02-20 05:51:31</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="property_name">last flyway file</td>
|
||||
@@ -273,7 +273,7 @@ td.section {
|
||||
<p> </p>
|
||||
<svg viewBox="0.00 0.00 4846.00 3765.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" id="erDiagram" style="overflow: hidden; width: 100%; height: 800px">
|
||||
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 3761)">
|
||||
<title>SchemaCrawler_Diagram</title> <polygon fill="white" stroke="transparent" points="-4,4 -4,-3761 4842,-3761 4842,4 -4,4" /> <text text-anchor="start" x="4598" y="-29.8" font-family="Helvetica,sans-Serif" font-size="14.00">generated by</text> <text text-anchor="start" x="4681" y="-29.8" font-family="Helvetica,sans-Serif" font-size="14.00">SchemaCrawler 16.27.1</text> <text text-anchor="start" x="4597" y="-10.8" font-family="Helvetica,sans-Serif" font-size="14.00">generated on</text> <text text-anchor="start" x="4681" y="-10.8" font-family="Helvetica,sans-Serif" font-size="14.00">2026-01-01 02:43:24</text> <polygon fill="none" stroke="#888888" points="4594,-4 4594,-44 4830,-44 4830,-4 4594,-4" /> <!-- allocationtoken_a08ccbef -->
|
||||
<title>SchemaCrawler_Diagram</title> <polygon fill="white" stroke="transparent" points="-4,4 -4,-3761 4842,-3761 4842,4 -4,4" /> <text text-anchor="start" x="4598" y="-29.8" font-family="Helvetica,sans-Serif" font-size="14.00">generated by</text> <text text-anchor="start" x="4681" y="-29.8" font-family="Helvetica,sans-Serif" font-size="14.00">SchemaCrawler 16.27.1</text> <text text-anchor="start" x="4597" y="-10.8" font-family="Helvetica,sans-Serif" font-size="14.00">generated on</text> <text text-anchor="start" x="4681" y="-10.8" font-family="Helvetica,sans-Serif" font-size="14.00">2026-02-20 05:51:31</text> <polygon fill="none" stroke="#888888" points="4594,-4 4594,-44 4830,-44 4830,-4 4594,-4" /> <!-- allocationtoken_a08ccbef -->
|
||||
<g id="node1" class="node">
|
||||
<title>allocationtoken_a08ccbef</title> <polygon fill="#e9c2f2" stroke="transparent" points="525.5,-1272 525.5,-1291 711.5,-1291 711.5,-1272 525.5,-1272" /> <text text-anchor="start" x="527.5" y="-1278.8" font-family="Helvetica,sans-Serif" font-weight="bold" font-style="italic" font-size="14.00">public."AllocationToken"</text> <polygon fill="#e9c2f2" stroke="transparent" points="711.5,-1272 711.5,-1291 785.5,-1291 785.5,-1272 711.5,-1272" /> <text text-anchor="start" x="746.5" y="-1277.8" font-family="Helvetica,sans-Serif" font-size="14.00">[table]</text> <text text-anchor="start" x="527.5" y="-1259.8" font-family="Helvetica,sans-Serif" font-weight="bold" font-style="italic" font-size="14.00">token</text> <text text-anchor="start" x="705.5" y="-1258.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text> <text text-anchor="start" x="713.5" y="-1258.8" font-family="Helvetica,sans-Serif" font-size="14.00">text not null</text> <text text-anchor="start" x="527.5" y="-1239.8" font-family="Helvetica,sans-Serif" font-size="14.00">domain_name</text> <text text-anchor="start" x="705.5" y="-1239.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text> <text text-anchor="start" x="713.5" y="-1239.8" font-family="Helvetica,sans-Serif" font-size="14.00">text</text> <text text-anchor="start" x="527.5" y="-1220.8" font-family="Helvetica,sans-Serif" font-size="14.00">redemption_domain_repo_id</text> <text text-anchor="start" x="705.5" y="-1220.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text> <text text-anchor="start" x="713.5" y="-1220.8" font-family="Helvetica,sans-Serif" font-size="14.00">text</text> <text text-anchor="start" x="527.5" y="-1201.8" font-family="Helvetica,sans-Serif" font-size="14.00">token_type</text> <text text-anchor="start" x="705.5" y="-1201.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text> <text text-anchor="start" x="713.5" y="-1201.8" font-family="Helvetica,sans-Serif" font-size="14.00">text</text> <polygon fill="none" stroke="#888888" points="524.5,-1195.5 524.5,-1292.5 786.5,-1292.5 786.5,-1195.5 524.5,-1195.5" />
|
||||
</g>
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -145,140 +145,6 @@
|
||||
primary key (revision_id)
|
||||
);
|
||||
|
||||
create table "Contact" (
|
||||
repo_id text not null,
|
||||
update_timestamp timestamp(6) with time zone,
|
||||
creation_registrar_id text,
|
||||
creation_time timestamp(6) with time zone,
|
||||
current_sponsor_registrar_id text,
|
||||
deletion_time timestamp(6) with time zone,
|
||||
last_epp_update_registrar_id text,
|
||||
last_epp_update_time timestamp(6) with time zone,
|
||||
statuses text[],
|
||||
auth_info_repo_id text,
|
||||
auth_info_value text,
|
||||
contact_id text,
|
||||
disclose_types_addr text[],
|
||||
disclose_show_email boolean,
|
||||
disclose_show_fax boolean,
|
||||
disclose_mode_flag boolean,
|
||||
disclose_types_name text[],
|
||||
disclose_types_org text[],
|
||||
disclose_show_voice boolean,
|
||||
email text,
|
||||
fax_phone_extension text,
|
||||
fax_phone_number text,
|
||||
addr_i18n_city text,
|
||||
addr_i18n_country_code text,
|
||||
addr_i18n_state text,
|
||||
addr_i18n_street_line1 text,
|
||||
addr_i18n_street_line2 text,
|
||||
addr_i18n_street_line3 text,
|
||||
addr_i18n_zip text,
|
||||
addr_i18n_name text,
|
||||
addr_i18n_org text,
|
||||
addr_i18n_type text check (addr_i18n_type in ('LOCALIZED','INTERNATIONALIZED')),
|
||||
last_transfer_time timestamp(6) with time zone,
|
||||
addr_local_city text,
|
||||
addr_local_country_code text,
|
||||
addr_local_state text,
|
||||
addr_local_street_line1 text,
|
||||
addr_local_street_line2 text,
|
||||
addr_local_street_line3 text,
|
||||
addr_local_zip text,
|
||||
addr_local_name text,
|
||||
addr_local_org text,
|
||||
addr_local_type text check (addr_local_type in ('LOCALIZED','INTERNATIONALIZED')),
|
||||
search_name text,
|
||||
transfer_history_entry_id bigint,
|
||||
transfer_poll_message_id_1 bigint,
|
||||
transfer_poll_message_id_2 bigint,
|
||||
transfer_poll_message_id_3 bigint,
|
||||
transfer_repo_id text,
|
||||
transfer_client_txn_id text,
|
||||
transfer_server_txn_id text,
|
||||
transfer_gaining_registrar_id text,
|
||||
transfer_losing_registrar_id text,
|
||||
transfer_pending_expiration_time timestamp(6) with time zone,
|
||||
transfer_request_time timestamp(6) with time zone,
|
||||
transfer_status text check (transfer_status in ('CLIENT_APPROVED','CLIENT_CANCELLED','CLIENT_REJECTED','PENDING','SERVER_APPROVED','SERVER_CANCELLED')),
|
||||
voice_phone_extension text,
|
||||
voice_phone_number text,
|
||||
primary key (repo_id)
|
||||
);
|
||||
|
||||
create table "ContactHistory" (
|
||||
contact_repo_id text not null,
|
||||
history_revision_id bigint not null,
|
||||
history_by_superuser boolean not null,
|
||||
history_registrar_id text,
|
||||
history_modification_time timestamp(6) with time zone not null,
|
||||
history_reason text,
|
||||
history_requested_by_registrar boolean,
|
||||
history_client_transaction_id text,
|
||||
history_server_transaction_id text,
|
||||
history_type text not null check (history_type in ('CONTACT_CREATE','CONTACT_DELETE','CONTACT_DELETE_FAILURE','CONTACT_PENDING_DELETE','CONTACT_TRANSFER_APPROVE','CONTACT_TRANSFER_CANCEL','CONTACT_TRANSFER_REJECT','CONTACT_TRANSFER_REQUEST','CONTACT_UPDATE','DOMAIN_ALLOCATE','DOMAIN_AUTORENEW','DOMAIN_CREATE','DOMAIN_DELETE','DOMAIN_RENEW','DOMAIN_RESTORE','DOMAIN_TRANSFER_APPROVE','DOMAIN_TRANSFER_CANCEL','DOMAIN_TRANSFER_REJECT','DOMAIN_TRANSFER_REQUEST','DOMAIN_UPDATE','HOST_CREATE','HOST_DELETE','HOST_DELETE_FAILURE','HOST_PENDING_DELETE','HOST_UPDATE','RDE_IMPORT','SYNTHETIC')),
|
||||
history_xml_bytes bytea,
|
||||
auth_info_repo_id text,
|
||||
auth_info_value text,
|
||||
contact_id text,
|
||||
disclose_types_addr text[],
|
||||
disclose_show_email boolean,
|
||||
disclose_show_fax boolean,
|
||||
disclose_mode_flag boolean,
|
||||
disclose_types_name text[],
|
||||
disclose_types_org text[],
|
||||
disclose_show_voice boolean,
|
||||
email text,
|
||||
fax_phone_extension text,
|
||||
fax_phone_number text,
|
||||
addr_i18n_city text,
|
||||
addr_i18n_country_code text,
|
||||
addr_i18n_state text,
|
||||
addr_i18n_street_line1 text,
|
||||
addr_i18n_street_line2 text,
|
||||
addr_i18n_street_line3 text,
|
||||
addr_i18n_zip text,
|
||||
addr_i18n_name text,
|
||||
addr_i18n_org text,
|
||||
addr_i18n_type text check (addr_i18n_type in ('LOCALIZED','INTERNATIONALIZED')),
|
||||
last_transfer_time timestamp(6) with time zone,
|
||||
addr_local_city text,
|
||||
addr_local_country_code text,
|
||||
addr_local_state text,
|
||||
addr_local_street_line1 text,
|
||||
addr_local_street_line2 text,
|
||||
addr_local_street_line3 text,
|
||||
addr_local_zip text,
|
||||
addr_local_name text,
|
||||
addr_local_org text,
|
||||
addr_local_type text check (addr_local_type in ('LOCALIZED','INTERNATIONALIZED')),
|
||||
search_name text,
|
||||
transfer_history_entry_id bigint,
|
||||
transfer_poll_message_id_1 bigint,
|
||||
transfer_poll_message_id_2 bigint,
|
||||
transfer_poll_message_id_3 bigint,
|
||||
transfer_repo_id text,
|
||||
transfer_client_txn_id text,
|
||||
transfer_server_txn_id text,
|
||||
transfer_gaining_registrar_id text,
|
||||
transfer_losing_registrar_id text,
|
||||
transfer_pending_expiration_time timestamp(6) with time zone,
|
||||
transfer_request_time timestamp(6) with time zone,
|
||||
transfer_status text check (transfer_status in ('CLIENT_APPROVED','CLIENT_CANCELLED','CLIENT_REJECTED','PENDING','SERVER_APPROVED','SERVER_CANCELLED')),
|
||||
voice_phone_extension text,
|
||||
voice_phone_number text,
|
||||
creation_registrar_id text,
|
||||
creation_time timestamp(6) with time zone,
|
||||
current_sponsor_registrar_id text,
|
||||
deletion_time timestamp(6) with time zone,
|
||||
last_epp_update_registrar_id text,
|
||||
last_epp_update_time timestamp(6) with time zone,
|
||||
statuses text[],
|
||||
update_timestamp timestamp(6) with time zone,
|
||||
primary key (contact_repo_id, history_revision_id)
|
||||
);
|
||||
|
||||
create table "Cursor" (
|
||||
scope text not null,
|
||||
type text not null check (type in ('BRDA','RDE_REPORT','RDE_STAGING','RDE_UPLOAD','RDE_UPLOAD_SFTP','RECURRING_BILLING','SYNC_REGISTRAR_SHEET','ICANN_UPLOAD_TX','ICANN_UPLOAD_ACTIVITY')),
|
||||
@@ -915,33 +781,6 @@
|
||||
create index idx_console_update_history_modification_time
|
||||
on "ConsoleUpdateHistory" (modification_time);
|
||||
|
||||
create index IDX3y752kr9uh4kh6uig54vemx0l
|
||||
on "Contact" (creation_time);
|
||||
|
||||
create index IDXtm415d6fe1rr35stm33s5mg18
|
||||
on "Contact" (current_sponsor_registrar_id);
|
||||
|
||||
create index IDXn1f711wicdnooa2mqb7g1m55o
|
||||
on "Contact" (deletion_time);
|
||||
|
||||
create index IDXoqd7n4hbx86hvlgkilq75olas
|
||||
on "Contact" (contact_id);
|
||||
|
||||
create index IDX1p3esngcwwu6hstyua6itn6ff
|
||||
on "Contact" (search_name);
|
||||
|
||||
create index IDXo1xdtpij2yryh0skxe9v91sep
|
||||
on "ContactHistory" (creation_time);
|
||||
|
||||
create index IDXhp33wybmb6tbpr1bq7ttwk8je
|
||||
on "ContactHistory" (history_registrar_id);
|
||||
|
||||
create index IDX9q53px6r302ftgisqifmc6put
|
||||
on "ContactHistory" (history_type);
|
||||
|
||||
create index IDXsudwswtwqnfnx2o1hx4s0k0g5
|
||||
on "ContactHistory" (history_modification_time);
|
||||
|
||||
create index IDXhlqqd5uy98cjyos72d81x9j95
|
||||
on "DelegationSignerData" (domain_repo_id);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user