Use randomly-generated base-58 strings for RegistryLock verification codes (#464)

* Use randomly-generated strings for RegistryLock verification codes

We were using UUIDs before which are also fine, but unnecessarily long.
The RegistryLock class itself does not enforce any particular format for
the lock verification codes.
This commit is contained in:
gbrodman
2020-02-03 13:50:54 -05:00
committed by GitHub
parent 76d8afe856
commit c0afb9aeee
13 changed files with 118 additions and 76 deletions
@@ -32,12 +32,14 @@ import google.registry.model.registry.RegistryLockDao;
import google.registry.model.reporting.HistoryEntry;
import google.registry.schema.domain.RegistryLock;
import google.registry.util.Clock;
import google.registry.util.StringGenerator;
import java.util.Optional;
import java.util.UUID;
import javax.annotation.Nullable;
import javax.inject.Inject;
import javax.inject.Named;
/**
* Utility class for validating and applying {@link RegistryLock}s.
* Utility functions for validating and applying {@link RegistryLock}s.
*
* <p>For both locks and unlocks, a lock must be requested via the createRegistry*Requst methods
* then verified through the verifyAndApply* methods. These methods will verify that the domain in
@@ -45,9 +47,16 @@ import javax.annotation.Nullable;
*/
public final class DomainLockUtils {
private DomainLockUtils() {}
private static final int VERIFICATION_CODE_LENGTH = 32;
public static RegistryLock createRegistryLockRequest(
private final StringGenerator stringGenerator;
@Inject
public DomainLockUtils(@Named("base58StringGenerator") StringGenerator stringGenerator) {
this.stringGenerator = stringGenerator;
}
public RegistryLock createRegistryLockRequest(
String domainName,
String registrarId,
@Nullable String registrarPocId,
@@ -68,7 +77,7 @@ public final class DomainLockUtils {
RegistryLock lock =
new RegistryLock.Builder()
.setVerificationCode(UUID.randomUUID().toString())
.setVerificationCode(stringGenerator.createString(VERIFICATION_CODE_LENGTH))
.setDomainName(domainName)
.setRepoId(domainBase.getRepoId())
.setRegistrarId(registrarId)
@@ -78,7 +87,7 @@ public final class DomainLockUtils {
return RegistryLockDao.save(lock);
}
public static RegistryLock createRegistryUnlockRequest(
public RegistryLock createRegistryUnlockRequest(
String domainName, String registrarId, boolean isAdmin, Clock clock) {
DomainBase domainBase = getDomain(domainName, clock);
Optional<RegistryLock> lockOptional =
@@ -121,7 +130,7 @@ public final class DomainLockUtils {
}
RegistryLock newLock =
newLockBuilder
.setVerificationCode(UUID.randomUUID().toString())
.setVerificationCode(stringGenerator.createString(VERIFICATION_CODE_LENGTH))
.isSuperuser(isAdmin)
.setUnlockRequestTimestamp(clock.nowUtc())
.setRegistrarId(registrarId)
@@ -129,8 +138,7 @@ public final class DomainLockUtils {
return RegistryLockDao.save(newLock);
}
public static RegistryLock verifyAndApplyLock(
String verificationCode, boolean isAdmin, Clock clock) {
public RegistryLock verifyAndApplyLock(String verificationCode, boolean isAdmin, Clock clock) {
return jpaTm()
.transact(
() -> {
@@ -156,8 +164,7 @@ public final class DomainLockUtils {
});
}
public static RegistryLock verifyAndApplyUnlock(
String verificationCode, boolean isAdmin, Clock clock) {
public RegistryLock verifyAndApplyUnlock(String verificationCode, boolean isAdmin, Clock clock) {
return jpaTm()
.transact(
() -> {
@@ -60,11 +60,11 @@ public class LockDomainCommand extends LockOrUnlockDomainCommand {
@Override
protected RegistryLock createLock(String domain) {
return DomainLockUtils.createRegistryLockRequest(domain, clientId, null, true, clock);
return domainLockUtils.createRegistryLockRequest(domain, clientId, null, true, clock);
}
@Override
protected void finalizeLockOrUnlockRequest(RegistryLock lock) {
DomainLockUtils.verifyAndApplyLock(lock.getVerificationCode(), true, clock);
domainLockUtils.verifyAndApplyLock(lock.getVerificationCode(), true, clock);
}
}
@@ -57,6 +57,8 @@ public abstract class LockOrUnlockDomainCommand extends ConfirmingCommand
@Inject Clock clock;
@Inject DomainLockUtils domainLockUtils;
protected ImmutableSet<String> relevantDomains = ImmutableSet.of();
protected ImmutableSet<String> getDomains() {
@@ -60,11 +60,11 @@ public class UnlockDomainCommand extends LockOrUnlockDomainCommand {
@Override
protected RegistryLock createLock(String domain) {
return DomainLockUtils.createRegistryUnlockRequest(domain, clientId, true, clock);
return domainLockUtils.createRegistryUnlockRequest(domain, clientId, true, clock);
}
@Override
protected void finalizeLockOrUnlockRequest(RegistryLock lock) {
DomainLockUtils.verifyAndApplyUnlock(lock.getVerificationCode(), true, clock);
domainLockUtils.verifyAndApplyUnlock(lock.getVerificationCode(), true, clock);
}
}
@@ -83,6 +83,7 @@ public class RegistryLockPostAction implements Runnable, JsonActionRunner.JsonAc
private final AuthenticatedRegistrarAccessor registrarAccessor;
private final SendEmailService sendEmailService;
private final Clock clock;
private final DomainLockUtils domainLockUtils;
private final InternetAddress gSuiteOutgoingEmailAddress;
@Inject
@@ -92,12 +93,14 @@ public class RegistryLockPostAction implements Runnable, JsonActionRunner.JsonAc
AuthenticatedRegistrarAccessor registrarAccessor,
SendEmailService sendEmailService,
Clock clock,
DomainLockUtils domainLockUtils,
@Config("gSuiteOutgoingEmailAddress") InternetAddress gSuiteOutgoingEmailAddress) {
this.jsonActionRunner = jsonActionRunner;
this.authResult = authResult;
this.registrarAccessor = registrarAccessor;
this.sendEmailService = sendEmailService;
this.clock = clock;
this.domainLockUtils = domainLockUtils;
this.gSuiteOutgoingEmailAddress = gSuiteOutgoingEmailAddress;
}
@@ -129,13 +132,13 @@ public class RegistryLockPostAction implements Runnable, JsonActionRunner.JsonAc
() -> {
RegistryLock registryLock =
postInput.isLock
? DomainLockUtils.createRegistryLockRequest(
? domainLockUtils.createRegistryLockRequest(
postInput.fullyQualifiedDomainName,
postInput.clientId,
postInput.pocId,
isAdmin,
clock)
: DomainLockUtils.createRegistryUnlockRequest(
: domainLockUtils.createRegistryUnlockRequest(
postInput.fullyQualifiedDomainName, postInput.clientId, isAdmin, clock);
sendVerificationEmail(registryLock, postInput.isLock);
});
@@ -49,15 +49,18 @@ public final class RegistryLockVerifyAction extends HtmlAction {
google.registry.ui.soy.registrar.RegistryLockVerificationSoyInfo.getInstance());
private final Clock clock;
private final DomainLockUtils domainLockUtils;
private final String lockVerificationCode;
private final Boolean isLock;
@Inject
public RegistryLockVerifyAction(
Clock clock,
DomainLockUtils domainLockUtils,
@Parameter("lockVerificationCode") String lockVerificationCode,
@Parameter("isLock") Boolean isLock) {
this.clock = clock;
this.domainLockUtils = domainLockUtils;
this.lockVerificationCode = lockVerificationCode;
this.isLock = isLock;
}
@@ -68,9 +71,9 @@ public final class RegistryLockVerifyAction extends HtmlAction {
boolean isAdmin = authResult.userAuthInfo().get().isUserAdmin();
final RegistryLock resultLock;
if (isLock) {
resultLock = DomainLockUtils.verifyAndApplyLock(lockVerificationCode, isAdmin, clock);
resultLock = domainLockUtils.verifyAndApplyLock(lockVerificationCode, isAdmin, clock);
} else {
resultLock = DomainLockUtils.verifyAndApplyUnlock(lockVerificationCode, isAdmin, clock);
resultLock = domainLockUtils.verifyAndApplyUnlock(lockVerificationCode, isAdmin, clock);
}
data.put("isLock", isLock);
data.put("success", true);