Skip to content

Commit b6ec730

Browse files
committed
Remove registry-lock-related fields from RegistrarPoc
We've moved these over to the User class, so we should remove these for clarity. In addition, we should make it clear (in Java at least) that the field in the RegistryLock object refers to the email address used for the lock in question.
1 parent 77ab80f commit b6ec730

File tree

19 files changed

+807
-5843
lines changed

19 files changed

+807
-5843
lines changed

core/src/main/java/google/registry/batch/RelockDomainAction.java

Lines changed: 14 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
package google.registry.batch;
1616

1717
import static com.google.common.base.Preconditions.checkArgument;
18-
import static com.google.common.collect.ImmutableSet.toImmutableSet;
1918
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
2019
import static google.registry.request.Action.Method.POST;
2120
import static google.registry.tools.LockOrUnlockDomainCommand.REGISTRY_LOCK_STATUSES;
@@ -30,8 +29,6 @@
3029
import google.registry.model.domain.Domain;
3130
import google.registry.model.domain.RegistryLock;
3231
import google.registry.model.eppcommon.StatusValue;
33-
import google.registry.model.registrar.Registrar;
34-
import google.registry.model.registrar.RegistrarPoc;
3532
import google.registry.model.tld.RegistryLockDao;
3633
import google.registry.persistence.VKey;
3734
import google.registry.request.Action;
@@ -70,12 +67,14 @@ public class RelockDomainAction implements Runnable {
7067
"""
7168
The domain %s was successfully re-locked.
7269
73-
Please contact support at %s if you have any questions.""";
70+
Please contact support at %s if you have any questions.\
71+
""";
7472
private static final String RELOCK_NON_RETRYABLE_FAILURE_EMAIL_TEMPLATE =
7573
"""
7674
There was an error when automatically re-locking %s. Error message: %s
7775
78-
Please contact support at %s if you have any questions.""";
76+
Please contact support at %s if you have any questions.\
77+
""";
7978
private static final String RELOCK_TRANSIENT_FAILURE_EMAIL_TEMPLATE =
8079
"There was an unexpected error when automatically re-locking %s. We will continue retrying "
8180
+ "the lock for five hours. Please contact support at %s if you have any questions";
@@ -171,7 +170,7 @@ private void applyRelock(RegistryLock oldLock) {
171170
domainLockUtils.administrativelyApplyLock(
172171
oldLock.getDomainName(),
173172
oldLock.getRegistrarId(),
174-
oldLock.getRegistrarPocId(),
173+
oldLock.getRegistryLockEmail(),
175174
oldLock.isSuperuser());
176175
logger.atInfo().log("Re-locked domain %s.", oldLock.getDomainName());
177176
response.setStatus(SC_OK);
@@ -221,7 +220,7 @@ private void handleNonRetryableFailure(RegistryLock oldLock, Throwable t) {
221220
EmailMessage.newBuilder()
222221
.setBody(body)
223222
.setSubject(String.format("Error re-locking domain %s", oldLock.getDomainName()))
224-
.setRecipients(getEmailRecipients(oldLock.getRegistrarId()))
223+
.setRecipients(ImmutableSet.of(getEmailRecipient(oldLock)))
225224
.build());
226225
}
227226

@@ -250,7 +249,7 @@ private void sendSuccessEmail(RegistryLock oldLock) {
250249
EmailMessage.newBuilder()
251250
.setBody(body)
252251
.setSubject(String.format("Successful re-lock of domain %s", oldLock.getDomainName()))
253-
.setRecipients(getEmailRecipients(oldLock.getRegistrarId()))
252+
.setRecipients(ImmutableSet.of(getEmailRecipient(oldLock)))
254253
.build());
255254
}
256255

@@ -261,7 +260,7 @@ private void sendGenericTransientFailureEmail(RegistryLock oldLock) {
261260
// For an unexpected failure, notify both the lock-enabled contacts and our alerting email
262261
ImmutableSet<InternetAddress> allRecipients =
263262
new ImmutableSet.Builder<InternetAddress>()
264-
.addAll(getEmailRecipients(oldLock.getRegistrarId()))
263+
.add(getEmailRecipient(oldLock))
265264
.add(alertRecipientAddress)
266265
.build();
267266
gmailClient.sendEmail(
@@ -281,31 +280,12 @@ private void sendUnknownRevisionIdAlertEmail() {
281280
.build());
282281
}
283282

284-
private ImmutableSet<InternetAddress> getEmailRecipients(String registrarId) {
285-
Registrar registrar =
286-
Registrar.loadByRegistrarIdCached(registrarId)
287-
.orElseThrow(
288-
() ->
289-
new IllegalStateException(String.format("Unknown registrar %s", registrarId)));
290-
291-
ImmutableSet<String> registryLockEmailAddresses =
292-
registrar.getContacts().stream()
293-
.filter(RegistrarPoc::isRegistryLockAllowed)
294-
.map(RegistrarPoc::getRegistryLockEmailAddress)
295-
.filter(Optional::isPresent)
296-
.map(Optional::get)
297-
.collect(toImmutableSet());
298-
299-
ImmutableSet.Builder<InternetAddress> builder = new ImmutableSet.Builder<>();
300-
// can't use streams due to the 'throws' in the InternetAddress constructor
301-
for (String registryLockEmailAddress : registryLockEmailAddresses) {
302-
try {
303-
builder.add(new InternetAddress(registryLockEmailAddress));
304-
} catch (AddressException e) {
305-
// This shouldn't stop any other emails going out, so swallow it
306-
logger.atWarning().log("Invalid email address '%s'.", registryLockEmailAddress);
307-
}
283+
private InternetAddress getEmailRecipient(RegistryLock lock) {
284+
try {
285+
return new InternetAddress(lock.getRegistryLockEmail());
286+
} catch (AddressException e) {
287+
// this really shouldn't happen
288+
throw new RuntimeException(e);
308289
}
309-
return builder.build();
310290
}
311291
}

core/src/main/java/google/registry/model/domain/RegistryLock.java

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -101,8 +101,15 @@ public final class RegistryLock extends UpdateAutoTimestampEntity implements Bui
101101
@Column(nullable = false)
102102
private String registrarId;
103103

104-
/** The POC that performed the action, or null if it was a superuser. */
105-
@Expose private String registrarPocId;
104+
/**
105+
* The email address of the user that performed the action, or null if it was a superuser.
106+
*
107+
* <p>Note: this is misnamed in the database due to historical reasons, where we used the
108+
* registrar POC ID as the email address rather than a separate specialized field.
109+
*/
110+
@Column(name = "registrarPocId")
111+
@Expose
112+
private String registryLockEmail;
106113

107114
/** When the lock is first requested. */
108115
@AttributeOverrides({
@@ -161,8 +168,8 @@ public String getRegistrarId() {
161168
return registrarId;
162169
}
163170

164-
public String getRegistrarPocId() {
165-
return registrarPocId;
171+
public String getRegistryLockEmail() {
172+
return registryLockEmail;
166173
}
167174

168175
public DateTime getLockRequestTime() {
@@ -255,7 +262,7 @@ public RegistryLock build() {
255262
checkArgumentNotNull(getInstance().registrarId, "Registrar ID cannot be null");
256263
checkArgumentNotNull(getInstance().verificationCode, "Verification code cannot be null");
257264
checkArgument(
258-
getInstance().registrarPocId != null || getInstance().isSuperuser,
265+
getInstance().registryLockEmail != null || getInstance().isSuperuser,
259266
"Registrar POC ID must be provided if superuser is false");
260267
return super.build();
261268
}
@@ -275,8 +282,8 @@ public Builder setRegistrarId(String registrarId) {
275282
return this;
276283
}
277284

278-
public Builder setRegistrarPocId(String registrarPocId) {
279-
getInstance().registrarPocId = registrarPocId;
285+
public Builder setRegistryLockEmail(String registryLockEmail) {
286+
getInstance().registryLockEmail = registryLockEmail;
280287
return this;
281288
}
282289

core/src/main/java/google/registry/model/registrar/RegistrarPoc.java

Lines changed: 1 addition & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,11 @@
1414

1515
package google.registry.model.registrar;
1616

17-
import static com.google.common.base.Preconditions.checkArgument;
1817
import static com.google.common.base.Preconditions.checkNotNull;
19-
import static com.google.common.base.Strings.isNullOrEmpty;
2018
import static com.google.common.collect.ImmutableSet.toImmutableSet;
21-
import static com.google.common.io.BaseEncoding.base64;
2219
import static google.registry.model.registrar.Registrar.checkValidEmail;
2320
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
2421
import static google.registry.util.CollectionUtils.nullToEmptyImmutableSortedCopy;
25-
import static google.registry.util.PasswordUtils.SALT_SUPPLIER;
26-
import static google.registry.util.PasswordUtils.hashPassword;
2722
import static java.util.stream.Collectors.joining;
2823

2924
import com.google.common.annotations.VisibleForTesting;
@@ -38,7 +33,6 @@
3833
import google.registry.model.UnsafeSerializable;
3934
import google.registry.persistence.VKey;
4035
import google.registry.persistence.transaction.QueryComposer;
41-
import google.registry.util.PasswordUtils;
4236
import jakarta.persistence.Column;
4337
import jakarta.persistence.Entity;
4438
import jakarta.persistence.EnumType;
@@ -47,9 +41,7 @@
4741
import jakarta.persistence.IdClass;
4842
import java.io.Serializable;
4943
import java.util.Map;
50-
import java.util.Optional;
5144
import java.util.Set;
52-
import javax.annotation.Nullable;
5345

5446
/**
5547
* A contact for a Registrar. Note, equality, hashCode and comparable have been overridden to only
@@ -107,9 +99,6 @@ public boolean isRequired() {
10799

108100
@Id @Expose public String registrarId;
109101

110-
/** External email address of this contact used for registry lock confirmations. */
111-
String registryLockEmailAddress;
112-
113102
/** The voice number of the contact. */
114103
@Expose String phoneNumber;
115104

@@ -147,22 +136,10 @@ public boolean isRequired() {
147136
@Expose
148137
boolean visibleInDomainWhoisAsAbuse = false;
149138

150-
/**
151-
* Whether the contact is allowed to set their registry lock password through the registrar
152-
* console. This will be set to false on contact creation and when the user sets a password.
153-
*/
139+
/** Legacy field, around until we can remove the non-null constraint and the column from SQL. */
154140
@Column(nullable = false)
155141
boolean allowedToSetRegistryLockPassword = false;
156142

157-
/**
158-
* A hashed password that exists iff this contact is registry-lock-enabled. The hash is a base64
159-
* encoded SHA256 string.
160-
*/
161-
String registryLockPasswordHash;
162-
163-
/** Randomly generated hash salt. */
164-
String registryLockPasswordSalt;
165-
166143
/**
167144
* Helper to update the contacts associated with a Registrar. This requires querying for the
168145
* existing contacts, deleting existing contacts that are not part of the given {@code contacts}
@@ -197,10 +174,6 @@ public String getEmailAddress() {
197174
return emailAddress;
198175
}
199176

200-
public Optional<String> getRegistryLockEmailAddress() {
201-
return Optional.ofNullable(registryLockEmailAddress);
202-
}
203-
204177
public String getPhoneNumber() {
205178
return phoneNumber;
206179
}
@@ -229,24 +202,6 @@ public Builder asBuilder() {
229202
return new Builder(clone(this));
230203
}
231204

232-
public boolean isAllowedToSetRegistryLockPassword() {
233-
return allowedToSetRegistryLockPassword;
234-
}
235-
236-
public boolean isRegistryLockAllowed() {
237-
return !isNullOrEmpty(registryLockPasswordHash) && !isNullOrEmpty(registryLockPasswordSalt);
238-
}
239-
240-
public boolean verifyRegistryLockPassword(String registryLockPassword) {
241-
if (isNullOrEmpty(registryLockPassword)
242-
|| isNullOrEmpty(registryLockPasswordSalt)
243-
|| isNullOrEmpty(registryLockPasswordHash)) {
244-
return false;
245-
}
246-
return PasswordUtils.verifyPassword(
247-
registryLockPassword, registryLockPasswordHash, registryLockPasswordSalt);
248-
}
249-
250205
/**
251206
* Returns a string representation that's human friendly.
252207
*
@@ -296,15 +251,12 @@ public Map<String, Object> toJsonMap() {
296251
return new JsonMapBuilder()
297252
.put("name", name)
298253
.put("emailAddress", emailAddress)
299-
.put("registryLockEmailAddress", registryLockEmailAddress)
300254
.put("phoneNumber", phoneNumber)
301255
.put("faxNumber", faxNumber)
302256
.put("types", getTypes().stream().map(Object::toString).collect(joining(",")))
303257
.put("visibleInWhoisAsAdmin", visibleInWhoisAsAdmin)
304258
.put("visibleInWhoisAsTech", visibleInWhoisAsTech)
305259
.put("visibleInDomainWhoisAsAbuse", visibleInDomainWhoisAsAbuse)
306-
.put("allowedToSetRegistryLockPassword", allowedToSetRegistryLockPassword)
307-
.put("registryLockAllowed", isRegistryLockAllowed())
308260
.put("id", getId())
309261
.build();
310262
}
@@ -344,14 +296,6 @@ protected Builder(RegistrarPoc instance) {
344296
public RegistrarPoc build() {
345297
checkNotNull(getInstance().registrarId, "Registrar ID cannot be null");
346298
checkValidEmail(getInstance().emailAddress);
347-
// Check allowedToSetRegistryLockPassword here because if we want to allow the user to set
348-
// a registry lock password, we must also set up the correct registry lock email concurrently
349-
// or beforehand.
350-
if (getInstance().allowedToSetRegistryLockPassword) {
351-
checkArgument(
352-
!isNullOrEmpty(getInstance().registryLockEmailAddress),
353-
"Registry lock email must not be null if allowing registry lock access");
354-
}
355299
return cloneEmptyToNull(super.build());
356300
}
357301

@@ -365,11 +309,6 @@ public Builder setEmailAddress(String emailAddress) {
365309
return this;
366310
}
367311

368-
public Builder setRegistryLockEmailAddress(@Nullable String registryLockEmailAddress) {
369-
getInstance().registryLockEmailAddress = registryLockEmailAddress;
370-
return this;
371-
}
372-
373312
public Builder setPhoneNumber(String phoneNumber) {
374313
getInstance().phoneNumber = phoneNumber;
375314
return this;
@@ -409,28 +348,6 @@ public Builder setVisibleInDomainWhoisAsAbuse(boolean visible) {
409348
getInstance().visibleInDomainWhoisAsAbuse = visible;
410349
return this;
411350
}
412-
413-
public Builder setAllowedToSetRegistryLockPassword(boolean allowedToSetRegistryLockPassword) {
414-
if (allowedToSetRegistryLockPassword) {
415-
getInstance().registryLockPasswordSalt = null;
416-
getInstance().registryLockPasswordHash = null;
417-
}
418-
getInstance().allowedToSetRegistryLockPassword = allowedToSetRegistryLockPassword;
419-
return this;
420-
}
421-
422-
public Builder setRegistryLockPassword(String registryLockPassword) {
423-
checkArgument(
424-
getInstance().allowedToSetRegistryLockPassword,
425-
"Not allowed to set registry lock password for this contact");
426-
checkArgument(
427-
!isNullOrEmpty(registryLockPassword), "Registry lock password was null or empty");
428-
byte[] salt = SALT_SUPPLIER.get();
429-
getInstance().registryLockPasswordSalt = base64().encode(salt);
430-
getInstance().registryLockPasswordHash = hashPassword(registryLockPassword, salt);
431-
getInstance().allowedToSetRegistryLockPassword = false;
432-
return this;
433-
}
434351
}
435352

436353
public static ImmutableList<RegistrarPoc> loadForRegistrar(String registrarId) {

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

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -74,11 +74,12 @@ public DomainLockUtils(
7474
* <p>The lock will not be applied until {@link #verifyVerificationCode} is called.
7575
*/
7676
public RegistryLock saveNewRegistryLockRequest(
77-
String domainName, String registrarId, @Nullable String registrarPocId, boolean isAdmin) {
77+
String domainName, String registrarId, @Nullable String registryLockEmail, boolean isAdmin) {
7878
return tm().transact(
7979
() ->
8080
RegistryLockDao.save(
81-
createLockBuilder(domainName, registrarId, registrarPocId, isAdmin).build()));
81+
createLockBuilder(domainName, registrarId, registryLockEmail, isAdmin)
82+
.build()));
8283
}
8384

8485
/**
@@ -129,13 +130,13 @@ public RegistryLock verifyVerificationCode(String verificationCode, boolean isAd
129130
* the case of relocks, isAdmin is determined by the previous lock.
130131
*/
131132
public RegistryLock administrativelyApplyLock(
132-
String domainName, String registrarId, @Nullable String registrarPocId, boolean isAdmin) {
133+
String domainName, String registrarId, @Nullable String registryLockEmail, boolean isAdmin) {
133134
return tm().transact(
134135
() -> {
135136
DateTime now = tm().getTransactionTime();
136137
RegistryLock newLock =
137138
RegistryLockDao.save(
138-
createLockBuilder(domainName, registrarId, registrarPocId, isAdmin)
139+
createLockBuilder(domainName, registrarId, registryLockEmail, isAdmin)
139140
.setLockCompletionTime(now)
140141
.build());
141142
applyLockStatuses(newLock, now, isAdmin);
@@ -235,7 +236,7 @@ private void setAsRelock(RegistryLock newLock) {
235236
}
236237

237238
private RegistryLock.Builder createLockBuilder(
238-
String domainName, String registrarId, @Nullable String registrarPocId, boolean isAdmin) {
239+
String domainName, String registrarId, @Nullable String registryLockEmail, boolean isAdmin) {
239240
DateTime now = tm().getTransactionTime();
240241
Domain domain = getDomain(domainName, registrarId, now);
241242
verifyDomainNotLocked(domain, isAdmin);
@@ -255,7 +256,7 @@ private RegistryLock.Builder createLockBuilder(
255256
.setDomainName(domainName)
256257
.setRepoId(domain.getRepoId())
257258
.setRegistrarId(registrarId)
258-
.setRegistrarPocId(registrarPocId)
259+
.setRegistryLockEmail(registryLockEmail)
259260
.isSuperuser(isAdmin);
260261
}
261262

0 commit comments

Comments
 (0)