Skip to content

Commit

Permalink
Merge pull request #1307 from Nuvindu/master
Browse files Browse the repository at this point in the history
Support preferred auth methods in SFTP client initialization
  • Loading branch information
dilanSachi authored Jul 23, 2024
2 parents adf65b7 + 8d6a10f commit 6644cf9
Show file tree
Hide file tree
Showing 9 changed files with 50 additions and 10 deletions.
6 changes: 3 additions & 3 deletions ballerina/Ballerina.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
org = "ballerina"
name = "ftp"
version = "2.9.1"
version = "2.10.0"
authors = ["Ballerina"]
keywords = ["FTP", "SFTP", "remote file", "file transfer", "client", "service"]
repository = "https://github.com/ballerina-platform/module-ballerina-ftp"
Expand Down Expand Up @@ -33,5 +33,5 @@ path = "./lib/commons-net-3.9.0.jar"
[[platform.java17.dependency]]
groupId = "io.ballerina.stdlib"
artifactId = "ftp-native"
version = "2.9.1"
path = "../native/build/libs/ftp-native-2.9.1.jar"
version = "2.10.0"
path = "../native/build/libs/ftp-native-2.10.0-SNAPSHOT.jar"
2 changes: 1 addition & 1 deletion ballerina/CompilerPlugin.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ id = "ftp-compiler-plugin"
class = "io.ballerina.stdlib.ftp.plugin.FtpCompilerPlugin"

[[dependency]]
path = "../compiler-plugin/build/libs/ftp-compiler-plugin-2.9.1.jar"
path = "../compiler-plugin/build/libs/ftp-compiler-plugin-2.10.0-SNAPSHOT.jar"
4 changes: 2 additions & 2 deletions ballerina/Dependencies.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ distribution-version = "2201.8.0"
[[package]]
org = "ballerina"
name = "ftp"
version = "2.9.1"
version = "2.10.0"
dependencies = [
{org = "ballerina", name = "io"},
{org = "ballerina", name = "jballerina.java"},
Expand Down Expand Up @@ -112,7 +112,7 @@ modules = [
[[package]]
org = "ballerina"
name = "observe"
version = "1.2.0"
version = "1.2.3"
dependencies = [
{org = "ballerina", name = "jballerina.java"}
]
Expand Down
15 changes: 15 additions & 0 deletions ballerina/commons.bal
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,26 @@ public type Credentials record {|
#
# + credentials - Username and password to be used
# + privateKey - Private key to be used
# + preferredMethods - Preferred authentication methods
public type AuthConfiguration record {|
Credentials credentials?;
PrivateKey privateKey?;
PreferredMethod[] preferredMethods = [PUBLICKEY, PASSWORD];
|};

# Authentication methods for the FTP listener.
#
# + KEYBOARD_INTERACTIVE - Keyboard interactive authentication
# + GSSAPI_WITH_MIC - GSSAPI with MIC authentication
# + PASSWORD - Password authentication
# + PUBLICKEY - Public key authentication
public enum PreferredMethod {
KEYBOARD_INTERACTIVE,
GSSAPI_WITH_MIC,
PASSWORD,
PUBLICKEY
}

# Configuration for the input given for `put` and `append` operations of
# the FTP module.
#
Expand Down
3 changes: 2 additions & 1 deletion ballerina/tests/client_endpoint_test.bal
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@ ClientConfiguration sftpConfig = {
privateKey: {
path: "tests/resources/sftp.private.key",
password: "changeit"
}
},
preferredMethods: [GSSAPI_WITH_MIC, PUBLICKEY, KEYBOARD_INTERACTIVE, PASSWORD]
}
};

Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
org.gradle.caching=true
group=io.ballerina.stdlib
version=2.9.2-SNAPSHOT
version=2.10.0-SNAPSHOT

puppycrawlCheckstyleVersion=10.12.0
testngVersion=7.6.1
Expand Down
20 changes: 20 additions & 0 deletions native/src/main/java/io/ballerina/stdlib/ftp/client/FtpClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import io.ballerina.runtime.api.Environment;
import io.ballerina.runtime.api.Future;
import io.ballerina.runtime.api.utils.StringUtils;
import io.ballerina.runtime.api.values.BArray;
import io.ballerina.runtime.api.values.BMap;
import io.ballerina.runtime.api.values.BObject;
import io.ballerina.runtime.api.values.BString;
Expand All @@ -41,10 +42,14 @@
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;

import static io.ballerina.stdlib.ftp.util.FtpConstants.ENDPOINT_CONFIG_PREFERRED_METHODS;
import static io.ballerina.stdlib.ftp.util.FtpConstants.ENTITY_BYTE_STREAM;
import static io.ballerina.stdlib.ftp.util.FtpConstants.NO_AUTH_METHOD_ERROR;
import static io.ballerina.stdlib.ftp.util.FtpConstants.READ_INPUT_STREAM;
import static io.ballerina.stdlib.ftp.util.FtpConstants.VFS_CLIENT_CONNECTOR;
import static io.ballerina.stdlib.ftp.util.FtpUtil.ErrorType.Error;
Expand Down Expand Up @@ -90,6 +95,17 @@ public static Object initClientEndpoint(BObject clientEndpoint, BMap<Object, Obj
ftpConfig.put(FtpConstants.IDENTITY_PASS_PHRASE, privateKeyPassword.getValue());
}
}
final BArray preferredMethods = auth.getArrayValue((StringUtils.fromString(
ENDPOINT_CONFIG_PREFERRED_METHODS)));
if (preferredMethods != null) {
if (preferredMethods.isEmpty()) {
return FtpUtil.createError(NO_AUTH_METHOD_ERROR, Error.errorType());
}
String authMethods = Arrays.stream(preferredMethods.getValues())
.map(FtpClient::getAuthMethod)
.collect(Collectors.joining(","));
ftpConfig.put(ENDPOINT_CONFIG_PREFERRED_METHODS, authMethods);
}
}
ftpConfig.put(FtpConstants.PASSIVE_MODE, String.valueOf(true));
ftpConfig.put(FtpConstants.USER_DIR_IS_ROOT, String.valueOf(false));
Expand All @@ -112,6 +128,10 @@ public static Object initClientEndpoint(BObject clientEndpoint, BMap<Object, Obj
return null;
}

private static String getAuthMethod(Object authMethodObj) {
return authMethodObj.toString().toLowerCase().replace("_", "-");
}

public static Object getFirst(Environment env, BObject clientConnector, BString filePath) {
clientConnector.addNativeData(ENTITY_BYTE_STREAM, null);
Future balFuture = env.markAsync();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static io.ballerina.stdlib.ftp.util.FtpConstants.ENDPOINT_CONFIG_PREFERRED_METHODS;
import static io.ballerina.stdlib.ftp.util.FtpConstants.IDENTITY_PASS_PHRASE;
import static io.ballerina.stdlib.ftp.util.FtpConstants.SCHEME_FTP;
import static io.ballerina.stdlib.ftp.util.FtpConstants.SCHEME_SFTP;
Expand Down Expand Up @@ -82,8 +83,8 @@ private static void setFtpOptions(Map<String, String> options, FileSystemOptions
private static void setSftpOptions(Map<String, String> options, FileSystemOptions opts)
throws RemoteFileSystemConnectorException {
final SftpFileSystemConfigBuilder configBuilder = SftpFileSystemConfigBuilder.getInstance();
configBuilder.setPreferredAuthentications(opts,
"gssapi-with-mic,publickey,keyboard-interactive,password");
String value = options.get(ENDPOINT_CONFIG_PREFERRED_METHODS);
configBuilder.setPreferredAuthentications(opts, value);
if (options.get(FtpConstants.USER_DIR_IS_ROOT) != null) {
configBuilder.setUserDirIsRoot(opts, false);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ private FtpConstants() {
public static final String ENDPOINT_CONFIG_AUTH = "auth";
public static final String ENDPOINT_CONFIG_CREDENTIALS = "credentials";
public static final String ENDPOINT_CONFIG_PRIVATE_KEY = "privateKey";
public static final String ENDPOINT_CONFIG_PREFERRED_METHODS = "preferredMethods";

public static final String INPUT_CONTENT_FILE_PATH_KEY = "filePath";
public static final String INPUT_CONTENT_IS_FILE_KEY = "isFile";
Expand All @@ -87,6 +88,8 @@ private FtpConstants() {
public static final String ON_FILE_CHANGE_REMOTE_FUNCTION = "onFileChange";
public static final String APACHE_VFS2_PACKAGE_NAME = "org.apache.commons.vfs2";
public static final String BALLERINA_FTP_PACKAGE_NAME = "io.ballerina.stdlib.ftp";
public static final String NO_AUTH_METHOD_ERROR = "No preferred auth method is specified in the " +
"SFTP client configurations";

public static final StrandMetadata ON_FILECHANGE_METADATA = new StrandMetadata(ModuleUtils.getModule().getOrg(),
ModuleUtils.getModule().getName(), ModuleUtils.getModule().getMajorVersion(),
Expand Down

0 comments on commit 6644cf9

Please sign in to comment.