Skip to content

Commit

Permalink
feat: add support for custom certificate path
Browse files Browse the repository at this point in the history
This is an extra attribute that can now be added to the connection
JSON information.

Fixes GoogleCloudPlatform#1794
  • Loading branch information
fbiville committed Sep 30, 2024
1 parent 7294b49 commit 071c64d
Show file tree
Hide file tree
Showing 10 changed files with 77 additions and 25 deletions.
4 changes: 4 additions & 0 deletions v2/googlecloud-to-neo4j/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@
<artifactId>common</artifactId>
<version>${project.version}</version>
</dependency>
<dependency><!-- required for custom certificate support (gs://) -->
<groupId>com.google.cloud</groupId>
<artifactId>google-cloud-nio</artifactId>
</dependency>
<dependency>
<groupId>org.apache.beam</groupId>
<artifactId>beam-sdks-java-extensions-sql</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,10 @@ public Neo4jConnection(ConnectionParams settings, String templateVersion) {
GraphDatabase.driver(
settings.getServerUrl(),
settings.asAuthToken(),
Config.builder().withUserAgent(Neo4jTelemetry.userAgent(templateVersion)).build()));
Config.builder()
.withTrustStrategy(settings.asTrustStrategy())
.withUserAgent(Neo4jTelemetry.userAgent(templateVersion))
.build()));
}

@VisibleForTesting
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,10 @@ class BasicConnectionParams extends ConnectionParams {
public BasicConnectionParams(
@JsonProperty("server_url") String serverUrl,
@JsonProperty("database") String database,
@JsonProperty("custom_certificate_path") String customCertificatePath,
@JsonProperty("username") String username,
@JsonProperty("pwd") String password) {
super(serverUrl, database);
super(serverUrl, database, customCertificatePath);
this.username = username;
this.password = password;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,9 @@ class BearerConnectionParams extends ConnectionParams {
public BearerConnectionParams(
@JsonProperty("server_url") String serverUrl,
@JsonProperty("database") String database,
@JsonProperty("custom_certificate_path") String customCertificatePath,
@JsonProperty("token") String token) {
super(serverUrl, database);
super(serverUrl, database, customCertificatePath);
this.token = token;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,12 @@
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.JsonTypeInfo.Id;
import java.io.Serializable;
import java.net.URI;
import java.nio.file.Paths;
import java.util.Objects;
import org.neo4j.driver.AuthToken;
import org.neo4j.driver.Config;
import org.neo4j.driver.Config.TrustStrategy;

@JsonTypeInfo(use = Id.NAME, property = "auth_type", defaultImpl = BasicConnectionParams.class)
@JsonSubTypes({
Expand All @@ -34,10 +38,12 @@ public abstract class ConnectionParams implements Serializable {

private final String serverUrl;
private final String database;
private final String customCertificatePath;

public ConnectionParams(String serverUrl, String database) {
public ConnectionParams(String serverUrl, String database, String customCertificatePath) {
this.serverUrl = serverUrl;
this.database = database == null ? "neo4j" : database;
this.customCertificatePath = customCertificatePath;
}

public String getServerUrl() {
Expand All @@ -48,23 +54,36 @@ public String getDatabase() {
return database;
}

public String getCustomCertificatePath() {
return customCertificatePath;
}

public abstract AuthToken asAuthToken();

public TrustStrategy asTrustStrategy() {
if (customCertificatePath == null) {
return Config.defaultConfig().trustStrategy();
}
return TrustStrategy.trustCustomCertificateSignedBy(
Paths.get(URI.create(customCertificatePath)).toFile());
}

@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
if (!(o instanceof ConnectionParams)) {
return false;
}

ConnectionParams that = (ConnectionParams) o;
return Objects.equals(serverUrl, that.serverUrl) && Objects.equals(database, that.database);
return Objects.equals(serverUrl, that.serverUrl)
&& Objects.equals(database, that.database)
&& Objects.equals(customCertificatePath, that.customCertificatePath);
}

@Override
public int hashCode() {
return Objects.hash(serverUrl, database);
return Objects.hash(serverUrl, database, customCertificatePath);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,13 @@ class CustomConnectionParams extends ConnectionParams {
public CustomConnectionParams(
@JsonProperty("server_url") String serverUrl,
@JsonProperty("database") String database,
@JsonProperty("custom_certificate_path") String customCertificatePath,
@JsonProperty("principal") String principal,
@JsonProperty("credentials") String credentials,
@JsonProperty("realm") String realm,
@JsonProperty("scheme") String scheme,
@JsonProperty("parameters") Map<String, Object> parameters) {
super(serverUrl, database);
super(serverUrl, database, customCertificatePath);
this.principal = principal;
this.credentials = credentials;
this.realm = realm;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,9 @@ class KerberosConnectionParams extends ConnectionParams {
public KerberosConnectionParams(
@JsonProperty("server_url") String serverUrl,
@JsonProperty("database") String database,
@JsonProperty("custom_certificate_path") String customCertificatePath,
@JsonProperty("ticket") String ticket) {
super(serverUrl, database);
super(serverUrl, database, customCertificatePath);
this.ticket = ticket;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,10 @@ class NoAuthConnectionParams extends ConnectionParams {

@JsonCreator
public NoAuthConnectionParams(
@JsonProperty("server_url") String serverUrl, @JsonProperty("database") String database) {
super(serverUrl, database);
@JsonProperty("server_url") String serverUrl,
@JsonProperty("database") String database,
@JsonProperty("custom_certificate_path") String customCertificatePath) {
super(serverUrl, database, customCertificatePath);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@
"default": "neo4j",
"minLength": 1
},
"custom_certificate_path": {
"description": "Path of the trusted certificate required to establish connections to Neo4j",
"type": "string",
"minLength": 1
},
"auth_type": {
"description": "Authentication type",
"type": "string",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,19 +39,22 @@ public void parsesMinimalBasicAuthInformation() throws Exception {

assertThat(connectionParams).isInstanceOf(BasicConnectionParams.class);
assertThat(connectionParams)
.isEqualTo(new BasicConnectionParams("bolt://example.com", null, "neo4j", "password"));
.isEqualTo(
new BasicConnectionParams("bolt://example.com", null, null, "neo4j", "password"));
}

@Test
public void parsesFullBasicAuthInformation() throws Exception {
ConnectionParams connectionParams =
Json.map(
json(
"{\"auth_type\": \"basic\", \"server_url\": \"bolt://example.com\", \"database\": \"db\", \"username\": \"neo4j\", \"pwd\": \"password\"}"),
"{\"auth_type\": \"basic\", \"server_url\": \"bolt://example.com\", \"custom_certificate_path\": \"gs://example.com/my/cert\", \"database\": \"db\", \"username\": \"neo4j\", \"pwd\": \"password\"}"),
ConnectionParams.class);

assertThat(connectionParams)
.isEqualTo(new BasicConnectionParams("bolt://example.com", "db", "neo4j", "password"));
.isEqualTo(
new BasicConnectionParams(
"bolt://example.com", "db", "gs://example.com/my/cert", "neo4j", "password"));
}

@Test
Expand All @@ -62,18 +65,21 @@ public void parsesMinimalNoAuthInformation() throws Exception {
ConnectionParams.class);

assertThat(connectionParams).isInstanceOf(NoAuthConnectionParams.class);
assertThat(connectionParams).isEqualTo(new NoAuthConnectionParams("bolt://example.com", null));
assertThat(connectionParams)
.isEqualTo(new NoAuthConnectionParams("bolt://example.com", null, null));
}

@Test
public void parsesFullNoAuthInformation() throws Exception {
ConnectionParams connectionParams =
Json.map(
json(
"{\"auth_type\": \"none\", \"server_url\": \"bolt://example.com\", \"database\": \"db\"}"),
"{\"auth_type\": \"none\", \"server_url\": \"bolt://example.com\", \"database\": \"db\", \"custom_certificate_path\": \"gs://example.com/my/cert\"}"),
ConnectionParams.class);

assertThat(connectionParams).isEqualTo(new NoAuthConnectionParams("bolt://example.com", "db"));
assertThat(connectionParams)
.isEqualTo(
new NoAuthConnectionParams("bolt://example.com", "db", "gs://example.com/my/cert"));
}

@Test
Expand All @@ -87,20 +93,25 @@ public void parsesMinimalKerberosInformation() throws Exception {
assertThat(connectionParams).isInstanceOf(KerberosConnectionParams.class);
assertThat(connectionParams)
.isEqualTo(
new KerberosConnectionParams("bolt://example.com", null, "dGhpcyBpcyBhIHRpY2tldA=="));
new KerberosConnectionParams(
"bolt://example.com", null, null, "dGhpcyBpcyBhIHRpY2tldA=="));
}

@Test
public void parsesFullKerberosInformation() throws Exception {
ConnectionParams connectionParams =
Json.map(
json(
"{\"auth_type\": \"kerberos\", \"server_url\": \"bolt://example.com\", \"database\": \"db\", \"ticket\": \"dGhpcyBpcyBhIHRpY2tldA==\"}"),
"{\"auth_type\": \"kerberos\", \"server_url\": \"bolt://example.com\", \"database\": \"db\", \"custom_certificate_path\": \"gs://example.com/my/cert\", \"ticket\": \"dGhpcyBpcyBhIHRpY2tldA==\"}"),
ConnectionParams.class);

assertThat(connectionParams)
.isEqualTo(
new KerberosConnectionParams("bolt://example.com", "db", "dGhpcyBpcyBhIHRpY2tldA=="));
new KerberosConnectionParams(
"bolt://example.com",
"db",
"gs://example.com/my/cert",
"dGhpcyBpcyBhIHRpY2tldA=="));
}

@Test
Expand All @@ -113,19 +124,21 @@ public void parsesMinimalBearerInformation() throws Exception {

assertThat(connectionParams).isInstanceOf(BearerConnectionParams.class);
assertThat(connectionParams)
.isEqualTo(new BearerConnectionParams("bolt://example.com", null, "a-token"));
.isEqualTo(new BearerConnectionParams("bolt://example.com", null, null, "a-token"));
}

@Test
public void parsesFullBearerInformation() throws Exception {
ConnectionParams connectionParams =
Json.map(
json(
"{\"auth_type\": \"bearer\", \"server_url\": \"bolt://example.com\", \"database\": \"db\", \"token\": \"a-token\"}"),
"{\"auth_type\": \"bearer\", \"server_url\": \"bolt://example.com\", \"database\": \"db\", \"custom_certificate_path\": \"gs://example.com/my/cert\", \"token\": \"a-token\"}"),
ConnectionParams.class);

assertThat(connectionParams)
.isEqualTo(new BearerConnectionParams("bolt://example.com", "db", "a-token"));
.isEqualTo(
new BearerConnectionParams(
"bolt://example.com", "db", "gs://example.com/my/cert", "a-token"));
}

@Test
Expand All @@ -142,6 +155,7 @@ public void parsesMinimalCustomInformation() throws Exception {
new CustomConnectionParams(
"bolt://example.com",
null,
null,
"a-principal",
"some-credentials",
null,
Expand All @@ -154,14 +168,15 @@ public void parsesFullCustomInformation() throws Exception {
ConnectionParams connectionParams =
Json.map(
json(
"{\"auth_type\": \"custom\", \"server_url\": \"bolt://example.com\", \"database\": \"db\", \"principal\": \"a-principal\", \"credentials\": \"some-credentials\", \"realm\": \"a-realm\", \"scheme\": \"a-scheme\", \"parameters\": {\"foo\": \"bar\", \"baz\": true}}"),
"{\"auth_type\": \"custom\", \"server_url\": \"bolt://example.com\", \"database\": \"db\", \"custom_certificate_path\": \"gs://example.com/my/cert\", \"principal\": \"a-principal\", \"credentials\": \"some-credentials\", \"realm\": \"a-realm\", \"scheme\": \"a-scheme\", \"parameters\": {\"foo\": \"bar\", \"baz\": true}}"),
ConnectionParams.class);

assertThat(connectionParams)
.isEqualTo(
new CustomConnectionParams(
"bolt://example.com",
"db",
"gs://example.com/my/cert",
"a-principal",
"some-credentials",
"a-realm",
Expand Down

0 comments on commit 071c64d

Please sign in to comment.