mirror of
https://github.com/google/nomulus.git
synced 2025-07-23 19:20:44 +02:00
Add console-api/settings/security endpoint (#2057)
This commit is contained in:
parent
3ea31d024e
commit
304e7c9726
8 changed files with 396 additions and 3 deletions
|
@ -50,6 +50,7 @@ import com.google.common.collect.Maps;
|
||||||
import com.google.common.collect.Range;
|
import com.google.common.collect.Range;
|
||||||
import com.google.common.collect.Sets;
|
import com.google.common.collect.Sets;
|
||||||
import com.google.common.collect.Streams;
|
import com.google.common.collect.Streams;
|
||||||
|
import com.google.gson.annotations.Expose;
|
||||||
import com.google.re2j.Pattern;
|
import com.google.re2j.Pattern;
|
||||||
import google.registry.model.Buildable;
|
import google.registry.model.Buildable;
|
||||||
import google.registry.model.CreateAutoTimestamp;
|
import google.registry.model.CreateAutoTimestamp;
|
||||||
|
@ -253,7 +254,7 @@ public class Registrar extends UpdateAutoTimestampEntity implements Buildable, J
|
||||||
// Authentication.
|
// Authentication.
|
||||||
|
|
||||||
/** X.509 PEM client certificate(s) used to authenticate registrar to EPP service. */
|
/** X.509 PEM client certificate(s) used to authenticate registrar to EPP service. */
|
||||||
String clientCertificate;
|
@Expose String clientCertificate;
|
||||||
|
|
||||||
/** Base64 encoded SHA256 hash of {@link #clientCertificate}. */
|
/** Base64 encoded SHA256 hash of {@link #clientCertificate}. */
|
||||||
String clientCertificateHash;
|
String clientCertificateHash;
|
||||||
|
@ -263,13 +264,13 @@ public class Registrar extends UpdateAutoTimestampEntity implements Buildable, J
|
||||||
*
|
*
|
||||||
* <p>This allows registrars to migrate certificates without downtime.
|
* <p>This allows registrars to migrate certificates without downtime.
|
||||||
*/
|
*/
|
||||||
String failoverClientCertificate;
|
@Expose String failoverClientCertificate;
|
||||||
|
|
||||||
/** Base64 encoded SHA256 hash of {@link #failoverClientCertificate}. */
|
/** Base64 encoded SHA256 hash of {@link #failoverClientCertificate}. */
|
||||||
String failoverClientCertificateHash;
|
String failoverClientCertificateHash;
|
||||||
|
|
||||||
/** An allow list of netmasks (in CIDR notation) which the client is allowed to connect from. */
|
/** An allow list of netmasks (in CIDR notation) which the client is allowed to connect from. */
|
||||||
List<CidrAddressBlock> ipAddressAllowList;
|
@Expose List<CidrAddressBlock> ipAddressAllowList;
|
||||||
|
|
||||||
/** A hashed password for EPP access. The hash is a base64 encoded SHA256 string. */
|
/** A hashed password for EPP access. The hash is a base64 encoded SHA256 string. */
|
||||||
String passwordHash;
|
String passwordHash;
|
||||||
|
|
|
@ -28,6 +28,7 @@ import google.registry.request.RequestScope;
|
||||||
import google.registry.ui.server.console.ConsoleDomainGetAction;
|
import google.registry.ui.server.console.ConsoleDomainGetAction;
|
||||||
import google.registry.ui.server.console.RegistrarsAction;
|
import google.registry.ui.server.console.RegistrarsAction;
|
||||||
import google.registry.ui.server.console.settings.ContactAction;
|
import google.registry.ui.server.console.settings.ContactAction;
|
||||||
|
import google.registry.ui.server.console.settings.SecurityAction;
|
||||||
import google.registry.ui.server.registrar.ConsoleOteSetupAction;
|
import google.registry.ui.server.registrar.ConsoleOteSetupAction;
|
||||||
import google.registry.ui.server.registrar.ConsoleRegistrarCreatorAction;
|
import google.registry.ui.server.registrar.ConsoleRegistrarCreatorAction;
|
||||||
import google.registry.ui.server.registrar.ConsoleUiAction;
|
import google.registry.ui.server.registrar.ConsoleUiAction;
|
||||||
|
@ -70,6 +71,8 @@ interface FrontendRequestComponent {
|
||||||
|
|
||||||
RegistrarsAction registrarsAction();
|
RegistrarsAction registrarsAction();
|
||||||
|
|
||||||
|
SecurityAction securityAction();
|
||||||
|
|
||||||
@Subcomponent.Builder
|
@Subcomponent.Builder
|
||||||
abstract class Builder implements RequestComponentBuilder<FrontendRequestComponent> {
|
abstract class Builder implements RequestComponentBuilder<FrontendRequestComponent> {
|
||||||
@Override public abstract Builder requestModule(RequestModule requestModule);
|
@Override public abstract Builder requestModule(RequestModule requestModule);
|
||||||
|
|
|
@ -0,0 +1,171 @@
|
||||||
|
// Copyright 2023 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.ui.server.console.settings;
|
||||||
|
|
||||||
|
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
|
||||||
|
import static google.registry.request.Action.Method.GET;
|
||||||
|
import static google.registry.request.Action.Method.POST;
|
||||||
|
|
||||||
|
import avro.shaded.com.google.common.collect.ImmutableList;
|
||||||
|
import com.google.api.client.http.HttpStatusCodes;
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import google.registry.flows.certs.CertificateChecker;
|
||||||
|
import google.registry.flows.certs.CertificateChecker.InsecureCertificateException;
|
||||||
|
import google.registry.model.console.ConsolePermission;
|
||||||
|
import google.registry.model.console.User;
|
||||||
|
import google.registry.model.registrar.Registrar;
|
||||||
|
import google.registry.request.Action;
|
||||||
|
import google.registry.request.Parameter;
|
||||||
|
import google.registry.request.Response;
|
||||||
|
import google.registry.request.auth.Auth;
|
||||||
|
import google.registry.request.auth.AuthResult;
|
||||||
|
import google.registry.request.auth.AuthenticatedRegistrarAccessor;
|
||||||
|
import google.registry.request.auth.AuthenticatedRegistrarAccessor.RegistrarAccessDeniedException;
|
||||||
|
import google.registry.ui.server.registrar.JsonGetAction;
|
||||||
|
import java.util.Optional;
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
|
@Action(
|
||||||
|
service = Action.Service.DEFAULT,
|
||||||
|
path = SecurityAction.PATH,
|
||||||
|
method = {GET, POST},
|
||||||
|
auth = Auth.AUTH_PUBLIC_LOGGED_IN)
|
||||||
|
public class SecurityAction implements JsonGetAction {
|
||||||
|
|
||||||
|
static final String PATH = "/console-api/settings/security";
|
||||||
|
private final HttpServletRequest req;
|
||||||
|
private final AuthResult authResult;
|
||||||
|
private final Response response;
|
||||||
|
private final Gson gson;
|
||||||
|
private final String registrarId;
|
||||||
|
private AuthenticatedRegistrarAccessor registrarAccessor;
|
||||||
|
private Optional<Registrar> registrar;
|
||||||
|
private CertificateChecker certificateChecker;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public SecurityAction(
|
||||||
|
HttpServletRequest req,
|
||||||
|
AuthResult authResult,
|
||||||
|
Response response,
|
||||||
|
Gson gson,
|
||||||
|
CertificateChecker certificateChecker,
|
||||||
|
AuthenticatedRegistrarAccessor registrarAccessor,
|
||||||
|
@Parameter("registrarId") String registrarId,
|
||||||
|
@Parameter("registrar") Optional<Registrar> registrar) {
|
||||||
|
this.req = req;
|
||||||
|
this.authResult = authResult;
|
||||||
|
this.response = response;
|
||||||
|
this.gson = gson;
|
||||||
|
this.registrarId = registrarId;
|
||||||
|
this.registrarAccessor = registrarAccessor;
|
||||||
|
this.registrar = registrar;
|
||||||
|
this.certificateChecker = certificateChecker;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
if (req.getMethod().equals(GET.toString())) {
|
||||||
|
getHandler();
|
||||||
|
} else {
|
||||||
|
postHandler();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void getHandler() {
|
||||||
|
try {
|
||||||
|
Registrar registrar = registrarAccessor.getRegistrar(registrarId);
|
||||||
|
response.setStatus(HttpStatusCodes.STATUS_CODE_OK);
|
||||||
|
response.setPayload(gson.toJson(registrar));
|
||||||
|
} catch (RegistrarAccessDeniedException e) {
|
||||||
|
response.setStatus(HttpStatusCodes.STATUS_CODE_FORBIDDEN);
|
||||||
|
response.setPayload(e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void postHandler() {
|
||||||
|
User user = authResult.userAuthInfo().get().consoleUser().get();
|
||||||
|
if (!user.getUserRoles().hasPermission(registrarId, ConsolePermission.EDIT_REGISTRAR_DETAILS)) {
|
||||||
|
response.setStatus(HttpStatusCodes.STATUS_CODE_FORBIDDEN);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!registrar.isPresent()) {
|
||||||
|
response.setStatus(HttpStatusCodes.STATUS_CODE_BAD_REQUEST);
|
||||||
|
response.setPayload(gson.toJson("'registrar' parameter is not present"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Registrar savedRegistrar;
|
||||||
|
try {
|
||||||
|
savedRegistrar = registrarAccessor.getRegistrar(registrarId);
|
||||||
|
} catch (RegistrarAccessDeniedException e) {
|
||||||
|
response.setStatus(HttpStatusCodes.STATUS_CODE_FORBIDDEN);
|
||||||
|
response.setPayload(e.getMessage());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
tm().transact(() -> setResponse(savedRegistrar));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setResponse(Registrar savedRegistrar) {
|
||||||
|
Registrar registrarParameter = registrar.get();
|
||||||
|
Registrar.Builder updatedRegistrar =
|
||||||
|
savedRegistrar
|
||||||
|
.asBuilder()
|
||||||
|
.setIpAddressAllowList(registrarParameter.getIpAddressAllowList());
|
||||||
|
|
||||||
|
boolean hasInvalidCerts =
|
||||||
|
ImmutableList.of(
|
||||||
|
registrarParameter.getClientCertificate(),
|
||||||
|
registrarParameter.getFailoverClientCertificate())
|
||||||
|
.stream()
|
||||||
|
.filter(Optional::isPresent)
|
||||||
|
.map(Optional::get)
|
||||||
|
.anyMatch(
|
||||||
|
cert -> {
|
||||||
|
try {
|
||||||
|
certificateChecker.validateCertificate(cert);
|
||||||
|
return false;
|
||||||
|
} catch (InsecureCertificateException e) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (hasInvalidCerts) {
|
||||||
|
response.setStatus(HttpStatusCodes.STATUS_CODE_BAD_REQUEST);
|
||||||
|
response.setPayload("Insecure Certificate in parameter");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
registrarParameter
|
||||||
|
.getClientCertificate()
|
||||||
|
.ifPresent(
|
||||||
|
newClientCert -> {
|
||||||
|
updatedRegistrar.setClientCertificate(newClientCert, tm().getTransactionTime());
|
||||||
|
});
|
||||||
|
|
||||||
|
registrarParameter
|
||||||
|
.getFailoverClientCertificate()
|
||||||
|
.ifPresent(
|
||||||
|
failoverCert -> {
|
||||||
|
updatedRegistrar.setFailoverClientCertificate(
|
||||||
|
failoverCert, tm().getTransactionTime());
|
||||||
|
});
|
||||||
|
|
||||||
|
tm().put(updatedRegistrar.build());
|
||||||
|
response.setStatus(HttpStatusCodes.STATUS_CODE_OK);
|
||||||
|
}
|
||||||
|
}
|
|
@ -24,6 +24,7 @@ import com.google.gson.Gson;
|
||||||
import com.google.gson.JsonObject;
|
import com.google.gson.JsonObject;
|
||||||
import dagger.Module;
|
import dagger.Module;
|
||||||
import dagger.Provides;
|
import dagger.Provides;
|
||||||
|
import google.registry.model.registrar.Registrar;
|
||||||
import google.registry.model.registrar.RegistrarPoc;
|
import google.registry.model.registrar.RegistrarPoc;
|
||||||
import google.registry.request.OptionalJsonPayload;
|
import google.registry.request.OptionalJsonPayload;
|
||||||
import google.registry.request.Parameter;
|
import google.registry.request.Parameter;
|
||||||
|
@ -187,4 +188,15 @@ public final class RegistrarConsoleModule {
|
||||||
static String provideRegistrarId(HttpServletRequest req) {
|
static String provideRegistrarId(HttpServletRequest req) {
|
||||||
return extractRequiredParameter(req, "registrarId");
|
return extractRequiredParameter(req, "registrarId");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Parameter("registrar")
|
||||||
|
public static Optional<Registrar> provideRegistrar(
|
||||||
|
Gson gson, @OptionalJsonPayload Optional<JsonObject> payload) {
|
||||||
|
if (payload.isPresent() && payload.get().has("registrar")) {
|
||||||
|
return Optional.of(gson.fromJson(payload.get().get("registrar"), Registrar.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,183 @@
|
||||||
|
// Copyright 2023 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.ui.server.console.settings;
|
||||||
|
|
||||||
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
import static google.registry.testing.CertificateSamples.SAMPLE_CERT;
|
||||||
|
import static google.registry.testing.CertificateSamples.SAMPLE_CERT2;
|
||||||
|
import static google.registry.testing.DatabaseHelper.loadRegistrar;
|
||||||
|
import static google.registry.testing.DatabaseHelper.persistResource;
|
||||||
|
import static google.registry.testing.SqlHelper.saveRegistrar;
|
||||||
|
import static google.registry.util.DateTimeUtils.START_OF_TIME;
|
||||||
|
import static org.mockito.Mockito.doReturn;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
import com.google.api.client.http.HttpStatusCodes;
|
||||||
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
import com.google.common.collect.ImmutableSetMultimap;
|
||||||
|
import com.google.common.collect.ImmutableSortedMap;
|
||||||
|
import com.google.common.net.InetAddresses;
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import google.registry.flows.certs.CertificateChecker;
|
||||||
|
import google.registry.model.console.GlobalRole;
|
||||||
|
import google.registry.model.console.User;
|
||||||
|
import google.registry.model.console.UserRoles;
|
||||||
|
import google.registry.model.registrar.Registrar;
|
||||||
|
import google.registry.persistence.transaction.JpaTestExtensions;
|
||||||
|
import google.registry.request.Action;
|
||||||
|
import google.registry.request.RequestModule;
|
||||||
|
import google.registry.request.auth.AuthResult;
|
||||||
|
import google.registry.request.auth.AuthSettings.AuthLevel;
|
||||||
|
import google.registry.request.auth.AuthenticatedRegistrarAccessor;
|
||||||
|
import google.registry.request.auth.UserAuthInfo;
|
||||||
|
import google.registry.testing.FakeClock;
|
||||||
|
import google.registry.testing.FakeResponse;
|
||||||
|
import google.registry.ui.server.registrar.RegistrarConsoleModule;
|
||||||
|
import google.registry.util.CidrAddressBlock;
|
||||||
|
import google.registry.util.UtilsModule;
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.StringReader;
|
||||||
|
import java.util.Optional;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import org.joda.time.DateTime;
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||||
|
|
||||||
|
/** Tests for {@link google.registry.ui.server.console.settings.SecurityAction}. */
|
||||||
|
class SecurityActionTest {
|
||||||
|
|
||||||
|
private static String jsonRegistrar1 =
|
||||||
|
String.format(
|
||||||
|
"{\"registrarId\": \"registrarId\", \"clientCertificate\": \"%s\","
|
||||||
|
+ " \"ipAddressAllowList\": [\"192.168.1.1/32\"]}",
|
||||||
|
SAMPLE_CERT2);
|
||||||
|
private static final Gson GSON = UtilsModule.provideGson();
|
||||||
|
private final HttpServletRequest request = mock(HttpServletRequest.class);
|
||||||
|
private final FakeClock clock = new FakeClock();
|
||||||
|
private Registrar testRegistrar;
|
||||||
|
private FakeResponse response = new FakeResponse();
|
||||||
|
|
||||||
|
private AuthenticatedRegistrarAccessor registrarAccessor =
|
||||||
|
AuthenticatedRegistrarAccessor.createForTesting(
|
||||||
|
ImmutableSetMultimap.of("registrarId", AuthenticatedRegistrarAccessor.Role.ADMIN));
|
||||||
|
|
||||||
|
private CertificateChecker certificateChecker =
|
||||||
|
new CertificateChecker(
|
||||||
|
ImmutableSortedMap.of(START_OF_TIME, 20825, DateTime.parse("2020-09-01T00:00:00Z"), 398),
|
||||||
|
30,
|
||||||
|
15,
|
||||||
|
2048,
|
||||||
|
ImmutableSet.of("secp256r1", "secp384r1"),
|
||||||
|
clock);
|
||||||
|
|
||||||
|
@RegisterExtension
|
||||||
|
final JpaTestExtensions.JpaIntegrationTestExtension jpa =
|
||||||
|
new JpaTestExtensions.Builder().withClock(clock).buildIntegrationTestExtension();
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
void beforeEach() {
|
||||||
|
testRegistrar = saveRegistrar("registrarId");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testSuccess_getRegistrarInfo() throws IOException {
|
||||||
|
persistResource(
|
||||||
|
testRegistrar
|
||||||
|
.asBuilder()
|
||||||
|
.setClientCertificate(SAMPLE_CERT, clock.nowUtc())
|
||||||
|
.setIpAddressAllowList(
|
||||||
|
ImmutableSet.of(
|
||||||
|
CidrAddressBlock.create(InetAddresses.forString("192.168.1.1"), 32),
|
||||||
|
CidrAddressBlock.create(InetAddresses.forString("2001:db8::1"), 128)))
|
||||||
|
.build());
|
||||||
|
SecurityAction action =
|
||||||
|
createAction(
|
||||||
|
Action.Method.GET,
|
||||||
|
AuthResult.create(
|
||||||
|
AuthLevel.USER,
|
||||||
|
UserAuthInfo.create(
|
||||||
|
createUser(new UserRoles.Builder().setGlobalRole(GlobalRole.FTE).build()))),
|
||||||
|
testRegistrar.getRegistrarId());
|
||||||
|
action.run();
|
||||||
|
assertThat(response.getStatus()).isEqualTo(HttpStatusCodes.STATUS_CODE_OK);
|
||||||
|
String payload = response.getPayload().replace("\\n", "").replace("\\u003d", "=");
|
||||||
|
assertThat(payload).contains(SAMPLE_CERT.replace("\n", ""));
|
||||||
|
assertThat(payload).contains("192.168.1.1/32");
|
||||||
|
assertThat(payload).contains("2001:db8:0:0:0:0:0:1/128");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testSuccess_postRegistrarInfo() throws IOException {
|
||||||
|
clock.setTo(DateTime.parse("2020-11-01T00:00:00Z"));
|
||||||
|
SecurityAction action =
|
||||||
|
createAction(
|
||||||
|
Action.Method.POST,
|
||||||
|
AuthResult.create(
|
||||||
|
AuthLevel.USER,
|
||||||
|
UserAuthInfo.create(
|
||||||
|
createUser(new UserRoles.Builder().setGlobalRole(GlobalRole.FTE).build()))),
|
||||||
|
testRegistrar.getRegistrarId());
|
||||||
|
action.run();
|
||||||
|
assertThat(response.getStatus()).isEqualTo(HttpStatusCodes.STATUS_CODE_OK);
|
||||||
|
Registrar r = loadRegistrar(testRegistrar.getRegistrarId());
|
||||||
|
assertThat(r.getClientCertificateHash().get())
|
||||||
|
.isEqualTo("GNd6ZP8/n91t9UTnpxR8aH7aAW4+CpvufYx9ViGbcMY");
|
||||||
|
assertThat(r.getIpAddressAllowList().get(0).getIp()).isEqualTo("192.168.1.1");
|
||||||
|
assertThat(r.getIpAddressAllowList().get(0).getNetmask()).isEqualTo(32);
|
||||||
|
}
|
||||||
|
|
||||||
|
private User createUser(UserRoles userRoles) {
|
||||||
|
return new User.Builder()
|
||||||
|
.setEmailAddress("email@email.com")
|
||||||
|
.setGaiaId("TestUserId")
|
||||||
|
.setUserRoles(userRoles)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
private SecurityAction createAction(
|
||||||
|
Action.Method method, AuthResult authResult, String registrarId) throws IOException {
|
||||||
|
when(request.getMethod()).thenReturn(method.toString());
|
||||||
|
if (method.equals(Action.Method.GET)) {
|
||||||
|
return new SecurityAction(
|
||||||
|
request,
|
||||||
|
authResult,
|
||||||
|
response,
|
||||||
|
GSON,
|
||||||
|
certificateChecker,
|
||||||
|
registrarAccessor,
|
||||||
|
registrarId,
|
||||||
|
Optional.empty());
|
||||||
|
} else {
|
||||||
|
doReturn(new BufferedReader(new StringReader("{\"registrar\":" + jsonRegistrar1 + "}")))
|
||||||
|
.when(request)
|
||||||
|
.getReader();
|
||||||
|
Optional<Registrar> maybeRegistrar =
|
||||||
|
RegistrarConsoleModule.provideRegistrar(
|
||||||
|
GSON, RequestModule.provideJsonBody(request, GSON));
|
||||||
|
return new SecurityAction(
|
||||||
|
request,
|
||||||
|
authResult,
|
||||||
|
response,
|
||||||
|
GSON,
|
||||||
|
certificateChecker,
|
||||||
|
registrarAccessor,
|
||||||
|
registrarId,
|
||||||
|
maybeRegistrar);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,6 +3,7 @@ PATH CLASS METHODS OK AUTH_ME
|
||||||
/console-api/domain ConsoleDomainGetAction GET n API,LEGACY USER PUBLIC
|
/console-api/domain ConsoleDomainGetAction GET n API,LEGACY USER PUBLIC
|
||||||
/console-api/registrars RegistrarsAction GET n API,LEGACY USER PUBLIC
|
/console-api/registrars RegistrarsAction GET n API,LEGACY USER PUBLIC
|
||||||
/console-api/settings/contacts ContactAction GET,POST n API,LEGACY USER PUBLIC
|
/console-api/settings/contacts ContactAction GET,POST n API,LEGACY USER PUBLIC
|
||||||
|
/console-api/settings/security SecurityAction GET,POST n API,LEGACY USER PUBLIC
|
||||||
/registrar ConsoleUiAction GET n API,LEGACY NONE PUBLIC
|
/registrar ConsoleUiAction GET n API,LEGACY NONE PUBLIC
|
||||||
/registrar-create ConsoleRegistrarCreatorAction POST,GET n API,LEGACY NONE PUBLIC
|
/registrar-create ConsoleRegistrarCreatorAction POST,GET n API,LEGACY NONE PUBLIC
|
||||||
/registrar-ote-setup ConsoleOteSetupAction POST,GET n API,LEGACY NONE PUBLIC
|
/registrar-ote-setup ConsoleOteSetupAction POST,GET n API,LEGACY NONE PUBLIC
|
||||||
|
|
|
@ -19,6 +19,10 @@ import static com.google.common.base.Preconditions.checkArgument;
|
||||||
import com.google.common.collect.AbstractSequentialIterator;
|
import com.google.common.collect.AbstractSequentialIterator;
|
||||||
import com.google.common.flogger.FluentLogger;
|
import com.google.common.flogger.FluentLogger;
|
||||||
import com.google.common.net.InetAddresses;
|
import com.google.common.net.InetAddresses;
|
||||||
|
import com.google.gson.TypeAdapter;
|
||||||
|
import com.google.gson.stream.JsonReader;
|
||||||
|
import com.google.gson.stream.JsonWriter;
|
||||||
|
import java.io.IOException;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
import java.net.UnknownHostException;
|
import java.net.UnknownHostException;
|
||||||
|
@ -476,4 +480,20 @@ public class CidrAddressBlock implements Iterable<InetAddress>, Serializable {
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return getCidrString(ip, netmask);
|
return getCidrString(ip, netmask);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class CidrAddressBlockAdapter extends TypeAdapter<CidrAddressBlock> {
|
||||||
|
@Override
|
||||||
|
public CidrAddressBlock read(JsonReader reader) throws IOException {
|
||||||
|
String stringValue = reader.nextString();
|
||||||
|
if (stringValue.equals("null")) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return new CidrAddressBlock(stringValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void write(JsonWriter writer, CidrAddressBlock cidrAddressBlock) throws IOException {
|
||||||
|
writer.value(cidrAddressBlock.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@ import com.google.gson.GsonBuilder;
|
||||||
import dagger.Binds;
|
import dagger.Binds;
|
||||||
import dagger.Module;
|
import dagger.Module;
|
||||||
import dagger.Provides;
|
import dagger.Provides;
|
||||||
|
import google.registry.util.CidrAddressBlock.CidrAddressBlockAdapter;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.security.ProviderException;
|
import java.security.ProviderException;
|
||||||
import java.security.SecureRandom;
|
import java.security.SecureRandom;
|
||||||
|
@ -79,6 +80,7 @@ public abstract class UtilsModule {
|
||||||
public static Gson provideGson() {
|
public static Gson provideGson() {
|
||||||
return new GsonBuilder()
|
return new GsonBuilder()
|
||||||
.registerTypeAdapter(DateTime.class, new DateTimeTypeAdapter())
|
.registerTypeAdapter(DateTime.class, new DateTimeTypeAdapter())
|
||||||
|
.registerTypeAdapter(CidrAddressBlock.class, new CidrAddressBlockAdapter())
|
||||||
.excludeFieldsWithoutExposeAnnotation()
|
.excludeFieldsWithoutExposeAnnotation()
|
||||||
.create();
|
.create();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue