|
25 | 25 |
|
26 | 26 | public class PostgresSourceStrictEncryptTest {
|
27 | 27 |
|
| 28 | + private final PostgresSourceStrictEncrypt source = new PostgresSourceStrictEncrypt(); |
| 29 | + private final PostgreSQLContainer<?> postgreSQLContainerNoSSL = new PostgreSQLContainer<>("postgres:13-alpine"); |
| 30 | + private final PostgreSQLContainer<?> postgreSQLContainerWithSSL = |
| 31 | + new PostgreSQLContainer<>(DockerImageName.parse("marcosmarxm/postgres-ssl:dev").asCompatibleSubstituteFor("postgres")) |
| 32 | + .withCommand("postgres -c ssl=on -c ssl_cert_file=/var/lib/postgresql/server.crt -c ssl_key_file=/var/lib/postgresql/server.key"); |
| 33 | + private static final List<String> NON_STRICT_SSL_MODES = List.of("disable", "allow", "prefer"); |
| 34 | + private static final String SSL_MODE_REQUIRE = "require"; |
| 35 | + |
28 | 36 | private static final SshBastionContainer bastion = new SshBastionContainer();
|
29 | 37 | private static final Network network = Network.newNetwork();
|
30 | 38 |
|
31 | 39 | @Test
|
32 |
| - void testCheckWithSSlModeDisable() throws Exception { |
| 40 | + void testSSlModesDisableAllowPreferWithTunnelIfServerDoesNotSupportSSL() throws Exception { |
| 41 | + |
| 42 | + try (PostgreSQLContainer<?> db = postgreSQLContainerNoSSL.withNetwork(network)) { |
| 43 | + bastion.initAndStartBastion(network); |
| 44 | + db.start(); |
| 45 | + |
| 46 | + for (String sslmode : NON_STRICT_SSL_MODES) { |
| 47 | + final AirbyteConnectionStatus connectionStatus = checkWithTunnel(db, sslmode); |
| 48 | + assertEquals(AirbyteConnectionStatus.Status.SUCCEEDED, connectionStatus.getStatus()); |
| 49 | + } |
| 50 | + |
| 51 | + } finally { |
| 52 | + bastion.stopAndClose(); |
| 53 | + } |
| 54 | + } |
| 55 | + |
| 56 | + @Test |
| 57 | + void testSSlModesDisableAllowPreferWithTunnelIfServerSupportSSL() throws Exception { |
| 58 | + try (PostgreSQLContainer<?> db = postgreSQLContainerWithSSL.withNetwork(network)) { |
| 59 | + |
| 60 | + bastion.initAndStartBastion(network); |
| 61 | + db.start(); |
| 62 | + for (String sslmode : NON_STRICT_SSL_MODES) { |
| 63 | + |
| 64 | + final AirbyteConnectionStatus connectionStatus = checkWithTunnel(db, sslmode); |
| 65 | + assertEquals(AirbyteConnectionStatus.Status.SUCCEEDED, connectionStatus.getStatus()); |
| 66 | + } |
| 67 | + } finally { |
| 68 | + bastion.stopAndClose(); |
| 69 | + } |
| 70 | + } |
| 71 | + |
| 72 | + @Test |
| 73 | + void testSSlModesDisableAllowPreferWithFailedTunnelIfServerSupportSSL() throws Exception { |
| 74 | + try (PostgreSQLContainer<?> db = postgreSQLContainerWithSSL) { |
33 | 75 |
|
34 |
| - try (PostgreSQLContainer<?> db = new PostgreSQLContainer<>("postgres:13-alpine").withNetwork(network)) { |
35 | 76 | bastion.initAndStartBastion(network);
|
36 | 77 | db.start();
|
| 78 | + for (String sslmode : NON_STRICT_SSL_MODES) { |
37 | 79 |
|
38 |
| - // stop to enforce ssl for ssl_mode disable |
39 |
| - final ImmutableMap.Builder<Object, Object> builderWithSSLModeDisable = getDatabaseConfigBuilderWithSSLMode(db, "disable"); |
40 |
| - final JsonNode configWithSSLModeDisable = bastion.getTunnelConfig(SshTunnel.TunnelMethod.SSH_PASSWORD_AUTH, builderWithSSLModeDisable); |
41 |
| - final AirbyteConnectionStatus connectionStatusForDisabledMode = new PostgresSourceStrictEncrypt().check(configWithSSLModeDisable); |
42 |
| - assertEquals(AirbyteConnectionStatus.Status.SUCCEEDED, connectionStatusForDisabledMode.getStatus()); |
| 80 | + final AirbyteConnectionStatus connectionStatus = checkWithTunnel(db, sslmode); |
| 81 | + assertEquals(AirbyteConnectionStatus.Status.FAILED, connectionStatus.getStatus()); |
| 82 | + assertTrue(connectionStatus.getMessage().contains("Connection is not available")); |
43 | 83 |
|
| 84 | + } |
44 | 85 | } finally {
|
45 | 86 | bastion.stopAndClose();
|
46 | 87 | }
|
47 | 88 | }
|
48 | 89 |
|
49 | 90 | @Test
|
50 |
| - void testCheckWithSSlModePrefer() throws Exception { |
| 91 | + void testSSlRequiredWithTunnelIfServerDoesNotSupportSSL() throws Exception { |
51 | 92 |
|
52 |
| - try (PostgreSQLContainer<?> db = new PostgreSQLContainer<>("postgres:13-alpine").withNetwork(network)) { |
| 93 | + try (PostgreSQLContainer<?> db = postgreSQLContainerNoSSL.withNetwork(network)) { |
53 | 94 | bastion.initAndStartBastion(network);
|
54 | 95 | db.start();
|
55 |
| - // continue to enforce ssl because ssl mode is prefer |
56 |
| - final ImmutableMap.Builder<Object, Object> builderWithSSLModePrefer = getDatabaseConfigBuilderWithSSLMode(db, "prefer"); |
57 |
| - final JsonNode configWithSSLModePrefer = bastion.getTunnelConfig(SshTunnel.TunnelMethod.SSH_PASSWORD_AUTH, builderWithSSLModePrefer); |
58 |
| - final AirbyteConnectionStatus connectionStatusForPreferredMode = new PostgresSourceStrictEncrypt().check(configWithSSLModePrefer); |
59 |
| - assertEquals(AirbyteConnectionStatus.Status.FAILED, connectionStatusForPreferredMode.getStatus()); |
60 |
| - assertEquals("State code: 08004; Message: The server does not support SSL.", connectionStatusForPreferredMode.getMessage()); |
| 96 | + final AirbyteConnectionStatus connectionStatus = checkWithTunnel(db, SSL_MODE_REQUIRE); |
| 97 | + assertEquals(AirbyteConnectionStatus.Status.FAILED, connectionStatus.getStatus()); |
| 98 | + assertEquals("State code: 08004; Message: The server does not support SSL.", connectionStatus.getMessage()); |
61 | 99 |
|
62 | 100 | } finally {
|
63 | 101 | bastion.stopAndClose();
|
64 | 102 | }
|
65 | 103 | }
|
66 | 104 |
|
| 105 | + @Test |
| 106 | + void testSSlRequiredNoTunnelIfServerSupportSSL() throws Exception { |
| 107 | + |
| 108 | + try (PostgreSQLContainer<?> db = postgreSQLContainerWithSSL) { |
| 109 | + db.start(); |
| 110 | + |
| 111 | + final ImmutableMap<Object, Object> configBuilderWithSSLMode = getDatabaseConfigBuilderWithSSLMode(db, SSL_MODE_REQUIRE).build(); |
| 112 | + final JsonNode config = Jsons.jsonNode(configBuilderWithSSLMode); |
| 113 | + addNoTunnel((ObjectNode) config); |
| 114 | + final AirbyteConnectionStatus connectionStatus = source.check(config); |
| 115 | + assertEquals(AirbyteConnectionStatus.Status.SUCCEEDED, connectionStatus.getStatus()); |
| 116 | + } |
| 117 | + } |
| 118 | + |
| 119 | + @Test |
| 120 | + void testStrictSSLSecuredWithTunnel() throws Exception { |
| 121 | + |
| 122 | + try (PostgreSQLContainer<?> db = postgreSQLContainerWithSSL.withNetwork(network)) { |
| 123 | + |
| 124 | + bastion.initAndStartBastion(network); |
| 125 | + db.start(); |
| 126 | + |
| 127 | + final AirbyteConnectionStatus connectionStatus = checkWithTunnel(db, SSL_MODE_REQUIRE); |
| 128 | + assertEquals(AirbyteConnectionStatus.Status.SUCCEEDED, connectionStatus.getStatus()); |
| 129 | + } finally { |
| 130 | + bastion.stopAndClose(); |
| 131 | + } |
| 132 | + } |
| 133 | + |
67 | 134 | private ImmutableMap.Builder<Object, Object> getDatabaseConfigBuilderWithSSLMode(PostgreSQLContainer<?> db, String sslMode) {
|
68 | 135 | return ImmutableMap.builder()
|
69 | 136 | .put(JdbcUtils.HOST_KEY, Objects.requireNonNull(db.getContainerInfo()
|
@@ -94,53 +161,26 @@ private JsonNode getMockedSSLConfig(String sslMode) {
|
94 | 161 |
|
95 | 162 | @Test
|
96 | 163 | void testSslModesUnsecuredNoTunnel() throws Exception {
|
97 |
| - for (String sslMode : List.of("disable", "allow", "prefer")) { |
| 164 | + for (String sslMode : NON_STRICT_SSL_MODES) { |
98 | 165 | final JsonNode config = getMockedSSLConfig(sslMode);
|
99 |
| - ((ObjectNode) config).putIfAbsent("tunnel_method", Jsons.jsonNode(ImmutableMap.builder() |
100 |
| - .put("tunnel_method", "NO_TUNNEL") |
101 |
| - .build())); |
| 166 | + addNoTunnel((ObjectNode) config); |
102 | 167 |
|
103 |
| - final AirbyteConnectionStatus actual = new PostgresSourceStrictEncrypt().check(config); |
104 |
| - assertEquals(AirbyteConnectionStatus.Status.FAILED, actual.getStatus()); |
105 |
| - assertTrue(actual.getMessage().contains("Unsecured connection not allowed")); |
| 168 | + final AirbyteConnectionStatus connectionStatus = source.check(config); |
| 169 | + assertEquals(AirbyteConnectionStatus.Status.FAILED, connectionStatus.getStatus()); |
| 170 | + assertTrue(connectionStatus.getMessage().contains("Unsecured connection not allowed")); |
106 | 171 | }
|
107 | 172 | }
|
108 | 173 |
|
109 |
| - @Test |
110 |
| - void testSslModeRequiredNoTunnel() throws Exception { |
111 |
| - |
112 |
| - try (PostgreSQLContainer<?> db = |
113 |
| - new PostgreSQLContainer<>(DockerImageName.parse("marcosmarxm/postgres-ssl:dev").asCompatibleSubstituteFor("postgres")) |
114 |
| - .withCommand("postgres -c ssl=on -c ssl_cert_file=/var/lib/postgresql/server.crt -c ssl_key_file=/var/lib/postgresql/server.key")) { |
115 |
| - db.start(); |
116 |
| - |
117 |
| - final ImmutableMap<Object, Object> configBuilderWithSslModeRequire = getDatabaseConfigBuilderWithSSLMode(db, "require").build(); |
118 |
| - final JsonNode config = Jsons.jsonNode(configBuilderWithSslModeRequire); |
119 |
| - ((ObjectNode) config).putIfAbsent("tunnel_method", Jsons.jsonNode(ImmutableMap.builder() |
120 |
| - .put("tunnel_method", "NO_TUNNEL") |
121 |
| - .build())); |
122 |
| - final AirbyteConnectionStatus connectionStatusForPreferredMode = new PostgresSourceStrictEncrypt().check(config); |
123 |
| - assertEquals(AirbyteConnectionStatus.Status.SUCCEEDED, connectionStatusForPreferredMode.getStatus()); |
124 |
| - } |
| 174 | + private AirbyteConnectionStatus checkWithTunnel(PostgreSQLContainer<?> db, String sslmode) throws Exception { |
| 175 | + final ImmutableMap.Builder<Object, Object> configBuilderWithSSLMode = getDatabaseConfigBuilderWithSSLMode(db, sslmode); |
| 176 | + final JsonNode configWithSSLModeDisable = bastion.getTunnelConfig(SshTunnel.TunnelMethod.SSH_PASSWORD_AUTH, configBuilderWithSSLMode); |
| 177 | + return source.check(configWithSSLModeDisable); |
125 | 178 | }
|
126 | 179 |
|
127 |
| - @Test |
128 |
| - void testStrictSSLSecuredWithTunnel() throws Exception { |
129 |
| - try (PostgreSQLContainer<?> db = |
130 |
| - new PostgreSQLContainer<>(DockerImageName.parse("marcosmarxm/postgres-ssl:dev").asCompatibleSubstituteFor("postgres")) |
131 |
| - .withCommand("postgres -c ssl=on -c ssl_cert_file=/var/lib/postgresql/server.crt -c ssl_key_file=/var/lib/postgresql/server.key") |
132 |
| - .withNetwork(network)) { |
133 |
| - |
134 |
| - bastion.initAndStartBastion(network); |
135 |
| - db.start(); |
136 |
| - |
137 |
| - final ImmutableMap.Builder<Object, Object> builderWithSSLModePrefer = getDatabaseConfigBuilderWithSSLMode(db, "require"); |
138 |
| - final JsonNode configWithSslAndSsh = bastion.getTunnelConfig(SshTunnel.TunnelMethod.SSH_PASSWORD_AUTH, builderWithSSLModePrefer); |
139 |
| - final AirbyteConnectionStatus connectionStatusForPreferredMode = new PostgresSourceStrictEncrypt().check(configWithSslAndSsh); |
140 |
| - assertEquals(AirbyteConnectionStatus.Status.SUCCEEDED, connectionStatusForPreferredMode.getStatus()); |
141 |
| - } finally { |
142 |
| - bastion.stopAndClose(); |
143 |
| - } |
| 180 | + private static void addNoTunnel(ObjectNode config) { |
| 181 | + config.putIfAbsent("tunnel_method", Jsons.jsonNode(ImmutableMap.builder() |
| 182 | + .put("tunnel_method", "NO_TUNNEL") |
| 183 | + .build())); |
144 | 184 | }
|
145 | 185 |
|
146 | 186 | }
|
0 commit comments