Skip to content

Commit

Permalink
improving mock SSH servers handling
Browse files Browse the repository at this point in the history
  • Loading branch information
prondzyn committed Sep 28, 2015
1 parent b517ce6 commit 4697106
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 59 deletions.
Expand Up @@ -29,10 +29,12 @@
*/
package com.jcabi.ssh;

import com.google.common.base.Optional;
import com.google.common.io.Files;
import java.io.File;
import java.security.PublicKey;
import java.util.Collections;
import java.util.ArrayList;
import java.util.List;
import org.apache.sshd.SshServer;
import org.apache.sshd.common.NamedFactory;
import org.apache.sshd.server.PasswordAuthenticator;
Expand All @@ -45,93 +47,104 @@
import org.mockito.Mockito;

/**
* Factory creating mock SSH servers.
* Builder creating mock SSH servers.
*
* @author Piotr Pradzynski (prondzyn@gmail.com)
* @version $Id$
* @since 1.6
* @checkstyle AbstractClassNameCheck (500 lines)
*/
final class MockSshServerFactory {
class MockSshServerBuilder {

/**
* Utility class constructor.
* SSH port.
*/
private MockSshServerFactory() {
super();
private final transient int sshport;

/**
* User auth factories.
*/
private final transient List<NamedFactory<UserAuth>> authfactories;

/**
* Optional password authenticator.
*/
private transient Optional<PasswordAuthenticator> passwordauth;

/**
* Optional public key authenticator.
*/
private transient Optional<PublickeyAuthenticator> publickeyauth;

/**
* Constructor with a SSH port number.
* @param port The port number for SSH server
*/
MockSshServerBuilder(final int port) {
this.sshport = port;
this.authfactories = new ArrayList<NamedFactory<UserAuth>>(2);
this.passwordauth = Optional.absent();
this.publickeyauth = Optional.absent();
}

/**
* Builds a new instance of SSH server.
* @return SSH server.
*/
public SshServer build() {
final SshServer sshd = SshServer.setUpDefaultServer();
sshd.setPort(this.sshport);
sshd.setKeyPairProvider(
new SimpleGeneratorHostKeyProvider(
new File(Files.createTempDir(), "hostkey.ser").getAbsolutePath()
)
);
sshd.setUserAuthFactories(this.authfactories);
sshd.setPasswordAuthenticator(this.passwordauth.orNull());
sshd.setPublickeyAuthenticator(this.publickeyauth.orNull());
return sshd;
}

/**
* Setup SSH server based on password authentication.
* Setup a password authentication.
*
* @param port Port to listen on.
* @param login Login for an authentication.
* @param password Password for an authentication.
* @return SSH server.
* @return This instance of builder.
*/
public static SshServer passwordAuthenticatedServer(final int port,
public MockSshServerBuilder usePasswordAuthentication(
final String login, final String password) {
final SshServer sshd = defaultServer(
port,
new UserAuthPassword.Factory()
);
final PasswordAuthenticator auth =
this.authfactories.add(new UserAuthPassword.Factory());
final PasswordAuthenticator authenticator =
Mockito.mock(PasswordAuthenticator.class);
Mockito.when(
auth.authenticate(
authenticator.authenticate(
Mockito.eq(login),
Mockito.eq(password),
Mockito.any(ServerSession.class)
)
).thenReturn(true);
sshd.setPasswordAuthenticator(auth);
return sshd;
this.passwordauth = Optional.of(authenticator);
return this;
}

/**
* Setup SSH server based on public key authentication.
* Setup a public key authentication.
*
* @param port Port to listen on.
* @return SSH server.
* @return This instance of builder.
*/
public static SshServer publicKeyAuthenticatedServer(final int port) {
final SshServer sshd = defaultServer(
port,
new UserAuthPublicKey.Factory()
);
final PublickeyAuthenticator auth =
public MockSshServerBuilder usePublicKeyAuthentication() {
this.authfactories.add(new UserAuthPublicKey.Factory());
final PublickeyAuthenticator authenticator =
Mockito.mock(PublickeyAuthenticator.class);
Mockito.when(
auth.authenticate(
authenticator.authenticate(
Mockito.anyString(),
Mockito.any(PublicKey.class),
Mockito.any(ServerSession.class)
)
).thenReturn(true);
sshd.setPublickeyAuthenticator(auth);
return sshd;
}

/**
* Setup default SSH server.
*
* @param port Port to listen on.
* @param authfactory Authentication factory to use.
* @return SSH server.
*/
private static SshServer defaultServer(final int port,
final NamedFactory<UserAuth> authfactory) {
final SshServer sshd = SshServer.setUpDefaultServer();
sshd.setPort(port);
sshd.setKeyPairProvider(
new SimpleGeneratorHostKeyProvider(
new File(Files.createTempDir(), "hostkey.ser").getAbsolutePath()
)
);
sshd.setUserAuthFactories(
Collections.singletonList(authfactory)
);
return sshd;
this.publickeyauth = Optional.of(authenticator);
return this;
}

}
6 changes: 2 additions & 4 deletions src/test/java/com/jcabi/ssh/SSHByPasswordTest.java
Expand Up @@ -74,10 +74,8 @@ public final class SSHByPasswordTest {
@Test
public void executesCommand() throws Exception {
final int port = SSHByPasswordTest.port();
final SshServer sshd =
MockSshServerFactory.passwordAuthenticatedServer(
port, LOGIN, PASSWORD
);
final SshServer sshd = new MockSshServerBuilder(port)
.usePasswordAuthentication(LOGIN, PASSWORD).build();
sshd.setCommandFactory(new SSHByPasswordTest.EchoCommandCreator());
sshd.start();
final String cmd = "some test command";
Expand Down
4 changes: 2 additions & 2 deletions src/test/java/com/jcabi/ssh/SSHTest.java
Expand Up @@ -79,8 +79,8 @@ public void escapesArgument() throws Exception {
@Test
public void executeCommandOnServer() throws Exception {
final int port = SSHTest.port();
final SshServer sshd =
MockSshServerFactory.publicKeyAuthenticatedServer(port);
final SshServer sshd = new MockSshServerBuilder(port)
.usePublicKeyAuthentication().build();
sshd.setCommandFactory(new SSHTest.EchoCommandCreator());
sshd.start();
final String cmd = "some test command";
Expand Down

0 comments on commit 4697106

Please sign in to comment.