diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 24865a5..0a3dc5a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -33,16 +33,29 @@ 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 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 + + ssh-keygen -t rsa -b 4096 -N "123456" -f ~/.ssh/sftptest + chmod -R 700 ~/.ssh/sftptest + chmod 600 ~/.ssh/sftptest.pub + sudo -u usr mkdir /home/usr/.ssh/ + sudo cat ~/.ssh/sftptest.pub >> /home/usr/.ssh/authorized_keys + sudo chown -R usr:${sshGroup} /home/usr/.ssh + sudo chmod -R 700 /home/usr/.ssh + sudo chmod 664 /home/usr/.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: diff --git a/sftp-connector-product/README.md b/sftp-connector-product/README.md index 4caf2be..2304ede 100644 --- a/sftp-connector-product/README.md +++ b/sftp-connector-product/README.md @@ -53,6 +53,8 @@ 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) + \* In order to test the connector with SSH key pair, put the public key file to folder `c:/sshkey`. + 2. Open the `configuration/variables.yaml` in your Designer and update the following global variables: ``` @@ -62,7 +64,10 @@ Before starting the demo, please make sure to have an SSH/SFTP server on your co com.axonivy.connector.sftp.server: # 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 @@ -74,7 +79,38 @@ Before starting the demo, please make sure to have an SSH/SFTP server on your co ``` -4. Save the changed settings. + Or in order to enable the connector with SSH keypair, update following global variables: + ``` + + Variables: + + com.axonivy.connector.sftp.server: + # 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 ssh key string to SFTP server + # [secret private key] + secret_sshkey: | + YOUR PRIVATE KEY CONTENT HERE + + # The ssh key passphrase + secret_sshpassphrase: 'Your ssh key passphrase' + ``` + \* the private key is in pair of the public key put in step 1 + +3. Save the changed settings. ### Prerequisites: diff --git a/sftp-connector-product/images/RebexTinySftpServer.exe.config.png b/sftp-connector-product/images/RebexTinySftpServer.exe.config.png index 16dddd8..f54c67e 100644 Binary files a/sftp-connector-product/images/RebexTinySftpServer.exe.config.png and b/sftp-connector-product/images/RebexTinySftpServer.exe.config.png differ diff --git a/sftp-connector-test/src_test/com/axonivy/connector/sftp/test/SftpProcessSSHTest.java b/sftp-connector-test/src_test/com/axonivy/connector/sftp/test/SftpProcessSSHTest.java new file mode 100644 index 0000000..698bda2 --- /dev/null +++ b/sftp-connector-test/src_test/com/axonivy/connector/sftp/test/SftpProcessSSHTest.java @@ -0,0 +1,144 @@ +package com.axonivy.connector.sftp.test; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.List; + +import org.apache.commons.io.FileUtils; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Order; +import org.junit.jupiter.api.Test; + +import com.axonivy.connector.sftp.service.SftpClientService; +import com.axonivy.connector.sftp.service.SftpClientService.FileData; + +import ch.ivyteam.ivy.bpm.engine.client.BpmClient; +import ch.ivyteam.ivy.bpm.engine.client.element.BpmElement; +import ch.ivyteam.ivy.bpm.engine.client.element.BpmProcess; +import ch.ivyteam.ivy.bpm.engine.client.sub.SubProcessCallResult; +import ch.ivyteam.ivy.bpm.exec.client.IvyProcessTest; +import ch.ivyteam.ivy.environment.Ivy; +import ch.ivyteam.ivy.scripting.objects.File; + + +/** + * This SftpProcessTest simulates SFTP operations by calling the sub processes: + * SftpUploadFile and SftpDownloadFile. + * + *
The test can either be run
right click > run as > JUnit Test
)mvn clean verify
)Detailed guidance on writing these kind of tests can be found in our + * Process Testing docs + *
+ */ +@IvyProcessTest(enableWebServer = true) +public class SftpProcessSSHTest { + + private static final BpmProcess TEST_HELPER_PROCESS = BpmProcess.path("Sftp/SftpHelper"); + private static final BpmProcess TEST_UPLOAD_FILE_PROCESS = BpmProcess.path("Sftp/SftpUploadFile"); + private static final BpmProcess TEST_DOWNLOAD_FILE_PROCESS = BpmProcess.path("Sftp/SftpDownloadFile"); + + private static final String TEST_FILE_NAME = "market_market_connector_sftp.pdf"; + private static final long TEST_FILE_SIZE = 207569L; + + + @BeforeAll + public static void init() throws Exception { + String prefix = "com_axonivy_connector_sftp_server_"; + Ivy.var().set(prefix+"auth", "ssh"); + Ivy.var().set(prefix+"password", ""); + + String keyString = Files.readString(Paths.get(SftpProcessSSHTest.class.getResource("sftptest").toURI())); + Ivy.var().set(prefix+"secret_sshkey", keyString); + Ivy.var().set(prefix+"secret_sshpassphrase", "123456"); + } + + @Test + @Order(1) + public void callOpenConnection(BpmClient bpmClient) throws Exception { + BpmElement startable = TEST_HELPER_PROCESS.elementName("openConnection()"); + + SubProcessCallResult result = bpmClient.start() + .subProcess(startable) + .execute() // Callable sub process input arguments + .subResult(); + + SftpClientService sftpClient = result.param("sftpClient", SftpClientService.class); + assertThat(sftpClient).isNotNull(); + if (sftpClient != null) { + sftpClient.close(); + } + } + + @Test + @Order(2) + public void callUploadFile(BpmClient bpmClient) { + InputStream fileToBeUploaded = getClass().getResourceAsStream(TEST_FILE_NAME); + + BpmElement startable = TEST_UPLOAD_FILE_PROCESS.elementName("uploadFile(InputStream,String)"); + + SubProcessCallResult result = bpmClient.start() + .subProcess(startable) + .execute(fileToBeUploaded, TEST_FILE_NAME) // Callable sub process input arguments + .subResult(); + + Boolean isSuccess = result.param("isSuccess", Boolean.class); + assertThat(isSuccess).isTrue(); + } + + @Test + @Order(3) + public void callUploadIvyFile(BpmClient bpmClient) throws IOException { + InputStream fileToBeUploaded = getClass().getResourceAsStream(TEST_FILE_NAME); + java.io.File javaFile = new java.io.File(TEST_FILE_NAME); + FileUtils.copyInputStreamToFile(fileToBeUploaded, javaFile); + + File ivyFile = new File(TEST_FILE_NAME, true); + FileUtils.moveFile(javaFile, ivyFile.getJavaFile()); + + BpmElement startable = TEST_UPLOAD_FILE_PROCESS.elementName("uploadFile(File)"); + + SubProcessCallResult result = bpmClient.start() + .subProcess(startable) + .execute(ivyFile) // Callable sub process input arguments + .subResult(); + + Boolean isSuccess = result.param("isSuccess", Boolean.class); + assertThat(isSuccess).isTrue(); + } + + @Test + @Order(4) + public void callListAllFiles(BpmClient bpmClient) { + BpmElement startable = TEST_DOWNLOAD_FILE_PROCESS.elementName("listAllFiles(String)"); + + SubProcessCallResult result = bpmClient.start() + .subProcess(startable) + .execute(".") // Callable sub process input arguments + .subResult(); + List