Skip to content

Commit 1d1c491

Browse files
committed
Made driver throw SQLSTATE 28000 for invalid username or password (#7)
* Made driver throw SQLSTATE 28000 for invalid username or password Signed-off-by: Guian Gumpac <[email protected]> * Made SQLSTATE string a constant and added a separate catch block for HTTPException Signed-off-by: Guian Gumpac <[email protected]> * Changed constant name to follow naming convention Signed-off-by: Guian Gumpac <[email protected]> * Added 08001 SQLSTATE to catch connection errors Signed-off-by: Guian Gumpac <[email protected]> * Reverted 08001 change Signed-off-by: Guian Gumpac <[email protected]> --------- Signed-off-by: Guian Gumpac <[email protected]>
1 parent 5aa8c12 commit 1d1c491

File tree

2 files changed

+47
-1
lines changed

2 files changed

+47
-1
lines changed

src/main/java/org/opensearch/jdbc/ConnectionImpl.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import org.opensearch.jdbc.protocol.Protocol;
1818
import org.opensearch.jdbc.protocol.ProtocolFactory;
1919
import org.opensearch.jdbc.protocol.exceptions.ResponseException;
20+
import org.opensearch.jdbc.protocol.http.HttpException;
2021
import org.opensearch.jdbc.protocol.http.JsonHttpProtocolFactory;
2122
import org.opensearch.jdbc.transport.Transport;
2223
import org.opensearch.jdbc.transport.TransportException;
@@ -55,6 +56,9 @@ public class ConnectionImpl implements OpenSearchConnection, JdbcWrapper, Loggin
5556
private Transport transport;
5657
private Protocol protocol;
5758
private ClusterMetadata clusterMetadata;
59+
// https://docs.oracle.com/cd/E15817_01/appdev.111/b31228/appd.htm
60+
// 28000 is the SQLSTATE for invalid authorization specification
61+
private final String INCORRECT_CREDENTIALS_SQLSTATE = "28000";
5862

5963
public ConnectionImpl(ConnectionConfig connectionConfig, Logger log) throws SQLException {
6064
this(connectionConfig, ApacheHttpTransportFactory.INSTANCE, JsonHttpProtocolFactory.INSTANCE, log);
@@ -83,8 +87,15 @@ log, new SQLNonTransientException("Could not initialize transport for the connec
8387
ConnectionResponse connectionResponse = this.protocol.connect(connectionConfig.getLoginTimeout() * 1000);
8488
this.clusterMetadata = connectionResponse.getClusterMetadata();
8589
this.open = true;
90+
} catch (HttpException ex) {
91+
if (ex.getStatusCode() == 401) {
92+
logAndThrowSQLException(log, new SQLException("Connection error " + ex.getMessage(),
93+
INCORRECT_CREDENTIALS_SQLSTATE, ex));
94+
} else {
95+
logAndThrowSQLException(log, new SQLException("Connection error " + ex.getMessage(), ex));
96+
}
8697
} catch (ResponseException | IOException ex) {
87-
logAndThrowSQLException(log, new SQLException("Connection error "+ex.getMessage(), ex));
98+
logAndThrowSQLException(log, new SQLException("Connection error " + ex.getMessage(), ex));
8899
}
89100

90101
}

src/test/java/org/opensearch/jdbc/ConnectionTests.java

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,17 @@
77
package org.opensearch.jdbc;
88

99
import org.opensearch.jdbc.config.AuthConnectionProperty;
10+
import org.opensearch.jdbc.config.ConnectionConfig;
1011
import org.opensearch.jdbc.config.ConnectionPropertyException;
1112
import org.opensearch.jdbc.config.PasswordConnectionProperty;
1213
import org.opensearch.jdbc.config.RegionConnectionProperty;
1314
import org.opensearch.jdbc.config.RequestCompressionConnectionProperty;
1415
import org.opensearch.jdbc.config.UserConnectionProperty;
16+
import org.opensearch.jdbc.logging.NoOpLogger;
17+
import org.opensearch.jdbc.protocol.Protocol;
18+
import org.opensearch.jdbc.protocol.ProtocolFactory;
19+
import org.opensearch.jdbc.protocol.exceptions.ResponseException;
20+
import org.opensearch.jdbc.protocol.http.HttpException;
1521
import org.opensearch.jdbc.protocol.http.JsonHttpProtocol;
1622
import org.opensearch.jdbc.test.PerTestWireMockServerExtension;
1723
import org.opensearch.jdbc.test.WireMockServerHelpers;
@@ -25,6 +31,8 @@
2531
import org.junit.jupiter.api.extension.ExtendWith;
2632
import org.junit.jupiter.params.ParameterizedTest;
2733
import org.junit.jupiter.params.provider.ValueSource;
34+
import org.opensearch.jdbc.transport.Transport;
35+
import org.opensearch.jdbc.transport.TransportFactory;
2836

2937
import java.io.IOException;
3038
import java.sql.Connection;
@@ -34,7 +42,12 @@
3442

3543
import static com.github.tomakehurst.wiremock.client.WireMock.*;
3644
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
45+
import static org.junit.jupiter.api.Assertions.assertEquals;
3746
import static org.junit.jupiter.api.Assertions.assertTrue;
47+
import static org.mockito.ArgumentMatchers.any;
48+
import static org.mockito.ArgumentMatchers.anyInt;
49+
import static org.mockito.Mockito.mock;
50+
import static org.mockito.Mockito.when;
3851

3952
@ExtendWith(PerTestWireMockServerExtension.class)
4053
class ConnectionTests implements WireMockServerHelpers {
@@ -117,6 +130,28 @@ void testConnectDefaultAuthWithUsername(final WireMockServer mockServer) throws
117130
con.close();
118131
}
119132

133+
@Test
134+
void testConnectInvalidUsernameOrPassword(final WireMockServer mockServer) throws ResponseException, IOException {
135+
TransportFactory mockTransportFactory = mock(TransportFactory.class);
136+
when(mockTransportFactory.getTransport(any(), any(), any()))
137+
.thenReturn(mock(Transport.class));
138+
ProtocolFactory mockProtocolFactory = mock(ProtocolFactory.class);
139+
Protocol mockProtocol = mock(Protocol.class);
140+
141+
when(mockProtocolFactory.getProtocol(any(ConnectionConfig.class), any(Transport.class)))
142+
.thenReturn(mockProtocol);
143+
when(mockProtocol.connect(anyInt())).thenThrow(new HttpException(401, "Unauthorized"));
144+
145+
SQLException sqlException = Assertions.assertThrows(SQLException.class,
146+
() -> new ConnectionImpl(mock(ConnectionConfig.class),
147+
mockTransportFactory, mockProtocolFactory, NoOpLogger.INSTANCE));
148+
149+
// 28000 is the SQLSTATE for invalid authorization specification
150+
// https://docs.oracle.com/cd/E15817_01/appdev.111/b31228/appd.htm
151+
assertEquals(sqlException.getSQLState(), "28000");
152+
assertEquals(sqlException.getMessage(), "Connection error Unauthorized");
153+
}
154+
120155
@Test
121156
void testConnectWithRequestCompression(final WireMockServer mockServer) throws SQLException {
122157
// Respond only if request mentions it accepts gzip

0 commit comments

Comments
 (0)