Add a registryLockEmailAddress field to RegistrarConctact objects (#523)

* Add a registryLockEmailAddress field to RegistrarConctact objects

Because we need to manage the login email, it should be on an account
that we manage. However, for registry lock, we would want to send the
verification emails to a separate email address that the user can use.

As a result, we will use a second field for a user-accessible registry
lock email address. This must be set on the contact when enabling
registry lock for this contact.

* Responses to CR

* derp
This commit is contained in:
gbrodman
2020-03-20 14:12:00 -04:00
committed by GitHub
parent b2df127dc4
commit 519a85af85
22 changed files with 118 additions and 26 deletions
@@ -247,6 +247,7 @@ public final class AppEngineRule extends ExternalResource {
.setParent(makeRegistrar2())
.setName("Marla Singer")
.setEmailAddress("Marla.Singer@crr.com")
.setRegistryLockEmailAddress("Marla.Singer.RegistryLock@crr.com")
.setPhoneNumber("+1.2128675309")
.setTypes(ImmutableSet.of(RegistrarContact.Type.TECH))
.setGaeUserId("12345")
@@ -89,6 +89,7 @@ public class RegistrarContactCommandTest extends CommandTestCase<RegistrarContac
"--mode=UPDATE",
"--name=Judith Registrar",
"--email=judith.doe@example.com",
"--registry_lock_email=judith.doe@external.com",
"--phone=+1.2125650000",
"--fax=+1.2125650001",
"--contact_type=WHOIS",
@@ -102,6 +103,7 @@ public class RegistrarContactCommandTest extends CommandTestCase<RegistrarContac
.setParent(registrar)
.setName("Judith Registrar")
.setEmailAddress("judith.doe@example.com")
.setRegistryLockEmailAddress("judith.doe@external.com")
.setPhoneNumber("+1.2125650000")
.setFaxNumber("+1.2125650001")
.setTypes(ImmutableSet.of(WHOIS))
@@ -292,6 +294,7 @@ public class RegistrarContactCommandTest extends CommandTestCase<RegistrarContac
"--mode=CREATE",
"--name=Jim Doe",
"--email=jim.doe@example.com",
"--registry_lock_email=jim.doe@external.com",
"--contact_type=ADMIN,ABUSE",
"--visible_in_whois_as_admin=true",
"--visible_in_whois_as_tech=false",
@@ -303,6 +306,7 @@ public class RegistrarContactCommandTest extends CommandTestCase<RegistrarContac
.setParent(registrar)
.setName("Jim Doe")
.setEmailAddress("jim.doe@example.com")
.setRegistryLockEmailAddress("jim.doe@external.com")
.setTypes(ImmutableSet.of(ADMIN, ABUSE))
.setVisibleInWhoisAsAdmin(true)
.setVisibleInWhoisAsTech(false)
@@ -374,6 +378,7 @@ public class RegistrarContactCommandTest extends CommandTestCase<RegistrarContac
"--mode=CREATE",
"--name=Jim Doe",
"--email=jim.doe@example.com",
"--registry_lock_email=jim.doe.registry.lock@example.com",
"--allowed_to_set_registry_lock_password=true",
"NewRegistrar");
RegistrarContact registrarContact = loadRegistrar("NewRegistrar").getContacts().asList().get(1);
@@ -392,12 +397,30 @@ public class RegistrarContactCommandTest extends CommandTestCase<RegistrarContac
.setEmailAddress("jim.doe@example.com")
.build());
assertThat(registrarContact.isAllowedToSetRegistryLockPassword()).isFalse();
// First, try (and fail) to set the password directly
assertThrows(
IllegalArgumentException.class,
() -> registrarContact.asBuilder().setRegistryLockPassword("foo"));
// Next, try (and fail) to allow registry lock without a registry lock email
assertThat(
assertThrows(
IllegalArgumentException.class,
() ->
runCommandForced(
"--mode=UPDATE",
"--email=jim.doe@example.com",
"--allowed_to_set_registry_lock_password=true",
"NewRegistrar")))
.hasMessageThat()
.isEqualTo("Registry lock email must not be null if allowing registry lock access");
// Next, include the email and it should succeed
runCommandForced(
"--mode=UPDATE",
"--email=jim.doe@example.com",
"--registry_lock_email=jim.doe.registry.lock@example.com",
"--allowed_to_set_registry_lock_password=true",
"NewRegistrar");
RegistrarContact newContact = reloadResource(registrarContact);
@@ -415,6 +438,7 @@ public class RegistrarContactCommandTest extends CommandTestCase<RegistrarContac
.setParent(registrar)
.setName("Jim Doe")
.setEmailAddress("jim.doe@example.com")
.setRegistryLockEmailAddress("jim.doe.registry.lock@example.com")
.setAllowedToSetRegistryLockPassword(true)
.setRegistryLockPassword("hi")
.build());
@@ -237,6 +237,7 @@ public class ContactSettingsTest extends RegistrarSettingsActionTestCase {
AppEngineRule.makeRegistrarContact2()
.asBuilder()
.setEmailAddress("someotheremail@example.com")
.setRegistryLockEmailAddress("someotherexample@example.com")
.setAllowedToSetRegistryLockPassword(true)
.build()
.toJsonMap(),
@@ -100,6 +100,7 @@ public abstract class RegistrarSettingsActionTestCase {
.setParent(loadRegistrar(CLIENT_ID))
.setName("Jian-Yang")
.setEmailAddress("jyang@bachman.accelerator")
.setRegistryLockEmailAddress("jyang.registrylock@bachman.accelerator")
.setPhoneNumber("+1.1234567890")
.setTypes(ImmutableSet.of(RegistrarContact.Type.TECH))
.build());
@@ -182,7 +182,7 @@ public final class RegistryLockGetActionTest {
"lockEnabledForContact",
true,
"email",
"Marla.Singer@crr.com",
"Marla.Singer.RegistryLock@crr.com",
"clientId",
"TheRegistrar",
"locks",
@@ -276,7 +276,7 @@ public final class RegistryLockGetActionTest {
"lockEnabledForContact",
false,
"email",
"Marla.Singer@crr.com",
"Marla.Singer.RegistryLock@crr.com",
"clientId",
"TheRegistrar",
"locks",
@@ -304,7 +304,7 @@ public final class RegistryLockGetActionTest {
"lockEnabledForContact",
true,
"email",
"Marla.Singer@crr.com",
"Marla.Singer.RegistryLock@crr.com",
"clientId",
"TheRegistrar",
"locks",
@@ -327,7 +327,7 @@ public final class RegistryLockGetActionTest {
"lockEnabledForContact",
true,
"email",
"Marla.Singer@crr.com",
"Marla.Singer.RegistryLock@crr.com",
"clientId",
"TheRegistrar",
"locks",
@@ -105,7 +105,7 @@ public final class RegistryLockPostActionTest {
@Test
public void testSuccess_lock() throws Exception {
Map<String, ?> response = action.handleJsonRequest(lockRequest());
assertSuccess(response, "lock", "Marla.Singer@crr.com");
assertSuccess(response, "lock", "Marla.Singer.RegistryLock@crr.com");
}
@Test
@@ -113,7 +113,7 @@ public final class RegistryLockPostActionTest {
saveRegistryLock(createLock().asBuilder().setLockCompletionTimestamp(clock.nowUtc()).build());
persistResource(domain.asBuilder().setStatusValues(REGISTRY_LOCK_STATUSES).build());
Map<String, ?> response = action.handleJsonRequest(unlockRequest());
assertSuccess(response, "unlock", "Marla.Singer@crr.com");
assertSuccess(response, "unlock", "Marla.Singer.RegistryLock@crr.com");
}
@Test
@@ -142,7 +142,7 @@ public final class RegistryLockPostActionTest {
createAction(
AuthResult.create(AuthLevel.USER, UserAuthInfo.create(userWithLockPermission, false)));
Map<String, ?> response = action.handleJsonRequest(lockRequest());
assertSuccess(response, "lock", "Marla.Singer@crr.com");
assertSuccess(response, "lock", "Marla.Singer.RegistryLock@crr.com");
}
@Test
@@ -309,7 +309,7 @@ public final class RegistryLockPostActionTest {
.build());
Map<String, ?> response = action.handleJsonRequest(lockRequest());
assertSuccess(response, "lock", "Marla.Singer@crr.com");
assertSuccess(response, "lock", "Marla.Singer.RegistryLock@crr.com");
}
@Test
@@ -319,7 +319,7 @@ public final class RegistryLockPostActionTest {
previousLock = getRegistryLockByVerificationCode(verificationCode).get();
clock.setTo(previousLock.getLockRequestTimestamp().plusHours(2));
Map<String, ?> response = action.handleJsonRequest(lockRequest());
assertSuccess(response, "lock", "Marla.Singer@crr.com");
assertSuccess(response, "lock", "Marla.Singer.RegistryLock@crr.com");
}
@Test
@@ -153,6 +153,7 @@ public class RegistrarConsoleScreenshotTest extends WebDriverTestCase {
persistResource(
makeRegistrarContact2()
.asBuilder()
.setRegistryLockEmailAddress("johndoe.registrylock@example.com")
.setAllowedToSetRegistryLockPassword(true)
.build());
persistResource(makeRegistrar2().asBuilder().setRegistryLockAllowed(true).build());
@@ -477,6 +477,7 @@ class google.registry.model.registrar.RegistrarContact {
java.lang.String gaeUserId;
java.lang.String name;
java.lang.String phoneNumber;
java.lang.String registryLockEmailAddress;
java.lang.String registryLockPasswordHash;
java.lang.String registryLockPasswordSalt;
java.util.Set<google.registry.model.registrar.RegistrarContact$Type> types;
@@ -11,10 +11,10 @@ emailAddress: the.registrar@example.com -> thase@the.registrar
url: http://my.fake.url -> http://my.new.url
contacts:
ADDED:
{parent=Key<?>(EntityGroupRoot("cross-tld")/Registrar("TheRegistrar")), name=Extra Terrestrial, emailAddress=etphonehome@example.com, phoneNumber=+1.2345678901, faxNumber=null, types=[ADMIN, BILLING, TECH, WHOIS], gaeUserId=null, visibleInWhoisAsAdmin=true, visibleInWhoisAsTech=false, visibleInDomainWhoisAsAbuse=false, allowedToSetRegistryLockPassword=false}
{parent=Key<?>(EntityGroupRoot("cross-tld")/Registrar("TheRegistrar")), name=Extra Terrestrial, emailAddress=etphonehome@example.com, registryLockEmailAddress=null, phoneNumber=+1.2345678901, faxNumber=null, types=[ADMIN, BILLING, TECH, WHOIS], gaeUserId=null, visibleInWhoisAsAdmin=true, visibleInWhoisAsTech=false, visibleInDomainWhoisAsAbuse=false, allowedToSetRegistryLockPassword=false}
REMOVED:
{parent=Key<?>(EntityGroupRoot("cross-tld")/Registrar("TheRegistrar")), name=Marla Singer, emailAddress=Marla.Singer@crr.com, phoneNumber=+1.2128675309, faxNumber=null, types=[TECH], gaeUserId=12345, visibleInWhoisAsAdmin=false, visibleInWhoisAsTech=false, visibleInDomainWhoisAsAbuse=false, allowedToSetRegistryLockPassword=false},
{parent=Key<?>(EntityGroupRoot("cross-tld")/Registrar("TheRegistrar")), name=John Doe, emailAddress=johndoe@theregistrar.com, phoneNumber=+1.1234567890, faxNumber=null, types=[ADMIN], gaeUserId=31337, visibleInWhoisAsAdmin=false, visibleInWhoisAsTech=false, visibleInDomainWhoisAsAbuse=false, allowedToSetRegistryLockPassword=false},
{parent=Key<?>(EntityGroupRoot("cross-tld")/Registrar("TheRegistrar")), name=Jian-Yang, emailAddress=jyang@bachman.accelerator, phoneNumber=+1.1234567890, faxNumber=null, types=[TECH], gaeUserId=null, visibleInWhoisAsAdmin=false, visibleInWhoisAsTech=false, visibleInDomainWhoisAsAbuse=false, allowedToSetRegistryLockPassword=false}
{parent=Key<?>(EntityGroupRoot("cross-tld")/Registrar("TheRegistrar")), name=Marla Singer, emailAddress=Marla.Singer@crr.com, registryLockEmailAddress=Marla.Singer.RegistryLock@crr.com, phoneNumber=+1.2128675309, faxNumber=null, types=[TECH], gaeUserId=12345, visibleInWhoisAsAdmin=false, visibleInWhoisAsTech=false, visibleInDomainWhoisAsAbuse=false, allowedToSetRegistryLockPassword=false},
{parent=Key<?>(EntityGroupRoot("cross-tld")/Registrar("TheRegistrar")), name=John Doe, emailAddress=johndoe@theregistrar.com, registryLockEmailAddress=null, phoneNumber=+1.1234567890, faxNumber=null, types=[ADMIN], gaeUserId=31337, visibleInWhoisAsAdmin=false, visibleInWhoisAsTech=false, visibleInDomainWhoisAsAbuse=false, allowedToSetRegistryLockPassword=false},
{parent=Key<?>(EntityGroupRoot("cross-tld")/Registrar("TheRegistrar")), name=Jian-Yang, emailAddress=jyang@bachman.accelerator, registryLockEmailAddress=jyang.registrylock@bachman.accelerator, phoneNumber=+1.1234567890, faxNumber=null, types=[TECH], gaeUserId=null, visibleInWhoisAsAdmin=false, visibleInWhoisAsTech=false, visibleInDomainWhoisAsAbuse=false, allowedToSetRegistryLockPassword=false}
FINAL CONTENTS:
{parent=Key<?>(EntityGroupRoot("cross-tld")/Registrar("TheRegistrar")), name=Extra Terrestrial, emailAddress=etphonehome@example.com, phoneNumber=+1.2345678901, faxNumber=null, types=[ADMIN, BILLING, TECH, WHOIS], gaeUserId=null, visibleInWhoisAsAdmin=true, visibleInWhoisAsTech=false, visibleInDomainWhoisAsAbuse=false, allowedToSetRegistryLockPassword=false}
{parent=Key<?>(EntityGroupRoot("cross-tld")/Registrar("TheRegistrar")), name=Extra Terrestrial, emailAddress=etphonehome@example.com, registryLockEmailAddress=null, phoneNumber=+1.2345678901, faxNumber=null, types=[ADMIN, BILLING, TECH, WHOIS], gaeUserId=null, visibleInWhoisAsAdmin=true, visibleInWhoisAsTech=false, visibleInDomainWhoisAsAbuse=false, allowedToSetRegistryLockPassword=false}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 49 KiB

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 69 KiB

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 52 KiB

After

Width:  |  Height:  |  Size: 52 KiB