diff --git a/core/src/main/java/google/registry/tools/DomainLockUtils.java b/core/src/main/java/google/registry/tools/DomainLockUtils.java
index c2374118b..cd47f10c0 100644
--- a/core/src/main/java/google/registry/tools/DomainLockUtils.java
+++ b/core/src/main/java/google/registry/tools/DomainLockUtils.java
@@ -37,6 +37,7 @@ import javax.annotation.Nullable;
import javax.inject.Inject;
import javax.inject.Named;
import org.joda.time.DateTime;
+import org.joda.time.Duration;
/**
* Utility functions for validating and applying {@link RegistryLock}s.
@@ -76,12 +77,12 @@ public final class DomainLockUtils {
*
The unlock will not be applied until {@link #verifyAndApplyUnlock} is called.
*/
public RegistryLock saveNewRegistryUnlockRequest(
- String domainName, String registrarId, boolean isAdmin) {
+ String domainName, String registrarId, boolean isAdmin, Optional relockDuration) {
return jpaTm()
.transact(
() ->
RegistryLockDao.save(
- createUnlockBuilder(domainName, registrarId, isAdmin).build()));
+ createUnlockBuilder(domainName, registrarId, isAdmin, relockDuration).build()));
}
/** Verifies and applies the lock request previously requested by a user. */
@@ -166,14 +167,14 @@ public final class DomainLockUtils {
* Nomulus tool commands.
*/
public RegistryLock administrativelyApplyUnlock(
- String domainName, String registrarId, boolean isAdmin) {
+ String domainName, String registrarId, boolean isAdmin, Optional relockDuration) {
return jpaTm()
.transact(
() -> {
DateTime now = jpaTm().getTransactionTime();
RegistryLock result =
RegistryLockDao.save(
- createUnlockBuilder(domainName, registrarId, isAdmin)
+ createUnlockBuilder(domainName, registrarId, isAdmin, relockDuration)
.setUnlockCompletionTimestamp(now)
.build());
tm().transact(() -> removeLockStatuses(result, isAdmin, now));
@@ -217,7 +218,7 @@ public final class DomainLockUtils {
}
private RegistryLock.Builder createUnlockBuilder(
- String domainName, String registrarId, boolean isAdmin) {
+ String domainName, String registrarId, boolean isAdmin, Optional relockDuration) {
DateTime now = jpaTm().getTransactionTime();
DomainBase domainBase = getDomain(domainName, now);
Optional lockOptional =
@@ -258,6 +259,7 @@ public final class DomainLockUtils {
!lock.isSuperuser(), "Non-admin user cannot unlock admin-locked domain %s", domainName);
newLockBuilder = lock.asBuilder();
}
+ relockDuration.ifPresent(newLockBuilder::setRelockDuration);
return newLockBuilder
.setVerificationCode(stringGenerator.createString(VERIFICATION_CODE_LENGTH))
.isSuperuser(isAdmin)
diff --git a/core/src/main/java/google/registry/tools/UnlockDomainCommand.java b/core/src/main/java/google/registry/tools/UnlockDomainCommand.java
index fa07df0cc..49a1ac508 100644
--- a/core/src/main/java/google/registry/tools/UnlockDomainCommand.java
+++ b/core/src/main/java/google/registry/tools/UnlockDomainCommand.java
@@ -22,6 +22,7 @@ import com.google.common.collect.Sets;
import com.google.common.flogger.FluentLogger;
import google.registry.model.domain.DomainBase;
import google.registry.model.eppcommon.StatusValue;
+import java.util.Optional;
import org.joda.time.DateTime;
/**
@@ -53,6 +54,6 @@ public class UnlockDomainCommand extends LockOrUnlockDomainCommand {
@Override
protected void createAndApplyRequest(String domain) {
- domainLockUtils.administrativelyApplyUnlock(domain, clientId, true);
+ domainLockUtils.administrativelyApplyUnlock(domain, clientId, true, Optional.empty());
}
}
diff --git a/core/src/main/java/google/registry/ui/server/registrar/RegistryLockPostAction.java b/core/src/main/java/google/registry/ui/server/registrar/RegistryLockPostAction.java
index eb42ca3d3..effbc4aba 100644
--- a/core/src/main/java/google/registry/ui/server/registrar/RegistryLockPostAction.java
+++ b/core/src/main/java/google/registry/ui/server/registrar/RegistryLockPostAction.java
@@ -56,6 +56,7 @@ 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;
/**
* UI action that allows for creating registry locks. Locks / unlocks must be verified separately
@@ -141,7 +142,8 @@ public class RegistryLockPostAction implements Runnable, JsonActionRunner.JsonAc
: domainLockUtils.saveNewRegistryUnlockRequest(
postInput.fullyQualifiedDomainName,
postInput.clientId,
- registrarAccessor.isAdmin());
+ registrarAccessor.isAdmin(),
+ Optional.ofNullable(postInput.relockDurationMillis).map(Duration::new));
sendVerificationEmail(registryLock, userEmail, postInput.isLock);
});
String action = postInput.isLock ? "lock" : "unlock";
@@ -218,5 +220,6 @@ public class RegistryLockPostAction implements Runnable, JsonActionRunner.JsonAc
private String fullyQualifiedDomainName;
private Boolean isLock;
private String password;
+ private Long relockDurationMillis;
}
}
diff --git a/core/src/test/java/google/registry/batch/RelockDomainActionTest.java b/core/src/test/java/google/registry/batch/RelockDomainActionTest.java
index a5bcbcb35..f8137d69d 100644
--- a/core/src/test/java/google/registry/batch/RelockDomainActionTest.java
+++ b/core/src/test/java/google/registry/batch/RelockDomainActionTest.java
@@ -40,6 +40,7 @@ import google.registry.testing.FakeResponse;
import google.registry.testing.UserInfo;
import google.registry.tools.DomainLockUtils;
import google.registry.util.StringGenerator.Alphabets;
+import java.util.Optional;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@@ -79,7 +80,9 @@ public class RelockDomainActionTest {
oldLock = domainLockUtils.administrativelyApplyLock(DOMAIN_NAME, CLIENT_ID, POC_ID, false);
assertThat(reloadDomain(domain).getStatusValues())
.containsAtLeastElementsIn(REGISTRY_LOCK_STATUSES);
- oldLock = domainLockUtils.administrativelyApplyUnlock(DOMAIN_NAME, CLIENT_ID, false);
+ oldLock =
+ domainLockUtils.administrativelyApplyUnlock(
+ DOMAIN_NAME, CLIENT_ID, false, Optional.empty());
assertThat(reloadDomain(domain).getStatusValues()).containsNoneIn(REGISTRY_LOCK_STATUSES);
action = createAction(oldLock.getRevisionId());
}
diff --git a/core/src/test/java/google/registry/tools/DomainLockUtilsTest.java b/core/src/test/java/google/registry/tools/DomainLockUtilsTest.java
index 4892c1cd9..dfc03722b 100644
--- a/core/src/test/java/google/registry/tools/DomainLockUtilsTest.java
+++ b/core/src/test/java/google/registry/tools/DomainLockUtilsTest.java
@@ -42,6 +42,7 @@ import google.registry.testing.DeterministicStringGenerator;
import google.registry.testing.FakeClock;
import google.registry.testing.UserInfo;
import google.registry.util.StringGenerator.Alphabets;
+import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import org.joda.time.Duration;
@@ -91,7 +92,8 @@ public final class DomainLockUtilsTest {
public void testSuccess_createUnlock() {
domainLockUtils.administrativelyApplyLock(DOMAIN_NAME, "TheRegistrar", POC_ID, false);
RegistryLock lock =
- domainLockUtils.saveNewRegistryUnlockRequest(DOMAIN_NAME, "TheRegistrar", false);
+ domainLockUtils.saveNewRegistryUnlockRequest(
+ DOMAIN_NAME, "TheRegistrar", false, Optional.empty());
assertThat(lock.getUnlockCompletionTimestamp().isPresent()).isFalse();
}
@@ -99,7 +101,8 @@ public final class DomainLockUtilsTest {
public void testSuccess_createUnlock_adminUnlockingAdmin() {
domainLockUtils.administrativelyApplyLock(DOMAIN_NAME, "TheRegistrar", null, true);
RegistryLock lock =
- domainLockUtils.saveNewRegistryUnlockRequest(DOMAIN_NAME, "TheRegistrar", true);
+ domainLockUtils.saveNewRegistryUnlockRequest(
+ DOMAIN_NAME, "TheRegistrar", true, Optional.empty());
assertThat(lock.getUnlockCompletionTimestamp().isPresent()).isFalse();
}
@@ -116,10 +119,12 @@ public final class DomainLockUtilsTest {
@Test
public void testSuccess_createUnlock_previousUnlockRequestExpired() {
domainLockUtils.administrativelyApplyLock(DOMAIN_NAME, "TheRegistrar", POC_ID, false);
- domainLockUtils.saveNewRegistryUnlockRequest(DOMAIN_NAME, "TheRegistrar", false);
+ domainLockUtils.saveNewRegistryUnlockRequest(
+ DOMAIN_NAME, "TheRegistrar", false, Optional.empty());
clock.advanceBy(Duration.standardDays(1));
RegistryLock unlockRequest =
- domainLockUtils.saveNewRegistryUnlockRequest(DOMAIN_NAME, "TheRegistrar", false);
+ domainLockUtils.saveNewRegistryUnlockRequest(
+ DOMAIN_NAME, "TheRegistrar", false, Optional.empty());
domainLockUtils.verifyAndApplyUnlock(unlockRequest.getVerificationCode(), false);
assertThat(reloadDomain().getStatusValues()).containsNoneIn(REGISTRY_LOCK_STATUSES);
}
@@ -136,7 +141,8 @@ public final class DomainLockUtilsTest {
public void testSuccess_applyUnlockDomain() {
domainLockUtils.administrativelyApplyLock(DOMAIN_NAME, "TheRegistrar", POC_ID, false);
RegistryLock unlock =
- domainLockUtils.saveNewRegistryUnlockRequest(DOMAIN_NAME, "TheRegistrar", false);
+ domainLockUtils.saveNewRegistryUnlockRequest(
+ DOMAIN_NAME, "TheRegistrar", false, Optional.empty());
domainLockUtils.verifyAndApplyUnlock(unlock.getVerificationCode(), false);
verifyProperlyUnlockedDomain(false);
}
@@ -155,7 +161,8 @@ public final class DomainLockUtilsTest {
domainLockUtils.saveNewRegistryLockRequest(DOMAIN_NAME, "TheRegistrar", null, true);
domainLockUtils.verifyAndApplyLock(lock.getVerificationCode(), true);
RegistryLock unlock =
- domainLockUtils.saveNewRegistryUnlockRequest(DOMAIN_NAME, "TheRegistrar", true);
+ domainLockUtils.saveNewRegistryUnlockRequest(
+ DOMAIN_NAME, "TheRegistrar", true, Optional.empty());
domainLockUtils.verifyAndApplyUnlock(unlock.getVerificationCode(), true);
verifyProperlyUnlockedDomain(true);
}
@@ -178,7 +185,8 @@ public final class DomainLockUtilsTest {
RegistryLock lock =
domainLockUtils.saveNewRegistryLockRequest(DOMAIN_NAME, "TheRegistrar", POC_ID, false);
domainLockUtils.verifyAndApplyLock(lock.getVerificationCode(), false);
- domainLockUtils.administrativelyApplyUnlock(DOMAIN_NAME, "TheRegistrar", false);
+ domainLockUtils.administrativelyApplyUnlock(
+ DOMAIN_NAME, "TheRegistrar", false, Optional.empty());
verifyProperlyUnlockedDomain(false);
}
@@ -187,7 +195,8 @@ public final class DomainLockUtilsTest {
RegistryLock lock =
domainLockUtils.saveNewRegistryLockRequest(DOMAIN_NAME, "TheRegistrar", null, true);
domainLockUtils.verifyAndApplyLock(lock.getVerificationCode(), true);
- domainLockUtils.administrativelyApplyUnlock(DOMAIN_NAME, "TheRegistrar", true);
+ domainLockUtils.administrativelyApplyUnlock(
+ DOMAIN_NAME, "TheRegistrar", true, Optional.empty());
verifyProperlyUnlockedDomain(true);
}
@@ -195,7 +204,8 @@ public final class DomainLockUtilsTest {
public void testSuccess_regularLock_relockSet() {
domainLockUtils.administrativelyApplyLock(DOMAIN_NAME, "TheRegistrar", POC_ID, false);
RegistryLock oldLock =
- domainLockUtils.administrativelyApplyUnlock(DOMAIN_NAME, "TheRegistrar", false);
+ domainLockUtils.administrativelyApplyUnlock(
+ DOMAIN_NAME, "TheRegistrar", false, Optional.empty());
RegistryLock newLock =
domainLockUtils.saveNewRegistryLockRequest(DOMAIN_NAME, "TheRegistrar", POC_ID, false);
newLock = domainLockUtils.verifyAndApplyLock(newLock.getVerificationCode(), false);
@@ -208,7 +218,8 @@ public final class DomainLockUtilsTest {
public void testSuccess_administrativelyLock_relockSet() {
domainLockUtils.administrativelyApplyLock(DOMAIN_NAME, "TheRegistrar", POC_ID, false);
RegistryLock oldLock =
- domainLockUtils.administrativelyApplyUnlock(DOMAIN_NAME, "TheRegistrar", false);
+ domainLockUtils.administrativelyApplyUnlock(
+ DOMAIN_NAME, "TheRegistrar", false, Optional.empty());
RegistryLock newLock =
domainLockUtils.administrativelyApplyLock(DOMAIN_NAME, "TheRegistrar", POC_ID, false);
assertThat(
@@ -216,19 +227,29 @@ public final class DomainLockUtilsTest {
.isEqualTo(newLock.getRevisionId());
}
+ @Test
+ public void testSuccess_createUnlock_relockDuration() {
+ domainLockUtils.administrativelyApplyLock(DOMAIN_NAME, "TheRegistrar", POC_ID, false);
+ RegistryLock lock =
+ domainLockUtils.saveNewRegistryUnlockRequest(
+ DOMAIN_NAME, "TheRegistrar", false, Optional.of(Duration.standardDays(1)));
+ assertThat(lock.getRelockDuration()).isEqualTo(Optional.of(Duration.standardDays(1)));
+ }
+
@Test
public void testFailure_createUnlock_alreadyPendingUnlock() {
RegistryLock lock =
domainLockUtils.saveNewRegistryLockRequest(DOMAIN_NAME, "TheRegistrar", POC_ID, false);
domainLockUtils.verifyAndApplyLock(lock.getVerificationCode(), false);
- domainLockUtils.saveNewRegistryUnlockRequest(DOMAIN_NAME, "TheRegistrar", false);
+ domainLockUtils.saveNewRegistryUnlockRequest(
+ DOMAIN_NAME, "TheRegistrar", false, Optional.empty());
assertThat(
assertThrows(
IllegalArgumentException.class,
() ->
domainLockUtils.saveNewRegistryUnlockRequest(
- DOMAIN_NAME, "TheRegistrar", false)))
+ DOMAIN_NAME, "TheRegistrar", false, Optional.empty())))
.hasMessageThat()
.isEqualTo("A pending unlock action already exists for example.tld");
}
@@ -243,7 +264,7 @@ public final class DomainLockUtilsTest {
IllegalArgumentException.class,
() ->
domainLockUtils.saveNewRegistryUnlockRequest(
- DOMAIN_NAME, "TheRegistrar", false)))
+ DOMAIN_NAME, "TheRegistrar", false, Optional.empty())))
.hasMessageThat()
.isEqualTo("Non-admin user cannot unlock admin-locked domain example.tld");
}
@@ -293,7 +314,7 @@ public final class DomainLockUtilsTest {
IllegalArgumentException.class,
() ->
domainLockUtils.saveNewRegistryUnlockRequest(
- DOMAIN_NAME, "TheRegistrar", false)))
+ DOMAIN_NAME, "TheRegistrar", false, Optional.empty())))
.hasMessageThat()
.isEqualTo("Domain example.tld is already unlocked");
}
@@ -346,7 +367,8 @@ public final class DomainLockUtilsTest {
domainLockUtils.saveNewRegistryLockRequest(DOMAIN_NAME, "TheRegistrar", POC_ID, false);
domainLockUtils.verifyAndApplyLock(lock.getVerificationCode(), false);
RegistryLock unlock =
- domainLockUtils.saveNewRegistryUnlockRequest(DOMAIN_NAME, "TheRegistrar", false);
+ domainLockUtils.saveNewRegistryUnlockRequest(
+ DOMAIN_NAME, "TheRegistrar", false, Optional.empty());
domainLockUtils.verifyAndApplyUnlock(unlock.getVerificationCode(), false);
assertThat(
diff --git a/core/src/test/java/google/registry/ui/server/registrar/RegistryLockPostActionTest.java b/core/src/test/java/google/registry/ui/server/registrar/RegistryLockPostActionTest.java
index 06eb224af..bc0c3e4c5 100644
--- a/core/src/test/java/google/registry/ui/server/registrar/RegistryLockPostActionTest.java
+++ b/core/src/test/java/google/registry/ui/server/registrar/RegistryLockPostActionTest.java
@@ -20,6 +20,7 @@ import static google.registry.testing.DatastoreHelper.createTld;
import static google.registry.testing.DatastoreHelper.loadRegistrar;
import static google.registry.testing.DatastoreHelper.newDomainBase;
import static google.registry.testing.DatastoreHelper.persistResource;
+import static google.registry.testing.SqlHelper.getMostRecentRegistryLockByRepoId;
import static google.registry.testing.SqlHelper.getRegistryLockByVerificationCode;
import static google.registry.testing.SqlHelper.saveRegistryLock;
import static google.registry.tools.LockOrUnlockDomainCommand.REGISTRY_LOCK_STATUSES;
@@ -49,9 +50,11 @@ import google.registry.util.EmailMessage;
import google.registry.util.SendEmailService;
import google.registry.util.StringGenerator.Alphabets;
import java.util.Map;
+import java.util.Optional;
import java.util.UUID;
import javax.mail.internet.InternetAddress;
import javax.servlet.http.HttpServletResponse;
+import org.joda.time.Duration;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@@ -116,6 +119,22 @@ public final class RegistryLockPostActionTest {
assertSuccess(response, "unlock", "Marla.Singer.RegistryLock@crr.com");
}
+ @Test
+ public void testSuccess_unlock_relockDurationSet() throws Exception {
+ saveRegistryLock(createLock().asBuilder().setLockCompletionTimestamp(clock.nowUtc()).build());
+ persistResource(domain.asBuilder().setStatusValues(REGISTRY_LOCK_STATUSES).build());
+ ImmutableMap request =
+ new ImmutableMap.Builder()
+ .putAll(unlockRequest())
+ .put("relockDurationMillis", Duration.standardDays(1).getMillis())
+ .build();
+ Map response = action.handleJsonRequest(request);
+ assertSuccess(response, "unlock", "Marla.Singer@crr.com");
+ RegistryLock savedUnlockRequest = getMostRecentRegistryLockByRepoId(domain.getRepoId()).get();
+ assertThat(savedUnlockRequest.getRelockDuration())
+ .isEqualTo(Optional.of(Duration.standardDays(1)));
+ }
+
@Test
public void testSuccess_unlock_adminUnlockingAdmin() throws Exception {
saveRegistryLock(