1
0
mirror of https://github.com/google/nomulus synced 2026-04-21 08:40:44 +00:00

Add console backend for EPP password change (#2396)

This commit is contained in:
Pavlo Tkach
2024-04-20 06:44:26 -04:00
committed by GitHub
parent b5629ff16f
commit 4de2bd5901
7 changed files with 352 additions and 2 deletions

View File

@@ -0,0 +1,210 @@
// Copyright 2024 The Nomulus Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package google.registry.ui.server.console;
import static com.google.common.truth.Truth.assertThat;
import static google.registry.request.auth.AuthenticatedRegistrarAccessor.Role.OWNER;
import static google.registry.testing.DatabaseHelper.loadRegistrar;
import static google.registry.testing.DatabaseHelper.persistNewRegistrar;
import static google.registry.testing.DatabaseHelper.persistResource;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import com.google.api.client.http.HttpStatusCodes;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSetMultimap;
import com.google.gson.Gson;
import google.registry.flows.PasswordOnlyTransportCredentials;
import google.registry.groups.GmailClient;
import google.registry.model.console.GlobalRole;
import google.registry.model.console.User;
import google.registry.model.console.UserRoles;
import google.registry.model.registrar.Registrar;
import google.registry.persistence.transaction.JpaTestExtensions;
import google.registry.request.Action;
import google.registry.request.auth.AuthResult;
import google.registry.request.auth.AuthenticatedRegistrarAccessor;
import google.registry.request.auth.UserAuthInfo;
import google.registry.testing.FakeConsoleApiParams;
import google.registry.testing.FakeResponse;
import google.registry.tools.GsonUtils;
import google.registry.ui.server.registrar.ConsoleApiParams;
import google.registry.util.EmailMessage;
import jakarta.servlet.http.Cookie;
import java.util.Optional;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
class ConsoleEppPasswordActionTest {
private static final Gson GSON = GsonUtils.provideGson();
private ConsoleApiParams consoleApiParams;
protected PasswordOnlyTransportCredentials credentials = new PasswordOnlyTransportCredentials();
private FakeResponse response;
private GmailClient gmailClient = mock(GmailClient.class);
@RegisterExtension
final JpaTestExtensions.JpaIntegrationTestExtension jpa =
new JpaTestExtensions.Builder().buildIntegrationTestExtension();
@BeforeEach
void beforeEach() {
Registrar registrar = persistNewRegistrar("registrarId");
registrar =
registrar
.asBuilder()
.setType(Registrar.Type.TEST)
.setIanaIdentifier(null)
.setPassword("foobar")
.setEmailAddress("testEmail@google.com")
.build();
persistResource(registrar);
}
@Test
void testFailure_emptyParams() {
ConsoleEppPasswordAction action = createAction();
action.run();
assertThat(((FakeResponse) consoleApiParams.response()).getStatus())
.isEqualTo(HttpStatusCodes.STATUS_CODE_BAD_REQUEST);
assertThat(((FakeResponse) consoleApiParams.response()).getPayload())
.isEqualTo("Missing parameter: registrarId");
}
@Test
void testFailure_passwordsDontMatch() {
ConsoleEppPasswordAction action = createAction();
setParams(
ImmutableMap.of(
"registrarId",
"registrarId",
"oldPassword",
"oldPassword",
"newPassword",
"newPassword",
"newPasswordRepeat",
"newPasswordRepeat"));
action.run();
assertThat(((FakeResponse) consoleApiParams.response()).getStatus())
.isEqualTo(HttpStatusCodes.STATUS_CODE_BAD_REQUEST);
assertThat(((FakeResponse) consoleApiParams.response()).getPayload())
.contains("New password fields don't match");
}
@Test
void testFailure_existingPasswordIncorrect() {
ConsoleEppPasswordAction action = createAction();
setParams(
ImmutableMap.of(
"registrarId",
"registrarId",
"oldPassword",
"oldPassword",
"newPassword",
"randomPasword",
"newPasswordRepeat",
"randomPasword"));
action.run();
assertThat(((FakeResponse) consoleApiParams.response()).getStatus())
.isEqualTo(HttpStatusCodes.STATUS_CODE_FORBIDDEN);
assertThat(((FakeResponse) consoleApiParams.response()).getPayload())
.contains("Registrar password is incorrect");
}
@Test
void testSuccess_sendsConfirmationEmail() throws AddressException {
ConsoleEppPasswordAction action = createAction();
setParams(
ImmutableMap.of(
"registrarId",
"registrarId",
"oldPassword",
"foobar",
"newPassword",
"randomPassword",
"newPasswordRepeat",
"randomPassword"));
action.run();
verify(gmailClient, times(1))
.sendEmail(
EmailMessage.create(
"EPP password update confirmation",
"Dear registrarId name,\n"
+ "This is to confirm that your account password has been changed.",
new InternetAddress("testEmail@google.com")));
assertThat(((FakeResponse) consoleApiParams.response()).getStatus())
.isEqualTo(HttpStatusCodes.STATUS_CODE_OK);
}
@Test
void testSuccess_passwordUpdated() throws AddressException {
ConsoleEppPasswordAction action = createAction();
setParams(
ImmutableMap.of(
"registrarId",
"registrarId",
"oldPassword",
"foobar",
"newPassword",
"randomPassword",
"newPasswordRepeat",
"randomPassword"));
action.run();
assertThat(((FakeResponse) consoleApiParams.response()).getStatus())
.isEqualTo(HttpStatusCodes.STATUS_CODE_OK);
assertDoesNotThrow(
() -> {
credentials.validate(loadRegistrar("registrarId"), "randomPassword");
});
}
private void setParams(ImmutableMap<String, String> params) {
params.entrySet().stream()
.forEach(
entry -> {
when(consoleApiParams.request().getParameter(entry.getKey()))
.thenReturn(entry.getValue());
});
}
private ConsoleEppPasswordAction createAction() {
response = new FakeResponse();
User user =
new User.Builder()
.setEmailAddress("email@email.com")
.setUserRoles(new UserRoles.Builder().setGlobalRole(GlobalRole.FTE).build())
.build();
AuthResult authResult = AuthResult.createUser(UserAuthInfo.create(user));
consoleApiParams = FakeConsoleApiParams.get(Optional.of(authResult));
AuthenticatedRegistrarAccessor authenticatedRegistrarAccessor =
AuthenticatedRegistrarAccessor.createForTesting(
ImmutableSetMultimap.of("registrarId", OWNER));
Cookie cookie =
new Cookie(
consoleApiParams.xsrfTokenManager().X_CSRF_TOKEN,
consoleApiParams.xsrfTokenManager().generateToken(""));
when(consoleApiParams.request().getMethod()).thenReturn(Action.Method.POST.toString());
when(consoleApiParams.request().getCookies()).thenReturn(new Cookie[] {cookie});
return new ConsoleEppPasswordAction(
consoleApiParams, authenticatedRegistrarAccessor, gmailClient);
}
}

View File

@@ -2,6 +2,7 @@ PATH CLASS METHODS OK AUT
/_dr/epp EppTlsAction POST n API APP ADMIN
/console-api/domain ConsoleDomainGetAction GET n API,LEGACY USER PUBLIC
/console-api/domain-list ConsoleDomainListAction GET n API,LEGACY USER PUBLIC
/console-api/eppPassword ConsoleEppPasswordAction POST n API,LEGACY USER PUBLIC
/console-api/registrars RegistrarsAction GET,POST n API,LEGACY USER PUBLIC
/console-api/settings/contacts ContactAction GET,POST n API,LEGACY USER PUBLIC
/console-api/settings/security SecurityAction POST n API,LEGACY USER PUBLIC
@@ -14,4 +15,4 @@ PATH CLASS METHODS OK AUT
/registrar-settings RegistrarSettingsAction POST n API,LEGACY USER PUBLIC
/registry-lock-get RegistryLockGetAction GET n API,LEGACY USER PUBLIC
/registry-lock-post RegistryLockPostAction POST n API,LEGACY USER PUBLIC
/registry-lock-verify RegistryLockVerifyAction GET n API,LEGACY NONE PUBLIC
/registry-lock-verify RegistryLockVerifyAction GET n API,LEGACY NONE PUBLIC

View File

@@ -57,6 +57,7 @@ PATH CLASS
/check CheckApiAction GET n API NONE PUBLIC
/console-api/domain ConsoleDomainGetAction GET n API,LEGACY USER PUBLIC
/console-api/domain-list ConsoleDomainListAction GET n API,LEGACY USER PUBLIC
/console-api/eppPassword ConsoleEppPasswordAction POST n API,LEGACY USER PUBLIC
/console-api/registrars RegistrarsAction GET,POST n API,LEGACY USER PUBLIC
/console-api/settings/contacts ContactAction GET,POST n API,LEGACY USER PUBLIC
/console-api/settings/security SecurityAction POST n API,LEGACY USER PUBLIC
@@ -79,4 +80,4 @@ PATH CLASS
/registry-lock-get RegistryLockGetAction GET n API,LEGACY USER PUBLIC
/registry-lock-post RegistryLockPostAction POST n API,LEGACY USER PUBLIC
/registry-lock-verify RegistryLockVerifyAction GET n API,LEGACY NONE PUBLIC
/whois/(*) WhoisHttpAction GET n API NONE PUBLIC
/whois/(*) WhoisHttpAction GET n API NONE PUBLIC