From e249c93b4f08649d5531b8e3ae2e19cf9aaf340b Mon Sep 17 00:00:00 2001 From: ptkach Date: Fri, 27 Feb 2026 18:51:58 +0000 Subject: [PATCH] Enable password reset for registrars --- .../security/eppPasswordEdit.component.html | 2 -- .../userLevelVisiblity.directive.ts | 3 +-- .../src/app/users/userEditForm.component.html | 2 -- .../console/PasswordResetRequestAction.java | 4 --- .../console/PasswordResetVerifyAction.java | 26 ++++++++++++------- .../PasswordResetVerifyActionTest.java | 5 ---- 6 files changed, 17 insertions(+), 25 deletions(-) diff --git a/console-webapp/src/app/settings/security/eppPasswordEdit.component.html b/console-webapp/src/app/settings/security/eppPasswordEdit.component.html index 93908ca51d4..62b175669a9 100644 --- a/console-webapp/src/app/settings/security/eppPasswordEdit.component.html +++ b/console-webapp/src/app/settings/security/eppPasswordEdit.component.html @@ -21,7 +21,6 @@

Update EPP password

[formGroup]="passwordUpdateForm" (submitResults)="save($event)" /> - @if(userDataService.userData()?.isAdmin) {

Need to reset your EPP password?

- } diff --git a/console-webapp/src/app/shared/directives/userLevelVisiblity.directive.ts b/console-webapp/src/app/shared/directives/userLevelVisiblity.directive.ts index fba4094f434..e1c06d1cc14 100644 --- a/console-webapp/src/app/shared/directives/userLevelVisiblity.directive.ts +++ b/console-webapp/src/app/shared/directives/userLevelVisiblity.directive.ts @@ -29,10 +29,9 @@ export const DISABLED_ELEMENTS_PER_ROLE = { RESTRICTED_ELEMENTS.REGISTRAR_ELEMENT, RESTRICTED_ELEMENTS.OTE, RESTRICTED_ELEMENTS.SUSPEND, - RESTRICTED_ELEMENTS.ACTIVITY_PER_USER, ], SUPPORT_LEAD: [], - SUPPORT_AGENT: [RESTRICTED_ELEMENTS.ACTIVITY_PER_USER], + SUPPORT_AGENT: [], }; @Directive({ diff --git a/console-webapp/src/app/users/userEditForm.component.html b/console-webapp/src/app/users/userEditForm.component.html index 0a581104483..a6f31b0f86a 100644 --- a/console-webapp/src/app/users/userEditForm.component.html +++ b/console-webapp/src/app/users/userEditForm.component.html @@ -46,7 +46,6 @@ Save - @if(userDataService.userData()?.isAdmin) { - } diff --git a/core/src/main/java/google/registry/ui/server/console/PasswordResetRequestAction.java b/core/src/main/java/google/registry/ui/server/console/PasswordResetRequestAction.java index 30d1bd3b321..ba634d610c9 100644 --- a/core/src/main/java/google/registry/ui/server/console/PasswordResetRequestAction.java +++ b/core/src/main/java/google/registry/ui/server/console/PasswordResetRequestAction.java @@ -61,10 +61,6 @@ public PasswordResetRequestAction( @Override protected void postHandler(User user) { - // Temporary flag when testing email sending etc - if (!user.getUserRoles().isAdmin()) { - setFailedResponse("", HttpServletResponse.SC_FORBIDDEN); - } tm().transact(() -> performRequest(user)); consoleApiParams.response().setStatus(HttpServletResponse.SC_OK); } diff --git a/core/src/main/java/google/registry/ui/server/console/PasswordResetVerifyAction.java b/core/src/main/java/google/registry/ui/server/console/PasswordResetVerifyAction.java index 640adb152a0..8800756e516 100644 --- a/core/src/main/java/google/registry/ui/server/console/PasswordResetVerifyAction.java +++ b/core/src/main/java/google/registry/ui/server/console/PasswordResetVerifyAction.java @@ -23,6 +23,7 @@ import com.google.common.base.Strings; import com.google.common.collect.ImmutableMap; import google.registry.model.console.ConsolePermission; +import google.registry.model.console.ConsoleUpdateHistory; import google.registry.model.console.PasswordResetRequest; import google.registry.model.console.User; import google.registry.model.registrar.Registrar; @@ -59,11 +60,6 @@ public PasswordResetVerifyAction( @Override protected void getHandler(User user) { - // Temporary flag when testing email sending etc - if (!user.getUserRoles().isAdmin()) { - setFailedResponse("", HttpServletResponse.SC_FORBIDDEN); - return; - } PasswordResetRequest request = tm().transact(() -> loadAndValidateResetRequest(user)); ImmutableMap result = ImmutableMap.of("type", request.getType(), "registrarId", request.getRegistrarId()); @@ -73,11 +69,6 @@ protected void getHandler(User user) { @Override protected void postHandler(User user) { - // Temporary flag when testing email sending etc - if (!user.getUserRoles().isAdmin()) { - setFailedResponse("", HttpServletResponse.SC_FORBIDDEN); - return; - } checkArgument(!Strings.isNullOrEmpty(newPassword.orElse(null)), "Password must be provided"); tm().transact( () -> { @@ -87,6 +78,16 @@ protected void postHandler(User user) { case REGISTRY_LOCK -> handleRegistryLockPasswordReset(request); } tm().put(request.asBuilder().setFulfillmentTime(tm().getTransactionTime()).build()); + + finishAndPersistConsoleUpdateHistory( + new ConsoleUpdateHistory.Builder() + .setType(ConsoleUpdateHistory.Type.EPP_PASSWORD_UPDATE) + .setDescription( + String.format( + "%s%s%s", + request.getRegistrarId(), + ConsoleUpdateHistory.DESCRIPTION_SEPARATOR, + "Password reset fulfilled via verification code"))); }); consoleApiParams.response().setStatus(HttpServletResponse.SC_OK); } @@ -110,6 +111,11 @@ private PasswordResetRequest loadAndValidateResetRequest(User user) { PasswordResetRequest request = tm().loadByKeyIfPresent(VKey.create(PasswordResetRequest.class, verificationCode)) .orElseThrow(this::createVerificationCodeException); + + if (request.getFulfillmentTime().isPresent()) { + throw new IllegalArgumentException("This reset request has already been used."); + } + ConsolePermission requiredVerifyPermission = switch (request.getType()) { case EPP -> ConsolePermission.MANAGE_USERS; diff --git a/core/src/test/java/google/registry/ui/server/console/PasswordResetVerifyActionTest.java b/core/src/test/java/google/registry/ui/server/console/PasswordResetVerifyActionTest.java index 852d7545f1a..700f4e29e9e 100644 --- a/core/src/test/java/google/registry/ui/server/console/PasswordResetVerifyActionTest.java +++ b/core/src/test/java/google/registry/ui/server/console/PasswordResetVerifyActionTest.java @@ -34,7 +34,6 @@ import javax.annotation.Nullable; import org.joda.time.Duration; import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; /** Tests for {@link PasswordResetVerifyAction}. */ @@ -111,28 +110,24 @@ void testFailure_emptyPassword() throws Exception { } @Test - @Disabled("Enable when testing is done in sandbox and isAdmin check is removed") void testFailure_get_epp_badPermission() throws Exception { createAction(createTechUser(), "GET", verificationCode, null).run(); assertThat(response.getStatus()).isEqualTo(HttpServletResponse.SC_FORBIDDEN); } @Test - @Disabled("Enable when testing is done in sandbox and isAdmin check is removed") void testFailure_get_lock_badPermission() throws Exception { createAction(createAccountManager(), "GET", verificationCode, null).run(); assertThat(response.getStatus()).isEqualTo(HttpServletResponse.SC_FORBIDDEN); } @Test - @Disabled("Enable when testing is done in sandbox and isAdmin check is removed") void testFailure_post_epp_badPermission() throws Exception { createAction(createTechUser(), "POST", verificationCode, "newPassword").run(); assertThat(response.getStatus()).isEqualTo(HttpServletResponse.SC_FORBIDDEN); } @Test - @Disabled("Enable when testing is done in sandbox and isAdmin check is removed") void testFailure_post_lock_badPermission() throws Exception { createAction(createAccountManager(), "POST", verificationCode, "newPassword").run(); assertThat(response.getStatus()).isEqualTo(HttpServletResponse.SC_FORBIDDEN);