Skip to content

Commit e54075f

Browse files
authored
Allow for removal of registry lock passwords in User objects (#2609)
This essentially enables the "forgot password" flow
1 parent 78cc1b2 commit e54075f

File tree

4 files changed

+107
-5
lines changed

4 files changed

+107
-5
lines changed

core/src/main/java/google/registry/request/auth/OidcTokenAuthenticationMechanism.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,9 @@
3636
import javax.inject.Inject;
3737

3838
/**
39-
* An authenticam mechanism that verifies the OIDC token.
39+
* An authentication mechanism that verifies the OIDC token.
4040
*
41-
* <p>Currently, two flavors are supported: one that checkes for the OIDC token as a regular bearer
41+
* <p>Currently, two flavors are supported: one that checks for the OIDC token as a regular bearer
4242
* token, and another that checks for the OIDC token passed by IAP. In both cases, the {@link
4343
* AuthResult} with the highest {@link AuthLevel} possible is returned. So, if the email address for
4444
* which the token is minted exists both as a {@link User} and as a service account, the returned

core/src/main/java/google/registry/tools/CreateOrUpdateUserCommand.java

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
package google.registry.tools;
1616

17+
import static com.google.common.base.Preconditions.checkArgument;
1718
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
1819
import static google.registry.util.PreconditionsUtils.checkArgumentNotNull;
1920

@@ -41,6 +42,15 @@ public abstract class CreateOrUpdateUserCommand extends ConfirmingCommand {
4142
+ " to remove the field.")
4243
private String registryLockEmailAddress;
4344

45+
@Nullable
46+
@Parameter(
47+
names = "--registry_lock_password",
48+
description =
49+
"Sets the registry lock password for this user, or removes it (allowing the user to"
50+
+ " re-set it). Do not set the password explicitly unless in exceptional"
51+
+ " circumstances.")
52+
private String registryLockPassword;
53+
4454
@Nullable
4555
@Parameter(
4656
names = "--admin",
@@ -94,6 +104,25 @@ private void executeInTransaction() {
94104
builder.setRegistryLockEmailAddress(registryLockEmailAddress);
95105
}
96106
}
107+
// Ditto the registry lock password
108+
if (registryLockPassword != null) {
109+
if (registryLockEmailAddress != null) {
110+
// Edge case, make sure we're not removing an email and setting a password at the same time
111+
checkArgument(
112+
!registryLockEmailAddress.isEmpty(),
113+
"Cannot set/remove registry lock password on a user without a registry lock email"
114+
+ " address");
115+
} else {
116+
checkArgument(
117+
user != null && user.getRegistryLockEmailAddress().isPresent(),
118+
"Cannot set/remove registry lock password on a user without a registry lock email"
119+
+ " address");
120+
}
121+
builder.removeRegistryLockPassword();
122+
if (!registryLockPassword.isEmpty()) {
123+
builder.setRegistryLockPassword(registryLockPassword);
124+
}
125+
}
97126
tm().put(builder.build());
98127
}
99128
}

core/src/test/java/google/registry/tools/CreateUserCommandTest.java

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,10 +91,16 @@ void testSuccess_registryLock() throws Exception {
9191
runCommandForced(
9292
"--email",
9393
94+
"--registrar_roles",
95+
"TheRegistrar=PRIMARY_CONTACT",
9496
"--registry_lock_email_address",
95-
96-
assertThat(loadExistingUser("[email protected]").getRegistryLockEmailAddress())
97-
.hasValue("[email protected]");
97+
98+
"--registry_lock_password",
99+
"password");
100+
User user = loadExistingUser("[email protected]");
101+
assertThat(user.getRegistryLockEmailAddress()).hasValue("[email protected]");
102+
assertThat(user.verifyRegistryLockPassword("password")).isTrue();
103+
assertThat(user.verifyRegistryLockPassword("foobar")).isFalse();
98104
}
99105

100106
@Test
@@ -174,4 +180,18 @@ void testFailure_badRegistryLockEmail() throws Exception {
174180
.hasMessageThat()
175181
.isEqualTo("Provided email this is not valid is not a valid email address");
176182
}
183+
184+
@Test
185+
void testFailure_registryLockPassword_withoutEmail() {
186+
assertThat(
187+
assertThrows(
188+
IllegalArgumentException.class,
189+
() ->
190+
runCommandForced(
191+
"--email", "[email protected]", "--registry_lock_password", "password")))
192+
.hasMessageThat()
193+
.isEqualTo(
194+
"Cannot set/remove registry lock password on a user without a registry lock email"
195+
+ " address");
196+
}
177197
}

core/src/test/java/google/registry/tools/UpdateUserCommandTest.java

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
import static com.google.common.truth.Truth.assertThat;
1818
import static google.registry.testing.DatabaseHelper.loadExistingUser;
19+
import static google.registry.testing.DatabaseHelper.persistResource;
1920
import static google.registry.testing.DatabaseHelper.putInDb;
2021
import static org.junit.Assert.assertThrows;
2122

@@ -98,6 +99,44 @@ void testSuccess_globalRole() throws Exception {
9899
.isEqualTo(GlobalRole.FTE);
99100
}
100101

102+
@Test
103+
void testSuccess_removePassword() throws Exception {
104+
// Empty password value removes the password
105+
persistResource(
106+
loadExistingUser("[email protected]")
107+
.asBuilder()
108+
.setUserRoles(
109+
new UserRoles.Builder()
110+
.setRegistrarRoles(ImmutableMap.of("TheRegistrar", RegistrarRole.TECH_CONTACT))
111+
.build())
112+
.setRegistryLockEmailAddress("[email protected]")
113+
.setRegistryLockPassword("password")
114+
.build());
115+
assertThat(loadExistingUser("[email protected]").hasRegistryLockPassword()).isTrue();
116+
runCommandForced("--email", "[email protected]", "--registry_lock_password", "");
117+
assertThat(loadExistingUser("[email protected]").hasRegistryLockPassword()).isFalse();
118+
}
119+
120+
@Test
121+
void testSuccess_setsPassword() throws Exception {
122+
persistResource(
123+
loadExistingUser("[email protected]")
124+
.asBuilder()
125+
.setUserRoles(
126+
new UserRoles.Builder()
127+
.setRegistrarRoles(ImmutableMap.of("TheRegistrar", RegistrarRole.TECH_CONTACT))
128+
.build())
129+
.setRegistryLockEmailAddress("[email protected]")
130+
.setRegistryLockPassword("password")
131+
.build());
132+
assertThat(loadExistingUser("[email protected]").verifyRegistryLockPassword("password"))
133+
.isTrue();
134+
runCommandForced("--email", "[email protected]", "--registry_lock_password", "foobar");
135+
assertThat(loadExistingUser("[email protected]").verifyRegistryLockPassword("password"))
136+
.isFalse();
137+
assertThat(loadExistingUser("[email protected]").verifyRegistryLockPassword("foobar")).isTrue();
138+
}
139+
101140
@Test
102141
void testFailure_doesntExist() {
103142
assertThat(
@@ -122,4 +161,18 @@ void testFailure_badRegistryLockEmail() {
122161
.hasMessageThat()
123162
.isEqualTo("Provided email this is not valid is not a valid email address");
124163
}
164+
165+
@Test
166+
void testFailure_setPassword_noEmail() {
167+
assertThat(
168+
assertThrows(
169+
IllegalArgumentException.class,
170+
() ->
171+
runCommandForced(
172+
"--email", "[email protected]", "--registry_lock_password", "foobar")))
173+
.hasMessageThat()
174+
.isEqualTo(
175+
"Cannot set/remove registry lock password on a user without a registry lock email"
176+
+ " address");
177+
}
125178
}

0 commit comments

Comments
 (0)