Added identity file auth to SFTPClient

This commit is contained in:
Josh Stark 2017-04-30 09:09:44 +01:00
parent 202b8e3f19
commit 0876a2dbbd
5 changed files with 109 additions and 9 deletions

View File

@ -4,20 +4,21 @@ import org.apache.commons.lang3.StringUtils;
import io.linuxserver.davos.persistence.model.ActionModel;
import io.linuxserver.davos.persistence.model.FilterModel;
import io.linuxserver.davos.persistence.model.HostModel;
import io.linuxserver.davos.persistence.model.ScheduleModel;
import io.linuxserver.davos.schedule.workflow.actions.HttpAPICallAction;
import io.linuxserver.davos.schedule.workflow.actions.MoveFileAction;
import io.linuxserver.davos.schedule.workflow.actions.PushbulletNotifyAction;
import io.linuxserver.davos.transfer.ftp.client.UserCredentials;
import io.linuxserver.davos.transfer.ftp.client.UserCredentials.Identity;
public class ScheduleConfigurationFactory {
public static ScheduleConfiguration createConfig(ScheduleModel model) {
ScheduleConfiguration config = new ScheduleConfiguration(model.name, model.host.protocol, model.host.address,
model.host.port, new UserCredentials(model.host.username, model.host.password), model.remoteFilePath,
model.localFilePath, model.transferType, model.getFiltersMandatory(), model.getInvertFilters(),
model.getDeleteHostFile());
model.host.port, buildCredentials(model.host), model.remoteFilePath, model.localFilePath, model.transferType,
model.getFiltersMandatory(), model.getInvertFilters(), model.getDeleteHostFile());
if (StringUtils.isNotBlank(model.moveFileTo))
config.getActions().add(new MoveFileAction(config.getLocalFilePath(), model.moveFileTo));
@ -31,6 +32,14 @@ public class ScheduleConfigurationFactory {
return config;
}
private static UserCredentials buildCredentials(HostModel host) {
if (host.isIdentityFileEnabled())
return new UserCredentials(host.username, new Identity(host.identityFile));
return new UserCredentials(host.username, host.password);
}
private static void addActions(ScheduleModel model, ScheduleConfiguration config) {
for (ActionModel action : model.actions) {

View File

@ -16,7 +16,7 @@ import io.linuxserver.davos.transfer.ftp.exception.ClientDisconnectException;
public class SFTPClient extends Client {
private static final Logger LOGGER = LoggerFactory.getLogger(SFTPClient.class);
private JSch jsch;
private ConnectionFactory connectionFactory;
@ -62,23 +62,33 @@ public class SFTPClient extends Client {
private void configureSessionAndConnect() throws JSchException {
LOGGER.debug("Configuring connection credentials and options on session");
if (null != userCredentials.getIdentity()) {
String identityFile = userCredentials.getIdentity().getIdentityFile();
LOGGER.debug("SSH identity found ({}). Setting against session", identityFile);
jsch.addIdentity(identityFile);
}
session = jsch.getSession(userCredentials.getUsername(), host, port);
session.setConfig("StrictHostKeyChecking", "no");
session.setPassword(userCredentials.getPassword());
// I'm going to have to think of a nicer way of doing this...
if (null == userCredentials.getIdentity())
session.setPassword(userCredentials.getPassword());
session.connect();
LOGGER.debug("Connected to session");
}
private void openChannelFromSession() throws JSchException {
LOGGER.debug("Opening SFTP channel from session");
channel = session.openChannel("sftp");
channel.connect();
LOGGER.debug("Connected to channel");
}
}

View File

@ -6,6 +6,7 @@ public class UserCredentials {
private String username;
private String password;
private Identity identity;
public UserCredentials(final String username, final String password) {
@ -13,6 +14,16 @@ public class UserCredentials {
this.password = password;
}
public UserCredentials(final String username, final Identity identity) {
this.username = username;
this.identity = identity;
}
public Identity getIdentity() {
return identity;
}
public String getUsername() {
return username;
}
@ -20,4 +31,17 @@ public class UserCredentials {
public String getPassword() {
return password;
}
public static class Identity {
private final String identityFile;
public Identity(String identityFile) {
this.identityFile = identityFile;
}
public String getIdentityFile() {
return identityFile;
}
}
}

View File

@ -43,6 +43,42 @@ public class ScheduleConfigurationFactoryTest {
assertThat(config.getLocalFilePath()).isEqualTo(model.localFilePath);
assertThat(config.getScheduleName()).isEqualTo(model.name);
assertThat(config.getCredentials().getPassword()).isEqualTo(model.host.password);
assertThat(config.getCredentials().getIdentity()).isNull();
assertThat(config.getPort()).isEqualTo(model.host.port);
assertThat(config.getRemoteFilePath()).isEqualTo(model.remoteFilePath);
assertThat(config.getTransferType()).isEqualTo(model.transferType);
assertThat(config.getCredentials().getUsername()).isEqualTo(model.host.username);
assertThat(config.isFiltersMandatory()).isTrue();
}
@Test
public void shouldUseCorrectCredentialsIfIdentityPresent() {
ScheduleModel model = new ScheduleModel();
model.host = new HostModel();
model.host.protocol = TransferProtocol.FTP;
model.host.address = "hostname";
model.host.password = "password";
model.host.port = 8;
model.host.username = "username";
model.host.setIdentityFileEnabled(true);
model.host.identityFile = "blah";
model.setFiltersMandatory(true);
model.localFilePath = "local/";
model.name = "schedulename";
model.remoteFilePath = "thing/";
model.setStartAutomatically(true);
model.transferType = FileTransferType.FILE;
ScheduleConfiguration config = ScheduleConfigurationFactory.createConfig(model);
assertThat(config.getConnectionType()).isEqualTo(model.host.protocol);
assertThat(config.getHostName()).isEqualTo(model.host.address);
assertThat(config.getLocalFilePath()).isEqualTo(model.localFilePath);
assertThat(config.getScheduleName()).isEqualTo(model.name);
assertThat(config.getCredentials().getPassword()).isNull();
assertThat(config.getCredentials().getIdentity().getIdentityFile()).isEqualTo("blah");
assertThat(config.getPort()).isEqualTo(model.host.port);
assertThat(config.getRemoteFilePath()).isEqualTo(model.remoteFilePath);
assertThat(config.getTransferType()).isEqualTo(model.transferType);

View File

@ -5,6 +5,7 @@ import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.is;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.mockito.MockitoAnnotations.initMocks;
@ -25,6 +26,7 @@ import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import io.linuxserver.davos.transfer.ftp.client.UserCredentials.Identity;
import io.linuxserver.davos.transfer.ftp.connection.Connection;
import io.linuxserver.davos.transfer.ftp.connection.ConnectionFactory;
import io.linuxserver.davos.transfer.ftp.connection.SFTPConnection;
@ -71,6 +73,25 @@ public class SFTPClientTest {
verify(mockJsch).getSession("user", "host", 999);
}
@Test
public void sessionFromInitialConnectionNeedsConfigAndIdentitySettingBeforeConnecting() throws JSchException {
Session mockSession = mockJsch.getSession("user", "host", 999);
InOrder inOrder = Mockito.inOrder(mockJsch, mockSession);
userCredentials = new UserCredentials("user", new Identity(".ssh/id_rsa"));
SFTPClient.setCredentials(userCredentials);
SFTPClient.connect();
inOrder.verify(mockJsch).addIdentity(".ssh/id_rsa");
inOrder.verify(mockSession).setConfig("StrictHostKeyChecking", "no");
inOrder.verify(mockSession, never()).setPassword("password");
inOrder.verify(mockSession).connect();
}
@Test
public void sessionFromInitialConnectionNeedsConfigAndPasswordSettingBeforeConnecting() throws JSchException {
@ -84,7 +105,7 @@ public class SFTPClientTest {
inOrder.verify(mockSession).setPassword("password");
inOrder.verify(mockSession).connect();
}
@Test
public void returnedSessionObjectShouldSetChannelToSftpAndOpen() throws JSchException {