Decouple SessionMetadata and TransportCredentials

TransportCredentials are per-request, not per-session, and
there's no reason to carry them within SessionMetadata.

While I'm in here, get rid of "null" credentials.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=125202213
This commit is contained in:
cgoldfeder 2016-06-17 14:24:04 -07:00 committed by Ben McIlwain
parent fe1cd06da8
commit 3ae646d687
26 changed files with 134 additions and 120 deletions

View file

@ -41,7 +41,8 @@ public class EppConsoleAction implements Runnable {
@Override
public void run() {
eppRequestHandler.executeEpp(
new HttpSessionMetadata(new GaeUserCredentials(getUserService().getCurrentUser()), session),
new HttpSessionMetadata(session),
new GaeUserCredentials(getUserService().getCurrentUser()),
inputXmlBytes);
}
}

View file

@ -51,7 +51,10 @@ public final class EppController {
* Read an EPP envelope from the client, find the matching flow, execute it, and return
* the response marshalled to a byte array.
*/
public byte[] handleEppCommand(SessionMetadata sessionMetadata, byte[] inputXmlBytes) {
public byte[] handleEppCommand(
SessionMetadata sessionMetadata,
TransportCredentials credentials,
byte[] inputXmlBytes) {
Trid trid = null;
try {
EppInput eppInput = unmarshal(EppInput.class, inputXmlBytes);
@ -68,6 +71,7 @@ public final class EppController {
eppInput,
trid,
sessionMetadata,
credentials,
inputXmlBytes,
metrics,
clock);

View file

@ -39,10 +39,13 @@ public class EppRequestHandler {
@Inject EppRequestHandler() {}
/** Handle an EPP request and write out a servlet response. */
public void executeEpp(SessionMetadata sessionMetadata, byte[] inputXmlBytes) {
public void executeEpp(
SessionMetadata sessionMetadata,
TransportCredentials credentials,
byte[] inputXmlBytes) {
try {
response.setPayload(new String(
eppController.handleEppCommand(sessionMetadata, inputXmlBytes), UTF_8));
eppController.handleEppCommand(sessionMetadata, credentials, inputXmlBytes), UTF_8));
response.setContentType(APPLICATION_EPP_XML);
// Note that we always return 200 (OK) even if the EppController returns an error response.
// This is because returning an non-OK HTTP status code will cause the proxy server to

View file

@ -46,7 +46,7 @@ public class EppTlsAction implements Runnable {
if (!tlsCredentials.hasSni()) {
logger.warning("Request did not include required SNI header.");
}
eppRequestHandler.executeEpp(new HttpSessionMetadata(tlsCredentials, session), inputXmlBytes);
eppRequestHandler.executeEpp(new HttpSessionMetadata(session), tlsCredentials, inputXmlBytes);
}
}

View file

@ -54,6 +54,7 @@ public class EppToolAction implements Runnable {
dryRun,
ProtocolDefinition.getVisibleServiceExtensionUris(),
SessionSource.TOOL),
new PasswordOnlyTransportCredentials(),
xml.getBytes(UTF_8));
}
@ -61,7 +62,7 @@ public class EppToolAction implements Runnable {
@Module
public static final class EppToolModule {
// TODO(b/29139545): Make parameters consistent across the graph. @Parameter("dryRun") is
// TODO(b/29139545): Make parameters consistent across the graph. @Parameter("dryRun") is
// already provided elsewhere in the graph and happens to work for us but that's just luck.
@Provides

View file

@ -42,6 +42,7 @@ public abstract class Flow {
protected EppInput eppInput;
protected SessionMetadata sessionMetadata;
protected TransportCredentials credentials;
protected Trid trid;
protected DateTime now;
protected byte[] inputXmlBytes;
@ -101,11 +102,13 @@ public abstract class Flow {
EppInput eppInput,
Trid trid,
SessionMetadata sessionMetadata,
TransportCredentials credentials,
DateTime now,
byte[] inputXmlBytes) throws EppException {
this.eppInput = eppInput;
this.trid = trid;
this.sessionMetadata = sessionMetadata;
this.credentials = credentials;
this.now = now;
this.superuser = sessionMetadata.isSuperuser();
this.inputXmlBytes = inputXmlBytes;

View file

@ -36,7 +36,7 @@ import org.joda.time.DateTime;
/** Run a flow, either transactionally or not, with logging and retrying as needed. */
public class FlowRunner {
private static final String COMMAND_LOG_FORMAT = "EPP Command" + Strings.repeat("\n\t%s", 4);
private static final String COMMAND_LOG_FORMAT = "EPP Command" + Strings.repeat("\n\t%s", 5);
private static final FormattingLogger logger = FormattingLogger.getLoggerForCallerClass();
@ -44,6 +44,7 @@ public class FlowRunner {
private final EppInput eppInput;
private final Trid trid;
private final SessionMetadata sessionMetadata;
private final TransportCredentials credentials;
private final byte[] inputXmlBytes;
private final EppMetrics metrics;
private final Clock clock;
@ -53,13 +54,16 @@ public class FlowRunner {
EppInput eppInput,
Trid trid,
SessionMetadata sessionMetadata,
TransportCredentials credentials,
byte[] inputXmlBytes,
final EppMetrics metrics,
Clock clock) {
credentials.toString();
this.flowClass = flowClass;
this.eppInput = eppInput;
this.trid = trid;
this.sessionMetadata = sessionMetadata;
this.credentials = credentials;
this.inputXmlBytes = inputXmlBytes;
this.metrics = metrics;
this.clock = clock;
@ -72,7 +76,8 @@ public class FlowRunner {
trid.getServerTransactionId(),
clientId,
sessionMetadata,
prettyPrint(inputXmlBytes).replaceAll("\n", "\n\t"));
prettyPrint(inputXmlBytes).replaceAll("\n", "\n\t"),
credentials);
if (!isTransactional()) {
if (metrics != null) {
metrics.incrementAttempts();
@ -124,6 +129,7 @@ public class FlowRunner {
eppInput,
trid,
sessionMetadata,
credentials,
now,
inputXmlBytes);
}

View file

@ -38,12 +38,8 @@ public class GaeUserCredentials implements TransportCredentials {
}
@Override
public boolean performsLoginCheck() {
return true;
}
@Override
public void validate(Registrar r) throws AuthenticationErrorException {
public void validate(Registrar registrar, String ignoredPassword)
throws AuthenticationErrorException {
if (gaeUser == null) {
throw new UserNotLoggedInException();
}
@ -53,7 +49,7 @@ public class GaeUserCredentials implements TransportCredentials {
}
// Check Registrar's contacts to see if any are associated with this gaeUserId.
final String gaeUserId = gaeUser.getUserId();
for (RegistrarContact rc : r.getContacts()) {
for (RegistrarContact rc : registrar.getContacts()) {
if (gaeUserId.equals(rc.getGaeUserId())) {
return;
}

View file

@ -24,9 +24,8 @@ public class HttpSessionMetadata extends SessionMetadata {
private final HttpSession session;
private boolean isValid = true;
public HttpSessionMetadata(TransportCredentials credentials, HttpSession session) {
public HttpSessionMetadata(HttpSession session) {
this.session = session;
setTransportCredentials(credentials);
}
@Override

View file

@ -0,0 +1,28 @@
// Copyright 2016 The Domain Registry 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.flows;
import google.registry.flows.EppException.AuthenticationErrorException;
import google.registry.model.registrar.Registrar;
/** A transport credentials that validates the registrar's EPP password and nothing else. */
public class PasswordOnlyTransportCredentials implements TransportCredentials {
@Override
public void validate(Registrar r, String password) throws AuthenticationErrorException {
if (!r.testPassword(password)) {
throw new BadRegistrarPasswordException();
}
}
}

View file

@ -46,9 +46,7 @@ public abstract class SessionMetadata {
NONE
}
private TransportCredentials credentials;
/** The key used for looking up the current client id on the session object. */
/** The key used for looking up the current client id on the session object. */
protected static final String CLIENT_ID_KEY = "CLIENT_ID";
/** The key used for looking up the superuser bit on the session object. */
@ -91,16 +89,6 @@ public abstract class SessionMetadata {
return clazz.cast(getProperty(key));
}
public TransportCredentials getTransportCredentials() {
checkValid();
return credentials;
}
public void setTransportCredentials(TransportCredentials credentials) {
checkValid();
this.credentials = credentials;
}
public String getClientId() {
return getProperty(String.class, CLIENT_ID_KEY);
}
@ -164,7 +152,6 @@ public abstract class SessionMetadata {
.add("failedLoginAttempts", getFailedLoginAttempts())
.add("sessionSource", getSessionSource())
.add("serviceExtensionUris", Joiner.on('.').join(nullToEmpty(getServiceExtensionUris())))
.add("transportCredentials", getTransportCredentials())
.toString();
}
}

View file

@ -68,11 +68,6 @@ public class StatelessRequestSessionMetadata extends SessionMetadata {
throw new UnsupportedOperationException();
}
@Override
public void setTransportCredentials(TransportCredentials credentials) {
throw new UnsupportedOperationException();
}
@Override
protected void setProperty(String key, Object value) {
throw new UnsupportedOperationException();

View file

@ -86,20 +86,16 @@ public class TlsCredentials implements TransportCredentials {
}
}
@Override
public boolean performsLoginCheck() {
return false;
}
/** Returns {@code true} if frontend passed us the requested server name. */
boolean hasSni() {
return !isNullOrEmpty(sni);
}
@Override
public void validate(Registrar registrar) throws AuthenticationErrorException {
public void validate(Registrar registrar, String password) throws AuthenticationErrorException {
validateIp(registrar);
validateCertificate(registrar);
validatePassword(registrar, password);
}
/**
@ -160,6 +156,13 @@ public class TlsCredentials implements TransportCredentials {
}
}
private void validatePassword(Registrar registrar, String password)
throws BadRegistrarPasswordException {
if (!registrar.testPassword(password)) {
throw new BadRegistrarPasswordException();
}
}
@Override
public String toString() {
return toStringHelper(getClass())

View file

@ -17,23 +17,21 @@ package google.registry.flows;
import google.registry.flows.EppException.AuthenticationErrorException;
import google.registry.model.registrar.Registrar;
/**
* A marker interface for objects containing registrar credentials provided via an EPP transport.
*/
/** Interface for objects containing registrar credentials provided via an EPP transport. */
public interface TransportCredentials {
/**
* Indicates whether the transport takes the place of EPP login checks, in which case LoginFlow
* will not check the password. Alternatively, if the password should be checked, it MUST match
* the user's and GAE's isUserAdmin should not be used to bypass this check as internal
* connections over RPC will have this property for all registrars.
* Check that these credentials are valid for the registrar and optionally check the password.
*
* Called by {@link google.registry.flows.session.LoginFlow LoginFlow} to check the transport
* credentials against the stored registrar's credentials. If they do not match, throw an
* {@link AuthenticationErrorException}.
*/
boolean performsLoginCheck();
void validate(Registrar registrar, String password) throws AuthenticationErrorException;
/**
* Called by {@link google.registry.flows.session.LoginFlow LoginFlow}
* to check the transport credentials against the stored registrar's credentials.
* If they do not match, throw an AuthenticationErrorException.
*/
void validate(Registrar r) throws AuthenticationErrorException;
/** Registrar password is incorrect. */
static class BadRegistrarPasswordException extends AuthenticationErrorException {
public BadRegistrarPasswordException() {
super("Registrar password is incorrect");
}
}
}

View file

@ -29,7 +29,6 @@ import google.registry.flows.EppException.UnimplementedExtensionException;
import google.registry.flows.EppException.UnimplementedObjectServiceException;
import google.registry.flows.EppException.UnimplementedOptionException;
import google.registry.flows.Flow;
import google.registry.flows.TransportCredentials;
import google.registry.model.eppcommon.ProtocolDefinition;
import google.registry.model.eppcommon.ProtocolDefinition.ServiceExtension;
import google.registry.model.eppinput.EppInput.Login;
@ -55,9 +54,9 @@ import java.util.Set;
* @error {@link google.registry.flows.TlsCredentials.BadRegistrarIpAddressException}
* @error {@link google.registry.flows.TlsCredentials.MissingRegistrarCertificateException}
* @error {@link google.registry.flows.TlsCredentials.NoSniException}
* @error {@link google.registry.flows.TransportCredentials.BadRegistrarPasswordException}
* @error {@link LoginFlow.AlreadyLoggedInException}
* @error {@link LoginFlow.BadRegistrarClientIdException}
* @error {@link LoginFlow.BadRegistrarPasswordException}
* @error {@link LoginFlow.TooManyFailedLoginsException}
* @error {@link LoginFlow.PasswordChangesNotSupportedException}
* @error {@link LoginFlow.RegistrarAccountNotActiveException}
@ -114,24 +113,15 @@ public class LoginFlow extends Flow {
throw new BadRegistrarClientIdException(login.getClientId());
}
TransportCredentials credentials = sessionMetadata.getTransportCredentials();
// AuthenticationErrorExceptions will propagate up through here.
if (credentials != null) { // Allow no-credential logins, for load-testing and RDE.
try {
credentials.validate(registrar);
} catch (AuthenticationErrorException e) {
sessionMetadata.incrementFailedLoginAttempts();
throw e;
}
}
final boolean requiresLoginCheck = credentials == null || !credentials.performsLoginCheck();
if (requiresLoginCheck && !registrar.testPassword(login.getPassword())) {
try {
credentials.validate(registrar, login.getPassword());
} catch (AuthenticationErrorException e) {
sessionMetadata.incrementFailedLoginAttempts();
if (sessionMetadata.getFailedLoginAttempts() > MAX_FAILED_LOGIN_ATTEMPTS_PER_CONNECTION) {
throw new TooManyFailedLoginsException();
} else {
throw new BadRegistrarPasswordException();
throw e;
}
}
if (registrar.getState().equals(Registrar.State.PENDING)) {
@ -157,13 +147,6 @@ public class LoginFlow extends Flow {
}
}
/** Registrar password is incorrect. */
static class BadRegistrarPasswordException extends AuthenticationErrorException {
public BadRegistrarPasswordException() {
super("Registrar password is incorrect");
}
}
/** Registrar login failed too many times. */
static class TooManyFailedLoginsException extends AuthenticationErrorClosingConnectionException {
public TooManyFailedLoginsException() {

View file

@ -104,12 +104,11 @@ final class ValidateLoginCredentialsCommand implements RemoteApiCommand, GtechCo
LoginFlow.class,
unmarshal(EppInput.class, inputXmlBytes),
Trid.create(null),
new HttpSessionMetadata(
new TlsCredentials(
clientCertificateHash,
Optional.of(clientIpAddress),
"placeholder"), // behave as if we have SNI on, since we're validating a cert
new BasicHttpSession()),
new HttpSessionMetadata(new BasicHttpSession()),
new TlsCredentials(
clientCertificateHash,
Optional.of(clientIpAddress),
"placeholder"), // behave as if we have SNI on, since we're validating a cert
inputXmlBytes,
null,
new SystemClock()).run()), UTF_8));

View file

@ -38,6 +38,7 @@ import dagger.Provides;
import google.registry.config.RegistryEnvironment;
import google.registry.flows.EppException;
import google.registry.flows.FlowRunner;
import google.registry.flows.PasswordOnlyTransportCredentials;
import google.registry.flows.SessionMetadata.SessionSource;
import google.registry.flows.StatelessRequestSessionMetadata;
import google.registry.flows.domain.DomainCheckFlow;
@ -119,6 +120,7 @@ public class CheckApiAction implements Runnable {
unmarshal(EppInput.class, inputXmlBytes),
Trid.create(getClass().getSimpleName()),
sessionMetadata,
new PasswordOnlyTransportCredentials(),
inputXmlBytes,
null,
clock)

View file

@ -51,11 +51,14 @@ public class EppConsoleActionTest extends ShardableTestCase {
action.session.setAttribute("SUPERUSER", superuser);
action.eppRequestHandler = mock(EppRequestHandler.class);
action.run();
ArgumentCaptor<SessionMetadata> captor = ArgumentCaptor.forClass(SessionMetadata.class);
verify(action.eppRequestHandler).executeEpp(captor.capture(), eq(INPUT_XML_BYTES));
SessionMetadata sessionMetadata = captor.getValue();
assertThat(((GaeUserCredentials) sessionMetadata.getTransportCredentials()).gaeUser.getEmail())
ArgumentCaptor<TransportCredentials> credentialsCaptor =
ArgumentCaptor.forClass(TransportCredentials.class);
ArgumentCaptor<SessionMetadata> metadataCaptor = ArgumentCaptor.forClass(SessionMetadata.class);
verify(action.eppRequestHandler).executeEpp(
metadataCaptor.capture(), credentialsCaptor.capture(), eq(INPUT_XML_BYTES));
assertThat(((GaeUserCredentials) credentialsCaptor.getValue()).gaeUser.getEmail())
.isEqualTo("person@example.com");
SessionMetadata sessionMetadata = metadataCaptor.getValue();
assertThat(sessionMetadata.getClientId()).isEqualTo("ClientIdentifier");
assertThat(sessionMetadata.isDryRun()).isFalse(); // Should always be false for console.
assertThat(sessionMetadata.isSuperuser()).isEqualTo(superuser);

View file

@ -50,8 +50,8 @@ public class EppTestCase extends ShardableTestCase {
private final FakeClock clock = new FakeClock();
private TestSessionMetadata sessionMetadata;
private TransportCredentials credentials;
private boolean superuser;
private TransportCredentials credentials = new PasswordOnlyTransportCredentials();
private boolean isSuperuser;
@Before
public void initTestCase() {
@ -70,8 +70,8 @@ public class EppTestCase extends ShardableTestCase {
this.credentials = credentials;
}
protected void setSuperuser(boolean superuser) {
this.superuser = superuser;
protected void setSuperuser(boolean isSuperuser) {
this.isSuperuser = isSuperuser;
}
String assertCommandAndResponse(String inputFilename, String outputFilename) throws Exception {
@ -95,9 +95,8 @@ public class EppTestCase extends ShardableTestCase {
loadFileWithSubstitutions(getClass(), outputFilename, outputSubstitutions);
if (sessionMetadata == null) {
sessionMetadata = new TestSessionMetadata();
sessionMetadata.setTransportCredentials(credentials);
}
sessionMetadata.setSuperuser(superuser);
sessionMetadata.setSuperuser(isSuperuser);
String actualOutput = executeXmlCommand(input);
if (!sessionMetadata.isValid()) {
sessionMetadata = null;
@ -119,7 +118,7 @@ public class EppTestCase extends ShardableTestCase {
handler.eppController = new EppController();
handler.eppController.clock = clock;
handler.eppController.metrics = mock(EppMetrics.class);
handler.executeEpp(sessionMetadata, inputXml.getBytes(UTF_8));
handler.executeEpp(sessionMetadata, credentials, inputXml.getBytes(UTF_8));
assertThat(response.getStatus()).isEqualTo(SC_OK);
assertThat(response.getContentType()).isEqualTo(APPLICATION_EPP_XML_UTF8);
String result = response.getPayload();

View file

@ -17,7 +17,8 @@ package google.registry.flows;
import static com.google.common.truth.Truth.assertThat;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.mockito.Mockito.eq;
import static org.mockito.Matchers.eq;
import static org.mockito.Matchers.same;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@ -47,12 +48,12 @@ public class EppTlsActionTest extends ShardableTestCase {
action.eppRequestHandler = mock(EppRequestHandler.class);
action.run();
ArgumentCaptor<SessionMetadata> captor = ArgumentCaptor.forClass(SessionMetadata.class);
verify(action.eppRequestHandler).executeEpp(captor.capture(), eq(INPUT_XML_BYTES));
verify(action.eppRequestHandler)
.executeEpp(captor.capture(), same(action.tlsCredentials), eq(INPUT_XML_BYTES));
SessionMetadata sessionMetadata = captor.getValue();
assertThat(sessionMetadata.getClientId()).isEqualTo("ClientIdentifier");
assertThat(sessionMetadata.isDryRun()).isFalse(); // Should always be false for TLS.
assertThat(sessionMetadata.isSuperuser()).isEqualTo(superuser);
assertThat(sessionMetadata.getTransportCredentials()).isSameAs(action.tlsCredentials);
}
@Test

View file

@ -16,7 +16,8 @@ package google.registry.flows;
import static com.google.common.truth.Truth.assertThat;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.mockito.Mockito.eq;
import static org.mockito.Matchers.eq;
import static org.mockito.Matchers.isA;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
@ -38,7 +39,10 @@ public class EppToolActionTest {
action.xml = "<xml>";
action.run();
ArgumentCaptor<SessionMetadata> captor = ArgumentCaptor.forClass(SessionMetadata.class);
verify(action.eppRequestHandler).executeEpp(captor.capture(), eq(action.xml.getBytes(UTF_8)));
verify(action.eppRequestHandler).executeEpp(
captor.capture(),
isA(PasswordOnlyTransportCredentials.class),
eq(action.xml.getBytes(UTF_8)));
SessionMetadata sessionMetadata = captor.getValue();
assertThat(sessionMetadata.getClientId()).isEqualTo("ClientIdentifier");
assertThat(sessionMetadata.isDryRun()).isEqualTo(dryRun);

View file

@ -93,6 +93,7 @@ public abstract class FlowTestCase<F extends Flow> {
protected Class<? extends Flow> flowClass;
protected TestSessionMetadata sessionMetadata;
protected FakeClock clock = new FakeClock(DateTime.now(UTC));
protected TransportCredentials credentials = new PasswordOnlyTransportCredentials();
@Before
public void init() throws Exception {
@ -141,6 +142,7 @@ public abstract class FlowTestCase<F extends Flow> {
eppInput,
getTrid(),
sessionMetadata,
credentials,
"<xml></xml>".getBytes(),
null,
clock);

View file

@ -22,9 +22,9 @@ import google.registry.flows.EppException.UnimplementedExtensionException;
import google.registry.flows.EppException.UnimplementedObjectServiceException;
import google.registry.flows.EppException.UnimplementedProtocolVersionException;
import google.registry.flows.FlowTestCase;
import google.registry.flows.TransportCredentials.BadRegistrarPasswordException;
import google.registry.flows.session.LoginFlow.AlreadyLoggedInException;
import google.registry.flows.session.LoginFlow.BadRegistrarClientIdException;
import google.registry.flows.session.LoginFlow.BadRegistrarPasswordException;
import google.registry.flows.session.LoginFlow.PasswordChangesNotSupportedException;
import google.registry.flows.session.LoginFlow.RegistrarAccountNotActiveException;
import google.registry.flows.session.LoginFlow.TooManyFailedLoginsException;

View file

@ -15,9 +15,9 @@
package google.registry.flows.session;
import static com.google.appengine.api.users.UserServiceFactory.getUserService;
import static google.registry.testing.DatastoreHelper.persistResource;
import com.google.appengine.api.users.UserServiceFactory;
import com.google.apphosting.api.ApiProxy;
import com.google.apphosting.api.ApiProxy.Environment;
import com.google.common.collect.ImmutableSet;
@ -150,15 +150,13 @@ public class LoginFlowViaConsoleTest extends LoginFlowTestCase {
return envAttr;
}
});
sessionMetadata.setTransportCredentials(new GaeUserCredentials(
UserServiceFactory.getUserService().getCurrentUser()));
credentials = new GaeUserCredentials(getUserService().getCurrentUser());
return oldEnv;
}
void noLogin() {
oldEnv = ApiProxy.getCurrentEnvironment();
sessionMetadata.setTransportCredentials(new GaeUserCredentials(
UserServiceFactory.getUserService().getCurrentUser()));
credentials = new GaeUserCredentials(getUserService().getCurrentUser());
}
void persistLinkedAccount(String email, String gaeUserId) {

View file

@ -52,7 +52,7 @@ public class LoginFlowViaTlsTest extends LoginFlowTestCase {
@Test
public void testSuccess_withGoodCredentials() throws Exception {
persistResource(getRegistrarBuilder().build());
sessionMetadata.setTransportCredentials(new TlsCredentials(GOOD_CERT, GOOD_IP, "goo.example"));
credentials = new TlsCredentials(GOOD_CERT, GOOD_IP, "goo.example");
doSuccessfulTest("login_valid.xml");
}
@ -63,8 +63,7 @@ public class LoginFlowViaTlsTest extends LoginFlowTestCase {
.setIpAddressWhitelist(ImmutableList.of(
CidrAddressBlock.create("2001:db8:0:0:0:0:1:1/32")))
.build());
sessionMetadata.setTransportCredentials(
new TlsCredentials(GOOD_CERT, GOOD_IPV6, "goo.example"));
credentials = new TlsCredentials(GOOD_CERT, GOOD_IPV6, "goo.example");
doSuccessfulTest("login_valid.xml");
}
@ -75,8 +74,7 @@ public class LoginFlowViaTlsTest extends LoginFlowTestCase {
.setIpAddressWhitelist(ImmutableList.of(
CidrAddressBlock.create("2001:db8:0:0:0:0:1:1/32")))
.build());
sessionMetadata.setTransportCredentials(
new TlsCredentials(GOOD_CERT, GOOD_IPV6, "goo.example"));
credentials = new TlsCredentials(GOOD_CERT, GOOD_IPV6, "goo.example");
doSuccessfulTest("login_valid.xml");
}
@ -87,28 +85,28 @@ public class LoginFlowViaTlsTest extends LoginFlowTestCase {
.setIpAddressWhitelist(ImmutableList.of(
CidrAddressBlock.create("192.168.1.255/24")))
.build());
sessionMetadata.setTransportCredentials(new TlsCredentials(GOOD_CERT, GOOD_IP, "goo.example"));
credentials = new TlsCredentials(GOOD_CERT, GOOD_IP, "goo.example");
doSuccessfulTest("login_valid.xml");
}
@Test
public void testFailure_incorrectClientCertificateHash() throws Exception {
persistResource(getRegistrarBuilder().build());
sessionMetadata.setTransportCredentials(new TlsCredentials(BAD_CERT, GOOD_IP, "goo.example"));
credentials = new TlsCredentials(BAD_CERT, GOOD_IP, "goo.example");
doFailingTest("login_valid.xml", BadRegistrarCertificateException.class);
}
@Test
public void testFailure_missingClientCertificateHash() throws Exception {
persistResource(getRegistrarBuilder().build());
sessionMetadata.setTransportCredentials(new TlsCredentials(null, GOOD_IP, "goo.example"));
credentials = new TlsCredentials(null, GOOD_IP, "goo.example");
doFailingTest("login_valid.xml", MissingRegistrarCertificateException.class);
}
@Test
public void testFailure_noSniAndCertRequired() throws Exception {
persistResource(getRegistrarBuilder().build());
sessionMetadata.setTransportCredentials(new TlsCredentials(null, GOOD_IP, null));
credentials = new TlsCredentials(null, GOOD_IP, null);
doFailingTest("login_valid.xml", NoSniException.class);
}
@ -120,8 +118,7 @@ public class LoginFlowViaTlsTest extends LoginFlowTestCase {
CidrAddressBlock.create(InetAddresses.forString("192.168.1.1"), 32),
CidrAddressBlock.create(InetAddresses.forString("2001:db8::1"), 128)))
.build());
sessionMetadata.setTransportCredentials(
new TlsCredentials(GOOD_CERT, Optional.<String>absent(), "goo.example"));
credentials = new TlsCredentials(GOOD_CERT, Optional.<String>absent(), "goo.example");
doFailingTest("login_valid.xml", BadRegistrarIpAddressException.class);
}
@ -133,7 +130,7 @@ public class LoginFlowViaTlsTest extends LoginFlowTestCase {
CidrAddressBlock.create(InetAddresses.forString("192.168.1.1"), 32),
CidrAddressBlock.create(InetAddresses.forString("2001:db8::1"), 128)))
.build());
sessionMetadata.setTransportCredentials(new TlsCredentials(GOOD_CERT, BAD_IP, "goo.example"));
credentials = new TlsCredentials(GOOD_CERT, BAD_IP, "goo.example");
doFailingTest("login_valid.xml", BadRegistrarIpAddressException.class);
}
@ -145,7 +142,7 @@ public class LoginFlowViaTlsTest extends LoginFlowTestCase {
CidrAddressBlock.create(InetAddresses.forString("192.168.1.1"), 32),
CidrAddressBlock.create(InetAddresses.forString("2001:db8::1"), 128)))
.build());
sessionMetadata.setTransportCredentials(new TlsCredentials(GOOD_CERT, BAD_IPV6, "goo.example"));
credentials = new TlsCredentials(GOOD_CERT, BAD_IPV6, "goo.example");
doFailingTest("login_valid.xml", BadRegistrarIpAddressException.class);
}
}

View file

@ -31,6 +31,7 @@ import static org.joda.time.Duration.standardDays;
import com.googlecode.objectify.Key;
import google.registry.flows.FlowRunner;
import google.registry.flows.PasswordOnlyTransportCredentials;
import google.registry.flows.SessionMetadata;
import google.registry.model.domain.DomainResource;
import google.registry.model.eppcommon.Trid;
@ -84,6 +85,7 @@ public class EppResourceUtilsTest {
eppLoader.getEpp(),
Trid.create(null, "server-trid"),
sessionMetadata,
new PasswordOnlyTransportCredentials(),
"<xml></xml>".getBytes(),
null,
clock)