Skip to content

Commit

Permalink
MARP-434 Authentication SSH & Multi connection (#39)
Browse files Browse the repository at this point in the history
* MARP-434 auth by ssh keypair & adapt multi sftp connection
  • Loading branch information
anh-bolt authored Aug 26, 2024
1 parent 70ac080 commit 6010f57
Show file tree
Hide file tree
Showing 22 changed files with 598 additions and 193 deletions.
27 changes: 24 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,32 +33,53 @@ jobs:
- name: Install and start SFTP
run: |
sudo apt install openssh-server
sudo sh -c 'echo "ChallengeResponseAuthentication no" >> /etc/ssh/sshd_config'
sudo sh -c 'echo "PasswordAuthentication no" >> /etc/ssh/sshd_config'
sudo sh -c 'echo "\nMatch User usr" >> /etc/ssh/sshd_config'
sudo sh -c 'echo "\tPasswordAuthentication yes" >> /etc/ssh/sshd_config'
sudo sh -c 'echo "\nMatch User All" >> /etc/ssh/sshd_config'
sudo sh -c 'echo "\tPasswordAuthentication no" >> /etc/ssh/sshd_config'
sudo systemctl enable ssh
sudo systemctl start ssh
- name: Create a test user account
run: |
sshGroupRaw=$(getent group | grep ssh)
sshGroup=${sshGroupRaw%:x*}
echo "adding user to group ${sshGroup}"
sudo useradd -s /bin/bash -d /home/usr -m -g ${sshGroup} -p $(echo pwd | openssl passwd -1 -stdin) usr
echo "adding user2ssh to group ${sshGroup}"
sudo useradd -s /bin/bash -d /home/usr2ssh -m -g ${sshGroup} -p $(echo pwd | openssl passwd -1 -stdin) usr2ssh
ssh-keygen -t rsa -b 4096 -N "123456" -f ~/.ssh/sftptest
chmod -R 700 ~/.ssh/sftptest
chmod 600 ~/.ssh/sftptest.pub
sudo -u usr2ssh mkdir /home/usr2ssh/.ssh/
sudo cat ~/.ssh/sftptest.pub >> /home/usr2ssh/.ssh/authorized_keys
sudo chown -R usr2ssh:${sshGroup} /home/usr2ssh/.ssh
sudo chmod go-w /home/usr2ssh
sudo chmod -R 700 /home/usr2ssh/.ssh
sudo chmod 600 /home/usr2ssh/.ssh/authorized_keys
cp ~/.ssh/sftptest ${GITHUB_WORKSPACE}/sftp-connector-test/src_test/com/axonivy/connector/sftp/test/sftptest
- name: Setup Maven
uses: stCarolas/setup-maven@v5
with:
maven-version: ${{ inputs.mvnVersion || '3.6.3' }}

- name: Build with Maven
run: mvn clean verify --batch-mode --fail-at-end ${{ inputs.mvnArgs }}

- name: Publish Unit Test Results
uses: EnricoMi/publish-unit-test-result-action@v2
if: always()
with:
junit_files: |
*/target/*-reports/*.xml
!*/target/*-reports/failsafe-summary.xml
- name: Archive build artifact
uses: actions/upload-artifact@v4
with:
Expand Down
25 changes: 24 additions & 1 deletion sftp-connector-demo/config/variables.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,27 @@
# please add a 'variables.yaml' in the sub directory '_<environment>'.
#
Variables:
#myVariable: value
com.axonivy.connector.sftp.server:
dummy:
# The host name to the SFTP server
host: 'localhost'

# The port number to the SFTP server
port: 22

# The username to the SFTP server
username: 'usr'

# Auth type to the SFPT server
# [enum: password, ssh]
auth: 'ssh'

# The password to the SFTP server
# [password]
password: ''

# The path of ssh key file to SFTP server
sshkeyFilePath: 'C:\NonInstall\RebexTinySftpServer-Binaries-Latest\sshkeyBK\rsa4096new'

# The ssh key passphrase
sshPassphraseSecret: '123456'
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.axonivy.connector.sftp.demo;

public class Constants {
public static final String TEST_SFTP_SERVER_NAME = "dummy";

}
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
<p:outputLabel for="fileUpload" value="File to Upload"/>
<p:fileUpload id="fileUpload" mode="advanced" skinSimple="true"
auto="true" update="@form" process="@form"
fileUploadListener="#{logic.handleFileUpload}" />
listener="#{logic.handleFileUpload}" />
</h:panelGrid>
</h:form>
</p:tab>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
SftpClientDemoData #class
com.axonivy.connector.sftp.demo.SftpClientDemo #namespace
sftpServerName String #field
sftpServerName PERSISTENT #fieldModifier
clientHost String #field
clientHost PERSISTENT #fieldModifier
clientPort Number #field
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,13 @@
"config" : {
"output" : {
"code" : [
"String prefix = \"com_axonivy_connector_sftp_server_\";",
"in.clientHost = ivy.var.variable(prefix+\"host\").value();",
"in.clientPort = Integer.parseInt(ivy.var.variable(prefix+\"port\").value());",
"in.clientUsername = ivy.var.variable(prefix+\"username\").value();"
"import com.axonivy.connector.sftp.service.SftpClientService;",
"import com.axonivy.connector.sftp.demo.Constants;",
"",
"in.sftpServerName = Constants.TEST_SFTP_SERVER_NAME;",
"in.clientHost = SftpClientService.getClientHost(in.sftpServerName);",
"in.clientPort = Integer.parseInt(SftpClientService.getPort(in.sftpServerName));",
"in.clientUsername = SftpClientService.getUsername(in.sftpServerName);"
]
}
},
Expand Down Expand Up @@ -77,7 +80,7 @@
"type" : "SubProcessCall",
"name" : "Sftp/SftpUploadFile",
"config" : {
"processCall" : "Sftp/SftpUploadFile:uploadFile(java.io.InputStream,String)",
"processCall" : "Sftp/SftpUploadFile:uploadFile(String,java.io.InputStream,String)",
"output" : {
"map" : {
"out" : "in",
Expand All @@ -86,10 +89,12 @@
},
"call" : {
"params" : [
{ "name" : "sftpName", "type" : "String" },
{ "name" : "fileToBeUploaded", "type" : "java.io.InputStream" },
{ "name" : "fileName", "type" : "String" }
],
"map" : {
"param.sftpName" : "in.sftpServerName",
"param.fileToBeUploaded" : "in.uploadedFile.getInputStream()",
"param.fileName" : "in.uploadedFile.getFileName()"
}
Expand All @@ -111,7 +116,7 @@
"type" : "SubProcessCall",
"name" : "Sftp/SftpDownloadFile",
"config" : {
"processCall" : "Sftp/SftpDownloadFile:downloadFile(String)",
"processCall" : "Sftp/SftpDownloadFile:downloadFile(String,String)",
"output" : {
"map" : {
"out" : "in",
Expand All @@ -120,9 +125,11 @@
},
"call" : {
"params" : [
{ "name" : "sftpName", "type" : "String" },
{ "name" : "remoteFileName", "type" : "String" }
],
"map" : {
"param.sftpName" : "in.sftpServerName",
"param.remoteFileName" : "in.fileToDownload.name"
}
}
Expand Down Expand Up @@ -191,7 +198,7 @@
"type" : "SubProcessCall",
"name" : "call list All Files",
"config" : {
"processCall" : "Sftp/SftpDownloadFile:listAllFiles(String)",
"processCall" : "Sftp/SftpDownloadFile:listAllFiles(String,String)",
"output" : {
"map" : {
"out" : "in",
Expand All @@ -200,9 +207,11 @@
},
"call" : {
"params" : [
{ "name" : "sftpName", "type" : "String" },
{ "name" : "remoteDirectory", "type" : "String" }
],
"map" : {
"param.sftpName" : "in.sftpServerName",
"param.remoteDirectory" : "\".\""
}
}
Expand Down
58 changes: 47 additions & 11 deletions sftp-connector-product/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,28 +53,64 @@ Before starting the demo, please make sure to have an SSH/SFTP server on your co
1. Open the following settings in “RebexTinySftpServer.exe.config” with a text editor and update the following values:
![RebexTinySftpServer.exe.config](images/RebexTinySftpServer.exe.config.png)

2. Open the `configuration/variables.yaml` in your Designer and update the following global variables:
\* In order to test the connector with SSH key pair, put the public key file to folder `c:/sshkey`.

2. Configure one or more SFTP connectors in global variables. A SFTP connector is identified by a name and a global variable section containing access information. The following example shows connection information for a SFTP connector that should be accessible under the name local-rebex.
Put this variable block into your project. At least `host`, `auth`, `username` and `password` must be defined.
```
Variables:
com.axonivy.connector.sftp.server:
# The host name to the SFTP server
host: 'localhost'
local-rebex:
# The host name to the SFTP server
host: 'localhost'
# Auth type to the SFPT server: password OR ssh
auth: 'password'
# The password to the SFTP server
password: pwd
# The port number to the SFTP server
port: 22
# The username to the SFTP server
username: 'usr'
# The password to the SFTP server
password: pwd
# The port number to the SFTP server
port: 22
```

# The username to the SFTP server
username: 'usr'
Or in order to enable the connector with SSH keypair, `secret.sshkey` and `secret.sshpassphrase` must be defined:
```
Variables:
com.axonivy.connector.sftp.server:
local-rebex:
# The host name to the SFTP server
host: 'localhost'
# Auth type to the SFPT server: password OR ssh
auth: 'ssh'
# The password to the SFTP server
password: ''
# The port number to the SFTP server
port: 22
# The username to the SFTP server
username: 'usr'
# The path of ssh key file to SFTP server
sshkeyFilePath: 'path/to/file'
# The ssh key passphrase
sshPassphraseSecret: 'Your ssh key passphrase'
```
\* the private key is in pair of the public key put in step 1

4. Save the changed settings.
3. Save the changed settings.


### Prerequisites:
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package com.axonivy.connector.sftp.test;

import ch.ivyteam.ivy.bpm.engine.client.element.BpmProcess;
import ch.ivyteam.ivy.environment.Ivy;
import ch.ivyteam.ivy.environment.IvyTest;

@IvyTest
public class BaseTest {
protected static final String TEST_SFTP_SERVER_NAME = "dummy";
protected static final String TEST_SFTP_SSH_SERVER_NAME = "dummy_ssh";

protected static final BpmProcess TEST_HELPER_PROCESS = BpmProcess.path("Sftp/SftpHelper");
protected static final BpmProcess TEST_UPLOAD_FILE_PROCESS = BpmProcess.path("Sftp/SftpUploadFile");
protected static final BpmProcess TEST_DOWNLOAD_FILE_PROCESS = BpmProcess.path("Sftp/SftpDownloadFile");

protected static final String PREFIX = "com.axonivy.connector.sftp.server";
protected static final String TEST_FILE_NAME = "market_market_connector_sftp.pdf";
protected static final long TEST_FILE_SIZE = 207569L;

protected static void setVarForSFTPName(String sftpServerName, String username, String auth, String password, String sshKeyFilePath, String sshpassphrase) {
setVar(sftpServerName, "host", "localhost");
setVar(sftpServerName, "username", username);
setVar(sftpServerName, "port", "22");
setVar(sftpServerName, "auth", auth);
setVar(sftpServerName, "password", password);
setVar(sftpServerName, "sshkeyFilePath", sshKeyFilePath);
setVar(sftpServerName, "sshPassphraseSecret", sshpassphrase);
}

private static void setVar(String sftpServerName, String var, String value) {
Ivy.var().set(String.format("%s.%s.%s", PREFIX, sftpServerName, var), value);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package com.axonivy.connector.sftp.test;

import static org.assertj.core.api.Assertions.assertThat;

import java.io.IOException;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import com.axonivy.connector.sftp.service.SftpClientService;

import ch.ivyteam.ivy.bpm.engine.client.BpmClient;
import ch.ivyteam.ivy.bpm.exec.client.IvyProcessTest;


/**
* This SftpMultiConnectionTest creates 2 sFTP connections
*/
@IvyProcessTest(enableWebServer = true)
public class SftpMultiConnectionTest extends BaseTest {

private static final String SFTP_NAME = "dummy";
private static final String SFTP_SSH_NAME = "dummy_ssh";

@BeforeEach
public void preInit() throws Exception {
setVarForSFTPName(TEST_SFTP_SERVER_NAME, "usr", "password", "pwd", "", "");
String keyPath = SftpProcessSSHTest.class.getResource("sftptest").getPath();
setVarForSFTPName(TEST_SFTP_SSH_SERVER_NAME, "usr2ssh", "ssh", "", keyPath, "123456");
}

@Test
public void callOpenConnection(BpmClient bpmClient) throws IOException {
SftpClientService sftpClient = new SftpClientService(SFTP_NAME);
SftpClientService sftpSSHClient = new SftpClientService(SFTP_SSH_NAME);

assertThat(sftpClient).isNotNull();
assertThat(sftpSSHClient).isNotNull();
sftpClient.close();
sftpSSHClient.close();
}
}
Loading

0 comments on commit 6010f57

Please sign in to comment.