1
0
mirror of https://github.com/google/nomulus synced 2026-06-09 16:33:02 +00:00

Compare commits

...

3 Commits

Author SHA1 Message Date
gbrodman
a5b280838c Remove usages of json-simple (#3060)
We should use gson wherever possible. There's no point in having
unnecessary dependencies (we'll need to keep around jackson for YAML
parsing).
2026-06-01 20:16:32 +00:00
Ben McIlwain
5599a0eb3d Add buildAll task and fix fragile builds (#3077)
This commit adds the buildAll task to restore the existence of a target that builds everything, which was unintentionally removed when the default build was stripped down in PR #3068. It also introduces necessary sequential constraints to the console-webapp build tasks to prevent parallel execution from corrupting the Angular CLI cache. Finally, it addresses paths for the newer Angular esbuild output and hardens the style injection in ConsoleScreenshotTest to prevent fragile test failures.
2026-06-01 19:11:05 +00:00
gbrodman
dde41078cd Forbid SHA-1 digests as part of RFC 9904 changes (#3069)
We can't change digest types that are already in the database but that's
fine (since we just store them as integers). But we forbid them as part
of domain creates/updates.
2026-06-01 17:59:19 +00:00
60 changed files with 533 additions and 249 deletions

View File

@@ -609,3 +609,15 @@ gradle.taskGraph.whenReady { graph ->
}
}
}
task buildAll {
group = 'build'
description = 'Runs the standard build plus all heavy staging/Docker dependencies and fragile tests that were stripped out of the default build for performance.'
dependsOn build
dependsOn ':core:fragileTest'
dependsOn ':core:sqlIntegrationTest'
dependsOn ':core:buildToolImage'
dependsOn ':stage'
dependsOn ':jetty:buildNomulusImage'
dependsOn ':console-webapp:buildConsoleForAll'
}

View File

@@ -74,6 +74,14 @@ def createConsoleTask = { env ->
createConsoleTask(env)
}
// Force an order so we don't run these tasks in parallel.
tasks.buildConsoleForCrash.mustRunAfter(tasks.buildConsoleForAlpha)
tasks.buildConsoleForQa.mustRunAfter(tasks.buildConsoleForCrash)
tasks.buildConsoleForSandbox.mustRunAfter(tasks.buildConsoleForQa)
tasks.buildConsoleForProduction.mustRunAfter(tasks.buildConsoleForSandbox)
// This task must run last, otherwise the previous tasks will have deleted the "dist" folder.
tasks.buildConsoleWebapp.mustRunAfter(tasks.buildConsoleForProduction)
task applyFormatting(type: Exec) {
workingDir "${consoleDir}/"
executable 'npm'

View File

@@ -170,7 +170,6 @@ dependencies {
implementation deps['com.google.oauth-client:google-oauth-client-servlet']
implementation deps['com.google.re2j:re2j']
implementation deps['org.freemarker:freemarker']
implementation deps['com.googlecode.json-simple:json-simple']
implementation deps['com.github.mwiede:jsch']
implementation deps['com.zaxxer:HikariCP']
implementation deps['com.squareup.okhttp3:okhttp']

View File

@@ -192,7 +192,6 @@ com.google.protobuf:protobuf-java:4.33.2=annotationProcessor,nonprodAnnotationPr
com.google.protobuf:protobuf-java:4.35.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.re2j:re2j:1.8=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.truth:truth:1.4.5=deploy_jar,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.googlecode.json-simple:json-simple:1.1.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.ibm.icu:icu4j:73.2=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.lmax:disruptor:3.4.2=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.puppycrawl.tools:checkstyle:10.24.0=checkstyle

View File

@@ -36,13 +36,13 @@ import static google.registry.persistence.PersistenceModule.TransactionIsolation
import static google.registry.persistence.transaction.TransactionManagerFactory.replicaTm;
import static google.registry.pricing.PricingEngineProxy.isDomainPremium;
import static google.registry.util.DomainNameUtils.canonicalizeHostname;
import static org.json.simple.JSONValue.toJSONString;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.flogger.FluentLogger;
import com.google.common.net.InternetDomainName;
import com.google.common.net.MediaType;
import com.google.gson.Gson;
import dagger.Module;
import dagger.Provides;
import google.registry.flows.domain.DomainFlowUtils.BadCommandForRegistryPhaseException;
@@ -83,6 +83,7 @@ public class CheckApiAction implements Runnable {
@Inject Response response;
@Inject CheckApiMetric.Builder metricBuilder;
@Inject CheckApiMetrics checkApiMetrics;
@Inject Gson gson;
@Inject
CheckApiAction() {}
@@ -94,7 +95,7 @@ public class CheckApiAction implements Runnable {
response.setHeader("X-Content-Type-Options", "nosniff");
response.setHeader(ACCESS_CONTROL_ALLOW_ORIGIN, "*");
response.setContentType(MediaType.JSON_UTF_8);
response.setPayload(toJSONString(doCheck()));
response.setPayload(gson.toJson(doCheck()));
} finally {
CheckApiMetric metric = metricBuilder.build();
checkApiMetrics.incrementCheckApiRequest(metric);

View File

@@ -24,6 +24,7 @@ import static java.nio.charset.StandardCharsets.UTF_8;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.ImmutableMap;
import com.google.common.flogger.FluentLogger;
import com.google.gson.Gson;
import google.registry.flows.FlowModule.EppExceptionInProviderException;
import google.registry.model.eppcommon.Trid;
import google.registry.model.eppinput.EppInput;
@@ -34,7 +35,6 @@ import google.registry.model.eppoutput.Result.Code;
import google.registry.monitoring.whitebox.EppMetric;
import jakarta.inject.Inject;
import java.util.Optional;
import org.json.simple.JSONValue;
/**
* An implementation of the EPP command/response protocol.
@@ -50,6 +50,8 @@ public final class EppController {
@Inject EppMetric.Builder eppMetricBuilder;
@Inject EppMetrics eppMetrics;
@Inject ServerTridProvider serverTridProvider;
@Inject Gson gson;
@Inject EppController() {}
/** Reads EPP XML, executes the matching flow, and returns an {@link EppOutput}. */
@@ -72,7 +74,7 @@ public final class EppController {
e.getMessage(),
lazy(
() ->
JSONValue.toJSONString(
gson.toJson(
ImmutableMap.<String, Object>of(
"clientId",
nullToEmpty(sessionMetadata.getRegistrarId()),

View File

@@ -23,6 +23,7 @@ import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Streams;
import com.google.common.flogger.FluentLogger;
import com.google.gson.Gson;
import google.registry.flows.FlowModule.InputXml;
import google.registry.flows.FlowModule.RegistrarId;
import google.registry.flows.annotations.ReportingSpec;
@@ -30,7 +31,6 @@ import google.registry.model.eppcommon.Trid;
import google.registry.model.eppinput.EppInput;
import jakarta.inject.Inject;
import java.util.Optional;
import org.json.simple.JSONValue;
/** Reporter used by {@link FlowRunner} to record flow execution data for reporting. */
public class FlowReporter {
@@ -49,6 +49,8 @@ public class FlowReporter {
@Inject @InputXml byte[] inputXmlBytes;
@Inject EppInput eppInput;
@Inject Class<? extends Flow> flowClass;
@Inject Gson gson;
@Inject FlowReporter() {}
/** Records information about the current flow execution in the request logs. */
@@ -61,7 +63,7 @@ public class FlowReporter {
logger.atInfo().log(
"%s: %s",
METADATA_LOG_SIGNATURE,
JSONValue.toJSONString(
gson.toJson(
new ImmutableMap.Builder<String, Object>()
.put("serverTrid", trid.getServerTransactionId())
.put("clientId", registrarId)

View File

@@ -23,6 +23,7 @@ import static com.google.common.collect.Sets.difference;
import static com.google.common.collect.Sets.intersection;
import static com.google.common.collect.Sets.union;
import static google.registry.bsa.persistence.BsaLabelUtils.isLabelBlocked;
import static google.registry.model.common.FeatureFlag.FeatureName.FORBID_INSECURE_ALGORITHMS_RFC_9904;
import static google.registry.model.domain.Domain.MAX_REGISTRATION_YEARS;
import static google.registry.model.domain.token.AllocationToken.TokenType.REGISTER_BSA;
import static google.registry.model.tld.Tld.TldState.GENERAL_AVAILABILITY;
@@ -73,6 +74,7 @@ import google.registry.model.EppResource;
import google.registry.model.billing.BillingBase.Flag;
import google.registry.model.billing.BillingBase.Reason;
import google.registry.model.billing.BillingRecurrence;
import google.registry.model.common.FeatureFlag;
import google.registry.model.domain.Domain;
import google.registry.model.domain.DomainCommand.Create;
import google.registry.model.domain.DomainCommand.CreateOrUpdate;
@@ -341,7 +343,7 @@ public class DomainFlowUtils {
}
ImmutableList<DomainDsData> invalidAlgorithms =
dsData.stream()
.filter(ds -> !validateAlgorithm(ds.getAlgorithm()))
.filter(ds -> algorithmIsInvalid(ds.getAlgorithm()))
.collect(toImmutableList());
if (!invalidAlgorithms.isEmpty()) {
throw new InvalidDsRecordException(
@@ -349,9 +351,16 @@ public class DomainFlowUtils {
"Domain contains DS record(s) with an invalid algorithm wire value: %s",
invalidAlgorithms));
}
boolean forbidInsecureTypes = FeatureFlag.isActiveNow(FORBID_INSECURE_ALGORITHMS_RFC_9904);
ImmutableList<DomainDsData> invalidDigestTypes =
dsData.stream()
.filter(ds -> DigestType.fromWireValue(ds.getDigestType()).isEmpty())
.filter(
ds -> {
Optional<DigestType> digestType = DigestType.fromWireValue(ds.getDigestType());
return digestType
.map(type -> forbidInsecureTypes && !type.isAllowedInRfc9904())
.orElse(true);
})
.collect(toImmutableList());
if (!invalidDigestTypes.isEmpty()) {
throw new InvalidDsRecordException(
@@ -376,14 +385,14 @@ public class DomainFlowUtils {
}
}
public static boolean validateAlgorithm(int alg) {
public static boolean algorithmIsInvalid(int alg) {
if (alg > 255 || alg < 0) {
return false;
return true;
}
// Algorithms that are reserved or unassigned will just return a string representation of their
// integer wire value.
String algorithm = Algorithm.string(alg);
return !algorithm.equals(Integer.toString(alg));
return algorithm.equals(Integer.toString(alg));
}
/** We only allow specifying years in a period. */

View File

@@ -84,7 +84,10 @@ public class FeatureFlag extends ImmutableObject implements Buildable {
INCLUDE_PENDING_DELETE_DATE_FOR_DOMAINS(FeatureStatus.INACTIVE),
/** If we're prohibiting the inclusion of the contact object URI on login. */
PROHIBIT_CONTACT_OBJECTS_ON_LOGIN(FeatureStatus.INACTIVE);
PROHIBIT_CONTACT_OBJECTS_ON_LOGIN(FeatureStatus.INACTIVE),
/** If we're prohibiting insecure algorithms as detailed by RFC 9904. */
FORBID_INSECURE_ALGORITHMS_RFC_9904(FeatureStatus.INACTIVE);
private final FeatureStatus defaultStatus;

View File

@@ -18,8 +18,8 @@ import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.net.HttpHeaders.CONTENT_DISPOSITION;
import static com.google.common.net.HttpHeaders.X_CONTENT_TYPE_OPTIONS;
import static com.google.common.net.MediaType.JSON_UTF_8;
import static org.json.simple.JSONValue.toJSONString;
import com.google.gson.Gson;
import jakarta.inject.Inject;
import java.time.Instant;
import java.util.Map;
@@ -31,10 +31,12 @@ public class JsonResponse {
public static final String JSON_SAFETY_PREFIX = ")]}'\n";
protected final Response response;
protected final Gson gson;
@Inject
public JsonResponse(Response rsp) {
public JsonResponse(Response rsp, Gson gson) {
this.response = rsp;
this.gson = gson;
}
/**
@@ -55,7 +57,7 @@ public class JsonResponse {
// response, even if all else fails. It's basically another anti-sniffing mechanism in the sense
// that if you hit this url directly, it would try to download the file instead of showing it.
response.setHeader(CONTENT_DISPOSITION, "attachment");
response.setPayload(JSON_SAFETY_PREFIX + toJSONString(checkNotNull(responseMap)));
response.setPayload(JSON_SAFETY_PREFIX + gson.toJson(checkNotNull(responseMap)));
}
/**

View File

@@ -14,6 +14,7 @@
package google.registry.request;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.net.MediaType.JSON_UTF_8;
import static google.registry.dns.PublishDnsUpdatesAction.CLOUD_TASKS_RETRY_HEADER;
import static google.registry.model.tld.Tlds.assertTldExists;
@@ -28,7 +29,6 @@ import static google.registry.request.RequestParameters.extractSetOfParameters;
import static java.nio.charset.StandardCharsets.UTF_8;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.VerifyException;
import com.google.common.collect.ImmutableListMultimap;
import com.google.common.collect.ImmutableSet;
import com.google.common.io.ByteStreams;
@@ -36,6 +36,8 @@ import com.google.common.io.CharStreams;
import com.google.common.net.MediaType;
import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonSyntaxException;
import com.google.gson.reflect.TypeToken;
import com.google.protobuf.ByteString;
import dagger.Module;
import dagger.Provides;
@@ -50,8 +52,6 @@ import jakarta.servlet.http.HttpSession;
import java.io.IOException;
import java.util.Map;
import java.util.Optional;
import org.json.simple.JSONValue;
import org.json.simple.parser.ParseException;
/** Dagger module for servlets. */
@Module
@@ -202,18 +202,16 @@ public final class RequestModule {
@Provides
@JsonPayload
@SuppressWarnings("unchecked")
static Map<String, Object> provideJsonPayload(
@Header("Content-Type") MediaType contentType, @Payload String payload) {
@Header("Content-Type") MediaType contentType, @Payload String payload, Gson gson) {
if (!JSON_UTF_8.is(contentType.withCharset(UTF_8))) {
throw new UnsupportedMediaTypeException(
String.format("Expected %s Content-Type", JSON_UTF_8.withoutParameters()));
}
try {
return (Map<String, Object>) JSONValue.parseWithException(payload);
} catch (ParseException e) {
throw new BadRequestException(
"Malformed JSON", new VerifyException("Malformed JSON:\n" + payload, e));
return checkNotNull(gson.fromJson(payload, new TypeToken<>() {}));
} catch (JsonSyntaxException | NullPointerException e) {
throw new BadRequestException("Malformed JSON:\n" + payload);
}
}

View File

@@ -18,10 +18,13 @@ import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.net.HttpHeaders.CONTENT_DISPOSITION;
import static com.google.common.net.HttpHeaders.X_CONTENT_TYPE_OPTIONS;
import static com.google.common.net.MediaType.JSON_UTF_8;
import static org.json.simple.JSONValue.writeJSONString;
import com.google.common.flogger.FluentLogger;
import com.google.common.net.MediaType;
import com.google.gson.Gson;
import com.google.gson.JsonSyntaxException;
import com.google.gson.reflect.TypeToken;
import google.registry.tools.GsonUtils;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
@@ -29,8 +32,6 @@ import java.io.Reader;
import java.io.Writer;
import java.util.Map;
import javax.annotation.Nullable;
import org.json.simple.JSONValue;
import org.json.simple.parser.ParseException;
/**
* Helper class for servlets that read or write JSON.
@@ -41,6 +42,8 @@ public final class JsonHttp {
private static final FluentLogger logger = FluentLogger.forEnclosingClass();
private static final Gson GSON = GsonUtils.provideGson();
/** String prefixed to all JSON-like responses. */
public static final String JSON_SAFETY_PREFIX = ")]}'\n";
@@ -51,7 +54,6 @@ public final class JsonHttp {
* @throws IOException if we failed to read from {@code req}.
*/
@Nullable
@SuppressWarnings("unchecked")
public static Map<String, ?> read(HttpServletRequest req) throws IOException {
if (!"POST".equals(req.getMethod())
&& !"PUT".equals(req.getMethod())) {
@@ -64,8 +66,8 @@ public final class JsonHttp {
}
try (Reader jsonReader = req.getReader()) {
try {
return checkNotNull((Map<String, ?>) JSONValue.parseWithException(jsonReader));
} catch (ParseException | NullPointerException | ClassCastException e) {
return checkNotNull(GSON.fromJson(jsonReader, new TypeToken<>() {}));
} catch (JsonSyntaxException | NullPointerException | ClassCastException e) {
logger.atWarning().withCause(e).log("Malformed JSON.");
return null;
}
@@ -88,7 +90,7 @@ public final class JsonHttp {
rsp.setHeader(CONTENT_DISPOSITION, "attachment");
try (Writer writer = rsp.getWriter()) {
writer.write(JSON_SAFETY_PREFIX);
writeJSONString(jsonObject, writer);
GSON.toJson(jsonObject, writer);
}
}
}

View File

@@ -29,21 +29,26 @@ import java.util.Optional;
* https://www.iana.org/assignments/ds-rr-types/ds-rr-types.xhtml
*/
public enum DigestType {
SHA1(1, 20),
SHA256(2, 32),
// Algorithm number 1 is SHA-1 and will be is deliberately NOT SUPPORTED.
// RFC 9904 specifies that this algorithm MUST NOT be used for DNSSEC delegations.
// This prohibition is gated behind a feature flag.
SHA1(1, 20, false),
SHA256(2, 32, true),
// Algorithm number 3 is GOST R 34.11-94 and is deliberately NOT SUPPORTED.
// This algorithm was reviewed by ise-crypto and deemed academically broken (b/207029800).
// In addition, RFC 8624 specifies that this algorithm MUST NOT be used for DNSSEC delegations.
// TODO(sarhabot@): Add note in Cloud DNS code to notify the Registry of any new changes to
// supported digest types.
SHA384(4, 48);
SHA384(4, 48, true);
private final int wireValue;
private final int bytes;
private final boolean allowedInRfc9904;
DigestType(int wireValue, int bytes) {
DigestType(int wireValue, int bytes, boolean allowedInRfc9904) {
this.wireValue = wireValue;
this.bytes = bytes;
this.allowedInRfc9904 = allowedInRfc9904;
}
private static final ImmutableMap<Integer, DigestType> WIRE_VALUE_TO_DIGEST_TYPE =
@@ -63,4 +68,9 @@ public enum DigestType {
public int getBytes() {
return bytes;
}
/** Whether this digest type is supported as of RFC 9904. */
public boolean isAllowedInRfc9904() {
return allowedInRfc9904;
}
}

View File

@@ -46,7 +46,7 @@ record DsRecord(int keyTag, int alg, int digestType, String digest) {
String.format("DS record has an invalid digest length: %s", digest));
}
if (!DomainFlowUtils.validateAlgorithm(alg)) {
if (DomainFlowUtils.algorithmIsInvalid(alg)) {
throw new IllegalArgumentException(
String.format("DS record uses an unrecognized algorithm: %d", alg));
}

View File

@@ -25,6 +25,7 @@ import com.beust.jcommander.Parameter;
import com.beust.jcommander.Parameters;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.gson.Gson;
import google.registry.model.domain.Domain;
import google.registry.model.host.Host;
import google.registry.persistence.transaction.QueryComposer.Comparator;
@@ -38,7 +39,6 @@ import java.nio.file.Paths;
import java.time.Instant;
import java.util.List;
import java.util.Map;
import org.json.simple.JSONValue;
/** Command to generate a report of all DNS data. */
@Parameters(separators = " =", commandDescription = "Generate report of all DNS data in a TLD.")
@@ -57,6 +57,7 @@ final class GenerateDnsReportCommand implements Command {
private Path output = Paths.get("/dev/stdout");
@Inject Clock clock;
@Inject Gson gson;
@Override
public void run() throws Exception {
@@ -144,7 +145,7 @@ final class GenerateDnsReportCommand implements Command {
} else {
result.append(",\n");
}
result.append(JSONValue.toJSONString(map));
result.append(gson.toJson(map));
}
}
}

View File

@@ -16,6 +16,7 @@ package google.registry.tools;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.ToNumberPolicy;
import com.google.gson.TypeAdapter;
import com.google.gson.TypeAdapterFactory;
import com.google.gson.reflect.TypeToken;
@@ -82,6 +83,7 @@ public class GsonUtils {
.registerTypeAdapter(Serializable.class, new SerializableJsonTypeAdapter())
.registerTypeAdapterFactory(new ClassProcessingTypeAdapterFactory())
.registerTypeAdapterFactory(new GsonPostProcessableTypeAdapterFactory())
.setObjectToNumberStrategy(ToNumberPolicy.LONG_OR_DOUBLE)
.excludeFieldsWithoutExposeAnnotation()
.create();
}

View File

@@ -23,10 +23,13 @@ import com.beust.jcommander.Parameter;
import com.google.common.base.VerifyException;
import com.google.common.collect.ImmutableMap;
import com.google.common.net.MediaType;
import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonParser;
import com.google.gson.reflect.TypeToken;
import java.util.List;
import java.util.Map;
import javax.annotation.Nullable;
import org.json.simple.JSONValue;
/**
* Abstract base class for commands that list objects by calling a server task.
@@ -35,6 +38,8 @@ import org.json.simple.JSONValue;
*/
abstract class ListObjectsCommand implements CommandWithConnection {
private static final Gson GSON = GsonUtils.provideGson();
@Nullable
@Parameter(
names = {"-f", "--fields"},
@@ -87,14 +92,13 @@ abstract class ListObjectsCommand implements CommandWithConnection {
connection.sendPostRequest(
getCommandPath(), params.build(), MediaType.PLAIN_TEXT_UTF_8, new byte[0]);
// Parse the returned JSON and make sure it's a map.
Object obj = JSONValue.parse(response.substring(JSON_SAFETY_PREFIX.length()));
if (!(obj instanceof Map<?, ?>)) {
JsonElement element = JsonParser.parseString(response.substring(JSON_SAFETY_PREFIX.length()));
if (!element.isJsonObject()) {
throw new VerifyException("Server returned unexpected JSON: " + response);
}
@SuppressWarnings("unchecked")
Map<String, Object> responseMap = (Map<String, Object>) obj;
Map<String, Object> responseMap = GSON.fromJson(element, new TypeToken<>() {});
// Get the status.
obj = responseMap.get("status");
Object obj = responseMap.get("status");
if (obj == null) {
throw new VerifyException("Server returned no status");
}

View File

@@ -34,6 +34,8 @@ import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.io.CharStreams;
import com.google.common.net.MediaType;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import google.registry.config.RegistryConfig.Config;
import google.registry.request.Action.Service;
import jakarta.inject.Inject;
@@ -42,7 +44,6 @@ import java.io.InputStreamReader;
import java.net.URL;
import java.util.Map;
import javax.annotation.Nullable;
import org.json.simple.JSONValue;
/**
* An HTTP connection to a service.
@@ -55,23 +56,25 @@ public class ServiceConnection {
private final Service service;
private final boolean useCanary;
private final HttpRequestFactory requestFactory;
private final Gson gson;
@Inject
ServiceConnection(
@Config("useCanary") boolean useCanary,
HttpRequestFactory requestFactory) {
this(Service.BACKEND, requestFactory, useCanary);
@Config("useCanary") boolean useCanary, HttpRequestFactory requestFactory, Gson gson) {
this(Service.BACKEND, requestFactory, useCanary, gson);
}
private ServiceConnection(Service service, HttpRequestFactory requestFactory, boolean useCanary) {
private ServiceConnection(
Service service, HttpRequestFactory requestFactory, boolean useCanary, Gson gson) {
this.service = service;
this.requestFactory = requestFactory;
this.useCanary = useCanary;
this.gson = gson;
}
/** Returns a copy of this connection that talks to a different service endpoint. */
public ServiceConnection withService(Service service, boolean useCanary) {
return new ServiceConnection(service, requestFactory, useCanary);
return new ServiceConnection(service, requestFactory, useCanary, gson);
}
/** Returns the HTML from the connection error stream, if any, otherwise the empty string. */
@@ -99,7 +102,7 @@ public class ServiceConnection {
request.setFollowRedirects(false);
request.setThrowExceptionOnExecuteError(false);
request.setUnsuccessfulResponseHandler(
(request1, response, supportsRetry) -> {
(request1, response, _) -> {
String error = getErrorHtmlAsString(response);
throw new IOException(
String.format(
@@ -137,14 +140,10 @@ public class ServiceConnection {
return internalSend(endpoint, params, MediaType.PLAIN_TEXT_UTF_8, null);
}
@SuppressWarnings("unchecked")
public Map<String, Object> sendJson(String endpoint, Map<String, ?> object) throws IOException {
String response =
sendPostRequest(
endpoint,
ImmutableMap.of(),
JSON_UTF_8,
JSONValue.toJSONString(object).getBytes(UTF_8));
return (Map<String, Object>) JSONValue.parse(response.substring(JSON_SAFETY_PREFIX.length()));
endpoint, ImmutableMap.of(), JSON_UTF_8, gson.toJson(object).getBytes(UTF_8));
return gson.fromJson(response.substring(JSON_SAFETY_PREFIX.length()), new TypeToken<>() {});
}
}

View File

@@ -29,6 +29,7 @@ import static google.registry.testing.DatabaseHelper.persistResource;
import static google.registry.util.DateTimeUtils.START_INSTANT;
import static org.mockito.Mockito.verify;
import com.google.gson.reflect.TypeToken;
import google.registry.bsa.persistence.BsaTestingUtils;
import google.registry.model.tld.Tld;
import google.registry.monitoring.whitebox.CheckApiMetric;
@@ -39,10 +40,10 @@ import google.registry.persistence.transaction.JpaTestExtensions;
import google.registry.persistence.transaction.JpaTestExtensions.JpaIntegrationTestExtension;
import google.registry.testing.FakeClock;
import google.registry.testing.FakeResponse;
import google.registry.tools.GsonUtils;
import java.time.Instant;
import java.util.Map;
import java.util.Optional;
import org.json.simple.JSONValue;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
@@ -83,9 +84,9 @@ class CheckApiActionTest {
.build());
}
@SuppressWarnings("unchecked")
private Map<String, Object> getCheckResponse(String domain) {
CheckApiAction action = new CheckApiAction();
action.gson = GsonUtils.provideGson();
action.domain = domain;
action.response = new FakeResponse();
action.metricBuilder = CheckApiMetric.builder(fakeClock);
@@ -94,7 +95,8 @@ class CheckApiActionTest {
endTime = fakeClock.now();
action.run();
return (Map<String, Object>) JSONValue.parse(((FakeResponse) action.response).getPayload());
return action.gson.fromJson(
((FakeResponse) action.response).getPayload(), new TypeToken<>() {});
}
@Test

View File

@@ -31,6 +31,8 @@ import static org.mockito.Mockito.when;
import com.google.common.base.Splitter;
import com.google.common.testing.TestLogHandler;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import google.registry.flows.EppException.UnimplementedExtensionException;
import google.registry.flows.EppTestComponent.FakeServerTridProvider;
import google.registry.flows.FlowModule.EppExceptionInProviderException;
@@ -43,6 +45,7 @@ import google.registry.monitoring.whitebox.EppMetric;
import google.registry.persistence.transaction.JpaTestExtensions;
import google.registry.persistence.transaction.JpaTestExtensions.JpaIntegrationTestExtension;
import google.registry.testing.FakeClock;
import google.registry.tools.GsonUtils;
import google.registry.util.Clock;
import google.registry.xml.ValidationMode;
import java.time.Instant;
@@ -50,7 +53,6 @@ import java.util.List;
import java.util.Map;
import java.util.logging.LogRecord;
import java.util.logging.Logger;
import org.json.simple.JSONValue;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@@ -82,6 +84,7 @@ class EppControllerTest {
@Mock Result result;
private static final Instant START_TIME = Instant.parse("2016-09-01T00:00:00Z");
private static final Gson GSON = GsonUtils.provideGson();
private final Clock clock = new FakeClock(START_TIME);
private final TestLogHandler logHandler = new TestLogHandler();
@@ -110,6 +113,7 @@ class EppControllerTest {
when(result.getCode()).thenReturn(Code.SUCCESS_WITH_NO_MESSAGES);
eppController = new EppController();
eppController.gson = GSON;
eppController.eppMetricBuilder = EppMetric.builderForRequest(clock);
when(flowRunner.run(eppController.eppMetricBuilder)).thenReturn(eppOutput);
eppController.flowComponentBuilder = flowComponentBuilder;
@@ -247,8 +251,7 @@ class EppControllerTest {
assertThat(logRecord.getThrown()).isInstanceOf(IllegalStateException.class);
}
@SuppressWarnings("unchecked")
private static Map<String, Object> parseJsonMap(String json) throws Exception {
return (Map<String, Object>) JSONValue.parseWithException(json);
return GSON.fromJson(json, new TypeToken<>() {});
}
}

View File

@@ -28,6 +28,7 @@ import google.registry.flows.custom.TestCustomLogicFactory;
import google.registry.flows.domain.DomainDeletionTimeCache;
import google.registry.flows.domain.DomainFlowTmchUtils;
import google.registry.monitoring.whitebox.EppMetric;
import google.registry.request.Modules.GsonModule;
import google.registry.request.RequestScope;
import google.registry.request.lock.LockHandler;
import google.registry.testing.CloudTasksHelper;
@@ -42,7 +43,8 @@ import jakarta.inject.Singleton;
/** Dagger component for running EPP tests. */
@Singleton
@Component(modules = {ConfigModule.class, EppTestComponent.FakesAndMocksModule.class})
@Component(
modules = {ConfigModule.class, GsonModule.class, EppTestComponent.FakesAndMocksModule.class})
public interface EppTestComponent {
RequestComponent startRequest();

View File

@@ -22,22 +22,26 @@ import static org.mockito.Mockito.when;
import com.google.common.collect.ImmutableList;
import com.google.common.testing.TestLogHandler;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import google.registry.flows.annotations.ReportingSpec;
import google.registry.model.eppcommon.Trid;
import google.registry.model.eppinput.EppInput;
import google.registry.model.eppoutput.EppOutput.ResponseOrGreeting;
import google.registry.model.eppoutput.EppResponse;
import google.registry.model.reporting.IcannReportingTypes.ActivityReportField;
import google.registry.tools.GsonUtils;
import google.registry.util.JdkLoggerConfig;
import java.util.Map;
import java.util.Optional;
import org.json.simple.JSONValue;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
/** Unit tests for {@link FlowReporter}. */
class FlowReporterTest {
private static final Gson GSON = GsonUtils.provideGson();
static class TestCommandFlow implements Flow {
@Override
public ResponseOrGreeting run() {
@@ -60,6 +64,7 @@ class FlowReporterTest {
void beforeEach() {
JdkLoggerConfig.getConfig(FlowReporter.class).addHandler(handler);
flowReporter.trid = Trid.create("client-123", "server-456");
flowReporter.gson = GSON;
flowReporter.registrarId = "TheRegistrar";
flowReporter.inputXmlBytes = "<xml/>".getBytes(UTF_8);
flowReporter.flowClass = TestCommandFlow.class;
@@ -205,8 +210,7 @@ class FlowReporterTest {
assertThat(json).containsEntry("tlds", ImmutableList.of());
}
@SuppressWarnings("unchecked")
private static Map<String, Object> parseJsonMap(String json) throws Exception {
return (Map<String, Object>) JSONValue.parseWithException(json);
return GSON.fromJson(json, new TypeToken<>() {});
}
}

View File

@@ -22,6 +22,7 @@ import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;
import com.google.common.testing.TestLogHandler;
import com.google.gson.Gson;
import google.registry.model.EppResource;
import google.registry.model.ForeignKeyUtils;
import google.registry.model.domain.DomainBase;
@@ -34,13 +35,13 @@ import google.registry.model.tmch.ClaimsList;
import google.registry.model.tmch.ClaimsListDao;
import google.registry.testing.DatabaseHelper;
import google.registry.testing.TestCacheExtension;
import google.registry.tools.GsonUtils;
import google.registry.util.JdkLoggerConfig;
import google.registry.util.TypeUtils.TypeInstantiator;
import java.time.Duration;
import java.time.Instant;
import java.util.logging.Level;
import javax.annotation.Nullable;
import org.json.simple.JSONValue;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.extension.RegisterExtension;
@@ -53,6 +54,8 @@ import org.junit.jupiter.api.extension.RegisterExtension;
public abstract class ResourceFlowTestCase<F extends Flow, R extends EppResource>
extends FlowTestCase<F> {
private static final Gson GSON = GsonUtils.provideGson();
protected final TestLogHandler logHandler = new TestLogHandler();
@RegisterExtension
@@ -108,21 +111,23 @@ public abstract class ResourceFlowTestCase<F extends Flow, R extends EppResource
.that(logHandler)
.hasLogAtLevelWithMessage(Level.INFO, "FLOW-LOG-SIGNATURE-METADATA")
.which()
.contains("\"clientId\":" + JSONValue.toJSONString(registrarId));
.contains("\"clientId\":" + GSON.toJson(registrarId));
}
protected void assertTldsFieldLogged(String... tlds) {
assertAboutLogs().that(logHandler)
assertAboutLogs()
.that(logHandler)
.hasLogAtLevelWithMessage(Level.INFO, "FLOW-LOG-SIGNATURE-METADATA")
.which()
.contains("\"tlds\":" + JSONValue.toJSONString(ImmutableList.copyOf(tlds)));
.contains("\"tlds\":" + GSON.toJson(ImmutableList.copyOf(tlds)));
}
protected void assertIcannReportingActivityFieldLogged(String fieldName) {
assertAboutLogs().that(logHandler)
assertAboutLogs()
.that(logHandler)
.hasLogAtLevelWithMessage(Level.INFO, "FLOW-LOG-SIGNATURE-METADATA")
.which()
.contains("\"icannActivityReportField\":" + JSONValue.toJSONString(fieldName));
.contains("\"icannActivityReportField\":" + GSON.toJson(fieldName));
}
protected void assertLastHistoryContainsResource(EppResource resource) {

View File

@@ -24,6 +24,7 @@ import static google.registry.model.billing.BillingBase.Flag.RESERVED;
import static google.registry.model.billing.BillingBase.Flag.SUNRISE;
import static google.registry.model.billing.BillingBase.RenewalPriceBehavior.NONPREMIUM;
import static google.registry.model.billing.BillingBase.RenewalPriceBehavior.SPECIFIED;
import static google.registry.model.common.FeatureFlag.FeatureName.FORBID_INSECURE_ALGORITHMS_RFC_9904;
import static google.registry.model.domain.fee.Fee.FEE_EXTENSION_URIS;
import static google.registry.model.domain.token.AllocationToken.TokenType.BULK_PRICING;
import static google.registry.model.domain.token.AllocationToken.TokenType.DEFAULT_PROMO;
@@ -150,6 +151,8 @@ import google.registry.model.billing.BillingBase.Reason;
import google.registry.model.billing.BillingBase.RenewalPriceBehavior;
import google.registry.model.billing.BillingEvent;
import google.registry.model.billing.BillingRecurrence;
import google.registry.model.common.FeatureFlag;
import google.registry.model.common.FeatureFlag.FeatureStatus;
import google.registry.model.domain.Domain;
import google.registry.model.domain.DomainHistory;
import google.registry.model.domain.GracePeriod;
@@ -794,7 +797,11 @@ class DomainCreateFlowTest extends ResourceFlowTestCase<DomainCreateFlow, Domain
.that(domain)
.hasExactlyDsData(
DomainDsData.create(
12345, 3, 1, base16().decode("A94A8FE5CCB19BA61C4C0873D391E987982FBBD3"))
12345,
3,
2,
base16()
.decode("D4B7D520E7BB5F0F67674A0CCEB1E3E0614B93C4F9E99B8383F6A1E4469DA50A"))
.cloneWithDomainRepoId(domain.getRepoId()));
}
@@ -957,6 +964,38 @@ class DomainCreateFlowTest extends ResourceFlowTestCase<DomainCreateFlow, Domain
assertAboutEppExceptions().that(thrown).marshalsToXml();
}
@Test
void testFailure_secDnsSha1DigestType() throws Exception {
setEppInput("domain_create_dsdata_sha1.xml");
persistHosts();
DatabaseHelper.persistResource(
new FeatureFlag.Builder()
.setFeatureName(FORBID_INSECURE_ALGORITHMS_RFC_9904)
.setStatusMap(ImmutableSortedMap.of(START_INSTANT, FeatureStatus.ACTIVE))
.build());
EppException thrown = assertThrows(InvalidDsRecordException.class, this::runFlow);
assertAboutEppExceptions().that(thrown).marshalsToXml();
}
@Test
void testSuccess_secDnsSha1_flagInactive() throws Exception {
setEppInput("domain_create_dsdata_sha1.xml");
persistHosts();
DatabaseHelper.persistResource(
new FeatureFlag.Builder()
.setFeatureName(FORBID_INSECURE_ALGORITHMS_RFC_9904)
.setStatusMap(ImmutableSortedMap.of(START_INSTANT, FeatureStatus.INACTIVE))
.build());
doSuccessfulTest("tld");
Domain domain = reloadResourceByForeignKey();
assertAboutDomains()
.that(domain)
.hasExactlyDsData(
DomainDsData.create(
12345, 3, 1, base16().decode("49FD46E6C4B45C55D4AC49FD46E6C4B45C55D4AC"))
.cloneWithDomainRepoId(domain.getRepoId()));
}
@Test
void testFailure_secDnsInvalidAlgorithm() throws Exception {
setEppInput("domain_create_dsdata_bad_algorithms.xml");

View File

@@ -19,6 +19,7 @@ import static com.google.common.collect.Sets.union;
import static com.google.common.io.BaseEncoding.base16;
import static com.google.common.truth.Truth.assertThat;
import static google.registry.model.ForeignKeyUtils.loadResource;
import static google.registry.model.common.FeatureFlag.FeatureName.FORBID_INSECURE_ALGORITHMS_RFC_9904;
import static google.registry.model.eppcommon.StatusValue.CLIENT_DELETE_PROHIBITED;
import static google.registry.model.eppcommon.StatusValue.CLIENT_HOLD;
import static google.registry.model.eppcommon.StatusValue.CLIENT_RENEW_PROHIBITED;
@@ -94,6 +95,8 @@ import google.registry.flows.exceptions.ResourceStatusProhibitsOperationExceptio
import google.registry.model.ImmutableObject;
import google.registry.model.billing.BillingBase.Reason;
import google.registry.model.billing.BillingEvent;
import google.registry.model.common.FeatureFlag;
import google.registry.model.common.FeatureFlag.FeatureStatus;
import google.registry.model.domain.Domain;
import google.registry.model.domain.DomainAuthInfo;
import google.registry.model.domain.DomainHistory;
@@ -115,6 +118,9 @@ import org.junit.jupiter.api.Test;
/** Unit tests for {@link DomainUpdateFlow}. */
class DomainUpdateFlowTest extends ResourceFlowTestCase<DomainUpdateFlow, Domain> {
private static final String SHA_256_DIGEST =
"D4B7D520E7BB5F0F67674A0CCEB1E3E0614B93C4F9E99B8383F6A1E4469DA50A";
private static final DomainDsData SOME_DSDATA =
DomainDsData.create(
1,
@@ -125,8 +131,8 @@ class DomainUpdateFlowTest extends ResourceFlowTestCase<DomainUpdateFlow, Domain
ImmutableMap.of(
"KEY_TAG", "12346",
"ALG", "3",
"DIGEST_TYPE", "1",
"DIGEST", "A94A8FE5CCB19BA61C4C0873D391E987982FBBD3");
"DIGEST_TYPE", "2",
"DIGEST", SHA_256_DIGEST);
@BeforeEach
void beforeEach() {
@@ -453,18 +459,9 @@ class DomainUpdateFlowTest extends ResourceFlowTestCase<DomainUpdateFlow, Domain
doSecDnsSuccessfulTest(
"domain_update_dsdata_add.xml",
null,
ImmutableSet.of(
DomainDsData.create(
12346, 3, 1, base16().decode("A94A8FE5CCB19BA61C4C0873D391E987982FBBD3"))),
ImmutableSet.of(DomainDsData.create(12346, 3, 2, base16().decode(SHA_256_DIGEST))),
ImmutableMap.of(
"KEY_TAG",
"12346",
"ALG",
"3",
"DIGEST_TYPE",
"1",
"DIGEST",
"A94A8FE5CCB19BA61C4C0873D391E987982FBBD3"),
"KEY_TAG", "12346", "ALG", "3", "DIGEST_TYPE", "2", "DIGEST", SHA_256_DIGEST),
true);
}
@@ -474,18 +471,9 @@ class DomainUpdateFlowTest extends ResourceFlowTestCase<DomainUpdateFlow, Domain
"domain_update_dsdata_add.xml",
ImmutableSet.of(SOME_DSDATA),
ImmutableSet.of(
SOME_DSDATA,
DomainDsData.create(
12346, 3, 1, base16().decode("A94A8FE5CCB19BA61C4C0873D391E987982FBBD3"))),
SOME_DSDATA, DomainDsData.create(12346, 3, 2, base16().decode(SHA_256_DIGEST))),
ImmutableMap.of(
"KEY_TAG",
"12346",
"ALG",
"3",
"DIGEST_TYPE",
"1",
"DIGEST",
"A94A8FE5CCB19BA61C4C0873D391E987982FBBD3"),
"KEY_TAG", "12346", "ALG", "3", "DIGEST_TYPE", "2", "DIGEST", SHA_256_DIGEST),
true);
}
@@ -660,11 +648,7 @@ class DomainUpdateFlowTest extends ResourceFlowTestCase<DomainUpdateFlow, Domain
union(
commonDsData,
ImmutableSet.of(
DomainDsData.create(
12346,
3,
1,
base16().decode("A94A8FE5CCB19BA61C4C0873D391E987982FBBD3"))))),
DomainDsData.create(12346, 3, 2, base16().decode(SHA_256_DIGEST))))),
true);
}
@@ -673,9 +657,7 @@ class DomainUpdateFlowTest extends ResourceFlowTestCase<DomainUpdateFlow, Domain
doSecDnsSuccessfulTest(
"domain_update_dsdata_rem.xml",
ImmutableSet.of(
SOME_DSDATA,
DomainDsData.create(
12346, 3, 1, base16().decode("A94A8FE5CCB19BA61C4C0873D391E987982FBBD3"))),
SOME_DSDATA, DomainDsData.create(12346, 3, 2, base16().decode(SHA_256_DIGEST))),
ImmutableSet.of(SOME_DSDATA),
true);
}
@@ -686,9 +668,7 @@ class DomainUpdateFlowTest extends ResourceFlowTestCase<DomainUpdateFlow, Domain
doSecDnsSuccessfulTest(
"domain_update_dsdata_rem_all.xml",
ImmutableSet.of(
SOME_DSDATA,
DomainDsData.create(
12346, 3, 1, base16().decode("A94A8FE5CCB19BA61C4C0873D391E987982FBBD3"))),
SOME_DSDATA, DomainDsData.create(12346, 3, 2, base16().decode(SHA_256_DIGEST))),
ImmutableSet.of(),
true);
}
@@ -698,13 +678,9 @@ class DomainUpdateFlowTest extends ResourceFlowTestCase<DomainUpdateFlow, Domain
doSecDnsSuccessfulTest(
"domain_update_dsdata_add_rem.xml",
ImmutableSet.of(
SOME_DSDATA,
DomainDsData.create(
12345, 3, 1, base16().decode("A94A8FE5CCB19BA61C4C0873D391E987982FBBD3"))),
SOME_DSDATA, DomainDsData.create(12345, 3, 2, base16().decode(SHA_256_DIGEST))),
ImmutableSet.of(
SOME_DSDATA,
DomainDsData.create(
12346, 3, 1, base16().decode("A94A8FE5CCB19BA61C4C0873D391E987982FBBD3"))),
SOME_DSDATA, DomainDsData.create(12346, 3, 2, base16().decode(SHA_256_DIGEST))),
true);
}
@@ -727,20 +703,12 @@ class DomainUpdateFlowTest extends ResourceFlowTestCase<DomainUpdateFlow, Domain
union(
commonDsData,
ImmutableSet.of(
DomainDsData.create(
12345,
3,
1,
base16().decode("A94A8FE5CCB19BA61C4C0873D391E987982FBBD3"))))),
DomainDsData.create(12345, 3, 2, base16().decode(SHA_256_DIGEST))))),
ImmutableSet.copyOf(
union(
commonDsData,
ImmutableSet.of(
DomainDsData.create(
12346,
3,
1,
base16().decode("A94A8FE5CCB19BA61C4C0873D391E987982FBBD3"))))),
DomainDsData.create(12346, 3, 2, base16().decode(SHA_256_DIGEST))))),
true);
}
@@ -915,6 +883,49 @@ class DomainUpdateFlowTest extends ResourceFlowTestCase<DomainUpdateFlow, Domain
assertAboutEppExceptions().that(thrown).marshalsToXml();
}
@Test
void testFailure_secDnsSha1DigestType() throws Exception {
setEppInput(
"domain_update_dsdata_add.xml",
ImmutableMap.of(
"KEY_TAG", "12346",
"ALG", "3",
"DIGEST_TYPE", "1",
"DIGEST", "A94A8FE5CCB19BA61C4C0873D391E987982FBBD3"));
persistResource(DatabaseHelper.newDomain(getUniqueIdFromCommand()));
DatabaseHelper.persistResource(
new FeatureFlag.Builder()
.setFeatureName(FORBID_INSECURE_ALGORITHMS_RFC_9904)
.setStatusMap(ImmutableSortedMap.of(START_INSTANT, FeatureStatus.ACTIVE))
.build());
EppException thrown = assertThrows(InvalidDsRecordException.class, this::runFlow);
assertAboutEppExceptions().that(thrown).marshalsToXml();
}
@Test
void testSuccess_secDnsSha1_flagInactive() throws Exception {
setEppInput(
"domain_update_dsdata_add.xml",
ImmutableMap.of(
"KEY_TAG", "12346",
"ALG", "3",
"DIGEST_TYPE", "1",
"DIGEST", "A94A8FE5CCB19BA61C4C0873D391E987982FBBD3"));
persistResource(DatabaseHelper.newDomain(getUniqueIdFromCommand()));
DatabaseHelper.persistResource(
new FeatureFlag.Builder()
.setFeatureName(FORBID_INSECURE_ALGORITHMS_RFC_9904)
.setStatusMap(ImmutableSortedMap.of(START_INSTANT, FeatureStatus.INACTIVE))
.build());
runFlow();
Domain domain = reloadResourceByForeignKey();
assertAboutDomains()
.that(domain)
.hasExactlyDsData(
DomainDsData.create(
12346, 3, 1, base16().decode("A94A8FE5CCB19BA61C4C0873D391E987982FBBD3")));
}
@Test
void testFailure_secDnsMultipleInvalidDigestTypes() throws Exception {
setEppInput("domain_update_dsdata_add.xml", OTHER_DSDATA_TEMPLATE_MAP);
@@ -938,7 +949,7 @@ class DomainUpdateFlowTest extends ResourceFlowTestCase<DomainUpdateFlow, Domain
persistResource(
DatabaseHelper.newDomain(getUniqueIdFromCommand())
.asBuilder()
.setDsData(ImmutableSet.of(DomainDsData.create(1, 2, 1, new byte[] {0, 1, 2})))
.setDsData(ImmutableSet.of(DomainDsData.create(1, 2, 2, new byte[] {0, 1, 2})))
.build());
EppException thrown = assertThrows(InvalidDsRecordException.class, this::runFlow);
assertAboutEppExceptions().that(thrown).marshalsToXml();
@@ -955,7 +966,7 @@ class DomainUpdateFlowTest extends ResourceFlowTestCase<DomainUpdateFlow, Domain
.asBuilder()
.setDsData(
ImmutableSet.of(
DomainDsData.create(1, 2, 1, new byte[] {0, 1, 2, 3, 4}),
DomainDsData.create(1, 2, 2, new byte[] {0, 1, 2, 3, 4}),
DomainDsData.create(2, 2, 2, new byte[] {5, 6, 7})))
.build());
EppException thrown = assertThrows(InvalidDsRecordException.class, this::runFlow);

View File

@@ -18,17 +18,21 @@ import static com.google.common.truth.Truth.assertThat;
import static google.registry.request.JsonResponse.JSON_SAFETY_PREFIX;
import com.google.common.collect.ImmutableMap;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import google.registry.testing.FakeResponse;
import google.registry.tools.GsonUtils;
import java.time.Instant;
import java.util.Map;
import org.json.simple.JSONValue;
import org.junit.jupiter.api.Test;
/** Unit tests for {@link JsonResponse}. */
class JsonResponseTest {
private static final Gson GSON = GsonUtils.provideGson();
private FakeResponse fakeResponse = new FakeResponse();
private JsonResponse jsonResponse = new JsonResponse(fakeResponse);
private JsonResponse jsonResponse = new JsonResponse(fakeResponse, GSON);
@Test
void testSetStatus() {
@@ -44,9 +48,8 @@ class JsonResponseTest {
jsonResponse.setPayload(responseValues);
String payload = fakeResponse.getPayload();
assertThat(payload).startsWith(JSON_SAFETY_PREFIX);
@SuppressWarnings("unchecked")
Map<String, Object> responseMap = (Map<String, Object>)
JSONValue.parse(payload.substring(JSON_SAFETY_PREFIX.length()));
Map<String, Object> responseMap =
GSON.fromJson(payload.substring(JSON_SAFETY_PREFIX.length()), new TypeToken<>() {});
assertThat(responseMap).containsExactlyEntriesIn(responseValues);
}

View File

@@ -19,21 +19,26 @@ import static google.registry.request.RequestModule.provideJsonPayload;
import static org.junit.jupiter.api.Assertions.assertThrows;
import com.google.common.net.MediaType;
import com.google.gson.Gson;
import google.registry.request.HttpException.BadRequestException;
import google.registry.request.HttpException.UnsupportedMediaTypeException;
import google.registry.tools.GsonUtils;
import org.junit.jupiter.api.Test;
/** Unit tests for {@link RequestModule}. */
final class RequestModuleTest {
private static final Gson GSON = GsonUtils.provideGson();
@Test
void testProvideJsonPayload() {
assertThat(provideJsonPayload(MediaType.JSON_UTF_8, "{\"k\":\"v\"}")).containsExactly("k", "v");
assertThat(provideJsonPayload(MediaType.JSON_UTF_8, "{\"k\":\"v\"}", GSON))
.containsExactly("k", "v");
}
@Test
void testProvideJsonPayload_contentTypeWithoutCharsetAllowed() {
assertThat(provideJsonPayload(MediaType.JSON_UTF_8.withoutParameters(), "{\"k\":\"v\"}"))
assertThat(provideJsonPayload(MediaType.JSON_UTF_8.withoutParameters(), "{\"k\":\"v\"}", GSON))
.containsExactly("k", "v");
}
@@ -41,14 +46,16 @@ final class RequestModuleTest {
void testProvideJsonPayload_malformedInput_throws500() {
BadRequestException thrown =
assertThrows(
BadRequestException.class, () -> provideJsonPayload(MediaType.JSON_UTF_8, "{\"k\":"));
BadRequestException.class,
() -> provideJsonPayload(MediaType.JSON_UTF_8, "{\"k\":", GSON));
assertThat(thrown).hasMessageThat().contains("Malformed JSON");
}
@Test
void testProvideJsonPayload_emptyInput_throws500() {
BadRequestException thrown =
assertThrows(BadRequestException.class, () -> provideJsonPayload(MediaType.JSON_UTF_8, ""));
assertThrows(
BadRequestException.class, () -> provideJsonPayload(MediaType.JSON_UTF_8, "", GSON));
assertThat(thrown).hasMessageThat().contains("Malformed JSON");
}
@@ -56,13 +63,13 @@ final class RequestModuleTest {
void testProvideJsonPayload_nonJsonContentType_throws415() {
assertThrows(
UnsupportedMediaTypeException.class,
() -> provideJsonPayload(MediaType.PLAIN_TEXT_UTF_8, "{}"));
() -> provideJsonPayload(MediaType.PLAIN_TEXT_UTF_8, "{}", GSON));
}
@Test
void testProvideJsonPayload_contentTypeWithWeirdParam_throws415() {
assertThrows(
UnsupportedMediaTypeException.class,
() -> provideJsonPayload(MediaType.JSON_UTF_8.withParameter("omg", "handel"), "{}"));
() -> provideJsonPayload(MediaType.JSON_UTF_8.withParameter("omg", "handel"), "{}", GSON));
}
}

View File

@@ -20,21 +20,25 @@ import static com.google.common.truth.Truth.assertWithMessage;
import static google.registry.security.JsonHttp.JSON_SAFETY_PREFIX;
import com.google.common.base.Supplier;
import com.google.gson.Gson;
import com.google.gson.JsonSyntaxException;
import com.google.gson.reflect.TypeToken;
import google.registry.tools.GsonUtils;
import java.io.BufferedReader;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.Map;
import org.json.simple.JSONValue;
import org.json.simple.parser.ParseException;
/**
* Helper class for testing JSON RPC servlets.
*/
public final class JsonHttpTestUtils {
private static final Gson GSON = GsonUtils.provideGson();
/** Returns JSON payload for mocked result of {@code rsp.getReader()}. */
public static BufferedReader createJsonPayload(Map<String, ?> object) {
return createJsonPayload(JSONValue.toJSONString(object));
return createJsonPayload(GSON.toJson(object));
}
/** @see #createJsonPayload(Map) */
@@ -58,10 +62,8 @@ public final class JsonHttpTestUtils {
assertThat(jsonText).startsWith(JSON_SAFETY_PREFIX);
jsonText = jsonText.substring(JSON_SAFETY_PREFIX.length());
try {
@SuppressWarnings("unchecked")
Map<String, Object> json = (Map<String, Object>) JSONValue.parseWithException(jsonText);
return json;
} catch (ClassCastException | ParseException e) {
return GSON.fromJson(jsonText, new TypeToken<>() {});
} catch (ClassCastException | JsonSyntaxException e) {
assertWithMessage("Bad JSON: %s\n%s", e.getMessage(), jsonText).fail();
throw new AssertionError();
}

View File

@@ -33,7 +33,7 @@ public final class RegistryTestServer {
public static final ImmutableMap<String, Path> RUNFILES =
new ImmutableMap.Builder<String, Path>()
.put("/console/*", PROJECT_ROOT.resolve("console-webapp/staged/dist"))
.put("/console/*", PROJECT_ROOT.resolve("console-webapp/staged/dist/browser"))
.build();
public static final ImmutableList<Route> ROUTES =

View File

@@ -15,6 +15,7 @@
package google.registry.testing;
import google.registry.request.JsonResponse;
import google.registry.tools.GsonUtils;
import java.util.Map;
/** Fake implementation of {@link JsonResponse} for testing. */
@@ -23,7 +24,7 @@ public final class FakeJsonResponse extends JsonResponse {
private Map<String, ?> responseMap;
public FakeJsonResponse() {
super(new FakeResponse());
super(new FakeResponse(), GsonUtils.provideGson());
}
@Override

View File

@@ -49,8 +49,8 @@ class CreateDomainCommandTest extends EppToolCommandTestCase<CreateDomainCommand
"--period=1",
"--nameservers=ns1.zdns.google,ns2.zdns.google,ns3.zdns.google,ns4.zdns.google",
"--password=2fooBAR",
"--ds_records=1 2 2 9F86D081884C7D659A2FEAA0C55AD015A3BF4F1B2B0B822CD15D6C15B0F00A08,4 5 1"
+ " A94A8FE5CCB19BA61C4C0873D391E987982FBBD3",
"--ds_records=1 2 2 9F86D081884C7D659A2FEAA0C55AD015A3BF4F1B2B0B822CD15D6C15B0F00A08,4 5 2"
+ " D4B7D520E7BB5F0F67674A0CCEB1E3E0614B93C4F9E99B8383F6A1E4469DA50A",
"--ds_records=60485 5 2 D4B7D520E7BB5F0F67674A0CCEB1E3E0614B93C4F9E99B8383F6A1E4469DA50A",
"example.tld");
eppVerifier.verifySent("domain_create_complete.xml");
@@ -63,8 +63,8 @@ class CreateDomainCommandTest extends EppToolCommandTestCase<CreateDomainCommand
"--period=1",
"--nameservers=NS1.zdns.google,ns2.ZDNS.google,ns3.zdns.gOOglE,ns4.zdns.google",
"--password=2fooBAR",
"--ds_records=1 2 2 9F86D081884C7D659A2FEAA0C55AD015A3BF4F1B2B0B822CD15D6C15B0F00A08,4 5 1"
+ " A94A8FE5CCB19BA61C4C0873D391E987982FBBD3",
"--ds_records=1 2 2 9F86D081884C7D659A2FEAA0C55AD015A3BF4F1B2B0B822CD15D6C15B0F00A08,4 5 2"
+ " D4B7D520E7BB5F0F67674A0CCEB1E3E0614B93C4F9E99B8383F6A1E4469DA50A",
"--ds_records=60485 5 2 D4B7D520E7BB5F0F67674A0CCEB1E3E0614B93C4F9E99B8383F6A1E4469DA50A",
"example.tld");
eppVerifier.verifySent("domain_create_complete.xml");
@@ -77,8 +77,8 @@ class CreateDomainCommandTest extends EppToolCommandTestCase<CreateDomainCommand
"--period=1",
"--nameservers=ns[1-4].zdns.google",
"--password=2fooBAR",
"--ds_records=1 2 2 9F86D081884C7D659A2FEAA0C55AD015A3BF4F1B2B0B822CD15D6C15B0F00A08,4 5 1"
+ " A94A8FE5CCB19BA61C4C0873D391E987982FBBD3",
"--ds_records=1 2 2 9F86D081884C7D659A2FEAA0C55AD015A3BF4F1B2B0B822CD15D6C15B0F00A08,4 5 2"
+ " D4B7D520E7BB5F0F67674A0CCEB1E3E0614B93C4F9E99B8383F6A1E4469DA50A",
"--ds_records=60485 5 2 D4B7D520E7BB5F0F67674A0CCEB1E3E0614B93C4F9E99B8383F6A1E4469DA50A",
"example.tld");
eppVerifier.verifySent("domain_create_complete.xml");
@@ -91,8 +91,8 @@ class CreateDomainCommandTest extends EppToolCommandTestCase<CreateDomainCommand
"--period=1",
"--nameservers=NS[1-4].zdns.google",
"--password=2fooBAR",
"--ds_records=1 2 2 9F86D081884C7D659A2FEAA0C55AD015A3BF4F1B2B0B822CD15D6C15B0F00A08,4 5 1"
+ " A94A8FE5CCB19BA61C4C0873D391E987982FBBD3",
"--ds_records=1 2 2 9F86D081884C7D659A2FEAA0C55AD015A3BF4F1B2B0B822CD15D6C15B0F00A08,4 5 2"
+ " D4B7D520E7BB5F0F67674A0CCEB1E3E0614B93C4F9E99B8383F6A1E4469DA50A",
"--ds_records=60485 5 2 D4B7D520E7BB5F0F67674A0CCEB1E3E0614B93C4F9E99B8383F6A1E4469DA50A",
"example.tld");
eppVerifier.verifySent("domain_create_complete.xml");
@@ -286,9 +286,7 @@ class CreateDomainCommandTest extends EppToolCommandTestCase<CreateDomainCommand
IllegalArgumentException.class,
() ->
runCommandForced(
"--client=NewRegistrar",
"--ds_records=1 2 1 abcd",
"example.tld"));
"--client=NewRegistrar", "--ds_records=1 2 2 abcd", "example.tld"));
assertThat(thrown).hasMessageThat().isEqualTo("DS record has an invalid digest length: ABCD");
}

View File

@@ -0,0 +1,48 @@
// Copyright 2026 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.tools;
import static com.google.common.truth.Truth.assertThat;
import org.junit.jupiter.api.Test;
/** Unit tests for {@link DigestType}. */
class DigestTypeTest {
@Test
void testFromWireValue_sha1_returnsSha1() {
assertThat(DigestType.fromWireValue(1)).hasValue(DigestType.SHA1);
}
@Test
void testFromWireValue_sha256_returnsSha256() {
assertThat(DigestType.fromWireValue(2)).hasValue(DigestType.SHA256);
}
@Test
void testFromWireValue_gost_returnsEmpty() {
assertThat(DigestType.fromWireValue(3)).isEmpty();
}
@Test
void testFromWireValue_sha384_returnsSha384() {
assertThat(DigestType.fromWireValue(4)).hasValue(DigestType.SHA384);
}
@Test
void testFromWireValue_invalid_returnsEmpty() {
assertThat(DigestType.fromWireValue(5)).isEmpty();
}
}

View File

@@ -85,7 +85,8 @@ final class GcpProjectConnectionTest {
when(lowLevelHttpResponse.getStatusCode()).thenReturn(200);
httpTransport = new TestHttpTransport();
connection = new ServiceConnection(false, httpTransport.createRequestFactory());
connection =
new ServiceConnection(false, httpTransport.createRequestFactory(), GsonUtils.provideGson());
}
@Test

View File

@@ -31,6 +31,7 @@ import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Lists;
import com.google.common.net.InetAddresses;
import com.google.gson.Gson;
import google.registry.model.domain.Domain;
import google.registry.model.domain.secdns.DomainDsData;
import google.registry.model.eppcommon.StatusValue;
@@ -41,19 +42,19 @@ import java.io.Reader;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
import org.json.simple.JSONValue;
import org.json.simple.parser.ParseException;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
/** Unit tests for {@link GenerateDnsReportCommand}. */
class GenerateDnsReportCommandTest extends CommandTestCase<GenerateDnsReportCommand> {
private static final Gson GSON = GsonUtils.provideGson();
private Path output;
private Object getOutputAsJson() throws IOException, ParseException {
private Object getOutputAsJson() throws IOException {
try (Reader reader = Files.newBufferedReader(output, UTF_8)) {
return JSONValue.parseWithException(reader);
return GSON.fromJson(reader, Object.class);
}
}
@@ -114,6 +115,7 @@ class GenerateDnsReportCommandTest extends CommandTestCase<GenerateDnsReportComm
void beforeEach() {
output = tmpDir.resolve("out.dat");
command.clock = fakeClock;
command.gson = GSON;
createTlds("xn--q9jyb4c", "example");
nameserver1 =

View File

@@ -26,6 +26,7 @@ import com.google.api.client.http.HttpRequest;
import com.google.api.client.http.HttpRequestFactory;
import com.google.api.client.http.HttpResponse;
import com.google.common.collect.ImmutableMap;
import com.google.gson.Gson;
import google.registry.request.Action.Service;
import java.io.ByteArrayInputStream;
import org.junit.jupiter.api.Test;
@@ -33,10 +34,12 @@ import org.junit.jupiter.api.Test;
/** Unit tests for {@link google.registry.tools.ServiceConnection}. */
public class ServiceConnectionTest {
private static final Gson GSON = GsonUtils.provideGson();
@Test
void testSuccess_serverUrl_notCanary() {
ServiceConnection connection =
new ServiceConnection(false, null).withService(Service.FRONTEND, false);
new ServiceConnection(false, null, GSON).withService(Service.FRONTEND, false);
String serverUrl = connection.getServer().toString();
assertThat(serverUrl).isEqualTo("https://frontend.registry.test"); // See default-config.yaml
}
@@ -52,7 +55,7 @@ public class ServiceConnectionTest {
when(request.execute()).thenReturn(response);
when(response.getContent()).thenReturn(ByteArrayInputStream.nullInputStream());
ServiceConnection connection =
new ServiceConnection(false, factory).withService(Service.PUBAPI, true);
new ServiceConnection(false, factory, GSON).withService(Service.PUBAPI, true);
String serverUrl = connection.getServer().toString();
assertThat(serverUrl).isEqualTo("https://pubapi.registry.test");
connection.sendGetRequest("/path", ImmutableMap.of());

View File

@@ -79,7 +79,7 @@ class UniformRapidSuspensionCommandTest
runCommandForced(
"--domain_name=evil.tld",
"--hosts=urs1.example.com,urs2.example.com",
"--dsdata=1 1 1 A94A8FE5CCB19BA61C4C0873D391E987982FBBD3",
"--dsdata=1 1 2 D4B7D520E7BB5F0F67674A0CCEB1E3E0614B93C4F9E99B8383F6A1E4469DA50A",
"--renew_one_year=false");
eppVerifier
.expectRegistrarId("CharlestonRoad")
@@ -107,7 +107,7 @@ class UniformRapidSuspensionCommandTest
runCommandForced(
"--domain_name=evil.tld",
"--hosts=urs1.example.com,urs2.example.com",
"--dsdata=1 1 1 A94A8FE5CCB19BA61C4C0873D391E987982FBBD3",
"--dsdata=1 1 2 D4B7D520E7BB5F0F67674A0CCEB1E3E0614B93C4F9E99B8383F6A1E4469DA50A",
"--renew_one_year=false");
eppVerifier
.expectRegistrarId("CharlestonRoad")
@@ -179,7 +179,7 @@ class UniformRapidSuspensionCommandTest
runCommandForced(
"--domain_name=evil.tld",
"--hosts=urs1.example.com,urs2.example.com",
"--dsdata=1 1 1 A94A8FE5CCB19BA61C4C0873D391E987982FBBD3",
"--dsdata=1 1 2 D4B7D520E7BB5F0F67674A0CCEB1E3E0614B93C4F9E99B8383F6A1E4469DA50A",
"--renew_one_year=false");
eppVerifier
.expectRegistrarId("CharlestonRoad")
@@ -198,7 +198,7 @@ class UniformRapidSuspensionCommandTest
runCommandForced(
"--domain_name=evil.tld",
"--hosts=URS[1-2].example.com",
"--dsdata=1 1 1 A94A8FE5CCB19BA61C4C0873D391E987982FBBD3",
"--dsdata=1 1 2 D4B7D520E7BB5F0F67674A0CCEB1E3E0614B93C4F9E99B8383F6A1E4469DA50A",
"--renew_one_year=false");
eppVerifier
.expectRegistrarId("CharlestonRoad")

View File

@@ -76,10 +76,11 @@ class UpdateDomainCommandTest extends EppToolCommandTestCase<UpdateDomainCommand
"--add_nameservers=ns1.zdns.google,ns2.zdns.google",
"--add_statuses=serverDeleteProhibited",
"--add_ds_records=1 2 2 9F86D081884C7D659A2FEAA0C55AD015A3BF4F1B2B0B822CD15D6C15B0F00A08,4"
+ " 5 1 A94A8FE5CCB19BA61C4C0873D391E987982FBBD3",
+ " 5 2 D4B7D520E7BB5F0F67674A0CCEB1E3E0614B93C4F9E99B8383F6A1E4469DA50A",
"--remove_nameservers=ns3.zdns.google,ns4.zdns.google",
"--remove_statuses=serverHold",
"--remove_ds_records=7 8 1 A94A8FE5CCB19BA61C4C0873D391E987982FBBD3,6 5 4"
"--remove_ds_records=7 8 2"
+ " D4B7D520E7BB5F0F67674A0CCEB1E3E0614B93C4F9E99B8383F6A1E4469DA50A,6 5 4"
+ " 768412320F7B0AA5812FCE428DC4706B3CAE50E02A64CAA16A782249BFE8EFC4B7EF1CCB126255D196047DFEDF17A0A9",
"--password=2fooBAR",
"example.tld");
@@ -93,10 +94,11 @@ class UpdateDomainCommandTest extends EppToolCommandTestCase<UpdateDomainCommand
"--add_nameservers=NS[1-2].zdns.google",
"--add_statuses=serverDeleteProhibited",
"--add_ds_records=1 2 2 9F86D081884C7D659A2FEAA0C55AD015A3BF4F1B2B0B822CD15D6C15B0F00A08,4"
+ " 5 1 A94A8FE5CCB19BA61C4C0873D391E987982FBBD3",
+ " 5 2 D4B7D520E7BB5F0F67674A0CCEB1E3E0614B93C4F9E99B8383F6A1E4469DA50A",
"--remove_nameservers=ns[3-4].zdns.google",
"--remove_statuses=serverHold",
"--remove_ds_records=7 8 1 A94A8FE5CCB19BA61C4C0873D391E987982FBBD3,6 5 4"
"--remove_ds_records=7 8 2"
+ " D4B7D520E7BB5F0F67674A0CCEB1E3E0614B93C4F9E99B8383F6A1E4469DA50A,6 5 4"
+ " 768412320F7B0AA5812FCE428DC4706B3CAE50E02A64CAA16A782249BFE8EFC4B7EF1CCB126255D196047DFEDF17A0A9",
"--password=2fooBAR",
"example.tld");
@@ -112,10 +114,11 @@ class UpdateDomainCommandTest extends EppToolCommandTestCase<UpdateDomainCommand
"--add_nameservers=ns1.zdns.google,ns2.zdns.google",
"--add_statuses=serverDeleteProhibited",
"--add_ds_records=1 2 2 9F86D081884C7D659A2FEAA0C55AD015A3BF4F1B2B0B822CD15D6C15B0F00A08,4"
+ " 5 1 A94A8FE5CCB19BA61C4C0873D391E987982FBBD3",
+ " 5 2 D4B7D520E7BB5F0F67674A0CCEB1E3E0614B93C4F9E99B8383F6A1E4469DA50A",
"--remove_nameservers=ns[3-4].zdns.google",
"--remove_statuses=serverHold",
"--remove_ds_records=7 8 1 A94A8FE5CCB19BA61C4C0873D391E987982FBBD3,6 5 4"
"--remove_ds_records=7 8 2"
+ " D4B7D520E7BB5F0F67674A0CCEB1E3E0614B93C4F9E99B8383F6A1E4469DA50A,6 5 4"
+ " 768412320F7B0AA5812FCE428DC4706B3CAE50E02A64CAA16A782249BFE8EFC4B7EF1CCB126255D196047DFEDF17A0A9",
"--password=2fooBAR",
"example.tld",
@@ -163,7 +166,7 @@ class UpdateDomainCommandTest extends EppToolCommandTestCase<UpdateDomainCommand
"--add_nameservers=ns2.zdns.google,ns3.zdns.google",
"--add_statuses=serverDeleteProhibited",
"--add_ds_records=1 2 2 D4B7D520E7BB5F0F67674A0CCEB1E3E0614B93C4F9E99B8383F6A1E4469DA50A,4"
+ " 5 1 A94A8FE5CCB19BA61C4C0873D391E987982FBBD3",
+ " 5 2 D4B7D520E7BB5F0F67674A0CCEB1E3E0614B93C4F9E99B8383F6A1E4469DA50A",
"example.tld");
eppVerifier.verifySent("domain_update_add.xml");
}
@@ -174,7 +177,8 @@ class UpdateDomainCommandTest extends EppToolCommandTestCase<UpdateDomainCommand
"--client=NewRegistrar",
"--remove_nameservers=ns4.zdns.google",
"--remove_statuses=serverHold",
"--remove_ds_records=7 8 1 A94A8FE5CCB19BA61C4C0873D391E987982FBBD3,6 5 4"
"--remove_ds_records=7 8 2"
+ " D4B7D520E7BB5F0F67674A0CCEB1E3E0614B93C4F9E99B8383F6A1E4469DA50A,6 5 4"
+ " 768412320F7B0AA5812FCE428DC4706B3CAE50E02A64CAA16A782249BFE8EFC4B7EF1CCB126255D196047DFEDF17A0A9",
"example.tld");
eppVerifier.verifySent("domain_update_remove.xml");
@@ -230,8 +234,8 @@ class UpdateDomainCommandTest extends EppToolCommandTestCase<UpdateDomainCommand
void testSuccess_setDsRecords() throws Exception {
runCommandForced(
"--client=NewRegistrar",
"--ds_records=1 2 2 D4B7D520E7BB5F0F67674A0CCEB1E3E0614B93C4F9E99B8383F6A1E4469DA50A,4 5 1"
+ " A94A8FE5CCB19BA61C4C0873D391E987982FBBD3",
"--ds_records=1 2 2 D4B7D520E7BB5F0F67674A0CCEB1E3E0614B93C4F9E99B8383F6A1E4469DA50A,4 5 2"
+ " D4B7D520E7BB5F0F67674A0CCEB1E3E0614B93C4F9E99B8383F6A1E4469DA50A",
"example.tld");
eppVerifier.verifySent("domain_update_set_ds_records.xml");
}
@@ -240,8 +244,8 @@ class UpdateDomainCommandTest extends EppToolCommandTestCase<UpdateDomainCommand
void testSuccess_setDsRecords_withUnneededClear() throws Exception {
runCommandForced(
"--client=NewRegistrar",
"--ds_records=1 2 2 D4B7D520E7BB5F0F67674A0CCEB1E3E0614B93C4F9E99B8383F6A1E4469DA50A,4 5 1"
+ " A94A8FE5CCB19BA61C4C0873D391E987982FBBD3",
"--ds_records=1 2 2 D4B7D520E7BB5F0F67674A0CCEB1E3E0614B93C4F9E99B8383F6A1E4469DA50A,4 5 2"
+ " D4B7D520E7BB5F0F67674A0CCEB1E3E0614B93C4F9E99B8383F6A1E4469DA50A",
"--clear_ds_records",
"example.tld");
eppVerifier.verifySent("domain_update_set_ds_records.xml");
@@ -538,9 +542,7 @@ class UpdateDomainCommandTest extends EppToolCommandTestCase<UpdateDomainCommand
IllegalArgumentException.class,
() ->
runCommandForced(
"--client=NewRegistrar",
"--ds_records=1 2 1 abcd",
"example.tld"));
"--client=NewRegistrar", "--ds_records=1 2 2 abcd", "example.tld"));
assertThat(thrown).hasMessageThat().isEqualTo("DS record has an invalid digest length: ABCD");
}
@@ -554,7 +556,8 @@ class UpdateDomainCommandTest extends EppToolCommandTestCase<UpdateDomainCommand
"--client=NewRegistrar",
"--add_ds_records=1 2 2"
+ " D4B7D520E7BB5F0F67674A0CCEB1E3E0614B93C4F9E99B8383F6A1E4469DA50A",
"--ds_records=4 5 1 A94A8FE5CCB19BA61C4C0873D391E987982FBBD3",
"--ds_records=4 5 2"
+ " D4B7D520E7BB5F0F67674A0CCEB1E3E0614B93C4F9E99B8383F6A1E4469DA50A",
"example.tld"));
assertThat(thrown)
.hasMessageThat()
@@ -571,8 +574,10 @@ class UpdateDomainCommandTest extends EppToolCommandTestCase<UpdateDomainCommand
() ->
runCommandForced(
"--client=NewRegistrar",
"--remove_ds_records=7 8 1 A94A8FE5CCB19BA61C4C0873D391E987982FBBD3",
"--ds_records=4 5 1 A94A8FE5CCB19BA61C4C0873D391E987982FBBD3",
"--remove_ds_records=7 8 2"
+ " D4B7D520E7BB5F0F67674A0CCEB1E3E0614B93C4F9E99B8383F6A1E4469DA50A",
"--ds_records=4 5 2"
+ " D4B7D520E7BB5F0F67674A0CCEB1E3E0614B93C4F9E99B8383F6A1E4469DA50A",
"example.tld"));
assertThat(thrown)
.hasMessageThat()
@@ -608,7 +613,8 @@ class UpdateDomainCommandTest extends EppToolCommandTestCase<UpdateDomainCommand
() ->
runCommandForced(
"--client=NewRegistrar",
"--remove_ds_records=7 8 1 A94A8FE5CCB19BA61C4C0873D391E987982FBBD3",
"--remove_ds_records=7 8 2"
+ " D4B7D520E7BB5F0F67674A0CCEB1E3E0614B93C4F9E99B8383F6A1E4469DA50A",
"--clear_ds_records",
"example.tld"));
assertThat(thrown)

View File

@@ -27,6 +27,7 @@ import static org.mockito.Mockito.when;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.gson.reflect.TypeToken;
import google.registry.model.OteStatsTestHelper;
import google.registry.model.console.GlobalRole;
import google.registry.model.console.User;
@@ -44,7 +45,6 @@ import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import org.json.simple.JSONArray;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@@ -131,7 +131,7 @@ class ConsoleOteActionTest extends ConsoleActionBaseTestCase {
Optional.of(new OteCreateData("theregistrar", "contact@registry.example")));
action.cloudTasksUtils = cloudTasksHelper.getTestCloudTasksUtils();
action.run();
var obsResponse = GSON.fromJson(response.getPayload(), Map.class);
Map<String, Object> obsResponse = GSON.fromJson(response.getPayload(), new TypeToken<>() {});
assertThat(
ImmutableMap.of(
"theregistrar-1", "theregistrar-sunrise",
@@ -175,7 +175,7 @@ class ConsoleOteActionTest extends ConsoleActionBaseTestCase {
Action.Method.GET, authResult, "theregistrar-1", Optional.empty(), Optional.empty());
action.run();
List<Map<String, ?>> responseMaps = GSON.fromJson(response.getPayload(), JSONArray.class);
List<Map<String, ?>> responseMaps = GSON.fromJson(response.getPayload(), new TypeToken<>() {});
assertThat(response.getStatus()).isEqualTo(SC_OK);
assertTrue(
responseMaps.stream().allMatch(status -> Boolean.TRUE.equals(status.get("completed"))));
@@ -191,7 +191,7 @@ class ConsoleOteActionTest extends ConsoleActionBaseTestCase {
Action.Method.GET, authResult, "theregistrar-1", Optional.empty(), Optional.empty());
action.run();
List<Map<String, ?>> responseMaps = GSON.fromJson(response.getPayload(), JSONArray.class);
List<Map<String, ?>> responseMaps = GSON.fromJson(response.getPayload(), new TypeToken<>() {});
assertThat(response.getStatus()).isEqualTo(SC_OK);
assertThat(
responseMaps.stream()

View File

@@ -174,7 +174,9 @@ public class ConsoleScreenshotTest {
// Script that set cursor to transparent to prevent blanking cursor flakiness when comparing
// screenshots
String script =
"document.styleSheets[0].insertRule(\"html * {caret-color: transparent !important;}\")";
"var style = document.createElement('style');"
+ "style.innerHTML = 'html * {caret-color: transparent !important;}';"
+ "document.head.appendChild(style);";
driver.executeScript(script);
}

View File

@@ -22,50 +22,50 @@
<secDNS:dsData>
<secDNS:keyTag>12345</secDNS:keyTag>
<secDNS:alg>3</secDNS:alg>
<secDNS:digestType>1</secDNS:digestType>
<secDNS:digest>A94A8FE5CCB19BA61C4C0873D391E987982FBBD3</secDNS:digest>
<secDNS:digestType>2</secDNS:digestType>
<secDNS:digest>D4B7D520E7BB5F0F67674A0CCEB1E3E0614B93C4F9E99B8383F6A1E4469DA50A</secDNS:digest>
</secDNS:dsData>
<secDNS:dsData>
<secDNS:keyTag>12346</secDNS:keyTag>
<secDNS:alg>3</secDNS:alg>
<secDNS:digestType>1</secDNS:digestType>
<secDNS:digest>A94A8FE5CCB19BA61C4C0873D391E987982FBBD3</secDNS:digest>
<secDNS:digestType>2</secDNS:digestType>
<secDNS:digest>D4B7D520E7BB5F0F67674A0CCEB1E3E0614B93C4F9E99B8383F6A1E4469DA50A</secDNS:digest>
</secDNS:dsData>
<secDNS:dsData>
<secDNS:keyTag>12347</secDNS:keyTag>
<secDNS:alg>3</secDNS:alg>
<secDNS:digestType>1</secDNS:digestType>
<secDNS:digest>A94A8FE5CCB19BA61C4C0873D391E987982FBBD3</secDNS:digest>
<secDNS:digestType>2</secDNS:digestType>
<secDNS:digest>D4B7D520E7BB5F0F67674A0CCEB1E3E0614B93C4F9E99B8383F6A1E4469DA50A</secDNS:digest>
</secDNS:dsData>
<secDNS:dsData>
<secDNS:keyTag>12348</secDNS:keyTag>
<secDNS:alg>3</secDNS:alg>
<secDNS:digestType>1</secDNS:digestType>
<secDNS:digest>A94A8FE5CCB19BA61C4C0873D391E987982FBBD3</secDNS:digest>
<secDNS:digestType>2</secDNS:digestType>
<secDNS:digest>D4B7D520E7BB5F0F67674A0CCEB1E3E0614B93C4F9E99B8383F6A1E4469DA50A</secDNS:digest>
</secDNS:dsData>
<secDNS:dsData>
<secDNS:keyTag>12349</secDNS:keyTag>
<secDNS:alg>3</secDNS:alg>
<secDNS:digestType>1</secDNS:digestType>
<secDNS:digest>A94A8FE5CCB19BA61C4C0873D391E987982FBBD3</secDNS:digest>
<secDNS:digestType>2</secDNS:digestType>
<secDNS:digest>D4B7D520E7BB5F0F67674A0CCEB1E3E0614B93C4F9E99B8383F6A1E4469DA50A</secDNS:digest>
</secDNS:dsData>
<secDNS:dsData>
<secDNS:keyTag>12350</secDNS:keyTag>
<secDNS:alg>3</secDNS:alg>
<secDNS:digestType>1</secDNS:digestType>
<secDNS:digest>A94A8FE5CCB19BA61C4C0873D391E987982FBBD3</secDNS:digest>
<secDNS:digestType>2</secDNS:digestType>
<secDNS:digest>D4B7D520E7BB5F0F67674A0CCEB1E3E0614B93C4F9E99B8383F6A1E4469DA50A</secDNS:digest>
</secDNS:dsData>
<secDNS:dsData>
<secDNS:keyTag>12351</secDNS:keyTag>
<secDNS:alg>3</secDNS:alg>
<secDNS:digestType>1</secDNS:digestType>
<secDNS:digest>A94A8FE5CCB19BA61C4C0873D391E987982FBBD3</secDNS:digest>
<secDNS:digestType>2</secDNS:digestType>
<secDNS:digest>D4B7D520E7BB5F0F67674A0CCEB1E3E0614B93C4F9E99B8383F6A1E4469DA50A</secDNS:digest>
</secDNS:dsData>
<secDNS:dsData>
<secDNS:keyTag>12352</secDNS:keyTag>
<secDNS:alg>3</secDNS:alg>
<secDNS:digestType>1</secDNS:digestType>
<secDNS:digest>A94A8FE5CCB19BA61C4C0873D391E987982FBBD3</secDNS:digest>
<secDNS:digestType>2</secDNS:digestType>
<secDNS:digest>D4B7D520E7BB5F0F67674A0CCEB1E3E0614B93C4F9E99B8383F6A1E4469DA50A</secDNS:digest>
</secDNS:dsData>
</secDNS:create>
</extension>

View File

@@ -22,8 +22,8 @@
<secDNS:dsData>
<secDNS:keyTag>12345</secDNS:keyTag>
<secDNS:alg>3</secDNS:alg>
<secDNS:digestType>1</secDNS:digestType>
<secDNS:digest>A94A8FE5CCB19BA61C4C0873D391E987982FBBD3</secDNS:digest>
<secDNS:digestType>2</secDNS:digestType>
<secDNS:digest>D4B7D520E7BB5F0F67674A0CCEB1E3E0614B93C4F9E99B8383F6A1E4469DA50A</secDNS:digest>
</secDNS:dsData>
</secDNS:create>
</extension>

View File

@@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<command>
<create>
<domain:create
xmlns:domain="urn:ietf:params:xml:ns:domain-1.0">
<domain:name>example.tld</domain:name>
<domain:period unit="y">2</domain:period>
<domain:ns>
<domain:hostObj>ns1.example.net</domain:hostObj>
<domain:hostObj>ns2.example.net</domain:hostObj>
</domain:ns>
<domain:authInfo>
<domain:pw>2fooBAR</domain:pw>
</domain:authInfo>
</domain:create>
</create>
<extension>
<secDNS:create
xmlns:secDNS="urn:ietf:params:xml:ns:secDNS-1.1">
<secDNS:dsData>
<secDNS:keyTag>12345</secDNS:keyTag>
<secDNS:alg>3</secDNS:alg>
<secDNS:digestType>1</secDNS:digestType>
<secDNS:digest>49FD46E6C4B45C55D4AC49FD46E6C4B45C55D4AC</secDNS:digest>
</secDNS:dsData>
</secDNS:create>
</extension>
<clTRID>ABC-12345</clTRID>
</command>
</epp>

View File

@@ -15,16 +15,16 @@
<secDNS:dsData>
<secDNS:keyTag>12345</secDNS:keyTag>
<secDNS:alg>3</secDNS:alg>
<secDNS:digestType>1</secDNS:digestType>
<secDNS:digest>A94A8FE5CCB19BA61C4C0873D391E987982FBBD3</secDNS:digest>
<secDNS:digestType>2</secDNS:digestType>
<secDNS:digest>D4B7D520E7BB5F0F67674A0CCEB1E3E0614B93C4F9E99B8383F6A1E4469DA50A</secDNS:digest>
</secDNS:dsData>
</secDNS:rem>
<secDNS:add>
<secDNS:dsData>
<secDNS:keyTag>12346</secDNS:keyTag>
<secDNS:alg>3</secDNS:alg>
<secDNS:digestType>1</secDNS:digestType>
<secDNS:digest>A94A8FE5CCB19BA61C4C0873D391E987982FBBD3</secDNS:digest>
<secDNS:digestType>2</secDNS:digestType>
<secDNS:digest>D4B7D520E7BB5F0F67674A0CCEB1E3E0614B93C4F9E99B8383F6A1E4469DA50A</secDNS:digest>
</secDNS:dsData>
</secDNS:add>
</secDNS:update>

View File

@@ -15,8 +15,8 @@
<secDNS:dsData>
<secDNS:keyTag>12346</secDNS:keyTag>
<secDNS:alg>3</secDNS:alg>
<secDNS:digestType>1</secDNS:digestType>
<secDNS:digest>A94A8FE5CCB19BA61C4C0873D391E987982FBBD3</secDNS:digest>
<secDNS:digestType>2</secDNS:digestType>
<secDNS:digest>D4B7D520E7BB5F0F67674A0CCEB1E3E0614B93C4F9E99B8383F6A1E4469DA50A</secDNS:digest>
</secDNS:dsData>
</secDNS:rem>
</secDNS:update>

View File

@@ -15,8 +15,8 @@
<secDNS:dsData>
<secDNS:keyTag>12346</secDNS:keyTag>
<secDNS:alg>3</secDNS:alg>
<secDNS:digestType>1</secDNS:digestType>
<secDNS:digest>A94A8FE5CCB19BA61C4C0873D391E987982FBBD3</secDNS:digest>
<secDNS:digestType>2</secDNS:digestType>
<secDNS:digest>D4B7D520E7BB5F0F67674A0CCEB1E3E0614B93C4F9E99B8383F6A1E4469DA50A</secDNS:digest>
</secDNS:dsData>
</secDNS:add>
</secDNS:update>

View File

@@ -15,8 +15,8 @@
<secDNS:dsData>
<secDNS:keyTag>12346</secDNS:keyTag>
<secDNS:alg>3</secDNS:alg>
<secDNS:digestType>1</secDNS:digestType>
<secDNS:digest>A94A8FE5CCB19BA61C4C0873D391E987982FBBD3</secDNS:digest>
<secDNS:digestType>2</secDNS:digestType>
<secDNS:digest>D4B7D520E7BB5F0F67674A0CCEB1E3E0614B93C4F9E99B8383F6A1E4469DA50A</secDNS:digest>
</secDNS:dsData>
</secDNS:rem>
</secDNS:update>

View File

@@ -28,8 +28,8 @@
<secDNS:dsData>
<secDNS:keyTag>4</secDNS:keyTag>
<secDNS:alg>5</secDNS:alg>
<secDNS:digestType>1</secDNS:digestType>
<secDNS:digest>A94A8FE5CCB19BA61C4C0873D391E987982FBBD3</secDNS:digest>
<secDNS:digestType>2</secDNS:digestType>
<secDNS:digest>D4B7D520E7BB5F0F67674A0CCEB1E3E0614B93C4F9E99B8383F6A1E4469DA50A</secDNS:digest>
</secDNS:dsData>
<secDNS:dsData>
<secDNS:keyTag>60485</secDNS:keyTag>

View File

@@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
<command>
<create>
<domain:create
xmlns:domain="urn:ietf:params:xml:ns:domain-1.0">
<domain:name>example.tld</domain:name>
<domain:period unit="y">1</domain:period>
<domain:ns>
<domain:hostObj>ns1.zdns.google</domain:hostObj>
<domain:hostObj>ns2.zdns.google</domain:hostObj>
<domain:hostObj>ns3.zdns.google</domain:hostObj>
<domain:hostObj>ns4.zdns.google</domain:hostObj>
</domain:ns>
<domain:authInfo>
<domain:pw>2fooBAR</domain:pw>
</domain:authInfo>
</domain:create>
</create>
<extension>
<secDNS:create xmlns:secDNS="urn:ietf:params:xml:ns:secDNS-1.1">
<secDNS:dsData>
<secDNS:keyTag>1</secDNS:keyTag>
<secDNS:alg>2</secDNS:alg>
<secDNS:digestType>1</secDNS:digestType>
<secDNS:digest>A94A8FE5CCB19BA61C4C0873D391E987982FBBD3</secDNS:digest>
</secDNS:dsData>
</secDNS:create>
</extension>
<clTRID>RegistryTool</clTRID>
</command>
</epp>

View File

@@ -26,8 +26,8 @@
<secDNS:dsData>
<secDNS:keyTag>4</secDNS:keyTag>
<secDNS:alg>5</secDNS:alg>
<secDNS:digestType>1</secDNS:digestType>
<secDNS:digest>A94A8FE5CCB19BA61C4C0873D391E987982FBBD3</secDNS:digest>
<secDNS:digestType>2</secDNS:digestType>
<secDNS:digest>D4B7D520E7BB5F0F67674A0CCEB1E3E0614B93C4F9E99B8383F6A1E4469DA50A</secDNS:digest>
</secDNS:dsData>
</secDNS:add>
</secDNS:update>

View File

@@ -32,8 +32,8 @@
<secDNS:dsData>
<secDNS:keyTag>7</secDNS:keyTag>
<secDNS:alg>8</secDNS:alg>
<secDNS:digestType>1</secDNS:digestType>
<secDNS:digest>A94A8FE5CCB19BA61C4C0873D391E987982FBBD3</secDNS:digest>
<secDNS:digestType>2</secDNS:digestType>
<secDNS:digest>D4B7D520E7BB5F0F67674A0CCEB1E3E0614B93C4F9E99B8383F6A1E4469DA50A</secDNS:digest>
</secDNS:dsData>
<secDNS:dsData>
<secDNS:keyTag>6</secDNS:keyTag>
@@ -52,8 +52,8 @@
<secDNS:dsData>
<secDNS:keyTag>4</secDNS:keyTag>
<secDNS:alg>5</secDNS:alg>
<secDNS:digestType>1</secDNS:digestType>
<secDNS:digest>A94A8FE5CCB19BA61C4C0873D391E987982FBBD3</secDNS:digest>
<secDNS:digestType>2</secDNS:digestType>
<secDNS:digest>D4B7D520E7BB5F0F67674A0CCEB1E3E0614B93C4F9E99B8383F6A1E4469DA50A</secDNS:digest>
</secDNS:dsData>
</secDNS:add>
</secDNS:update>

View File

@@ -32,8 +32,8 @@
<secDNS:dsData>
<secDNS:keyTag>7</secDNS:keyTag>
<secDNS:alg>8</secDNS:alg>
<secDNS:digestType>1</secDNS:digestType>
<secDNS:digest>A94A8FE5CCB19BA61C4C0873D391E987982FBBD3</secDNS:digest>
<secDNS:digestType>2</secDNS:digestType>
<secDNS:digest>D4B7D520E7BB5F0F67674A0CCEB1E3E0614B93C4F9E99B8383F6A1E4469DA50A</secDNS:digest>
</secDNS:dsData>
<secDNS:dsData>
<secDNS:keyTag>6</secDNS:keyTag>
@@ -52,8 +52,8 @@
<secDNS:dsData>
<secDNS:keyTag>4</secDNS:keyTag>
<secDNS:alg>5</secDNS:alg>
<secDNS:digestType>1</secDNS:digestType>
<secDNS:digest>A94A8FE5CCB19BA61C4C0873D391E987982FBBD3</secDNS:digest>
<secDNS:digestType>2</secDNS:digestType>
<secDNS:digest>D4B7D520E7BB5F0F67674A0CCEB1E3E0614B93C4F9E99B8383F6A1E4469DA50A</secDNS:digest>
</secDNS:dsData>
</secDNS:add>
</secDNS:update>

View File

@@ -19,8 +19,8 @@
<secDNS:dsData>
<secDNS:keyTag>7</secDNS:keyTag>
<secDNS:alg>8</secDNS:alg>
<secDNS:digestType>1</secDNS:digestType>
<secDNS:digest>A94A8FE5CCB19BA61C4C0873D391E987982FBBD3</secDNS:digest>
<secDNS:digestType>2</secDNS:digestType>
<secDNS:digest>D4B7D520E7BB5F0F67674A0CCEB1E3E0614B93C4F9E99B8383F6A1E4469DA50A</secDNS:digest>
</secDNS:dsData>
<secDNS:dsData>
<secDNS:keyTag>6</secDNS:keyTag>

View File

@@ -22,8 +22,8 @@
<secDNS:dsData>
<secDNS:keyTag>4</secDNS:keyTag>
<secDNS:alg>5</secDNS:alg>
<secDNS:digestType>1</secDNS:digestType>
<secDNS:digest>A94A8FE5CCB19BA61C4C0873D391E987982FBBD3</secDNS:digest>
<secDNS:digestType>2</secDNS:digestType>
<secDNS:digest>D4B7D520E7BB5F0F67674A0CCEB1E3E0614B93C4F9E99B8383F6A1E4469DA50A</secDNS:digest>
</secDNS:dsData>
</secDNS:add>
</secDNS:update>

View File

@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
<command>
<update>
<domain:update
xmlns:domain="urn:ietf:params:xml:ns:domain-1.0">
<domain:name>example.tld</domain:name>
<domain:add>
<domain:ns>
<domain:hostObj>ns2.zdns.google</domain:hostObj>
<domain:hostObj>ns3.zdns.google</domain:hostObj>
</domain:ns>
<domain:status s="serverDeleteProhibited"/>
</domain:add>
</domain:update>
</update>
<extension>
<secDNS:update xmlns:secDNS="urn:ietf:params:xml:ns:secDNS-1.1">
<secDNS:add>
<secDNS:dsData>
<secDNS:keyTag>1</secDNS:keyTag>
<secDNS:alg>2</secDNS:alg>
<secDNS:digestType>1</secDNS:digestType>
<secDNS:digest>A94A8FE5CCB19BA61C4C0873D391E987982FBBD3</secDNS:digest>
</secDNS:dsData>
</secDNS:add>
</secDNS:update>
</extension>
<clTRID>RegistryTool</clTRID>
</command>
</epp>

View File

@@ -30,8 +30,8 @@
<secDNS:dsData>
<secDNS:keyTag>1</secDNS:keyTag>
<secDNS:alg>1</secDNS:alg>
<secDNS:digestType>1</secDNS:digestType>
<secDNS:digest>A94A8FE5CCB19BA61C4C0873D391E987982FBBD3</secDNS:digest>
<secDNS:digestType>2</secDNS:digestType>
<secDNS:digest>D4B7D520E7BB5F0F67674A0CCEB1E3E0614B93C4F9E99B8383F6A1E4469DA50A</secDNS:digest>
</secDNS:dsData>
</secDNS:add>
</secDNS:update>

View File

@@ -31,8 +31,8 @@
<secDNS:dsData>
<secDNS:keyTag>1</secDNS:keyTag>
<secDNS:alg>1</secDNS:alg>
<secDNS:digestType>1</secDNS:digestType>
<secDNS:digest>A94A8FE5CCB19BA61C4C0873D391E987982FBBD3</secDNS:digest>
<secDNS:digestType>2</secDNS:digestType>
<secDNS:digest>D4B7D520E7BB5F0F67674A0CCEB1E3E0614B93C4F9E99B8383F6A1E4469DA50A</secDNS:digest>
</secDNS:dsData>
</secDNS:add>
</secDNS:update>

View File

@@ -29,8 +29,8 @@
<secDNS:dsData>
<secDNS:keyTag>1</secDNS:keyTag>
<secDNS:alg>1</secDNS:alg>
<secDNS:digestType>1</secDNS:digestType>
<secDNS:digest>A94A8FE5CCB19BA61C4C0873D391E987982FBBD3</secDNS:digest>
<secDNS:digestType>2</secDNS:digestType>
<secDNS:digest>D4B7D520E7BB5F0F67674A0CCEB1E3E0614B93C4F9E99B8383F6A1E4469DA50A</secDNS:digest>
</secDNS:dsData>
</secDNS:add>
</secDNS:update>

View File

@@ -116,7 +116,6 @@ ext {
'com.google.oauth-client:google-oauth-client:[1.31.4,)',
'com.google.re2j:re2j:[1.6,)',
'com.google.truth:truth:[1.1.2,)',
'com.googlecode.json-simple:json-simple:[1.1.1,)',
'com.squareup.okhttp3:okhttp:[4.10.0,)',
'org.freemarker:freemarker:[2.3.32,)',
'com.ibm.icu:icu4j:[68.2,)',

View File

@@ -55,8 +55,7 @@ configurations {
matching {
it.name in ['runtimeClasspath', 'compileClasspath']
}.all {
// JUnit is from org.apache.beam:beam-runners-google-cloud-dataflow-java,
// and json-simple.
// JUnit is from org.apache.beam:beam-runners-google-cloud-dataflow-java
exclude group: 'junit'
// Mockito is from org.apache.beam:beam-runners-google-cloud-dataflow-java
// See https://issues.apache.org/jira/browse/BEAM-8862

View File

@@ -162,7 +162,6 @@ com.google.protobuf:protobuf-java:4.33.2=annotationProcessor,testAnnotationProce
com.google.protobuf:protobuf-java:4.35.0=deploy_jar,runtimeClasspath,testRuntimeClasspath
com.google.re2j:re2j:1.8=deploy_jar,runtimeClasspath,testRuntimeClasspath
com.google.truth:truth:1.4.5=deploy_jar,runtimeClasspath,testRuntimeClasspath
com.googlecode.json-simple:json-simple:1.1.1=deploy_jar,runtimeClasspath,testRuntimeClasspath
com.ibm.icu:icu4j:73.2=deploy_jar,runtimeClasspath,testRuntimeClasspath
com.lmax:disruptor:3.4.2=deploy_jar,runtimeClasspath,testRuntimeClasspath
com.puppycrawl.tools:checkstyle:10.24.0=checkstyle