mirror of
https://github.com/google/nomulus
synced 2026-01-08 07:11:44 +00:00
Allow for removal of registry lock passwords in User objects (#2609)
This essentially enables the "forgot password" flow
This commit is contained in:
@@ -36,9 +36,9 @@ import javax.annotation.Nullable;
|
||||
import javax.inject.Inject;
|
||||
|
||||
/**
|
||||
* An authenticam mechanism that verifies the OIDC token.
|
||||
* An authentication mechanism that verifies the OIDC token.
|
||||
*
|
||||
* <p>Currently, two flavors are supported: one that checkes for the OIDC token as a regular bearer
|
||||
* <p>Currently, two flavors are supported: one that checks for the OIDC token as a regular bearer
|
||||
* token, and another that checks for the OIDC token passed by IAP. In both cases, the {@link
|
||||
* AuthResult} with the highest {@link AuthLevel} possible is returned. So, if the email address for
|
||||
* which the token is minted exists both as a {@link User} and as a service account, the returned
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
package google.registry.tools;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
|
||||
import static google.registry.util.PreconditionsUtils.checkArgumentNotNull;
|
||||
|
||||
@@ -41,6 +42,15 @@ public abstract class CreateOrUpdateUserCommand extends ConfirmingCommand {
|
||||
+ " to remove the field.")
|
||||
private String registryLockEmailAddress;
|
||||
|
||||
@Nullable
|
||||
@Parameter(
|
||||
names = "--registry_lock_password",
|
||||
description =
|
||||
"Sets the registry lock password for this user, or removes it (allowing the user to"
|
||||
+ " re-set it). Do not set the password explicitly unless in exceptional"
|
||||
+ " circumstances.")
|
||||
private String registryLockPassword;
|
||||
|
||||
@Nullable
|
||||
@Parameter(
|
||||
names = "--admin",
|
||||
@@ -94,6 +104,25 @@ public abstract class CreateOrUpdateUserCommand extends ConfirmingCommand {
|
||||
builder.setRegistryLockEmailAddress(registryLockEmailAddress);
|
||||
}
|
||||
}
|
||||
// Ditto the registry lock password
|
||||
if (registryLockPassword != null) {
|
||||
if (registryLockEmailAddress != null) {
|
||||
// Edge case, make sure we're not removing an email and setting a password at the same time
|
||||
checkArgument(
|
||||
!registryLockEmailAddress.isEmpty(),
|
||||
"Cannot set/remove registry lock password on a user without a registry lock email"
|
||||
+ " address");
|
||||
} else {
|
||||
checkArgument(
|
||||
user != null && user.getRegistryLockEmailAddress().isPresent(),
|
||||
"Cannot set/remove registry lock password on a user without a registry lock email"
|
||||
+ " address");
|
||||
}
|
||||
builder.removeRegistryLockPassword();
|
||||
if (!registryLockPassword.isEmpty()) {
|
||||
builder.setRegistryLockPassword(registryLockPassword);
|
||||
}
|
||||
}
|
||||
tm().put(builder.build());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,10 +91,16 @@ public class CreateUserCommandTest extends CommandTestCase<CreateUserCommand> {
|
||||
runCommandForced(
|
||||
"--email",
|
||||
"user@example.test",
|
||||
"--registrar_roles",
|
||||
"TheRegistrar=PRIMARY_CONTACT",
|
||||
"--registry_lock_email_address",
|
||||
"registrylockemail@otherexample.test");
|
||||
assertThat(loadExistingUser("user@example.test").getRegistryLockEmailAddress())
|
||||
.hasValue("registrylockemail@otherexample.test");
|
||||
"registrylockemail@otherexample.test",
|
||||
"--registry_lock_password",
|
||||
"password");
|
||||
User user = loadExistingUser("user@example.test");
|
||||
assertThat(user.getRegistryLockEmailAddress()).hasValue("registrylockemail@otherexample.test");
|
||||
assertThat(user.verifyRegistryLockPassword("password")).isTrue();
|
||||
assertThat(user.verifyRegistryLockPassword("foobar")).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -174,4 +180,18 @@ public class CreateUserCommandTest extends CommandTestCase<CreateUserCommand> {
|
||||
.hasMessageThat()
|
||||
.isEqualTo("Provided email this is not valid is not a valid email address");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_registryLockPassword_withoutEmail() {
|
||||
assertThat(
|
||||
assertThrows(
|
||||
IllegalArgumentException.class,
|
||||
() ->
|
||||
runCommandForced(
|
||||
"--email", "user@example.test", "--registry_lock_password", "password")))
|
||||
.hasMessageThat()
|
||||
.isEqualTo(
|
||||
"Cannot set/remove registry lock password on a user without a registry lock email"
|
||||
+ " address");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ package google.registry.tools;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static google.registry.testing.DatabaseHelper.loadExistingUser;
|
||||
import static google.registry.testing.DatabaseHelper.persistResource;
|
||||
import static google.registry.testing.DatabaseHelper.putInDb;
|
||||
import static org.junit.Assert.assertThrows;
|
||||
|
||||
@@ -98,6 +99,44 @@ public class UpdateUserCommandTest extends CommandTestCase<UpdateUserCommand> {
|
||||
.isEqualTo(GlobalRole.FTE);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_removePassword() throws Exception {
|
||||
// Empty password value removes the password
|
||||
persistResource(
|
||||
loadExistingUser("user@example.test")
|
||||
.asBuilder()
|
||||
.setUserRoles(
|
||||
new UserRoles.Builder()
|
||||
.setRegistrarRoles(ImmutableMap.of("TheRegistrar", RegistrarRole.TECH_CONTACT))
|
||||
.build())
|
||||
.setRegistryLockEmailAddress("registrylock@example.test")
|
||||
.setRegistryLockPassword("password")
|
||||
.build());
|
||||
assertThat(loadExistingUser("user@example.test").hasRegistryLockPassword()).isTrue();
|
||||
runCommandForced("--email", "user@example.test", "--registry_lock_password", "");
|
||||
assertThat(loadExistingUser("user@example.test").hasRegistryLockPassword()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_setsPassword() throws Exception {
|
||||
persistResource(
|
||||
loadExistingUser("user@example.test")
|
||||
.asBuilder()
|
||||
.setUserRoles(
|
||||
new UserRoles.Builder()
|
||||
.setRegistrarRoles(ImmutableMap.of("TheRegistrar", RegistrarRole.TECH_CONTACT))
|
||||
.build())
|
||||
.setRegistryLockEmailAddress("registrylock@example.test")
|
||||
.setRegistryLockPassword("password")
|
||||
.build());
|
||||
assertThat(loadExistingUser("user@example.test").verifyRegistryLockPassword("password"))
|
||||
.isTrue();
|
||||
runCommandForced("--email", "user@example.test", "--registry_lock_password", "foobar");
|
||||
assertThat(loadExistingUser("user@example.test").verifyRegistryLockPassword("password"))
|
||||
.isFalse();
|
||||
assertThat(loadExistingUser("user@example.test").verifyRegistryLockPassword("foobar")).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_doesntExist() {
|
||||
assertThat(
|
||||
@@ -122,4 +161,18 @@ public class UpdateUserCommandTest extends CommandTestCase<UpdateUserCommand> {
|
||||
.hasMessageThat()
|
||||
.isEqualTo("Provided email this is not valid is not a valid email address");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_setPassword_noEmail() {
|
||||
assertThat(
|
||||
assertThrows(
|
||||
IllegalArgumentException.class,
|
||||
() ->
|
||||
runCommandForced(
|
||||
"--email", "user@example.test", "--registry_lock_password", "foobar")))
|
||||
.hasMessageThat()
|
||||
.isEqualTo(
|
||||
"Cannot set/remove registry lock password on a user without a registry lock email"
|
||||
+ " address");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user