Skip to content

Commit 3145a55

Browse files
committed
Add RegistrarUpdateHistory objects for console changes
1 parent 142c910 commit 3145a55

13 files changed

+113
-16
lines changed

core/src/main/java/google/registry/ui/server/console/ConsoleApiAction.java

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
import google.registry.config.RegistryConfig;
3636
import google.registry.export.sheet.SyncRegistrarsSheetAction;
3737
import google.registry.model.console.ConsolePermission;
38+
import google.registry.model.console.ConsoleUpdateHistory;
3839
import google.registry.model.console.GlobalRole;
3940
import google.registry.model.console.User;
4041
import google.registry.model.console.UserRoles;
@@ -208,10 +209,10 @@ protected void sendExternalUpdates(
208209
registrar.getRegistrarName(), registrar.getRegistrarId(), environment),
209210
String.format(
210211
"""
211-
The following changes were made in registry %s environment to the registrar %s by\
212-
%s:
212+
The following changes were made in registry %s environment to the registrar %s by\
213+
%s:
213214
214-
%s""",
215+
%s""",
215216
environment,
216217
registrar.getRegistrarId(),
217218
consoleApiParams.authResult().userIdForLogging(),
@@ -261,6 +262,14 @@ public static EmailInfo create(
261262
}
262263
}
263264

265+
protected void finishAndPersistConsoleUpdateHistory(ConsoleUpdateHistory.Builder<?, ?> builder) {
266+
builder.setActingUser(consoleApiParams.authResult().user().get());
267+
builder.setUrl(consoleApiParams.request().getRequestURI());
268+
builder.setMethod(consoleApiParams.request().getMethod());
269+
builder.setModificationTime(tm().getTransactionTime());
270+
tm().put(builder.build());
271+
}
272+
264273
/** Specialized exception class used for failure when a user doesn't have the right permission. */
265274
private static class ConsolePermissionForbiddenException extends RuntimeException {
266275
private ConsolePermissionForbiddenException(String message) {

core/src/main/java/google/registry/ui/server/console/ConsoleEppPasswordAction.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,12 @@
2424
import com.google.common.base.Strings;
2525
import com.google.common.collect.ImmutableMap;
2626
import com.google.common.collect.ImmutableSet;
27+
import com.google.gson.Gson;
2728
import com.google.gson.annotations.Expose;
2829
import google.registry.flows.EppException.AuthenticationErrorException;
2930
import google.registry.flows.PasswordOnlyTransportCredentials;
31+
import google.registry.model.console.ConsoleUpdateHistory;
32+
import google.registry.model.console.RegistrarUpdateHistory;
3033
import google.registry.model.console.User;
3134
import google.registry.model.registrar.Registrar;
3235
import google.registry.request.Action;
@@ -53,16 +56,18 @@ public class ConsoleEppPasswordAction extends ConsoleApiAction {
5356
private final PasswordOnlyTransportCredentials credentials =
5457
new PasswordOnlyTransportCredentials();
5558
private final AuthenticatedRegistrarAccessor registrarAccessor;
56-
59+
private final Gson gson;
5760
private final Optional<EppPasswordData> eppPasswordChangeRequest;
5861

5962
@Inject
6063
public ConsoleEppPasswordAction(
6164
ConsoleApiParams consoleApiParams,
6265
AuthenticatedRegistrarAccessor registrarAccessor,
66+
Gson gson,
6367
@Parameter("eppPasswordChangeRequest") Optional<EppPasswordData> eppPasswordChangeRequest) {
6468
super(consoleApiParams);
6569
this.registrarAccessor = registrarAccessor;
70+
this.gson = gson;
6671
this.eppPasswordChangeRequest = eppPasswordChangeRequest;
6772
}
6873

@@ -106,6 +111,11 @@ protected void postHandler(User user) {
106111
Registrar updatedRegistrar =
107112
registrar.asBuilder().setPassword(eppRequestBody.newPassword()).build();
108113
tm().put(updatedRegistrar);
114+
finishAndPersistConsoleUpdateHistory(
115+
new RegistrarUpdateHistory.Builder()
116+
.setType(ConsoleUpdateHistory.Type.REGISTRAR_UPDATE)
117+
.setRegistrar(updatedRegistrar)
118+
.setRequestBody(gson.toJson(eppRequestBody)));
109119
sendExternalUpdates(
110120
ImmutableMap.of("password", new DiffUtils.DiffPair("********", "••••••••")),
111121
registrar,

core/src/main/java/google/registry/ui/server/console/ConsoleUpdateRegistrarAction.java

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,10 @@
2222

2323
import com.google.common.base.Strings;
2424
import com.google.common.collect.ImmutableSet;
25+
import com.google.gson.Gson;
2526
import google.registry.model.console.ConsolePermission;
27+
import google.registry.model.console.ConsoleUpdateHistory;
28+
import google.registry.model.console.RegistrarUpdateHistory;
2629
import google.registry.model.console.User;
2730
import google.registry.model.registrar.Registrar;
2831
import google.registry.request.Action;
@@ -45,12 +48,16 @@
4548
auth = Auth.AUTH_PUBLIC_LOGGED_IN)
4649
public class ConsoleUpdateRegistrarAction extends ConsoleApiAction {
4750
static final String PATH = "/console-api/registrar";
51+
private final Gson gson;
4852
private final Optional<Registrar> registrar;
4953

5054
@Inject
5155
ConsoleUpdateRegistrarAction(
52-
ConsoleApiParams consoleApiParams, @Parameter("registrar") Optional<Registrar> registrar) {
56+
ConsoleApiParams consoleApiParams,
57+
Gson gson,
58+
@Parameter("registrar") Optional<Registrar> registrar) {
5359
super(consoleApiParams);
60+
this.gson = gson;
5461
this.registrar = registrar;
5562
}
5663

@@ -99,6 +106,11 @@ protected void postHandler(User user) {
99106
.build();
100107

101108
tm().put(updatedRegistrar);
109+
finishAndPersistConsoleUpdateHistory(
110+
new RegistrarUpdateHistory.Builder()
111+
.setType(ConsoleUpdateHistory.Type.REGISTRAR_UPDATE)
112+
.setRegistrar(updatedRegistrar)
113+
.setRequestBody(gson.toJson(registrarParam)));
102114
sendExternalUpdatesIfNecessary(
103115
EmailInfo.create(
104116
existingRegistrar.get(),

core/src/main/java/google/registry/ui/server/console/RegistrarsAction.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828
import com.google.common.collect.Streams;
2929
import com.google.gson.Gson;
3030
import google.registry.model.console.ConsolePermission;
31+
import google.registry.model.console.ConsoleUpdateHistory;
32+
import google.registry.model.console.RegistrarUpdateHistory;
3133
import google.registry.model.console.User;
3234
import google.registry.model.registrar.Registrar;
3335
import google.registry.model.registrar.RegistrarBase;
@@ -175,6 +177,11 @@ protected void postHandler(User user) {
175177
"Registrar with registrarId %s already exists",
176178
registrar.getRegistrarId());
177179
tm().putAll(registrar, contact);
180+
finishAndPersistConsoleUpdateHistory(
181+
new RegistrarUpdateHistory.Builder()
182+
.setType(ConsoleUpdateHistory.Type.REGISTRAR_UPDATE)
183+
.setRegistrar(registrar)
184+
.setRequestBody(gson.toJson(registrar)));
178185
});
179186
}
180187

core/src/main/java/google/registry/ui/server/console/settings/SecurityAction.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,12 @@
2222
import static jakarta.servlet.http.HttpServletResponse.SC_OK;
2323

2424
import com.google.common.collect.ImmutableSet;
25+
import com.google.gson.Gson;
2526
import google.registry.flows.certs.CertificateChecker;
2627
import google.registry.flows.certs.CertificateChecker.InsecureCertificateException;
2728
import google.registry.model.console.ConsolePermission;
29+
import google.registry.model.console.ConsoleUpdateHistory;
30+
import google.registry.model.console.RegistrarUpdateHistory;
2831
import google.registry.model.console.User;
2932
import google.registry.model.registrar.Registrar;
3033
import google.registry.request.Action;
@@ -50,6 +53,7 @@ public class SecurityAction extends ConsoleApiAction {
5053
static final String PATH = "/console-api/settings/security";
5154
private final String registrarId;
5255
private final AuthenticatedRegistrarAccessor registrarAccessor;
56+
private final Gson gson;
5357
private final Optional<Registrar> registrar;
5458
private final CertificateChecker certificateChecker;
5559

@@ -58,11 +62,13 @@ public SecurityAction(
5862
ConsoleApiParams consoleApiParams,
5963
CertificateChecker certificateChecker,
6064
AuthenticatedRegistrarAccessor registrarAccessor,
65+
Gson gson,
6166
@Parameter("registrarId") String registrarId,
6267
@Parameter("registrar") Optional<Registrar> registrar) {
6368
super(consoleApiParams);
6469
this.registrarId = registrarId;
6570
this.registrarAccessor = registrarAccessor;
71+
this.gson = gson;
6672
this.registrar = registrar;
6773
this.certificateChecker = certificateChecker;
6874
}
@@ -117,6 +123,11 @@ private void setResponse(Registrar savedRegistrar) {
117123

118124
Registrar updatedRegistrar = updatedRegistrarBuilder.build();
119125
tm().put(updatedRegistrar);
126+
finishAndPersistConsoleUpdateHistory(
127+
new RegistrarUpdateHistory.Builder()
128+
.setType(ConsoleUpdateHistory.Type.REGISTRAR_UPDATE)
129+
.setRegistrar(updatedRegistrar)
130+
.setRequestBody(gson.toJson(registrar.get())));
120131

121132
sendExternalUpdatesIfNecessary(
122133
EmailInfo.create(savedRegistrar, updatedRegistrar, ImmutableSet.of(), ImmutableSet.of()));

core/src/main/java/google/registry/ui/server/console/settings/WhoisRegistrarFieldsAction.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,10 @@
2121
import static jakarta.servlet.http.HttpServletResponse.SC_FORBIDDEN;
2222
import static jakarta.servlet.http.HttpServletResponse.SC_OK;
2323

24+
import com.google.gson.Gson;
2425
import google.registry.model.console.ConsolePermission;
26+
import google.registry.model.console.ConsoleUpdateHistory;
27+
import google.registry.model.console.RegistrarUpdateHistory;
2528
import google.registry.model.console.User;
2629
import google.registry.model.registrar.Registrar;
2730
import google.registry.request.Action;
@@ -53,15 +56,18 @@ public class WhoisRegistrarFieldsAction extends ConsoleApiAction {
5356

5457
static final String PATH = "/console-api/settings/whois-fields";
5558
private final AuthenticatedRegistrarAccessor registrarAccessor;
59+
private final Gson gson;
5660
private final Optional<Registrar> registrar;
5761

5862
@Inject
5963
public WhoisRegistrarFieldsAction(
6064
ConsoleApiParams consoleApiParams,
6165
AuthenticatedRegistrarAccessor registrarAccessor,
66+
Gson gson,
6267
@Parameter("registrar") Optional<Registrar> registrar) {
6368
super(consoleApiParams);
6469
this.registrarAccessor = registrarAccessor;
70+
this.gson = gson;
6571
this.registrar = registrar;
6672
}
6773

@@ -104,6 +110,11 @@ private void loadAndModifyRegistrar(Registrar providedRegistrar, User user) {
104110
.setEmailAddress(providedRegistrar.getEmailAddress())
105111
.build();
106112
tm().put(newRegistrar);
113+
finishAndPersistConsoleUpdateHistory(
114+
new RegistrarUpdateHistory.Builder()
115+
.setType(ConsoleUpdateHistory.Type.REGISTRAR_UPDATE)
116+
.setRegistrar(newRegistrar)
117+
.setRequestBody(gson.toJson(registrar.get())));
107118
sendExternalUpdatesIfNecessary(
108119
EmailInfo.create(
109120
savedRegistrar,

core/src/test/java/google/registry/testing/ConsoleApiParamsUtils.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ public static ConsoleApiParams createFake(AuthResult authResult) {
4545
xsrfTokenManager.generateToken(
4646
authResult.user().map(User::getEmailAddress).orElse("")))
4747
});
48+
when(request.getRequestURI()).thenReturn("/console/fake-url");
4849
return ConsoleApiParams.create(
4950
request, new FakeResponse(), authResult, sendEmailUtils, xsrfTokenManager);
5051
}

core/src/test/java/google/registry/testing/DatabaseHelper.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1294,6 +1294,11 @@ public static <T> ImmutableList<T> loadByEntitiesIfPresent(Iterable<T> entities)
12941294
return tm().transact(() -> tm().loadByEntitiesIfPresent(entities));
12951295
}
12961296

1297+
/** Loads the only instance of this particular class, or empty if none exists. */
1298+
public static <T> Optional<T> loadSingleton(Class<T> clazz) {
1299+
return tm().transact(() -> tm().loadSingleton(clazz));
1300+
}
1301+
12971302
/** Returns whether or not the given entity exists in Cloud SQL. */
12981303
public static boolean existsInDb(ImmutableObject object) {
12991304
return tm().transact(() -> tm().exists(object));

core/src/test/java/google/registry/ui/server/console/ConsoleEppPasswordActionTest.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import static com.google.common.truth.Truth.assertThat;
1818
import static google.registry.request.auth.AuthenticatedRegistrarAccessor.Role.OWNER;
1919
import static google.registry.testing.DatabaseHelper.loadRegistrar;
20+
import static google.registry.testing.DatabaseHelper.loadSingleton;
2021
import static google.registry.testing.DatabaseHelper.persistResource;
2122
import static jakarta.servlet.http.HttpServletResponse.SC_BAD_REQUEST;
2223
import static jakarta.servlet.http.HttpServletResponse.SC_FORBIDDEN;
@@ -32,6 +33,7 @@
3233
import com.google.gson.Gson;
3334
import google.registry.flows.PasswordOnlyTransportCredentials;
3435
import google.registry.model.console.GlobalRole;
36+
import google.registry.model.console.RegistrarUpdateHistory;
3537
import google.registry.model.console.User;
3638
import google.registry.model.console.UserRoles;
3739
import google.registry.model.registrar.Registrar;
@@ -41,6 +43,7 @@
4143
import google.registry.request.auth.AuthResult;
4244
import google.registry.request.auth.AuthenticatedRegistrarAccessor;
4345
import google.registry.testing.ConsoleApiParamsUtils;
46+
import google.registry.testing.DatabaseHelper;
4447
import google.registry.testing.FakeResponse;
4548
import google.registry.tools.GsonUtils;
4649
import google.registry.ui.server.console.ConsoleEppPasswordAction.EppPasswordData;
@@ -139,6 +142,10 @@ void testSuccess_passwordUpdated() throws IOException {
139142
() -> {
140143
credentials.validate(loadRegistrar("TheRegistrar"), "randomPassword");
141144
});
145+
assertThat(loadSingleton(RegistrarUpdateHistory.class).get().getRequestBody())
146+
.isEqualTo(
147+
"{\"registrarId\":\"TheRegistrar\",\"oldPassword\":\"foobar\",\"newPassword\":"
148+
+ "\"randomPassword\",\"newPasswordRepeat\":\"randomPassword\"}");
142149
}
143150

144151
private ConsoleEppPasswordAction createAction(
@@ -150,6 +157,7 @@ private ConsoleEppPasswordAction createAction(
150157
.setEmailAddress("[email protected]")
151158
.setUserRoles(new UserRoles.Builder().setGlobalRole(GlobalRole.FTE).build())
152159
.build();
160+
DatabaseHelper.putInDb(user);
153161

154162
AuthResult authResult = AuthResult.createUser(user);
155163
consoleApiParams = ConsoleApiParamsUtils.createFake(authResult);
@@ -169,6 +177,6 @@ private ConsoleEppPasswordAction createAction(
169177
GSON, RequestModule.provideJsonBody(consoleApiParams.request(), GSON));
170178

171179
return new ConsoleEppPasswordAction(
172-
consoleApiParams, authenticatedRegistrarAccessor, maybePasswordChangeRequest);
180+
consoleApiParams, authenticatedRegistrarAccessor, GSON, maybePasswordChangeRequest);
173181
}
174182
}

core/src/test/java/google/registry/ui/server/console/ConsoleUpdateRegistrarActionTest.java

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,10 @@
1515
package google.registry.ui.server.console;
1616

1717
import static com.google.common.truth.Truth.assertThat;
18+
import static google.registry.model.ImmutableObjectSubject.assertAboutImmutableObjects;
1819
import static google.registry.model.registrar.RegistrarPocBase.Type.WHOIS;
1920
import static google.registry.testing.DatabaseHelper.createTlds;
21+
import static google.registry.testing.DatabaseHelper.loadSingleton;
2022
import static google.registry.testing.DatabaseHelper.persistResource;
2123
import static jakarta.servlet.http.HttpServletResponse.SC_BAD_REQUEST;
2224
import static jakarta.servlet.http.HttpServletResponse.SC_OK;
@@ -29,6 +31,7 @@
2931
import com.google.common.collect.ImmutableSet;
3032
import com.google.gson.Gson;
3133
import google.registry.model.console.GlobalRole;
34+
import google.registry.model.console.RegistrarUpdateHistory;
3235
import google.registry.model.console.User;
3336
import google.registry.model.console.UserRoles;
3437
import google.registry.model.registrar.Registrar;
@@ -85,10 +88,11 @@ void beforeEach() throws Exception {
8588
.setRegistryLockAllowed(false)
8689
.build());
8790
user =
88-
new User.Builder()
89-
.setEmailAddress("[email protected]")
90-
.setUserRoles(new UserRoles.Builder().setGlobalRole(GlobalRole.FTE).build())
91-
.build();
91+
persistResource(
92+
new User.Builder()
93+
.setEmailAddress("[email protected]")
94+
.setUserRoles(new UserRoles.Builder().setGlobalRole(GlobalRole.FTE).build())
95+
.build());
9296
consoleApiParams = createParams();
9397
}
9498

@@ -104,6 +108,9 @@ void testSuccess_updatesRegistrar() throws IOException {
104108
assertThat(newRegistrar.getAllowedTlds()).containsExactly("app", "dev");
105109
assertThat(newRegistrar.isRegistryLockAllowed()).isFalse();
106110
assertThat(((FakeResponse) consoleApiParams.response()).getStatus()).isEqualTo(SC_OK);
111+
assertAboutImmutableObjects()
112+
.that(newRegistrar)
113+
.hasFieldsEqualTo(loadSingleton(RegistrarUpdateHistory.class).get().getRegistrar());
107114
}
108115

109116
@Test
@@ -172,6 +179,6 @@ ConsoleUpdateRegistrarAction createAction(String requestData) throws IOException
172179
Optional<Registrar> maybeRegistrarUpdateData =
173180
ConsoleModule.provideRegistrar(
174181
GSON, RequestModule.provideJsonBody(consoleApiParams.request(), GSON));
175-
return new ConsoleUpdateRegistrarAction(consoleApiParams, maybeRegistrarUpdateData);
182+
return new ConsoleUpdateRegistrarAction(consoleApiParams, GSON, maybeRegistrarUpdateData);
176183
}
177184
}

0 commit comments

Comments
 (0)