mirror of
https://github.com/google/nomulus
synced 2026-01-11 00:10:36 +00:00
Implement rdap_query command (#2886)
* Implement rdap_query command * modifying and correcting issues * modifying and correcting issues * modifying and correcting issues * resolving comments * resolving comments * resolving comments * resolving comments * resolving comments * modifying and correcting issues * resolving comments * resolving comments * resolving comments * modifying and correcting issues * modifying and correcting issues * modifying and correcting issues * resolving comments * modifying and correcting issues * resolving comments * Fixing Deduplication in test * Fixing Deduplication in test * resolving comments
This commit is contained in:
100
core/src/main/java/google/registry/tools/RdapQueryCommand.java
Normal file
100
core/src/main/java/google/registry/tools/RdapQueryCommand.java
Normal file
@@ -0,0 +1,100 @@
|
||||
// Copyright 2025 The Nomulus Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package google.registry.tools;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkState;
|
||||
|
||||
import com.beust.jcommander.Parameter;
|
||||
import com.beust.jcommander.Parameters;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonParser;
|
||||
import google.registry.config.RegistryConfig.Config;
|
||||
import google.registry.request.Action.Service;
|
||||
import jakarta.inject.Inject;
|
||||
import java.io.IOException;
|
||||
import java.util.Optional;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/** Command to manually perform an authenticated RDAP query. */
|
||||
@Parameters(separators = " =", commandDescription = "Manually perform an authenticated RDAP query")
|
||||
public final class RdapQueryCommand implements CommandWithConnection {
|
||||
|
||||
private static final Gson GSON = new GsonBuilder().setPrettyPrinting().create();
|
||||
|
||||
enum RdapQueryType {
|
||||
DOMAIN("/rdap/domain/%s"),
|
||||
DOMAIN_SEARCH("/rdap/domains", "name"),
|
||||
NAMESERVER("/rdap/nameserver/%s"),
|
||||
NAMESERVER_SEARCH("/rdap/nameservers", "name"),
|
||||
ENTITY("/rdap/entity/%s"),
|
||||
ENTITY_SEARCH("/rdap/entities", "fn");
|
||||
|
||||
private final String pathFormat;
|
||||
private final Optional<String> searchParamKey;
|
||||
|
||||
RdapQueryType(String pathFormat) {
|
||||
this(pathFormat, null);
|
||||
}
|
||||
|
||||
RdapQueryType(String pathFormat, @Nullable String searchParamKey) {
|
||||
this.pathFormat = pathFormat;
|
||||
this.searchParamKey = Optional.ofNullable(searchParamKey);
|
||||
}
|
||||
|
||||
String getQueryPath(String queryTerm) {
|
||||
return String.format(pathFormat, queryTerm);
|
||||
}
|
||||
|
||||
ImmutableMap<String, String> getQueryParameters(String queryTerm) {
|
||||
return searchParamKey.map(key -> ImmutableMap.of(key, queryTerm)).orElse(ImmutableMap.of());
|
||||
}
|
||||
}
|
||||
|
||||
@Parameter(names = "--type", description = "The type of RDAP query to perform.", required = true)
|
||||
private RdapQueryType type;
|
||||
|
||||
@Parameter(
|
||||
description = "The main query term (e.g., a domain name or search pattern).",
|
||||
required = true)
|
||||
private String queryTerm;
|
||||
|
||||
@Inject ServiceConnection defaultConnection;
|
||||
|
||||
@Inject
|
||||
@Config("useCanary")
|
||||
boolean useCanary;
|
||||
|
||||
@Override
|
||||
public void setConnection(ServiceConnection connection) {
|
||||
this.defaultConnection = connection;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() throws IOException {
|
||||
checkState(defaultConnection != null, "ServiceConnection was not set by RegistryCli.");
|
||||
|
||||
String path = type.getQueryPath(queryTerm);
|
||||
ImmutableMap<String, String> queryParams = type.getQueryParameters(queryTerm);
|
||||
|
||||
ServiceConnection pubapiConnection = defaultConnection.withService(Service.PUBAPI, useCanary);
|
||||
String rdapResponse = pubapiConnection.sendGetRequest(path, queryParams);
|
||||
|
||||
JsonElement rdapJson = JsonParser.parseString(rdapResponse);
|
||||
System.out.println(GSON.toJson(rdapJson));
|
||||
}
|
||||
}
|
||||
@@ -98,6 +98,7 @@ public final class RegistryTool {
|
||||
.put("login", LoginCommand.class)
|
||||
.put("logout", LogoutCommand.class)
|
||||
.put("pending_escrow", PendingEscrowCommand.class)
|
||||
.put("rdap_query", RdapQueryCommand.class)
|
||||
.put("recreate_billing_recurrences", RecreateBillingRecurrencesCommand.class)
|
||||
.put("registrar_poc", RegistrarPocCommand.class)
|
||||
.put("renew_domain", RenewDomainCommand.class)
|
||||
|
||||
@@ -135,6 +135,8 @@ interface RegistryToolComponent {
|
||||
|
||||
void inject(PendingEscrowCommand command);
|
||||
|
||||
void inject(RdapQueryCommand command);
|
||||
|
||||
void inject(RenewDomainCommand command);
|
||||
|
||||
void inject(SaveSqlCredentialCommand command);
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
// Copyright 2025 The Nomulus Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package google.registry.tools;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import com.beust.jcommander.ParameterException;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import google.registry.request.Action.Service;
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.mockito.junit.jupiter.MockitoSettings;
|
||||
import org.mockito.quality.Strictness;
|
||||
|
||||
/** Unit tests for {@link RdapQueryCommand}. */
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
@MockitoSettings(strictness = Strictness.LENIENT)
|
||||
class RdapQueryCommandTest extends CommandTestCase<RdapQueryCommand> {
|
||||
|
||||
@Mock private ServiceConnection mockDefaultConnection;
|
||||
@Mock private ServiceConnection mockPubapiConnection;
|
||||
|
||||
@BeforeEach
|
||||
void beforeEach() throws IOException {
|
||||
command.setConnection(mockDefaultConnection);
|
||||
when(mockDefaultConnection.withService(Service.PUBAPI, false)).thenReturn(mockPubapiConnection);
|
||||
when(mockPubapiConnection.sendGetRequest(anyString(), any(Map.class))).thenReturn("");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_domainLookup() throws Exception {
|
||||
runCommand("--type=DOMAIN", "example.dev");
|
||||
verify(mockPubapiConnection).sendGetRequest("/rdap/domain/example.dev", ImmutableMap.of());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_domainSearch() throws Exception {
|
||||
runCommand("--type=DOMAIN_SEARCH", "exam*.dev");
|
||||
verify(mockPubapiConnection)
|
||||
.sendGetRequest("/rdap/domains", ImmutableMap.of("name", "exam*.dev"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_nameserverLookup() throws Exception {
|
||||
runCommand("--type=NAMESERVER", "ns1.example.com");
|
||||
verify(mockPubapiConnection)
|
||||
.sendGetRequest("/rdap/nameserver/ns1.example.com", ImmutableMap.of());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_nameserverSearch() throws Exception {
|
||||
runCommand("--type=NAMESERVER_SEARCH", "ns*.example.com");
|
||||
verify(mockPubapiConnection)
|
||||
.sendGetRequest("/rdap/nameservers", ImmutableMap.of("name", "ns*.example.com"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_entityLookup() throws Exception {
|
||||
runCommand("--type=ENTITY", "123-FOO");
|
||||
verify(mockPubapiConnection).sendGetRequest("/rdap/entity/123-FOO", ImmutableMap.of());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_entitySearch() throws Exception {
|
||||
runCommand("--type=ENTITY_SEARCH", "John*");
|
||||
verify(mockPubapiConnection).sendGetRequest("/rdap/entities", ImmutableMap.of("fn", "John*"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_missingType() {
|
||||
assertThrows(ParameterException.class, () -> runCommand("some-term"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_missingQueryTerm() {
|
||||
assertThrows(ParameterException.class, () -> runCommand("--type=DOMAIN"));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user