mirror of
https://github.com/google/nomulus
synced 2026-05-23 16:21:55 +00:00
Compare commits
5 Commits
nomulus-20
...
nomulus-20
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9eddecf70f | ||
|
|
d4bcff0c31 | ||
|
|
62065f88fb | ||
|
|
c9ac9437fd | ||
|
|
1f6a09182d |
@@ -24,7 +24,7 @@ export type contactType =
|
||||
| 'LEGAL'
|
||||
| 'MARKETING'
|
||||
| 'TECH'
|
||||
| 'RDAP';
|
||||
| 'WHOIS';
|
||||
|
||||
type contactTypesToUserFriendlyTypes = { [type in contactType]: string };
|
||||
|
||||
@@ -35,7 +35,7 @@ export const contactTypeToTextMap: contactTypesToUserFriendlyTypes = {
|
||||
LEGAL: 'Legal contact',
|
||||
MARKETING: 'Marketing contact',
|
||||
TECH: 'Technical contact',
|
||||
RDAP: 'RDAP-Inquiry contact',
|
||||
WHOIS: 'RDAP-Inquiry contact',
|
||||
};
|
||||
|
||||
type UserFriendlyType = (typeof contactTypeToTextMap)[contactType];
|
||||
@@ -59,7 +59,10 @@ export interface ViewReadyContact extends Contact {
|
||||
export function contactTypeToViewReadyContact(c: Contact): ViewReadyContact {
|
||||
return {
|
||||
...c,
|
||||
userFriendlyTypes: c.types?.map((cType) => contactTypeToTextMap[cType]),
|
||||
userFriendlyTypes: (c.types || []).map(
|
||||
(cType) => contactTypeToTextMap[cType]
|
||||
),
|
||||
types: c.types || [],
|
||||
};
|
||||
}
|
||||
|
||||
@@ -98,19 +101,21 @@ export class ContactService {
|
||||
);
|
||||
}
|
||||
|
||||
saveContacts(contacts: ViewReadyContact[]): Observable<Contact[]> {
|
||||
updateContact(contact: ViewReadyContact) {
|
||||
return this.backend
|
||||
.postContacts(this.registrarService.registrarId(), contacts)
|
||||
.updateContact(this.registrarService.registrarId(), contact)
|
||||
.pipe(switchMap((_) => this.fetchContacts()));
|
||||
}
|
||||
|
||||
addContact(contact: ViewReadyContact) {
|
||||
const newContacts = this.contacts().concat([contact]);
|
||||
return this.saveContacts(newContacts);
|
||||
return this.backend
|
||||
.createContact(this.registrarService.registrarId(), contact)
|
||||
.pipe(switchMap((_) => this.fetchContacts()));
|
||||
}
|
||||
|
||||
deleteContact(contact: ViewReadyContact) {
|
||||
const newContacts = this.contacts().filter((c) => c !== contact);
|
||||
return this.saveContacts(newContacts);
|
||||
return this.backend
|
||||
.deleteContact(this.registrarService.registrarId(), contact)
|
||||
.pipe(switchMap((_) => this.fetchContacts()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,9 +69,13 @@ export class ContactDetailsComponent {
|
||||
|
||||
save(e: SubmitEvent) {
|
||||
e.preventDefault();
|
||||
if ((this.contactService.contactInEdit.types || []).length === 0) {
|
||||
this._snackBar.open('Required to select contact type');
|
||||
return;
|
||||
}
|
||||
const request = this.contactService.isContactNewView
|
||||
? this.contactService.addContact(this.contactService.contactInEdit)
|
||||
: this.contactService.saveContacts(this.contactService.contacts());
|
||||
: this.contactService.updateContact(this.contactService.contactInEdit);
|
||||
request.subscribe({
|
||||
complete: () => {
|
||||
this.goBack();
|
||||
|
||||
@@ -70,13 +70,26 @@ export class BackendService {
|
||||
.pipe(catchError((err) => this.errorCatcher<Contact[]>(err)));
|
||||
}
|
||||
|
||||
postContacts(
|
||||
registrarId: string,
|
||||
contacts: Contact[]
|
||||
): Observable<Contact[]> {
|
||||
return this.http.post<Contact[]>(
|
||||
updateContact(registrarId: string, contact: Contact): Observable<Contact> {
|
||||
return this.http.put<Contact>(
|
||||
`/console-api/settings/contacts?registrarId=${registrarId}`,
|
||||
contacts
|
||||
contact
|
||||
);
|
||||
}
|
||||
|
||||
createContact(registrarId: string, contact: Contact): Observable<Contact> {
|
||||
return this.http.post<Contact>(
|
||||
`/console-api/settings/contacts?registrarId=${registrarId}`,
|
||||
contact
|
||||
);
|
||||
}
|
||||
|
||||
deleteContact(registrarId: string, contact: Contact): Observable<Contact> {
|
||||
return this.http.delete<Contact>(
|
||||
`/console-api/settings/contacts?registrarId=${registrarId}`,
|
||||
{
|
||||
body: JSON.stringify(contact),
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -185,7 +185,8 @@ public class CheckApiAction implements Runnable {
|
||||
}
|
||||
|
||||
private boolean checkExists(String domainString, DateTime now) {
|
||||
return !ForeignKeyUtils.loadCached(Domain.class, ImmutableList.of(domainString), now).isEmpty();
|
||||
return !ForeignKeyUtils.loadByCache(Domain.class, ImmutableList.of(domainString), now)
|
||||
.isEmpty();
|
||||
}
|
||||
|
||||
private Optional<String> checkReserved(InternetDomainName domainName) {
|
||||
|
||||
@@ -432,7 +432,7 @@ public final class DomainCheckFlow implements TransactionalFlow {
|
||||
.filter(existingDomains::containsKey)
|
||||
.collect(toImmutableMap(d -> d, existingDomains::get));
|
||||
ImmutableMap<VKey<? extends EppResource>, EppResource> loadedDomains =
|
||||
EppResource.loadCached(ImmutableList.copyOf(existingDomainsToLoad.values()));
|
||||
EppResource.loadByCacheIfEnabled(ImmutableList.copyOf(existingDomainsToLoad.values()));
|
||||
return ImmutableMap.copyOf(
|
||||
Maps.transformEntries(existingDomainsToLoad, (k, v) -> (Domain) loadedDomains.get(v)));
|
||||
}
|
||||
|
||||
@@ -417,7 +417,7 @@ public class DomainFlowUtils {
|
||||
contacts.stream().map(DesignatedContact::getContactKey).forEach(keysToLoad::add);
|
||||
registrant.ifPresent(keysToLoad::add);
|
||||
keysToLoad.addAll(nameservers);
|
||||
verifyNotInPendingDelete(EppResource.loadCached(keysToLoad.build()).values());
|
||||
verifyNotInPendingDelete(EppResource.loadByCacheIfEnabled(keysToLoad.build()).values());
|
||||
}
|
||||
|
||||
private static void verifyNotInPendingDelete(Iterable<EppResource> resources)
|
||||
|
||||
@@ -404,7 +404,7 @@ public abstract class EppResource extends UpdateAutoTimestampEntity implements B
|
||||
* <p>Don't use this unless you really need it for performance reasons, and be sure that you are
|
||||
* OK with the trade-offs in loss of transactional consistency.
|
||||
*/
|
||||
public static ImmutableMap<VKey<? extends EppResource>, EppResource> loadCached(
|
||||
public static ImmutableMap<VKey<? extends EppResource>, EppResource> loadByCacheIfEnabled(
|
||||
Iterable<VKey<? extends EppResource>> keys) {
|
||||
if (!RegistryConfig.isEppResourceCachingEnabled()) {
|
||||
return tm().reTransact(() -> tm().loadByKeys(keys));
|
||||
@@ -413,15 +413,12 @@ public abstract class EppResource extends UpdateAutoTimestampEntity implements B
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads a given EppResource by its key using the cache (if enabled).
|
||||
* Loads a given EppResource by its key using the cache.
|
||||
*
|
||||
* <p>Don't use this unless you really need it for performance reasons, and be sure that you are
|
||||
* OK with the trade-offs in loss of transactional consistency.
|
||||
* <p>This method ignores the `isEppResourceCachingEnabled` config setting. It is reserved for use
|
||||
* cases that can tolerate slightly stale data, e.g., RDAP queries.
|
||||
*/
|
||||
public static <T extends EppResource> T loadCached(VKey<T> key) {
|
||||
if (!RegistryConfig.isEppResourceCachingEnabled()) {
|
||||
return tm().reTransact(() -> tm().loadByKey(key));
|
||||
}
|
||||
public static <T extends EppResource> T loadByCache(VKey<T> key) {
|
||||
// Safe to cast because loading a Key<T> returns an entity of type T.
|
||||
@SuppressWarnings("unchecked")
|
||||
T resource = (T) cacheEppResources.get(key);
|
||||
|
||||
@@ -16,6 +16,7 @@ package google.registry.model;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.collect.ImmutableSet.toImmutableSet;
|
||||
import static google.registry.persistence.transaction.TransactionManagerFactory.replicaTm;
|
||||
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
|
||||
import static google.registry.util.DateTimeUtils.START_OF_TIME;
|
||||
import static google.registry.util.DateTimeUtils.isAtOrAfter;
|
||||
@@ -40,6 +41,7 @@ import google.registry.model.transfer.DomainTransferData;
|
||||
import google.registry.model.transfer.TransferData;
|
||||
import google.registry.model.transfer.TransferStatus;
|
||||
import google.registry.persistence.VKey;
|
||||
import google.registry.persistence.transaction.TransactionManager;
|
||||
import jakarta.persistence.Query;
|
||||
import java.util.Collection;
|
||||
import java.util.Comparator;
|
||||
@@ -109,12 +111,12 @@ public final class EppResourceUtils {
|
||||
*/
|
||||
public static <T extends EppResource> Optional<T> loadByForeignKey(
|
||||
Class<T> clazz, String foreignKey, DateTime now) {
|
||||
return loadByForeignKeyHelper(clazz, foreignKey, now, false);
|
||||
return loadByForeignKeyHelper(tm(), clazz, foreignKey, now, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the last created version of an {@link EppResource} from the database by foreign key,
|
||||
* using a cache.
|
||||
* using a cache, if caching is enabled in config settings.
|
||||
*
|
||||
* <p>Returns null if no resource with this foreign key was ever created, or if the most recently
|
||||
* created resource was deleted before time "now".
|
||||
@@ -134,20 +136,36 @@ public final class EppResourceUtils {
|
||||
* @param foreignKey id to match
|
||||
* @param now the current logical time to project resources at
|
||||
*/
|
||||
public static <T extends EppResource> Optional<T> loadByForeignKeyCached(
|
||||
public static <T extends EppResource> Optional<T> loadByForeignKeyByCacheIfEnabled(
|
||||
Class<T> clazz, String foreignKey, DateTime now) {
|
||||
return loadByForeignKeyHelper(
|
||||
clazz, foreignKey, now, RegistryConfig.isEppResourceCachingEnabled());
|
||||
tm(), clazz, foreignKey, now, RegistryConfig.isEppResourceCachingEnabled());
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the last created version of an {@link EppResource} from the replica database by foreign
|
||||
* key, using a cache.
|
||||
*
|
||||
* <p>This method ignores the config setting for caching, and is reserved for use cases that can
|
||||
* tolerate slightly stale data.
|
||||
*/
|
||||
public static <T extends EppResource> Optional<T> loadByForeignKeyByCache(
|
||||
Class<T> clazz, String foreignKey, DateTime now) {
|
||||
return loadByForeignKeyHelper(replicaTm(), clazz, foreignKey, now, true);
|
||||
}
|
||||
|
||||
private static <T extends EppResource> Optional<T> loadByForeignKeyHelper(
|
||||
Class<T> clazz, String foreignKey, DateTime now, boolean useCache) {
|
||||
TransactionManager txnManager,
|
||||
Class<T> clazz,
|
||||
String foreignKey,
|
||||
DateTime now,
|
||||
boolean useCache) {
|
||||
checkArgument(
|
||||
ForeignKeyedEppResource.class.isAssignableFrom(clazz),
|
||||
"loadByForeignKey may only be called for foreign keyed EPP resources");
|
||||
VKey<T> key =
|
||||
useCache
|
||||
? ForeignKeyUtils.loadCached(clazz, ImmutableList.of(foreignKey), now).get(foreignKey)
|
||||
? ForeignKeyUtils.loadByCache(clazz, ImmutableList.of(foreignKey), now).get(foreignKey)
|
||||
: ForeignKeyUtils.load(clazz, foreignKey, now);
|
||||
// The returned key is null if the resource is hard deleted or soft deleted by the given time.
|
||||
if (key == null) {
|
||||
@@ -155,10 +173,10 @@ public final class EppResourceUtils {
|
||||
}
|
||||
T resource =
|
||||
useCache
|
||||
? EppResource.loadCached(key)
|
||||
? EppResource.loadByCache(key)
|
||||
// This transaction is buried very deeply inside many outer nested calls, hence merits
|
||||
// the use of reTransact() for now pending a substantial refactoring.
|
||||
: tm().reTransact(() -> tm().loadByKeyIfPresent(key).orElse(null));
|
||||
: txnManager.reTransact(() -> txnManager.loadByKeyIfPresent(key).orElse(null));
|
||||
if (resource == null || isAtOrAfter(now, resource.getDeletionTime())) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
@@ -204,11 +204,25 @@ public final class ForeignKeyUtils {
|
||||
* <p>Don't use the cached version of this method unless you really need it for performance
|
||||
* reasons, and are OK with the trade-offs in loss of transactional consistency.
|
||||
*/
|
||||
public static <E extends EppResource> ImmutableMap<String, VKey<E>> loadCached(
|
||||
public static <E extends EppResource> ImmutableMap<String, VKey<E>> loadByCacheIfEnabled(
|
||||
Class<E> clazz, Collection<String> foreignKeys, final DateTime now) {
|
||||
if (!RegistryConfig.isEppResourceCachingEnabled()) {
|
||||
return load(clazz, foreignKeys, now);
|
||||
}
|
||||
return loadByCache(clazz, foreignKeys, now);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a list of {@link VKey} to {@link EppResource} instances by class and foreign key strings
|
||||
* that are active at or after the specified moment in time, using the cache.
|
||||
*
|
||||
* <p>The returned map will omit any keys for which the {@link EppResource} doesn't exist or has
|
||||
* been soft-deleted.
|
||||
*
|
||||
* <p>This method is reserved for use cases that can tolerate slightly stale data.
|
||||
*/
|
||||
public static <E extends EppResource> ImmutableMap<String, VKey<E>> loadByCache(
|
||||
Class<E> clazz, Collection<String> foreignKeys, final DateTime now) {
|
||||
return foreignKeyCache
|
||||
.getAll(foreignKeys.stream().map(fk -> VKey.create(clazz, fk)).collect(toImmutableList()))
|
||||
.entrySet()
|
||||
|
||||
@@ -0,0 +1,150 @@
|
||||
// Copyright 2025 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.console;
|
||||
|
||||
import static google.registry.util.PreconditionsUtils.checkArgumentNotNull;
|
||||
|
||||
import google.registry.model.Buildable;
|
||||
import google.registry.model.CreateAutoTimestamp;
|
||||
import google.registry.model.ImmutableObject;
|
||||
import google.registry.persistence.WithVKey;
|
||||
import jakarta.persistence.AttributeOverride;
|
||||
import jakarta.persistence.AttributeOverrides;
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.EnumType;
|
||||
import jakarta.persistence.Enumerated;
|
||||
import jakarta.persistence.Id;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import org.joda.time.DateTime;
|
||||
|
||||
/**
|
||||
* Represents a password reset request of some type.
|
||||
*
|
||||
* <p>Password reset requests must be performed within an hour of the time that they were requested,
|
||||
* as well as requiring that the requester and the fulfiller have the proper respective permissions.
|
||||
*/
|
||||
@Entity
|
||||
@WithVKey(String.class)
|
||||
public class PasswordResetRequest extends ImmutableObject implements Buildable {
|
||||
|
||||
public enum Type {
|
||||
EPP,
|
||||
REGISTRY_LOCK
|
||||
}
|
||||
|
||||
@Id private String verificationCode;
|
||||
|
||||
@Column(nullable = false)
|
||||
@Enumerated(EnumType.STRING)
|
||||
Type type;
|
||||
|
||||
@AttributeOverrides({
|
||||
@AttributeOverride(
|
||||
name = "creationTime",
|
||||
column = @Column(name = "requestTime", nullable = false))
|
||||
})
|
||||
CreateAutoTimestamp requestTime = CreateAutoTimestamp.create(null);
|
||||
|
||||
@Column(nullable = false)
|
||||
String requester;
|
||||
|
||||
@Column DateTime fulfillmentTime;
|
||||
|
||||
@Column(nullable = false)
|
||||
String destinationEmail;
|
||||
|
||||
@Column(nullable = false)
|
||||
String registrarId;
|
||||
|
||||
public String getVerificationCode() {
|
||||
return verificationCode;
|
||||
}
|
||||
|
||||
public Type getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public DateTime getRequestTime() {
|
||||
return requestTime.getTimestamp();
|
||||
}
|
||||
|
||||
public String getRequester() {
|
||||
return requester;
|
||||
}
|
||||
|
||||
public Optional<DateTime> getFulfillmentTime() {
|
||||
return Optional.ofNullable(fulfillmentTime);
|
||||
}
|
||||
|
||||
public String getDestinationEmail() {
|
||||
return destinationEmail;
|
||||
}
|
||||
|
||||
public String getRegistrarId() {
|
||||
return registrarId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder asBuilder() {
|
||||
return new Builder(clone(this));
|
||||
}
|
||||
|
||||
/** Builder for constructing immutable {@link PasswordResetRequest} objects. */
|
||||
public static class Builder extends Buildable.Builder<PasswordResetRequest> {
|
||||
|
||||
public Builder() {}
|
||||
|
||||
private Builder(PasswordResetRequest instance) {
|
||||
super(instance);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PasswordResetRequest build() {
|
||||
checkArgumentNotNull(getInstance().type, "Type must be specified");
|
||||
checkArgumentNotNull(getInstance().requester, "Requester must be specified");
|
||||
checkArgumentNotNull(getInstance().destinationEmail, "Destination email must be specified");
|
||||
checkArgumentNotNull(getInstance().registrarId, "Registrar ID must be specified");
|
||||
getInstance().verificationCode = UUID.randomUUID().toString();
|
||||
return super.build();
|
||||
}
|
||||
|
||||
public Builder setType(Type type) {
|
||||
getInstance().type = type;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setRequester(String requester) {
|
||||
getInstance().requester = requester;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setDestinationEmail(String destinationEmail) {
|
||||
getInstance().destinationEmail = destinationEmail;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setRegistrarId(String registrarId) {
|
||||
getInstance().registrarId = registrarId;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setFulfillmentTime(DateTime fulfillmentTime) {
|
||||
getInstance().fulfillmentTime = fulfillmentTime;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -441,7 +441,8 @@ public class DomainCommand {
|
||||
private static <T extends EppResource> ImmutableMap<String, VKey<T>> loadByForeignKeysCached(
|
||||
final Set<String> foreignKeys, final Class<T> clazz, final DateTime now)
|
||||
throws InvalidReferencesException {
|
||||
ImmutableMap<String, VKey<T>> fks = ForeignKeyUtils.loadCached(clazz, foreignKeys, now);
|
||||
ImmutableMap<String, VKey<T>> fks =
|
||||
ForeignKeyUtils.loadByCacheIfEnabled(clazz, foreignKeys, now);
|
||||
if (!fks.keySet().equals(foreignKeys)) {
|
||||
throw new InvalidReferencesException(
|
||||
clazz, ImmutableSet.copyOf(difference(foreignKeys, fks.keySet())));
|
||||
|
||||
@@ -27,6 +27,7 @@ import static com.google.common.io.BaseEncoding.base64;
|
||||
import static google.registry.config.RegistryConfig.getDefaultRegistrarWhoisServer;
|
||||
import static google.registry.model.CacheUtils.memoizeWithShortExpiration;
|
||||
import static google.registry.model.tld.Tlds.assertTldsExist;
|
||||
import static google.registry.persistence.transaction.TransactionManagerFactory.replicaTm;
|
||||
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
|
||||
import static google.registry.util.CollectionUtils.nullToEmptyImmutableCopy;
|
||||
import static google.registry.util.CollectionUtils.nullToEmptyImmutableSortedCopy;
|
||||
@@ -62,6 +63,7 @@ import google.registry.model.tld.Tld.TldType;
|
||||
import google.registry.persistence.VKey;
|
||||
import google.registry.persistence.converter.CidrBlockListUserType;
|
||||
import google.registry.persistence.converter.CurrencyToStringMapUserType;
|
||||
import google.registry.persistence.transaction.TransactionManager;
|
||||
import google.registry.util.CidrAddressBlock;
|
||||
import google.registry.util.PasswordUtils;
|
||||
import jakarta.mail.internet.AddressException;
|
||||
@@ -576,7 +578,20 @@ public class Registrar extends UpdateAutoTimestampEntity implements Buildable, J
|
||||
* address.
|
||||
*/
|
||||
public ImmutableSortedSet<RegistrarPoc> getContacts() {
|
||||
return getContactPocs().stream()
|
||||
return getContactPocs(tm()).stream()
|
||||
.filter(Objects::nonNull)
|
||||
.collect(toImmutableSortedSet(CONTACT_EMAIL_COMPARATOR));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of all {@link RegistrarPoc} objects for this registrar sorted by their email
|
||||
* address.
|
||||
*
|
||||
* <p>This method queries the replica database. It is reserved for use cases that can tolerate
|
||||
* slightly stale data.
|
||||
*/
|
||||
public ImmutableSortedSet<RegistrarPoc> getContactsFromReplica() {
|
||||
return getContactPocs(replicaTm()).stream()
|
||||
.filter(Objects::nonNull)
|
||||
.collect(toImmutableSortedSet(CONTACT_EMAIL_COMPARATOR));
|
||||
}
|
||||
@@ -586,7 +601,7 @@ public class Registrar extends UpdateAutoTimestampEntity implements Buildable, J
|
||||
* their email address.
|
||||
*/
|
||||
public ImmutableSortedSet<RegistrarPoc> getContactsOfType(final RegistrarPoc.Type type) {
|
||||
return getContactPocs().stream()
|
||||
return getContactPocs(tm()).stream()
|
||||
.filter(Objects::nonNull)
|
||||
.filter((@Nullable RegistrarPoc contact) -> contact.getTypes().contains(type))
|
||||
.collect(toImmutableSortedSet(CONTACT_EMAIL_COMPARATOR));
|
||||
@@ -600,13 +615,8 @@ public class Registrar extends UpdateAutoTimestampEntity implements Buildable, J
|
||||
return getContacts().stream().filter(RegistrarPoc::getVisibleInDomainWhoisAsAbuse).findFirst();
|
||||
}
|
||||
|
||||
private ImmutableSet<RegistrarPoc> getContactPocs() {
|
||||
return tm().transact(
|
||||
() ->
|
||||
tm().query("FROM RegistrarPoc WHERE registrarId = :registrarId", RegistrarPoc.class)
|
||||
.setParameter("registrarId", registrarId)
|
||||
.getResultStream()
|
||||
.collect(toImmutableSet()));
|
||||
private ImmutableList<RegistrarPoc> getContactPocs(TransactionManager txnManager) {
|
||||
return txnManager.transact(() -> RegistrarPoc.loadForRegistrar(registrarId));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -27,6 +27,7 @@ import static google.registry.util.PasswordUtils.hashPassword;
|
||||
import static java.util.stream.Collectors.joining;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.ImmutableSortedSet;
|
||||
import com.google.gson.annotations.Expose;
|
||||
@@ -36,6 +37,7 @@ import google.registry.model.JsonMapBuilder;
|
||||
import google.registry.model.Jsonifiable;
|
||||
import google.registry.model.UnsafeSerializable;
|
||||
import google.registry.persistence.VKey;
|
||||
import google.registry.persistence.transaction.QueryComposer;
|
||||
import google.registry.util.PasswordUtils;
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
@@ -93,6 +95,10 @@ public class RegistrarPoc extends ImmutableObject implements Jsonifiable, Unsafe
|
||||
}
|
||||
}
|
||||
|
||||
@Expose
|
||||
@Column(insertable = false, updatable = false)
|
||||
protected Long id;
|
||||
|
||||
/** The name of the contact. */
|
||||
@Expose String name;
|
||||
|
||||
@@ -179,6 +185,10 @@ public class RegistrarPoc extends ImmutableObject implements Jsonifiable, Unsafe
|
||||
tm().putAll(contacts);
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
@@ -295,6 +305,7 @@ public class RegistrarPoc extends ImmutableObject implements Jsonifiable, Unsafe
|
||||
.put("visibleInDomainWhoisAsAbuse", visibleInDomainWhoisAsAbuse)
|
||||
.put("allowedToSetRegistryLockPassword", allowedToSetRegistryLockPassword)
|
||||
.put("registryLockAllowed", isRegistryLockAllowed())
|
||||
.put("id", getId())
|
||||
.build();
|
||||
}
|
||||
|
||||
@@ -423,6 +434,12 @@ public class RegistrarPoc extends ImmutableObject implements Jsonifiable, Unsafe
|
||||
}
|
||||
}
|
||||
|
||||
public static ImmutableList<RegistrarPoc> loadForRegistrar(String registrarId) {
|
||||
return tm().createQueryComposer(RegistrarPoc.class)
|
||||
.where("registrarId", QueryComposer.Comparator.EQ, registrarId)
|
||||
.list();
|
||||
}
|
||||
|
||||
/** Class to represent the composite primary key for {@link RegistrarPoc} entity. */
|
||||
@VisibleForTesting
|
||||
public static class RegistrarPocId extends ImmutableObject implements Serializable {
|
||||
|
||||
@@ -336,7 +336,7 @@ abstract class AbstractJsonableObject implements Jsonable {
|
||||
// According to RFC 9083 section 3, the syntax of dates and times is defined in RFC3339.
|
||||
//
|
||||
// According to RFC3339, we should use ISO8601, which is what DateTime.toString does!
|
||||
return new JsonPrimitive(((DateTime) object).toString());
|
||||
return new JsonPrimitive(object.toString());
|
||||
}
|
||||
if (object == null) {
|
||||
return JsonNull.INSTANCE;
|
||||
|
||||
@@ -24,10 +24,14 @@ import static jakarta.servlet.http.HttpServletResponse.SC_NOT_FOUND;
|
||||
import static jakarta.servlet.http.HttpServletResponse.SC_OK;
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
|
||||
import com.google.common.collect.Streams;
|
||||
import com.google.common.flogger.FluentLogger;
|
||||
import com.google.common.net.MediaType;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import google.registry.config.RegistryConfig.Config;
|
||||
import google.registry.model.EppResource;
|
||||
import google.registry.model.registrar.Registrar;
|
||||
@@ -41,6 +45,7 @@ import google.registry.request.HttpException;
|
||||
import google.registry.request.Parameter;
|
||||
import google.registry.request.RequestMethod;
|
||||
import google.registry.request.RequestPath;
|
||||
import google.registry.request.RequestUrl;
|
||||
import google.registry.request.Response;
|
||||
import google.registry.util.Clock;
|
||||
import jakarta.inject.Inject;
|
||||
@@ -75,6 +80,7 @@ public abstract class RdapActionBase implements Runnable {
|
||||
@Inject Response response;
|
||||
@Inject @RequestMethod Action.Method requestMethod;
|
||||
@Inject @RequestPath String requestPath;
|
||||
@Inject @RequestUrl String requestUrl;
|
||||
@Inject RdapAuthorization rdapAuthorization;
|
||||
@Inject RdapJsonFormatter rdapJsonFormatter;
|
||||
@Inject @Parameter("includeDeleted") Optional<Boolean> includeDeletedParam;
|
||||
@@ -198,7 +204,9 @@ public abstract class RdapActionBase implements Runnable {
|
||||
TopLevelReplyObject topLevelObject =
|
||||
TopLevelReplyObject.create(replyObject, rdapJsonFormatter.createTosNotice());
|
||||
Gson gson = formatOutputParam.orElse(false) ? FORMATTED_OUTPUT_GSON : GSON;
|
||||
response.setPayload(gson.toJson(topLevelObject.toJson()));
|
||||
JsonObject jsonResult = topLevelObject.toJson();
|
||||
addLinkValuesRecursively(jsonResult);
|
||||
response.setPayload(gson.toJson(jsonResult));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -264,4 +272,34 @@ public abstract class RdapActionBase implements Runnable {
|
||||
return rdapJsonFormatter.getRequestTime();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a request-referencing "value" to each link object.
|
||||
*
|
||||
* <p>This is the "context URI" as described in RFC 8288. Basically, this contains a reference to
|
||||
* the request URL that generated this RDAP response.
|
||||
*
|
||||
* <p>This is required per the RDAP February 2024 response profile sections 2.6.3 and 2.10, and
|
||||
* the technical implementation guide sections 3.2 and 3.3.2.
|
||||
*
|
||||
* <p>We must do this here (instead of where the links are generated) because many of the links
|
||||
* (e.g. terms of service) are static constants, and thus cannot by default know what the request
|
||||
* URL was.
|
||||
*/
|
||||
private void addLinkValuesRecursively(JsonElement jsonElement) {
|
||||
if (jsonElement instanceof JsonArray jsonArray) {
|
||||
jsonArray.forEach(this::addLinkValuesRecursively);
|
||||
} else if (jsonElement instanceof JsonObject jsonObject) {
|
||||
if (jsonObject.get("links") instanceof JsonArray linksArray) {
|
||||
addLinkValues(linksArray);
|
||||
}
|
||||
jsonObject.entrySet().forEach(entry -> addLinkValuesRecursively(entry.getValue()));
|
||||
}
|
||||
}
|
||||
|
||||
private void addLinkValues(JsonArray linksArray) {
|
||||
Streams.stream(linksArray)
|
||||
.map(JsonElement::getAsJsonObject)
|
||||
.filter(o -> !o.has("value"))
|
||||
.forEach(o -> o.addProperty("value", requestUrl));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
package google.registry.rdap;
|
||||
|
||||
import static google.registry.flows.domain.DomainFlowUtils.validateDomainName;
|
||||
import static google.registry.model.EppResourceUtils.loadByForeignKeyCached;
|
||||
import static google.registry.model.EppResourceUtils.loadByForeignKeyByCache;
|
||||
import static google.registry.request.Action.Method.GET;
|
||||
import static google.registry.request.Action.Method.HEAD;
|
||||
import static google.registry.util.DateTimeUtils.START_OF_TIME;
|
||||
@@ -65,7 +65,7 @@ public class RdapDomainAction extends RdapActionBase {
|
||||
}
|
||||
// The query string is not used; the RDAP syntax is /rdap/domain/mydomain.com.
|
||||
Optional<Domain> domain =
|
||||
loadByForeignKeyCached(
|
||||
loadByForeignKeyByCache(
|
||||
Domain.class,
|
||||
pathSearchString,
|
||||
shouldIncludeDeleted() ? START_OF_TIME : rdapJsonFormatter.getRequestTime());
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
package google.registry.rdap;
|
||||
|
||||
import static com.google.common.collect.ImmutableSet.toImmutableSet;
|
||||
import static google.registry.model.EppResourceUtils.loadByForeignKeyCached;
|
||||
import static google.registry.model.EppResourceUtils.loadByForeignKeyByCache;
|
||||
import static google.registry.persistence.transaction.TransactionManagerFactory.replicaTm;
|
||||
import static google.registry.request.Action.Method.GET;
|
||||
import static google.registry.request.Action.Method.HEAD;
|
||||
@@ -184,7 +184,7 @@ public class RdapDomainSearchAction extends RdapSearchActionBase {
|
||||
private DomainSearchResponse searchByDomainNameWithoutWildcard(
|
||||
final RdapSearchPattern partialStringQuery) {
|
||||
Optional<Domain> domain =
|
||||
loadByForeignKeyCached(
|
||||
loadByForeignKeyByCache(
|
||||
Domain.class, partialStringQuery.getInitialString(), getRequestTime());
|
||||
return makeSearchResults(
|
||||
shouldBeVisible(domain) ? ImmutableList.of(domain.get()) : ImmutableList.of());
|
||||
@@ -339,7 +339,7 @@ public class RdapDomainSearchAction extends RdapSearchActionBase {
|
||||
Optional<String> desiredRegistrar = getDesiredRegistrar();
|
||||
if (desiredRegistrar.isPresent()) {
|
||||
Optional<Host> host =
|
||||
loadByForeignKeyCached(
|
||||
loadByForeignKeyByCache(
|
||||
Host.class,
|
||||
partialStringQuery.getInitialString(),
|
||||
shouldIncludeDeleted() ? START_OF_TIME : getRequestTime());
|
||||
@@ -364,7 +364,7 @@ public class RdapDomainSearchAction extends RdapSearchActionBase {
|
||||
// through the subordinate hosts. This is more efficient, and lets us permit wildcard searches
|
||||
// with no initial string.
|
||||
Domain domain =
|
||||
loadByForeignKeyCached(
|
||||
loadByForeignKeyByCache(
|
||||
Domain.class,
|
||||
partialStringQuery.getSuffix(),
|
||||
shouldIncludeDeleted() ? START_OF_TIME : getRequestTime())
|
||||
@@ -381,7 +381,7 @@ public class RdapDomainSearchAction extends RdapSearchActionBase {
|
||||
if (partialStringQuery.matches(fqhn)) {
|
||||
if (desiredRegistrar.isPresent()) {
|
||||
Optional<Host> host =
|
||||
loadByForeignKeyCached(
|
||||
loadByForeignKeyByCache(
|
||||
Host.class, fqhn, shouldIncludeDeleted() ? START_OF_TIME : getRequestTime());
|
||||
if (host.isPresent()
|
||||
&& desiredRegistrar
|
||||
|
||||
@@ -44,7 +44,7 @@ public class RdapIcannStandardInformation {
|
||||
+ " https://icann.org/epp")
|
||||
.addLink(
|
||||
Link.builder()
|
||||
.setRel("alternate")
|
||||
.setRel("glossary")
|
||||
.setHref("https://icann.org/epp")
|
||||
.setType("text/html")
|
||||
.build())
|
||||
@@ -57,7 +57,7 @@ public class RdapIcannStandardInformation {
|
||||
.setDescription("URL of the ICANN RDDS Inaccuracy Complaint Form: https://icann.org/wicf")
|
||||
.addLink(
|
||||
Link.builder()
|
||||
.setRel("alternate")
|
||||
.setRel("help")
|
||||
.setHref("https://icann.org/wicf")
|
||||
.setType("text/html")
|
||||
.build())
|
||||
|
||||
@@ -271,7 +271,7 @@ public class RdapJsonFormatter {
|
||||
URI htmlUri = htmlBaseURI.resolve(rdapTosStaticUrl);
|
||||
noticeBuilder.addLink(
|
||||
Link.builder()
|
||||
.setRel("alternate")
|
||||
.setRel("terms-of-service")
|
||||
.setHref(htmlUri.toString())
|
||||
.setType("text/html")
|
||||
.build());
|
||||
@@ -740,7 +740,7 @@ public class RdapJsonFormatter {
|
||||
//
|
||||
if (outputDataType != OutputDataType.SUMMARY) {
|
||||
ImmutableList<RdapContactEntity> registrarContacts =
|
||||
registrar.getContacts().stream()
|
||||
registrar.getContactsFromReplica().stream()
|
||||
.map(RdapJsonFormatter::makeRdapJsonForRegistrarContact)
|
||||
.filter(Optional::isPresent)
|
||||
.map(Optional::get)
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
package google.registry.rdap;
|
||||
|
||||
import static google.registry.flows.host.HostFlowUtils.validateHostName;
|
||||
import static google.registry.model.EppResourceUtils.loadByForeignKeyCached;
|
||||
import static google.registry.model.EppResourceUtils.loadByForeignKeyByCache;
|
||||
import static google.registry.request.Action.Method.GET;
|
||||
import static google.registry.request.Action.Method.HEAD;
|
||||
import static google.registry.util.DateTimeUtils.START_OF_TIME;
|
||||
@@ -63,7 +63,7 @@ public class RdapNameserverAction extends RdapActionBase {
|
||||
// If there are no undeleted nameservers with the given name, the foreign key should point to
|
||||
// the most recently deleted one.
|
||||
Optional<Host> host =
|
||||
loadByForeignKeyCached(
|
||||
loadByForeignKeyByCache(
|
||||
Host.class,
|
||||
pathSearchString,
|
||||
shouldIncludeDeleted() ? START_OF_TIME : getRequestTime());
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
package google.registry.rdap;
|
||||
|
||||
import static google.registry.model.EppResourceUtils.loadByForeignKeyCached;
|
||||
import static google.registry.model.EppResourceUtils.loadByForeignKeyByCache;
|
||||
import static google.registry.persistence.transaction.TransactionManagerFactory.replicaTm;
|
||||
import static google.registry.request.Action.Method.GET;
|
||||
import static google.registry.request.Action.Method.HEAD;
|
||||
@@ -159,7 +159,8 @@ public class RdapNameserverSearchAction extends RdapSearchActionBase {
|
||||
.setIncompletenessWarningType(IncompletenessWarningType.COMPLETE);
|
||||
|
||||
Optional<Host> host =
|
||||
loadByForeignKeyCached(Host.class, partialStringQuery.getInitialString(), getRequestTime());
|
||||
loadByForeignKeyByCache(
|
||||
Host.class, partialStringQuery.getInitialString(), getRequestTime());
|
||||
|
||||
metricInformationBuilder.setNumHostsRetrieved(host.isPresent() ? 1 : 0);
|
||||
|
||||
@@ -175,7 +176,7 @@ public class RdapNameserverSearchAction extends RdapSearchActionBase {
|
||||
private NameserverSearchResponse searchByNameUsingSuperordinateDomain(
|
||||
RdapSearchPattern partialStringQuery) {
|
||||
Optional<Domain> domain =
|
||||
loadByForeignKeyCached(Domain.class, partialStringQuery.getSuffix(), getRequestTime());
|
||||
loadByForeignKeyByCache(Domain.class, partialStringQuery.getSuffix(), getRequestTime());
|
||||
if (domain.isEmpty()) {
|
||||
// Don't allow wildcards with suffixes which are not domains we manage. That would risk a
|
||||
// table scan in many easily foreseeable cases. The user might ask for ns*.zombo.com,
|
||||
@@ -193,7 +194,7 @@ public class RdapNameserverSearchAction extends RdapSearchActionBase {
|
||||
// We can't just check that the host name starts with the initial query string, because
|
||||
// then the query ns.exam*.example.com would match against nameserver ns.example.com.
|
||||
if (partialStringQuery.matches(fqhn)) {
|
||||
Optional<Host> host = loadByForeignKeyCached(Host.class, fqhn, getRequestTime());
|
||||
Optional<Host> host = loadByForeignKeyByCache(Host.class, fqhn, getRequestTime());
|
||||
if (shouldBeVisible(host)) {
|
||||
hostList.add(host.get());
|
||||
if (hostList.size() > rdapResultSetMaxSize) {
|
||||
|
||||
@@ -31,7 +31,6 @@ import google.registry.request.HttpException.BadRequestException;
|
||||
import google.registry.request.HttpException.UnprocessableEntityException;
|
||||
import google.registry.request.Parameter;
|
||||
import google.registry.request.ParameterMap;
|
||||
import google.registry.request.RequestUrl;
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.persistence.criteria.CriteriaBuilder;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
@@ -54,7 +53,6 @@ public abstract class RdapSearchActionBase extends RdapActionBase {
|
||||
|
||||
private static final int RESULT_SET_SIZE_SCALING_FACTOR = 30;
|
||||
|
||||
@Inject @RequestUrl String requestUrl;
|
||||
@Inject @ParameterMap ImmutableListMultimap<String, String> parameterMap;
|
||||
@Inject @Parameter("cursor") Optional<String> cursorTokenParam;
|
||||
@Inject @Parameter("registrar") Optional<String> registrarParam;
|
||||
|
||||
@@ -16,7 +16,7 @@ package google.registry.tools;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static google.registry.batch.AsyncTaskEnqueuer.QUEUE_ASYNC_ACTIONS;
|
||||
import static google.registry.model.EppResourceUtils.loadByForeignKeyCached;
|
||||
import static google.registry.model.EppResourceUtils.loadByForeignKeyByCacheIfEnabled;
|
||||
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
|
||||
import static google.registry.tools.LockOrUnlockDomainCommand.REGISTRY_LOCK_STATUSES;
|
||||
|
||||
@@ -326,7 +326,7 @@ public final class DomainLockUtils {
|
||||
|
||||
private Domain getDomain(String domainName, String registrarId, DateTime now) {
|
||||
Domain domain =
|
||||
loadByForeignKeyCached(Domain.class, domainName, now)
|
||||
loadByForeignKeyByCacheIfEnabled(Domain.class, domainName, now)
|
||||
.orElseThrow(() -> new IllegalArgumentException("Domain doesn't exist"));
|
||||
// The user must have specified either the correct registrar ID or the admin registrar ID
|
||||
checkArgument(
|
||||
|
||||
@@ -251,11 +251,12 @@ final class UniformRapidSuspensionCommand extends MutatingEppToolCommand {
|
||||
if (undo) {
|
||||
return "";
|
||||
}
|
||||
StringBuilder undoBuilder = new StringBuilder("UNDO COMMAND:\n\n)")
|
||||
.append("nomulus -e ")
|
||||
.append(RegistryToolEnvironment.get())
|
||||
.append(" uniform_rapid_suspension --undo --domain_name ")
|
||||
.append(domainName);
|
||||
StringBuilder undoBuilder =
|
||||
new StringBuilder("UNDO COMMAND:\n\n")
|
||||
.append("nomulus -e ")
|
||||
.append(RegistryToolEnvironment.get())
|
||||
.append(" uniform_rapid_suspension --undo --domain_name ")
|
||||
.append(domainName);
|
||||
if (!existingNameservers.isEmpty()) {
|
||||
undoBuilder.append(" --hosts ").append(Joiner.on(',').join(existingNameservers));
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ public class ConsoleDomainGetAction extends ConsoleApiAction {
|
||||
Optional<Domain> possibleDomain =
|
||||
tm().transact(
|
||||
() ->
|
||||
EppResourceUtils.loadByForeignKeyCached(
|
||||
EppResourceUtils.loadByForeignKeyByCacheIfEnabled(
|
||||
Domain.class, paramDomain, tm().getTransactionTime()));
|
||||
if (possibleDomain.isEmpty()) {
|
||||
consoleApiParams.response().setStatus(SC_NOT_FOUND);
|
||||
|
||||
@@ -19,7 +19,6 @@ import static google.registry.request.RequestParameters.extractOptionalIntParame
|
||||
import static google.registry.request.RequestParameters.extractOptionalParameter;
|
||||
import static google.registry.request.RequestParameters.extractRequiredParameter;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonElement;
|
||||
import dagger.Module;
|
||||
@@ -192,10 +191,10 @@ public final class ConsoleModule {
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Parameter("contacts")
|
||||
public static Optional<ImmutableSet<RegistrarPoc>> provideContacts(
|
||||
@Parameter("contact")
|
||||
public static Optional<RegistrarPoc> provideContacts(
|
||||
Gson gson, @OptionalJsonPayload Optional<JsonElement> payload) {
|
||||
return payload.map(s -> ImmutableSet.copyOf(gson.fromJson(s, RegistrarPoc[].class)));
|
||||
return payload.map(s -> gson.fromJson(s, RegistrarPoc.class));
|
||||
}
|
||||
|
||||
@Provides
|
||||
|
||||
@@ -15,12 +15,13 @@
|
||||
package google.registry.ui.server.console.settings;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.collect.ImmutableList.toImmutableList;
|
||||
import static com.google.common.collect.ImmutableSet.toImmutableSet;
|
||||
import static com.google.common.collect.Sets.difference;
|
||||
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
|
||||
import static google.registry.request.Action.Method.DELETE;
|
||||
import static google.registry.request.Action.Method.GET;
|
||||
import static google.registry.request.Action.Method.POST;
|
||||
import static google.registry.request.Action.Method.PUT;
|
||||
import static jakarta.servlet.http.HttpServletResponse.SC_OK;
|
||||
|
||||
import com.google.common.collect.HashMultimap;
|
||||
@@ -33,66 +34,122 @@ import google.registry.model.console.User;
|
||||
import google.registry.model.registrar.Registrar;
|
||||
import google.registry.model.registrar.RegistrarPoc;
|
||||
import google.registry.model.registrar.RegistrarPoc.Type;
|
||||
import google.registry.persistence.transaction.QueryComposer.Comparator;
|
||||
import google.registry.request.Action;
|
||||
import google.registry.request.Action.GaeService;
|
||||
import google.registry.request.Action.GkeService;
|
||||
import google.registry.request.Parameter;
|
||||
import google.registry.request.auth.Auth;
|
||||
import google.registry.ui.forms.FormException;
|
||||
import google.registry.ui.server.RegistrarFormFields;
|
||||
import google.registry.ui.server.console.ConsoleApiAction;
|
||||
import google.registry.ui.server.console.ConsoleApiParams;
|
||||
import jakarta.inject.Inject;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
@Action(
|
||||
service = GaeService.DEFAULT,
|
||||
gkeService = GkeService.CONSOLE,
|
||||
path = ContactAction.PATH,
|
||||
method = {GET, POST},
|
||||
method = {GET, POST, DELETE, PUT},
|
||||
auth = Auth.AUTH_PUBLIC_LOGGED_IN)
|
||||
public class ContactAction extends ConsoleApiAction {
|
||||
static final String PATH = "/console-api/settings/contacts";
|
||||
private static final FluentLogger logger = FluentLogger.forEnclosingClass();
|
||||
private final Optional<ImmutableSet<RegistrarPoc>> contacts;
|
||||
private final Optional<RegistrarPoc> contact;
|
||||
private final String registrarId;
|
||||
|
||||
@Inject
|
||||
public ContactAction(
|
||||
ConsoleApiParams consoleApiParams,
|
||||
@Parameter("registrarId") String registrarId,
|
||||
@Parameter("contacts") Optional<ImmutableSet<RegistrarPoc>> contacts) {
|
||||
@Parameter("contact") Optional<RegistrarPoc> contact) {
|
||||
super(consoleApiParams);
|
||||
this.registrarId = registrarId;
|
||||
this.contacts = contacts;
|
||||
this.contact = contact;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void getHandler(User user) {
|
||||
checkPermission(user, registrarId, ConsolePermission.VIEW_REGISTRAR_DETAILS);
|
||||
ImmutableList<RegistrarPoc> am =
|
||||
tm().transact(
|
||||
() ->
|
||||
tm()
|
||||
.createQueryComposer(RegistrarPoc.class)
|
||||
.where("registrarId", Comparator.EQ, registrarId)
|
||||
.stream()
|
||||
.filter(r -> !r.getTypes().isEmpty())
|
||||
.collect(toImmutableList()));
|
||||
|
||||
ImmutableList<RegistrarPoc> contacts =
|
||||
tm().transact(() -> RegistrarPoc.loadForRegistrar(registrarId));
|
||||
consoleApiParams.response().setStatus(SC_OK);
|
||||
consoleApiParams.response().setPayload(consoleApiParams.gson().toJson(am));
|
||||
consoleApiParams.response().setPayload(consoleApiParams.gson().toJson(contacts));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void deleteHandler(User user) {
|
||||
updateContacts(
|
||||
user,
|
||||
(registrar, oldContacts) ->
|
||||
oldContacts.stream()
|
||||
.filter(
|
||||
oldContact ->
|
||||
!oldContact.getEmailAddress().equals(contact.get().getEmailAddress()))
|
||||
.collect(toImmutableSet()));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void postHandler(User user) {
|
||||
updateContacts(
|
||||
user,
|
||||
(registrar, oldContacts) -> {
|
||||
RegistrarPoc newContact = contact.get();
|
||||
return ImmutableSet.<RegistrarPoc>builder()
|
||||
.addAll(oldContacts)
|
||||
.add(
|
||||
new RegistrarPoc()
|
||||
.asBuilder()
|
||||
.setTypes(newContact.getTypes())
|
||||
.setVisibleInWhoisAsTech(newContact.getVisibleInWhoisAsTech())
|
||||
.setVisibleInWhoisAsAdmin(newContact.getVisibleInWhoisAsAdmin())
|
||||
.setVisibleInDomainWhoisAsAbuse(newContact.getVisibleInDomainWhoisAsAbuse())
|
||||
.setFaxNumber(newContact.getFaxNumber())
|
||||
.setName(newContact.getName())
|
||||
.setEmailAddress(newContact.getEmailAddress())
|
||||
.setPhoneNumber(newContact.getPhoneNumber())
|
||||
.setRegistrar(registrar)
|
||||
.build())
|
||||
.build();
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void putHandler(User user) {
|
||||
updateContacts(
|
||||
user,
|
||||
(registrar, oldContacts) -> {
|
||||
RegistrarPoc updatedContact = contact.get();
|
||||
return oldContacts.stream()
|
||||
.map(
|
||||
oldContact ->
|
||||
oldContact.getId().equals(updatedContact.getId())
|
||||
? oldContact
|
||||
.asBuilder()
|
||||
.setTypes(updatedContact.getTypes())
|
||||
.setVisibleInWhoisAsTech(updatedContact.getVisibleInWhoisAsTech())
|
||||
.setVisibleInWhoisAsAdmin(updatedContact.getVisibleInWhoisAsAdmin())
|
||||
.setVisibleInDomainWhoisAsAbuse(
|
||||
updatedContact.getVisibleInDomainWhoisAsAbuse())
|
||||
.setFaxNumber(updatedContact.getFaxNumber())
|
||||
.setName(updatedContact.getName())
|
||||
.setEmailAddress(updatedContact.getEmailAddress())
|
||||
.setPhoneNumber(updatedContact.getPhoneNumber())
|
||||
.build()
|
||||
: oldContact)
|
||||
.collect(toImmutableSet());
|
||||
});
|
||||
}
|
||||
|
||||
private void updateContacts(
|
||||
User user,
|
||||
BiFunction<Registrar, ImmutableSet<RegistrarPoc>, ImmutableSet<RegistrarPoc>>
|
||||
contactsUpdater) {
|
||||
checkPermission(user, registrarId, ConsolePermission.EDIT_REGISTRAR_DETAILS);
|
||||
checkArgument(contacts.isPresent(), "Contacts parameter is not present");
|
||||
checkArgument(contact.isPresent(), "Contact parameter is not present");
|
||||
Registrar registrar =
|
||||
Registrar.loadByRegistrarId(registrarId)
|
||||
.orElseThrow(
|
||||
@@ -101,20 +158,10 @@ public class ContactAction extends ConsoleApiAction {
|
||||
String.format("Unknown registrar %s", registrarId)));
|
||||
|
||||
ImmutableSet<RegistrarPoc> oldContacts = registrar.getContacts();
|
||||
ImmutableSet<RegistrarPoc> updatedContacts =
|
||||
RegistrarFormFields.getRegistrarContactBuilders(
|
||||
oldContacts,
|
||||
Collections.singletonMap(
|
||||
"contacts",
|
||||
contacts.get().stream()
|
||||
.map(RegistrarPoc::toJsonMap)
|
||||
.collect(toImmutableList())))
|
||||
.stream()
|
||||
.map(builder -> builder.setRegistrar(registrar).build())
|
||||
.collect(toImmutableSet());
|
||||
ImmutableSet<RegistrarPoc> newContacts = contactsUpdater.apply(registrar, oldContacts);
|
||||
|
||||
try {
|
||||
checkContactRequirements(oldContacts, updatedContacts);
|
||||
checkContactRequirements(oldContacts, newContacts);
|
||||
} catch (FormException e) {
|
||||
logger.atWarning().withCause(e).log(
|
||||
"Error processing contacts post request for registrar: %s", registrarId);
|
||||
@@ -123,14 +170,13 @@ public class ContactAction extends ConsoleApiAction {
|
||||
|
||||
tm().transact(
|
||||
() -> {
|
||||
RegistrarPoc.updateContacts(registrar, updatedContacts);
|
||||
RegistrarPoc.updateContacts(registrar, newContacts);
|
||||
Registrar updatedRegistrar =
|
||||
registrar.asBuilder().setContactsRequireSyncing(true).build();
|
||||
tm().put(updatedRegistrar);
|
||||
sendExternalUpdatesIfNecessary(
|
||||
EmailInfo.create(registrar, updatedRegistrar, oldContacts, updatedContacts));
|
||||
EmailInfo.create(registrar, updatedRegistrar, oldContacts, newContacts));
|
||||
});
|
||||
|
||||
consoleApiParams.response().setStatus(SC_OK);
|
||||
}
|
||||
|
||||
@@ -169,6 +215,7 @@ public class ContactAction extends ConsoleApiAction {
|
||||
throw new ContactRequirementException(t);
|
||||
}
|
||||
}
|
||||
|
||||
enforcePrimaryContactRestrictions(oldContactsByType, newContactsByType);
|
||||
ensurePhoneNumberNotRemovedForContactTypes(oldContactsByType, newContactsByType, Type.TECH);
|
||||
Optional<RegistrarPoc> domainWhoisAbuseContact =
|
||||
|
||||
@@ -17,7 +17,7 @@ package google.registry.whois;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static google.registry.flows.domain.DomainFlowUtils.isBlockedByBsa;
|
||||
import static google.registry.model.EppResourceUtils.loadByForeignKey;
|
||||
import static google.registry.model.EppResourceUtils.loadByForeignKeyCached;
|
||||
import static google.registry.model.EppResourceUtils.loadByForeignKeyByCache;
|
||||
import static google.registry.model.tld.Tlds.findTldForName;
|
||||
import static google.registry.model.tld.Tlds.getTlds;
|
||||
import static google.registry.persistence.transaction.TransactionManagerFactory.replicaTm;
|
||||
@@ -94,7 +94,7 @@ public class DomainLookupCommand implements WhoisCommand {
|
||||
private Optional<WhoisResponse> getResponse(InternetDomainName domainName, DateTime now) {
|
||||
Optional<Domain> domainResource =
|
||||
cached
|
||||
? loadByForeignKeyCached(Domain.class, domainName.toString(), now)
|
||||
? loadByForeignKeyByCache(Domain.class, domainName.toString(), now)
|
||||
: loadByForeignKey(Domain.class, domainName.toString(), now);
|
||||
return domainResource.map(
|
||||
domain -> new DomainWhoisResponse(domain, fullOutput, whoisRedactedEmailText, now));
|
||||
|
||||
@@ -81,7 +81,7 @@ final class DomainWhoisResponse extends WhoisResponseImpl {
|
||||
domain.getCurrentSponsorRegistrarId());
|
||||
Registrar registrar = registrarOptional.get();
|
||||
Optional<RegistrarPoc> abuseContact =
|
||||
registrar.getContacts().stream()
|
||||
registrar.getContactsFromReplica().stream()
|
||||
.filter(RegistrarPoc::getVisibleInDomainWhoisAsAbuse)
|
||||
.findFirst();
|
||||
return WhoisResponseResults.create(
|
||||
@@ -154,7 +154,7 @@ final class DomainWhoisResponse extends WhoisResponseImpl {
|
||||
// If we refer to a contact that doesn't exist, that's a bug. It means referential integrity
|
||||
// has somehow been broken. We skip the rest of this contact, but log it to hopefully bring it
|
||||
// someone's attention.
|
||||
Contact contact1 = EppResource.loadCached(contact.get());
|
||||
Contact contact1 = EppResource.loadByCache(contact.get());
|
||||
if (contact1 == null) {
|
||||
logger.atSevere().log(
|
||||
"(BUG) Broken reference found from domain %s to contact %s.",
|
||||
|
||||
@@ -16,7 +16,7 @@ package google.registry.whois;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static google.registry.model.EppResourceUtils.loadByForeignKey;
|
||||
import static google.registry.model.EppResourceUtils.loadByForeignKeyCached;
|
||||
import static google.registry.model.EppResourceUtils.loadByForeignKeyByCache;
|
||||
import static google.registry.model.tld.Tlds.findTldForName;
|
||||
import static google.registry.model.tld.Tlds.getTlds;
|
||||
import static jakarta.servlet.http.HttpServletResponse.SC_NOT_FOUND;
|
||||
@@ -57,7 +57,7 @@ public class NameserverLookupByHostCommand implements WhoisCommand {
|
||||
private Optional<WhoisResponse> getResponse(InternetDomainName hostName, DateTime now) {
|
||||
Optional<Host> host =
|
||||
cached
|
||||
? loadByForeignKeyCached(Host.class, hostName.toString(), now)
|
||||
? loadByForeignKeyByCache(Host.class, hostName.toString(), now)
|
||||
: loadByForeignKey(Host.class, hostName.toString(), now);
|
||||
return host.map(h -> new NameserverWhoisResponse(h, now));
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ class RegistrarWhoisResponse extends WhoisResponseImpl {
|
||||
|
||||
@Override
|
||||
public WhoisResponseResults getResponse(boolean preferUnicode, String disclaimer) {
|
||||
Set<RegistrarPoc> contacts = registrar.getContacts();
|
||||
Set<RegistrarPoc> contacts = registrar.getContactsFromReplica();
|
||||
String plaintext =
|
||||
new RegistrarEmitter()
|
||||
.emitField("Registrar", registrar.getRegistrarName())
|
||||
|
||||
@@ -47,13 +47,14 @@
|
||||
<class>google.registry.model.billing.BillingRecurrence</class>
|
||||
<class>google.registry.model.common.Cursor</class>
|
||||
<class>google.registry.model.common.DnsRefreshRequest</class>
|
||||
<class>google.registry.model.common.FeatureFlag</class>
|
||||
<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.common.FeatureFlag</class>
|
||||
<class>google.registry.model.domain.GracePeriod</class>
|
||||
<class>google.registry.model.domain.GracePeriod$GracePeriodHistory</class>
|
||||
<class>google.registry.model.domain.secdns.DomainDsData</class>
|
||||
|
||||
@@ -36,27 +36,27 @@ public class EppResourceTest extends EntityTestCase {
|
||||
new TestCacheExtension.Builder().withEppResourceCache(Duration.ofDays(1)).build();
|
||||
|
||||
@Test
|
||||
void test_loadCached_ignoresContactChange() {
|
||||
void test_loadByCacheIfEnabled_ignoresContactChange() {
|
||||
Contact originalContact = persistActiveContact("contact123");
|
||||
assertThat(EppResource.loadCached(ImmutableList.of(originalContact.createVKey())))
|
||||
assertThat(EppResource.loadByCacheIfEnabled(ImmutableList.of(originalContact.createVKey())))
|
||||
.containsExactly(originalContact.createVKey(), originalContact);
|
||||
Contact modifiedContact =
|
||||
persistResource(originalContact.asBuilder().setEmailAddress("different@fake.lol").build());
|
||||
assertThat(EppResource.loadCached(ImmutableList.of(originalContact.createVKey())))
|
||||
assertThat(EppResource.loadByCacheIfEnabled(ImmutableList.of(originalContact.createVKey())))
|
||||
.containsExactly(originalContact.createVKey(), originalContact);
|
||||
assertThat(loadByForeignKey(Contact.class, "contact123", fakeClock.nowUtc()))
|
||||
.hasValue(modifiedContact);
|
||||
}
|
||||
|
||||
@Test
|
||||
void test_loadCached_ignoresHostChange() {
|
||||
void test_loadByCacheIfEnabled_ignoresHostChange() {
|
||||
Host originalHost = persistActiveHost("ns1.example.com");
|
||||
assertThat(EppResource.loadCached(ImmutableList.of(originalHost.createVKey())))
|
||||
assertThat(EppResource.loadByCacheIfEnabled(ImmutableList.of(originalHost.createVKey())))
|
||||
.containsExactly(originalHost.createVKey(), originalHost);
|
||||
Host modifiedHost =
|
||||
persistResource(
|
||||
originalHost.asBuilder().setLastTransferTime(fakeClock.nowUtc().minusDays(60)).build());
|
||||
assertThat(EppResource.loadCached(ImmutableList.of(originalHost.createVKey())))
|
||||
assertThat(EppResource.loadByCacheIfEnabled(ImmutableList.of(originalHost.createVKey())))
|
||||
.containsExactly(originalHost.createVKey(), originalHost);
|
||||
assertThat(loadByForeignKey(Host.class, "ns1.example.com", fakeClock.nowUtc()))
|
||||
.hasValue(modifiedHost);
|
||||
|
||||
@@ -121,7 +121,7 @@ class ForeignKeyUtilsTest {
|
||||
fakeClock.advanceOneMilli();
|
||||
Host newHost1 = persistActiveHost("ns1.example.com");
|
||||
assertThat(
|
||||
ForeignKeyUtils.loadCached(
|
||||
ForeignKeyUtils.loadByCacheIfEnabled(
|
||||
Host.class,
|
||||
ImmutableList.of("ns1.example.com", "ns2.example.com", "ns3.example.com"),
|
||||
fakeClock.nowUtc()))
|
||||
@@ -134,7 +134,7 @@ class ForeignKeyUtilsTest {
|
||||
Host host2 = persistActiveHost("ns2.example.com");
|
||||
persistResource(host2.asBuilder().setDeletionTime(fakeClock.nowUtc().minusDays(1)).build());
|
||||
assertThat(
|
||||
ForeignKeyUtils.loadCached(
|
||||
ForeignKeyUtils.loadByCacheIfEnabled(
|
||||
Host.class,
|
||||
ImmutableList.of("ns1.example.com", "ns2.example.com", "ns3.example.com"),
|
||||
fakeClock.nowUtc()))
|
||||
@@ -144,7 +144,7 @@ class ForeignKeyUtilsTest {
|
||||
persistActiveHost("ns1.example.com");
|
||||
// Even though a new host1 is now live, the cache still returns the VKey to the old one.
|
||||
assertThat(
|
||||
ForeignKeyUtils.loadCached(
|
||||
ForeignKeyUtils.loadByCacheIfEnabled(
|
||||
Host.class,
|
||||
ImmutableList.of("ns1.example.com", "ns2.example.com", "ns3.example.com"),
|
||||
fakeClock.nowUtc()))
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
// Copyright 2025 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.console;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static google.registry.model.ImmutableObjectSubject.assertAboutImmutableObjects;
|
||||
import static google.registry.testing.DatabaseHelper.persistResource;
|
||||
import static org.junit.Assert.assertThrows;
|
||||
|
||||
import google.registry.model.EntityTestCase;
|
||||
import google.registry.persistence.VKey;
|
||||
import google.registry.testing.DatabaseHelper;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/** Tests for {@link PasswordResetRequest}. */
|
||||
public class PasswordResetRequestTest extends EntityTestCase {
|
||||
|
||||
PasswordResetRequestTest() {
|
||||
super(JpaEntityCoverageCheck.ENABLED);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_persistence() {
|
||||
PasswordResetRequest request =
|
||||
new PasswordResetRequest.Builder()
|
||||
.setRequester("requestor@email.tld")
|
||||
.setDestinationEmail("destination@email.tld")
|
||||
.setType(PasswordResetRequest.Type.EPP)
|
||||
.setRegistrarId("TheRegistrar")
|
||||
.build();
|
||||
String verificationCode = request.getVerificationCode();
|
||||
assertThat(verificationCode).isNotEmpty();
|
||||
persistResource(request);
|
||||
PasswordResetRequest fromDatabase =
|
||||
DatabaseHelper.loadByKey(VKey.create(PasswordResetRequest.class, verificationCode));
|
||||
assertAboutImmutableObjects().that(fromDatabase).isEqualExceptFields(request, "requestTime");
|
||||
assertThat(fromDatabase.getRequestTime()).isEqualTo(fakeClock.nowUtc());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_nullFields() {
|
||||
PasswordResetRequest.Builder builder = new PasswordResetRequest.Builder();
|
||||
assertThrows(IllegalArgumentException.class, builder::build);
|
||||
builder.setType(PasswordResetRequest.Type.EPP);
|
||||
assertThrows(IllegalArgumentException.class, builder::build);
|
||||
builder.setRequester("foobar@email.tld");
|
||||
assertThrows(IllegalArgumentException.class, builder::build);
|
||||
builder.setDestinationEmail("email@email.tld");
|
||||
assertThrows(IllegalArgumentException.class, builder::build);
|
||||
builder.setRegistrarId("TheRegistrar");
|
||||
builder.build();
|
||||
}
|
||||
}
|
||||
@@ -44,6 +44,7 @@ import google.registry.model.registrar.Registrar.Type;
|
||||
import google.registry.model.tld.Tld;
|
||||
import google.registry.model.tld.Tld.TldType;
|
||||
import google.registry.model.tld.Tlds;
|
||||
import google.registry.testing.DatabaseHelper;
|
||||
import google.registry.util.CidrAddressBlock;
|
||||
import google.registry.util.SerializeUtils;
|
||||
import java.math.BigDecimal;
|
||||
@@ -340,6 +341,7 @@ class RegistrarTest extends EntityTestCase {
|
||||
.setFaxNumber("+1.2125551213")
|
||||
.setTypes(ImmutableSet.of(RegistrarPoc.Type.TECH, RegistrarPoc.Type.ABUSE))
|
||||
.build());
|
||||
abuseAdminContact = DatabaseHelper.loadByKey(abuseAdminContact.createVKey());
|
||||
ImmutableSortedSet<RegistrarPoc> techContacts =
|
||||
registrar.getContactsOfType(RegistrarPoc.Type.TECH);
|
||||
assertThat(techContacts).containsExactly(newTechContact, newTechAbuseContact).inOrder();
|
||||
|
||||
@@ -90,12 +90,6 @@ class RdapActionBaseTest extends RdapActionBaseTestCase<RdapActionBaseTest.RdapT
|
||||
assertThat(response.getStatus()).isEqualTo(500);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testValidName_works() {
|
||||
assertThat(generateActualJson("no.thing")).isEqualTo(loadJsonFile("rdapjson_toplevel.json"));
|
||||
assertThat(response.getStatus()).isEqualTo(200);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testContentType_rdapjson_utf8() {
|
||||
generateActualJson("no.thing");
|
||||
|
||||
@@ -22,7 +22,12 @@ import static google.registry.request.Action.Method.GET;
|
||||
import static google.registry.request.Action.Method.HEAD;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
import google.registry.model.console.User;
|
||||
import google.registry.model.console.UserRoles;
|
||||
import google.registry.persistence.transaction.JpaTestExtensions;
|
||||
@@ -35,6 +40,7 @@ import google.registry.util.Idn;
|
||||
import google.registry.util.TypeUtils;
|
||||
import java.util.HashMap;
|
||||
import java.util.Optional;
|
||||
import javax.annotation.Nullable;
|
||||
import org.joda.time.DateTime;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||
@@ -43,6 +49,7 @@ import org.junit.jupiter.api.extension.RegisterExtension;
|
||||
abstract class RdapActionBaseTestCase<A extends RdapActionBase> {
|
||||
|
||||
protected final FakeClock clock = new FakeClock(DateTime.parse("2000-01-01TZ"));
|
||||
static final Gson GSON = new GsonBuilder().setPrettyPrinting().disableHtmlEscaping().create();
|
||||
|
||||
@RegisterExtension
|
||||
final JpaIntegrationTestExtension jpa =
|
||||
@@ -107,18 +114,13 @@ abstract class RdapActionBaseTestCase<A extends RdapActionBase> {
|
||||
metricRole = ADMINISTRATOR;
|
||||
}
|
||||
|
||||
JsonObject generateActualJson(String domainName) {
|
||||
action.requestPath = actionPath + domainName;
|
||||
action.requestMethod = GET;
|
||||
action.run();
|
||||
return RdapTestHelper.parseJsonObject(response.getPayload());
|
||||
JsonObject generateActualJson(String name) {
|
||||
return RdapTestHelper.parseJsonObject(runAction(name));
|
||||
}
|
||||
|
||||
String generateHeadPayload(String domainName) {
|
||||
action.requestPath = actionPath + domainName;
|
||||
String generateHeadPayload(String name) {
|
||||
action.requestMethod = HEAD;
|
||||
action.run();
|
||||
return response.getPayload();
|
||||
return runAction(name);
|
||||
}
|
||||
|
||||
JsonObject generateExpectedJsonError(String description, int code) {
|
||||
@@ -138,16 +140,135 @@ abstract class RdapActionBaseTestCase<A extends RdapActionBase> {
|
||||
"TITLE",
|
||||
title,
|
||||
"CODE",
|
||||
String.valueOf(code));
|
||||
String.valueOf(code),
|
||||
"REQUEST_URL",
|
||||
action.requestUrl);
|
||||
}
|
||||
|
||||
static JsonFileBuilder jsonFileBuilder() {
|
||||
return new JsonFileBuilder();
|
||||
JsonFileBuilder jsonFileBuilder() {
|
||||
return new JsonFileBuilder(action.requestUrl);
|
||||
}
|
||||
|
||||
private String runAction(String name) {
|
||||
action.requestPath = actionPath + name;
|
||||
action.requestUrl = "https://example.tld" + actionPath + name;
|
||||
action.run();
|
||||
return response.getPayload();
|
||||
}
|
||||
|
||||
JsonElement createTosNotice() {
|
||||
return JsonParser.parseString(
|
||||
"""
|
||||
{
|
||||
"title": "RDAP Terms of Service",
|
||||
"description": [
|
||||
"By querying our Domain Database, you are agreeing to comply with these terms so please read \
|
||||
them carefully.",
|
||||
"Any information provided is 'as is' without any guarantee of accuracy.",
|
||||
"Please do not misuse the Domain Database. It is intended solely for query-based access.",
|
||||
"Don't use the Domain Database to allow, enable, or otherwise support the transmission of mass \
|
||||
unsolicited, commercial advertising or solicitations.",
|
||||
"Don't access our Domain Database through the use of high volume, automated electronic \
|
||||
processes that send queries or data to the systems of any ICANN-accredited registrar.",
|
||||
"You may only use the information contained in the Domain Database for lawful purposes.",
|
||||
"Do not compile, repackage, disseminate, or otherwise use the information contained in the \
|
||||
Domain Database in its entirety, or in any substantial portion, without our prior written \
|
||||
permission.",
|
||||
"We may retain certain details about queries to our Domain Database for the purposes of \
|
||||
detecting and preventing misuse.",
|
||||
"We reserve the right to restrict or deny your access to the database if we suspect that you \
|
||||
have failed to comply with these terms.",
|
||||
"We reserve the right to modify this agreement at any time."
|
||||
],
|
||||
"links": [
|
||||
{
|
||||
"rel": "self",
|
||||
"href": "https://example.tld/rdap/help/tos",
|
||||
"type": "application/rdap+json",
|
||||
"value": "%REQUEST_URL%"
|
||||
},
|
||||
{
|
||||
"rel": "terms-of-service",
|
||||
"href": "https://www.example.tld/about/rdap/tos.html",
|
||||
"type": "text/html",
|
||||
"value": "%REQUEST_URL%"
|
||||
}
|
||||
]
|
||||
}
|
||||
"""
|
||||
.replaceAll("%REQUEST_URL%", action.requestUrl));
|
||||
}
|
||||
|
||||
JsonObject addPermanentBoilerplateNotices(JsonObject jsonObject) {
|
||||
if (!jsonObject.has("notices")) {
|
||||
jsonObject.add("notices", new JsonArray());
|
||||
}
|
||||
JsonArray notices = jsonObject.getAsJsonArray("notices");
|
||||
notices.add(createTosNotice());
|
||||
notices.add(
|
||||
JsonParser.parseString(
|
||||
"""
|
||||
{
|
||||
"description": [
|
||||
"This response conforms to the RDAP Operational Profile for gTLD Registries and Registrars \
|
||||
version 1.0"
|
||||
]
|
||||
}
|
||||
"""));
|
||||
return jsonObject;
|
||||
}
|
||||
|
||||
JsonObject addDomainBoilerplateNotices(JsonObject jsonObject) {
|
||||
addPermanentBoilerplateNotices(jsonObject);
|
||||
JsonArray notices = jsonObject.getAsJsonArray("notices");
|
||||
notices.add(
|
||||
JsonParser.parseString(
|
||||
"""
|
||||
{
|
||||
"title": "Status Codes",
|
||||
"description": [
|
||||
"For more information on domain status codes, please visit https://icann.org/epp"
|
||||
],
|
||||
"links": [
|
||||
{
|
||||
"rel": "glossary",
|
||||
"href": "https://icann.org/epp",
|
||||
"type": "text/html",
|
||||
"value": "%REQUEST_URL%"
|
||||
}
|
||||
]
|
||||
}
|
||||
"""
|
||||
.replaceAll("%REQUEST_URL%", action.requestUrl)));
|
||||
notices.add(
|
||||
JsonParser.parseString(
|
||||
"""
|
||||
{
|
||||
"title": "RDDS Inaccuracy Complaint Form",
|
||||
"description": [
|
||||
"URL of the ICANN RDDS Inaccuracy Complaint Form: https://icann.org/wicf"
|
||||
],
|
||||
"links": [
|
||||
{
|
||||
"rel": "help",
|
||||
"href": "https://icann.org/wicf",
|
||||
"type": "text/html",
|
||||
"value": "%REQUEST_URL%"
|
||||
}
|
||||
]
|
||||
}
|
||||
"""
|
||||
.replaceAll("%REQUEST_URL%", action.requestUrl)));
|
||||
return jsonObject;
|
||||
}
|
||||
|
||||
protected static final class JsonFileBuilder {
|
||||
private final HashMap<String, String> substitutions = new HashMap<>();
|
||||
|
||||
private JsonFileBuilder(String requestUrl) {
|
||||
substitutions.put("REQUEST_URL", requestUrl);
|
||||
}
|
||||
|
||||
public JsonObject load(String filename) {
|
||||
return RdapTestHelper.loadJsonFile(filename, substitutions);
|
||||
}
|
||||
@@ -158,6 +279,14 @@ abstract class RdapActionBaseTestCase<A extends RdapActionBase> {
|
||||
return this;
|
||||
}
|
||||
|
||||
public JsonFileBuilder putAll(String... keysAndValues) {
|
||||
checkArgument(keysAndValues.length % 2 == 0);
|
||||
for (int i = 0; i < keysAndValues.length; i += 2) {
|
||||
put(keysAndValues[i], keysAndValues[i + 1]);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public JsonFileBuilder put(String key, int index, String value) {
|
||||
return put(String.format("%s%d", key, index), value);
|
||||
}
|
||||
@@ -189,10 +318,38 @@ abstract class RdapActionBaseTestCase<A extends RdapActionBase> {
|
||||
return putNext("REGISTRAR_FULL_NAME_", fullName);
|
||||
}
|
||||
|
||||
JsonFileBuilder addFullRegistrar(
|
||||
String handle, @Nullable String fullName, String status, @Nullable String address) {
|
||||
if (fullName != null) {
|
||||
putNext("REGISTRAR_FULLNAME_", fullName);
|
||||
}
|
||||
if (address != null) {
|
||||
putNext("REGISTRAR_ADDRESS_", address);
|
||||
}
|
||||
return putNext("REGISTRAR_HANDLE_", handle, "STATUS_", status);
|
||||
}
|
||||
|
||||
JsonFileBuilder addContact(String handle) {
|
||||
return putNext("CONTACT_HANDLE_", handle);
|
||||
}
|
||||
|
||||
JsonFileBuilder addFullContact(
|
||||
String handle,
|
||||
@Nullable String status,
|
||||
@Nullable String fullName,
|
||||
@Nullable String address) {
|
||||
if (fullName != null) {
|
||||
putNext("CONTACT_FULLNAME_", fullName);
|
||||
}
|
||||
if (address != null) {
|
||||
putNext("CONTACT_ADDRESS_", address);
|
||||
}
|
||||
if (status != null) {
|
||||
putNext("STATUS_", status);
|
||||
}
|
||||
return putNext("CONTACT_HANDLE_", handle);
|
||||
}
|
||||
|
||||
JsonFileBuilder setNextQuery(String nextQuery) {
|
||||
return put("NEXT_QUERY", nextQuery);
|
||||
}
|
||||
|
||||
@@ -59,9 +59,12 @@ final class RdapDataStructuresTest {
|
||||
.setRel("myRel")
|
||||
.setTitle("myTitle")
|
||||
.setType("myType")
|
||||
.setValue("myValue")
|
||||
.build();
|
||||
assertThat(link.toJson())
|
||||
.isEqualTo(createJson("{'href':'myHref','rel':'myRel','title':'myTitle','type':'myType'}"));
|
||||
.isEqualTo(
|
||||
createJson(
|
||||
"{'href':'myHref','rel':'myRel','title':'myTitle','type':'myType','value':'myValue'}"));
|
||||
assertRestrictedNames(link, "links[]");
|
||||
}
|
||||
|
||||
|
||||
@@ -230,16 +230,11 @@ class RdapDomainActionTest extends RdapActionBaseTestCase<RdapDomainAction> {
|
||||
clock.nowUtc().minusMonths(6)));
|
||||
}
|
||||
|
||||
private JsonObject addBoilerplate(JsonObject obj) {
|
||||
RdapTestHelper.addDomainBoilerplateNotices(obj, "https://example.tld/rdap/");
|
||||
return obj;
|
||||
}
|
||||
|
||||
private void assertProperResponseForCatLol(String queryString, String expectedOutputFile) {
|
||||
assertAboutJson()
|
||||
.that(generateActualJson(queryString))
|
||||
.isEqualTo(
|
||||
addBoilerplate(
|
||||
addDomainBoilerplateNotices(
|
||||
jsonFileBuilder()
|
||||
.addDomain("cat.lol", "C-LOL")
|
||||
.addContact("4-ROID")
|
||||
@@ -357,7 +352,7 @@ class RdapDomainActionTest extends RdapActionBaseTestCase<RdapDomainAction> {
|
||||
assertAboutJson()
|
||||
.that(generateActualJson("cat.みんな"))
|
||||
.isEqualTo(
|
||||
addBoilerplate(
|
||||
addDomainBoilerplateNotices(
|
||||
jsonFileBuilder()
|
||||
.addDomain("cat.みんな", "1D-Q9JYB4C")
|
||||
.addContact("19-ROID")
|
||||
@@ -376,7 +371,7 @@ class RdapDomainActionTest extends RdapActionBaseTestCase<RdapDomainAction> {
|
||||
assertAboutJson()
|
||||
.that(generateActualJson("cat.%E3%81%BF%E3%82%93%E3%81%AA"))
|
||||
.isEqualTo(
|
||||
addBoilerplate(
|
||||
addDomainBoilerplateNotices(
|
||||
jsonFileBuilder()
|
||||
.addDomain("cat.みんな", "1D-Q9JYB4C")
|
||||
.addContact("19-ROID")
|
||||
@@ -395,7 +390,7 @@ class RdapDomainActionTest extends RdapActionBaseTestCase<RdapDomainAction> {
|
||||
assertAboutJson()
|
||||
.that(generateActualJson("cat.xn--q9jyb4c"))
|
||||
.isEqualTo(
|
||||
addBoilerplate(
|
||||
addDomainBoilerplateNotices(
|
||||
jsonFileBuilder()
|
||||
.addDomain("cat.みんな", "1D-Q9JYB4C")
|
||||
.addContact("19-ROID")
|
||||
@@ -414,7 +409,7 @@ class RdapDomainActionTest extends RdapActionBaseTestCase<RdapDomainAction> {
|
||||
assertAboutJson()
|
||||
.that(generateActualJson("cat.1.tld"))
|
||||
.isEqualTo(
|
||||
addBoilerplate(
|
||||
addDomainBoilerplateNotices(
|
||||
jsonFileBuilder()
|
||||
.addDomain("cat.1.tld", "25-1_TLD")
|
||||
.addContact("21-ROID")
|
||||
@@ -473,7 +468,7 @@ class RdapDomainActionTest extends RdapActionBaseTestCase<RdapDomainAction> {
|
||||
assertAboutJson()
|
||||
.that(generateActualJson("dodo.lol"))
|
||||
.isEqualTo(
|
||||
addBoilerplate(
|
||||
addDomainBoilerplateNotices(
|
||||
jsonFileBuilder()
|
||||
.addDomain("dodo.lol", "15-LOL")
|
||||
.addContact("11-ROID")
|
||||
@@ -493,7 +488,7 @@ class RdapDomainActionTest extends RdapActionBaseTestCase<RdapDomainAction> {
|
||||
assertAboutJson()
|
||||
.that(generateActualJson("dodo.lol"))
|
||||
.isEqualTo(
|
||||
addBoilerplate(
|
||||
addDomainBoilerplateNotices(
|
||||
jsonFileBuilder()
|
||||
.addDomain("dodo.lol", "15-LOL")
|
||||
.addContact("11-ROID")
|
||||
@@ -512,7 +507,9 @@ class RdapDomainActionTest extends RdapActionBaseTestCase<RdapDomainAction> {
|
||||
"addgraceperiod", "lol", clock.nowUtc(), clock.nowUtc().plusYears(1));
|
||||
assertAboutJson()
|
||||
.that(generateActualJson("addgraceperiod.lol"))
|
||||
.isEqualTo(addBoilerplate(jsonFileBuilder().load("rdap_domain_add_grace_period.json")));
|
||||
.isEqualTo(
|
||||
addDomainBoilerplateNotices(
|
||||
jsonFileBuilder().load("rdap_domain_add_grace_period.json")));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -522,7 +519,8 @@ class RdapDomainActionTest extends RdapActionBaseTestCase<RdapDomainAction> {
|
||||
assertAboutJson()
|
||||
.that(generateActualJson("autorenew.lol"))
|
||||
.isEqualTo(
|
||||
addBoilerplate(jsonFileBuilder().load("rdap_domain_auto_renew_grace_period.json")));
|
||||
addDomainBoilerplateNotices(
|
||||
jsonFileBuilder().load("rdap_domain_auto_renew_grace_period.json")));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -545,7 +543,7 @@ class RdapDomainActionTest extends RdapActionBaseTestCase<RdapDomainAction> {
|
||||
assertAboutJson()
|
||||
.that(generateActualJson("redemption.lol"))
|
||||
.isEqualTo(
|
||||
addBoilerplate(
|
||||
addDomainBoilerplateNotices(
|
||||
jsonFileBuilder().load("rdap_domain_pending_delete_redemption_grace_period.json")));
|
||||
}
|
||||
|
||||
@@ -568,7 +566,8 @@ class RdapDomainActionTest extends RdapActionBaseTestCase<RdapDomainAction> {
|
||||
assertAboutJson()
|
||||
.that(generateActualJson("renew.lol"))
|
||||
.isEqualTo(
|
||||
addBoilerplate(jsonFileBuilder().load("rdap_domain_explicit_renew_grace_period.json")));
|
||||
addDomainBoilerplateNotices(
|
||||
jsonFileBuilder().load("rdap_domain_explicit_renew_grace_period.json")));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -590,7 +589,8 @@ class RdapDomainActionTest extends RdapActionBaseTestCase<RdapDomainAction> {
|
||||
assertAboutJson()
|
||||
.that(generateActualJson("transfer.lol"))
|
||||
.isEqualTo(
|
||||
addBoilerplate(jsonFileBuilder().load("rdap_domain_transfer_grace_period.json")));
|
||||
addDomainBoilerplateNotices(
|
||||
jsonFileBuilder().load("rdap_domain_transfer_grace_period.json")));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -631,12 +631,15 @@ class RdapDomainActionTest extends RdapActionBaseTestCase<RdapDomainAction> {
|
||||
"rel",
|
||||
"alternate",
|
||||
"type",
|
||||
"text/html")));
|
||||
"text/html",
|
||||
"value",
|
||||
"https://example.tld/rdap/domain/example.lol")));
|
||||
JsonObject actuaResponse = generateActualJson("example.lol");
|
||||
JsonObject expectedErrorResponse = generateExpectedJsonError("example.lol blocked by BSA", 404);
|
||||
expectedErrorResponse
|
||||
.getAsJsonArray("notices")
|
||||
.add(RdapTestHelper.GSON.toJsonTree(expectedBsaNotice));
|
||||
assertAboutJson().that(generateActualJson("example.lol")).isEqualTo(expectedErrorResponse);
|
||||
assertAboutJson().that(actuaResponse).isEqualTo(expectedErrorResponse);
|
||||
assertThat(response.getStatus()).isEqualTo(404);
|
||||
}
|
||||
|
||||
|
||||
@@ -473,8 +473,7 @@ class RdapDomainSearchActionTest extends RdapSearchActionTestCase<RdapDomainSear
|
||||
|
||||
private JsonObject wrapInSearchReply(JsonObject obj) {
|
||||
obj = RdapTestHelper.wrapInSearchReply("domainSearchResults", obj);
|
||||
RdapTestHelper.addDomainBoilerplateNotices(obj, "https://example.tld/rdap/");
|
||||
return obj;
|
||||
return addDomainBoilerplateNotices(obj);
|
||||
}
|
||||
|
||||
private void runSuccessfulTest(RequestType requestType, String queryString, JsonObject expected) {
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
package google.registry.rdap;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static google.registry.rdap.RdapTestHelper.loadJsonFile;
|
||||
import static google.registry.testing.DatabaseHelper.createTld;
|
||||
import static google.registry.testing.DatabaseHelper.persistResource;
|
||||
import static google.registry.testing.DatabaseHelper.persistSimpleResources;
|
||||
@@ -28,7 +27,6 @@ import static google.registry.testing.GsonSubject.assertAboutJson;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.gson.JsonObject;
|
||||
import google.registry.model.contact.Contact;
|
||||
import google.registry.model.host.Host;
|
||||
import google.registry.model.registrar.Registrar;
|
||||
@@ -39,13 +37,15 @@ import google.registry.rdap.RdapSearchResults.IncompletenessWarningType;
|
||||
import google.registry.request.Action;
|
||||
import google.registry.testing.FullFieldsTestEntityHelper;
|
||||
import java.util.Optional;
|
||||
import javax.annotation.Nullable;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/** Unit tests for {@link RdapEntityAction}. */
|
||||
class RdapEntityActionTest extends RdapActionBaseTestCase<RdapEntityAction> {
|
||||
|
||||
private static final String CONTACT_NAME = "(◕‿◕)";
|
||||
private static final String CONTACT_ADDRESS = "\"1 Smiley Row\", \"Suite みんな\"";
|
||||
|
||||
RdapEntityActionTest() {
|
||||
super(RdapEntityAction.class);
|
||||
}
|
||||
@@ -67,7 +67,7 @@ class RdapEntityActionTest extends RdapActionBaseTestCase<RdapEntityAction> {
|
||||
registrant =
|
||||
FullFieldsTestEntityHelper.makeAndPersistContact(
|
||||
"8372808-REG",
|
||||
"(◕‿◕)",
|
||||
CONTACT_NAME,
|
||||
"lol@cat.みんな",
|
||||
ImmutableList.of("1 Smiley Row", "Suite みんな"),
|
||||
clock.nowUtc(),
|
||||
@@ -75,7 +75,7 @@ class RdapEntityActionTest extends RdapActionBaseTestCase<RdapEntityAction> {
|
||||
adminContact =
|
||||
FullFieldsTestEntityHelper.makeAndPersistContact(
|
||||
"8372808-ADM",
|
||||
"(◕‿◕)",
|
||||
CONTACT_NAME,
|
||||
"lol@cat.みんな",
|
||||
ImmutableList.of("1 Smiley Row", "Suite みんな"),
|
||||
clock.nowUtc(),
|
||||
@@ -83,7 +83,7 @@ class RdapEntityActionTest extends RdapActionBaseTestCase<RdapEntityAction> {
|
||||
techContact =
|
||||
FullFieldsTestEntityHelper.makeAndPersistContact(
|
||||
"8372808-TEC",
|
||||
"(◕‿◕)",
|
||||
CONTACT_NAME,
|
||||
"lol@cat.みんな",
|
||||
ImmutableList.of("1 Smiley Row", "Suite みんな"),
|
||||
clock.nowUtc(),
|
||||
@@ -110,7 +110,7 @@ class RdapEntityActionTest extends RdapActionBaseTestCase<RdapEntityAction> {
|
||||
disconnectedContact =
|
||||
FullFieldsTestEntityHelper.makeAndPersistContact(
|
||||
"8372808-DIS",
|
||||
"(◕‿◕)",
|
||||
CONTACT_NAME,
|
||||
"lol@cat.みんな",
|
||||
ImmutableList.of("1 Smiley Row", "Suite みんな"),
|
||||
clock.nowUtc(),
|
||||
@@ -123,186 +123,191 @@ class RdapEntityActionTest extends RdapActionBaseTestCase<RdapEntityAction> {
|
||||
clock.nowUtc().minusMonths(6));
|
||||
}
|
||||
|
||||
private JsonObject generateExpectedJson(
|
||||
String handle,
|
||||
String fullName,
|
||||
String status,
|
||||
@Nullable String address,
|
||||
String expectedOutputFile) {
|
||||
return loadJsonFile(
|
||||
expectedOutputFile,
|
||||
"NAME", handle,
|
||||
"FULLNAME", fullName,
|
||||
"ADDRESS", (address == null) ? "\"1 Smiley Row\", \"Suite みんな\"" : address,
|
||||
"TYPE", "entity",
|
||||
"STATUS", status);
|
||||
}
|
||||
|
||||
private JsonObject generateExpectedJsonWithTopLevelEntries(
|
||||
String handle,
|
||||
String expectedOutputFile) {
|
||||
return generateExpectedJsonWithTopLevelEntries(
|
||||
handle, "(◕‿◕)", "active", null, expectedOutputFile);
|
||||
}
|
||||
|
||||
private JsonObject generateExpectedJsonWithTopLevelEntries(
|
||||
String handle,
|
||||
String fullName,
|
||||
String status,
|
||||
String address,
|
||||
String expectedOutputFile) {
|
||||
JsonObject obj = generateExpectedJson(handle, fullName, status, address, expectedOutputFile);
|
||||
RdapTestHelper.addNonDomainBoilerplateNotices(obj, "https://example.tld/rdap/");
|
||||
return obj;
|
||||
}
|
||||
|
||||
private void runSuccessfulHandleTest(String handleQuery, String fileName) {
|
||||
runSuccessfulHandleTest(handleQuery, "(◕‿◕)", "active", null, fileName);
|
||||
}
|
||||
|
||||
private void runSuccessfulHandleTest(String handleQuery, String fullName, String fileName) {
|
||||
runSuccessfulHandleTest(handleQuery, fullName, "active", null, fileName);
|
||||
}
|
||||
|
||||
private void runSuccessfulHandleTest(
|
||||
String handleQuery,
|
||||
String fullName,
|
||||
String rdapStatus,
|
||||
String address,
|
||||
String fileName) {
|
||||
@Test
|
||||
void testUnknownEntity_RoidPattern_notFound() {
|
||||
assertAboutJson()
|
||||
.that(generateActualJson(handleQuery))
|
||||
.isEqualTo(
|
||||
generateExpectedJsonWithTopLevelEntries(
|
||||
handleQuery, fullName, rdapStatus, address, fileName));
|
||||
assertThat(response.getStatus()).isEqualTo(200);
|
||||
}
|
||||
|
||||
private void runNotFoundTest(String handleQuery) {
|
||||
assertAboutJson()
|
||||
.that(generateActualJson(handleQuery))
|
||||
.isEqualTo(generateExpectedJsonError(handleQuery + " not found", 404));
|
||||
.that(generateActualJson("_MISSING-ENTITY_"))
|
||||
.isEqualTo(generateExpectedJsonError("_MISSING-ENTITY_ not found", 404));
|
||||
assertThat(response.getStatus()).isEqualTo(404);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testUnknownEntity_RoidPattern_notFound() {
|
||||
runNotFoundTest("_MISSING-ENTITY_");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testUnknownEntity_IanaPattern_notFound() {
|
||||
runNotFoundTest("123");
|
||||
assertAboutJson()
|
||||
.that(generateActualJson("123"))
|
||||
.isEqualTo(generateExpectedJsonError("123 not found", 404));
|
||||
assertThat(response.getStatus()).isEqualTo(404);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testUnknownEntity_notRoidNotIana_notFound() {
|
||||
// Since we allow search by registrar name, every string is a possible name
|
||||
runNotFoundTest("some,random,string");
|
||||
assertAboutJson()
|
||||
.that(generateActualJson("some,random,string"))
|
||||
.isEqualTo(generateExpectedJsonError("some,random,string not found", 404));
|
||||
assertThat(response.getStatus()).isEqualTo(404);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testValidRegistrantContact_works() {
|
||||
login("evilregistrar");
|
||||
runSuccessfulHandleTest(registrant.getRepoId(), "rdap_associated_contact.json");
|
||||
assertAboutJson()
|
||||
.that(generateActualJson(registrant.getRepoId()))
|
||||
.isEqualTo(
|
||||
addPermanentBoilerplateNotices(
|
||||
jsonFileBuilder()
|
||||
.addFullContact(registrant.getRepoId(), null, CONTACT_NAME, CONTACT_ADDRESS)
|
||||
.load("rdap_associated_contact.json")));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testValidRegistrantContact_found_asAdministrator() {
|
||||
loginAsAdmin();
|
||||
runSuccessfulHandleTest(registrant.getRepoId(), "rdap_associated_contact.json");
|
||||
assertAboutJson()
|
||||
.that(generateActualJson(registrant.getRepoId()))
|
||||
.isEqualTo(
|
||||
addPermanentBoilerplateNotices(
|
||||
jsonFileBuilder()
|
||||
.addFullContact(registrant.getRepoId(), null, CONTACT_NAME, CONTACT_ADDRESS)
|
||||
.load("rdap_associated_contact.json")));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testValidRegistrantContact_found_notLoggedIn() {
|
||||
runSuccessfulHandleTest(
|
||||
registrant.getRepoId(),
|
||||
"(◕‿◕)",
|
||||
"active",
|
||||
null,
|
||||
"rdap_associated_contact_no_personal_data.json");
|
||||
assertAboutJson()
|
||||
.that(generateActualJson(registrant.getRepoId()))
|
||||
.isEqualTo(
|
||||
addPermanentBoilerplateNotices(
|
||||
jsonFileBuilder()
|
||||
.addFullContact(registrant.getRepoId(), "active", CONTACT_NAME, CONTACT_ADDRESS)
|
||||
.load("rdap_associated_contact_no_personal_data.json")));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testValidRegistrantContact_found_loggedInAsOtherRegistrar() {
|
||||
login("otherregistrar");
|
||||
runSuccessfulHandleTest(
|
||||
registrant.getRepoId(),
|
||||
"(◕‿◕)",
|
||||
"active",
|
||||
null,
|
||||
"rdap_associated_contact_no_personal_data.json");
|
||||
assertAboutJson()
|
||||
.that(generateActualJson(registrant.getRepoId()))
|
||||
.isEqualTo(
|
||||
addPermanentBoilerplateNotices(
|
||||
jsonFileBuilder()
|
||||
.addFullContact(registrant.getRepoId(), "active", CONTACT_NAME, CONTACT_ADDRESS)
|
||||
.load("rdap_associated_contact_no_personal_data.json")));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testValidAdminContact_works() {
|
||||
login("evilregistrar");
|
||||
runSuccessfulHandleTest(adminContact.getRepoId(), "rdap_associated_contact.json");
|
||||
assertAboutJson()
|
||||
.that(generateActualJson(adminContact.getRepoId()))
|
||||
.isEqualTo(
|
||||
addPermanentBoilerplateNotices(
|
||||
jsonFileBuilder()
|
||||
.addFullContact(adminContact.getRepoId(), null, CONTACT_NAME, CONTACT_ADDRESS)
|
||||
.load("rdap_associated_contact.json")));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testValidTechContact_works() {
|
||||
login("evilregistrar");
|
||||
runSuccessfulHandleTest(techContact.getRepoId(), "rdap_associated_contact.json");
|
||||
assertAboutJson()
|
||||
.that(generateActualJson(techContact.getRepoId()))
|
||||
.isEqualTo(
|
||||
addPermanentBoilerplateNotices(
|
||||
jsonFileBuilder()
|
||||
.addFullContact(techContact.getRepoId(), null, CONTACT_NAME, CONTACT_ADDRESS)
|
||||
.load("rdap_associated_contact.json")));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testValidDisconnectedContact_works() {
|
||||
login("evilregistrar");
|
||||
runSuccessfulHandleTest(disconnectedContact.getRepoId(), "rdap_contact.json");
|
||||
assertAboutJson()
|
||||
.that(generateActualJson(disconnectedContact.getRepoId()))
|
||||
.isEqualTo(
|
||||
addPermanentBoilerplateNotices(
|
||||
jsonFileBuilder()
|
||||
.addFullContact(
|
||||
disconnectedContact.getRepoId(), "active", CONTACT_NAME, CONTACT_ADDRESS)
|
||||
.load("rdap_contact.json")));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDeletedContact_notFound() {
|
||||
runNotFoundTest(deletedContact.getRepoId());
|
||||
String repoId = deletedContact.getRepoId();
|
||||
assertAboutJson()
|
||||
.that(generateActualJson(repoId))
|
||||
.isEqualTo(generateExpectedJsonError(repoId + " not found", 404));
|
||||
assertThat(response.getStatus()).isEqualTo(404);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDeletedContact_notFound_includeDeletedSetFalse() {
|
||||
action.includeDeletedParam = Optional.of(false);
|
||||
runNotFoundTest(deletedContact.getRepoId());
|
||||
String repoId = deletedContact.getRepoId();
|
||||
assertAboutJson()
|
||||
.that(generateActualJson(repoId))
|
||||
.isEqualTo(generateExpectedJsonError(repoId + " not found", 404));
|
||||
assertThat(response.getStatus()).isEqualTo(404);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDeletedContact_notFound_notLoggedIn() {
|
||||
action.includeDeletedParam = Optional.of(true);
|
||||
runNotFoundTest(deletedContact.getRepoId());
|
||||
String repoId = deletedContact.getRepoId();
|
||||
assertAboutJson()
|
||||
.that(generateActualJson(repoId))
|
||||
.isEqualTo(generateExpectedJsonError(repoId + " not found", 404));
|
||||
assertThat(response.getStatus()).isEqualTo(404);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDeletedContact_notFound_loggedInAsDifferentRegistrar() {
|
||||
login("idnregistrar");
|
||||
action.includeDeletedParam = Optional.of(true);
|
||||
runNotFoundTest(deletedContact.getRepoId());
|
||||
String repoId = deletedContact.getRepoId();
|
||||
assertAboutJson()
|
||||
.that(generateActualJson(repoId))
|
||||
.isEqualTo(generateExpectedJsonError(repoId + " not found", 404));
|
||||
assertThat(response.getStatus()).isEqualTo(404);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDeletedContact_found_loggedInAsCorrectRegistrar() {
|
||||
login("evilregistrar");
|
||||
action.includeDeletedParam = Optional.of(true);
|
||||
runSuccessfulHandleTest(
|
||||
deletedContact.getRepoId(),
|
||||
"",
|
||||
"inactive",
|
||||
"",
|
||||
"rdap_contact_deleted.json");
|
||||
assertAboutJson()
|
||||
.that(generateActualJson(deletedContact.getRepoId()))
|
||||
.isEqualTo(
|
||||
addPermanentBoilerplateNotices(
|
||||
jsonFileBuilder()
|
||||
.addContact(deletedContact.getRepoId())
|
||||
.load("rdap_contact_deleted.json")));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDeletedContact_found_loggedInAsAdmin() {
|
||||
loginAsAdmin();
|
||||
action.includeDeletedParam = Optional.of(true);
|
||||
runSuccessfulHandleTest(
|
||||
deletedContact.getRepoId(),
|
||||
"",
|
||||
"inactive",
|
||||
"",
|
||||
"rdap_contact_deleted.json");
|
||||
assertAboutJson()
|
||||
.that(generateActualJson(deletedContact.getRepoId()))
|
||||
.isEqualTo(
|
||||
addPermanentBoilerplateNotices(
|
||||
jsonFileBuilder()
|
||||
.addContact(deletedContact.getRepoId())
|
||||
.load("rdap_contact_deleted.json")));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testRegistrar_found() {
|
||||
runSuccessfulHandleTest("101", "Yes Virginia <script>", "rdap_registrar.json");
|
||||
assertAboutJson()
|
||||
.that(generateActualJson("101"))
|
||||
.isEqualTo(
|
||||
addPermanentBoilerplateNotices(
|
||||
jsonFileBuilder()
|
||||
.addFullRegistrar("101", "Yes Virginia <script>", "active", null)
|
||||
.load("rdap_registrar.json")));
|
||||
assertThat(response.getStatus()).isEqualTo(200);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -310,58 +315,97 @@ class RdapEntityActionTest extends RdapActionBaseTestCase<RdapEntityAction> {
|
||||
assertAboutJson()
|
||||
.that(generateActualJson("IDN%20Registrar"))
|
||||
.isEqualTo(
|
||||
generateExpectedJsonWithTopLevelEntries(
|
||||
"102", "IDN Registrar", "active", null, "rdap_registrar.json"));
|
||||
addPermanentBoilerplateNotices(
|
||||
jsonFileBuilder()
|
||||
.addFullRegistrar("102", "IDN Registrar", "active", null)
|
||||
.load("rdap_registrar.json")));
|
||||
assertThat(response.getStatus()).isEqualTo(200);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testRegistrar102_works() {
|
||||
runSuccessfulHandleTest("102", "IDN Registrar", "rdap_registrar.json");
|
||||
assertAboutJson()
|
||||
.that(generateActualJson("102"))
|
||||
.isEqualTo(
|
||||
addPermanentBoilerplateNotices(
|
||||
jsonFileBuilder()
|
||||
.addFullRegistrar("102", "IDN Registrar", "active", null)
|
||||
.load("rdap_registrar.json")));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testRegistrar103_works() {
|
||||
runSuccessfulHandleTest("103", "Multilevel Registrar", "rdap_registrar.json");
|
||||
assertAboutJson()
|
||||
.that(generateActualJson("103"))
|
||||
.isEqualTo(
|
||||
addPermanentBoilerplateNotices(
|
||||
jsonFileBuilder()
|
||||
.addFullRegistrar("103", "Multilevel Registrar", "active", null)
|
||||
.load("rdap_registrar.json")));
|
||||
assertThat(response.getStatus()).isEqualTo(200);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testRegistrar104_notFound() {
|
||||
runNotFoundTest("104");
|
||||
assertAboutJson()
|
||||
.that(generateActualJson("104"))
|
||||
.isEqualTo(generateExpectedJsonError("104 not found", 404));
|
||||
assertThat(response.getStatus()).isEqualTo(404);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testRegistrar104_notFound_deletedFlagWhenNotLoggedIn() {
|
||||
action.includeDeletedParam = Optional.of(true);
|
||||
runNotFoundTest("104");
|
||||
assertAboutJson()
|
||||
.that(generateActualJson("104"))
|
||||
.isEqualTo(generateExpectedJsonError("104 not found", 404));
|
||||
assertThat(response.getStatus()).isEqualTo(404);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testRegistrar104_found_deletedFlagWhenLoggedIn() {
|
||||
login("deletedregistrar");
|
||||
action.includeDeletedParam = Optional.of(true);
|
||||
runSuccessfulHandleTest(
|
||||
"104", "Yes Virginia <script>", "inactive", null, "rdap_registrar.json");
|
||||
assertAboutJson()
|
||||
.that(generateActualJson("104"))
|
||||
.isEqualTo(
|
||||
addPermanentBoilerplateNotices(
|
||||
jsonFileBuilder()
|
||||
.addFullRegistrar("104", "Yes Virginia <script>", "inactive", null)
|
||||
.load("rdap_registrar.json")));
|
||||
assertThat(response.getStatus()).isEqualTo(200);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testRegistrar104_notFound_deletedFlagWhenLoggedInAsOther() {
|
||||
login("1tldregistrar");
|
||||
action.includeDeletedParam = Optional.of(true);
|
||||
runNotFoundTest("104");
|
||||
assertAboutJson()
|
||||
.that(generateActualJson("104"))
|
||||
.isEqualTo(generateExpectedJsonError("104 not found", 404));
|
||||
assertThat(response.getStatus()).isEqualTo(404);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testRegistrar104_found_deletedFlagWhenLoggedInAsAdmin() {
|
||||
loginAsAdmin();
|
||||
action.includeDeletedParam = Optional.of(true);
|
||||
runSuccessfulHandleTest(
|
||||
"104", "Yes Virginia <script>", "inactive", null, "rdap_registrar.json");
|
||||
assertAboutJson()
|
||||
.that(generateActualJson("104"))
|
||||
.isEqualTo(
|
||||
addPermanentBoilerplateNotices(
|
||||
jsonFileBuilder()
|
||||
.addFullRegistrar("104", "Yes Virginia <script>", "inactive", null)
|
||||
.load("rdap_registrar.json")));
|
||||
assertThat(response.getStatus()).isEqualTo(200);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testRegistrar105_doesNotExist() {
|
||||
runNotFoundTest("105");
|
||||
assertAboutJson()
|
||||
.that(generateActualJson("105"))
|
||||
.isEqualTo(generateExpectedJsonError("105 not found", 404));
|
||||
assertThat(response.getStatus()).isEqualTo(404);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -370,8 +414,10 @@ class RdapEntityActionTest extends RdapActionBaseTestCase<RdapEntityAction> {
|
||||
assertAboutJson()
|
||||
.that(generateActualJson(techContact.getRepoId() + "?key=value"))
|
||||
.isEqualTo(
|
||||
generateExpectedJsonWithTopLevelEntries(
|
||||
techContact.getRepoId(), "rdap_associated_contact.json"));
|
||||
addPermanentBoilerplateNotices(
|
||||
jsonFileBuilder()
|
||||
.addFullContact(techContact.getRepoId(), null, CONTACT_NAME, CONTACT_ADDRESS)
|
||||
.load("rdap_associated_contact.json")));
|
||||
assertThat(response.getStatus()).isEqualTo(200);
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
package google.registry.rdap;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static google.registry.rdap.RdapTestHelper.loadJsonFile;
|
||||
import static google.registry.rdap.RdapTestHelper.parseJsonObject;
|
||||
import static google.registry.request.Action.Method.GET;
|
||||
import static google.registry.testing.DatabaseHelper.createTld;
|
||||
@@ -30,7 +29,6 @@ import static google.registry.testing.GsonSubject.assertAboutJson;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableListMultimap;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
@@ -45,13 +43,15 @@ import google.registry.testing.FakeResponse;
|
||||
import google.registry.testing.FullFieldsTestEntityHelper;
|
||||
import java.net.URLDecoder;
|
||||
import java.util.Optional;
|
||||
import javax.annotation.Nullable;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/** Unit tests for {@link RdapEntitySearchAction}. */
|
||||
class RdapEntitySearchActionTest extends RdapSearchActionTestCase<RdapEntitySearchAction> {
|
||||
|
||||
private static final String BINKY_ADDRESS = "\"123 Blinky St\", \"Blinkyland\"";
|
||||
private static final String BINKY_FULL_NAME = "Blinky (赤ベイ)";
|
||||
|
||||
RdapEntitySearchActionTest() {
|
||||
super(RdapEntitySearchAction.class);
|
||||
}
|
||||
@@ -128,7 +128,7 @@ class RdapEntitySearchActionTest extends RdapSearchActionTestCase<RdapEntitySear
|
||||
|
||||
FullFieldsTestEntityHelper.makeAndPersistContact(
|
||||
"blinky",
|
||||
"Blinky (赤ベイ)",
|
||||
BINKY_FULL_NAME,
|
||||
"blinky@b.tld",
|
||||
ImmutableList.of("123 Blinky St", "Blinkyland"),
|
||||
clock.nowUtc(),
|
||||
@@ -150,45 +150,9 @@ class RdapEntitySearchActionTest extends RdapSearchActionTestCase<RdapEntitySear
|
||||
action.subtypeParam = Optional.empty();
|
||||
}
|
||||
|
||||
private JsonObject generateExpectedJson(String expectedOutputFile) {
|
||||
return loadJsonFile(expectedOutputFile, "TYPE", "entity");
|
||||
}
|
||||
|
||||
private JsonObject generateExpectedJson(
|
||||
String handle,
|
||||
String expectedOutputFile) {
|
||||
return generateExpectedJson(handle, null, "active", null, expectedOutputFile);
|
||||
}
|
||||
|
||||
private JsonObject generateExpectedJson(
|
||||
String handle,
|
||||
@Nullable String fullName,
|
||||
String status,
|
||||
@Nullable String address,
|
||||
String expectedOutputFile) {
|
||||
ImmutableMap.Builder<String, String> builder = new ImmutableMap.Builder<>();
|
||||
builder.put("NAME", handle);
|
||||
if (fullName != null) {
|
||||
builder.put("FULLNAME", fullName);
|
||||
}
|
||||
if (address != null) {
|
||||
builder.put("ADDRESS", address);
|
||||
}
|
||||
builder.put("TYPE", "entity");
|
||||
builder.put("STATUS", status);
|
||||
return loadJsonFile(expectedOutputFile, builder.build());
|
||||
}
|
||||
|
||||
private JsonObject generateExpectedJsonForEntity(
|
||||
String handle,
|
||||
String fullName,
|
||||
String status,
|
||||
@Nullable String address,
|
||||
String expectedOutputFile) {
|
||||
JsonObject obj = generateExpectedJson(handle, fullName, status, address, expectedOutputFile);
|
||||
obj = RdapTestHelper.wrapInSearchReply("entitySearchResults", obj);
|
||||
RdapTestHelper.addNonDomainBoilerplateNotices(obj, "https://example.tld/rdap/");
|
||||
return obj;
|
||||
private JsonObject addBoilerplate(JsonObject jsonObject) {
|
||||
jsonObject = RdapTestHelper.wrapInSearchReply("entitySearchResults", jsonObject);
|
||||
return addPermanentBoilerplateNotices(jsonObject);
|
||||
}
|
||||
|
||||
private void createManyContactsAndRegistrars(
|
||||
@@ -259,38 +223,6 @@ class RdapEntitySearchActionTest extends RdapSearchActionTestCase<RdapEntitySear
|
||||
verifyMetrics(numContactsRetrieved);
|
||||
}
|
||||
|
||||
private void runSuccessfulNameTestWithBlinky(String queryString, String fileName) {
|
||||
runSuccessfulNameTest(
|
||||
queryString,
|
||||
"2-ROID",
|
||||
"Blinky (赤ベイ)",
|
||||
"active",
|
||||
"\"123 Blinky St\", \"Blinkyland\"",
|
||||
fileName);
|
||||
}
|
||||
|
||||
private void runSuccessfulNameTest(
|
||||
String queryString,
|
||||
String handle,
|
||||
@Nullable String fullName,
|
||||
String fileName) {
|
||||
runSuccessfulNameTest(queryString, handle, fullName, "active", null, fileName);
|
||||
}
|
||||
|
||||
private void runSuccessfulNameTest(
|
||||
String queryString,
|
||||
String handle,
|
||||
@Nullable String fullName,
|
||||
String status,
|
||||
@Nullable String address,
|
||||
String fileName) {
|
||||
rememberWildcardType(queryString);
|
||||
assertAboutJson()
|
||||
.that(generateActualJsonWithFullName(queryString))
|
||||
.isEqualTo(generateExpectedJsonForEntity(handle, fullName, status, address, fileName));
|
||||
assertThat(response.getStatus()).isEqualTo(200);
|
||||
}
|
||||
|
||||
private void runNotFoundNameTest(String queryString) {
|
||||
rememberWildcardType(queryString);
|
||||
assertAboutJson()
|
||||
@@ -299,38 +231,6 @@ class RdapEntitySearchActionTest extends RdapSearchActionTestCase<RdapEntitySear
|
||||
assertThat(response.getStatus()).isEqualTo(404);
|
||||
}
|
||||
|
||||
private void runSuccessfulHandleTestWithBlinky(String queryString, String fileName) {
|
||||
runSuccessfulHandleTest(
|
||||
queryString,
|
||||
"2-ROID",
|
||||
"Blinky (赤ベイ)",
|
||||
"active",
|
||||
"\"123 Blinky St\", \"Blinkyland\"",
|
||||
fileName);
|
||||
}
|
||||
|
||||
private void runSuccessfulHandleTest(
|
||||
String queryString,
|
||||
String handle,
|
||||
@Nullable String fullName,
|
||||
String fileName) {
|
||||
runSuccessfulHandleTest(queryString, handle, fullName, "active", null, fileName);
|
||||
}
|
||||
|
||||
private void runSuccessfulHandleTest(
|
||||
String queryString,
|
||||
String handle,
|
||||
@Nullable String fullName,
|
||||
String status,
|
||||
@Nullable String address,
|
||||
String fileName) {
|
||||
rememberWildcardType(queryString);
|
||||
assertAboutJson()
|
||||
.that(generateActualJsonWithHandle(queryString))
|
||||
.isEqualTo(generateExpectedJsonForEntity(handle, fullName, status, address, fileName));
|
||||
assertThat(response.getStatus()).isEqualTo(200);
|
||||
}
|
||||
|
||||
private void runNotFoundHandleTest(String queryString) {
|
||||
rememberWildcardType(queryString);
|
||||
assertAboutJson()
|
||||
@@ -470,7 +370,7 @@ class RdapEntitySearchActionTest extends RdapSearchActionTestCase<RdapEntitySear
|
||||
void testInvalidSubtype_rejected() {
|
||||
action.subtypeParam = Optional.of("Space Aliens");
|
||||
assertAboutJson()
|
||||
.that(generateActualJsonWithFullName("Blinky (赤ベイ)"))
|
||||
.that(generateActualJsonWithFullName(BINKY_FULL_NAME))
|
||||
.isEqualTo(
|
||||
generateExpectedJsonError(
|
||||
"Subtype parameter must specify contacts, registrars or all", 400));
|
||||
@@ -482,23 +382,44 @@ class RdapEntitySearchActionTest extends RdapSearchActionTestCase<RdapEntitySear
|
||||
@Test
|
||||
void testNameMatchContact_found() {
|
||||
login("2-RegistrarTest");
|
||||
runSuccessfulNameTestWithBlinky("Blinky (赤ベイ)", "rdap_contact.json");
|
||||
rememberWildcardType(BINKY_FULL_NAME);
|
||||
assertAboutJson()
|
||||
.that(generateActualJsonWithFullName(BINKY_FULL_NAME))
|
||||
.isEqualTo(
|
||||
addBoilerplate(
|
||||
jsonFileBuilder()
|
||||
.addFullContact("2-ROID", "active", BINKY_FULL_NAME, BINKY_ADDRESS)
|
||||
.load("rdap_contact.json")));
|
||||
verifyMetrics(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testNameMatchContact_found_subtypeAll() {
|
||||
login("2-RegistrarTest");
|
||||
rememberWildcardType(BINKY_FULL_NAME);
|
||||
action.subtypeParam = Optional.of("aLl");
|
||||
runSuccessfulNameTestWithBlinky("Blinky (赤ベイ)", "rdap_contact.json");
|
||||
assertAboutJson()
|
||||
.that(generateActualJsonWithFullName(BINKY_FULL_NAME))
|
||||
.isEqualTo(
|
||||
addBoilerplate(
|
||||
jsonFileBuilder()
|
||||
.addFullContact("2-ROID", "active", BINKY_FULL_NAME, BINKY_ADDRESS)
|
||||
.load("rdap_contact.json")));
|
||||
verifyMetrics(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testNameMatchContact_found_subtypeContacts() {
|
||||
login("2-RegistrarTest");
|
||||
rememberWildcardType(BINKY_FULL_NAME);
|
||||
action.subtypeParam = Optional.of("cONTACTS");
|
||||
runSuccessfulNameTestWithBlinky("Blinky (赤ベイ)", "rdap_contact.json");
|
||||
assertAboutJson()
|
||||
.that(generateActualJsonWithFullName(BINKY_FULL_NAME))
|
||||
.isEqualTo(
|
||||
addBoilerplate(
|
||||
jsonFileBuilder()
|
||||
.addFullContact("2-ROID", "active", BINKY_FULL_NAME, BINKY_ADDRESS)
|
||||
.load("rdap_contact.json")));
|
||||
verifyMetrics(1);
|
||||
}
|
||||
|
||||
@@ -506,15 +427,22 @@ class RdapEntitySearchActionTest extends RdapSearchActionTestCase<RdapEntitySear
|
||||
void testNameMatchContact_notFound_subtypeRegistrars() {
|
||||
login("2-RegistrarTest");
|
||||
action.subtypeParam = Optional.of("Registrars");
|
||||
runNotFoundNameTest("Blinky (赤ベイ)");
|
||||
runNotFoundNameTest(BINKY_FULL_NAME);
|
||||
verifyErrorMetrics(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testNameMatchContact_found_specifyingSameRegistrar() {
|
||||
login("2-RegistrarTest");
|
||||
rememberWildcardType(BINKY_FULL_NAME);
|
||||
action.registrarParam = Optional.of("2-RegistrarTest");
|
||||
runSuccessfulNameTestWithBlinky("Blinky (赤ベイ)", "rdap_contact.json");
|
||||
assertAboutJson()
|
||||
.that(generateActualJsonWithFullName(BINKY_FULL_NAME))
|
||||
.isEqualTo(
|
||||
addBoilerplate(
|
||||
jsonFileBuilder()
|
||||
.addFullContact("2-ROID", "active", BINKY_FULL_NAME, BINKY_ADDRESS)
|
||||
.load("rdap_contact.json")));
|
||||
verifyMetrics(1);
|
||||
}
|
||||
|
||||
@@ -522,35 +450,48 @@ class RdapEntitySearchActionTest extends RdapSearchActionTestCase<RdapEntitySear
|
||||
void testNameMatchContact_notFound_specifyingOtherRegistrar() {
|
||||
login("2-RegistrarTest");
|
||||
action.registrarParam = Optional.of("2-RegistrarInact");
|
||||
runNotFoundNameTest("Blinky (赤ベイ)");
|
||||
runNotFoundNameTest(BINKY_FULL_NAME);
|
||||
verifyErrorMetrics(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testNameMatchContact_found_asAdministrator() {
|
||||
loginAsAdmin();
|
||||
rememberWildcardType("Blinky (赤ベイ)");
|
||||
runSuccessfulNameTestWithBlinky("Blinky (赤ベイ)", "rdap_contact.json");
|
||||
rememberWildcardType(BINKY_FULL_NAME);
|
||||
assertAboutJson()
|
||||
.that(generateActualJsonWithFullName(BINKY_FULL_NAME))
|
||||
.isEqualTo(
|
||||
addBoilerplate(
|
||||
jsonFileBuilder()
|
||||
.addFullContact("2-ROID", "active", BINKY_FULL_NAME, BINKY_ADDRESS)
|
||||
.load("rdap_contact.json")));
|
||||
verifyMetrics(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testNameMatchContact_notFound_notLoggedIn() {
|
||||
runNotFoundNameTest("Blinky (赤ベイ)");
|
||||
runNotFoundNameTest(BINKY_FULL_NAME);
|
||||
verifyErrorMetrics(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testNameMatchContact_notFound_loggedInAsOtherRegistrar() {
|
||||
login("2-Registrar");
|
||||
runNotFoundNameTest("Blinky (赤ベイ)");
|
||||
runNotFoundNameTest(BINKY_FULL_NAME);
|
||||
verifyErrorMetrics(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testNameMatchContact_found_wildcard() {
|
||||
login("2-RegistrarTest");
|
||||
runSuccessfulNameTestWithBlinky("Blinky*", "rdap_contact.json");
|
||||
rememberWildcardType("Blinky*");
|
||||
assertAboutJson()
|
||||
.that(generateActualJsonWithFullName("Blinky*"))
|
||||
.isEqualTo(
|
||||
addBoilerplate(
|
||||
jsonFileBuilder()
|
||||
.addFullContact("2-ROID", "active", BINKY_FULL_NAME, BINKY_ADDRESS)
|
||||
.load("rdap_contact.json")));
|
||||
verifyMetrics(1);
|
||||
}
|
||||
|
||||
@@ -558,7 +499,14 @@ class RdapEntitySearchActionTest extends RdapSearchActionTestCase<RdapEntitySear
|
||||
void testNameMatchContact_found_wildcardSpecifyingSameRegistrar() {
|
||||
login("2-RegistrarTest");
|
||||
action.registrarParam = Optional.of("2-RegistrarTest");
|
||||
runSuccessfulNameTestWithBlinky("Blinky*", "rdap_contact.json");
|
||||
rememberWildcardType("Blinky*");
|
||||
assertAboutJson()
|
||||
.that(generateActualJsonWithFullName("Blinky*"))
|
||||
.isEqualTo(
|
||||
addBoilerplate(
|
||||
jsonFileBuilder()
|
||||
.addFullContact("2-ROID", "active", BINKY_FULL_NAME, BINKY_ADDRESS)
|
||||
.load("rdap_contact.json")));
|
||||
verifyMetrics(1);
|
||||
}
|
||||
|
||||
@@ -576,7 +524,7 @@ class RdapEntitySearchActionTest extends RdapSearchActionTestCase<RdapEntitySear
|
||||
rememberWildcardType("Blin*");
|
||||
assertAboutJson()
|
||||
.that(generateActualJsonWithFullName("Blin*"))
|
||||
.isEqualTo(generateExpectedJson("rdap_multiple_contacts2.json"));
|
||||
.isEqualTo(jsonFileBuilder().load("rdap_multiple_contacts2.json"));
|
||||
assertThat(response.getStatus()).isEqualTo(200);
|
||||
verifyMetrics(2);
|
||||
}
|
||||
@@ -615,8 +563,14 @@ class RdapEntitySearchActionTest extends RdapSearchActionTestCase<RdapEntitySear
|
||||
@Test
|
||||
void testNameMatchRegistrar_found() {
|
||||
login("2-RegistrarTest");
|
||||
runSuccessfulNameTest(
|
||||
"Yes Virginia <script>", "20", "Yes Virginia <script>", "rdap_registrar.json");
|
||||
rememberWildcardType("Yes Virginia <script>");
|
||||
assertAboutJson()
|
||||
.that(generateActualJsonWithFullName("Yes Virginia <script>"))
|
||||
.isEqualTo(
|
||||
addBoilerplate(
|
||||
jsonFileBuilder()
|
||||
.addFullRegistrar("20", "Yes Virginia <script>", "active", null)
|
||||
.load("rdap_registrar.json")));
|
||||
verifyMetrics(0);
|
||||
}
|
||||
|
||||
@@ -624,8 +578,14 @@ class RdapEntitySearchActionTest extends RdapSearchActionTestCase<RdapEntitySear
|
||||
void testNameMatchRegistrar_found_subtypeAll() {
|
||||
login("2-RegistrarTest");
|
||||
action.subtypeParam = Optional.of("all");
|
||||
runSuccessfulNameTest(
|
||||
"Yes Virginia <script>", "20", "Yes Virginia <script>", "rdap_registrar.json");
|
||||
rememberWildcardType("Yes Virginia <script>");
|
||||
assertAboutJson()
|
||||
.that(generateActualJsonWithFullName("Yes Virginia <script>"))
|
||||
.isEqualTo(
|
||||
addBoilerplate(
|
||||
jsonFileBuilder()
|
||||
.addFullRegistrar("20", "Yes Virginia <script>", "active", null)
|
||||
.load("rdap_registrar.json")));
|
||||
verifyMetrics(0);
|
||||
}
|
||||
|
||||
@@ -633,8 +593,14 @@ class RdapEntitySearchActionTest extends RdapSearchActionTestCase<RdapEntitySear
|
||||
void testNameMatchRegistrar_found_subtypeRegistrars() {
|
||||
login("2-RegistrarTest");
|
||||
action.subtypeParam = Optional.of("REGISTRARS");
|
||||
runSuccessfulNameTest(
|
||||
"Yes Virginia <script>", "20", "Yes Virginia <script>", "rdap_registrar.json");
|
||||
rememberWildcardType("Yes Virginia <script>");
|
||||
assertAboutJson()
|
||||
.that(generateActualJsonWithFullName("Yes Virginia <script>"))
|
||||
.isEqualTo(
|
||||
addBoilerplate(
|
||||
jsonFileBuilder()
|
||||
.addFullRegistrar("20", "Yes Virginia <script>", "active", null)
|
||||
.load("rdap_registrar.json")));
|
||||
verifyMetrics(0);
|
||||
}
|
||||
|
||||
@@ -649,8 +615,14 @@ class RdapEntitySearchActionTest extends RdapSearchActionTestCase<RdapEntitySear
|
||||
@Test
|
||||
void testNameMatchRegistrar_found_specifyingSameRegistrar() {
|
||||
action.registrarParam = Optional.of("2-Registrar");
|
||||
runSuccessfulNameTest(
|
||||
"Yes Virginia <script>", "20", "Yes Virginia <script>", "rdap_registrar.json");
|
||||
rememberWildcardType("Yes Virginia <script>");
|
||||
assertAboutJson()
|
||||
.that(generateActualJsonWithFullName("Yes Virginia <script>"))
|
||||
.isEqualTo(
|
||||
addBoilerplate(
|
||||
jsonFileBuilder()
|
||||
.addFullRegistrar("20", "Yes Virginia <script>", "active", null)
|
||||
.load("rdap_registrar.json")));
|
||||
verifyMetrics(0);
|
||||
}
|
||||
|
||||
@@ -666,10 +638,9 @@ class RdapEntitySearchActionTest extends RdapSearchActionTestCase<RdapEntitySear
|
||||
login("2-RegistrarTest");
|
||||
createManyContactsAndRegistrars(4, 0, registrarTest);
|
||||
rememberWildcardType("Entity *");
|
||||
// JsonObject foo = generateActualJsonWithFullName("Entity *");
|
||||
assertAboutJson()
|
||||
.that(generateActualJsonWithFullName("Entity *"))
|
||||
.isEqualTo(generateExpectedJson("rdap_nontruncated_contacts.json"));
|
||||
.isEqualTo(jsonFileBuilder().load("rdap_nontruncated_contacts.json"));
|
||||
assertThat(response.getStatus()).isEqualTo(200);
|
||||
verifyMetrics(4);
|
||||
}
|
||||
@@ -682,8 +653,9 @@ class RdapEntitySearchActionTest extends RdapSearchActionTestCase<RdapEntitySear
|
||||
assertAboutJson()
|
||||
.that(generateActualJsonWithFullName("Entity *"))
|
||||
.isEqualTo(
|
||||
generateExpectedJson(
|
||||
"fn=Entity+*&cursor=YzpFbnRpdHkgNA%3D%3D", "rdap_truncated_contacts.json"));
|
||||
jsonFileBuilder()
|
||||
.put("NAME", "fn=Entity+*&cursor=YzpFbnRpdHkgNA%3D%3D")
|
||||
.load("rdap_truncated_contacts.json"));
|
||||
assertThat(response.getStatus()).isEqualTo(200);
|
||||
verifyMetrics(5, IncompletenessWarningType.TRUNCATED);
|
||||
}
|
||||
@@ -696,8 +668,9 @@ class RdapEntitySearchActionTest extends RdapSearchActionTestCase<RdapEntitySear
|
||||
assertAboutJson()
|
||||
.that(generateActualJsonWithFullName("Entity *"))
|
||||
.isEqualTo(
|
||||
generateExpectedJson(
|
||||
"fn=Entity+*&cursor=YzpFbnRpdHkgNA%3D%3D", "rdap_truncated_contacts.json"));
|
||||
jsonFileBuilder()
|
||||
.put("NAME", "fn=Entity+*&cursor=YzpFbnRpdHkgNA%3D%3D")
|
||||
.load("rdap_truncated_contacts.json"));
|
||||
assertThat(response.getStatus()).isEqualTo(200);
|
||||
// For contacts, we only need to fetch one result set's worth (plus one).
|
||||
verifyMetrics(5, IncompletenessWarningType.TRUNCATED);
|
||||
@@ -728,7 +701,7 @@ class RdapEntitySearchActionTest extends RdapSearchActionTestCase<RdapEntitySear
|
||||
rememberWildcardType("Entity *");
|
||||
assertAboutJson()
|
||||
.that(generateActualJsonWithFullName("Entity *"))
|
||||
.isEqualTo(generateExpectedJson("rdap_nontruncated_registrars.json"));
|
||||
.isEqualTo(jsonFileBuilder().load("rdap_nontruncated_registrars.json"));
|
||||
assertThat(response.getStatus()).isEqualTo(200);
|
||||
verifyMetrics(0);
|
||||
}
|
||||
@@ -740,8 +713,9 @@ class RdapEntitySearchActionTest extends RdapSearchActionTestCase<RdapEntitySear
|
||||
assertAboutJson()
|
||||
.that(generateActualJsonWithFullName("Entity *"))
|
||||
.isEqualTo(
|
||||
generateExpectedJson(
|
||||
"fn=Entity+*&cursor=cjpFbnRpdHkgNA%3D%3D", "rdap_truncated_registrars.json"));
|
||||
jsonFileBuilder()
|
||||
.put("NAME", "fn=Entity+*&cursor=cjpFbnRpdHkgNA%3D%3D")
|
||||
.load("rdap_truncated_registrars.json"));
|
||||
assertThat(response.getStatus()).isEqualTo(200);
|
||||
verifyMetrics(0, IncompletenessWarningType.TRUNCATED);
|
||||
}
|
||||
@@ -753,8 +727,9 @@ class RdapEntitySearchActionTest extends RdapSearchActionTestCase<RdapEntitySear
|
||||
assertAboutJson()
|
||||
.that(generateActualJsonWithFullName("Entity *"))
|
||||
.isEqualTo(
|
||||
generateExpectedJson(
|
||||
"fn=Entity+*&cursor=cjpFbnRpdHkgNA%3D%3D", "rdap_truncated_registrars.json"));
|
||||
jsonFileBuilder()
|
||||
.put("NAME", "fn=Entity+*&cursor=cjpFbnRpdHkgNA%3D%3D")
|
||||
.load("rdap_truncated_registrars.json"));
|
||||
assertThat(response.getStatus()).isEqualTo(200);
|
||||
verifyMetrics(0, IncompletenessWarningType.TRUNCATED);
|
||||
}
|
||||
@@ -815,8 +790,9 @@ class RdapEntitySearchActionTest extends RdapSearchActionTestCase<RdapEntitySear
|
||||
assertAboutJson()
|
||||
.that(generateActualJsonWithFullName("Entity *"))
|
||||
.isEqualTo(
|
||||
generateExpectedJson(
|
||||
"fn=Entity+*&cursor=cjpFbnRpdHkgNA%3D%3D", "rdap_truncated_mixed_entities.json"));
|
||||
jsonFileBuilder()
|
||||
.put("NAME", "fn=Entity+*&cursor=cjpFbnRpdHkgNA%3D%3D")
|
||||
.load("rdap_truncated_mixed_entities.json"));
|
||||
assertThat(response.getStatus()).isEqualTo(200);
|
||||
verifyMetrics(3, IncompletenessWarningType.TRUNCATED);
|
||||
}
|
||||
@@ -845,7 +821,7 @@ class RdapEntitySearchActionTest extends RdapSearchActionTestCase<RdapEntitySear
|
||||
rememberWildcardType("Entity *");
|
||||
assertAboutJson()
|
||||
.that(generateActualJsonWithFullName("Entity *"))
|
||||
.isEqualTo(generateExpectedJson("rdap_nontruncated_contacts.json"));
|
||||
.isEqualTo(jsonFileBuilder().load("rdap_nontruncated_contacts.json"));
|
||||
assertThat(response.getStatus()).isEqualTo(200);
|
||||
verifyMetrics(4);
|
||||
}
|
||||
@@ -855,8 +831,14 @@ class RdapEntitySearchActionTest extends RdapSearchActionTestCase<RdapEntitySear
|
||||
login("2-RegistrarTest");
|
||||
action.subtypeParam = Optional.of("registrars");
|
||||
createManyContactsAndRegistrars(1, 1, registrarTest);
|
||||
runSuccessfulNameTest(
|
||||
"Entity *", "301", "Entity 2", "rdap_registrar.json");
|
||||
rememberWildcardType("Entity *");
|
||||
assertAboutJson()
|
||||
.that(generateActualJsonWithFullName("Entity *"))
|
||||
.isEqualTo(
|
||||
addBoilerplate(
|
||||
jsonFileBuilder()
|
||||
.addFullRegistrar("301", "Entity 2", "active", null)
|
||||
.load("rdap_registrar.json")));
|
||||
verifyMetrics(0);
|
||||
}
|
||||
|
||||
@@ -878,7 +860,14 @@ class RdapEntitySearchActionTest extends RdapSearchActionTestCase<RdapEntitySear
|
||||
void testNameMatchRegistrar_found_inactiveAsSameRegistrar() {
|
||||
action.includeDeletedParam = Optional.of(true);
|
||||
login("2-RegistrarInact");
|
||||
runSuccessfulNameTest("No Way", "21", "No Way", "inactive", null, "rdap_registrar.json");
|
||||
rememberWildcardType("No Way");
|
||||
assertAboutJson()
|
||||
.that(generateActualJsonWithFullName("No Way"))
|
||||
.isEqualTo(
|
||||
addBoilerplate(
|
||||
jsonFileBuilder()
|
||||
.addFullRegistrar("21", "No Way", "inactive", null)
|
||||
.load("rdap_registrar.json")));
|
||||
verifyMetrics(0);
|
||||
}
|
||||
|
||||
@@ -886,7 +875,14 @@ class RdapEntitySearchActionTest extends RdapSearchActionTestCase<RdapEntitySear
|
||||
void testNameMatchRegistrar_found_inactiveAsAdmin() {
|
||||
action.includeDeletedParam = Optional.of(true);
|
||||
loginAsAdmin();
|
||||
runSuccessfulNameTest("No Way", "21", "No Way", "inactive", null, "rdap_registrar.json");
|
||||
rememberWildcardType("No Way");
|
||||
assertAboutJson()
|
||||
.that(generateActualJsonWithFullName("No Way"))
|
||||
.isEqualTo(
|
||||
addBoilerplate(
|
||||
jsonFileBuilder()
|
||||
.addFullRegistrar("21", "No Way", "inactive", null)
|
||||
.load("rdap_registrar.json")));
|
||||
verifyMetrics(0);
|
||||
}
|
||||
|
||||
@@ -908,8 +904,14 @@ class RdapEntitySearchActionTest extends RdapSearchActionTestCase<RdapEntitySear
|
||||
void testNameMatchRegistrar_found_testAsSameRegistrar() {
|
||||
action.includeDeletedParam = Optional.of(true);
|
||||
login("2-RegistrarTest");
|
||||
runSuccessfulNameTest(
|
||||
"Da Test Registrar", "not applicable", "Da Test Registrar", "rdap_registrar_test.json");
|
||||
rememberWildcardType("Da Test Registrar");
|
||||
assertAboutJson()
|
||||
.that(generateActualJsonWithFullName("Da Test Registrar"))
|
||||
.isEqualTo(
|
||||
addBoilerplate(
|
||||
jsonFileBuilder()
|
||||
.addFullRegistrar("not applicable", "Da Test Registrar", "active", null)
|
||||
.load("rdap_registrar_test.json")));
|
||||
verifyMetrics(0);
|
||||
}
|
||||
|
||||
@@ -917,15 +919,28 @@ class RdapEntitySearchActionTest extends RdapSearchActionTestCase<RdapEntitySear
|
||||
void testNameMatchRegistrar_found_testAsAdmin() {
|
||||
action.includeDeletedParam = Optional.of(true);
|
||||
loginAsAdmin();
|
||||
runSuccessfulNameTest(
|
||||
"Da Test Registrar", "not applicable", "Da Test Registrar", "rdap_registrar_test.json");
|
||||
rememberWildcardType("Da Test Registrar");
|
||||
assertAboutJson()
|
||||
.that(generateActualJsonWithFullName("Da Test Registrar"))
|
||||
.isEqualTo(
|
||||
addBoilerplate(
|
||||
jsonFileBuilder()
|
||||
.addFullRegistrar("not applicable", "Da Test Registrar", "active", null)
|
||||
.load("rdap_registrar_test.json")));
|
||||
verifyMetrics(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testHandleMatchContact_found() {
|
||||
login("2-RegistrarTest");
|
||||
runSuccessfulHandleTestWithBlinky("2-ROID", "rdap_contact.json");
|
||||
rememberWildcardType("2-ROID");
|
||||
assertAboutJson()
|
||||
.that(generateActualJsonWithHandle("2-ROID"))
|
||||
.isEqualTo(
|
||||
addBoilerplate(
|
||||
jsonFileBuilder()
|
||||
.addFullContact("2-ROID", "active", BINKY_FULL_NAME, BINKY_ADDRESS)
|
||||
.load("rdap_contact.json")));
|
||||
verifyMetrics(1);
|
||||
}
|
||||
|
||||
@@ -933,7 +948,14 @@ class RdapEntitySearchActionTest extends RdapSearchActionTestCase<RdapEntitySear
|
||||
void testHandleMatchContact_found_subtypeAll() {
|
||||
login("2-RegistrarTest");
|
||||
action.subtypeParam = Optional.of("all");
|
||||
runSuccessfulHandleTestWithBlinky("2-ROID", "rdap_contact.json");
|
||||
rememberWildcardType("2-ROID");
|
||||
assertAboutJson()
|
||||
.that(generateActualJsonWithHandle("2-ROID"))
|
||||
.isEqualTo(
|
||||
addBoilerplate(
|
||||
jsonFileBuilder()
|
||||
.addFullContact("2-ROID", "active", BINKY_FULL_NAME, BINKY_ADDRESS)
|
||||
.load("rdap_contact.json")));
|
||||
verifyMetrics(1);
|
||||
}
|
||||
|
||||
@@ -941,7 +963,14 @@ class RdapEntitySearchActionTest extends RdapSearchActionTestCase<RdapEntitySear
|
||||
void testHandleMatchContact_found_subtypeContacts() {
|
||||
login("2-RegistrarTest");
|
||||
action.subtypeParam = Optional.of("contacts");
|
||||
runSuccessfulHandleTestWithBlinky("2-ROID", "rdap_contact.json");
|
||||
rememberWildcardType("2-ROID");
|
||||
assertAboutJson()
|
||||
.that(generateActualJsonWithHandle("2-ROID"))
|
||||
.isEqualTo(
|
||||
addBoilerplate(
|
||||
jsonFileBuilder()
|
||||
.addFullContact("2-ROID", "active", BINKY_FULL_NAME, BINKY_ADDRESS)
|
||||
.load("rdap_contact.json")));
|
||||
verifyMetrics(1);
|
||||
}
|
||||
|
||||
@@ -956,7 +985,12 @@ class RdapEntitySearchActionTest extends RdapSearchActionTestCase<RdapEntitySear
|
||||
@Test
|
||||
void testHandleMatchContact_found_specifyingSameRegistrar() {
|
||||
action.registrarParam = Optional.of("2-RegistrarTest");
|
||||
runSuccessfulHandleTestWithBlinky("2-ROID", "rdap_contact_no_personal_data_with_remark.json");
|
||||
rememberWildcardType("2-ROID");
|
||||
assertAboutJson()
|
||||
.that(generateActualJsonWithHandle("2-ROID"))
|
||||
.isEqualTo(
|
||||
addBoilerplate(
|
||||
jsonFileBuilder().load("rdap_contact_no_personal_data_with_remark.json")));
|
||||
verifyMetrics(1);
|
||||
}
|
||||
|
||||
@@ -986,13 +1020,12 @@ class RdapEntitySearchActionTest extends RdapSearchActionTestCase<RdapEntitySear
|
||||
void testHandleMatchContact_found_deletedWhenLoggedInAsSameRegistrar() {
|
||||
login("2-Registrar");
|
||||
action.includeDeletedParam = Optional.of(true);
|
||||
runSuccessfulHandleTest(
|
||||
"6-ROID",
|
||||
"6-ROID",
|
||||
"",
|
||||
"inactive",
|
||||
"",
|
||||
"rdap_contact_deleted.json");
|
||||
rememberWildcardType("6-ROID");
|
||||
assertAboutJson()
|
||||
.that(generateActualJsonWithHandle("6-ROID"))
|
||||
.isEqualTo(
|
||||
addBoilerplate(
|
||||
jsonFileBuilder().addContact("6-ROID").load("rdap_contact_deleted.json")));
|
||||
verifyMetrics(1);
|
||||
}
|
||||
|
||||
@@ -1000,13 +1033,12 @@ class RdapEntitySearchActionTest extends RdapSearchActionTestCase<RdapEntitySear
|
||||
void testHandleMatchContact_found_deletedWhenLoggedInAsAdmin() {
|
||||
loginAsAdmin();
|
||||
action.includeDeletedParam = Optional.of(true);
|
||||
runSuccessfulHandleTest(
|
||||
"6-ROID",
|
||||
"6-ROID",
|
||||
"",
|
||||
"inactive",
|
||||
"",
|
||||
"rdap_contact_deleted.json");
|
||||
rememberWildcardType("6-ROID");
|
||||
assertAboutJson()
|
||||
.that(generateActualJsonWithHandle("6-ROID"))
|
||||
.isEqualTo(
|
||||
addBoilerplate(
|
||||
jsonFileBuilder().addContact("6-ROID").load("rdap_contact_deleted.json")));
|
||||
verifyMetrics(1);
|
||||
}
|
||||
|
||||
@@ -1029,13 +1061,12 @@ class RdapEntitySearchActionTest extends RdapSearchActionTestCase<RdapEntitySear
|
||||
void testHandleMatchContact_found_deletedWildcardWhenLoggedInAsSameRegistrar() {
|
||||
login("2-Registrar");
|
||||
action.includeDeletedParam = Optional.of(true);
|
||||
runSuccessfulHandleTest(
|
||||
"6-ROI*",
|
||||
"6-ROID",
|
||||
"",
|
||||
"inactive",
|
||||
"",
|
||||
"rdap_contact_deleted.json");
|
||||
rememberWildcardType("6-ROI*");
|
||||
assertAboutJson()
|
||||
.that(generateActualJsonWithHandle("6-ROI*"))
|
||||
.isEqualTo(
|
||||
addBoilerplate(
|
||||
jsonFileBuilder().addContact("6-ROID").load("rdap_contact_deleted.json")));
|
||||
verifyMetrics(1);
|
||||
}
|
||||
|
||||
@@ -1043,33 +1074,53 @@ class RdapEntitySearchActionTest extends RdapSearchActionTestCase<RdapEntitySear
|
||||
void testHandleMatchContact_found_deletedWildcardWhenLoggedInAsAdmin() {
|
||||
loginAsAdmin();
|
||||
action.includeDeletedParam = Optional.of(true);
|
||||
runSuccessfulHandleTest(
|
||||
"6-ROI*",
|
||||
"6-ROID",
|
||||
"",
|
||||
"inactive",
|
||||
"",
|
||||
"rdap_contact_deleted.json");
|
||||
rememberWildcardType("6-ROI*");
|
||||
assertAboutJson()
|
||||
.that(generateActualJsonWithHandle("6-ROI*"))
|
||||
.isEqualTo(
|
||||
addBoilerplate(
|
||||
jsonFileBuilder().addContact("6-ROID").load("rdap_contact_deleted.json")));
|
||||
verifyMetrics(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testHandleMatchRegistrar_found() {
|
||||
runSuccessfulHandleTest("20", "20", "Yes Virginia <script>", "rdap_registrar.json");
|
||||
rememberWildcardType("20");
|
||||
assertAboutJson()
|
||||
.that(generateActualJsonWithHandle("20"))
|
||||
.isEqualTo(
|
||||
addBoilerplate(
|
||||
jsonFileBuilder()
|
||||
.addFullRegistrar("20", "Yes Virginia <script>", "active", null)
|
||||
.load("rdap_registrar.json")));
|
||||
verifyMetrics(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testHandleMatchRegistrar_found_subtypeAll() {
|
||||
action.subtypeParam = Optional.of("all");
|
||||
runSuccessfulHandleTest("20", "20", "Yes Virginia <script>", "rdap_registrar.json");
|
||||
rememberWildcardType("20");
|
||||
assertAboutJson()
|
||||
.that(generateActualJsonWithHandle("20"))
|
||||
.isEqualTo(
|
||||
addBoilerplate(
|
||||
jsonFileBuilder()
|
||||
.addFullRegistrar("20", "Yes Virginia <script>", "active", null)
|
||||
.load("rdap_registrar.json")));
|
||||
verifyMetrics(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testHandleMatchRegistrar_found_subtypeRegistrars() {
|
||||
action.subtypeParam = Optional.of("registrars");
|
||||
runSuccessfulHandleTest("20", "20", "Yes Virginia <script>", "rdap_registrar.json");
|
||||
rememberWildcardType("20");
|
||||
assertAboutJson()
|
||||
.that(generateActualJsonWithHandle("20"))
|
||||
.isEqualTo(
|
||||
addBoilerplate(
|
||||
jsonFileBuilder()
|
||||
.addFullRegistrar("20", "Yes Virginia <script>", "active", null)
|
||||
.load("rdap_registrar.json")));
|
||||
verifyMetrics(0);
|
||||
}
|
||||
|
||||
@@ -1083,7 +1134,14 @@ class RdapEntitySearchActionTest extends RdapSearchActionTestCase<RdapEntitySear
|
||||
@Test
|
||||
void testHandleMatchRegistrar_found_specifyingSameRegistrar() {
|
||||
action.registrarParam = Optional.of("2-Registrar");
|
||||
runSuccessfulHandleTest("20", "20", "Yes Virginia <script>", "rdap_registrar.json");
|
||||
rememberWildcardType("20");
|
||||
assertAboutJson()
|
||||
.that(generateActualJsonWithHandle("20"))
|
||||
.isEqualTo(
|
||||
addBoilerplate(
|
||||
jsonFileBuilder()
|
||||
.addFullRegistrar("20", "Yes Virginia <script>", "active", null)
|
||||
.load("rdap_registrar.json")));
|
||||
verifyMetrics(0);
|
||||
}
|
||||
|
||||
@@ -1098,14 +1156,28 @@ class RdapEntitySearchActionTest extends RdapSearchActionTestCase<RdapEntitySear
|
||||
void testHandleMatchContact_found_wildcardWithResultSetSizeOne() {
|
||||
login("2-RegistrarTest");
|
||||
action.rdapResultSetMaxSize = 1;
|
||||
runSuccessfulHandleTestWithBlinky("2-R*", "rdap_contact.json");
|
||||
rememberWildcardType("2-R*");
|
||||
assertAboutJson()
|
||||
.that(generateActualJsonWithHandle("2-R*"))
|
||||
.isEqualTo(
|
||||
addBoilerplate(
|
||||
jsonFileBuilder()
|
||||
.addFullContact("2-ROID", "active", BINKY_FULL_NAME, BINKY_ADDRESS)
|
||||
.load("rdap_contact.json")));
|
||||
verifyMetrics(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testHandleMatchContact_found_wildcard() {
|
||||
login("2-RegistrarTest");
|
||||
runSuccessfulHandleTestWithBlinky("2-RO*", "rdap_contact.json");
|
||||
rememberWildcardType("2-R*");
|
||||
assertAboutJson()
|
||||
.that(generateActualJsonWithHandle("2-R*"))
|
||||
.isEqualTo(
|
||||
addBoilerplate(
|
||||
jsonFileBuilder()
|
||||
.addFullContact("2-ROID", "active", BINKY_FULL_NAME, BINKY_ADDRESS)
|
||||
.load("rdap_contact.json")));
|
||||
verifyMetrics(1);
|
||||
}
|
||||
|
||||
@@ -1113,7 +1185,14 @@ class RdapEntitySearchActionTest extends RdapSearchActionTestCase<RdapEntitySear
|
||||
void testHandleMatchContact_found_wildcardSpecifyingSameRegistrar() {
|
||||
action.registrarParam = Optional.of("2-RegistrarTest");
|
||||
login("2-RegistrarTest");
|
||||
runSuccessfulHandleTestWithBlinky("2-RO*", "rdap_contact.json");
|
||||
rememberWildcardType("2-RO*");
|
||||
assertAboutJson()
|
||||
.that(generateActualJsonWithHandle("2-RO*"))
|
||||
.isEqualTo(
|
||||
addBoilerplate(
|
||||
jsonFileBuilder()
|
||||
.addFullContact("2-ROID", "active", BINKY_FULL_NAME, BINKY_ADDRESS)
|
||||
.load("rdap_contact.json")));
|
||||
verifyMetrics(1);
|
||||
}
|
||||
|
||||
@@ -1128,7 +1207,14 @@ class RdapEntitySearchActionTest extends RdapSearchActionTestCase<RdapEntitySear
|
||||
@Test
|
||||
void testHandleMatchContact_found_deleted() {
|
||||
login("2-RegistrarTest");
|
||||
runSuccessfulHandleTestWithBlinky("2-RO*", "rdap_contact.json");
|
||||
rememberWildcardType("2-R*");
|
||||
assertAboutJson()
|
||||
.that(generateActualJsonWithHandle("2-R*"))
|
||||
.isEqualTo(
|
||||
addBoilerplate(
|
||||
jsonFileBuilder()
|
||||
.addFullContact("2-ROID", "active", BINKY_FULL_NAME, BINKY_ADDRESS)
|
||||
.load("rdap_contact.json")));
|
||||
verifyMetrics(1);
|
||||
}
|
||||
|
||||
@@ -1245,7 +1331,14 @@ class RdapEntitySearchActionTest extends RdapSearchActionTestCase<RdapEntitySear
|
||||
void testHandleMatchRegistrar_found_inactiveAsSameRegistrar() {
|
||||
action.includeDeletedParam = Optional.of(true);
|
||||
login("2-RegistrarInact");
|
||||
runSuccessfulHandleTest("21", "21", "No Way", "inactive", null, "rdap_registrar.json");
|
||||
rememberWildcardType("21");
|
||||
assertAboutJson()
|
||||
.that(generateActualJsonWithHandle("21"))
|
||||
.isEqualTo(
|
||||
addBoilerplate(
|
||||
jsonFileBuilder()
|
||||
.addFullRegistrar("21", "No Way", "inactive", null)
|
||||
.load("rdap_registrar.json")));
|
||||
verifyMetrics(0);
|
||||
}
|
||||
|
||||
@@ -1253,7 +1346,14 @@ class RdapEntitySearchActionTest extends RdapSearchActionTestCase<RdapEntitySear
|
||||
void testHandleMatchRegistrar_found_inactiveAsAdmin() {
|
||||
action.includeDeletedParam = Optional.of(true);
|
||||
loginAsAdmin();
|
||||
runSuccessfulHandleTest("21", "21", "No Way", "inactive", null, "rdap_registrar.json");
|
||||
rememberWildcardType("21");
|
||||
assertAboutJson()
|
||||
.that(generateActualJsonWithHandle("21"))
|
||||
.isEqualTo(
|
||||
addBoilerplate(
|
||||
jsonFileBuilder()
|
||||
.addFullRegistrar("21", "No Way", "inactive", null)
|
||||
.load("rdap_registrar.json")));
|
||||
verifyMetrics(0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,13 +48,15 @@ class RdapHelpActionTest extends RdapActionBaseTestCase<RdapHelpAction> {
|
||||
|
||||
@Test
|
||||
void testHelpActionDefault_getsIndex() {
|
||||
assertThat(generateActualJson("")).isEqualTo(loadJsonFile("rdap_help_index.json"));
|
||||
assertThat(generateActualJson(""))
|
||||
.isEqualTo(loadJsonFile("rdap_help_index.json", "POSSIBLE_SLASH", ""));
|
||||
assertThat(response.getStatus()).isEqualTo(200);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testHelpActionSlash_getsIndex() {
|
||||
assertThat(generateActualJson("/")).isEqualTo(loadJsonFile("rdap_help_index.json"));
|
||||
assertThat(generateActualJson("/"))
|
||||
.isEqualTo(loadJsonFile("rdap_help_index.json", "POSSIBLE_SLASH", "/"));
|
||||
assertThat(response.getStatus()).isEqualTo(200);
|
||||
}
|
||||
|
||||
|
||||
@@ -15,15 +15,12 @@
|
||||
package google.registry.rdap;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static google.registry.rdap.RdapTestHelper.loadJsonFile;
|
||||
import static google.registry.testing.DatabaseHelper.createTld;
|
||||
import static google.registry.testing.DatabaseHelper.persistResource;
|
||||
import static google.registry.testing.FullFieldsTestEntityHelper.makeRegistrar;
|
||||
import static google.registry.testing.GsonSubject.assertAboutJson;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.gson.JsonObject;
|
||||
import google.registry.model.registrar.Registrar;
|
||||
import google.registry.rdap.RdapMetrics.EndpointType;
|
||||
import google.registry.rdap.RdapMetrics.SearchType;
|
||||
@@ -32,7 +29,6 @@ import google.registry.rdap.RdapSearchResults.IncompletenessWarningType;
|
||||
import google.registry.request.Action;
|
||||
import google.registry.testing.FullFieldsTestEntityHelper;
|
||||
import java.util.Optional;
|
||||
import javax.annotation.Nullable;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@@ -72,37 +68,6 @@ class RdapNameserverActionTest extends RdapActionBaseTestCase<RdapNameserverActi
|
||||
"ns1.domain.external", "9.10.11.12", clock.nowUtc().minusYears(1));
|
||||
}
|
||||
|
||||
private JsonObject generateExpectedJson(
|
||||
String name,
|
||||
@Nullable ImmutableMap<String, String> otherSubstitutions,
|
||||
String expectedOutputFile) {
|
||||
ImmutableMap.Builder<String, String> builder = new ImmutableMap.Builder<>();
|
||||
builder.put("TYPE", "nameserver");
|
||||
builder.put("NAME", name);
|
||||
boolean punycodeSet = false;
|
||||
if (otherSubstitutions != null) {
|
||||
builder.putAll(otherSubstitutions);
|
||||
if (otherSubstitutions.containsKey("PUNYCODENAME")) {
|
||||
punycodeSet = true;
|
||||
}
|
||||
}
|
||||
if (!punycodeSet) {
|
||||
builder.put("PUNYCODENAME", name);
|
||||
}
|
||||
return loadJsonFile(
|
||||
expectedOutputFile,
|
||||
builder.build());
|
||||
}
|
||||
|
||||
private JsonObject generateExpectedJsonWithTopLevelEntries(
|
||||
String name,
|
||||
@Nullable ImmutableMap<String, String> otherSubstitutions,
|
||||
String expectedOutputFile) {
|
||||
JsonObject obj = generateExpectedJson(name, otherSubstitutions, expectedOutputFile);
|
||||
RdapTestHelper.addNonDomainBoilerplateNotices(obj, "https://example.tld/rdap/");
|
||||
return obj;
|
||||
}
|
||||
|
||||
@Test
|
||||
void testInvalidNameserver_returns400() {
|
||||
assertAboutJson()
|
||||
@@ -126,14 +91,11 @@ class RdapNameserverActionTest extends RdapActionBaseTestCase<RdapNameserverActi
|
||||
assertAboutJson()
|
||||
.that(generateActualJson("ns1.cat.lol"))
|
||||
.isEqualTo(
|
||||
generateExpectedJsonWithTopLevelEntries(
|
||||
"ns1.cat.lol",
|
||||
ImmutableMap.of(
|
||||
"HANDLE", "2-ROID",
|
||||
"ADDRESSTYPE", "v4",
|
||||
"ADDRESS", "1.2.3.4",
|
||||
"STATUS", "active"),
|
||||
"rdap_host.json"));
|
||||
addPermanentBoilerplateNotices(
|
||||
jsonFileBuilder()
|
||||
.addNameserver("ns1.cat.lol", "2-ROID")
|
||||
.putAll("ADDRESSTYPE", "v4", "ADDRESS", "1.2.3.4", "STATUS", "active")
|
||||
.load("rdap_host.json")));
|
||||
assertThat(response.getStatus()).isEqualTo(200);
|
||||
}
|
||||
|
||||
@@ -142,14 +104,11 @@ class RdapNameserverActionTest extends RdapActionBaseTestCase<RdapNameserverActi
|
||||
assertAboutJson()
|
||||
.that(generateActualJson("ns1.cat.lol."))
|
||||
.isEqualTo(
|
||||
generateExpectedJsonWithTopLevelEntries(
|
||||
"ns1.cat.lol",
|
||||
ImmutableMap.of(
|
||||
"HANDLE", "2-ROID",
|
||||
"ADDRESSTYPE", "v4",
|
||||
"ADDRESS", "1.2.3.4",
|
||||
"STATUS", "active"),
|
||||
"rdap_host.json"));
|
||||
addPermanentBoilerplateNotices(
|
||||
jsonFileBuilder()
|
||||
.addNameserver("ns1.cat.lol", "2-ROID")
|
||||
.putAll("ADDRESSTYPE", "v4", "ADDRESS", "1.2.3.4", "STATUS", "active")
|
||||
.load("rdap_host.json")));
|
||||
assertThat(response.getStatus()).isEqualTo(200);
|
||||
}
|
||||
|
||||
@@ -158,14 +117,11 @@ class RdapNameserverActionTest extends RdapActionBaseTestCase<RdapNameserverActi
|
||||
assertAboutJson()
|
||||
.that(generateActualJson("Ns1.CaT.lOl."))
|
||||
.isEqualTo(
|
||||
generateExpectedJsonWithTopLevelEntries(
|
||||
"ns1.cat.lol",
|
||||
ImmutableMap.of(
|
||||
"HANDLE", "2-ROID",
|
||||
"ADDRESSTYPE", "v4",
|
||||
"ADDRESS", "1.2.3.4",
|
||||
"STATUS", "active"),
|
||||
"rdap_host.json"));
|
||||
addPermanentBoilerplateNotices(
|
||||
jsonFileBuilder()
|
||||
.addNameserver("ns1.cat.lol", "2-ROID")
|
||||
.putAll("ADDRESSTYPE", "v4", "ADDRESS", "1.2.3.4", "STATUS", "active")
|
||||
.load("rdap_host.json")));
|
||||
assertThat(response.getStatus()).isEqualTo(200);
|
||||
}
|
||||
|
||||
@@ -174,14 +130,11 @@ class RdapNameserverActionTest extends RdapActionBaseTestCase<RdapNameserverActi
|
||||
assertAboutJson()
|
||||
.that(generateActualJson("ns1.cat.lol?key=value"))
|
||||
.isEqualTo(
|
||||
generateExpectedJsonWithTopLevelEntries(
|
||||
"ns1.cat.lol",
|
||||
ImmutableMap.of(
|
||||
"HANDLE", "2-ROID",
|
||||
"ADDRESSTYPE", "v4",
|
||||
"ADDRESS", "1.2.3.4",
|
||||
"STATUS", "active"),
|
||||
"rdap_host.json"));
|
||||
addPermanentBoilerplateNotices(
|
||||
jsonFileBuilder()
|
||||
.addNameserver("ns1.cat.lol", "2-ROID")
|
||||
.putAll("ADDRESSTYPE", "v4", "ADDRESS", "1.2.3.4", "STATUS", "active")
|
||||
.load("rdap_host.json")));
|
||||
assertThat(response.getStatus()).isEqualTo(200);
|
||||
}
|
||||
|
||||
@@ -190,15 +143,11 @@ class RdapNameserverActionTest extends RdapActionBaseTestCase<RdapNameserverActi
|
||||
assertAboutJson()
|
||||
.that(generateActualJson("ns1.cat.みんな"))
|
||||
.isEqualTo(
|
||||
generateExpectedJsonWithTopLevelEntries(
|
||||
"ns1.cat.みんな",
|
||||
ImmutableMap.of(
|
||||
"PUNYCODENAME", "ns1.cat.xn--q9jyb4c",
|
||||
"HANDLE", "5-ROID",
|
||||
"ADDRESSTYPE", "v6",
|
||||
"ADDRESS", "bad:f00d:cafe::15:beef",
|
||||
"STATUS", "active"),
|
||||
"rdap_host_unicode.json"));
|
||||
addPermanentBoilerplateNotices(
|
||||
jsonFileBuilder()
|
||||
.addNameserver("ns1.cat.みんな", "5-ROID")
|
||||
.putAll("ADDRESSTYPE", "v6", "ADDRESS", "bad:f00d:cafe::15:beef")
|
||||
.load("rdap_host_unicode.json")));
|
||||
assertThat(response.getStatus()).isEqualTo(200);
|
||||
}
|
||||
|
||||
@@ -207,15 +156,11 @@ class RdapNameserverActionTest extends RdapActionBaseTestCase<RdapNameserverActi
|
||||
assertAboutJson()
|
||||
.that(generateActualJson("ns1.cat.xn--q9jyb4c"))
|
||||
.isEqualTo(
|
||||
generateExpectedJsonWithTopLevelEntries(
|
||||
"ns1.cat.みんな",
|
||||
ImmutableMap.of(
|
||||
"PUNYCODENAME", "ns1.cat.xn--q9jyb4c",
|
||||
"HANDLE", "5-ROID",
|
||||
"ADDRESSTYPE", "v6",
|
||||
"ADDRESS", "bad:f00d:cafe::15:beef",
|
||||
"STATUS", "active"),
|
||||
"rdap_host_unicode.json"));
|
||||
addPermanentBoilerplateNotices(
|
||||
jsonFileBuilder()
|
||||
.addNameserver("ns1.cat.みんな", "5-ROID")
|
||||
.putAll("ADDRESSTYPE", "v6", "ADDRESS", "bad:f00d:cafe::15:beef")
|
||||
.load("rdap_host_unicode.json")));
|
||||
assertThat(response.getStatus()).isEqualTo(200);
|
||||
}
|
||||
|
||||
@@ -224,14 +169,11 @@ class RdapNameserverActionTest extends RdapActionBaseTestCase<RdapNameserverActi
|
||||
assertAboutJson()
|
||||
.that(generateActualJson("ns1.domain.1.tld"))
|
||||
.isEqualTo(
|
||||
generateExpectedJsonWithTopLevelEntries(
|
||||
"ns1.domain.1.tld",
|
||||
ImmutableMap.of(
|
||||
"HANDLE", "8-ROID",
|
||||
"ADDRESSTYPE", "v4",
|
||||
"ADDRESS", "5.6.7.8",
|
||||
"STATUS", "active"),
|
||||
"rdap_host.json"));
|
||||
addPermanentBoilerplateNotices(
|
||||
jsonFileBuilder()
|
||||
.addNameserver("ns1.domain.1.tld", "8-ROID")
|
||||
.putAll("ADDRESSTYPE", "v4", "ADDRESS", "5.6.7.8", "STATUS", "active")
|
||||
.load("rdap_host.json")));
|
||||
assertThat(response.getStatus()).isEqualTo(200);
|
||||
}
|
||||
|
||||
@@ -240,14 +182,11 @@ class RdapNameserverActionTest extends RdapActionBaseTestCase<RdapNameserverActi
|
||||
assertAboutJson()
|
||||
.that(generateActualJson("ns1.domain.external"))
|
||||
.isEqualTo(
|
||||
generateExpectedJsonWithTopLevelEntries(
|
||||
"ns1.domain.external",
|
||||
ImmutableMap.of(
|
||||
"HANDLE", "C-ROID",
|
||||
"ADDRESSTYPE", "v4",
|
||||
"ADDRESS", "9.10.11.12",
|
||||
"STATUS", "active"),
|
||||
"rdap_host.json"));
|
||||
addPermanentBoilerplateNotices(
|
||||
jsonFileBuilder()
|
||||
.addNameserver("ns1.domain.external", "C-ROID")
|
||||
.putAll("ADDRESSTYPE", "v4", "ADDRESS", "9.10.11.12", "STATUS", "active")
|
||||
.load("rdap_host.json")));
|
||||
assertThat(response.getStatus()).isEqualTo(200);
|
||||
}
|
||||
|
||||
@@ -287,14 +226,11 @@ class RdapNameserverActionTest extends RdapActionBaseTestCase<RdapNameserverActi
|
||||
assertAboutJson()
|
||||
.that(generateActualJson("nsdeleted.cat.lol"))
|
||||
.isEqualTo(
|
||||
generateExpectedJsonWithTopLevelEntries(
|
||||
"nsdeleted.cat.lol",
|
||||
ImmutableMap.of(
|
||||
"HANDLE", "A-ROID",
|
||||
"ADDRESSTYPE", "v4",
|
||||
"ADDRESS", "1.2.3.4",
|
||||
"STATUS", "inactive"),
|
||||
"rdap_host.json"));
|
||||
addPermanentBoilerplateNotices(
|
||||
jsonFileBuilder()
|
||||
.addNameserver("nsdeleted.cat.lol", "A-ROID")
|
||||
.putAll("ADDRESSTYPE", "v4", "ADDRESS", "1.2.3.4", "STATUS", "inactive")
|
||||
.load("rdap_host.json")));
|
||||
assertThat(response.getStatus()).isEqualTo(200);
|
||||
}
|
||||
|
||||
@@ -305,14 +241,11 @@ class RdapNameserverActionTest extends RdapActionBaseTestCase<RdapNameserverActi
|
||||
assertAboutJson()
|
||||
.that(generateActualJson("nsdeleted.cat.lol"))
|
||||
.isEqualTo(
|
||||
generateExpectedJsonWithTopLevelEntries(
|
||||
"nsdeleted.cat.lol",
|
||||
ImmutableMap.of(
|
||||
"HANDLE", "A-ROID",
|
||||
"ADDRESSTYPE", "v4",
|
||||
"ADDRESS", "1.2.3.4",
|
||||
"STATUS", "inactive"),
|
||||
"rdap_host.json"));
|
||||
addPermanentBoilerplateNotices(
|
||||
jsonFileBuilder()
|
||||
.addNameserver("nsdeleted.cat.lol", "A-ROID")
|
||||
.putAll("ADDRESSTYPE", "v4", "ADDRESS", "1.2.3.4", "STATUS", "inactive")
|
||||
.load("rdap_host.json")));
|
||||
assertThat(response.getStatus()).isEqualTo(200);
|
||||
}
|
||||
|
||||
|
||||
@@ -158,26 +158,9 @@ class RdapNameserverSearchActionTest extends RdapSearchActionTestCase<RdapNamese
|
||||
action.nameParam = Optional.empty();
|
||||
}
|
||||
|
||||
private JsonObject generateExpectedJsonForNameserver(
|
||||
String name,
|
||||
String punycodeName,
|
||||
String handle,
|
||||
String ipAddressType,
|
||||
String ipAddress,
|
||||
String expectedOutputFile) {
|
||||
JsonObject obj =
|
||||
loadJsonFile(
|
||||
expectedOutputFile,
|
||||
"NAME", name,
|
||||
"PUNYCODENAME", punycodeName,
|
||||
"HANDLE", handle,
|
||||
"ADDRESSTYPE", ipAddressType,
|
||||
"ADDRESS", ipAddress,
|
||||
"STATUS", "active",
|
||||
"TYPE", "nameserver");
|
||||
obj = RdapTestHelper.wrapInSearchReply("nameserverSearchResults", obj);
|
||||
RdapTestHelper.addNonDomainBoilerplateNotices(obj, "https://example.tld/rdap/");
|
||||
return obj;
|
||||
private JsonObject addBoilerplate(JsonObject jsonObject) {
|
||||
jsonObject = RdapTestHelper.wrapInSearchReply("nameserverSearchResults", jsonObject);
|
||||
return addPermanentBoilerplateNotices(jsonObject);
|
||||
}
|
||||
|
||||
private void createManyHosts(int numHosts) {
|
||||
@@ -318,8 +301,11 @@ class RdapNameserverSearchActionTest extends RdapSearchActionTestCase<RdapNamese
|
||||
assertAboutJson()
|
||||
.that(generateActualJsonWithName("ns1.cat.lol"))
|
||||
.isEqualTo(
|
||||
generateExpectedJsonForNameserver(
|
||||
"ns1.cat.lol", null, "2-ROID", "v4", "1.2.3.4", "rdap_host_linked.json"));
|
||||
addBoilerplate(
|
||||
jsonFileBuilder()
|
||||
.addNameserver("ns1.cat.lol", "2-ROID")
|
||||
.putAll("ADDRESSTYPE", "v4", "ADDRESS", "1.2.3.4")
|
||||
.load("rdap_host_linked.json")));
|
||||
assertThat(response.getStatus()).isEqualTo(200);
|
||||
verifyMetrics(1);
|
||||
}
|
||||
@@ -329,8 +315,11 @@ class RdapNameserverSearchActionTest extends RdapSearchActionTestCase<RdapNamese
|
||||
assertAboutJson()
|
||||
.that(generateActualJsonWithName("Ns1.CaT.lOl"))
|
||||
.isEqualTo(
|
||||
generateExpectedJsonForNameserver(
|
||||
"ns1.cat.lol", null, "2-ROID", "v4", "1.2.3.4", "rdap_host_linked.json"));
|
||||
addBoilerplate(
|
||||
jsonFileBuilder()
|
||||
.addNameserver("ns1.cat.lol", "2-ROID")
|
||||
.putAll("ADDRESSTYPE", "v4", "ADDRESS", "1.2.3.4")
|
||||
.load("rdap_host_linked.json")));
|
||||
assertThat(response.getStatus()).isEqualTo(200);
|
||||
verifyMetrics(1);
|
||||
}
|
||||
@@ -356,13 +345,11 @@ class RdapNameserverSearchActionTest extends RdapSearchActionTestCase<RdapNamese
|
||||
assertAboutJson()
|
||||
.that(generateActualJsonWithName("ns2.cat.lol"))
|
||||
.isEqualTo(
|
||||
generateExpectedJsonForNameserver(
|
||||
"ns2.cat.lol",
|
||||
null,
|
||||
"4-ROID",
|
||||
"v6",
|
||||
"bad:f00d:cafe::15:beef",
|
||||
"rdap_host_linked.json"));
|
||||
addBoilerplate(
|
||||
jsonFileBuilder()
|
||||
.addNameserver("ns2.cat.lol", "4-ROID")
|
||||
.putAll("ADDRESSTYPE", "v6", "ADDRESS", "bad:f00d:cafe::15:beef")
|
||||
.load("rdap_host_linked.json")));
|
||||
assertThat(response.getStatus()).isEqualTo(200);
|
||||
verifyMetrics(1);
|
||||
}
|
||||
@@ -380,8 +367,10 @@ class RdapNameserverSearchActionTest extends RdapSearchActionTestCase<RdapNamese
|
||||
assertAboutJson()
|
||||
.that(generateActualJsonWithName("ns1.cat.external"))
|
||||
.isEqualTo(
|
||||
generateExpectedJsonForNameserver(
|
||||
"ns1.cat.external", null, "8-ROID", null, null, "rdap_host_external.json"));
|
||||
addBoilerplate(
|
||||
jsonFileBuilder()
|
||||
.addNameserver("ns1.cat.external", "8-ROID")
|
||||
.load("rdap_host_external.json")));
|
||||
assertThat(response.getStatus()).isEqualTo(200);
|
||||
verifyMetrics(1);
|
||||
}
|
||||
@@ -391,13 +380,11 @@ class RdapNameserverSearchActionTest extends RdapSearchActionTestCase<RdapNamese
|
||||
assertAboutJson()
|
||||
.that(generateActualJsonWithName("ns1.cat.みんな"))
|
||||
.isEqualTo(
|
||||
generateExpectedJsonForNameserver(
|
||||
"ns1.cat.みんな",
|
||||
"ns1.cat.xn--q9jyb4c",
|
||||
"B-ROID",
|
||||
"v4",
|
||||
"1.2.3.5",
|
||||
"rdap_host_unicode.json"));
|
||||
addBoilerplate(
|
||||
jsonFileBuilder()
|
||||
.addNameserver("ns1.cat.みんな", "B-ROID")
|
||||
.putAll("ADDRESSTYPE", "v4", "ADDRESS", "1.2.3.5")
|
||||
.load("rdap_host_unicode.json")));
|
||||
metricWildcardType = WildcardType.NO_WILDCARD;
|
||||
metricPrefixLength = 19;
|
||||
assertThat(response.getStatus()).isEqualTo(200);
|
||||
@@ -409,13 +396,11 @@ class RdapNameserverSearchActionTest extends RdapSearchActionTestCase<RdapNamese
|
||||
assertAboutJson()
|
||||
.that(generateActualJsonWithName("ns1.cat.xn--q9jyb4c"))
|
||||
.isEqualTo(
|
||||
generateExpectedJsonForNameserver(
|
||||
"ns1.cat.みんな",
|
||||
"ns1.cat.xn--q9jyb4c",
|
||||
"B-ROID",
|
||||
"v4",
|
||||
"1.2.3.5",
|
||||
"rdap_host_unicode.json"));
|
||||
addBoilerplate(
|
||||
jsonFileBuilder()
|
||||
.addNameserver("ns1.cat.みんな", "B-ROID")
|
||||
.putAll("ADDRESSTYPE", "v4", "ADDRESS", "1.2.3.5")
|
||||
.load("rdap_host_unicode.json")));
|
||||
assertThat(response.getStatus()).isEqualTo(200);
|
||||
verifyMetrics(1);
|
||||
}
|
||||
@@ -425,8 +410,11 @@ class RdapNameserverSearchActionTest extends RdapSearchActionTestCase<RdapNamese
|
||||
assertAboutJson()
|
||||
.that(generateActualJsonWithName("ns1.cat.1.test"))
|
||||
.isEqualTo(
|
||||
generateExpectedJsonForNameserver(
|
||||
"ns1.cat.1.test", null, "E-ROID", "v4", "1.2.3.6", "rdap_host.json"));
|
||||
addBoilerplate(
|
||||
jsonFileBuilder()
|
||||
.addNameserver("ns1.cat.1.test", "E-ROID")
|
||||
.putAll("ADDRESSTYPE", "v4", "ADDRESS", "1.2.3.6", "STATUS", "active")
|
||||
.load("rdap_host.json")));
|
||||
assertThat(response.getStatus()).isEqualTo(200);
|
||||
verifyMetrics(1);
|
||||
}
|
||||
@@ -553,13 +541,11 @@ class RdapNameserverSearchActionTest extends RdapSearchActionTestCase<RdapNamese
|
||||
assertAboutJson()
|
||||
.that(generateActualJsonWithName("ns*.cat.lol"))
|
||||
.isEqualTo(
|
||||
generateExpectedJsonForNameserver(
|
||||
"ns2.cat.lol",
|
||||
null,
|
||||
"4-ROID",
|
||||
"v6",
|
||||
"bad:f00d:cafe::15:beef",
|
||||
"rdap_host_linked.json"));
|
||||
addBoilerplate(
|
||||
jsonFileBuilder()
|
||||
.addNameserver("ns2.cat.lol", "4-ROID")
|
||||
.putAll("ADDRESSTYPE", "v6", "ADDRESS", "bad:f00d:cafe::15:beef")
|
||||
.load("rdap_host_linked.json")));
|
||||
assertThat(response.getStatus()).isEqualTo(200);
|
||||
verifyMetrics(2);
|
||||
}
|
||||
@@ -749,8 +735,11 @@ class RdapNameserverSearchActionTest extends RdapSearchActionTestCase<RdapNamese
|
||||
assertAboutJson()
|
||||
.that(generateActualJsonWithIp("1.2.3.4"))
|
||||
.isEqualTo(
|
||||
generateExpectedJsonForNameserver(
|
||||
"ns1.cat.lol", null, "2-ROID", "v4", "1.2.3.4", "rdap_host_linked.json"));
|
||||
addBoilerplate(
|
||||
jsonFileBuilder()
|
||||
.addNameserver("ns1.cat.lol", "2-ROID")
|
||||
.putAll("ADDRESSTYPE", "v4", "ADDRESS", "1.2.3.4")
|
||||
.load("rdap_host_linked.json")));
|
||||
assertThat(response.getStatus()).isEqualTo(200);
|
||||
verifyMetrics(1);
|
||||
}
|
||||
|
||||
@@ -45,107 +45,6 @@ class RdapTestHelper {
|
||||
CONTACT
|
||||
}
|
||||
|
||||
private static JsonObject createTosNotice(String linkBase) {
|
||||
return GSON.toJsonTree(
|
||||
ImmutableMap.of(
|
||||
"title", "RDAP Terms of Service",
|
||||
"description",
|
||||
ImmutableList.of(
|
||||
"By querying our Domain Database, you are agreeing to comply with these"
|
||||
+ " terms so please read them carefully.",
|
||||
"Any information provided is 'as is' without any guarantee of accuracy.",
|
||||
"Please do not misuse the Domain Database. It is intended solely for"
|
||||
+ " query-based access.",
|
||||
"Don't use the Domain Database to allow, enable, or otherwise support the"
|
||||
+ " transmission of mass unsolicited, commercial advertising or"
|
||||
+ " solicitations.",
|
||||
"Don't access our Domain Database through the use of high volume, automated"
|
||||
+ " electronic processes that send queries or data to the systems of"
|
||||
+ " any ICANN-accredited registrar.",
|
||||
"You may only use the information contained in the Domain Database for"
|
||||
+ " lawful purposes.",
|
||||
"Do not compile, repackage, disseminate, or otherwise use the information"
|
||||
+ " contained in the Domain Database in its entirety, or in any"
|
||||
+ " substantial portion, without our prior written permission.",
|
||||
"We may retain certain details about queries to our Domain Database for the"
|
||||
+ " purposes of detecting and preventing misuse.",
|
||||
"We reserve the right to restrict or deny your access to the database if we"
|
||||
+ " suspect that you have failed to comply with these terms.",
|
||||
"We reserve the right to modify this agreement at any time."),
|
||||
"links",
|
||||
ImmutableList.of(
|
||||
ImmutableMap.of(
|
||||
"rel", "self",
|
||||
"href", linkBase + "help/tos",
|
||||
"type", "application/rdap+json"),
|
||||
ImmutableMap.of(
|
||||
"rel", "alternate",
|
||||
"href", "https://www.registry.tld/about/rdap/tos.html",
|
||||
"type", "text/html"))))
|
||||
.getAsJsonObject();
|
||||
}
|
||||
|
||||
static void addNonDomainBoilerplateNotices(JsonObject jsonObject, String linkBase) {
|
||||
if (!jsonObject.has("notices")) {
|
||||
jsonObject.add("notices", new JsonArray());
|
||||
}
|
||||
JsonArray notices = jsonObject.getAsJsonArray("notices");
|
||||
|
||||
notices.add(createTosNotice(linkBase));
|
||||
notices.add(
|
||||
GSON.toJsonTree(
|
||||
ImmutableMap.of(
|
||||
"description",
|
||||
ImmutableList.of(
|
||||
"This response conforms to the RDAP Operational Profile for gTLD"
|
||||
+ " Registries and Registrars version 1.0"))));
|
||||
}
|
||||
|
||||
static void addDomainBoilerplateNotices(JsonObject jsonObject, String linkBase) {
|
||||
if (!jsonObject.has("notices")) {
|
||||
jsonObject.add("notices", new JsonArray());
|
||||
}
|
||||
JsonArray notices = jsonObject.getAsJsonArray("notices");
|
||||
|
||||
notices.add(createTosNotice(linkBase));
|
||||
notices.add(
|
||||
GSON.toJsonTree(
|
||||
ImmutableMap.of(
|
||||
"description",
|
||||
ImmutableList.of(
|
||||
"This response conforms to the RDAP Operational Profile for gTLD"
|
||||
+ " Registries and Registrars version 1.0"))));
|
||||
notices.add(
|
||||
GSON.toJsonTree(
|
||||
ImmutableMap.of(
|
||||
"title",
|
||||
"Status Codes",
|
||||
"description",
|
||||
ImmutableList.of(
|
||||
"For more information on domain status codes, please visit"
|
||||
+ " https://icann.org/epp"),
|
||||
"links",
|
||||
ImmutableList.of(
|
||||
ImmutableMap.of(
|
||||
"rel", "alternate",
|
||||
"href", "https://icann.org/epp",
|
||||
"type", "text/html")))));
|
||||
notices.add(
|
||||
GSON.toJsonTree(
|
||||
ImmutableMap.of(
|
||||
"title",
|
||||
"RDDS Inaccuracy Complaint Form",
|
||||
"description",
|
||||
ImmutableList.of(
|
||||
"URL of the ICANN RDDS Inaccuracy Complaint Form: https://icann.org/wicf"),
|
||||
"links",
|
||||
ImmutableList.of(
|
||||
ImmutableMap.of(
|
||||
"rel", "alternate",
|
||||
"href", "https://icann.org/wicf",
|
||||
"type", "text/html")))));
|
||||
}
|
||||
|
||||
static RdapJsonFormatter getTestRdapJsonFormatter(Clock clock) {
|
||||
RdapJsonFormatter rdapJsonFormatter = new RdapJsonFormatter();
|
||||
rdapJsonFormatter.rdapAuthorization = RdapAuthorization.PUBLIC_AUTHORIZATION;
|
||||
@@ -174,7 +73,7 @@ class RdapTestHelper {
|
||||
"We reserve the right to restrict or deny your access to the database if we"
|
||||
+ " suspect that you have failed to comply with these terms.",
|
||||
"We reserve the right to modify this agreement at any time.");
|
||||
rdapJsonFormatter.rdapTosStaticUrl = "https://www.registry.tld/about/rdap/tos.html";
|
||||
rdapJsonFormatter.rdapTosStaticUrl = "https://www.example.tld/about/rdap/tos.html";
|
||||
return rdapJsonFormatter;
|
||||
}
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ import google.registry.model.common.CursorTest;
|
||||
import google.registry.model.common.DnsRefreshRequestTest;
|
||||
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;
|
||||
@@ -104,6 +105,7 @@ import org.junit.runner.RunWith;
|
||||
FeatureFlagTest.class,
|
||||
HostHistoryTest.class,
|
||||
LockTest.class,
|
||||
PasswordResetRequestTest.class,
|
||||
PollMessageTest.class,
|
||||
PremiumListDaoTest.class,
|
||||
RdeRevisionTest.class,
|
||||
|
||||
@@ -15,10 +15,10 @@
|
||||
package google.registry.schema.registrar;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static google.registry.model.ImmutableObjectSubject.assertAboutImmutableObjects;
|
||||
import static google.registry.model.registrar.RegistrarPoc.Type.WHOIS;
|
||||
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
|
||||
import static google.registry.testing.DatabaseHelper.insertInDb;
|
||||
import static google.registry.testing.DatabaseHelper.loadByEntity;
|
||||
import static google.registry.testing.SqlHelper.saveRegistrar;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
@@ -63,7 +63,9 @@ class RegistrarPocTest {
|
||||
@Test
|
||||
void testPersistence_succeeds() {
|
||||
insertInDb(testRegistrarPoc);
|
||||
assertThat(loadByEntity(testRegistrarPoc)).isEqualTo(testRegistrarPoc);
|
||||
assertAboutImmutableObjects()
|
||||
.that(testRegistrarPoc)
|
||||
.isEqualExceptFields(testRegistrarPoc, "id");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
package google.registry.tools;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static google.registry.model.ImmutableObjectSubject.assertAboutImmutableObjects;
|
||||
import static google.registry.model.registrar.RegistrarPoc.Type.ABUSE;
|
||||
import static google.registry.model.registrar.RegistrarPoc.Type.ADMIN;
|
||||
import static google.registry.model.registrar.RegistrarPoc.Type.TECH;
|
||||
@@ -102,8 +103,9 @@ class RegistrarPocCommandTest extends CommandTestCase<RegistrarPocCommand> {
|
||||
"--visible_in_domain_whois_as_abuse=false",
|
||||
"NewRegistrar");
|
||||
RegistrarPoc registrarPoc = loadRegistrar("NewRegistrar").getContacts().asList().get(1);
|
||||
assertThat(registrarPoc)
|
||||
.isEqualTo(
|
||||
assertAboutImmutableObjects()
|
||||
.that(registrarPoc)
|
||||
.isEqualExceptFields(
|
||||
new RegistrarPoc.Builder()
|
||||
.setRegistrar(registrar)
|
||||
.setName("Judith Registrar")
|
||||
@@ -115,7 +117,8 @@ class RegistrarPocCommandTest extends CommandTestCase<RegistrarPocCommand> {
|
||||
.setVisibleInWhoisAsAdmin(true)
|
||||
.setVisibleInWhoisAsTech(false)
|
||||
.setVisibleInDomainWhoisAsAbuse(false)
|
||||
.build());
|
||||
.build(),
|
||||
"id");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -261,8 +264,9 @@ class RegistrarPocCommandTest extends CommandTestCase<RegistrarPocCommand> {
|
||||
"--visible_in_domain_whois_as_abuse=true",
|
||||
"NewRegistrar");
|
||||
RegistrarPoc registrarPoc = loadRegistrar("NewRegistrar").getContacts().asList().get(1);
|
||||
assertThat(registrarPoc)
|
||||
.isEqualTo(
|
||||
assertAboutImmutableObjects()
|
||||
.that(registrarPoc)
|
||||
.isEqualExceptFields(
|
||||
new RegistrarPoc.Builder()
|
||||
.setRegistrar(registrar)
|
||||
.setName("Jim Doe")
|
||||
@@ -272,7 +276,8 @@ class RegistrarPocCommandTest extends CommandTestCase<RegistrarPocCommand> {
|
||||
.setVisibleInWhoisAsAdmin(true)
|
||||
.setVisibleInWhoisAsTech(false)
|
||||
.setVisibleInDomainWhoisAsAbuse(true)
|
||||
.build());
|
||||
.build(),
|
||||
"id");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -20,8 +20,10 @@ import static google.registry.model.registrar.RegistrarPoc.Type.ABUSE;
|
||||
import static google.registry.model.registrar.RegistrarPoc.Type.ADMIN;
|
||||
import static google.registry.model.registrar.RegistrarPoc.Type.MARKETING;
|
||||
import static google.registry.model.registrar.RegistrarPoc.Type.TECH;
|
||||
import static google.registry.testing.DatabaseHelper.deleteResource;
|
||||
import static google.registry.testing.DatabaseHelper.insertInDb;
|
||||
import static google.registry.testing.DatabaseHelper.loadAllOf;
|
||||
import static google.registry.testing.DatabaseHelper.persistResource;
|
||||
import static google.registry.testing.SqlHelper.saveRegistrar;
|
||||
import static jakarta.servlet.http.HttpServletResponse.SC_BAD_REQUEST;
|
||||
import static jakarta.servlet.http.HttpServletResponse.SC_FORBIDDEN;
|
||||
@@ -57,7 +59,7 @@ import org.junit.jupiter.api.Test;
|
||||
/** Tests for {@link google.registry.ui.server.console.settings.ContactAction}. */
|
||||
class ContactActionTest extends ConsoleActionBaseTestCase {
|
||||
private static String jsonRegistrar1 =
|
||||
"{\"name\":\"Test Registrar 1\","
|
||||
"{\"id\":%s,\"name\":\"Test Registrar 1\","
|
||||
+ "\"emailAddress\":\"test.registrar1@example.com\","
|
||||
+ "\"registrarId\":\"registrarId\","
|
||||
+ "\"phoneNumber\":\"+1.9999999999\",\"faxNumber\":\"+1.9999999991\","
|
||||
@@ -73,17 +75,18 @@ class ContactActionTest extends ConsoleActionBaseTestCase {
|
||||
void beforeEach() {
|
||||
testRegistrar = saveRegistrar("registrarId");
|
||||
adminPoc =
|
||||
new RegistrarPoc.Builder()
|
||||
.setRegistrar(testRegistrar)
|
||||
.setName("Test Registrar 1")
|
||||
.setEmailAddress("test.registrar1@example.com")
|
||||
.setPhoneNumber("+1.9999999999")
|
||||
.setFaxNumber("+1.9999999991")
|
||||
.setTypes(ImmutableSet.of(ADMIN))
|
||||
.setVisibleInWhoisAsAdmin(true)
|
||||
.setVisibleInWhoisAsTech(false)
|
||||
.setVisibleInDomainWhoisAsAbuse(false)
|
||||
.build();
|
||||
persistResource(
|
||||
new RegistrarPoc.Builder()
|
||||
.setRegistrar(testRegistrar)
|
||||
.setName("Test Registrar 1")
|
||||
.setEmailAddress("test.registrar1@example.com")
|
||||
.setPhoneNumber("+1.9999999999")
|
||||
.setFaxNumber("+1.9999999991")
|
||||
.setTypes(ImmutableSet.of(ADMIN))
|
||||
.setVisibleInWhoisAsAdmin(true)
|
||||
.setVisibleInWhoisAsTech(false)
|
||||
.setVisibleInDomainWhoisAsAbuse(false)
|
||||
.build());
|
||||
techPoc =
|
||||
adminPoc
|
||||
.asBuilder()
|
||||
@@ -109,39 +112,26 @@ class ContactActionTest extends ConsoleActionBaseTestCase {
|
||||
|
||||
@Test
|
||||
void testSuccess_getContactInfo() throws IOException {
|
||||
insertInDb(adminPoc);
|
||||
ContactAction action = createAction(Action.Method.GET, fteUser, testRegistrar.getRegistrarId());
|
||||
ContactAction action =
|
||||
createAction(Action.Method.GET, fteUser, testRegistrar.getRegistrarId(), null);
|
||||
action.run();
|
||||
assertThat(response.getStatus()).isEqualTo(SC_OK);
|
||||
assertThat(response.getPayload()).isEqualTo("[" + jsonRegistrar1 + "]");
|
||||
assertThat(response.getPayload()).contains(String.format(jsonRegistrar1, adminPoc.getId()));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_noOp() throws IOException {
|
||||
insertInDb(adminPoc);
|
||||
ContactAction action =
|
||||
createAction(Action.Method.POST, fteUser, testRegistrar.getRegistrarId(), adminPoc);
|
||||
createAction(Action.Method.PUT, fteUser, testRegistrar.getRegistrarId(), adminPoc);
|
||||
action.run();
|
||||
assertThat(response.getStatus()).isEqualTo(SC_OK);
|
||||
verify(consoleApiParams.sendEmailUtils().gmailClient, never()).sendEmail(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_onlyContactsWithNonEmptyType() throws IOException {
|
||||
adminPoc = adminPoc.asBuilder().setTypes(ImmutableSet.of()).build();
|
||||
insertInDb(adminPoc);
|
||||
ContactAction action = createAction(Action.Method.GET, fteUser, testRegistrar.getRegistrarId());
|
||||
action.run();
|
||||
assertThat(response.getStatus()).isEqualTo(SC_OK);
|
||||
assertThat(response.getPayload()).isEqualTo("[]");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_postCreateContactInfo() throws IOException {
|
||||
insertInDb(adminPoc);
|
||||
ContactAction action =
|
||||
createAction(
|
||||
Action.Method.POST, fteUser, testRegistrar.getRegistrarId(), adminPoc, techPoc);
|
||||
createAction(Action.Method.POST, fteUser, testRegistrar.getRegistrarId(), techPoc);
|
||||
action.run();
|
||||
assertThat(response.getStatus()).isEqualTo(SC_OK);
|
||||
assertThat(
|
||||
@@ -154,10 +144,14 @@ class ContactActionTest extends ConsoleActionBaseTestCase {
|
||||
|
||||
@Test
|
||||
void testSuccess_postUpdateContactInfo() throws IOException {
|
||||
insertInDb(techPoc.asBuilder().setEmailAddress("incorrect@email.com").build());
|
||||
RegistrarPoc techPocIncorrect =
|
||||
persistResource(techPoc.asBuilder().setEmailAddress("incorrect@email.com").build());
|
||||
ContactAction action =
|
||||
createAction(
|
||||
Action.Method.POST, fteUser, testRegistrar.getRegistrarId(), adminPoc, techPoc);
|
||||
Action.Method.PUT,
|
||||
fteUser,
|
||||
testRegistrar.getRegistrarId(),
|
||||
techPocIncorrect.asBuilder().setEmailAddress(techPoc.getEmailAddress()).build());
|
||||
action.run();
|
||||
assertThat(response.getStatus()).isEqualTo(SC_OK);
|
||||
HashMap<String, String> testResult = new HashMap<>();
|
||||
@@ -174,12 +168,12 @@ class ContactActionTest extends ConsoleActionBaseTestCase {
|
||||
|
||||
@Test
|
||||
void testFailure_postUpdateContactInfo_duplicateEmails() throws IOException {
|
||||
insertInDb(techPoc);
|
||||
ContactAction action =
|
||||
createAction(
|
||||
Action.Method.POST,
|
||||
fteUser,
|
||||
testRegistrar.getRegistrarId(),
|
||||
adminPoc,
|
||||
techPoc.asBuilder().setEmailAddress("test.registrar1@example.com").build());
|
||||
action.run();
|
||||
assertThat(response.getStatus()).isEqualTo(SC_BAD_REQUEST);
|
||||
@@ -189,16 +183,16 @@ class ContactActionTest extends ConsoleActionBaseTestCase {
|
||||
assertThat(
|
||||
loadAllOf(RegistrarPoc.class).stream()
|
||||
.filter(r -> r.registrarId.equals(testRegistrar.getRegistrarId()))
|
||||
.map(r -> r.getName())
|
||||
.collect(toImmutableList()))
|
||||
.isEmpty();
|
||||
.containsExactly("Test Registrar 1", "Test Registrar 2");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_postUpdateContactInfo_requiredContactRemoved() throws IOException {
|
||||
insertInDb(adminPoc);
|
||||
ContactAction action =
|
||||
createAction(
|
||||
Action.Method.POST,
|
||||
Action.Method.PUT,
|
||||
fteUser,
|
||||
testRegistrar.getRegistrarId(),
|
||||
adminPoc.asBuilder().setTypes(ImmutableSet.of(ABUSE)).build());
|
||||
@@ -214,11 +208,10 @@ class ContactActionTest extends ConsoleActionBaseTestCase {
|
||||
|
||||
@Test
|
||||
void testFailure_postUpdateContactInfo_phoneNumberRemoved() throws IOException {
|
||||
adminPoc = adminPoc.asBuilder().setTypes(ImmutableSet.of(ADMIN, TECH)).build();
|
||||
insertInDb(adminPoc);
|
||||
adminPoc = persistResource(adminPoc.asBuilder().setTypes(ImmutableSet.of(ADMIN, TECH)).build());
|
||||
ContactAction action =
|
||||
createAction(
|
||||
Action.Method.POST,
|
||||
Action.Method.PUT,
|
||||
fteUser,
|
||||
testRegistrar.getRegistrarId(),
|
||||
adminPoc
|
||||
@@ -244,25 +237,19 @@ class ContactActionTest extends ConsoleActionBaseTestCase {
|
||||
Action.Method.POST,
|
||||
fteUser,
|
||||
testRegistrar.getRegistrarId(),
|
||||
adminPoc.asBuilder().setPhoneNumber(null).setVisibleInDomainWhoisAsAbuse(true).build());
|
||||
techPoc.asBuilder().setPhoneNumber(null).setVisibleInDomainWhoisAsAbuse(true).build());
|
||||
action.run();
|
||||
assertThat(response.getStatus()).isEqualTo(SC_BAD_REQUEST);
|
||||
assertThat(response.getPayload())
|
||||
.isEqualTo("The abuse contact visible in domain WHOIS query must have a phone number");
|
||||
assertThat(
|
||||
loadAllOf(RegistrarPoc.class).stream()
|
||||
.filter(r -> r.registrarId.equals(testRegistrar.getRegistrarId()))
|
||||
.collect(toImmutableList()))
|
||||
.isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_postUpdateContactInfo_whoisContactPhoneNumberRemoved() throws IOException {
|
||||
adminPoc = adminPoc.asBuilder().setVisibleInDomainWhoisAsAbuse(true).build();
|
||||
insertInDb(adminPoc);
|
||||
adminPoc = persistResource(adminPoc.asBuilder().setVisibleInDomainWhoisAsAbuse(true).build());
|
||||
ContactAction action =
|
||||
createAction(
|
||||
Action.Method.POST,
|
||||
Action.Method.PUT,
|
||||
fteUser,
|
||||
testRegistrar.getRegistrarId(),
|
||||
adminPoc.asBuilder().setVisibleInDomainWhoisAsAbuse(false).build());
|
||||
@@ -277,88 +264,17 @@ class ContactActionTest extends ConsoleActionBaseTestCase {
|
||||
.containsExactly(adminPoc);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_postUpdateContactInfo_newContactCannotSetRegistryLockPassword()
|
||||
throws IOException {
|
||||
ContactAction action =
|
||||
createAction(
|
||||
Action.Method.POST,
|
||||
fteUser,
|
||||
testRegistrar.getRegistrarId(),
|
||||
adminPoc
|
||||
.asBuilder()
|
||||
.setAllowedToSetRegistryLockPassword(true)
|
||||
.setRegistryLockEmailAddress("lock@example.com")
|
||||
.build());
|
||||
action.run();
|
||||
assertThat(response.getStatus()).isEqualTo(SC_BAD_REQUEST);
|
||||
assertThat(response.getPayload())
|
||||
.isEqualTo("Cannot set registry lock password directly on new contact");
|
||||
assertThat(
|
||||
loadAllOf(RegistrarPoc.class).stream()
|
||||
.filter(r -> r.registrarId.equals(testRegistrar.getRegistrarId()))
|
||||
.collect(toImmutableList()))
|
||||
.isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_postUpdateContactInfo_cannotModifyRegistryLockEmail() throws IOException {
|
||||
adminPoc =
|
||||
adminPoc
|
||||
.asBuilder()
|
||||
.setRegistryLockEmailAddress("lock@example.com")
|
||||
.setAllowedToSetRegistryLockPassword(true)
|
||||
.build();
|
||||
insertInDb(adminPoc);
|
||||
ContactAction action =
|
||||
createAction(
|
||||
Action.Method.POST,
|
||||
fteUser,
|
||||
testRegistrar.getRegistrarId(),
|
||||
adminPoc.asBuilder().setRegistryLockEmailAddress("unlock@example.com").build());
|
||||
action.run();
|
||||
assertThat(response.getStatus()).isEqualTo(SC_BAD_REQUEST);
|
||||
assertThat(response.getPayload())
|
||||
.isEqualTo("Cannot modify registryLockEmailAddress through the UI");
|
||||
assertThat(
|
||||
loadAllOf(RegistrarPoc.class).stream()
|
||||
.filter(r -> r.registrarId.equals(testRegistrar.getRegistrarId()))
|
||||
.collect(toImmutableList()))
|
||||
.containsExactly(adminPoc);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_postUpdateContactInfo_cannotSetIsAllowedToSetRegistryLockPassword()
|
||||
throws IOException {
|
||||
adminPoc =
|
||||
adminPoc
|
||||
.asBuilder()
|
||||
.setRegistryLockEmailAddress("lock@example.com")
|
||||
.setAllowedToSetRegistryLockPassword(false)
|
||||
.build();
|
||||
insertInDb(adminPoc);
|
||||
ContactAction action =
|
||||
createAction(
|
||||
Action.Method.POST,
|
||||
fteUser,
|
||||
testRegistrar.getRegistrarId(),
|
||||
adminPoc.asBuilder().setAllowedToSetRegistryLockPassword(true).build());
|
||||
action.run();
|
||||
assertThat(response.getStatus()).isEqualTo(SC_BAD_REQUEST);
|
||||
assertThat(response.getPayload())
|
||||
.isEqualTo("Cannot modify isAllowedToSetRegistryLockPassword through the UI");
|
||||
assertThat(
|
||||
loadAllOf(RegistrarPoc.class).stream()
|
||||
.filter(r -> r.registrarId.equals(testRegistrar.getRegistrarId()))
|
||||
.collect(toImmutableList()))
|
||||
.containsExactly(adminPoc);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_sendsEmail() throws IOException, AddressException {
|
||||
insertInDb(techPoc.asBuilder().setEmailAddress("incorrect@email.com").build());
|
||||
deleteResource(adminPoc);
|
||||
techPoc = persistResource(techPoc);
|
||||
Long id = techPoc.getId();
|
||||
ContactAction action =
|
||||
createAction(Action.Method.POST, fteUser, testRegistrar.getRegistrarId(), techPoc);
|
||||
createAction(
|
||||
Action.Method.PUT,
|
||||
fteUser,
|
||||
testRegistrar.getRegistrarId(),
|
||||
techPoc.asBuilder().setEmailAddress("incorrect@example.com").build());
|
||||
action.run();
|
||||
assertThat(response.getStatus()).isEqualTo(SC_OK);
|
||||
verify(consoleApiParams.sendEmailUtils().gmailClient, times(1))
|
||||
@@ -373,23 +289,29 @@ class ContactActionTest extends ConsoleActionBaseTestCase {
|
||||
+ "\n"
|
||||
+ "contacts:\n"
|
||||
+ " ADDED:\n"
|
||||
+ " {name=Test Registrar 2,"
|
||||
+ " emailAddress=test.registrar2@example.com, registrarId=registrarId,"
|
||||
+ " {id="
|
||||
+ id
|
||||
+ ", name=Test Registrar 2,"
|
||||
+ " emailAddress=incorrect@example.com, registrarId=registrarId,"
|
||||
+ " registryLockEmailAddress=null, phoneNumber=+1.1234567890,"
|
||||
+ " faxNumber=+1.1234567891, types=[TECH],"
|
||||
+ " visibleInWhoisAsAdmin=false, visibleInWhoisAsTech=true,"
|
||||
+ " visibleInDomainWhoisAsAbuse=false,"
|
||||
+ " allowedToSetRegistryLockPassword=false}\n"
|
||||
+ " REMOVED:\n"
|
||||
+ " {name=Test Registrar 2, emailAddress=incorrect@email.com,"
|
||||
+ " {id="
|
||||
+ id
|
||||
+ ", name=Test Registrar 2, emailAddress=test.registrar2@example.com,"
|
||||
+ " registrarId=registrarId, registryLockEmailAddress=null,"
|
||||
+ " phoneNumber=+1.1234567890, faxNumber=+1.1234567891, types=[TECH],"
|
||||
+ " visibleInWhoisAsAdmin=false,"
|
||||
+ " visibleInWhoisAsTech=true, visibleInDomainWhoisAsAbuse=false,"
|
||||
+ " allowedToSetRegistryLockPassword=false}\n"
|
||||
+ " FINAL CONTENTS:\n"
|
||||
+ " {name=Test Registrar 2,"
|
||||
+ " emailAddress=test.registrar2@example.com, registrarId=registrarId,"
|
||||
+ " {id="
|
||||
+ id
|
||||
+ ", name=Test Registrar 2,"
|
||||
+ " emailAddress=incorrect@example.com, registrarId=registrarId,"
|
||||
+ " registryLockEmailAddress=null, phoneNumber=+1.1234567890,"
|
||||
+ " faxNumber=+1.1234567891, types=[TECH],"
|
||||
+ " visibleInWhoisAsAdmin=false, visibleInWhoisAsTech=true,"
|
||||
@@ -401,10 +323,9 @@ class ContactActionTest extends ConsoleActionBaseTestCase {
|
||||
|
||||
@Test
|
||||
void testSuccess_postDeleteContactInfo() throws IOException {
|
||||
insertInDb(adminPoc, techPoc, marketingPoc);
|
||||
insertInDb(techPoc, marketingPoc);
|
||||
ContactAction action =
|
||||
createAction(
|
||||
Action.Method.POST, fteUser, testRegistrar.getRegistrarId(), adminPoc, techPoc);
|
||||
createAction(Action.Method.DELETE, fteUser, testRegistrar.getRegistrarId(), marketingPoc);
|
||||
action.run();
|
||||
assertThat(response.getStatus()).isEqualTo(SC_OK);
|
||||
assertThat(
|
||||
@@ -417,10 +338,9 @@ class ContactActionTest extends ConsoleActionBaseTestCase {
|
||||
|
||||
@Test
|
||||
void testFailure_postDeleteContactInfo_missingPermission() throws IOException {
|
||||
insertInDb(adminPoc);
|
||||
ContactAction action =
|
||||
createAction(
|
||||
Action.Method.POST,
|
||||
Action.Method.DELETE,
|
||||
new User.Builder()
|
||||
.setEmailAddress("email@email.com")
|
||||
.setUserRoles(
|
||||
@@ -438,9 +358,12 @@ class ContactActionTest extends ConsoleActionBaseTestCase {
|
||||
|
||||
@Test
|
||||
void testFailure_changesAdminEmail() throws Exception {
|
||||
insertInDb(adminPoc.asBuilder().setEmailAddress("oldemail@example.com").build());
|
||||
ContactAction action =
|
||||
createAction(Action.Method.POST, fteUser, testRegistrar.getRegistrarId(), adminPoc);
|
||||
createAction(
|
||||
Action.Method.PUT,
|
||||
fteUser,
|
||||
testRegistrar.getRegistrarId(),
|
||||
adminPoc.asBuilder().setEmailAddress("testemail@example.com").build());
|
||||
action.run();
|
||||
FakeResponse fakeResponse = response;
|
||||
assertThat(fakeResponse.getStatus()).isEqualTo(400);
|
||||
@@ -449,16 +372,14 @@ class ContactActionTest extends ConsoleActionBaseTestCase {
|
||||
}
|
||||
|
||||
private ContactAction createAction(
|
||||
Action.Method method, User user, String registrarId, RegistrarPoc... contacts)
|
||||
Action.Method method, User user, String registrarId, RegistrarPoc contact)
|
||||
throws IOException {
|
||||
consoleApiParams = ConsoleApiParamsUtils.createFake(AuthResult.createUser(user));
|
||||
when(consoleApiParams.request().getMethod()).thenReturn(method.toString());
|
||||
response = (FakeResponse) consoleApiParams.response();
|
||||
if (method.equals(Action.Method.GET)) {
|
||||
return new ContactAction(consoleApiParams, registrarId, Optional.empty());
|
||||
} else {
|
||||
return new ContactAction(
|
||||
consoleApiParams, registrarId, Optional.of(ImmutableSet.copyOf(contacts)));
|
||||
}
|
||||
return new ContactAction(consoleApiParams, registrarId, Optional.of(contact));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ package google.registry.whois;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static google.registry.bsa.persistence.BsaTestingUtils.persistBsaLabel;
|
||||
import static google.registry.model.EppResourceUtils.loadByForeignKeyCached;
|
||||
import static google.registry.model.EppResourceUtils.loadByForeignKeyByCacheIfEnabled;
|
||||
import static google.registry.model.registrar.Registrar.State.ACTIVE;
|
||||
import static google.registry.model.registrar.Registrar.Type.PDT;
|
||||
import static google.registry.model.tld.Tlds.getTlds;
|
||||
@@ -147,8 +147,9 @@ public class WhoisActionTest {
|
||||
persistResource(makeDomainWithRegistrar(registrar));
|
||||
persistSimpleResources(makeRegistrarPocs(registrar));
|
||||
// Populate the cache for both the domain and contact.
|
||||
Domain domain = loadByForeignKeyCached(Domain.class, "cat.lol", clock.nowUtc()).get();
|
||||
Contact contact = loadByForeignKeyCached(Contact.class, "5372808-ERL", clock.nowUtc()).get();
|
||||
Domain domain = loadByForeignKeyByCacheIfEnabled(Domain.class, "cat.lol", clock.nowUtc()).get();
|
||||
Contact contact =
|
||||
loadByForeignKeyByCacheIfEnabled(Contact.class, "5372808-ERL", clock.nowUtc()).get();
|
||||
// Make a change to the domain and contact that won't be seen because the cache will be hit.
|
||||
persistResource(domain.asBuilder().setDeletionTime(clock.nowUtc().minusDays(1)).build());
|
||||
persistResource(
|
||||
@@ -280,7 +281,7 @@ public class WhoisActionTest {
|
||||
@Test
|
||||
void testRun_domainNotFound_usesCache() {
|
||||
// Populate the cache with the nonexistence of this domain.
|
||||
assertThat(loadByForeignKeyCached(Domain.class, "cat.lol", clock.nowUtc())).isEmpty();
|
||||
assertThat(loadByForeignKeyByCacheIfEnabled(Domain.class, "cat.lol", clock.nowUtc())).isEmpty();
|
||||
// Add a new valid cat.lol domain that won't be found because the cache will be hit instead.
|
||||
persistActiveDomain("cat.lol");
|
||||
newWhoisAction("domain cat.lol\r\n").run();
|
||||
@@ -435,7 +436,8 @@ public class WhoisActionTest {
|
||||
void testRun_nameserver_usesCache() {
|
||||
persistResource(FullFieldsTestEntityHelper.makeHost("ns1.cat.xn--q9jyb4c", "1.2.3.4"));
|
||||
// Populate the cache.
|
||||
Host host = loadByForeignKeyCached(Host.class, "ns1.cat.xn--q9jyb4c", clock.nowUtc()).get();
|
||||
Host host =
|
||||
loadByForeignKeyByCacheIfEnabled(Host.class, "ns1.cat.xn--q9jyb4c", clock.nowUtc()).get();
|
||||
// Make a change to the persisted host that won't be seen because the cache will be hit.
|
||||
persistResource(
|
||||
host.asBuilder()
|
||||
|
||||
@@ -11,7 +11,7 @@ CONSOLE /console-api/registrar ConsoleUpdateRegistrarAction POST
|
||||
CONSOLE /console-api/registrars RegistrarsAction GET,POST n USER PUBLIC
|
||||
CONSOLE /console-api/registry-lock ConsoleRegistryLockAction GET,POST n USER PUBLIC
|
||||
CONSOLE /console-api/registry-lock-verify ConsoleRegistryLockVerifyAction GET n USER PUBLIC
|
||||
CONSOLE /console-api/settings/contacts ContactAction GET,POST n USER PUBLIC
|
||||
CONSOLE /console-api/settings/contacts ContactAction GET,POST,DELETE,PUT n USER PUBLIC
|
||||
CONSOLE /console-api/settings/rdap-fields RdapRegistrarFieldsAction POST n USER PUBLIC
|
||||
CONSOLE /console-api/settings/security SecurityAction POST n USER PUBLIC
|
||||
CONSOLE /console-api/userdata ConsoleUserDataAction GET n USER PUBLIC
|
||||
|
||||
@@ -79,7 +79,7 @@ CONSOLE /console-api/registrar ConsoleUpdateRegistr
|
||||
CONSOLE /console-api/registrars RegistrarsAction GET,POST n USER PUBLIC
|
||||
CONSOLE /console-api/registry-lock ConsoleRegistryLockAction GET,POST n USER PUBLIC
|
||||
CONSOLE /console-api/registry-lock-verify ConsoleRegistryLockVerifyAction GET n USER PUBLIC
|
||||
CONSOLE /console-api/settings/contacts ContactAction GET,POST n USER PUBLIC
|
||||
CONSOLE /console-api/settings/contacts ContactAction GET,POST,DELETE,PUT n USER PUBLIC
|
||||
CONSOLE /console-api/settings/rdap-fields RdapRegistrarFieldsAction POST n USER PUBLIC
|
||||
CONSOLE /console-api/settings/security SecurityAction POST n USER PUBLIC
|
||||
CONSOLE /console-api/userdata ConsoleUserDataAction GET n USER PUBLIC
|
||||
|
||||
@@ -5,13 +5,14 @@
|
||||
"icann_rdap_technical_implementation_guide_0"
|
||||
],
|
||||
"objectClassName": "entity",
|
||||
"handle": "%NAME%",
|
||||
"handle": "%CONTACT_HANDLE_1%",
|
||||
"status": ["active", "associated"],
|
||||
"links": [
|
||||
{
|
||||
"rel": "self",
|
||||
"href": "https://example.tld/rdap/entity/%NAME%",
|
||||
"type": "application/rdap+json"
|
||||
"href": "https://example.tld/rdap/entity/%CONTACT_HANDLE_1%",
|
||||
"type": "application/rdap+json",
|
||||
"value": "%REQUEST_URL%"
|
||||
}
|
||||
],
|
||||
"events": [
|
||||
@@ -25,13 +26,13 @@
|
||||
"vcard",
|
||||
[
|
||||
["version", {}, "text", "4.0"],
|
||||
["fn", {}, "text", "%FULLNAME%"],
|
||||
["fn", {}, "text", "%CONTACT_FULLNAME_1%"],
|
||||
["org", {}, "text", "GOOGLE INCORPORATED <script>"],
|
||||
["adr", {}, "text",
|
||||
[
|
||||
"",
|
||||
"",
|
||||
[ %ADDRESS% ],
|
||||
[ %CONTACT_ADDRESS_1% ],
|
||||
"KOKOMO",
|
||||
"BM",
|
||||
"31337",
|
||||
|
||||
@@ -27,7 +27,8 @@
|
||||
{
|
||||
"type":"text\/html",
|
||||
"href": "https:\/\/github.com\/google\/nomulus\/blob\/master\/docs\/rdap.md#authentication",
|
||||
"rel": "alternate"
|
||||
"rel": "alternate",
|
||||
"value": "%REQUEST_URL%"
|
||||
}
|
||||
],
|
||||
"description": [
|
||||
|
||||
@@ -5,14 +5,15 @@
|
||||
"icann_rdap_technical_implementation_guide_0"
|
||||
],
|
||||
"objectClassName" : "entity",
|
||||
"handle" : "%NAME%",
|
||||
"status" : ["%STATUS%"],
|
||||
"handle" : "%CONTACT_HANDLE_1%",
|
||||
"status" : ["%STATUS_1%"],
|
||||
"links" :
|
||||
[
|
||||
{
|
||||
"rel" : "self",
|
||||
"href": "https://example.tld/rdap/entity/%NAME%",
|
||||
"type" : "application/rdap+json"
|
||||
"href": "https://example.tld/rdap/entity/%CONTACT_HANDLE_1%",
|
||||
"type" : "application/rdap+json",
|
||||
"value": "%REQUEST_URL%"
|
||||
}
|
||||
],
|
||||
"events": [
|
||||
@@ -26,13 +27,13 @@
|
||||
"vcard",
|
||||
[
|
||||
["version", {}, "text", "4.0"],
|
||||
["fn", {}, "text", "%FULLNAME%"],
|
||||
["fn", {}, "text", "%CONTACT_FULLNAME_1%"],
|
||||
["org", {}, "text", "GOOGLE INCORPORATED <script>"],
|
||||
["adr", {}, "text",
|
||||
[
|
||||
"",
|
||||
"",
|
||||
[ %ADDRESS% ],
|
||||
[ %CONTACT_ADDRESS_1% ],
|
||||
"KOKOMO",
|
||||
"BM",
|
||||
"31337",
|
||||
|
||||
@@ -5,14 +5,15 @@
|
||||
"icann_rdap_technical_implementation_guide_0"
|
||||
],
|
||||
"objectClassName" : "entity",
|
||||
"handle" : "%NAME%",
|
||||
"handle" : "%CONTACT_HANDLE_1%",
|
||||
"status" : ["inactive"],
|
||||
"links" :
|
||||
[
|
||||
{
|
||||
"rel" : "self",
|
||||
"href": "https://example.tld/rdap/entity/%NAME%",
|
||||
"type" : "application/rdap+json"
|
||||
"href": "https://example.tld/rdap/entity/%CONTACT_HANDLE_1%",
|
||||
"type" : "application/rdap+json",
|
||||
"value": "%REQUEST_URL%"
|
||||
}
|
||||
],
|
||||
"events":
|
||||
@@ -38,5 +39,4 @@
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
}
|
||||
|
||||
@@ -32,7 +32,8 @@
|
||||
{
|
||||
"rel" : "alternate",
|
||||
"href" : "https://github.com/google/nomulus/blob/master/docs/rdap.md#authentication",
|
||||
"type" : "text/html"
|
||||
"type" : "text/html",
|
||||
"value": "https://example.tld/rdap/entities"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -17,17 +17,20 @@
|
||||
{
|
||||
"href": "https://example.tld/rdap/domain/%DOMAIN_PUNYCODE_NAME_1%",
|
||||
"type": "application/rdap+json",
|
||||
"rel": "self"
|
||||
"rel": "self",
|
||||
"value": "%REQUEST_URL%"
|
||||
},
|
||||
{
|
||||
"href": "https://rdap.example.com/withSlash/domain/%DOMAIN_PUNYCODE_NAME_1%",
|
||||
"type": "application/rdap+json",
|
||||
"rel": "related"
|
||||
"rel": "related",
|
||||
"value": "%REQUEST_URL%"
|
||||
},
|
||||
{
|
||||
"href": "https://rdap.example.com/withoutSlash/domain/%DOMAIN_PUNYCODE_NAME_1%",
|
||||
"type": "application/rdap+json",
|
||||
"rel": "related"
|
||||
"rel": "related",
|
||||
"value": "%REQUEST_URL%"
|
||||
}
|
||||
],
|
||||
"events": [
|
||||
@@ -58,7 +61,8 @@
|
||||
{
|
||||
"href": "https://example.tld/rdap/nameserver/%NAMESERVER_NAME_1%",
|
||||
"type": "application/rdap+json",
|
||||
"rel": "self"
|
||||
"rel": "self",
|
||||
"value": "%REQUEST_URL%"
|
||||
}
|
||||
],
|
||||
"remarks": [
|
||||
@@ -79,7 +83,8 @@
|
||||
{
|
||||
"href": "https://example.tld/rdap/nameserver/%NAMESERVER_NAME_2%",
|
||||
"type": "application/rdap+json",
|
||||
"rel": "self"
|
||||
"rel": "self",
|
||||
"value": "%REQUEST_URL%"
|
||||
}
|
||||
],
|
||||
"remarks": [
|
||||
@@ -115,7 +120,8 @@
|
||||
{
|
||||
"href": "https://example.tld/rdap/entity/1",
|
||||
"type": "application/rdap+json",
|
||||
"rel": "self"
|
||||
"rel": "self",
|
||||
"value": "%REQUEST_URL%"
|
||||
}
|
||||
],
|
||||
"vcardArray" : [
|
||||
@@ -160,7 +166,8 @@
|
||||
{
|
||||
"href": "https://example.tld/rdap/entity/%CONTACT_HANDLE_1%",
|
||||
"type": "application/rdap+json",
|
||||
"rel": "self"
|
||||
"rel": "self",
|
||||
"value": "%REQUEST_URL%"
|
||||
}
|
||||
],
|
||||
"vcardArray": [
|
||||
@@ -197,7 +204,8 @@
|
||||
{
|
||||
"href": "https://example.tld/rdap/entity/%CONTACT_HANDLE_2%",
|
||||
"type": "application/rdap+json",
|
||||
"rel": "self"
|
||||
"rel": "self",
|
||||
"value": "%REQUEST_URL%"
|
||||
}
|
||||
],
|
||||
"vcardArray": [
|
||||
@@ -236,7 +244,8 @@
|
||||
{
|
||||
"href": "https://example.tld/rdap/entity/%CONTACT_HANDLE_3%",
|
||||
"type": "application/rdap+json",
|
||||
"rel": "self"
|
||||
"rel": "self",
|
||||
"value": "%REQUEST_URL%"
|
||||
}
|
||||
],
|
||||
"vcardArray": [
|
||||
|
||||
@@ -13,7 +13,8 @@
|
||||
{
|
||||
"href": "https://example.tld/rdap/entity/1",
|
||||
"rel": "self",
|
||||
"type": "application/rdap+json"
|
||||
"type": "application/rdap+json",
|
||||
"value": "https://example.tld/rdap/domain/addgraceperiod.lol"
|
||||
}
|
||||
],
|
||||
"publicIds": [
|
||||
@@ -65,7 +66,8 @@
|
||||
{
|
||||
"href": "https://github.com/google/nomulus/blob/master/docs/rdap.md#authentication",
|
||||
"rel": "alternate",
|
||||
"type": "text/html"
|
||||
"type": "text/html",
|
||||
"value": "https://example.tld/rdap/domain/addgraceperiod.lol"
|
||||
}
|
||||
],
|
||||
"title": "REDACTED FOR PRIVACY",
|
||||
@@ -124,7 +126,8 @@
|
||||
{
|
||||
"href": "https://example.tld/rdap/domain/addgraceperiod.lol",
|
||||
"rel": "self",
|
||||
"type": "application/rdap+json"
|
||||
"type": "application/rdap+json",
|
||||
"value": "https://example.tld/rdap/domain/addgraceperiod.lol"
|
||||
}
|
||||
],
|
||||
"nameservers": [
|
||||
@@ -136,7 +139,8 @@
|
||||
{
|
||||
"href": "https://example.tld/rdap/nameserver/ns1.cat.lol",
|
||||
"rel": "self",
|
||||
"type": "application/rdap+json"
|
||||
"type": "application/rdap+json",
|
||||
"value": "https://example.tld/rdap/domain/addgraceperiod.lol"
|
||||
}
|
||||
],
|
||||
"remarks": [
|
||||
|
||||
@@ -13,7 +13,8 @@
|
||||
{
|
||||
"href": "https://example.tld/rdap/entity/1",
|
||||
"rel": "self",
|
||||
"type": "application/rdap+json"
|
||||
"type": "application/rdap+json",
|
||||
"value": "https://example.tld/rdap/domain/autorenew.lol"
|
||||
}
|
||||
],
|
||||
"publicIds": [
|
||||
@@ -65,7 +66,8 @@
|
||||
{
|
||||
"href": "https://github.com/google/nomulus/blob/master/docs/rdap.md#authentication",
|
||||
"rel": "alternate",
|
||||
"type": "text/html"
|
||||
"type": "text/html",
|
||||
"value": "https://example.tld/rdap/domain/autorenew.lol"
|
||||
}
|
||||
],
|
||||
"title": "REDACTED FOR PRIVACY",
|
||||
@@ -128,7 +130,8 @@
|
||||
{
|
||||
"href": "https://example.tld/rdap/domain/autorenew.lol",
|
||||
"rel": "self",
|
||||
"type": "application/rdap+json"
|
||||
"type": "application/rdap+json",
|
||||
"value": "https://example.tld/rdap/domain/autorenew.lol"
|
||||
}
|
||||
],
|
||||
"nameservers": [
|
||||
@@ -140,7 +143,8 @@
|
||||
{
|
||||
"href": "https://example.tld/rdap/nameserver/ns1.cat.lol",
|
||||
"rel": "self",
|
||||
"type": "application/rdap+json"
|
||||
"type": "application/rdap+json",
|
||||
"value": "https://example.tld/rdap/domain/autorenew.lol"
|
||||
}
|
||||
],
|
||||
"remarks": [
|
||||
|
||||
@@ -17,17 +17,20 @@
|
||||
{
|
||||
"href": "https://example.tld/rdap/domain/%DOMAIN_PUNYCODE_NAME_1%",
|
||||
"type": "application/rdap+json",
|
||||
"rel": "self"
|
||||
"rel": "self",
|
||||
"value": "https://example.tld/rdap/domains"
|
||||
},
|
||||
{
|
||||
"href": "https://rdap.example.com/withSlash/domain/%DOMAIN_PUNYCODE_NAME_1%",
|
||||
"type": "application/rdap+json",
|
||||
"rel": "related"
|
||||
"rel": "related",
|
||||
"value": "https://example.tld/rdap/domains"
|
||||
},
|
||||
{
|
||||
"href": "https://rdap.example.com/withoutSlash/domain/%DOMAIN_PUNYCODE_NAME_1%",
|
||||
"type": "application/rdap+json",
|
||||
"rel": "related"
|
||||
"rel": "related",
|
||||
"value": "https://example.tld/rdap/domains"
|
||||
}
|
||||
],
|
||||
"events": [
|
||||
@@ -58,7 +61,8 @@
|
||||
{
|
||||
"href": "https://example.tld/rdap/nameserver/%NAMESERVER_NAME_1%",
|
||||
"type": "application/rdap+json",
|
||||
"rel": "self"
|
||||
"rel": "self",
|
||||
"value": "https://example.tld/rdap/domains"
|
||||
}
|
||||
],
|
||||
"remarks": [
|
||||
@@ -77,7 +81,8 @@
|
||||
{
|
||||
"href": "https://example.tld/rdap/nameserver/%NAMESERVER_NAME_2%",
|
||||
"type": "application/rdap+json",
|
||||
"rel": "self"
|
||||
"rel": "self",
|
||||
"value": "https://example.tld/rdap/domains"
|
||||
}
|
||||
],
|
||||
"remarks": [
|
||||
@@ -98,7 +103,8 @@
|
||||
{
|
||||
"href": "https://example.tld/rdap/entity/1",
|
||||
"type": "application/rdap+json",
|
||||
"rel": "self"
|
||||
"rel": "self",
|
||||
"value": "https://example.tld/rdap/domains"
|
||||
}
|
||||
],
|
||||
"vcardArray" : [
|
||||
@@ -149,7 +155,8 @@
|
||||
{
|
||||
"href": "https://example.tld/rdap/entity/%CONTACT_HANDLE_1%",
|
||||
"type": "application/rdap+json",
|
||||
"rel": "self"
|
||||
"rel": "self",
|
||||
"value": "%REQUEST_URL%"
|
||||
}
|
||||
],
|
||||
"vcardArray": [
|
||||
@@ -186,7 +193,8 @@
|
||||
{
|
||||
"href": "https://example.tld/rdap/entity/%CONTACT_HANDLE_2%",
|
||||
"type": "application/rdap+json",
|
||||
"rel": "self"
|
||||
"rel": "self",
|
||||
"value": "%REQUEST_URL%"
|
||||
}
|
||||
],
|
||||
"vcardArray": [
|
||||
@@ -223,7 +231,8 @@
|
||||
{
|
||||
"href": "https://example.tld/rdap/entity/%CONTACT_HANDLE_3%",
|
||||
"type": "application/rdap+json",
|
||||
"rel": "self"
|
||||
"rel": "self",
|
||||
"value": "%REQUEST_URL%"
|
||||
}
|
||||
],
|
||||
"vcardArray": [
|
||||
|
||||
@@ -18,17 +18,20 @@
|
||||
{
|
||||
"href": "https://example.tld/rdap/domain/%DOMAIN_PUNYCODE_NAME_1%",
|
||||
"type": "application/rdap+json",
|
||||
"rel": "self"
|
||||
"rel": "self",
|
||||
"value": "%REQUEST_URL%"
|
||||
},
|
||||
{
|
||||
"href": "https://rdap.example.com/withSlash/domain/%DOMAIN_PUNYCODE_NAME_1%",
|
||||
"type": "application/rdap+json",
|
||||
"rel": "related"
|
||||
"rel": "related",
|
||||
"value": "%REQUEST_URL%"
|
||||
},
|
||||
{
|
||||
"href": "https://rdap.example.com/withoutSlash/domain/%DOMAIN_PUNYCODE_NAME_1%",
|
||||
"type": "application/rdap+json",
|
||||
"rel": "related"
|
||||
"rel": "related",
|
||||
"value": "%REQUEST_URL%"
|
||||
}
|
||||
],
|
||||
"events": [
|
||||
@@ -64,7 +67,8 @@
|
||||
{
|
||||
"href": "https://example.tld/rdap/nameserver/%NAMESERVER_NAME_1%",
|
||||
"type": "application/rdap+json",
|
||||
"rel": "self"
|
||||
"rel": "self",
|
||||
"value": "%REQUEST_URL%"
|
||||
}
|
||||
],
|
||||
"remarks": [
|
||||
@@ -83,7 +87,8 @@
|
||||
{
|
||||
"href": "https://example.tld/rdap/nameserver/%NAMESERVER_NAME_2%",
|
||||
"type": "application/rdap+json",
|
||||
"rel": "self"
|
||||
"rel": "self",
|
||||
"value": "%REQUEST_URL%"
|
||||
}
|
||||
],
|
||||
"remarks": [
|
||||
@@ -110,7 +115,8 @@
|
||||
{
|
||||
"href": "https://example.tld/rdap/entity/1",
|
||||
"type": "application/rdap+json",
|
||||
"rel": "self"
|
||||
"rel": "self",
|
||||
"value": "%REQUEST_URL%"
|
||||
}
|
||||
],
|
||||
"vcardArray" : [
|
||||
@@ -155,7 +161,8 @@
|
||||
{
|
||||
"href": "https://example.tld/rdap/entity/%CONTACT_HANDLE_1%",
|
||||
"type": "application/rdap+json",
|
||||
"rel": "self"
|
||||
"rel": "self",
|
||||
"value": "%REQUEST_URL%"
|
||||
}
|
||||
],
|
||||
"vcardArray": [
|
||||
@@ -192,7 +199,8 @@
|
||||
{
|
||||
"href": "https://example.tld/rdap/entity/%CONTACT_HANDLE_2%",
|
||||
"type": "application/rdap+json",
|
||||
"rel": "self"
|
||||
"rel": "self",
|
||||
"value": "%REQUEST_URL%"
|
||||
}
|
||||
],
|
||||
"vcardArray": [
|
||||
@@ -229,7 +237,8 @@
|
||||
{
|
||||
"href": "https://example.tld/rdap/entity/%CONTACT_HANDLE_3%",
|
||||
"type": "application/rdap+json",
|
||||
"rel": "self"
|
||||
"rel": "self",
|
||||
"value": "%REQUEST_URL%"
|
||||
}
|
||||
],
|
||||
"vcardArray": [
|
||||
|
||||
@@ -13,7 +13,8 @@
|
||||
{
|
||||
"href": "https://example.tld/rdap/entity/1",
|
||||
"rel": "self",
|
||||
"type": "application/rdap+json"
|
||||
"type": "application/rdap+json",
|
||||
"value": "https://example.tld/rdap/domain/renew.lol"
|
||||
}
|
||||
],
|
||||
"publicIds": [
|
||||
@@ -65,7 +66,8 @@
|
||||
{
|
||||
"href": "https://github.com/google/nomulus/blob/master/docs/rdap.md#authentication",
|
||||
"rel": "alternate",
|
||||
"type": "text/html"
|
||||
"type": "text/html",
|
||||
"value": "https://example.tld/rdap/domain/renew.lol"
|
||||
}
|
||||
],
|
||||
"title": "REDACTED FOR PRIVACY",
|
||||
@@ -124,7 +126,8 @@
|
||||
{
|
||||
"href": "https://example.tld/rdap/domain/renew.lol",
|
||||
"rel": "self",
|
||||
"type": "application/rdap+json"
|
||||
"type": "application/rdap+json",
|
||||
"value": "https://example.tld/rdap/domain/renew.lol"
|
||||
}
|
||||
],
|
||||
"nameservers": [
|
||||
@@ -136,7 +139,8 @@
|
||||
{
|
||||
"href": "https://example.tld/rdap/nameserver/ns1.cat.lol",
|
||||
"rel": "self",
|
||||
"type": "application/rdap+json"
|
||||
"type": "application/rdap+json",
|
||||
"value": "https://example.tld/rdap/domain/renew.lol"
|
||||
}
|
||||
],
|
||||
"remarks": [
|
||||
|
||||
@@ -17,17 +17,20 @@
|
||||
{
|
||||
"href": "https://example.tld/rdap/domain/%DOMAIN_PUNYCODE_NAME_1%",
|
||||
"type": "application/rdap+json",
|
||||
"rel": "self"
|
||||
"rel": "self",
|
||||
"value": "https://example.tld/rdap/domain/cat.lol"
|
||||
},
|
||||
{
|
||||
"href": "https://rdap.example.com/withSlash/domain/%DOMAIN_PUNYCODE_NAME_1%",
|
||||
"type": "application/rdap+json",
|
||||
"rel": "related"
|
||||
"rel": "related",
|
||||
"value": "https://example.tld/rdap/domain/cat.lol"
|
||||
},
|
||||
{
|
||||
"href": "https://rdap.example.com/withoutSlash/domain/%DOMAIN_PUNYCODE_NAME_1%",
|
||||
"type": "application/rdap+json",
|
||||
"rel": "related"
|
||||
"rel": "related",
|
||||
"value": "https://example.tld/rdap/domain/cat.lol"
|
||||
}
|
||||
],
|
||||
"events": [
|
||||
@@ -58,7 +61,8 @@
|
||||
{
|
||||
"href": "https://example.tld/rdap/nameserver/%NAMESERVER_NAME_1%",
|
||||
"type": "application/rdap+json",
|
||||
"rel": "self"
|
||||
"rel": "self",
|
||||
"value": "https://example.tld/rdap/domain/cat.lol"
|
||||
}
|
||||
],
|
||||
"remarks": [
|
||||
@@ -77,7 +81,8 @@
|
||||
{
|
||||
"href": "https://example.tld/rdap/nameserver/%NAMESERVER_NAME_2%",
|
||||
"type": "application/rdap+json",
|
||||
"rel": "self"
|
||||
"rel": "self",
|
||||
"value": "https://example.tld/rdap/domain/cat.lol"
|
||||
}
|
||||
],
|
||||
"remarks": [
|
||||
@@ -105,7 +110,8 @@
|
||||
{
|
||||
"rel" : "self",
|
||||
"href" : "https://example.tld/rdap/entity/1",
|
||||
"type" : "application/rdap+json"
|
||||
"type" : "application/rdap+json",
|
||||
"value": "https://example.tld/rdap/domain/cat.lol"
|
||||
}
|
||||
],
|
||||
"publicIds" : [
|
||||
|
||||
@@ -17,17 +17,20 @@
|
||||
{
|
||||
"href": "https://example.tld/rdap/domain/%DOMAIN_PUNYCODE_NAME_1%",
|
||||
"type": "application/rdap+json",
|
||||
"rel": "self"
|
||||
"rel": "self",
|
||||
"value": "https://example.tld/rdap/domain/cat.lol"
|
||||
},
|
||||
{
|
||||
"href": "https://rdap.example.com/withSlash/domain/%DOMAIN_PUNYCODE_NAME_1%",
|
||||
"type": "application/rdap+json",
|
||||
"rel": "related"
|
||||
"rel": "related",
|
||||
"value": "https://example.tld/rdap/domain/cat.lol"
|
||||
},
|
||||
{
|
||||
"href": "https://rdap.example.com/withoutSlash/domain/%DOMAIN_PUNYCODE_NAME_1%",
|
||||
"type": "application/rdap+json",
|
||||
"rel": "related"
|
||||
"rel": "related",
|
||||
"value": "https://example.tld/rdap/domain/cat.lol"
|
||||
}
|
||||
],
|
||||
"events": [
|
||||
@@ -58,7 +61,8 @@
|
||||
{
|
||||
"href": "https://example.tld/rdap/nameserver/%NAMESERVER_NAME_1%",
|
||||
"type": "application/rdap+json",
|
||||
"rel": "self"
|
||||
"rel": "self",
|
||||
"value": "https://example.tld/rdap/domain/cat.lol"
|
||||
}
|
||||
],
|
||||
"remarks": [
|
||||
@@ -77,7 +81,8 @@
|
||||
{
|
||||
"href": "https://example.tld/rdap/nameserver/%NAMESERVER_NAME_2%",
|
||||
"type": "application/rdap+json",
|
||||
"rel": "self"
|
||||
"rel": "self",
|
||||
"value": "https://example.tld/rdap/domain/cat.lol"
|
||||
}
|
||||
],
|
||||
"remarks": [
|
||||
@@ -105,7 +110,8 @@
|
||||
{
|
||||
"rel" : "self",
|
||||
"href" : "https://example.tld/rdap/entity/1",
|
||||
"type" : "application/rdap+json"
|
||||
"type" : "application/rdap+json",
|
||||
"value": "https://example.tld/rdap/domain/cat.lol"
|
||||
}
|
||||
],
|
||||
"publicIds" : [
|
||||
@@ -164,7 +170,8 @@
|
||||
{
|
||||
"href":"https://github.com/google/nomulus/blob/master/docs/rdap.md#authentication",
|
||||
"rel":"alternate",
|
||||
"type":"text/html"
|
||||
"type":"text/html",
|
||||
"value": "https://example.tld/rdap/domain/cat.lol"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -200,7 +207,8 @@
|
||||
{
|
||||
"href":"https://github.com/google/nomulus/blob/master/docs/rdap.md#authentication",
|
||||
"rel":"alternate",
|
||||
"type":"text/html"
|
||||
"type":"text/html",
|
||||
"value": "https://example.tld/rdap/domain/cat.lol"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -13,7 +13,8 @@
|
||||
{
|
||||
"href": "https://example.tld/rdap/entity/1",
|
||||
"rel": "self",
|
||||
"type": "application/rdap+json"
|
||||
"type": "application/rdap+json",
|
||||
"value": "https://example.tld/rdap/domain/redemption.lol"
|
||||
}
|
||||
],
|
||||
"publicIds": [
|
||||
@@ -65,7 +66,8 @@
|
||||
{
|
||||
"href": "https://github.com/google/nomulus/blob/master/docs/rdap.md#authentication",
|
||||
"rel": "alternate",
|
||||
"type": "text/html"
|
||||
"type": "text/html",
|
||||
"value": "https://example.tld/rdap/domain/redemption.lol"
|
||||
}
|
||||
],
|
||||
"title": "REDACTED FOR PRIVACY",
|
||||
@@ -124,7 +126,8 @@
|
||||
{
|
||||
"href": "https://example.tld/rdap/domain/redemption.lol",
|
||||
"rel": "self",
|
||||
"type": "application/rdap+json"
|
||||
"type": "application/rdap+json",
|
||||
"value": "https://example.tld/rdap/domain/redemption.lol"
|
||||
}
|
||||
],
|
||||
"nameservers": [
|
||||
@@ -136,7 +139,8 @@
|
||||
{
|
||||
"href": "https://example.tld/rdap/nameserver/ns1.cat.lol",
|
||||
"rel": "self",
|
||||
"type": "application/rdap+json"
|
||||
"type": "application/rdap+json",
|
||||
"value": "https://example.tld/rdap/domain/redemption.lol"
|
||||
}
|
||||
],
|
||||
"remarks": [
|
||||
|
||||
@@ -17,17 +17,20 @@
|
||||
{
|
||||
"href": "https://example.tld/rdap/domain/%DOMAIN_PUNYCODE_NAME_1%",
|
||||
"type": "application/rdap+json",
|
||||
"rel": "self"
|
||||
"rel": "self",
|
||||
"value": "%REQUEST_URL%"
|
||||
},
|
||||
{
|
||||
"href": "https://rdap.example.com/withSlash/domain/%DOMAIN_PUNYCODE_NAME_1%",
|
||||
"type": "application/rdap+json",
|
||||
"rel": "related"
|
||||
"rel": "related",
|
||||
"value": "%REQUEST_URL%"
|
||||
},
|
||||
{
|
||||
"href": "https://rdap.example.com/withoutSlash/domain/%DOMAIN_PUNYCODE_NAME_1%",
|
||||
"type": "application/rdap+json",
|
||||
"rel": "related"
|
||||
"rel": "related",
|
||||
"value": "%REQUEST_URL%"
|
||||
}
|
||||
],
|
||||
"events": [
|
||||
@@ -58,7 +61,8 @@
|
||||
{
|
||||
"href": "https://example.tld/rdap/nameserver/%NAMESERVER_NAME_1%",
|
||||
"type": "application/rdap+json",
|
||||
"rel": "self"
|
||||
"rel": "self",
|
||||
"value": "%REQUEST_URL%"
|
||||
}
|
||||
],
|
||||
"remarks": [
|
||||
@@ -77,7 +81,8 @@
|
||||
{
|
||||
"href": "https://example.tld/rdap/nameserver/%NAMESERVER_NAME_2%",
|
||||
"type": "application/rdap+json",
|
||||
"rel": "self"
|
||||
"rel": "self",
|
||||
"value": "%REQUEST_URL%"
|
||||
}
|
||||
],
|
||||
"remarks": [
|
||||
@@ -105,7 +110,8 @@
|
||||
{
|
||||
"rel" : "self",
|
||||
"href" : "https://example.tld/rdap/entity/1",
|
||||
"type" : "application/rdap+json"
|
||||
"type" : "application/rdap+json",
|
||||
"value": "%REQUEST_URL%"
|
||||
}
|
||||
],
|
||||
"publicIds" : [
|
||||
@@ -164,7 +170,8 @@
|
||||
{
|
||||
"href":"https://github.com/google/nomulus/blob/master/docs/rdap.md#authentication",
|
||||
"rel":"alternate",
|
||||
"type":"text/html"
|
||||
"type":"text/html",
|
||||
"value": "%REQUEST_URL%"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -200,7 +207,8 @@
|
||||
{
|
||||
"href":"https://github.com/google/nomulus/blob/master/docs/rdap.md#authentication",
|
||||
"rel":"alternate",
|
||||
"type":"text/html"
|
||||
"type":"text/html",
|
||||
"value": "%REQUEST_URL%"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -237,7 +245,8 @@
|
||||
{
|
||||
"href":"https://github.com/google/nomulus/blob/master/docs/rdap.md#authentication",
|
||||
"rel":"alternate",
|
||||
"type":"text/html"
|
||||
"type":"text/html",
|
||||
"value": "%REQUEST_URL%"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -13,7 +13,8 @@
|
||||
{
|
||||
"href": "https://example.tld/rdap/entity/1",
|
||||
"rel": "self",
|
||||
"type": "application/rdap+json"
|
||||
"type": "application/rdap+json",
|
||||
"value": "https://example.tld/rdap/domain/transfer.lol"
|
||||
}
|
||||
],
|
||||
"publicIds": [
|
||||
@@ -65,7 +66,8 @@
|
||||
{
|
||||
"href": "https://github.com/google/nomulus/blob/master/docs/rdap.md#authentication",
|
||||
"rel": "alternate",
|
||||
"type": "text/html"
|
||||
"type": "text/html",
|
||||
"value": "https://example.tld/rdap/domain/transfer.lol"
|
||||
}
|
||||
],
|
||||
"title": "REDACTED FOR PRIVACY",
|
||||
@@ -124,7 +126,8 @@
|
||||
{
|
||||
"href": "https://example.tld/rdap/domain/transfer.lol",
|
||||
"rel": "self",
|
||||
"type": "application/rdap+json"
|
||||
"type": "application/rdap+json",
|
||||
"value": "https://example.tld/rdap/domain/transfer.lol"
|
||||
}
|
||||
],
|
||||
"nameservers": [
|
||||
@@ -136,7 +139,8 @@
|
||||
{
|
||||
"href": "https://example.tld/rdap/nameserver/ns1.cat.lol",
|
||||
"rel": "self",
|
||||
"type": "application/rdap+json"
|
||||
"type": "application/rdap+json",
|
||||
"value": "https://example.tld/rdap/domain/transfer.lol"
|
||||
}
|
||||
],
|
||||
"remarks": [
|
||||
|
||||
@@ -18,17 +18,20 @@
|
||||
{
|
||||
"href": "https://example.tld/rdap/domain/%DOMAIN_PUNYCODE_NAME_1%",
|
||||
"type": "application/rdap+json",
|
||||
"rel": "self"
|
||||
"rel": "self",
|
||||
"value": "%REQUEST_URL%"
|
||||
},
|
||||
{
|
||||
"href": "https://rdap.example.com/withSlash/domain/%DOMAIN_PUNYCODE_NAME_1%",
|
||||
"type": "application/rdap+json",
|
||||
"rel": "related"
|
||||
"rel": "related",
|
||||
"value": "%REQUEST_URL%"
|
||||
},
|
||||
{
|
||||
"href": "https://rdap.example.com/withoutSlash/domain/%DOMAIN_PUNYCODE_NAME_1%",
|
||||
"type": "application/rdap+json",
|
||||
"rel": "related"
|
||||
"rel": "related",
|
||||
"value": "%REQUEST_URL%"
|
||||
}
|
||||
],
|
||||
"events": [
|
||||
@@ -60,7 +63,8 @@
|
||||
"href":
|
||||
"https://example.tld/rdap/nameserver/%NAMESERVER_NAME_1%",
|
||||
"type": "application/rdap+json",
|
||||
"rel": "self"
|
||||
"rel": "self",
|
||||
"value": "%REQUEST_URL%"
|
||||
}
|
||||
],
|
||||
"remarks": [
|
||||
@@ -80,7 +84,8 @@
|
||||
"href":
|
||||
"https://example.tld/rdap/nameserver/%NAMESERVER_NAME_2%",
|
||||
"type": "application/rdap+json",
|
||||
"rel": "self"
|
||||
"rel": "self",
|
||||
"value": "%REQUEST_URL%"
|
||||
}
|
||||
],
|
||||
"remarks": [
|
||||
@@ -108,7 +113,8 @@
|
||||
{
|
||||
"href": "https://example.tld/rdap/entity/1",
|
||||
"type": "application/rdap+json",
|
||||
"rel": "self"
|
||||
"rel": "self",
|
||||
"value": "%REQUEST_URL%"
|
||||
}
|
||||
],
|
||||
"vcardArray" : [
|
||||
@@ -159,7 +165,8 @@
|
||||
{
|
||||
"href": "https://example.tld/rdap/entity/%CONTACT_HANDLE_1%",
|
||||
"type": "application/rdap+json",
|
||||
"rel": "self"
|
||||
"rel": "self",
|
||||
"value": "%REQUEST_URL%"
|
||||
}
|
||||
],
|
||||
"vcardArray": [
|
||||
@@ -196,7 +203,8 @@
|
||||
{
|
||||
"href": "https://example.tld/rdap/entity/%CONTACT_HANDLE_2%",
|
||||
"type": "application/rdap+json",
|
||||
"rel": "self"
|
||||
"rel": "self",
|
||||
"value": "%REQUEST_URL%"
|
||||
}
|
||||
],
|
||||
"vcardArray": [
|
||||
@@ -233,7 +241,8 @@
|
||||
{
|
||||
"href": "https://example.tld/rdap/entity/%CONTACT_HANDLE_3%",
|
||||
"type": "application/rdap+json",
|
||||
"rel": "self"
|
||||
"rel": "self",
|
||||
"value": "%REQUEST_URL%"
|
||||
}
|
||||
],
|
||||
"vcardArray": [
|
||||
|
||||
@@ -18,17 +18,20 @@
|
||||
{
|
||||
"href": "https://example.tld/rdap/domain/%DOMAIN_PUNYCODE_NAME_1%",
|
||||
"type": "application/rdap+json",
|
||||
"rel": "self"
|
||||
"rel": "self",
|
||||
"value": "https://example.tld/rdap/domains"
|
||||
},
|
||||
{
|
||||
"href": "https://rdap.example.com/withSlash/domain/%DOMAIN_PUNYCODE_NAME_1%",
|
||||
"type": "application/rdap+json",
|
||||
"rel": "related"
|
||||
"rel": "related",
|
||||
"value": "https://example.tld/rdap/domains"
|
||||
},
|
||||
{
|
||||
"href": "https://rdap.example.com/withoutSlash/domain/%DOMAIN_PUNYCODE_NAME_1%",
|
||||
"type": "application/rdap+json",
|
||||
"rel": "related"
|
||||
"rel": "related",
|
||||
"value": "https://example.tld/rdap/domains"
|
||||
}
|
||||
],
|
||||
"events": [
|
||||
@@ -60,7 +63,8 @@
|
||||
{
|
||||
"href": "https://example.tld/rdap/nameserver/%NAMESERVER_NAME_1%",
|
||||
"type": "application/rdap+json",
|
||||
"rel": "self"
|
||||
"rel": "self",
|
||||
"value": "https://example.tld/rdap/domains"
|
||||
}
|
||||
],
|
||||
"remarks": [
|
||||
@@ -80,7 +84,8 @@
|
||||
{
|
||||
"href": "https://example.tld/rdap/nameserver/%NAMESERVER_NAME_2%",
|
||||
"type": "application/rdap+json",
|
||||
"rel": "self"
|
||||
"rel": "self",
|
||||
"value": "https://example.tld/rdap/domains"
|
||||
}
|
||||
],
|
||||
"remarks": [
|
||||
@@ -108,7 +113,8 @@
|
||||
{
|
||||
"rel" : "self",
|
||||
"href" : "https://example.tld/rdap/entity/1",
|
||||
"type" : "application/rdap+json"
|
||||
"type" : "application/rdap+json",
|
||||
"value": "https://example.tld/rdap/domains"
|
||||
}
|
||||
],
|
||||
"publicIds" : [
|
||||
@@ -167,7 +173,8 @@
|
||||
{
|
||||
"href":"https://github.com/google/nomulus/blob/master/docs/rdap.md#authentication",
|
||||
"rel":"alternate",
|
||||
"type":"text/html"
|
||||
"type":"text/html",
|
||||
"value": "https://example.tld/rdap/domains"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -203,7 +210,8 @@
|
||||
{
|
||||
"href":"https://github.com/google/nomulus/blob/master/docs/rdap.md#authentication",
|
||||
"rel":"alternate",
|
||||
"type":"text/html"
|
||||
"type":"text/html",
|
||||
"value": "https://example.tld/rdap/domains"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -239,7 +247,8 @@
|
||||
{
|
||||
"href":"https://github.com/google/nomulus/blob/master/docs/rdap.md#authentication",
|
||||
"rel":"alternate",
|
||||
"type":"text/html"
|
||||
"type":"text/html",
|
||||
"value": "https://example.tld/rdap/domains"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -8,7 +8,8 @@
|
||||
{
|
||||
"href": "https://example.tld/rdap/domain/%DOMAIN_PUNYCODE_NAME_1%",
|
||||
"type": "application/rdap+json",
|
||||
"rel": "self"
|
||||
"rel": "self",
|
||||
"value": "https://example.tld/rdap/domains"
|
||||
}
|
||||
],
|
||||
"remarks": [
|
||||
@@ -27,7 +28,8 @@
|
||||
{
|
||||
"href": "https://example.tld/rdap/domain/%DOMAIN_PUNYCODE_NAME_2%",
|
||||
"type": "application/rdap+json",
|
||||
"rel": "self"
|
||||
"rel": "self",
|
||||
"value": "https://example.tld/rdap/domains"
|
||||
}
|
||||
],
|
||||
"remarks": [
|
||||
@@ -46,7 +48,8 @@
|
||||
{
|
||||
"href": "https://example.tld/rdap/domain/%DOMAIN_PUNYCODE_NAME_3%",
|
||||
"type": "application/rdap+json",
|
||||
"rel": "self"
|
||||
"rel": "self",
|
||||
"value": "https://example.tld/rdap/domains"
|
||||
}
|
||||
],
|
||||
"remarks": [
|
||||
@@ -65,7 +68,8 @@
|
||||
{
|
||||
"href": "https://example.tld/rdap/domain/%DOMAIN_PUNYCODE_NAME_4%",
|
||||
"type": "application/rdap+json",
|
||||
"rel": "self"
|
||||
"rel": "self",
|
||||
"value": "https://example.tld/rdap/domains"
|
||||
}
|
||||
],
|
||||
"remarks": [
|
||||
@@ -100,7 +104,8 @@
|
||||
{
|
||||
"type" : "application/rdap+json",
|
||||
"rel" : "next",
|
||||
"href" : "https://example.tld/rdap/domains?%NEXT_QUERY%"
|
||||
"href" : "https://example.tld/rdap/domains?%NEXT_QUERY%",
|
||||
"value": "https://example.tld/rdap/domains"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -124,12 +129,14 @@
|
||||
{
|
||||
"href": "https://example.tld/rdap/help/tos",
|
||||
"rel": "self",
|
||||
"type": "application/rdap+json"
|
||||
"type": "application/rdap+json",
|
||||
"value": "https://example.tld/rdap/domains"
|
||||
},
|
||||
{
|
||||
"href": "https://www.registry.tld/about/rdap/tos.html",
|
||||
"rel": "alternate",
|
||||
"type": "text/html"
|
||||
"href": "https://www.example.tld/about/rdap/tos.html",
|
||||
"rel": "terms-of-service",
|
||||
"type": "text/html",
|
||||
"value": "https://example.tld/rdap/domains"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -148,9 +155,10 @@
|
||||
"links" :
|
||||
[
|
||||
{
|
||||
"rel" : "alternate",
|
||||
"rel" : "glossary",
|
||||
"href" : "https://icann.org/epp",
|
||||
"type" : "text/html"
|
||||
"type" : "text/html",
|
||||
"value": "https://example.tld/rdap/domains"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -160,9 +168,10 @@
|
||||
"links" :
|
||||
[
|
||||
{
|
||||
"rel" : "alternate",
|
||||
"rel" : "help",
|
||||
"href" : "https://icann.org/wicf",
|
||||
"type" : "text/html"
|
||||
"type" : "text/html",
|
||||
"value": "https://example.tld/rdap/domains"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -8,7 +8,8 @@
|
||||
{
|
||||
"href": "https://example.tld/rdap/domain/%DOMAIN_PUNYCODE_NAME_1%",
|
||||
"type": "application/rdap+json",
|
||||
"rel": "self"
|
||||
"rel": "self",
|
||||
"value": "https://example.tld/rdap/domains"
|
||||
}
|
||||
],
|
||||
"remarks": [
|
||||
@@ -27,7 +28,8 @@
|
||||
{
|
||||
"href": "https://example.tld/rdap/domain/%DOMAIN_PUNYCODE_NAME_2%",
|
||||
"type": "application/rdap+json",
|
||||
"rel": "self"
|
||||
"rel": "self",
|
||||
"value": "https://example.tld/rdap/domains"
|
||||
}
|
||||
],
|
||||
"remarks": [
|
||||
@@ -46,7 +48,8 @@
|
||||
{
|
||||
"href": "https://example.tld/rdap/domain/%DOMAIN_PUNYCODE_NAME_3%",
|
||||
"type": "application/rdap+json",
|
||||
"rel": "self"
|
||||
"rel": "self",
|
||||
"value": "https://example.tld/rdap/domains"
|
||||
}
|
||||
],
|
||||
"remarks": [
|
||||
@@ -66,7 +69,8 @@
|
||||
{
|
||||
"href": "https://example.tld/rdap/domain/%DOMAIN_PUNYCODE_NAME_4%",
|
||||
"type": "application/rdap+json",
|
||||
"rel": "self"
|
||||
"rel": "self",
|
||||
"value": "https://example.tld/rdap/domains"
|
||||
}
|
||||
],
|
||||
"remarks": [
|
||||
@@ -105,12 +109,14 @@
|
||||
{
|
||||
"href": "https://example.tld/rdap/help/tos",
|
||||
"rel": "self",
|
||||
"type": "application/rdap+json"
|
||||
"type": "application/rdap+json",
|
||||
"value": "https://example.tld/rdap/domains"
|
||||
},
|
||||
{
|
||||
"href": "https://www.registry.tld/about/rdap/tos.html",
|
||||
"rel": "alternate",
|
||||
"type": "text/html"
|
||||
"href": "https://www.example.tld/about/rdap/tos.html",
|
||||
"rel": "terms-of-service",
|
||||
"type": "text/html",
|
||||
"value": "https://example.tld/rdap/domains"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -129,9 +135,10 @@
|
||||
"links" :
|
||||
[
|
||||
{
|
||||
"rel" : "alternate",
|
||||
"rel" : "glossary",
|
||||
"href" : "https://icann.org/epp",
|
||||
"type" : "text/html"
|
||||
"type" : "text/html",
|
||||
"value": "https://example.tld/rdap/domains"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -141,9 +148,10 @@
|
||||
"links" :
|
||||
[
|
||||
{
|
||||
"rel" : "alternate",
|
||||
"rel" : "help",
|
||||
"href" : "https://icann.org/wicf",
|
||||
"type" : "text/html"
|
||||
"type" : "text/html",
|
||||
"value": "https://example.tld/rdap/domains"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -8,7 +8,8 @@
|
||||
{
|
||||
"href": "https://example.tld/rdap/domain/%DOMAIN_PUNYCODE_NAME_1%",
|
||||
"type": "application/rdap+json",
|
||||
"rel": "self"
|
||||
"rel": "self",
|
||||
"value": "https://example.tld/rdap/domains"
|
||||
}
|
||||
],
|
||||
"remarks": [
|
||||
@@ -27,7 +28,8 @@
|
||||
{
|
||||
"href": "https://example.tld/rdap/domain/%DOMAIN_PUNYCODE_NAME_2%",
|
||||
"type": "application/rdap+json",
|
||||
"rel": "self"
|
||||
"rel": "self",
|
||||
"value": "https://example.tld/rdap/domains"
|
||||
}
|
||||
],
|
||||
"remarks": [
|
||||
@@ -46,7 +48,8 @@
|
||||
{
|
||||
"href": "https://example.tld/rdap/domain/%DOMAIN_PUNYCODE_NAME_3%",
|
||||
"type": "application/rdap+json",
|
||||
"rel": "self"
|
||||
"rel": "self",
|
||||
"value": "https://example.tld/rdap/domains"
|
||||
}
|
||||
],
|
||||
"remarks": [
|
||||
@@ -66,7 +69,8 @@
|
||||
{
|
||||
"href": "https://example.tld/rdap/domain/%DOMAIN_PUNYCODE_NAME_4%",
|
||||
"type": "application/rdap+json",
|
||||
"rel": "self"
|
||||
"rel": "self",
|
||||
"value": "https://example.tld/rdap/domains"
|
||||
}
|
||||
],
|
||||
"remarks": [
|
||||
@@ -101,7 +105,8 @@
|
||||
{
|
||||
"type" : "application/rdap+json",
|
||||
"rel" : "next",
|
||||
"href" : "https://example.tld/rdap/domains?%NEXT_QUERY%"
|
||||
"href" : "https://example.tld/rdap/domains?%NEXT_QUERY%",
|
||||
"value": "https://example.tld/rdap/domains"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -125,12 +130,14 @@
|
||||
{
|
||||
"href": "https://example.tld/rdap/help/tos",
|
||||
"rel": "self",
|
||||
"type": "application/rdap+json"
|
||||
"type": "application/rdap+json",
|
||||
"value": "https://example.tld/rdap/domains"
|
||||
},
|
||||
{
|
||||
"href": "https://www.registry.tld/about/rdap/tos.html",
|
||||
"rel": "alternate",
|
||||
"type": "text/html"
|
||||
"href": "https://www.example.tld/about/rdap/tos.html",
|
||||
"rel": "terms-of-service",
|
||||
"type": "text/html",
|
||||
"value": "https://example.tld/rdap/domains"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -149,9 +156,10 @@
|
||||
"links" :
|
||||
[
|
||||
{
|
||||
"rel" : "alternate",
|
||||
"rel" : "glossary",
|
||||
"href" : "https://icann.org/epp",
|
||||
"type" : "text/html"
|
||||
"type" : "text/html",
|
||||
"value": "https://example.tld/rdap/domains"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -161,9 +169,10 @@
|
||||
"links" :
|
||||
[
|
||||
{
|
||||
"rel" : "alternate",
|
||||
"rel" : "help",
|
||||
"href" : "https://icann.org/wicf",
|
||||
"type" : "text/html"
|
||||
"type" : "text/html",
|
||||
"value": "https://example.tld/rdap/domains"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -13,7 +13,8 @@
|
||||
{
|
||||
"href": "https://example.tld/rdap/domain/%DOMAIN_PUNYCODE_NAME_1%",
|
||||
"type": "application/rdap+json",
|
||||
"rel": "self"
|
||||
"rel": "self",
|
||||
"value": "https://example.tld/rdap/domains"
|
||||
}
|
||||
],
|
||||
"remarks": [
|
||||
@@ -34,7 +35,8 @@
|
||||
{
|
||||
"href": "https://example.tld/rdap/domain/%DOMAIN_PUNYCODE_NAME_2%",
|
||||
"type": "application/rdap+json",
|
||||
"rel": "self"
|
||||
"rel": "self",
|
||||
"value": "https://example.tld/rdap/domains"
|
||||
}
|
||||
],
|
||||
"remarks": [
|
||||
@@ -69,12 +71,14 @@
|
||||
{
|
||||
"href": "https://example.tld/rdap/help/tos",
|
||||
"rel": "self",
|
||||
"type": "application/rdap+json"
|
||||
"type": "application/rdap+json",
|
||||
"value": "https://example.tld/rdap/domains"
|
||||
},
|
||||
{
|
||||
"href": "https://www.registry.tld/about/rdap/tos.html",
|
||||
"rel": "alternate",
|
||||
"type": "text/html"
|
||||
"href": "https://www.example.tld/about/rdap/tos.html",
|
||||
"rel": "terms-of-service",
|
||||
"type": "text/html",
|
||||
"value": "https://example.tld/rdap/domains"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -87,9 +91,10 @@
|
||||
"links":
|
||||
[
|
||||
{
|
||||
"rel": "alternate",
|
||||
"rel": "glossary",
|
||||
"href": "https://icann.org/epp",
|
||||
"type": "text/html"
|
||||
"type": "text/html",
|
||||
"value": "https://example.tld/rdap/domains"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -99,9 +104,10 @@
|
||||
"links":
|
||||
[
|
||||
{
|
||||
"rel": "alternate",
|
||||
"rel": "help",
|
||||
"href": "https://icann.org/wicf",
|
||||
"type": "text/html"
|
||||
"type": "text/html",
|
||||
"value": "https://example.tld/rdap/domains"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -28,12 +28,14 @@
|
||||
{
|
||||
"href": "https://example.tld/rdap/help/tos",
|
||||
"rel": "self",
|
||||
"type": "application/rdap+json"
|
||||
"type": "application/rdap+json",
|
||||
"value": "%REQUEST_URL%"
|
||||
},
|
||||
{
|
||||
"href": "https://www.registry.tld/about/rdap/tos.html",
|
||||
"rel": "alternate",
|
||||
"type": "text/html"
|
||||
"href": "https://www.example.tld/about/rdap/tos.html",
|
||||
"rel": "terms-of-service",
|
||||
"type": "text/html",
|
||||
"value": "%REQUEST_URL%"
|
||||
}
|
||||
],
|
||||
"title": "RDAP Terms of Service"
|
||||
|
||||
@@ -27,12 +27,14 @@
|
||||
{
|
||||
"rel" : "alternate",
|
||||
"type" : "text/html",
|
||||
"href" : "https://github.com/google/nomulus/blob/master/docs/rdap.md"
|
||||
"href" : "https://github.com/google/nomulus/blob/master/docs/rdap.md",
|
||||
"value": "https://example.tld/rdap/help%POSSIBLE_SLASH%"
|
||||
},
|
||||
{
|
||||
"rel": "self",
|
||||
"type": "application/rdap+json",
|
||||
"href": "https://example.tld/rdap/help"
|
||||
"href": "https://example.tld/rdap/help",
|
||||
"value": "https://example.tld/rdap/help%POSSIBLE_SLASH%"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -56,12 +58,14 @@
|
||||
{
|
||||
"href": "https://example.tld/rdap/help/tos",
|
||||
"rel": "self",
|
||||
"type": "application/rdap+json"
|
||||
"type": "application/rdap+json",
|
||||
"value": "https://example.tld/rdap/help%POSSIBLE_SLASH%"
|
||||
},
|
||||
{
|
||||
"href": "https://www.registry.tld/about/rdap/tos.html",
|
||||
"rel": "alternate",
|
||||
"type": "text/html"
|
||||
"href": "https://www.example.tld/about/rdap/tos.html",
|
||||
"rel": "terms-of-service",
|
||||
"type": "text/html",
|
||||
"value": "https://example.tld/rdap/help%POSSIBLE_SLASH%"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -26,12 +26,14 @@
|
||||
{
|
||||
"href": "https://example.tld/rdap/help/tos",
|
||||
"rel": "self",
|
||||
"type": "application/rdap+json"
|
||||
"type": "application/rdap+json",
|
||||
"value": "https://example.tld/rdap/help/tos"
|
||||
},
|
||||
{
|
||||
"href": "https://www.registry.tld/about/rdap/tos.html",
|
||||
"rel": "alternate",
|
||||
"type": "text/html"
|
||||
"href": "https://www.example.tld/about/rdap/tos.html",
|
||||
"rel": "terms-of-service",
|
||||
"type": "text/html",
|
||||
"value": "https://example.tld/rdap/help/tos"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -5,14 +5,15 @@
|
||||
"icann_rdap_technical_implementation_guide_0"
|
||||
],
|
||||
"objectClassName": "nameserver",
|
||||
"handle": "%HANDLE%",
|
||||
"ldhName": "%NAME%",
|
||||
"handle": "%NAMESERVER_HANDLE_1%",
|
||||
"ldhName": "%NAMESERVER_NAME_1%",
|
||||
"status": ["%STATUS%"],
|
||||
"links": [
|
||||
{
|
||||
"href": "https://example.tld/rdap/nameserver/%NAME%",
|
||||
"href": "https://example.tld/rdap/nameserver/%NAMESERVER_NAME_1%",
|
||||
"type": "application/rdap+json",
|
||||
"rel": "self"
|
||||
"rel": "self",
|
||||
"value": "%REQUEST_URL%"
|
||||
}
|
||||
],
|
||||
"ipAddresses": {
|
||||
@@ -36,7 +37,8 @@
|
||||
{
|
||||
"rel" : "self",
|
||||
"href" : "https://example.tld/rdap/entity/1",
|
||||
"type" : "application/rdap+json"
|
||||
"type" : "application/rdap+json",
|
||||
"value": "%REQUEST_URL%"
|
||||
}
|
||||
],
|
||||
"publicIds" :
|
||||
|
||||
@@ -7,15 +7,16 @@
|
||||
"status": [
|
||||
"active"
|
||||
],
|
||||
"handle": "%HANDLE%",
|
||||
"handle": "%NAMESERVER_HANDLE_1%",
|
||||
"links": [
|
||||
{
|
||||
"href": "https://example.tld/rdap/nameserver/%NAME%",
|
||||
"href": "https://example.tld/rdap/nameserver/%NAMESERVER_NAME_1%",
|
||||
"type": "application/rdap+json",
|
||||
"rel": "self"
|
||||
"rel": "self",
|
||||
"value": "%REQUEST_URL%"
|
||||
}
|
||||
],
|
||||
"ldhName": "%NAME%",
|
||||
"ldhName": "%NAMESERVER_NAME_1%",
|
||||
"events": [
|
||||
{
|
||||
"eventAction": "last update of RDAP database",
|
||||
@@ -33,7 +34,8 @@
|
||||
{
|
||||
"rel" : "self",
|
||||
"href" : "https://example.tld/rdap/entity/1",
|
||||
"type" : "application/rdap+json"
|
||||
"type" : "application/rdap+json",
|
||||
"value": "%REQUEST_URL%"
|
||||
}
|
||||
],
|
||||
"publicIds" :
|
||||
|
||||
@@ -5,17 +5,18 @@
|
||||
"icann_rdap_technical_implementation_guide_0"
|
||||
],
|
||||
"objectClassName": "nameserver",
|
||||
"handle": "%HANDLE%",
|
||||
"ldhName": "%NAME%",
|
||||
"handle": "%NAMESERVER_HANDLE_1%",
|
||||
"ldhName": "%NAMESERVER_NAME_1%",
|
||||
"status": [
|
||||
"active",
|
||||
"associated"
|
||||
],
|
||||
"links": [
|
||||
{
|
||||
"href": "https://example.tld/rdap/nameserver/%NAME%",
|
||||
"href": "https://example.tld/rdap/nameserver/%NAMESERVER_NAME_1%",
|
||||
"type": "application/rdap+json",
|
||||
"rel": "self"
|
||||
"rel": "self",
|
||||
"value": "%REQUEST_URL%"
|
||||
}
|
||||
],
|
||||
"ipAddresses": {
|
||||
@@ -39,7 +40,8 @@
|
||||
{
|
||||
"rel" : "self",
|
||||
"href" : "https://example.tld/rdap/entity/1",
|
||||
"type" : "application/rdap+json"
|
||||
"type" : "application/rdap+json",
|
||||
"value": "%REQUEST_URL%"
|
||||
}
|
||||
],
|
||||
"publicIds" :
|
||||
|
||||
@@ -5,15 +5,16 @@
|
||||
"icann_rdap_technical_implementation_guide_0"
|
||||
],
|
||||
"objectClassName": "nameserver",
|
||||
"handle": "%HANDLE%",
|
||||
"ldhName": "%PUNYCODENAME%",
|
||||
"unicodeName": "%NAME%",
|
||||
"handle": "%NAMESERVER_HANDLE_1%",
|
||||
"ldhName": "%NAMESERVER_NAME_1%",
|
||||
"unicodeName": "%NAMESERVER_UNICODE_NAME_1%",
|
||||
"status": ["active"],
|
||||
"links": [
|
||||
{
|
||||
"href": "https://example.tld/rdap/nameserver/%PUNYCODENAME%",
|
||||
"href": "https://example.tld/rdap/nameserver/%NAMESERVER_NAME_1%",
|
||||
"type": "application/rdap+json",
|
||||
"rel": "self"
|
||||
"rel": "self",
|
||||
"value": "%REQUEST_URL%"
|
||||
}
|
||||
],
|
||||
"ipAddresses": {
|
||||
@@ -37,7 +38,8 @@
|
||||
{
|
||||
"rel" : "self",
|
||||
"href" : "https://example.tld/rdap/entity/1",
|
||||
"type" : "application/rdap+json"
|
||||
"type" : "application/rdap+json",
|
||||
"value": "%REQUEST_URL%"
|
||||
}
|
||||
],
|
||||
"publicIds" :
|
||||
|
||||
@@ -9,7 +9,8 @@
|
||||
{
|
||||
"rel":"self",
|
||||
"href":"https://example.tld/rdap/domain/%DOMAIN_PUNYCODE_NAME_1%",
|
||||
"type":"application/rdap+json"
|
||||
"type":"application/rdap+json",
|
||||
"value": "https://example.tld/rdap/domains"
|
||||
}
|
||||
],
|
||||
"remarks": [
|
||||
@@ -31,7 +32,8 @@
|
||||
{
|
||||
"rel":"self",
|
||||
"href":"https://example.tld/rdap/domain/%DOMAIN_PUNYCODE_NAME_2%",
|
||||
"type":"application/rdap+json"
|
||||
"type":"application/rdap+json",
|
||||
"value": "https://example.tld/rdap/domains"
|
||||
}
|
||||
],
|
||||
"remarks": [
|
||||
@@ -53,7 +55,8 @@
|
||||
{
|
||||
"rel":"self",
|
||||
"href":"https://example.tld/rdap/domain/%DOMAIN_PUNYCODE_NAME_3%",
|
||||
"type":"application/rdap+json"
|
||||
"type":"application/rdap+json",
|
||||
"value": "https://example.tld/rdap/domains"
|
||||
}
|
||||
],
|
||||
"remarks": [
|
||||
@@ -97,12 +100,14 @@
|
||||
{
|
||||
"href": "https://example.tld/rdap/help/tos",
|
||||
"rel": "self",
|
||||
"type": "application/rdap+json"
|
||||
"type": "application/rdap+json",
|
||||
"value": "https://example.tld/rdap/domains"
|
||||
},
|
||||
{
|
||||
"href": "https://www.registry.tld/about/rdap/tos.html",
|
||||
"rel": "alternate",
|
||||
"type": "text/html"
|
||||
"href": "https://www.example.tld/about/rdap/tos.html",
|
||||
"rel": "terms-of-service",
|
||||
"type": "text/html",
|
||||
"value": "https://example.tld/rdap/domains"
|
||||
}
|
||||
],
|
||||
"title":"RDAP Terms of Service"
|
||||
@@ -121,9 +126,10 @@
|
||||
"links":
|
||||
[
|
||||
{
|
||||
"rel":"alternate",
|
||||
"rel":"glossary",
|
||||
"href":"https://icann.org/epp",
|
||||
"type":"text/html"
|
||||
"type":"text/html",
|
||||
"value": "https://example.tld/rdap/domains"
|
||||
}
|
||||
],
|
||||
"title":"Status Codes"
|
||||
@@ -134,9 +140,10 @@
|
||||
"links":
|
||||
[
|
||||
{
|
||||
"rel":"alternate",
|
||||
"rel":"help",
|
||||
"href":"https://icann.org/wicf",
|
||||
"type":"text/html"
|
||||
"type":"text/html",
|
||||
"value": "https://example.tld/rdap/domains"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -17,7 +17,8 @@
|
||||
{
|
||||
"type":"application/rdap+json",
|
||||
"rel":"self",
|
||||
"href":"https://example.tld/rdap/domain/%DOMAIN_PUNYCODE_NAME_1%"
|
||||
"href":"https://example.tld/rdap/domain/%DOMAIN_PUNYCODE_NAME_1%",
|
||||
"value": "https://example.tld/rdap/domains"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -38,7 +39,8 @@
|
||||
{
|
||||
"type":"application/rdap+json",
|
||||
"rel":"self",
|
||||
"href":"https://example.tld/rdap/domain/%DOMAIN_PUNYCODE_NAME_2%"
|
||||
"href":"https://example.tld/rdap/domain/%DOMAIN_PUNYCODE_NAME_2%",
|
||||
"value": "https://example.tld/rdap/domains"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -69,12 +71,14 @@
|
||||
{
|
||||
"href": "https://example.tld/rdap/help/tos",
|
||||
"rel": "self",
|
||||
"type": "application/rdap+json"
|
||||
"type": "application/rdap+json",
|
||||
"value": "https://example.tld/rdap/domains"
|
||||
},
|
||||
{
|
||||
"href": "https://www.registry.tld/about/rdap/tos.html",
|
||||
"rel": "alternate",
|
||||
"type": "text/html"
|
||||
"href": "https://www.example.tld/about/rdap/tos.html",
|
||||
"rel": "terms-of-service",
|
||||
"type": "text/html",
|
||||
"value": "https://example.tld/rdap/domains"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -91,8 +95,9 @@
|
||||
"links":[
|
||||
{
|
||||
"type":"text/html",
|
||||
"rel":"alternate",
|
||||
"href":"https://icann.org/epp"
|
||||
"rel":"glossary",
|
||||
"href":"https://icann.org/epp",
|
||||
"value": "https://example.tld/rdap/domains"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -102,8 +107,9 @@
|
||||
"links":[
|
||||
{
|
||||
"type":"text/html",
|
||||
"rel":"alternate",
|
||||
"href":"https://icann.org/wicf"
|
||||
"rel":"help",
|
||||
"href":"https://icann.org/wicf",
|
||||
"value": "https://example.tld/rdap/domains"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -129,7 +129,7 @@
|
||||
"type": "application/rdap+json"
|
||||
},
|
||||
{
|
||||
"href": "https://www.registry.tld/about/rdap/tos.html",
|
||||
"href": "https://www.example.tld/about/rdap/tos.html",
|
||||
"rel": "alternate",
|
||||
"type": "text/html"
|
||||
}
|
||||
|
||||
@@ -9,7 +9,8 @@
|
||||
{
|
||||
"rel" : "self",
|
||||
"href": "https://example.tld/rdap/entity/4-ROID",
|
||||
"type" : "application/rdap+json"
|
||||
"type" : "application/rdap+json",
|
||||
"value": "https://example.tld/rdap/entities"
|
||||
}
|
||||
],
|
||||
"events": [
|
||||
@@ -65,7 +66,8 @@
|
||||
{
|
||||
"rel" : "self",
|
||||
"href": "https://example.tld/rdap/entity/2-ROID",
|
||||
"type" : "application/rdap+json"
|
||||
"type" : "application/rdap+json",
|
||||
"value": "https://example.tld/rdap/entities"
|
||||
}
|
||||
],
|
||||
"events": [
|
||||
@@ -141,12 +143,14 @@
|
||||
{
|
||||
"href": "https://example.tld/rdap/help/tos",
|
||||
"rel": "self",
|
||||
"type": "application/rdap+json"
|
||||
"type": "application/rdap+json",
|
||||
"value": "https://example.tld/rdap/entities"
|
||||
},
|
||||
{
|
||||
"href": "https://www.registry.tld/about/rdap/tos.html",
|
||||
"rel": "alternate",
|
||||
"type": "text/html"
|
||||
"href": "https://www.example.tld/about/rdap/tos.html",
|
||||
"rel": "terms-of-service",
|
||||
"type": "text/html",
|
||||
"value": "https://example.tld/rdap/entities"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -10,7 +10,8 @@
|
||||
{
|
||||
"rel" : "self",
|
||||
"type" : "application/rdap+json",
|
||||
"href" : "https://example.tld/rdap/nameserver/ns2.cat.lol"
|
||||
"href" : "https://example.tld/rdap/nameserver/ns2.cat.lol",
|
||||
"value": "https://example.tld/rdap/nameservers"
|
||||
}
|
||||
],
|
||||
"ipAddresses" :
|
||||
@@ -42,7 +43,8 @@
|
||||
{
|
||||
"rel" : "self",
|
||||
"type" : "application/rdap+json",
|
||||
"href" : "https://example.tld/rdap/nameserver/ns1.cat2.lol"
|
||||
"href" : "https://example.tld/rdap/nameserver/ns1.cat2.lol",
|
||||
"value": "https://example.tld/rdap/nameservers"
|
||||
}
|
||||
],
|
||||
"ipAddresses" :
|
||||
@@ -94,12 +96,14 @@
|
||||
{
|
||||
"href": "https://example.tld/rdap/help/tos",
|
||||
"rel": "self",
|
||||
"type": "application/rdap+json"
|
||||
"type": "application/rdap+json",
|
||||
"value": "https://example.tld/rdap/nameservers"
|
||||
},
|
||||
{
|
||||
"href": "https://www.registry.tld/about/rdap/tos.html",
|
||||
"rel": "alternate",
|
||||
"type": "text/html"
|
||||
"href": "https://www.example.tld/about/rdap/tos.html",
|
||||
"rel": "terms-of-service",
|
||||
"type": "text/html",
|
||||
"value": "https://example.tld/rdap/nameservers"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -9,7 +9,8 @@
|
||||
{
|
||||
"rel" : "self",
|
||||
"href": "https://example.tld/rdap/entity/0001-ROID",
|
||||
"type" : "application/rdap+json"
|
||||
"type" : "application/rdap+json",
|
||||
"value": "https://example.tld/rdap/entities"
|
||||
}
|
||||
],
|
||||
"events": [
|
||||
@@ -65,7 +66,8 @@
|
||||
{
|
||||
"rel" : "self",
|
||||
"href": "https://example.tld/rdap/entity/0002-ROID",
|
||||
"type" : "application/rdap+json"
|
||||
"type" : "application/rdap+json",
|
||||
"value": "https://example.tld/rdap/entities"
|
||||
}
|
||||
],
|
||||
"events": [
|
||||
@@ -121,7 +123,8 @@
|
||||
{
|
||||
"rel" : "self",
|
||||
"href": "https://example.tld/rdap/entity/0003-ROID",
|
||||
"type" : "application/rdap+json"
|
||||
"type" : "application/rdap+json",
|
||||
"value": "https://example.tld/rdap/entities"
|
||||
}
|
||||
],
|
||||
"events": [
|
||||
@@ -177,7 +180,8 @@
|
||||
{
|
||||
"rel" : "self",
|
||||
"href": "https://example.tld/rdap/entity/0004-ROID",
|
||||
"type" : "application/rdap+json"
|
||||
"type" : "application/rdap+json",
|
||||
"value": "https://example.tld/rdap/entities"
|
||||
}
|
||||
],
|
||||
"events": [
|
||||
@@ -253,12 +257,14 @@
|
||||
{
|
||||
"href": "https://example.tld/rdap/help/tos",
|
||||
"rel": "self",
|
||||
"type": "application/rdap+json"
|
||||
"type": "application/rdap+json",
|
||||
"value": "https://example.tld/rdap/entities"
|
||||
},
|
||||
{
|
||||
"href": "https://www.registry.tld/about/rdap/tos.html",
|
||||
"rel": "alternate",
|
||||
"type": "text/html"
|
||||
"href": "https://www.example.tld/about/rdap/tos.html",
|
||||
"rel": "terms-of-service",
|
||||
"type": "text/html",
|
||||
"value": "https://example.tld/rdap/entities"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -8,7 +8,8 @@
|
||||
{
|
||||
"href": "https://example.tld/rdap/domain/%DOMAIN_PUNYCODE_NAME_1%",
|
||||
"type": "application/rdap+json",
|
||||
"rel": "self"
|
||||
"rel": "self",
|
||||
"value": "https://example.tld/rdap/domains"
|
||||
}
|
||||
],
|
||||
"remarks": [
|
||||
@@ -29,7 +30,8 @@
|
||||
{
|
||||
"href": "https://example.tld/rdap/domain/%DOMAIN_PUNYCODE_NAME_2%",
|
||||
"type": "application/rdap+json",
|
||||
"rel": "self"
|
||||
"rel": "self",
|
||||
"value": "https://example.tld/rdap/domains"
|
||||
}
|
||||
],
|
||||
"remarks": [
|
||||
@@ -50,7 +52,8 @@
|
||||
{
|
||||
"href": "https://example.tld/rdap/domain/%DOMAIN_PUNYCODE_NAME_3%",
|
||||
"type": "application/rdap+json",
|
||||
"rel": "self"
|
||||
"rel": "self",
|
||||
"value": "https://example.tld/rdap/domains"
|
||||
}
|
||||
],
|
||||
"remarks": [
|
||||
@@ -71,7 +74,8 @@
|
||||
{
|
||||
"href": "https://example.tld/rdap/domain/%DOMAIN_PUNYCODE_NAME_4%",
|
||||
"type": "application/rdap+json",
|
||||
"rel": "self"
|
||||
"rel": "self",
|
||||
"value": "https://example.tld/rdap/domains"
|
||||
}
|
||||
],
|
||||
"remarks": [
|
||||
@@ -112,12 +116,14 @@
|
||||
{
|
||||
"href": "https://example.tld/rdap/help/tos",
|
||||
"rel": "self",
|
||||
"type": "application/rdap+json"
|
||||
"type": "application/rdap+json",
|
||||
"value": "https://example.tld/rdap/domains"
|
||||
},
|
||||
{
|
||||
"href": "https://www.registry.tld/about/rdap/tos.html",
|
||||
"rel": "alternate",
|
||||
"type": "text/html"
|
||||
"href": "https://www.example.tld/about/rdap/tos.html",
|
||||
"rel": "terms-of-service",
|
||||
"type": "text/html",
|
||||
"value": "https://example.tld/rdap/domains"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -136,9 +142,10 @@
|
||||
"links" :
|
||||
[
|
||||
{
|
||||
"rel" : "alternate",
|
||||
"rel" : "glossary",
|
||||
"href" : "https://icann.org/epp",
|
||||
"type" : "text/html"
|
||||
"type" : "text/html",
|
||||
"value": "https://example.tld/rdap/domains"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -148,9 +155,10 @@
|
||||
"links" :
|
||||
[
|
||||
{
|
||||
"rel" : "alternate",
|
||||
"rel" : "help",
|
||||
"href" : "https://icann.org/wicf",
|
||||
"type" : "text/html"
|
||||
"type" : "text/html",
|
||||
"value": "https://example.tld/rdap/domains"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -10,7 +10,8 @@
|
||||
{
|
||||
"rel" : "self",
|
||||
"type" : "application/rdap+json",
|
||||
"href" : "https://example.tld/rdap/nameserver/nsx1.cat.lol"
|
||||
"href" : "https://example.tld/rdap/nameserver/nsx1.cat.lol",
|
||||
"value": "https://example.tld/rdap/nameservers"
|
||||
}
|
||||
],
|
||||
"ipAddresses" :
|
||||
@@ -42,7 +43,8 @@
|
||||
{
|
||||
"rel" : "self",
|
||||
"type" : "application/rdap+json",
|
||||
"href" : "https://example.tld/rdap/nameserver/nsx2.cat.lol"
|
||||
"href" : "https://example.tld/rdap/nameserver/nsx2.cat.lol",
|
||||
"value": "https://example.tld/rdap/nameservers"
|
||||
}
|
||||
],
|
||||
"ipAddresses" :
|
||||
@@ -74,7 +76,8 @@
|
||||
{
|
||||
"rel" : "self",
|
||||
"type" : "application/rdap+json",
|
||||
"href" : "https://example.tld/rdap/nameserver/nsx3.cat.lol"
|
||||
"href" : "https://example.tld/rdap/nameserver/nsx3.cat.lol",
|
||||
"value": "https://example.tld/rdap/nameservers"
|
||||
}
|
||||
],
|
||||
"ipAddresses" :
|
||||
@@ -106,7 +109,8 @@
|
||||
{
|
||||
"rel" : "self",
|
||||
"type" : "application/rdap+json",
|
||||
"href" : "https://example.tld/rdap/nameserver/nsx4.cat.lol"
|
||||
"href" : "https://example.tld/rdap/nameserver/nsx4.cat.lol",
|
||||
"value": "https://example.tld/rdap/nameservers"
|
||||
}
|
||||
],
|
||||
"ipAddresses" :
|
||||
@@ -157,12 +161,14 @@
|
||||
{
|
||||
"href": "https://example.tld/rdap/help/tos",
|
||||
"rel": "self",
|
||||
"type": "application/rdap+json"
|
||||
"type": "application/rdap+json",
|
||||
"value": "https://example.tld/rdap/nameservers"
|
||||
},
|
||||
{
|
||||
"href": "https://www.registry.tld/about/rdap/tos.html",
|
||||
"rel": "alternate",
|
||||
"type": "text/html"
|
||||
"href": "https://www.example.tld/about/rdap/tos.html",
|
||||
"rel": "terms-of-service",
|
||||
"type": "text/html",
|
||||
"value": "https://example.tld/rdap/nameservers"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -9,7 +9,8 @@
|
||||
{
|
||||
"rel": "self",
|
||||
"href": "https://example.tld/rdap/entity/301",
|
||||
"type": "application/rdap+json"
|
||||
"type": "application/rdap+json",
|
||||
"value": "https://example.tld/rdap/entities"
|
||||
}
|
||||
],
|
||||
"publicIds":
|
||||
@@ -66,7 +67,8 @@
|
||||
{
|
||||
"rel": "self",
|
||||
"href": "https://example.tld/rdap/entity/302",
|
||||
"type": "application/rdap+json"
|
||||
"type": "application/rdap+json",
|
||||
"value": "https://example.tld/rdap/entities"
|
||||
}
|
||||
],
|
||||
"publicIds":
|
||||
@@ -123,7 +125,8 @@
|
||||
{
|
||||
"rel": "self",
|
||||
"href": "https://example.tld/rdap/entity/303",
|
||||
"type": "application/rdap+json"
|
||||
"type": "application/rdap+json",
|
||||
"value": "https://example.tld/rdap/entities"
|
||||
}
|
||||
],
|
||||
"publicIds":
|
||||
@@ -180,7 +183,8 @@
|
||||
{
|
||||
"rel": "self",
|
||||
"href": "https://example.tld/rdap/entity/304",
|
||||
"type": "application/rdap+json"
|
||||
"type": "application/rdap+json",
|
||||
"value": "https://example.tld/rdap/entities"
|
||||
}
|
||||
],
|
||||
"publicIds":
|
||||
@@ -257,12 +261,14 @@
|
||||
{
|
||||
"href": "https://example.tld/rdap/help/tos",
|
||||
"rel": "self",
|
||||
"type": "application/rdap+json"
|
||||
"type": "application/rdap+json",
|
||||
"value": "https://example.tld/rdap/entities"
|
||||
},
|
||||
{
|
||||
"href": "https://www.registry.tld/about/rdap/tos.html",
|
||||
"rel": "alternate",
|
||||
"type": "text/html"
|
||||
"href": "https://www.example.tld/about/rdap/tos.html",
|
||||
"rel": "terms-of-service",
|
||||
"type": "text/html",
|
||||
"value": "https://example.tld/rdap/entities"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -5,22 +5,23 @@
|
||||
"icann_rdap_technical_implementation_guide_0"
|
||||
],
|
||||
"objectClassName" : "entity",
|
||||
"handle" : "%NAME%",
|
||||
"status" : ["%STATUS%"],
|
||||
"handle" : "%REGISTRAR_HANDLE_1%",
|
||||
"status" : ["%STATUS_1%"],
|
||||
"roles" : ["registrar"],
|
||||
"links" :
|
||||
[
|
||||
{
|
||||
"rel" : "self",
|
||||
"href": "https://example.tld/rdap/entity/%NAME%",
|
||||
"type" : "application/rdap+json"
|
||||
"href": "https://example.tld/rdap/entity/%REGISTRAR_HANDLE_1%",
|
||||
"type" : "application/rdap+json",
|
||||
"value": "%REQUEST_URL%"
|
||||
}
|
||||
],
|
||||
"publicIds" :
|
||||
[
|
||||
{
|
||||
"type" : "IANA Registrar ID",
|
||||
"identifier" : "%NAME%"
|
||||
"identifier" : "%REGISTRAR_HANDLE_1%"
|
||||
}
|
||||
],
|
||||
"events": [
|
||||
@@ -34,7 +35,7 @@
|
||||
"vcard",
|
||||
[
|
||||
["version", {}, "text", "4.0"],
|
||||
["fn", {}, "text", "%FULLNAME%"],
|
||||
["fn", {}, "text", "%REGISTRAR_FULLNAME_1%"],
|
||||
["adr", {}, "text",
|
||||
[
|
||||
"",
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
"icann_rdap_technical_implementation_guide_0"
|
||||
],
|
||||
"objectClassName" : "entity",
|
||||
"handle" : "%NAME%",
|
||||
"status" : ["%STATUS%"],
|
||||
"handle" : "%REGISTRAR_HANDLE_1%",
|
||||
"status" : ["%STATUS_1%"],
|
||||
"roles" : ["registrar"],
|
||||
"events": [
|
||||
{
|
||||
@@ -19,7 +19,7 @@
|
||||
"vcard",
|
||||
[
|
||||
["version", {}, "text", "4.0"],
|
||||
["fn", {}, "text", "%FULLNAME%"],
|
||||
["fn", {}, "text", "%REGISTRAR_FULLNAME_1%"],
|
||||
["adr", {}, "text",
|
||||
[
|
||||
"",
|
||||
|
||||
@@ -9,7 +9,8 @@
|
||||
{
|
||||
"rel": "self",
|
||||
"href": "https://example.tld/rdap/entity/0001-ROID",
|
||||
"type": "application/rdap+json"
|
||||
"type": "application/rdap+json",
|
||||
"value": "https://example.tld/rdap/entities"
|
||||
}
|
||||
],
|
||||
"events": [
|
||||
@@ -65,7 +66,8 @@
|
||||
{
|
||||
"rel": "self",
|
||||
"href": "https://example.tld/rdap/entity/0002-ROID",
|
||||
"type": "application/rdap+json"
|
||||
"type": "application/rdap+json",
|
||||
"value": "https://example.tld/rdap/entities"
|
||||
}
|
||||
],
|
||||
"events": [
|
||||
@@ -121,7 +123,8 @@
|
||||
{
|
||||
"rel": "self",
|
||||
"href": "https://example.tld/rdap/entity/0003-ROID",
|
||||
"type": "application/rdap+json"
|
||||
"type": "application/rdap+json",
|
||||
"value": "https://example.tld/rdap/entities"
|
||||
}
|
||||
],
|
||||
"events": [
|
||||
@@ -177,7 +180,8 @@
|
||||
{
|
||||
"rel": "self",
|
||||
"href": "https://example.tld/rdap/entity/0004-ROID",
|
||||
"type": "application/rdap+json"
|
||||
"type": "application/rdap+json",
|
||||
"value": "https://example.tld/rdap/entities"
|
||||
}
|
||||
],
|
||||
"events": [
|
||||
@@ -248,7 +252,8 @@
|
||||
{
|
||||
"type": "application/rdap+json",
|
||||
"href": "https://example.tld/rdap/entities?%NAME%",
|
||||
"rel": "next"
|
||||
"rel": "next",
|
||||
"value": "https://example.tld/rdap/entities"
|
||||
}
|
||||
],
|
||||
"description": [ "Links to related pages." ]
|
||||
@@ -273,12 +278,14 @@
|
||||
{
|
||||
"href": "https://example.tld/rdap/help/tos",
|
||||
"rel": "self",
|
||||
"type": "application/rdap+json"
|
||||
"type": "application/rdap+json",
|
||||
"value": "https://example.tld/rdap/entities"
|
||||
},
|
||||
{
|
||||
"href": "https://www.registry.tld/about/rdap/tos.html",
|
||||
"rel": "alternate",
|
||||
"type": "text/html"
|
||||
"href": "https://www.example.tld/about/rdap/tos.html",
|
||||
"rel": "terms-of-service",
|
||||
"type": "text/html",
|
||||
"value": "https://example.tld/rdap/entities"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -10,7 +10,8 @@
|
||||
{
|
||||
"rel" : "self",
|
||||
"type" : "application/rdap+json",
|
||||
"href" : "https://example.tld/rdap/nameserver/nsx1.cat.lol"
|
||||
"href" : "https://example.tld/rdap/nameserver/nsx1.cat.lol",
|
||||
"value": "https://example.tld/rdap/nameservers"
|
||||
}
|
||||
],
|
||||
"ipAddresses" :
|
||||
@@ -42,7 +43,8 @@
|
||||
{
|
||||
"rel" : "self",
|
||||
"type" : "application/rdap+json",
|
||||
"href" : "https://example.tld/rdap/nameserver/nsx2.cat.lol"
|
||||
"href" : "https://example.tld/rdap/nameserver/nsx2.cat.lol",
|
||||
"value": "https://example.tld/rdap/nameservers"
|
||||
}
|
||||
],
|
||||
"ipAddresses" :
|
||||
@@ -74,7 +76,8 @@
|
||||
{
|
||||
"rel" : "self",
|
||||
"type" : "application/rdap+json",
|
||||
"href" : "https://example.tld/rdap/nameserver/nsx3.cat.lol"
|
||||
"href" : "https://example.tld/rdap/nameserver/nsx3.cat.lol",
|
||||
"value": "https://example.tld/rdap/nameservers"
|
||||
}
|
||||
],
|
||||
"ipAddresses" :
|
||||
@@ -106,7 +109,8 @@
|
||||
{
|
||||
"rel" : "self",
|
||||
"type" : "application/rdap+json",
|
||||
"href" : "https://example.tld/rdap/nameserver/nsx4.cat.lol"
|
||||
"href" : "https://example.tld/rdap/nameserver/nsx4.cat.lol",
|
||||
"value": "https://example.tld/rdap/nameservers"
|
||||
}
|
||||
],
|
||||
"ipAddresses" :
|
||||
@@ -153,7 +157,8 @@
|
||||
{
|
||||
"type" : "application/rdap+json",
|
||||
"rel" : "next",
|
||||
"href" : "https://example.tld/rdap/nameservers?%QUERY%"
|
||||
"href" : "https://example.tld/rdap/nameservers?%QUERY%",
|
||||
"value": "https://example.tld/rdap/nameservers"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -177,12 +182,14 @@
|
||||
{
|
||||
"href": "https://example.tld/rdap/help/tos",
|
||||
"rel": "self",
|
||||
"type": "application/rdap+json"
|
||||
"type": "application/rdap+json",
|
||||
"value": "https://example.tld/rdap/nameservers"
|
||||
},
|
||||
{
|
||||
"href": "https://www.registry.tld/about/rdap/tos.html",
|
||||
"rel": "alternate",
|
||||
"type": "text/html"
|
||||
"href": "https://www.example.tld/about/rdap/tos.html",
|
||||
"rel": "terms-of-service",
|
||||
"type": "text/html",
|
||||
"value": "https://example.tld/rdap/nameservers"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -9,7 +9,8 @@
|
||||
{
|
||||
"rel" : "self",
|
||||
"href": "https://example.tld/rdap/entity/0001-ROID",
|
||||
"type" : "application/rdap+json"
|
||||
"type" : "application/rdap+json",
|
||||
"value": "https://example.tld/rdap/entities"
|
||||
}
|
||||
],
|
||||
"events": [
|
||||
@@ -65,7 +66,8 @@
|
||||
{
|
||||
"rel" : "self",
|
||||
"href": "https://example.tld/rdap/entity/0002-ROID",
|
||||
"type" : "application/rdap+json"
|
||||
"type" : "application/rdap+json",
|
||||
"value": "https://example.tld/rdap/entities"
|
||||
}
|
||||
],
|
||||
"events": [
|
||||
@@ -121,7 +123,8 @@
|
||||
{
|
||||
"rel" : "self",
|
||||
"href": "https://example.tld/rdap/entity/0003-ROID",
|
||||
"type" : "application/rdap+json"
|
||||
"type" : "application/rdap+json",
|
||||
"value": "https://example.tld/rdap/entities"
|
||||
}
|
||||
],
|
||||
"events": [
|
||||
@@ -177,7 +180,8 @@
|
||||
{
|
||||
"rel" : "self",
|
||||
"href": "https://example.tld/rdap/entity/301",
|
||||
"type" : "application/rdap+json"
|
||||
"type" : "application/rdap+json",
|
||||
"value": "https://example.tld/rdap/entities"
|
||||
}
|
||||
],
|
||||
"publicIds" :
|
||||
@@ -249,7 +253,8 @@
|
||||
{
|
||||
"type" : "application/rdap+json",
|
||||
"href" : "https://example.tld/rdap/entities?%NAME%",
|
||||
"rel" : "next"
|
||||
"rel" : "next",
|
||||
"value": "https://example.tld/rdap/entities"
|
||||
}
|
||||
],
|
||||
"description" : [ "Links to related pages." ]
|
||||
@@ -274,12 +279,14 @@
|
||||
{
|
||||
"href": "https://example.tld/rdap/help/tos",
|
||||
"rel": "self",
|
||||
"type": "application/rdap+json"
|
||||
"type": "application/rdap+json",
|
||||
"value": "https://example.tld/rdap/entities"
|
||||
},
|
||||
{
|
||||
"href": "https://www.registry.tld/about/rdap/tos.html",
|
||||
"rel": "alternate",
|
||||
"type": "text/html"
|
||||
"href": "https://www.example.tld/about/rdap/tos.html",
|
||||
"rel": "terms-of-service",
|
||||
"type": "text/html",
|
||||
"value": "https://example.tld/rdap/entities"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -9,7 +9,8 @@
|
||||
{
|
||||
"rel" : "self",
|
||||
"href": "https://example.tld/rdap/entity/301",
|
||||
"type" : "application/rdap+json"
|
||||
"type" : "application/rdap+json",
|
||||
"value": "https://example.tld/rdap/entities"
|
||||
}
|
||||
],
|
||||
"publicIds" :
|
||||
@@ -66,7 +67,8 @@
|
||||
{
|
||||
"rel" : "self",
|
||||
"href": "https://example.tld/rdap/entity/302",
|
||||
"type" : "application/rdap+json"
|
||||
"type" : "application/rdap+json",
|
||||
"value": "https://example.tld/rdap/entities"
|
||||
}
|
||||
],
|
||||
"publicIds" :
|
||||
@@ -123,7 +125,8 @@
|
||||
{
|
||||
"rel" : "self",
|
||||
"href": "https://example.tld/rdap/entity/303",
|
||||
"type" : "application/rdap+json"
|
||||
"type" : "application/rdap+json",
|
||||
"value": "https://example.tld/rdap/entities"
|
||||
}
|
||||
],
|
||||
"publicIds" :
|
||||
@@ -180,7 +183,8 @@
|
||||
{
|
||||
"rel" : "self",
|
||||
"href": "https://example.tld/rdap/entity/304",
|
||||
"type" : "application/rdap+json"
|
||||
"type" : "application/rdap+json",
|
||||
"value": "https://example.tld/rdap/entities"
|
||||
}
|
||||
],
|
||||
"publicIds" :
|
||||
@@ -252,7 +256,8 @@
|
||||
{
|
||||
"type" : "application/rdap+json",
|
||||
"href" : "https://example.tld/rdap/entities?%NAME%",
|
||||
"rel" : "next"
|
||||
"rel" : "next",
|
||||
"value": "https://example.tld/rdap/entities"
|
||||
}
|
||||
],
|
||||
"description" : [ "Links to related pages." ]
|
||||
@@ -277,12 +282,14 @@
|
||||
{
|
||||
"href": "https://example.tld/rdap/help/tos",
|
||||
"rel": "self",
|
||||
"type": "application/rdap+json"
|
||||
"type": "application/rdap+json",
|
||||
"value": "https://example.tld/rdap/entities"
|
||||
},
|
||||
{
|
||||
"href": "https://www.registry.tld/about/rdap/tos.html",
|
||||
"rel": "alternate",
|
||||
"type": "text/html"
|
||||
"href": "https://www.example.tld/about/rdap/tos.html",
|
||||
"rel": "terms-of-service",
|
||||
"type": "text/html",
|
||||
"value": "https://example.tld/rdap/entities"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -1 +1 @@
|
||||
{"key":"value","rdapConformance":["rdap_level_0","icann_rdap_response_profile_0","icann_rdap_technical_implementation_guide_0"],"notices":[{"title":"RDAP Terms of Service","links":[{"href":"https:\/\/www.registry.tld\/about\/rdap\/tos.html","rel":"alternate","type":"text\/html","value":"http:\/\/myserver.example.com\/help\/tos"}],"description":["By querying our Domain Database, you are agreeing to comply with these terms so please read them carefully.","Any information provided is 'as is' without any guarantee of accuracy.","Please do not misuse the Domain Database. It is intended solely for query-based access.","Don't use the Domain Database to allow, enable, or otherwise support the transmission of mass unsolicited, commercial advertising or solicitations.","Don't access our Domain Database through the use of high volume, automated electronic processes that send queries or data to the systems of any ICANN-accredited registrar.","You may only use the information contained in the Domain Database for lawful purposes.","Do not compile, repackage, disseminate, or otherwise use the information contained in the Domain Database in its entirety, or in any substantial portion, without our prior written permission.","We may retain certain details about queries to our Domain Database for the purposes of detecting and preventing misuse.","We reserve the right to restrict or deny your access to the database if we suspect that you have failed to comply with these terms.","We reserve the right to modify this agreement at any time."]}]}
|
||||
{"key":"value","rdapConformance":["rdap_level_0","icann_rdap_response_profile_0","icann_rdap_technical_implementation_guide_0"],"notices":[{"title":"RDAP Terms of Service","links":[{"href":"https:\/\/www.example.tld\/about\/rdap\/tos.html","rel":"alternate","type":"text\/html","value":"http:\/\/myserver.example.com\/help\/tos"}],"description":["By querying our Domain Database, you are agreeing to comply with these terms so please read them carefully.","Any information provided is 'as is' without any guarantee of accuracy.","Please do not misuse the Domain Database. It is intended solely for query-based access.","Don't use the Domain Database to allow, enable, or otherwise support the transmission of mass unsolicited, commercial advertising or solicitations.","Don't access our Domain Database through the use of high volume, automated electronic processes that send queries or data to the systems of any ICANN-accredited registrar.","You may only use the information contained in the Domain Database for lawful purposes.","Do not compile, repackage, disseminate, or otherwise use the information contained in the Domain Database in its entirety, or in any substantial portion, without our prior written permission.","We may retain certain details about queries to our Domain Database for the purposes of detecting and preventing misuse.","We reserve the right to restrict or deny your access to the database if we suspect that you have failed to comply with these terms.","We reserve the right to modify this agreement at any time."]}]}
|
||||
|
||||
@@ -30,8 +30,8 @@
|
||||
"type": "application/rdap+json"
|
||||
},
|
||||
{
|
||||
"href": "https://www.registry.tld/about/rdap/tos.html",
|
||||
"rel": "alternate",
|
||||
"href": "https://www.example.tld/about/rdap/tos.html",
|
||||
"rel": "terms-of-service",
|
||||
"type": "text/html"
|
||||
}
|
||||
]
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user