mirror of
https://github.com/google/nomulus
synced 2025-12-23 06:15:42 +00:00
Add a separate RegistryLock action for the console (#2411)
This handles both GET and POST requests. For POST requests it doesn't actually change anything about the domains because we will need to add a verification action (this will be done in a future PR).
This commit is contained in:
@@ -18,6 +18,7 @@ import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static google.registry.util.DateTimeUtils.isBeforeOrAt;
|
||||
import static google.registry.util.PreconditionsUtils.checkArgumentNotNull;
|
||||
|
||||
import com.google.gson.annotations.Expose;
|
||||
import google.registry.model.Buildable;
|
||||
import google.registry.model.CreateAutoTimestamp;
|
||||
import google.registry.model.UpdateAutoTimestampEntity;
|
||||
@@ -90,6 +91,7 @@ public final class RegistryLock extends UpdateAutoTimestampEntity implements Bui
|
||||
|
||||
// TODO (b/140568328): remove this when everything is in Cloud SQL and we can join on "domain"
|
||||
@Column(nullable = false)
|
||||
@Expose
|
||||
private String domainName;
|
||||
|
||||
/**
|
||||
@@ -100,7 +102,7 @@ public final class RegistryLock extends UpdateAutoTimestampEntity implements Bui
|
||||
private String registrarId;
|
||||
|
||||
/** The POC that performed the action, or null if it was a superuser. */
|
||||
private String registrarPocId;
|
||||
@Expose private String registrarPocId;
|
||||
|
||||
/** When the lock is first requested. */
|
||||
@AttributeOverrides({
|
||||
@@ -108,22 +110,23 @@ public final class RegistryLock extends UpdateAutoTimestampEntity implements Bui
|
||||
name = "creationTime",
|
||||
column = @Column(name = "lockRequestTime", nullable = false))
|
||||
})
|
||||
@Expose
|
||||
private final CreateAutoTimestamp lockRequestTime = CreateAutoTimestamp.create(null);
|
||||
|
||||
/** When the unlock is first requested. */
|
||||
private DateTime unlockRequestTime;
|
||||
@Expose private DateTime unlockRequestTime;
|
||||
|
||||
/**
|
||||
* When the user has verified the lock. If this field is null, it means the lock has not been
|
||||
* verified yet (and thus not been put into effect).
|
||||
*/
|
||||
private DateTime lockCompletionTime;
|
||||
@Expose private DateTime lockCompletionTime;
|
||||
|
||||
/**
|
||||
* When the user has verified the unlock of this lock. If this field is null, it means the unlock
|
||||
* action has not been verified yet (and has not been put into effect).
|
||||
*/
|
||||
private DateTime unlockCompletionTime;
|
||||
@Expose private DateTime unlockCompletionTime;
|
||||
|
||||
/** The user must provide the random verification code in order to complete the action. */
|
||||
@Column(nullable = false)
|
||||
@@ -134,6 +137,7 @@ public final class RegistryLock extends UpdateAutoTimestampEntity implements Bui
|
||||
* this case, the action was performed by a registry admin rather than a registrar.
|
||||
*/
|
||||
@Column(nullable = false)
|
||||
@Expose
|
||||
private boolean isSuperuser;
|
||||
|
||||
/** The lock that undoes this lock, if this lock has been unlocked and the domain locked again. */
|
||||
|
||||
@@ -112,6 +112,7 @@ import google.registry.ui.server.console.ConsoleDomainGetAction;
|
||||
import google.registry.ui.server.console.ConsoleDomainListAction;
|
||||
import google.registry.ui.server.console.ConsoleDumDownloadAction;
|
||||
import google.registry.ui.server.console.ConsoleEppPasswordAction;
|
||||
import google.registry.ui.server.console.ConsoleRegistryLockAction;
|
||||
import google.registry.ui.server.console.ConsoleUserDataAction;
|
||||
import google.registry.ui.server.console.RegistrarsAction;
|
||||
import google.registry.ui.server.console.settings.ContactAction;
|
||||
@@ -186,6 +187,8 @@ interface RequestComponent {
|
||||
|
||||
ConsoleRegistrarCreatorAction consoleRegistrarCreatorAction();
|
||||
|
||||
ConsoleRegistryLockAction consoleRegistryLockAction();
|
||||
|
||||
ConsoleUiAction consoleUiAction();
|
||||
|
||||
ConsoleUserDataAction consoleUserDataAction();
|
||||
|
||||
@@ -29,6 +29,7 @@ import google.registry.ui.server.console.ConsoleDomainGetAction;
|
||||
import google.registry.ui.server.console.ConsoleDomainListAction;
|
||||
import google.registry.ui.server.console.ConsoleDumDownloadAction;
|
||||
import google.registry.ui.server.console.ConsoleEppPasswordAction;
|
||||
import google.registry.ui.server.console.ConsoleRegistryLockAction;
|
||||
import google.registry.ui.server.console.ConsoleUserDataAction;
|
||||
import google.registry.ui.server.console.RegistrarsAction;
|
||||
import google.registry.ui.server.console.settings.ContactAction;
|
||||
@@ -64,6 +65,9 @@ public interface FrontendRequestComponent {
|
||||
|
||||
ConsoleOteSetupAction consoleOteSetupAction();
|
||||
ConsoleRegistrarCreatorAction consoleRegistrarCreatorAction();
|
||||
|
||||
ConsoleRegistryLockAction consoleRegistryLockAction();
|
||||
|
||||
ConsoleUiAction consoleUiAction();
|
||||
|
||||
ConsoleUserDataAction consoleUserDataAction();
|
||||
|
||||
@@ -106,6 +106,20 @@ public final class RequestParameters {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns first GET or POST parameter associated with {@code name} as a long.
|
||||
*
|
||||
* @throws BadRequestException if request parameter is present but not a valid long
|
||||
*/
|
||||
public static Optional<Long> extractOptionalLongParameter(HttpServletRequest req, String name) {
|
||||
String stringParam = req.getParameter(name);
|
||||
try {
|
||||
return isNullOrEmpty(stringParam) ? Optional.empty() : Optional.of(Long.valueOf(stringParam));
|
||||
} catch (NumberFormatException e) {
|
||||
throw new BadRequestException("Expected long: " + name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns first GET or POST parameter associated with {@code name} as a long.
|
||||
*
|
||||
|
||||
@@ -0,0 +1,215 @@
|
||||
// Copyright 2024 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;
|
||||
|
||||
import static com.google.common.collect.ImmutableList.toImmutableList;
|
||||
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 static google.registry.request.RequestParameters.extractBooleanParameter;
|
||||
import static google.registry.request.RequestParameters.extractOptionalLongParameter;
|
||||
import static google.registry.request.RequestParameters.extractOptionalParameter;
|
||||
import static google.registry.request.RequestParameters.extractRequiredParameter;
|
||||
import static google.registry.ui.server.registrar.RegistryLockPostAction.VERIFICATION_EMAIL_TEMPLATE;
|
||||
|
||||
import com.google.api.client.http.HttpStatusCodes;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.flogger.FluentLogger;
|
||||
import com.google.gson.Gson;
|
||||
import google.registry.flows.EppException;
|
||||
import google.registry.flows.domain.DomainFlowUtils;
|
||||
import google.registry.groups.GmailClient;
|
||||
import google.registry.model.console.ConsolePermission;
|
||||
import google.registry.model.console.User;
|
||||
import google.registry.model.domain.RegistryLock;
|
||||
import google.registry.model.registrar.Registrar;
|
||||
import google.registry.model.tld.RegistryLockDao;
|
||||
import google.registry.request.Action;
|
||||
import google.registry.request.HttpException;
|
||||
import google.registry.request.Parameter;
|
||||
import google.registry.request.Response;
|
||||
import google.registry.request.auth.Auth;
|
||||
import google.registry.tools.DomainLockUtils;
|
||||
import google.registry.ui.server.registrar.ConsoleApiParams;
|
||||
import google.registry.util.EmailMessage;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.Optional;
|
||||
import javax.inject.Inject;
|
||||
import javax.mail.internet.AddressException;
|
||||
import javax.mail.internet.InternetAddress;
|
||||
import org.apache.http.client.utils.URIBuilder;
|
||||
import org.joda.time.Duration;
|
||||
|
||||
/**
|
||||
* Handler for retrieving / creating registry lock requests in the console.
|
||||
*
|
||||
* <p>Note: two-factor verification of the locks occurs separately (TODO: link the verification
|
||||
* action).
|
||||
*/
|
||||
@Action(
|
||||
service = Action.Service.DEFAULT,
|
||||
path = ConsoleRegistryLockAction.PATH,
|
||||
method = {GET, POST},
|
||||
auth = Auth.AUTH_PUBLIC_LOGGED_IN)
|
||||
public class ConsoleRegistryLockAction extends ConsoleApiAction {
|
||||
|
||||
private static final FluentLogger logger = FluentLogger.forEnclosingClass();
|
||||
|
||||
static final String PATH = "/console-api/registry-lock";
|
||||
|
||||
private final DomainLockUtils domainLockUtils;
|
||||
private final GmailClient gmailClient;
|
||||
private final Gson gson;
|
||||
private final String registrarId;
|
||||
|
||||
@Inject
|
||||
public ConsoleRegistryLockAction(
|
||||
ConsoleApiParams consoleApiParams,
|
||||
DomainLockUtils domainLockUtils,
|
||||
GmailClient gmailClient,
|
||||
Gson gson,
|
||||
@Parameter("registrarId") String registrarId) {
|
||||
super(consoleApiParams);
|
||||
this.domainLockUtils = domainLockUtils;
|
||||
this.gmailClient = gmailClient;
|
||||
this.gson = gson;
|
||||
this.registrarId = registrarId;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void getHandler(User user) {
|
||||
if (!user.getUserRoles().hasPermission(registrarId, ConsolePermission.REGISTRY_LOCK)) {
|
||||
consoleApiParams.response().setStatus(HttpStatusCodes.STATUS_CODE_FORBIDDEN);
|
||||
return;
|
||||
}
|
||||
consoleApiParams.response().setPayload(gson.toJson(getLockedDomains()));
|
||||
consoleApiParams.response().setStatus(HttpStatusCodes.STATUS_CODE_OK);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void postHandler(User user) {
|
||||
HttpServletRequest req = consoleApiParams.request();
|
||||
Response response = consoleApiParams.response();
|
||||
// User must have the proper permission on the registrar
|
||||
if (!user.getUserRoles().hasPermission(registrarId, ConsolePermission.REGISTRY_LOCK)) {
|
||||
setFailedResponse("", HttpStatusCodes.STATUS_CODE_FORBIDDEN);
|
||||
return;
|
||||
}
|
||||
|
||||
// Shouldn't happen, but double-check the registrar has registry lock enabled
|
||||
Registrar registrar = Registrar.loadByRegistrarIdCached(registrarId).get();
|
||||
if (!registrar.isRegistryLockAllowed()) {
|
||||
setFailedResponse(
|
||||
String.format("Registry lock not allowed for registrar %s", registrarId),
|
||||
HttpStatusCodes.STATUS_CODE_BAD_REQUEST);
|
||||
return;
|
||||
}
|
||||
|
||||
// Retrieve and validate the necessary params
|
||||
String domainName;
|
||||
boolean isLock;
|
||||
Optional<String> maybePassword;
|
||||
Optional<Long> relockDurationMillis;
|
||||
|
||||
try {
|
||||
domainName = extractRequiredParameter(req, "domainName");
|
||||
isLock = extractBooleanParameter(req, "isLock");
|
||||
maybePassword = extractOptionalParameter(req, "password");
|
||||
relockDurationMillis = extractOptionalLongParameter(req, "relockDurationMillis");
|
||||
DomainFlowUtils.validateDomainName(domainName);
|
||||
} catch (HttpException.BadRequestException | EppException e) {
|
||||
logger.atWarning().withCause(e).log("Bad request when attempting registry lock/unlock");
|
||||
setFailedResponse(e.getMessage(), HttpStatusCodes.STATUS_CODE_BAD_REQUEST);
|
||||
return;
|
||||
}
|
||||
|
||||
// Passwords aren't required for admin users, otherwise we need to validate it
|
||||
boolean isAdmin = user.getUserRoles().isAdmin();
|
||||
if (!isAdmin) {
|
||||
if (maybePassword.isEmpty()) {
|
||||
setFailedResponse("No password provided", HttpStatusCodes.STATUS_CODE_BAD_REQUEST);
|
||||
return;
|
||||
}
|
||||
if (!user.verifyRegistryLockPassword(maybePassword.get())) {
|
||||
setFailedResponse(
|
||||
"Incorrect registry lock password", HttpStatusCodes.STATUS_CODE_UNAUTHORIZED);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
String userEmail = user.getEmailAddress();
|
||||
try {
|
||||
tm().transact(
|
||||
() -> {
|
||||
RegistryLock registryLock =
|
||||
isLock
|
||||
? domainLockUtils.saveNewRegistryLockRequest(
|
||||
domainName, registrarId, userEmail, isAdmin)
|
||||
: domainLockUtils.saveNewRegistryUnlockRequest(
|
||||
domainName,
|
||||
registrarId,
|
||||
isAdmin,
|
||||
relockDurationMillis.map(Duration::new));
|
||||
sendVerificationEmail(registryLock, userEmail, isLock);
|
||||
});
|
||||
} catch (IllegalArgumentException e) {
|
||||
// Catch IllegalArgumentExceptions separately to give a nicer error message and code
|
||||
logger.atWarning().withCause(e).log("Failed to lock/unlock domain");
|
||||
setFailedResponse(e.getMessage(), HttpStatusCodes.STATUS_CODE_BAD_REQUEST);
|
||||
return;
|
||||
} catch (Throwable t) {
|
||||
logger.atWarning().withCause(t).log("Failed to lock/unlock domain");
|
||||
setFailedResponse("Internal server error", HttpStatusCodes.STATUS_CODE_SERVER_ERROR);
|
||||
return;
|
||||
}
|
||||
response.setStatus(HttpStatusCodes.STATUS_CODE_OK);
|
||||
}
|
||||
|
||||
private void sendVerificationEmail(RegistryLock lock, String userEmail, boolean isLock) {
|
||||
try {
|
||||
String url =
|
||||
new URIBuilder()
|
||||
.setScheme("https")
|
||||
.setHost(consoleApiParams.request().getServerName())
|
||||
// TODO: replace this with the PATH in ConsoleRegistryLockVerifyAction once it exists
|
||||
.setPath("/console-api/registry-lock-verify")
|
||||
.setParameter("lockVerificationCode", lock.getVerificationCode())
|
||||
.setParameter("isLock", String.valueOf(isLock))
|
||||
.build()
|
||||
.toString();
|
||||
String body = String.format(VERIFICATION_EMAIL_TEMPLATE, lock.getDomainName(), url);
|
||||
ImmutableList<InternetAddress> recipients =
|
||||
ImmutableList.of(new InternetAddress(userEmail, true));
|
||||
String action = isLock ? "lock" : "unlock";
|
||||
gmailClient.sendEmail(
|
||||
EmailMessage.newBuilder()
|
||||
.setBody(body)
|
||||
.setSubject(String.format("Registry %s verification", action))
|
||||
.setRecipients(recipients)
|
||||
.build());
|
||||
} catch (AddressException | URISyntaxException e) {
|
||||
throw new RuntimeException(e); // caught above -- this is so we can run in a transaction
|
||||
}
|
||||
}
|
||||
|
||||
private ImmutableList<RegistryLock> getLockedDomains() {
|
||||
return tm().transact(
|
||||
() ->
|
||||
RegistryLockDao.getLocksByRegistrarId(registrarId).stream()
|
||||
.filter(lock -> !lock.isLockRequestExpired(tm().getTransactionTime()))
|
||||
.collect(toImmutableList()));
|
||||
}
|
||||
}
|
||||
@@ -70,17 +70,16 @@ import org.joda.time.Duration;
|
||||
auth = Auth.AUTH_PUBLIC_LOGGED_IN)
|
||||
public class RegistryLockPostAction implements Runnable, JsonActionRunner.JsonAction {
|
||||
public static final String PATH = "/registry-lock-post";
|
||||
|
||||
private static final FluentLogger logger = FluentLogger.forEnclosingClass();
|
||||
private static final Gson GSON = new Gson();
|
||||
|
||||
private static final String VERIFICATION_EMAIL_TEMPLATE =
|
||||
public static final String VERIFICATION_EMAIL_TEMPLATE =
|
||||
"""
|
||||
Please click the link below to perform the lock / unlock action on domain %s. Note: this\
|
||||
code will expire in one hour.
|
||||
|
||||
%s""";
|
||||
|
||||
private static final FluentLogger logger = FluentLogger.forEnclosingClass();
|
||||
private static final Gson GSON = new Gson();
|
||||
|
||||
private final HttpServletRequest req;
|
||||
private final JsonActionRunner jsonActionRunner;
|
||||
private final AuthResult authResult;
|
||||
|
||||
@@ -0,0 +1,539 @@
|
||||
// Copyright 2024 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;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static google.registry.testing.DatabaseHelper.createTld;
|
||||
import static google.registry.testing.DatabaseHelper.loadByEntity;
|
||||
import static google.registry.testing.DatabaseHelper.loadRegistrar;
|
||||
import static google.registry.testing.DatabaseHelper.newDomain;
|
||||
import static google.registry.testing.DatabaseHelper.persistActiveDomain;
|
||||
import static google.registry.testing.DatabaseHelper.persistResource;
|
||||
import static google.registry.testing.SqlHelper.getMostRecentRegistryLockByRepoId;
|
||||
import static google.registry.testing.SqlHelper.saveRegistryLock;
|
||||
import static google.registry.tools.LockOrUnlockDomainCommand.REGISTRY_LOCK_STATUSES;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import com.google.api.client.http.HttpStatusCodes;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.gson.Gson;
|
||||
import google.registry.groups.GmailClient;
|
||||
import google.registry.model.console.GlobalRole;
|
||||
import google.registry.model.console.RegistrarRole;
|
||||
import google.registry.model.console.User;
|
||||
import google.registry.model.console.UserRoles;
|
||||
import google.registry.model.domain.Domain;
|
||||
import google.registry.model.domain.RegistryLock;
|
||||
import google.registry.model.eppcommon.StatusValue;
|
||||
import google.registry.persistence.transaction.JpaTestExtensions;
|
||||
import google.registry.request.RequestModule;
|
||||
import google.registry.request.auth.AuthResult;
|
||||
import google.registry.request.auth.UserAuthInfo;
|
||||
import google.registry.testing.CloudTasksHelper;
|
||||
import google.registry.testing.DeterministicStringGenerator;
|
||||
import google.registry.testing.FakeClock;
|
||||
import google.registry.testing.FakeConsoleApiParams;
|
||||
import google.registry.testing.FakeResponse;
|
||||
import google.registry.tools.DomainLockUtils;
|
||||
import google.registry.ui.server.registrar.ConsoleApiParams;
|
||||
import google.registry.util.EmailMessage;
|
||||
import google.registry.util.StringGenerator;
|
||||
import java.io.IOException;
|
||||
import java.util.Optional;
|
||||
import javax.mail.internet.InternetAddress;
|
||||
import org.joda.time.DateTime;
|
||||
import org.joda.time.Duration;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.mockito.junit.jupiter.MockitoSettings;
|
||||
import org.mockito.quality.Strictness;
|
||||
|
||||
/** Tests for {@link ConsoleRegistryLockAction}. */
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
@MockitoSettings(strictness = Strictness.LENIENT)
|
||||
public class ConsoleRegistryLockActionTest {
|
||||
|
||||
private static final String EMAIL_MESSAGE_TEMPLATE =
|
||||
"Please click the link below to perform the lock \\/ unlock action on domain example.test."
|
||||
+ " Note: this code will expire in one hour.\n\n"
|
||||
+ "https:\\/\\/registrarconsole.tld\\/console-api\\/registry-lock-verify\\?lockVerificationCode="
|
||||
+ "[0-9a-zA-Z_\\-]+&isLock=(true|false)";
|
||||
|
||||
private static final Gson GSON = RequestModule.provideGson();
|
||||
|
||||
private final FakeClock fakeClock = new FakeClock(DateTime.parse("2024-04-18T12:00:00.000Z"));
|
||||
|
||||
@RegisterExtension
|
||||
final JpaTestExtensions.JpaIntegrationTestExtension jpa =
|
||||
new JpaTestExtensions.Builder().withClock(fakeClock).buildIntegrationTestExtension();
|
||||
|
||||
@Mock GmailClient gmailClient;
|
||||
private ConsoleRegistryLockAction action;
|
||||
private Domain defaultDomain;
|
||||
private FakeResponse response;
|
||||
private User user;
|
||||
|
||||
@BeforeEach
|
||||
void beforeEach() throws Exception {
|
||||
createTld("test");
|
||||
defaultDomain = persistActiveDomain("example.test");
|
||||
user =
|
||||
new User.Builder()
|
||||
.setEmailAddress("user@theregistrar.com")
|
||||
.setUserRoles(
|
||||
new UserRoles.Builder()
|
||||
.setRegistrarRoles(
|
||||
ImmutableMap.of("TheRegistrar", RegistrarRole.PRIMARY_CONTACT))
|
||||
.build())
|
||||
.setRegistryLockPassword("registryLockPassword")
|
||||
.build();
|
||||
action = createGetAction();
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
void afterEach() {
|
||||
verifyNoMoreInteractions(gmailClient);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGet_simpleLock() {
|
||||
saveRegistryLock(
|
||||
new RegistryLock.Builder()
|
||||
.setRepoId("repoId")
|
||||
.setDomainName("example.test")
|
||||
.setRegistrarId("TheRegistrar")
|
||||
.setVerificationCode("123456789ABCDEFGHJKLMNPQRSTUVWXY")
|
||||
.setRegistrarPocId("johndoe@theregistrar.com")
|
||||
.setLockCompletionTime(fakeClock.nowUtc())
|
||||
.build());
|
||||
action.run();
|
||||
assertThat(response.getStatus()).isEqualTo(HttpStatusCodes.STATUS_CODE_OK);
|
||||
assertThat(response.getPayload())
|
||||
.isEqualTo(
|
||||
"""
|
||||
[{"domainName":"example.test","registrarPocId":"johndoe@theregistrar.com","lockRequestTime":\
|
||||
{"creationTime":"2024-04-18T12:00:00.000Z"},"unlockRequestTime":"null","lockCompletionTime":\
|
||||
"2024-04-18T12:00:00.000Z","unlockCompletionTime":"null","isSuperuser":false}]\
|
||||
""");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGet_allCurrentlyValidLocks() {
|
||||
RegistryLock expiredLock =
|
||||
new RegistryLock.Builder()
|
||||
.setRepoId("repoId")
|
||||
.setDomainName("expired.test")
|
||||
.setRegistrarId("TheRegistrar")
|
||||
.setVerificationCode("123456789ABCDEFGHJKLMNPQRSTUVWXY")
|
||||
.setRegistrarPocId("johndoe@theregistrar.com")
|
||||
.build();
|
||||
saveRegistryLock(expiredLock);
|
||||
RegistryLock expiredUnlock =
|
||||
new RegistryLock.Builder()
|
||||
.setRepoId("repoId")
|
||||
.setDomainName("expiredunlock.test")
|
||||
.setRegistrarId("TheRegistrar")
|
||||
.setVerificationCode("123456789ABCDEFGHJKLMNPQRSTUVWXY")
|
||||
.setRegistrarPocId("johndoe@theregistrar.com")
|
||||
.setLockCompletionTime(fakeClock.nowUtc())
|
||||
.setUnlockRequestTime(fakeClock.nowUtc())
|
||||
.build();
|
||||
saveRegistryLock(expiredUnlock);
|
||||
fakeClock.advanceBy(Duration.standardDays(1));
|
||||
|
||||
RegistryLock regularLock =
|
||||
new RegistryLock.Builder()
|
||||
.setRepoId("repoId")
|
||||
.setDomainName("example.test")
|
||||
.setRegistrarId("TheRegistrar")
|
||||
.setVerificationCode("123456789ABCDEFGHJKLMNPQRSTUVWXY")
|
||||
.setRegistrarPocId("johndoe@theregistrar.com")
|
||||
.setLockCompletionTime(fakeClock.nowUtc())
|
||||
.build();
|
||||
fakeClock.advanceOneMilli();
|
||||
RegistryLock adminLock =
|
||||
new RegistryLock.Builder()
|
||||
.setRepoId("repoId")
|
||||
.setDomainName("adminexample.test")
|
||||
.setRegistrarId("TheRegistrar")
|
||||
.setVerificationCode("122222222ABCDEFGHJKLMNPQRSTUVWXY")
|
||||
.isSuperuser(true)
|
||||
.setLockCompletionTime(fakeClock.nowUtc())
|
||||
.build();
|
||||
RegistryLock incompleteLock =
|
||||
new RegistryLock.Builder()
|
||||
.setRepoId("repoId")
|
||||
.setDomainName("pending.test")
|
||||
.setRegistrarId("TheRegistrar")
|
||||
.setVerificationCode("111111111ABCDEFGHJKLMNPQRSTUVWXY")
|
||||
.setRegistrarPocId("johndoe@theregistrar.com")
|
||||
.build();
|
||||
|
||||
RegistryLock incompleteUnlock =
|
||||
new RegistryLock.Builder()
|
||||
.setRepoId("repoId")
|
||||
.setDomainName("incompleteunlock.test")
|
||||
.setRegistrarId("TheRegistrar")
|
||||
.setVerificationCode("123456789ABCDEFGHJKLMNPQRSTUVWXY")
|
||||
.setRegistrarPocId("johndoe@theregistrar.com")
|
||||
.setLockCompletionTime(fakeClock.nowUtc())
|
||||
.setUnlockRequestTime(fakeClock.nowUtc())
|
||||
.build();
|
||||
|
||||
RegistryLock unlockedLock =
|
||||
new RegistryLock.Builder()
|
||||
.setRepoId("repoId")
|
||||
.setDomainName("unlocked.test")
|
||||
.setRegistrarId("TheRegistrar")
|
||||
.setRegistrarPocId("johndoe@theregistrar.com")
|
||||
.setVerificationCode("123456789ABCDEFGHJKLMNPQRSTUUUUU")
|
||||
.setLockCompletionTime(fakeClock.nowUtc())
|
||||
.setUnlockRequestTime(fakeClock.nowUtc())
|
||||
.setUnlockCompletionTime(fakeClock.nowUtc())
|
||||
.build();
|
||||
|
||||
saveRegistryLock(regularLock);
|
||||
saveRegistryLock(adminLock);
|
||||
saveRegistryLock(incompleteLock);
|
||||
saveRegistryLock(incompleteUnlock);
|
||||
saveRegistryLock(unlockedLock);
|
||||
|
||||
action.run();
|
||||
assertThat(response.getStatus()).isEqualTo(HttpStatusCodes.STATUS_CODE_OK);
|
||||
// We should include all the locks that are currently locked, which does not include pending
|
||||
// locks or completed unlocks
|
||||
assertThat(response.getPayload())
|
||||
.isEqualTo(
|
||||
"""
|
||||
[{"domainName":"adminexample.test","lockRequestTime":{"creationTime":"2024-04-19T12:00:00.001Z"},\
|
||||
"unlockRequestTime":"null","lockCompletionTime":"2024-04-19T12:00:00.001Z","unlockCompletionTime":\
|
||||
"null","isSuperuser":true},\
|
||||
\
|
||||
{"domainName":"example.test","registrarPocId":"johndoe@theregistrar.com","lockRequestTime":\
|
||||
{"creationTime":"2024-04-19T12:00:00.001Z"},"unlockRequestTime":"null","lockCompletionTime":\
|
||||
"2024-04-19T12:00:00.000Z","unlockCompletionTime":"null","isSuperuser":false},\
|
||||
\
|
||||
{"domainName":"expiredunlock.test","registrarPocId":"johndoe@theregistrar.com","lockRequestTime":\
|
||||
{"creationTime":"2024-04-18T12:00:00.000Z"},"unlockRequestTime":"2024-04-18T12:00:00.000Z",\
|
||||
"lockCompletionTime":"2024-04-18T12:00:00.000Z","unlockCompletionTime":"null","isSuperuser":false},\
|
||||
\
|
||||
{"domainName":"incompleteunlock.test","registrarPocId":"johndoe@theregistrar.com","lockRequestTime":\
|
||||
{"creationTime":"2024-04-19T12:00:00.001Z"},"unlockRequestTime":"2024-04-19T12:00:00.001Z",\
|
||||
"lockCompletionTime":"2024-04-19T12:00:00.001Z","unlockCompletionTime":"null","isSuperuser":false},\
|
||||
\
|
||||
{"domainName":"pending.test","registrarPocId":"johndoe@theregistrar.com","lockRequestTime":\
|
||||
{"creationTime":"2024-04-19T12:00:00.001Z"},"unlockRequestTime":"null","lockCompletionTime":"null",\
|
||||
"unlockCompletionTime":"null","isSuperuser":false}]""");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGet_noLocks() {
|
||||
action.run();
|
||||
assertThat(response.getStatus()).isEqualTo(HttpStatusCodes.STATUS_CODE_OK);
|
||||
assertThat(response.getPayload()).isEqualTo("[]");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGet_failure_noRegistrarAccess() throws Exception {
|
||||
user =
|
||||
user.asBuilder()
|
||||
.setUserRoles(
|
||||
user.getUserRoles().asBuilder().setRegistrarRoles(ImmutableMap.of()).build())
|
||||
.build();
|
||||
action = createGetAction();
|
||||
action.run();
|
||||
assertThat(response.getStatus()).isEqualTo(HttpStatusCodes.STATUS_CODE_FORBIDDEN);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGet_failure_noRegistryLockAccess() throws Exception {
|
||||
// User has access to the registrar, but not to do locks
|
||||
user =
|
||||
user.asBuilder()
|
||||
.setUserRoles(
|
||||
user.getUserRoles()
|
||||
.asBuilder()
|
||||
.setRegistrarRoles(
|
||||
ImmutableMap.of("TheRegistrar", RegistrarRole.ACCOUNT_MANAGER))
|
||||
.build())
|
||||
.build();
|
||||
action = createGetAction();
|
||||
action.run();
|
||||
assertThat(response.getStatus()).isEqualTo(HttpStatusCodes.STATUS_CODE_FORBIDDEN);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testPost_lock() throws Exception {
|
||||
action = createDefaultPostAction(true);
|
||||
action.run();
|
||||
assertThat(response.getStatus()).isEqualTo(HttpStatusCodes.STATUS_CODE_OK);
|
||||
assertThat(getMostRecentRegistryLockByRepoId(defaultDomain.getRepoId())).isPresent();
|
||||
verifyEmail();
|
||||
// Doesn't actually change the status values (hasn't been verified)
|
||||
assertThat(loadByEntity(defaultDomain).getStatusValues()).containsExactly(StatusValue.INACTIVE);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testPost_unlock() throws Exception {
|
||||
saveRegistryLock(createDefaultLockBuilder().setLockCompletionTime(fakeClock.nowUtc()).build());
|
||||
persistResource(defaultDomain.asBuilder().setStatusValues(REGISTRY_LOCK_STATUSES).build());
|
||||
action = createDefaultPostAction(false);
|
||||
action.run();
|
||||
assertThat(response.getStatus()).isEqualTo(HttpStatusCodes.STATUS_CODE_OK);
|
||||
verifyEmail();
|
||||
// Doesn't actually change the status values (hasn't been verified)
|
||||
assertThat(loadByEntity(defaultDomain).getStatusValues())
|
||||
.containsAtLeastElementsIn(REGISTRY_LOCK_STATUSES);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testPost_unlock_relockDuration() throws Exception {
|
||||
saveRegistryLock(createDefaultLockBuilder().setLockCompletionTime(fakeClock.nowUtc()).build());
|
||||
persistResource(defaultDomain.asBuilder().setStatusValues(REGISTRY_LOCK_STATUSES).build());
|
||||
action =
|
||||
createPostAction(
|
||||
"example.test",
|
||||
false,
|
||||
"registryLockPassword",
|
||||
Optional.of(Duration.standardDays(1).getMillis()));
|
||||
action.run();
|
||||
assertThat(response.getStatus()).isEqualTo(HttpStatusCodes.STATUS_CODE_OK);
|
||||
verifyEmail();
|
||||
RegistryLock savedUnlockRequest =
|
||||
getMostRecentRegistryLockByRepoId(defaultDomain.getRepoId()).get();
|
||||
assertThat(savedUnlockRequest.getRelockDuration())
|
||||
.isEqualTo(Optional.of(Duration.standardDays(1)));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testPost_adminUnlockingAdmin() throws Exception {
|
||||
saveRegistryLock(
|
||||
createDefaultLockBuilder()
|
||||
.setLockCompletionTime(fakeClock.nowUtc())
|
||||
.isSuperuser(true)
|
||||
.build());
|
||||
persistResource(defaultDomain.asBuilder().setStatusValues(REGISTRY_LOCK_STATUSES).build());
|
||||
user =
|
||||
user.asBuilder()
|
||||
.setUserRoles(
|
||||
new UserRoles.Builder().setGlobalRole(GlobalRole.FTE).setIsAdmin(true).build())
|
||||
.build();
|
||||
action = createDefaultPostAction(false);
|
||||
action.run();
|
||||
assertThat(response.getStatus()).isEqualTo(HttpStatusCodes.STATUS_CODE_OK);
|
||||
verifyEmail();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testPost_success_noPasswordForAdmin() throws Exception {
|
||||
user =
|
||||
user.asBuilder()
|
||||
.setUserRoles(
|
||||
new UserRoles.Builder().setGlobalRole(GlobalRole.FTE).setIsAdmin(true).build())
|
||||
.build();
|
||||
action = createPostAction("example.test", true, "", Optional.empty());
|
||||
action.run();
|
||||
assertThat(response.getStatus()).isEqualTo(HttpStatusCodes.STATUS_CODE_OK);
|
||||
verifyEmail();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testPost_failure_noRegistrarAccess() throws Exception {
|
||||
user =
|
||||
user.asBuilder()
|
||||
.setUserRoles(
|
||||
user.getUserRoles().asBuilder().setRegistrarRoles(ImmutableMap.of()).build())
|
||||
.build();
|
||||
action = createDefaultPostAction(true);
|
||||
action.run();
|
||||
assertThat(response.getStatus()).isEqualTo(HttpStatusCodes.STATUS_CODE_FORBIDDEN);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testPost_failure_noRegistryLockAccess() throws Exception {
|
||||
// User has access to the registrar, but not to do locks
|
||||
user =
|
||||
user.asBuilder()
|
||||
.setUserRoles(
|
||||
user.getUserRoles()
|
||||
.asBuilder()
|
||||
.setRegistrarRoles(
|
||||
ImmutableMap.of("TheRegistrar", RegistrarRole.ACCOUNT_MANAGER))
|
||||
.build())
|
||||
.build();
|
||||
action = createDefaultPostAction(true);
|
||||
action.run();
|
||||
assertThat(response.getStatus()).isEqualTo(HttpStatusCodes.STATUS_CODE_FORBIDDEN);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testPost_failure_unlock_noLock() throws Exception {
|
||||
action = createDefaultPostAction(false);
|
||||
action.run();
|
||||
assertThat(response.getStatus()).isEqualTo(HttpStatusCodes.STATUS_CODE_BAD_REQUEST);
|
||||
assertThat(response.getPayload()).isEqualTo("Domain example.test is already unlocked");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testPost_failure_nonAdminUnlockingAdmin() throws Exception {
|
||||
saveRegistryLock(
|
||||
createDefaultLockBuilder()
|
||||
.setLockCompletionTime(fakeClock.nowUtc())
|
||||
.isSuperuser(true)
|
||||
.build());
|
||||
persistResource(defaultDomain.asBuilder().setStatusValues(REGISTRY_LOCK_STATUSES).build());
|
||||
action = createDefaultPostAction(false);
|
||||
action.run();
|
||||
assertThat(response.getStatus()).isEqualTo(HttpStatusCodes.STATUS_CODE_BAD_REQUEST);
|
||||
assertThat(response.getPayload())
|
||||
.isEqualTo("Non-admin user cannot unlock admin-locked domain example.test");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testPost_failure_wrongRegistrarForDomain() throws Exception {
|
||||
persistResource(
|
||||
newDomain("otherregistrar.test")
|
||||
.asBuilder()
|
||||
.setCreationRegistrarId("NewRegistrar")
|
||||
.setPersistedCurrentSponsorRegistrarId("NewRegistrar")
|
||||
.build());
|
||||
action =
|
||||
createPostAction("otherregistrar.test", true, "registryLockPassword", Optional.empty());
|
||||
action.run();
|
||||
assertThat(response.getStatus()).isEqualTo(HttpStatusCodes.STATUS_CODE_BAD_REQUEST);
|
||||
assertThat(response.getPayload())
|
||||
.isEqualTo("Domain otherregistrar.test is not owned by registrar TheRegistrar");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testPost_failure_notAllowedForRegistrar() throws Exception {
|
||||
persistResource(
|
||||
loadRegistrar("TheRegistrar").asBuilder().setRegistryLockAllowed(false).build());
|
||||
action = createDefaultPostAction(true);
|
||||
action.run();
|
||||
assertThat(response.getStatus()).isEqualTo(HttpStatusCodes.STATUS_CODE_BAD_REQUEST);
|
||||
assertThat(response.getPayload())
|
||||
.isEqualTo("Registry lock not allowed for registrar TheRegistrar");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testPost_failure_badPassword() throws Exception {
|
||||
action = createPostAction("example.test", true, "badPassword", Optional.empty());
|
||||
action.run();
|
||||
assertThat(response.getStatus()).isEqualTo(HttpStatusCodes.STATUS_CODE_UNAUTHORIZED);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testPost_failure_lock_alreadyPendingLock() throws Exception {
|
||||
saveRegistryLock(createDefaultLockBuilder().build());
|
||||
action = createDefaultPostAction(true);
|
||||
action.run();
|
||||
assertThat(response.getStatus()).isEqualTo(HttpStatusCodes.STATUS_CODE_BAD_REQUEST);
|
||||
assertThat(response.getPayload())
|
||||
.isEqualTo("A pending or completed lock action already exists for example.test");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testPost_failure_alreadyLocked() throws Exception {
|
||||
persistResource(defaultDomain.asBuilder().setStatusValues(REGISTRY_LOCK_STATUSES).build());
|
||||
action = createDefaultPostAction(true);
|
||||
action.run();
|
||||
assertThat(response.getStatus()).isEqualTo(HttpStatusCodes.STATUS_CODE_BAD_REQUEST);
|
||||
assertThat(response.getPayload()).isEqualTo("Domain example.test is already locked");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testPost_failure_alreadyUnlocked() throws Exception {
|
||||
saveRegistryLock(
|
||||
createDefaultLockBuilder()
|
||||
.setLockCompletionTime(fakeClock.nowUtc())
|
||||
.setUnlockRequestTime(fakeClock.nowUtc())
|
||||
.setUnlockCompletionTime(fakeClock.nowUtc())
|
||||
.build());
|
||||
action = createDefaultPostAction(false);
|
||||
action.run();
|
||||
assertThat(response.getStatus()).isEqualTo(HttpStatusCodes.STATUS_CODE_BAD_REQUEST);
|
||||
assertThat(response.getPayload()).isEqualTo("Domain example.test is already unlocked");
|
||||
}
|
||||
|
||||
private ConsoleRegistryLockAction createDefaultPostAction(boolean isLock) {
|
||||
return createPostAction("example.test", isLock, "registryLockPassword", Optional.empty());
|
||||
}
|
||||
|
||||
private ConsoleRegistryLockAction createPostAction(
|
||||
String domainName, boolean isLock, String password, Optional<Long> relockDurationMillis) {
|
||||
ConsoleApiParams params = createParams();
|
||||
when(params.request().getParameter("domainName")).thenReturn(domainName);
|
||||
when(params.request().getParameterMap())
|
||||
.thenReturn(ImmutableMap.of("isLock", new String[] {String.valueOf(isLock)}));
|
||||
when(params.request().getParameter("isLock")).thenReturn(String.valueOf(isLock));
|
||||
when(params.request().getParameter("password")).thenReturn(password);
|
||||
relockDurationMillis.ifPresent(
|
||||
duration ->
|
||||
when(params.request().getParameter("relockDurationMillis"))
|
||||
.thenReturn(String.valueOf(duration)));
|
||||
return createGenericAction(params, "POST");
|
||||
}
|
||||
|
||||
private ConsoleRegistryLockAction createGetAction() throws IOException {
|
||||
return createGenericAction(createParams(), "GET");
|
||||
}
|
||||
|
||||
private ConsoleRegistryLockAction createGenericAction(ConsoleApiParams params, String method) {
|
||||
when(params.request().getMethod()).thenReturn(method);
|
||||
when(params.request().getServerName()).thenReturn("registrarconsole.tld");
|
||||
when(params.request().getParameter("registrarId")).thenReturn("TheRegistrar");
|
||||
DomainLockUtils domainLockUtils =
|
||||
new DomainLockUtils(
|
||||
new DeterministicStringGenerator(StringGenerator.Alphabets.BASE_58),
|
||||
"adminreg",
|
||||
new CloudTasksHelper(fakeClock).getTestCloudTasksUtils());
|
||||
response = (FakeResponse) params.response();
|
||||
return new ConsoleRegistryLockAction(
|
||||
params, domainLockUtils, gmailClient, GSON, "TheRegistrar");
|
||||
}
|
||||
|
||||
private ConsoleApiParams createParams() {
|
||||
AuthResult authResult = AuthResult.createUser(UserAuthInfo.create(user));
|
||||
return FakeConsoleApiParams.get(Optional.of(authResult));
|
||||
}
|
||||
|
||||
private RegistryLock.Builder createDefaultLockBuilder() {
|
||||
return new RegistryLock.Builder()
|
||||
.setRepoId(defaultDomain.getRepoId())
|
||||
.setDomainName(defaultDomain.getDomainName())
|
||||
.setRegistrarId(defaultDomain.getCurrentSponsorRegistrarId())
|
||||
.setRegistrarPocId("johndoe@theregistrar.com")
|
||||
.setVerificationCode("123456789ABCDEFGHJKLMNPQRSTUUUUU");
|
||||
}
|
||||
|
||||
private void verifyEmail() throws Exception {
|
||||
ArgumentCaptor<EmailMessage> emailCaptor = ArgumentCaptor.forClass(EmailMessage.class);
|
||||
verify(gmailClient).sendEmail(emailCaptor.capture());
|
||||
EmailMessage sentMessage = emailCaptor.getValue();
|
||||
assertThat(sentMessage.subject()).matches("Registry (un)?lock verification");
|
||||
assertThat(sentMessage.body()).matches(EMAIL_MESSAGE_TEMPLATE);
|
||||
assertThat(sentMessage.recipients())
|
||||
.containsExactly(new InternetAddress("user@theregistrar.com"));
|
||||
}
|
||||
}
|
||||
@@ -22,7 +22,6 @@ import com.google.api.client.http.HttpStatusCodes;
|
||||
import com.google.gson.Gson;
|
||||
import google.registry.model.console.User;
|
||||
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.UserAuthInfo;
|
||||
@@ -54,8 +53,7 @@ class ConsoleUserDataActionTest {
|
||||
User user = DatabaseHelper.createAdminUser("email@email.com");
|
||||
AuthResult authResult = AuthResult.createUser(UserAuthInfo.create(user));
|
||||
ConsoleUserDataAction action =
|
||||
createAction(
|
||||
Optional.of(FakeConsoleApiParams.get(Optional.of(authResult))), Action.Method.GET);
|
||||
createAction(Optional.of(FakeConsoleApiParams.get(Optional.of(authResult))));
|
||||
action.run();
|
||||
List<Cookie> cookies = ((FakeResponse) consoleApiParams.response()).getCookies();
|
||||
assertThat(cookies.stream().map(cookie -> cookie.getName()).collect(toImmutableList()))
|
||||
@@ -67,8 +65,7 @@ class ConsoleUserDataActionTest {
|
||||
User user = DatabaseHelper.createAdminUser("email@email.com");
|
||||
AuthResult authResult = AuthResult.createUser(UserAuthInfo.create(user));
|
||||
ConsoleUserDataAction action =
|
||||
createAction(
|
||||
Optional.of(FakeConsoleApiParams.get(Optional.of(authResult))), Action.Method.GET);
|
||||
createAction(Optional.of(FakeConsoleApiParams.get(Optional.of(authResult))));
|
||||
action.run();
|
||||
assertThat(((FakeResponse) consoleApiParams.response()).getStatus())
|
||||
.isEqualTo(HttpStatusCodes.STATUS_CODE_OK);
|
||||
@@ -92,17 +89,17 @@ class ConsoleUserDataActionTest {
|
||||
|
||||
@Test
|
||||
void testFailure_notAConsoleUser() throws IOException {
|
||||
ConsoleUserDataAction action = createAction(Optional.empty(), Action.Method.GET);
|
||||
ConsoleUserDataAction action = createAction(Optional.empty());
|
||||
action.run();
|
||||
assertThat(((FakeResponse) consoleApiParams.response()).getStatus())
|
||||
.isEqualTo(HttpStatusCodes.STATUS_CODE_UNAUTHORIZED);
|
||||
}
|
||||
|
||||
private ConsoleUserDataAction createAction(
|
||||
Optional<ConsoleApiParams> maybeConsoleApiParams, Action.Method method) throws IOException {
|
||||
private ConsoleUserDataAction createAction(Optional<ConsoleApiParams> maybeConsoleApiParams)
|
||||
throws IOException {
|
||||
consoleApiParams =
|
||||
maybeConsoleApiParams.orElseGet(() -> FakeConsoleApiParams.get(Optional.empty()));
|
||||
when(consoleApiParams.request().getMethod()).thenReturn(method.toString());
|
||||
when(consoleApiParams.request().getMethod()).thenReturn("GET");
|
||||
return new ConsoleUserDataAction(
|
||||
consoleApiParams, "Nomulus", "support@example.com", "+1 (212) 867 5309", "test");
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ PATH CLASS METHODS OK AUT
|
||||
/console-api/dum-download ConsoleDumDownloadAction GET n API,LEGACY USER PUBLIC
|
||||
/console-api/eppPassword ConsoleEppPasswordAction POST n API,LEGACY USER PUBLIC
|
||||
/console-api/registrars RegistrarsAction GET,POST n API,LEGACY USER PUBLIC
|
||||
/console-api/registry-lock ConsoleRegistryLockAction GET,POST n API,LEGACY USER PUBLIC
|
||||
/console-api/settings/contacts ContactAction GET,POST n API,LEGACY USER PUBLIC
|
||||
/console-api/settings/security SecurityAction POST n API,LEGACY USER PUBLIC
|
||||
/console-api/settings/whois-fields WhoisRegistrarFieldsAction POST n API,LEGACY USER PUBLIC
|
||||
|
||||
@@ -60,6 +60,7 @@ PATH CLASS
|
||||
/console-api/dum-download ConsoleDumDownloadAction GET n API,LEGACY USER PUBLIC
|
||||
/console-api/eppPassword ConsoleEppPasswordAction POST n API,LEGACY USER PUBLIC
|
||||
/console-api/registrars RegistrarsAction GET,POST n API,LEGACY USER PUBLIC
|
||||
/console-api/registry-lock ConsoleRegistryLockAction GET,POST n API,LEGACY USER PUBLIC
|
||||
/console-api/settings/contacts ContactAction GET,POST n API,LEGACY USER PUBLIC
|
||||
/console-api/settings/security SecurityAction POST n API,LEGACY USER PUBLIC
|
||||
/console-api/settings/whois-fields WhoisRegistrarFieldsAction POST n API,LEGACY USER PUBLIC
|
||||
|
||||
Reference in New Issue
Block a user