diff --git a/.gitignore b/.gitignore index 4df5624..2b9a816 100644 --- a/.gitignore +++ b/.gitignore @@ -23,3 +23,5 @@ jacoco.exec # VS Code .vscode/ + +.java-version \ No newline at end of file diff --git a/src/main/java/com/amazonaws/secretsmanager/sql/AWSSecretsManagerDb2Driver.java b/src/main/java/com/amazonaws/secretsmanager/sql/AWSSecretsManagerDb2Driver.java index e5aee2d..f7e6e72 100644 --- a/src/main/java/com/amazonaws/secretsmanager/sql/AWSSecretsManagerDb2Driver.java +++ b/src/main/java/com/amazonaws/secretsmanager/sql/AWSSecretsManagerDb2Driver.java @@ -15,6 +15,7 @@ import com.amazonaws.secretsmanager.caching.SecretCache; import com.amazonaws.secretsmanager.caching.SecretCacheConfiguration; import com.amazonaws.secretsmanager.util.SQLExceptionUtils; +import com.amazonaws.secretsmanager.util.URLBuilder; import software.amazon.awssdk.services.secretsmanager.SecretsManagerClient; import software.amazon.awssdk.services.secretsmanager.SecretsManagerClientBuilder; import software.amazon.awssdk.utils.StringUtils; @@ -113,6 +114,17 @@ public String constructUrlFromEndpointPortDatabase(String endpoint, String port, if (StringUtils.isNotBlank(dbname)) { url += "/" + dbname; } + else { + url += "/"; + } + return url; + } + + @Override + public String enforceSSL(String url, String sslMode) { + if("true".equalsIgnoreCase(sslMode)) { + return new URLBuilder(url).appendProperty("sslConnection", "true").build(); + } return url; } diff --git a/src/main/java/com/amazonaws/secretsmanager/sql/AWSSecretsManagerDriver.java b/src/main/java/com/amazonaws/secretsmanager/sql/AWSSecretsManagerDriver.java index ec07ab2..f4b566c 100644 --- a/src/main/java/com/amazonaws/secretsmanager/sql/AWSSecretsManagerDriver.java +++ b/src/main/java/com/amazonaws/secretsmanager/sql/AWSSecretsManagerDriver.java @@ -108,6 +108,11 @@ public abstract class AWSSecretsManagerDriver implements Driver { */ public static final String INVALID_SECRET_STRING_JSON = "Could not parse SecretString JSON"; + /** + * Logger for the AWSSecretsManagerDriver class. + */ + private static final Logger logger = Logger.getLogger(AWSSecretsManagerDriver.class.getName()); + private SecretCache secretCache; private String realDriverClass; @@ -319,6 +324,32 @@ public boolean acceptsURL(String url) throws SQLException { */ public abstract String getDefaultDriverClass(); + /** + * Enforce SSL on the given database URL based on the specified SSL mode. + * This method is called when the connect method is called with a secret ID instead of a URL. + * + * @param url The database URL to enforce SSL on. + * @param sslMode The SSL mode to enforce. + * + * @return String The database URL with SSL enforced. + */ + public abstract String enforceSSL(String url, String sslMode); + + private String getSSLConfig(JsonNode jsonObject) { + JsonNode sslNode = jsonObject.get("ssl"); + + if(sslNode == null) { + return "true"; + } + + if (sslNode.isBoolean()) { + return sslNode.asBoolean() ? "true" : "false"; + } else if (sslNode.isTextual()) { + return sslNode.asText(); + } + return "true"; + } + /** * Calls the real driver's connect method using credentials from a secret stored in AWS Secrets * Manager. @@ -329,6 +360,7 @@ public boolean acceptsURL(String url) throws SQLException { * credentials retrieved from Secrets Manager. * @param credentialsSecretId The friendly name or ARN of the secret that stores the * login credentials. + * @param isSecretId A flag indicating if the connection uses a secret ID. * * @return Connection A database connection. * @@ -336,9 +368,10 @@ public boolean acceptsURL(String url) throws SQLException { * database. * @throws InterruptedException If there was an interruption during secret refresh. */ - private Connection connectWithSecret(String unwrappedUrl, Properties info, String credentialsSecretId) + private Connection connectWithSecret(String unwrappedUrl, Properties info, String credentialsSecretId, boolean isSecretId) throws SQLException, InterruptedException { int retryCount = 0; + String sslMode = null; while (retryCount++ <= MAX_RETRY) { String secretString = secretCache.getSecretString(credentialsSecretId); Properties updatedInfo = new Properties(info); @@ -346,6 +379,7 @@ private Connection connectWithSecret(String unwrappedUrl, Properties info, Strin JsonNode jsonObject = mapper.readTree(secretString); updatedInfo.setProperty("user", jsonObject.get("username").asText()); updatedInfo.setProperty("password", jsonObject.get("password").asText()); + sslMode = isSecretId ? getSSLConfig(jsonObject) : null; } catch (IOException e) { // Most likely to occur in the event that the data is not JSON. // Or the secret's username and/or password fields have been @@ -353,6 +387,15 @@ private Connection connectWithSecret(String unwrappedUrl, Properties info, Strin throw new RuntimeException(INVALID_SECRET_STRING_JSON); } + if (sslMode != null && !"false".equalsIgnoreCase(sslMode)) { + try { + return getWrappedDriver().connect(enforceSSL(unwrappedUrl, sslMode), updatedInfo); + } catch (SQLException e) { + // If SSL connection fails, fall back to non-SSL + logger.warning("SSL connection failed. Falling back to non-SSL connection. Error: " + e.getMessage()); + } + } + try { return getWrappedDriver().connect(unwrappedUrl, updatedInfo); } catch (Exception e) { @@ -379,6 +422,7 @@ public Connection connect(String url, Properties info) throws SQLException { } String unwrappedUrl = ""; + boolean isSecretId = false; if (url.startsWith(SCHEME)) { // If this is a URL in the correct scheme, unwrap it unwrappedUrl = unwrapUrl(url); } else { // Else, assume this is a secret ID and try to retrieve it @@ -395,6 +439,7 @@ public Connection connect(String url, Properties info) throws SQLException { JsonNode dbnameNode = jsonObject.get("dbname"); String dbname = dbnameNode == null ? null : dbnameNode.asText(); unwrappedUrl = constructUrlFromEndpointPortDatabase(endpoint, port, dbname); + isSecretId = true; } catch (IOException e) { // Most likely to occur in the event that the data is not JSON. // Or the secret has been modified and is no longer valid. @@ -406,7 +451,7 @@ public Connection connect(String url, Properties info) throws SQLException { if (info != null && info.getProperty("user") != null) { String credentialsSecretId = info.getProperty("user"); try { - return connectWithSecret(unwrappedUrl, info, credentialsSecretId); + return connectWithSecret(unwrappedUrl, info, credentialsSecretId, isSecretId); } catch (InterruptedException e) { // User driven exception. Throw a runtime exception. throw new RuntimeException(e); diff --git a/src/main/java/com/amazonaws/secretsmanager/sql/AWSSecretsManagerMSSQLServerDriver.java b/src/main/java/com/amazonaws/secretsmanager/sql/AWSSecretsManagerMSSQLServerDriver.java index 1a44728..ced9e5c 100644 --- a/src/main/java/com/amazonaws/secretsmanager/sql/AWSSecretsManagerMSSQLServerDriver.java +++ b/src/main/java/com/amazonaws/secretsmanager/sql/AWSSecretsManagerMSSQLServerDriver.java @@ -13,6 +13,7 @@ package com.amazonaws.secretsmanager.sql; import java.sql.SQLException; +import com.amazonaws.secretsmanager.util.URLBuilder; import com.amazonaws.secretsmanager.caching.SecretCache; import com.amazonaws.secretsmanager.caching.SecretCacheConfiguration; @@ -126,6 +127,21 @@ public String constructUrlFromEndpointPortDatabase(String endpoint, String port, return url; } + @Override + public String enforceSSL(String url, String sslMode) { + URLBuilder builder = new URLBuilder(url); + switch(sslMode) { + case "TLS": + case "TLSv1": + case "TLSv1.1": + case "TLSv1.2": + return builder.appendProperty("sslProtocol", sslMode).build(); + default: + break; + } + return builder.appendProperty("sslProtocol", "TLS").build(); + } + @Override public String getDefaultDriverClass() { return "com.microsoft.sqlserver.jdbc.SQLServerDriver"; diff --git a/src/main/java/com/amazonaws/secretsmanager/sql/AWSSecretsManagerMariaDBDriver.java b/src/main/java/com/amazonaws/secretsmanager/sql/AWSSecretsManagerMariaDBDriver.java index e151b86..ee4dba3 100644 --- a/src/main/java/com/amazonaws/secretsmanager/sql/AWSSecretsManagerMariaDBDriver.java +++ b/src/main/java/com/amazonaws/secretsmanager/sql/AWSSecretsManagerMariaDBDriver.java @@ -15,6 +15,7 @@ import com.amazonaws.secretsmanager.caching.SecretCache; import com.amazonaws.secretsmanager.caching.SecretCacheConfiguration; import com.amazonaws.secretsmanager.util.SQLExceptionUtils; +import com.amazonaws.secretsmanager.util.URLBuilder; import software.amazon.awssdk.services.secretsmanager.SecretsManagerClient; import software.amazon.awssdk.services.secretsmanager.SecretsManagerClientBuilder; @@ -121,6 +122,22 @@ public String constructUrlFromEndpointPortDatabase(String endpoint, String port, return url; } + @Override + public String enforceSSL(String url, String sslMode) { + URLBuilder builder = new URLBuilder(url); + switch(sslMode) { + case "disable": + break; + case "trust": + case "verify-full": + case "verify-ca": + return builder.appendParameter("sslMode", sslMode, !url.contains("?")).build(); + default: + return builder.appendParameter("sslMode", "trust", !url.contains("?")).build(); + } + return url; + } + @Override public String getDefaultDriverClass() { return "org.mariadb.jdbc.Driver"; diff --git a/src/main/java/com/amazonaws/secretsmanager/sql/AWSSecretsManagerMySQLDriver.java b/src/main/java/com/amazonaws/secretsmanager/sql/AWSSecretsManagerMySQLDriver.java index 975f4ce..97a2f48 100644 --- a/src/main/java/com/amazonaws/secretsmanager/sql/AWSSecretsManagerMySQLDriver.java +++ b/src/main/java/com/amazonaws/secretsmanager/sql/AWSSecretsManagerMySQLDriver.java @@ -15,6 +15,7 @@ import com.amazonaws.secretsmanager.caching.SecretCache; import com.amazonaws.secretsmanager.caching.SecretCacheConfiguration; import com.amazonaws.secretsmanager.util.SQLExceptionUtils; +import com.amazonaws.secretsmanager.util.URLBuilder; import software.amazon.awssdk.services.secretsmanager.SecretsManagerClient; import software.amazon.awssdk.services.secretsmanager.SecretsManagerClientBuilder; @@ -121,6 +122,23 @@ public String constructUrlFromEndpointPortDatabase(String endpoint, String port, return url; } + @Override + public String enforceSSL(String url, String sslMode) { + URLBuilder builder = new URLBuilder(url); + switch(sslMode) { + case "DISABLED": + break; + case "PREFERRED": + case "REQUIRED": + case "VERIFY_CA": + case "VERIFY_IDENTITY": + return builder.appendParameter("sslMode", sslMode, !url.contains("?")).build(); + default: + return builder.appendParameter("sslMode", "PREFERRED", !url.contains("?")).build(); + } + return url; + } + @Override public String getDefaultDriverClass() { try { diff --git a/src/main/java/com/amazonaws/secretsmanager/sql/AWSSecretsManagerOracleDriver.java b/src/main/java/com/amazonaws/secretsmanager/sql/AWSSecretsManagerOracleDriver.java index a8f1d96..8684b2e 100644 --- a/src/main/java/com/amazonaws/secretsmanager/sql/AWSSecretsManagerOracleDriver.java +++ b/src/main/java/com/amazonaws/secretsmanager/sql/AWSSecretsManagerOracleDriver.java @@ -143,6 +143,16 @@ public String constructUrlFromEndpointPortDatabase(String endpoint, String port, return url; } + @Override + public String enforceSSL(String url, String sslMode) { + if("true".equalsIgnoreCase(sslMode)) { + if (url.startsWith("jdbc:oracle:thin:@//")) { + return url.replace("jdbc:oracle:thin:@//", "jdbc:oracle:thin:@tcps://"); + } + } + return url; + } + @Override public String getDefaultDriverClass() { return "oracle.jdbc.OracleDriver"; diff --git a/src/main/java/com/amazonaws/secretsmanager/sql/AWSSecretsManagerPostgreSQLDriver.java b/src/main/java/com/amazonaws/secretsmanager/sql/AWSSecretsManagerPostgreSQLDriver.java index 1b6dacf..92724b8 100644 --- a/src/main/java/com/amazonaws/secretsmanager/sql/AWSSecretsManagerPostgreSQLDriver.java +++ b/src/main/java/com/amazonaws/secretsmanager/sql/AWSSecretsManagerPostgreSQLDriver.java @@ -13,6 +13,7 @@ package com.amazonaws.secretsmanager.sql; import java.sql.SQLException; +import com.amazonaws.secretsmanager.util.URLBuilder; import com.amazonaws.secretsmanager.caching.SecretCache; import com.amazonaws.secretsmanager.caching.SecretCacheConfiguration; @@ -134,6 +135,34 @@ public String constructUrlFromEndpointPortDatabase(String endpoint, String port, return url; } + @Override + public String enforceSSL(String url, String sslMode) { + + if (url.endsWith("/")) { + url = url.substring(0, url.length() - 1); + } + + URLBuilder builder = new URLBuilder(url); + + if ("true".equalsIgnoreCase(sslMode)) { + return builder.appendParameter("sslMode", "verify-full", !url.contains("?")).build(); + } else { + switch(sslMode) { + case "disable": + break; + case "allow": + case "prefer": + case "require": + case "verify-ca": + case "verify-full": + return builder.appendParameter("sslMode", sslMode, !url.contains("?")).build(); + default: + return builder.appendParameter("sslMode", "prefer", !url.contains("?")).build(); + } + } + return url; + } + @Override public String getDefaultDriverClass() { return "org.postgresql.Driver"; diff --git a/src/main/java/com/amazonaws/secretsmanager/sql/AWSSecretsManagerRedshiftDriver.java b/src/main/java/com/amazonaws/secretsmanager/sql/AWSSecretsManagerRedshiftDriver.java index 4b84dc6..fd6b6b3 100644 --- a/src/main/java/com/amazonaws/secretsmanager/sql/AWSSecretsManagerRedshiftDriver.java +++ b/src/main/java/com/amazonaws/secretsmanager/sql/AWSSecretsManagerRedshiftDriver.java @@ -13,6 +13,7 @@ package com.amazonaws.secretsmanager.sql; import java.sql.SQLException; +import com.amazonaws.secretsmanager.util.URLBuilder; import com.amazonaws.secretsmanager.caching.SecretCache; import com.amazonaws.secretsmanager.caching.SecretCacheConfiguration; @@ -128,6 +129,24 @@ public String constructUrlFromEndpointPortDatabase(String endpoint, String port, return url; } + @Override + public String enforceSSL(String url, String sslMode) { + URLBuilder builder = new URLBuilder(url); + switch(sslMode) { + case "disable": + break; + case "allow": + case "prefer": + case "require": + case "verify-ca": + case "verify-full": + return builder.appendProperty("sslmode", sslMode).build(); + default: + return builder.appendProperty("sslmode", "prefer").build(); + } + return url; + } + @Override public String getDefaultDriverClass() { return "com.amazon.redshift.Driver"; diff --git a/src/main/java/com/amazonaws/secretsmanager/util/URLBuilder.java b/src/main/java/com/amazonaws/secretsmanager/util/URLBuilder.java new file mode 100644 index 0000000..3f4e2c6 --- /dev/null +++ b/src/main/java/com/amazonaws/secretsmanager/util/URLBuilder.java @@ -0,0 +1,68 @@ +/* + * Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with + * the License. A copy of the License is located at + * + * http://aws.amazon.com/apache2.0 + * + * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ +package com.amazonaws.secretsmanager.util; + +public class URLBuilder { + private StringBuilder url; + + /** + * Initializes the URL Builder with base URL. + * + * @param baseUrl The base URL to use. + */ + public URLBuilder(String baseUrl) { + this.url = new StringBuilder(baseUrl); + } + + /** + * Appends a parameter to the URL in the form of ?key=value or &key=value. + * + * @param key The key of the parameter. + * @param value The value of the parameter. + * @param isFirstParameter Indicates whether this is the first parameter in the URL. + * @return The URL Builder object. + */ + public URLBuilder appendParameter(String key, String value, boolean isFirstParameter) { + if (isFirstParameter) { + url.append("?"); + } else { + url.append("&"); + } + url.append(key).append("=").append(value); + return this; + } + + /** + * Appends a property to the URL in the form of ;key=value; + * + * @param key The key of the property. + * @param value The value of the property. + * @return The URL Builder object. + */ + public URLBuilder appendProperty(String key, String value) { + if(url.charAt(url.length() - 1) != ';') { + url.append(";"); + } + url.append(key).append("=").append(value).append(";"); + return this; + } + + /** + * Returns the constructed URL. + * + * @return String The built URL. + */ + public String build() { + return url.toString(); + } +} \ No newline at end of file diff --git a/src/test/java/com/amazonaws/secretsmanager/sql/AWSSecretsManagerDb2DriverTest.java b/src/test/java/com/amazonaws/secretsmanager/sql/AWSSecretsManagerDb2DriverTest.java index b402ddf..9de89cd 100644 --- a/src/test/java/com/amazonaws/secretsmanager/sql/AWSSecretsManagerDb2DriverTest.java +++ b/src/test/java/com/amazonaws/secretsmanager/sql/AWSSecretsManagerDb2DriverTest.java @@ -94,7 +94,31 @@ public void test_constructUrlNullPort() { @Test public void test_constructUrlNullDatabase() { String url = sut.constructUrlFromEndpointPortDatabase("test-endpoint", "1234", null); - assertEquals(url, "jdbc:db2://test-endpoint:1234"); + assertEquals(url, "jdbc:db2://test-endpoint:1234/"); + } + + @Test + public void test_enforceSSL_WithTrueSSLMode() { + String url = sut.enforceSSL("jdbc:db2://test-endpoint:1234/dev", "true"); + assertEquals(url, "jdbc:db2://test-endpoint:1234/dev;sslConnection=true;"); + } + + @Test + public void test_enforceSSLNullPort_WithTrueSSLModeUpperCas() { + String url = sut.enforceSSL("jdbc:db2://test-endpoint/dev", "TRUE"); + assertEquals(url, "jdbc:db2://test-endpoint/dev;sslConnection=true;"); + } + + @Test + public void test_enforceSSLNullDatabase_WithTrueSSLMode() { + String url = sut.enforceSSL("jdbc:db2://test-endpoint:1234/", "TRue"); + assertEquals(url, "jdbc:db2://test-endpoint:1234/;sslConnection=true;"); + } + + @Test + public void test_enforceSSL_WithNonBooleanSSLMode() { + String url = sut.enforceSSL("jdbc:db2://test-endpoint:1234/dev", "verify-full"); + assertEquals(url, "jdbc:db2://test-endpoint:1234/dev"); } @Test diff --git a/src/test/java/com/amazonaws/secretsmanager/sql/AWSSecretsManagerDummyDriver.java b/src/test/java/com/amazonaws/secretsmanager/sql/AWSSecretsManagerDummyDriver.java index 170b8c4..7570f59 100644 --- a/src/test/java/com/amazonaws/secretsmanager/sql/AWSSecretsManagerDummyDriver.java +++ b/src/test/java/com/amazonaws/secretsmanager/sql/AWSSecretsManagerDummyDriver.java @@ -88,6 +88,11 @@ public String constructUrlFromEndpointPortDatabase(String endpoint, String port, return "mysuperconnectionurl"; } + @Override + public String enforceSSL(String url, String sslMode) { + return "mysslconnectionurl"; + } + @Override public String getDefaultDriverClass() { return "com.amazonaws.secretsmanager.sql.DummyDriver"; diff --git a/src/test/java/com/amazonaws/secretsmanager/sql/AWSSecretsManagerMSSQLServerDriverTest.java b/src/test/java/com/amazonaws/secretsmanager/sql/AWSSecretsManagerMSSQLServerDriverTest.java index e98b5c9..3b07b5c 100644 --- a/src/test/java/com/amazonaws/secretsmanager/sql/AWSSecretsManagerMSSQLServerDriverTest.java +++ b/src/test/java/com/amazonaws/secretsmanager/sql/AWSSecretsManagerMSSQLServerDriverTest.java @@ -98,6 +98,30 @@ public void test_constructUrlNullDatabase() { assertEquals(url, "jdbc:sqlserver://test-endpoint:1234"); } + @Test + public void test_enforceSSL_WithTlsMode() { + String url = sut.enforceSSL("jdbc:sqlserver://test-endpoint:1234;databaseName=dev;", "TLS"); + assertEquals(url, "jdbc:sqlserver://test-endpoint:1234;databaseName=dev;sslProtocol=TLS;"); + } + + @Test + public void test_enforceSSLNullPort_WithTlsv1Mode() { + String url = sut.enforceSSL("jdbc:sqlserver://test-endpoint;databaseName=dev;", "TLSv1"); + assertEquals(url, "jdbc:sqlserver://test-endpoint;databaseName=dev;sslProtocol=TLSv1;"); + } + + @Test + public void test_enforceSSLNullDatabase_WithTlsv1_2Mode() { + String url = sut.enforceSSL("jdbc:sqlserver://test-endpoint:1234", "TLSv1.2"); + assertEquals(url, "jdbc:sqlserver://test-endpoint:1234;sslProtocol=TLSv1.2;"); + } + + @Test + public void test_enforceSSL_WithDefaultSSLMode() { + String url = sut.enforceSSL("jdbc:sqlserver://test-endpoint:1234;databaseName=dev;", "true"); + assertEquals(url, "jdbc:sqlserver://test-endpoint:1234;databaseName=dev;sslProtocol=TLS;"); + } + @Test public void test_getDefaultDriverClass() { System.clearProperty("drivers.sqlserver.realDriverClass"); diff --git a/src/test/java/com/amazonaws/secretsmanager/sql/AWSSecretsManagerMariaDBDriverTest.java b/src/test/java/com/amazonaws/secretsmanager/sql/AWSSecretsManagerMariaDBDriverTest.java index fff739d..bbec65b 100644 --- a/src/test/java/com/amazonaws/secretsmanager/sql/AWSSecretsManagerMariaDBDriverTest.java +++ b/src/test/java/com/amazonaws/secretsmanager/sql/AWSSecretsManagerMariaDBDriverTest.java @@ -98,6 +98,30 @@ public void test_constructUrlNullDatabase() { assertEquals(url, "jdbc:mariadb://test-endpoint:1234"); } + @Test + public void test_enforceSSL_WithDisableMode() { + String url = sut.enforceSSL("jdbc:mariadb://test-endpoint:1234/dev", "disable"); + assertEquals(url, "jdbc:mariadb://test-endpoint:1234/dev"); + } + + @Test + public void test_enforceSSLNullPort_withVerifyFullMode() { + String url = sut.enforceSSL("jdbc:mariadb://test-endpoint/dev", "verify-full"); + assertEquals(url, "jdbc:mariadb://test-endpoint/dev?sslMode=verify-full"); + } + + @Test + public void test_enforceSSLNullDatabase_withVerifyCaMode() { + String url = sut.enforceSSL("jdbc:mariadb://test-endpoint:1234", "verify-ca"); + assertEquals(url, "jdbc:mariadb://test-endpoint:1234?sslMode=verify-ca"); + } + + @Test + public void test_enforceSSL_WithDefaultSSLMode() { + String url = sut.enforceSSL("jdbc:mariadb://test-endpoint:1234/dev", "true"); + assertEquals(url, "jdbc:mariadb://test-endpoint:1234/dev?sslMode=trust"); + } + @Test public void test_getDefaultDriverClass() { System.clearProperty("drivers.mariadb.realDriverClass"); diff --git a/src/test/java/com/amazonaws/secretsmanager/sql/AWSSecretsManagerMySQLDriverTest.java b/src/test/java/com/amazonaws/secretsmanager/sql/AWSSecretsManagerMySQLDriverTest.java index 382a3ea..dc4ee2e 100644 --- a/src/test/java/com/amazonaws/secretsmanager/sql/AWSSecretsManagerMySQLDriverTest.java +++ b/src/test/java/com/amazonaws/secretsmanager/sql/AWSSecretsManagerMySQLDriverTest.java @@ -98,6 +98,36 @@ public void test_constructUrlNullDatabase() { assertEquals(url, "jdbc:mysql://test-endpoint:1234"); } + @Test + public void test_enforceSSL_WithDisabledMode() { + String url = sut.enforceSSL("jdbc:mysql://test-endpoint:1234/dev", "DISABLED"); + assertEquals(url, "jdbc:mysql://test-endpoint:1234/dev"); + } + + @Test + public void test_enforceSSLNullPort_withVerifyCAMode() { + String url = sut.enforceSSL("jdbc:mysql://test-endpoint/dev", "VERIFY_CA"); + assertEquals(url, "jdbc:mysql://test-endpoint/dev?sslMode=VERIFY_CA"); + } + + @Test + public void test_enforceSSLNullDatabase_withVerifyIdentityMode() { + String url = sut.enforceSSL("jdbc:mysql://test-endpoint:1234", "VERIFY_IDENTITY"); + assertEquals(url, "jdbc:mysql://test-endpoint:1234?sslMode=VERIFY_IDENTITY"); + } + + @Test + public void test_enforceSSL_WithRequiredSSLMode() { + String url = sut.enforceSSL("jdbc:mysql://test-endpoint:1234/dev", "REQUIRED"); + assertEquals(url, "jdbc:mysql://test-endpoint:1234/dev?sslMode=REQUIRED"); + } + + @Test + public void test_enforceSSL_WithDefaultSSLMode() { + String url = sut.enforceSSL("jdbc:mysql://test-endpoint:1234/dev", "true"); + assertEquals(url, "jdbc:mysql://test-endpoint:1234/dev?sslMode=PREFERRED"); + } + @Test public void test_getDefaultDriverClass() { System.clearProperty("drivers.mysql.realDriverClass"); diff --git a/src/test/java/com/amazonaws/secretsmanager/sql/AWSSecretsManagerOracleDriverTest.java b/src/test/java/com/amazonaws/secretsmanager/sql/AWSSecretsManagerOracleDriverTest.java index 59a6ab6..62a9e7c 100644 --- a/src/test/java/com/amazonaws/secretsmanager/sql/AWSSecretsManagerOracleDriverTest.java +++ b/src/test/java/com/amazonaws/secretsmanager/sql/AWSSecretsManagerOracleDriverTest.java @@ -103,6 +103,30 @@ public void test_constructUrlNullDatabase() { assertEquals(url, "jdbc:oracle:thin:@//test-endpoint:1234"); } + @Test + public void test_enforceSSL_WithTrueSSLMode() { + String url = sut.enforceSSL("jdbc:oracle:thin:@//test-endpoint:1234/dev", "true"); + assertEquals(url, "jdbc:oracle:thin:@tcps://test-endpoint:1234/dev"); + } + + @Test + public void test_enforceSSLNullPort_WithTrueSSLModeUpperCas() { + String url = sut.enforceSSL("jdbc:oracle:thin:@//test-endpoint/dev", "TRUE"); + assertEquals(url, "jdbc:oracle:thin:@tcps://test-endpoint/dev"); + } + + @Test + public void test_enforceSSLNullDatabase_WithTrueSSLMode() { + String url = sut.enforceSSL("jdbc:oracle:thin:@//test-endpoint:1234", "TRue"); + assertEquals(url, "jdbc:oracle:thin:@tcps://test-endpoint:1234"); + } + + @Test + public void test_enforceSSL_WithNonBooleanSSLMode() { + String url = sut.enforceSSL("jdbc:oracle:thin:@//test-endpoint:1234/dev", "verify-full"); + assertEquals(url, "jdbc:oracle:thin:@//test-endpoint:1234/dev"); + } + @Test public void test_getDefaultDriverClass() { System.clearProperty("drivers.oracle.realDriverClass"); diff --git a/src/test/java/com/amazonaws/secretsmanager/sql/AWSSecretsManagerPostgreSQLDriverTest.java b/src/test/java/com/amazonaws/secretsmanager/sql/AWSSecretsManagerPostgreSQLDriverTest.java index a07579e..4ecb082 100644 --- a/src/test/java/com/amazonaws/secretsmanager/sql/AWSSecretsManagerPostgreSQLDriverTest.java +++ b/src/test/java/com/amazonaws/secretsmanager/sql/AWSSecretsManagerPostgreSQLDriverTest.java @@ -98,6 +98,36 @@ public void test_constructUrlNullDatabase() { assertEquals(url, "jdbc:postgresql://test-endpoint:1234/"); } + @Test + public void test_enforceSSL_WithDisableMode() { + String url = sut.enforceSSL("jdbc:postgresql://test-endpoint:1234/dev", "disable"); + assertEquals(url, "jdbc:postgresql://test-endpoint:1234/dev"); + } + + @Test + public void test_enforceSSL_WithAllowMode() { + String url = sut.enforceSSL("jdbc:postgresql://test-endpoint:1234/dev", "allow"); + assertEquals(url, "jdbc:postgresql://test-endpoint:1234/dev?sslMode=allow"); + } + + @Test + public void test_enforceSSL_WithDefaultSSLMode() { + String url = sut.enforceSSL("jdbc:postgresql://test-endpoint:1234/dev", "Verify_full"); + assertEquals(url, "jdbc:postgresql://test-endpoint:1234/dev?sslMode=prefer"); + } + + @Test + public void test_enforceSSLNullPort_withVerifyCAMode() { + String url = sut.enforceSSL("jdbc:postgresql://test-endpoint/dev", "verify-ca"); + assertEquals(url, "jdbc:postgresql://test-endpoint/dev?sslMode=verify-ca"); + } + + @Test + public void test_enforceSSLNullDatabase_withTrueMode() { + String url = sut.enforceSSL("jdbc:postgresql://test-endpoint:1234/", "True"); + assertEquals(url, "jdbc:postgresql://test-endpoint:1234?sslMode=verify-full"); + } + @Test public void test_getDefaultDriverClass() { System.clearProperty("drivers.postgresql.realDriverClass"); diff --git a/src/test/java/com/amazonaws/secretsmanager/sql/AWSSecretsManagerRedshiftDriverTest.java b/src/test/java/com/amazonaws/secretsmanager/sql/AWSSecretsManagerRedshiftDriverTest.java index 600d8d6..e7b2ced 100644 --- a/src/test/java/com/amazonaws/secretsmanager/sql/AWSSecretsManagerRedshiftDriverTest.java +++ b/src/test/java/com/amazonaws/secretsmanager/sql/AWSSecretsManagerRedshiftDriverTest.java @@ -98,6 +98,36 @@ public void test_constructUrlNullDatabase() { assertEquals(url, "jdbc:redshift://test-endpoint:1234"); } + @Test + public void test_enforceSSL_WithDisableMode() { + String url = sut.enforceSSL("jdbc:redshift://test-endpoint:1234/dev", "disable"); + assertEquals(url, "jdbc:redshift://test-endpoint:1234/dev"); + } + + @Test + public void test_enforceSSL_WithAllowMode() { + String url = sut.enforceSSL("jdbc:redshift://test-endpoint:1234/dev", "allow"); + assertEquals(url, "jdbc:redshift://test-endpoint:1234/dev;sslmode=allow;"); + } + + @Test + public void test_enforceSSL_WithDefaultSSLMode() { + String url = sut.enforceSSL("jdbc:redshift://test-endpoint:1234/dev", "True"); + assertEquals(url, "jdbc:redshift://test-endpoint:1234/dev;sslmode=prefer;"); + } + + @Test + public void test_enforceSSLNullPort_withVerifyCAMode() { + String url = sut.enforceSSL("jdbc:redshift://test-endpoint/dev", "verify-ca"); + assertEquals(url, "jdbc:redshift://test-endpoint/dev;sslmode=verify-ca;"); + } + + @Test + public void test_enforceSSLNullDatabase_withRequireMode() { + String url = sut.enforceSSL("jdbc:redshift://test-endpoint:1234", "require"); + assertEquals(url, "jdbc:redshift://test-endpoint:1234;sslmode=require;"); + } + @Test public void test_getDefaultDriverClass() { System.clearProperty("drivers.redshift.realDriverClass"); diff --git a/src/test/java/com/amazonaws/secretsmanager/util/URLBuilderTest.java b/src/test/java/com/amazonaws/secretsmanager/util/URLBuilderTest.java new file mode 100644 index 0000000..e847cc0 --- /dev/null +++ b/src/test/java/com/amazonaws/secretsmanager/util/URLBuilderTest.java @@ -0,0 +1,46 @@ +package com.amazonaws.secretsmanager.util; + +import static org.junit.Assert.assertEquals; +import org.junit.Test; + +public class URLBuilderTest { + + @Test + public void test_append_parameter_with_one_parameter() { + URLBuilder builder = new URLBuilder("jdbc:mysql://test-endpoint:1234/dev"); + String url = builder.appendParameter("sslMode", "REQUIRED", true).build(); + assertEquals("jdbc:mysql://test-endpoint:1234/dev?sslMode=REQUIRED", url); + } + + @Test + public void test_append_parameter_with_multiple_parameters() { + URLBuilder builder = new URLBuilder("jdbc:mysql://test-endpoint:1234/dev"); + String url = builder.appendParameter("user", "root", true) + .appendParameter("password", "password", false) + .appendParameter("sslMode", "REQUIRED", false).build(); + assertEquals("jdbc:mysql://test-endpoint:1234/dev?user=root&password=password&sslMode=REQUIRED", url); + } + + @Test + public void test_append_property_with_one_property() { + URLBuilder builder = new URLBuilder("jdbc:sqlserver://test-endpoint:1234;databaseName=dev;"); + String url = builder.appendProperty("sslProtocol", "TLS").build(); + assertEquals("jdbc:sqlserver://test-endpoint:1234;databaseName=dev;sslProtocol=TLS;", url); + } + + @Test + public void test_append_property_with_multiple_properties() { + URLBuilder builder = new URLBuilder("jdbc:sqlserver://test-endpoint:1234;databaseName=dev;"); + String url = builder.appendProperty("sslProtocol", "TLS") + .appendProperty("trustStore", "truststore.jks") + .appendProperty("trustStorePassword", "password").build(); + assertEquals("jdbc:sqlserver://test-endpoint:1234;databaseName=dev;sslProtocol=TLS;trustStore=truststore.jks;trustStorePassword=password;", url); + } + + @Test + public void test_urlbuilder_with_no_modification(){ + URLBuilder builder = new URLBuilder("jdbc:postgresql://test-endpoint:1234/"); + String url = builder.build(); + assertEquals("jdbc:postgresql://test-endpoint:1234/", url); + } +} \ No newline at end of file