1
0
mirror of https://github.com/google/nomulus synced 2026-05-26 09:41:09 +00:00

Compare commits

..

6 Commits

Author SHA1 Message Date
Ben McIlwain
8d22c2a8d8 Remove unnecessary if statements in CloudDnsWriter (#2071)
The condition they are guarding against cannot possibly occur.
2023-07-07 13:15:02 -04:00
gbrodman
fe19f0fe78 Clean up issues with RDAP redaction (#2067)
Instead of using REDACTED FOR PRIVACY everywhere we should just include
the empty string (this is what the spec says, what other gTLD registrars
do, and what the RDAP conformance tool at
https://github.com/icann/rdap-conformance-tool says to do.

In the contact VCards, we omit redacted fields entirely unless the spec
requires that they exist (the version number and an empty 'fn' field).
This also applies to the "handle" field.

Eventually we will probably want to add the redaction extension but
that's not RFCed yet and isn't required for the August RDAP conformance
deadline.
2023-07-06 14:48:51 -04:00
Ben McIlwain
599a55d5b1 Fix the output slightly when running nomulus update_premium_list (#2065)
It was previously calling toString() on an Optional<PremiumList> which was
unnecessarily verbose. The existing premium list is required to be present
anyway.
2023-07-06 13:46:28 -04:00
Pavlo Tkach
845f792044 Add better integration for console formatting check and apply (#2070) 2023-07-06 12:33:32 -04:00
Ben McIlwain
ad68052524 Add minor refactoring follow-up for RefreshDnsForAllDomainsAction (#2063)
This is a follow-on to comments in PR #2037. It makes the main loop cleaner and
also removes ambiguities around database handling when the first query is run
with the cursor still empty because no results have been found yet.
2023-07-05 15:09:20 -04:00
gbrodman
04c6652793 Fix minor RDAP typos (#2062)
See https://buganizer.corp.google.com/issues/252317192 for more info,
these are just the low-hanging fruit (removing a www and fixing a typo
in a status)
2023-06-30 12:24:39 -04:00
27 changed files with 955 additions and 1297 deletions

View File

@@ -505,6 +505,7 @@ task javaIncrementalFormatCheck {
println("Omitting format check: not in a git directory.")
}
}
dependsOn('console-webapp:checkFormatting')
}
// Shows how modified lines in Java source files will change after formatting.
@@ -522,6 +523,7 @@ task javaIncrementalFormatApply {
doLast {
invokeJavaDiffFormatScript("format")
}
dependsOn('console-webapp:applyFormatting')
}
task javadoc(type: Javadoc) {

View File

@@ -50,12 +50,19 @@ task buildConsoleWebappProd(type: Exec) {
args 'run', 'build'
}
task applyFormatting() {
exec {
workingDir "${consoleDir}/"
commandLine 'npm', 'run', 'prettify'
}
task applyFormatting(type: Exec) {
workingDir "${consoleDir}/"
executable 'npm'
args 'run', 'prettify'
}
task checkFormatting(type: Exec) {
workingDir "${consoleDir}/"
executable 'npm'
args 'run', 'prettify:check'
}
tasks.runConsoleWebappUnitTests.dependsOn(tasks.npmInstallDeps)
tasks.buildConsoleWebappProd.dependsOn(tasks.npmInstallDeps)
tasks.applyFormatting.dependsOn(tasks.npmInstallDeps)
tasks.checkFormatting.dependsOn(tasks.npmInstallDeps)

File diff suppressed because it is too large Load Diff

View File

@@ -10,6 +10,7 @@
"test": "ng test --browsers=ChromeHeadless --watch=false",
"run:dev": "",
"prettify": "npx prettier --write ./src/",
"prettify:check": "npx prettier --check ./src/",
"start:dev": "concurrently \"./../gradlew :core:runTestServer\" \"ng serve --proxy-config dev-proxy.config.json\"",
"lint": "ng lint"
},

View File

@@ -144,15 +144,13 @@ public class CloudDnsWriter extends BaseDnsWriter {
dsRrData.add(ds.toRrData());
}
if (!dsRrData.isEmpty()) {
domainRecords.add(
new ResourceRecordSet()
.setName(absoluteDomainName)
.setTtl((int) tld.getDnsDsTtl().orElse(defaultDsTtl).getStandardSeconds())
.setType("DS")
.setKind("dns#resourceRecordSet")
.setRrdatas(ImmutableList.copyOf(dsRrData)));
}
domainRecords.add(
new ResourceRecordSet()
.setName(absoluteDomainName)
.setTtl((int) tld.getDnsDsTtl().orElse(defaultDsTtl).getStandardSeconds())
.setType("DS")
.setKind("dns#resourceRecordSet")
.setRrdatas(ImmutableList.copyOf(dsRrData)));
}
// Construct NS records (if any).
@@ -169,15 +167,13 @@ public class CloudDnsWriter extends BaseDnsWriter {
}
}
if (!nsRrData.isEmpty()) {
domainRecords.add(
new ResourceRecordSet()
.setName(absoluteDomainName)
.setTtl((int) tld.getDnsNsTtl().orElse(defaultNsTtl).getStandardSeconds())
.setType("NS")
.setKind("dns#resourceRecordSet")
.setRrdatas(ImmutableList.copyOf(nsRrData)));
}
domainRecords.add(
new ResourceRecordSet()
.setName(absoluteDomainName)
.setTtl((int) tld.getDnsNsTtl().orElse(defaultNsTtl).getStandardSeconds())
.setType("NS")
.setKind("dns#resourceRecordSet")
.setRrdatas(ImmutableList.copyOf(nsRrData)));
}
desiredRecords.put(absoluteDomainName, domainRecords.build());

View File

@@ -367,7 +367,7 @@ final class RdapDataStructures {
PENDING_RESTORE("pending restore"),
REDEMPTION_PERIOD("redemption period"),
RENEW_PERIOD("renew period"),
SERVER_DELETE_PROHIBITED("server deleted prohibited"),
SERVER_DELETE_PROHIBITED("server delete prohibited"),
SERVER_RENEW_PROHIBITED("server renew prohibited"),
SERVER_TRANSFER_PROHIBITED("server transfer prohibited"),
SERVER_UPDATE_PROHIBITED("server update prohibited"),

View File

@@ -54,12 +54,11 @@ public class RdapIcannStandardInformation {
private static final Notice INACCURACY_COMPLAINT_FORM_NOTICE =
Notice.builder()
.setTitle("RDDS Inaccuracy Complaint Form")
.setDescription(
"URL of the ICANN RDDS Inaccuracy Complaint Form: https://www.icann.org/wicf")
.setDescription("URL of the ICANN RDDS Inaccuracy Complaint Form: https://icann.org/wicf")
.addLink(
Link.builder()
.setRel("alternate")
.setHref("https://www.icann.org/wicf")
.setHref("https://icann.org/wicf")
.setType("text/html")
.build())
.build();
@@ -150,14 +149,6 @@ public class RdapIcannStandardInformation {
.build())
.build();
/**
* String that replaces GDPR redacted values.
*
* <p>GTLD Registration Data Temp Spec 17may18, Appendix A, 2.2: Fields required to be "redacted"
* MUST privide in the value section text similar to "REDACTED FOR PRIVACY"
*/
static final String CONTACT_REDACTED_VALUE = "REDACTED FOR PRIVACY";
/**
* Included in ALL contact responses, even if the user is authorized.
*

View File

@@ -21,7 +21,6 @@ import static com.google.common.collect.ImmutableSet.toImmutableSet;
import static com.google.common.collect.ImmutableSetMultimap.toImmutableSetMultimap;
import static google.registry.model.EppResourceUtils.isLinked;
import static google.registry.persistence.transaction.TransactionManagerFactory.replicaTm;
import static google.registry.rdap.RdapIcannStandardInformation.CONTACT_REDACTED_VALUE;
import static google.registry.util.CollectionUtils.union;
import com.google.common.annotations.VisibleForTesting;
@@ -39,7 +38,6 @@ import com.google.gson.JsonArray;
import google.registry.config.RegistryConfig.Config;
import google.registry.model.EppResource;
import google.registry.model.contact.Contact;
import google.registry.model.contact.ContactAddress;
import google.registry.model.contact.ContactPhoneNumber;
import google.registry.model.contact.PostalInfo;
import google.registry.model.domain.DesignatedContact;
@@ -519,69 +517,68 @@ public class RdapJsonFormatter {
boolean isAuthorized =
rdapAuthorization.isAuthorizedForRegistrar(contact.getCurrentSponsorRegistrarId());
// ROID needs to be redacted if we aren't authorized, so we can't have a self-link for
// unauthorized users
VcardArray.Builder vcardBuilder = VcardArray.builder();
if (isAuthorized) {
contactBuilder.linksBuilder().add(makeSelfLink("entity", contact.getRepoId()));
}
// Only show the "summary data remark" if the user is authorized to see this data - because
// unauthorized users don't have a self link meaning they can't navigate to the full data.
if (outputDataType != OutputDataType.FULL && isAuthorized) {
contactBuilder.remarksBuilder().add(RdapIcannStandardInformation.SUMMARY_DATA_REMARK);
}
// GTLD Registration Data Temp Spec 17may18, Appendix A, 2.3, 2.4 and RDAP Response Profile
// 2.7.4.1, 2.7.4.2 - the following fields must be redacted:
// for REGISTRANT:
// handle (ROID), FN (name), TEL (telephone/fax and extension), street, city, postal code
// for ADMIN, TECH:
// handle (ROID), FN (name), TEL (telephone/fax and extension), Organization, street, city,
// state/province, postal code, country
//
// Note that in theory we have to show the Organization and state/province and country for the
// REGISTRANT. For now, we won't do that until we make sure it's really OK for GDPR
//
if (!isAuthorized) {
fillRdapContactEntityWhenAuthorized(contactBuilder, vcardBuilder, contact, outputDataType);
} else {
// GTLD Registration Data Temp Spec 17may18, Appendix A, 2.3, 2.4 and RDAP Response Profile
// 2.7.4.1, 2.7.4.2 - the following fields must be redacted:
// for REGISTRANT:
// handle (ROID), FN (name), TEL (telephone/fax and extension), street, city, postal code
// for ADMIN, TECH:
// handle (ROID), FN (name), TEL (telephone/fax and extension), Organization, street, city,
// state/province, postal code, country
//
// Note that in theory we have to show the Organization and state/province and country for the
// REGISTRANT. For now, we won't do that until we make sure it's really OK for GDPR
//
// RDAP Response Profile 2.7.4.3: if we redact values from the contact, we MUST include a
// remark
contactBuilder
.remarksBuilder()
.add(RdapIcannStandardInformation.CONTACT_PERSONAL_DATA_HIDDEN_DATA_REMARK);
// to make sure we don't accidentally display data we shouldn't - we replace the
// contact with a safe resource. Then we can add any information we need (e.g. the
// Organization / state / country of the registrant), although we currently don't do that.
contact =
new Contact.Builder()
.setRepoId(CONTACT_REDACTED_VALUE)
.setVoiceNumber(
new ContactPhoneNumber.Builder().setPhoneNumber(CONTACT_REDACTED_VALUE).build())
.setFaxNumber(
new ContactPhoneNumber.Builder().setPhoneNumber(CONTACT_REDACTED_VALUE).build())
.setInternationalizedPostalInfo(
new PostalInfo.Builder()
.setName(CONTACT_REDACTED_VALUE)
.setOrg(CONTACT_REDACTED_VALUE)
.setType(PostalInfo.Type.INTERNATIONALIZED)
.setAddress(
new ContactAddress.Builder()
.setStreet(ImmutableList.of(CONTACT_REDACTED_VALUE))
.setCity(CONTACT_REDACTED_VALUE)
.setState(CONTACT_REDACTED_VALUE)
.setZip(CONTACT_REDACTED_VALUE)
.setCountryCode("XX")
.build())
.build())
.build();
contactBuilder.setHandle("");
// The VCard format requires a "fn" entry even if it is empty (redacted)
vcardBuilder.add(Vcard.create("fn", "text", ""));
}
// RDAP Response Profile 2.7.3 - we MUST provide a handle set with the ROID, subject to the
// redaction above.
contactBuilder.setHandle(contact.getRepoId());
contactBuilder.setVcardArray(vcardBuilder.build());
contactBuilder.rolesBuilder().addAll(roles);
// RDAP Response Profile doesn't mention status for contacts, so we only show it if we're both
// FULL and Authorized.
if (outputDataType == OutputDataType.FULL && isAuthorized) {
// RDAP Response Profile 2.7.5.1, 2.7.5.3:
// email MUST be omitted, and we MUST have a Remark saying so
contactBuilder
.remarksBuilder()
.add(RdapIcannStandardInformation.CONTACT_EMAIL_REDACTED_FOR_DOMAIN);
if (outputDataType != OutputDataType.INTERNAL) {
// Rdap Response Profile 2.7.6 must have "last update of RDAP database" response. But this is
// only for direct query responses and not for internal objects. I'm not sure why it's in that
// section at all...
contactBuilder.setLastUpdateOfRdapDatabaseEvent(
Event.builder()
.setEventAction(EventAction.LAST_UPDATE_OF_RDAP_DATABASE)
.setEventDate(getRequestTime())
.build());
}
return contactBuilder.build();
}
private void fillRdapContactEntityWhenAuthorized(
RdapContactEntity.Builder contactBuilder,
VcardArray.Builder vcardBuilder,
Contact contact,
OutputDataType outputDataType) {
// ROID needs to be redacted if we aren't authorized, so we can't have a self-link for
// unauthorized users
contactBuilder.linksBuilder().add(makeSelfLink("entity", contact.getRepoId()));
// RDAP Response Profile 2.7.3 - we MUST provide a handle set with the ROID, subject to
// redaction.
contactBuilder.setHandle(contact.getRepoId());
if (outputDataType.equals(OutputDataType.FULL)) {
// RDAP Response Profile doesn't mention status for contacts, so we only show it if we're both
// FULL and Authorized.
contactBuilder
.statusBuilder()
.addAll(
@@ -591,12 +588,18 @@ public class RdapJsonFormatter {
: contact.getStatusValues(),
false,
contact.getDeletionTime().isBefore(getRequestTime())));
// If we are outputting all data (not just summary data), also add events taken from the
// history entries. This isn't strictly required.
//
// We also only add it for authorized users because millisecond times can fingerprint a user
// just as much as the handle can.
contactBuilder.eventsBuilder().addAll(makeOptionalEvents(contact));
} else {
// Only show the "summary data remark" if the user is authorized to see this data - because
// unauthorized users don't have a self link meaning they can't navigate to the full data.
contactBuilder.remarksBuilder().add(RdapIcannStandardInformation.SUMMARY_DATA_REMARK);
}
contactBuilder.rolesBuilder().addAll(roles);
VcardArray.Builder vcardBuilder = VcardArray.builder();
// Adding the VCard members subject to the redaction above.
// Adding the VCard members when not redacted.
//
// RDAP Response Profile 2.7.3 - we MUST have FN, ADR, TEL, EMAIL.
//
@@ -622,33 +625,6 @@ public class RdapJsonFormatter {
if (faxPhoneNumber != null) {
vcardBuilder.add(makePhoneEntry(PHONE_TYPE_FAX, makePhoneString(faxPhoneNumber)));
}
// RDAP Response Profile 2.7.5.1, 2.7.5.3:
// email MUST be omitted, and we MUST have a Remark saying so
contactBuilder
.remarksBuilder()
.add(RdapIcannStandardInformation.CONTACT_EMAIL_REDACTED_FOR_DOMAIN);
contactBuilder.setVcardArray(vcardBuilder.build());
if (outputDataType != OutputDataType.INTERNAL) {
// Rdap Response Profile 2.7.6 must have "last update of RDAP database" response. But this is
// only for direct query responses and not for internal objects. I'm not sure why it's in that
// section at all...
contactBuilder.setLastUpdateOfRdapDatabaseEvent(
Event.builder()
.setEventAction(EventAction.LAST_UPDATE_OF_RDAP_DATABASE)
.setEventDate(getRequestTime())
.build());
}
// If we are outputting all data (not just summary data), also add events taken from the history
// entries. This isn't strictly required.
//
// We also only add it for authorized users because millisecond times can fingerprint a user
// just as much as the handle can.
if (outputDataType == OutputDataType.FULL && isAuthorized) {
contactBuilder.eventsBuilder().addAll(makeOptionalEvents(contact));
}
return contactBuilder.build();
}
/**
@@ -1000,7 +976,7 @@ public class RdapJsonFormatter {
// Gustavo Lozano of ICANN, the one we should use is an embedded array of street address lines
// if there is more than one line:
//
// RFC7095 provides two examples of structured addresses, and one of the examples shows a
// RFC 7095 provides two examples of structured addresses, and one of the examples shows a
// street JSON element that contains several data elements. The example showing (see below)
// several data elements is the expected output when two or more <contact:street> elements
// exists in the contact object.

View File

@@ -24,7 +24,6 @@ import google.registry.model.tld.label.PremiumList;
import google.registry.model.tld.label.PremiumListDao;
import google.registry.model.tld.label.PremiumListUtils;
import java.nio.file.Files;
import java.util.Optional;
/** Command to safely update {@link PremiumList} in Database for a given TLD. */
@Parameters(separators = " =", commandDescription = "Update a PremiumList in Database.")
@@ -33,16 +32,19 @@ class UpdatePremiumListCommand extends CreateOrUpdatePremiumListCommand {
@Override
protected String prompt() throws Exception {
name = Strings.isNullOrEmpty(name) ? convertFilePathToName(inputFile) : name;
Optional<PremiumList> list = PremiumListDao.getLatestRevision(name);
checkArgument(
list.isPresent(),
String.format("Could not update premium list %s because it doesn't exist.", name));
PremiumList existingList =
PremiumListDao.getLatestRevision(name)
.orElseThrow(
() ->
new IllegalArgumentException(
String.format(
"Could not update premium list %s because it doesn't exist", name)));
inputData = Files.readAllLines(inputFile, UTF_8);
checkArgument(!inputData.isEmpty(), "New premium list data cannot be empty");
currency = list.get().getCurrency();
currency = existingList.getCurrency();
PremiumList updatedPremiumList = PremiumListUtils.parseToPremiumList(name, currency, inputData);
return String.format(
"Update premium list for %s?\n Old List: %s\n New List: %s",
name, list, updatedPremiumList);
name, existingList, updatedPremiumList);
}
}

View File

@@ -32,7 +32,9 @@ import google.registry.request.Response;
import google.registry.request.auth.Auth;
import java.util.Optional;
import java.util.Random;
import javax.annotation.Nullable;
import javax.inject.Inject;
import javax.persistence.TypedQuery;
import org.apache.arrow.util.VisibleForTesting;
import org.apache.http.HttpStatus;
import org.joda.time.Duration;
@@ -85,11 +87,14 @@ public class RefreshDnsForAllDomainsAction implements Runnable {
assertTldsExist(tlds);
checkArgument(batchSize > 0, "Must specify a positive number for batch size");
int smearMinutes = tm().transact(this::calculateSmearMinutes);
ImmutableList<String> previousBatch = ImmutableList.of("");
ImmutableList<String> domainsBatch;
@Nullable String lastInPreviousBatch = null;
do {
String lastInPreviousBatch = getLast(previousBatch);
previousBatch = tm().transact(() -> refreshBatch(lastInPreviousBatch, smearMinutes));
} while (previousBatch.size() == batchSize);
Optional<String> lastInPreviousBatchOpt = Optional.ofNullable(lastInPreviousBatch);
domainsBatch = tm().transact(() -> refreshBatch(lastInPreviousBatchOpt, smearMinutes));
lastInPreviousBatch = domainsBatch.isEmpty() ? null : getLast(domainsBatch);
} while (domainsBatch.size() == batchSize);
}
/**
@@ -107,22 +112,22 @@ public class RefreshDnsForAllDomainsAction implements Runnable {
return Math.max(activeDomains.intValue() / 1000, 1);
}
private ImmutableList<String> getBatch(String lastInPreviousBatch) {
return tm().query(
private ImmutableList<String> getBatch(Optional<String> lastInPreviousBatch) {
String sql =
String.format(
"SELECT domainName FROM Domain WHERE tld IN (:tlds) AND"
+ " deletionTime = :endOfTime AND domainName >"
+ " :lastInPreviousBatch ORDER BY domainName ASC",
String.class)
.setParameter("tlds", tlds)
.setParameter("endOfTime", END_OF_TIME)
.setParameter("lastInPreviousBatch", lastInPreviousBatch)
.setMaxResults(batchSize)
.getResultStream()
.collect(toImmutableList());
+ " deletionTime = :endOfTime %s ORDER BY domainName ASC",
lastInPreviousBatch.isPresent() ? "AND domainName > :lastInPreviousBatch" : "");
TypedQuery<String> query =
tm().query(sql, String.class)
.setParameter("tlds", tlds)
.setParameter("endOfTime", END_OF_TIME);
lastInPreviousBatch.ifPresent(l -> query.setParameter("lastInPreviousBatch", l));
return query.setMaxResults(batchSize).getResultStream().collect(toImmutableList());
}
@VisibleForTesting
ImmutableList<String> refreshBatch(String lastInPreviousBatch, int smearMinutes) {
ImmutableList<String> refreshBatch(Optional<String> lastInPreviousBatch, int smearMinutes) {
ImmutableList<String> domainBatch = getBatch(lastInPreviousBatch);
try {
// Smear the task execution time over the next N minutes.

View File

@@ -139,13 +139,12 @@ class RdapTestHelper {
"RDDS Inaccuracy Complaint Form",
"description",
ImmutableList.of(
"URL of the ICANN RDDS Inaccuracy Complaint Form:"
+ " https://www.icann.org/wicf"),
"URL of the ICANN RDDS Inaccuracy Complaint Form: https://icann.org/wicf"),
"links",
ImmutableList.of(
ImmutableMap.of(
"rel", "alternate",
"href", "https://www.icann.org/wicf",
"href", "https://icann.org/wicf",
"type", "text/html")))));
}

View File

@@ -134,15 +134,13 @@ class UpdatePremiumListCommandTest<C extends UpdatePremiumListCommand>
@Test
void commandPrompt_failureNoPreviousVersion() {
String fileName = "random";
registry = createTld(fileName, null, null);
registry = createTld("random", null, null);
UpdatePremiumListCommand command = new UpdatePremiumListCommand();
command.name = fileName;
command.name = "random";
IllegalArgumentException thrown = assertThrows(IllegalArgumentException.class, command::prompt);
assertThat(thrown)
.hasMessageThat()
.isEqualTo(
String.format("Could not update premium list %s because it doesn't exist.", fileName));
.isEqualTo("Could not update premium list random because it doesn't exist");
}
@Test
@@ -153,27 +151,22 @@ class UpdatePremiumListCommandTest<C extends UpdatePremiumListCommand>
@Test
void commandPrompt_failureTldFromNameDoesNotExist() {
String fileName = "random";
UpdatePremiumListCommand command = new UpdatePremiumListCommand();
command.name = fileName;
command.name = "random2";
IllegalArgumentException thrown = assertThrows(IllegalArgumentException.class, command::prompt);
assertThat(thrown)
.hasMessageThat()
.isEqualTo(
String.format("Could not update premium list %s because it doesn't exist.", fileName));
.isEqualTo("Could not update premium list random2 because it doesn't exist");
}
@Test
void commandPrompt_failureTldFromInputFileDoesNotExist() {
String fileName = "random";
UpdatePremiumListCommand command = new UpdatePremiumListCommand();
// using tld extracted from file name but this tld is not part of the registry
command.inputFile =
Paths.get(tmpDir.resolve(String.format("%s.txt", fileName)).toFile().getPath());
command.inputFile = Paths.get(tmpDir.resolve("random3.txt").toFile().getPath());
IllegalArgumentException thrown = assertThrows(IllegalArgumentException.class, command::prompt);
assertThat(thrown)
.hasMessageThat()
.isEqualTo(
String.format("Could not update premium list %s because it doesn't exist.", fileName));
.isEqualTo("Could not update premium list random3 because it doesn't exist");
}
}

View File

@@ -75,8 +75,8 @@ public class RefreshDnsForAllDomainsActionTest {
action =
new RefreshDnsForAllDomainsAction(
response, ImmutableSet.of("bar"), Optional.of(1), new Random());
tm().transact(() -> action.refreshBatch("", 1000));
tm().transact(() -> action.refreshBatch("", 1000));
tm().transact(() -> action.refreshBatch(Optional.empty(), 1000));
tm().transact(() -> action.refreshBatch(Optional.empty(), 1000));
ImmutableList<DnsRefreshRequest> refreshRequests =
tm().transact(
() ->

View File

@@ -5,7 +5,7 @@
"icann_rdap_technical_implementation_guide_0"
],
"objectClassName" : "entity",
"handle" : "REDACTED FOR PRIVACY",
"handle" : "",
"events": [
{
"eventAction": "last update of RDAP database",
@@ -15,25 +15,8 @@
"vcardArray": [
"vcard",
[
["version",{},"text","4.0"],
["fn",{},"text","REDACTED FOR PRIVACY"],
["org",{},"text","REDACTED FOR PRIVACY"],
[
"adr",
{},
"text",
[
"",
"",
"REDACTED FOR PRIVACY",
"REDACTED FOR PRIVACY",
"REDACTED FOR PRIVACY",
"REDACTED FOR PRIVACY",
"XX"
]
],
["tel",{"type":["voice"]},"uri","tel:REDACTED FOR PRIVACY"],
["tel",{"type":["fax"]},"uri","tel:REDACTED FOR PRIVACY"]
["version", {}, "text", "4.0"],
["fn", {}, "text", ""]
]
],
"remarks": [

View File

@@ -5,7 +5,7 @@
"icann_rdap_technical_implementation_guide_0"
],
"objectClassName" : "entity",
"handle" : "REDACTED FOR PRIVACY",
"handle" : "",
"events": [
{
"eventAction": "last update of RDAP database",
@@ -15,25 +15,8 @@
"vcardArray": [
"vcard",
[
["version",{},"text","4.0"],
["fn",{},"text","REDACTED FOR PRIVACY"],
["org",{},"text","REDACTED FOR PRIVACY"],
[
"adr",
{},
"text",
[
"",
"",
"REDACTED FOR PRIVACY",
"REDACTED FOR PRIVACY",
"REDACTED FOR PRIVACY",
"REDACTED FOR PRIVACY",
"XX"
]
],
["tel",{"type":["voice"]},"uri","tel:REDACTED FOR PRIVACY"],
["tel",{"type":["fax"]},"uri","tel:REDACTED FOR PRIVACY"]
["version", {}, "text", "4.0"],
["fn", {}, "text", ""]
]
],
"remarks": [

View File

@@ -150,7 +150,7 @@
},
{
"objectClassName": "entity",
"handle": "REDACTED FOR PRIVACY",
"handle": "",
"roles":["administrative"],
"remarks": [
{
@@ -180,18 +180,14 @@
"vcard",
[
["version", {}, "text", "4.0"],
["fn", {}, "text", "REDACTED FOR PRIVACY"],
["org", {}, "text", "REDACTED FOR PRIVACY"],
["adr", {}, "text", ["", "", "REDACTED FOR PRIVACY", "REDACTED FOR PRIVACY", "REDACTED FOR PRIVACY", "REDACTED FOR PRIVACY", "XX"]],
["tel", {"type":["voice"]}, "uri", "tel:REDACTED FOR PRIVACY"],
["tel", {"type":["fax"]}, "uri", "tel:REDACTED FOR PRIVACY"]
["fn", {}, "text", ""]
]
]
},
{
"objectClassName":"entity",
"handle":"REDACTED FOR PRIVACY",
"handle":"",
"remarks":[
{
"title":"REDACTED FOR PRIVACY",
@@ -221,18 +217,14 @@
"vcard",
[
["version", {}, "text", "4.0"],
["fn", {}, "text", "REDACTED FOR PRIVACY"],
["org", {}, "text", "REDACTED FOR PRIVACY"],
["adr", {}, "text", ["", "", "REDACTED FOR PRIVACY", "REDACTED FOR PRIVACY", "REDACTED FOR PRIVACY", "REDACTED FOR PRIVACY", "XX"]],
["tel", {"type":["voice"]}, "uri", "tel:REDACTED FOR PRIVACY"],
["tel", {"type":["fax"]}, "uri", "tel:REDACTED FOR PRIVACY"]
["fn", {}, "text", ""]
]
]
},
{
"objectClassName":"entity",
"handle":"REDACTED FOR PRIVACY",
"handle":"",
"remarks":[
{
"title":"REDACTED FOR PRIVACY",
@@ -262,11 +254,7 @@
"vcard",
[
["version", {}, "text", "4.0"],
["fn", {}, "text", "REDACTED FOR PRIVACY"],
["org", {}, "text", "REDACTED FOR PRIVACY"],
["adr", {}, "text", ["", "", "REDACTED FOR PRIVACY", "REDACTED FOR PRIVACY", "REDACTED FOR PRIVACY", "REDACTED FOR PRIVACY", "XX"]],
["tel", {"type":["voice"]}, "uri", "tel:REDACTED FOR PRIVACY"],
["tel", {"type":["fax"]}, "uri", "tel:REDACTED FOR PRIVACY"]
["fn", {}, "text", ""]
]
]
}

View File

@@ -153,7 +153,7 @@
},
{
"objectClassName": "entity",
"handle": "REDACTED FOR PRIVACY",
"handle": "",
"roles":["administrative"],
"remarks": [
{
@@ -183,18 +183,14 @@
"vcard",
[
["version", {}, "text", "4.0"],
["fn", {}, "text", "REDACTED FOR PRIVACY"],
["org", {}, "text", "REDACTED FOR PRIVACY"],
["adr", {}, "text", ["", "", "REDACTED FOR PRIVACY", "REDACTED FOR PRIVACY", "REDACTED FOR PRIVACY", "REDACTED FOR PRIVACY", "XX"]],
["tel", {"type":["voice"]}, "uri", "tel:REDACTED FOR PRIVACY"],
["tel", {"type":["fax"]}, "uri", "tel:REDACTED FOR PRIVACY"]
["fn", {}, "text", ""]
]
]
},
{
"objectClassName":"entity",
"handle":"REDACTED FOR PRIVACY",
"handle":"",
"remarks":[
{
"title":"REDACTED FOR PRIVACY",
@@ -224,18 +220,13 @@
"vcard",
[
["version", {}, "text", "4.0"],
["fn", {}, "text", "REDACTED FOR PRIVACY"],
["org", {}, "text", "REDACTED FOR PRIVACY"],
["adr", {}, "text", ["", "", "REDACTED FOR PRIVACY", "REDACTED FOR PRIVACY", "REDACTED FOR PRIVACY", "REDACTED FOR PRIVACY", "XX"]],
["tel", {"type":["voice"]}, "uri", "tel:REDACTED FOR PRIVACY"],
["tel", {"type":["fax"]}, "uri", "tel:REDACTED FOR PRIVACY"]
]
["fn", {}, "text", ""] ]
]
},
{
"objectClassName":"entity",
"handle":"REDACTED FOR PRIVACY",
"handle":"",
"remarks":[
{
"title":"REDACTED FOR PRIVACY",
@@ -265,11 +256,7 @@
"vcard",
[
["version", {}, "text", "4.0"],
["fn", {}, "text", "REDACTED FOR PRIVACY"],
["org", {}, "text", "REDACTED FOR PRIVACY"],
["adr", {}, "text", ["", "", "REDACTED FOR PRIVACY", "REDACTED FOR PRIVACY", "REDACTED FOR PRIVACY", "REDACTED FOR PRIVACY", "XX"]],
["tel", {"type":["voice"]}, "uri", "tel:REDACTED FOR PRIVACY"],
["tel", {"type":["fax"]}, "uri", "tel:REDACTED FOR PRIVACY"]
["fn", {}, "text", ""]
]
]
}

View File

@@ -156,12 +156,12 @@
},
{
"title": "RDDS Inaccuracy Complaint Form",
"description" : ["URL of the ICANN RDDS Inaccuracy Complaint Form: https://www.icann.org/wicf"],
"description" : ["URL of the ICANN RDDS Inaccuracy Complaint Form: https://icann.org/wicf"],
"links" :
[
{
"rel" : "alternate",
"href" : "https://www.icann.org/wicf",
"href" : "https://icann.org/wicf",
"type" : "text/html"
}
]

View File

@@ -137,12 +137,12 @@
},
{
"title": "RDDS Inaccuracy Complaint Form",
"description" : ["URL of the ICANN RDDS Inaccuracy Complaint Form: https://www.icann.org/wicf"],
"description" : ["URL of the ICANN RDDS Inaccuracy Complaint Form: https://icann.org/wicf"],
"links" :
[
{
"rel" : "alternate",
"href" : "https://www.icann.org/wicf",
"href" : "https://icann.org/wicf",
"type" : "text/html"
}
]

View File

@@ -157,12 +157,12 @@
},
{
"title": "RDDS Inaccuracy Complaint Form",
"description" : ["URL of the ICANN RDDS Inaccuracy Complaint Form: https://www.icann.org/wicf"],
"description" : ["URL of the ICANN RDDS Inaccuracy Complaint Form: https://icann.org/wicf"],
"links" :
[
{
"rel" : "alternate",
"href" : "https://www.icann.org/wicf",
"href" : "https://icann.org/wicf",
"type" : "text/html"
}
]

View File

@@ -95,12 +95,12 @@
},
{
"title": "RDDS Inaccuracy Complaint Form",
"description": ["URL of the ICANN RDDS Inaccuracy Complaint Form: https://www.icann.org/wicf"],
"description": ["URL of the ICANN RDDS Inaccuracy Complaint Form: https://icann.org/wicf"],
"links":
[
{
"rel": "alternate",
"href": "https://www.icann.org/wicf",
"href": "https://icann.org/wicf",
"type": "text/html"
}
]

View File

@@ -130,12 +130,12 @@
},
{
"title": "RDDS Inaccuracy Complaint Form",
"description": ["URL of the ICANN RDDS Inaccuracy Complaint Form: https://www.icann.org/wicf"],
"description": ["URL of the ICANN RDDS Inaccuracy Complaint Form: https://icann.org/wicf"],
"links":
[
{
"rel":"alternate",
"href":"https://www.icann.org/wicf",
"href":"https://icann.org/wicf",
"type":"text/html"
}
]

View File

@@ -98,12 +98,12 @@
},
{
"title": "RDDS Inaccuracy Complaint Form",
"description":["URL of the ICANN RDDS Inaccuracy Complaint Form: https://www.icann.org/wicf"],
"description":["URL of the ICANN RDDS Inaccuracy Complaint Form: https://icann.org/wicf"],
"links":[
{
"type":"text/html",
"rel":"alternate",
"href":"https://www.icann.org/wicf"
"href":"https://icann.org/wicf"
}
]
}

View File

@@ -144,12 +144,12 @@
},
{
"title": "RDDS Inaccuracy Complaint Form",
"description" : ["URL of the ICANN RDDS Inaccuracy Complaint Form: https://www.icann.org/wicf"],
"description" : ["URL of the ICANN RDDS Inaccuracy Complaint Form: https://icann.org/wicf"],
"links" :
[
{
"rel" : "alternate",
"href" : "https://www.icann.org/wicf",
"href" : "https://icann.org/wicf",
"type" : "text/html"
}
]

View File

@@ -137,7 +137,7 @@
},
{
"objectClassName": "entity",
"handle": "REDACTED FOR PRIVACY",
"handle": "",
"roles": ["administrative"],
"remarks": [
{
@@ -166,31 +166,14 @@
"vcardArray": [
"vcard",
[
["version",{},"text","4.0"],
["fn",{},"text","REDACTED FOR PRIVACY"],
["org",{},"text","REDACTED FOR PRIVACY"],
[
"adr",
{},
"text",
[
"",
"",
"REDACTED FOR PRIVACY",
"REDACTED FOR PRIVACY",
"REDACTED FOR PRIVACY",
"REDACTED FOR PRIVACY",
"XX"
]
],
["tel",{"type":["voice"]},"uri","tel:REDACTED FOR PRIVACY"],
["tel",{"type":["fax"]},"uri","tel:REDACTED FOR PRIVACY"]
["version", {}, "text", "4.0"],
["fn", {}, "text", ""]
]
]
},
{
"objectClassName": "entity",
"handle": "REDACTED FOR PRIVACY",
"handle": "",
"roles": ["technical"],
"remarks": [
{
@@ -219,31 +202,14 @@
"vcardArray": [
"vcard",
[
["version",{},"text","4.0"],
["fn",{},"text","REDACTED FOR PRIVACY"],
["org",{},"text","REDACTED FOR PRIVACY"],
[
"adr",
{},
"text",
[
"",
"",
"REDACTED FOR PRIVACY",
"REDACTED FOR PRIVACY",
"REDACTED FOR PRIVACY",
"REDACTED FOR PRIVACY",
"XX"
]
],
["tel",{"type":["voice"]},"uri","tel:REDACTED FOR PRIVACY"],
["tel",{"type":["fax"]},"uri","tel:REDACTED FOR PRIVACY"]
["version", {}, "text", "4.0"],
["fn", {}, "text", ""]
]
]
},
{
"objectClassName": "entity",
"handle": "REDACTED FOR PRIVACY",
"handle": "",
"roles": ["registrant"],
"remarks": [
{
@@ -272,25 +238,8 @@
"vcardArray": [
"vcard",
[
["version",{},"text","4.0"],
["fn",{},"text","REDACTED FOR PRIVACY"],
["org",{},"text","REDACTED FOR PRIVACY"],
[
"adr",
{},
"text",
[
"",
"",
"REDACTED FOR PRIVACY",
"REDACTED FOR PRIVACY",
"REDACTED FOR PRIVACY",
"REDACTED FOR PRIVACY",
"XX"
]
],
["tel",{"type":["voice"]},"uri","tel:REDACTED FOR PRIVACY"],
["tel",{"type":["fax"]},"uri","tel:REDACTED FOR PRIVACY"]
["version", {}, "text", "4.0"],
["fn", {}, "text", ""]
]
]
}

View File

@@ -1,6 +1,6 @@
{
"objectClassName" : "entity",
"handle" : "REDACTED FOR PRIVACY",
"handle" : "",
"roles" : ["registrant"],
"events": [
{
@@ -11,25 +11,8 @@
"vcardArray": [
"vcard",
[
["version",{},"text","4.0"],
["fn",{},"text","REDACTED FOR PRIVACY"],
["org",{},"text","REDACTED FOR PRIVACY"],
[
"adr",
{},
"text",
[
"",
"",
"REDACTED FOR PRIVACY",
"REDACTED FOR PRIVACY",
"REDACTED FOR PRIVACY",
"REDACTED FOR PRIVACY",
"XX"
]
],
["tel",{"type":["voice"]},"uri","tel:REDACTED FOR PRIVACY"],
["tel",{"type":["fax"]},"uri","tel:REDACTED FOR PRIVACY"]
["version", {}, "text", "4.0"],
["fn", {}, "text", ""]
]
],
"remarks": [

View File

@@ -59,12 +59,12 @@
},
{
"title": "RDDS Inaccuracy Complaint Form",
"description": ["URL of the ICANN RDDS Inaccuracy Complaint Form: https://www.icann.org/wicf"],
"description": ["URL of the ICANN RDDS Inaccuracy Complaint Form: https://icann.org/wicf"],
"links":
[
{
"rel": "alternate",
"href": "https://www.icann.org/wicf",
"href": "https://icann.org/wicf",
"type": "text/html"
}
]