Skip to content

Add SecurityPlans to Bolt layer #1611

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jan 30, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
import org.junit.jupiter.api.Test;
import org.neo4j.driver.internal.bolt.api.BoltServerAddress;
import org.neo4j.driver.internal.bolt.api.SecurityPlan;
import org.neo4j.driver.internal.bolt.api.SecurityPlans;
import org.neo4j.driver.internal.bolt.basicimpl.impl.NoopLoggingProvider;

class NettyChannelInitializerTest {
Expand All @@ -65,7 +66,7 @@ void shouldAddSslHandlerWhenRequiresEncryption() {

@Test
void shouldNotAddSslHandlerWhenDoesNotRequireEncryption() {
var security = SecurityPlan.INSECURE;
var security = SecurityPlans.unencrypted();
var initializer = newInitializer(security);

initializer.initChannel(channel);
Expand All @@ -90,7 +91,7 @@ void shouldAddSslHandlerWithHandshakeTimeout() {
void shouldUpdateChannelAttributes() {
var clock = mock(Clock.class);
when(clock.millis()).thenReturn(42L);
var security = SecurityPlan.INSECURE;
var security = SecurityPlans.unencrypted();
var initializer = newInitializer(security, Integer.MAX_VALUE, clock);

initializer.initChannel(channel);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
import org.neo4j.driver.internal.bolt.api.ResponseHandler;
import org.neo4j.driver.internal.bolt.api.RoutingContext;
import org.neo4j.driver.internal.bolt.api.SecurityPlan;
import org.neo4j.driver.internal.bolt.api.SecurityPlans;
import org.neo4j.driver.internal.bolt.api.exception.MinVersionAcquisitionException;
import org.neo4j.driver.internal.bolt.api.summary.ResetSummary;
import org.neo4j.driver.internal.bolt.api.values.Value;
Expand Down Expand Up @@ -104,7 +105,7 @@ class PooledBoltConnectionProviderTest {
final String userAgent = "agent";
final int timeout = 1000;

final SecurityPlan securityPlan = SecurityPlan.INSECURE;
final SecurityPlan securityPlan = SecurityPlans.unencrypted();
final DatabaseName databaseName = DatabaseNameUtil.defaultDatabase();
final AccessMode mode = AccessMode.WRITE;
final Set<String> bookmarks = Set.of("bookmark1", "bookmark2");
Expand Down Expand Up @@ -512,7 +513,7 @@ void shouldVerifyConnectivity() {
boltAgent,
userAgent,
timeout,
SecurityPlan.INSECURE,
SecurityPlans.unencrypted(),
AuthTokens.custom(Collections.emptyMap()))
.toCompletableFuture()
.join();
Expand Down Expand Up @@ -577,7 +578,7 @@ void shouldSupportMultiDb(BoltProtocolVersion boltProtocolVersion, boolean expec
boltAgent,
userAgent,
timeout,
SecurityPlan.INSECURE,
SecurityPlans.unencrypted(),
AuthTokens.custom(Collections.emptyMap()))
.toCompletableFuture()
.join();
Expand Down Expand Up @@ -649,7 +650,7 @@ void shouldSupportsSessionAuth(BoltProtocolVersion boltProtocolVersion, boolean
boltAgent,
userAgent,
timeout,
SecurityPlan.INSECURE,
SecurityPlans.unencrypted(),
AuthTokens.custom(Collections.emptyMap()))
.toCompletableFuture()
.join();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@
import org.neo4j.driver.internal.bolt.api.LoggingProvider;
import org.neo4j.driver.internal.bolt.api.ResponseHandler;
import org.neo4j.driver.internal.bolt.api.RoutingContext;
import org.neo4j.driver.internal.bolt.api.SecurityPlan;
import org.neo4j.driver.internal.bolt.api.SecurityPlans;
import org.neo4j.driver.internal.bolt.api.exception.BoltFailureException;
import org.neo4j.driver.internal.bolt.api.exception.BoltServiceUnavailableException;
import org.neo4j.driver.internal.bolt.api.exception.BoltUnsupportedFeatureException;
Expand All @@ -99,7 +99,7 @@ void shouldUseFirstRouterInTable() {

var actualComposition = rediscovery
.lookupClusterComposition(
SecurityPlan.INSECURE,
SecurityPlans.unencrypted(),
table,
connectionProviderGetter,
emptySet(),
Expand Down Expand Up @@ -131,7 +131,7 @@ void shouldSkipFailingRouters() {

var actualComposition = rediscovery
.lookupClusterComposition(
SecurityPlan.INSECURE,
SecurityPlans.unencrypted(),
table,
connectionProviderGetter,
emptySet(),
Expand Down Expand Up @@ -168,7 +168,7 @@ void shouldFailImmediatelyOnAuthError() {

Throwable error = assertThrows(CompletionException.class, () -> rediscovery
.lookupClusterComposition(
SecurityPlan.INSECURE,
SecurityPlans.unencrypted(),
table,
connectionProviderGetter,
emptySet(),
Expand Down Expand Up @@ -206,7 +206,7 @@ void shouldUseAnotherRouterOnAuthorizationExpiredException() {

var actualComposition = rediscovery
.lookupClusterComposition(
SecurityPlan.INSECURE,
SecurityPlans.unencrypted(),
table,
connectionProviderGetter,
emptySet(),
Expand Down Expand Up @@ -248,7 +248,7 @@ void shouldFailImmediatelyOnBookmarkErrors(String code) {

Throwable actualError = assertThrows(CompletionException.class, () -> rediscovery
.lookupClusterComposition(
SecurityPlan.INSECURE,
SecurityPlans.unencrypted(),
table,
connectionProviderGetter,
emptySet(),
Expand Down Expand Up @@ -277,7 +277,7 @@ void shouldFailImmediatelyOnClosedPoolError() {

Throwable actualError = assertThrows(CompletionException.class, () -> rediscovery
.lookupClusterComposition(
SecurityPlan.INSECURE,
SecurityPlans.unencrypted(),
table,
connectionProviderGetter,
emptySet(),
Expand Down Expand Up @@ -310,7 +310,7 @@ void shouldFallbackToInitialRouterWhenKnownRoutersFail() {

var actualComposition = rediscovery
.lookupClusterComposition(
SecurityPlan.INSECURE,
SecurityPlans.unencrypted(),
table,
connectionProviderGetter,
emptySet(),
Expand Down Expand Up @@ -346,7 +346,7 @@ void shouldResolveInitialRouterAddress() {

var actualComposition = rediscovery
.lookupClusterComposition(
SecurityPlan.INSECURE,
SecurityPlans.unencrypted(),
table,
connectionProviderGetter,
emptySet(),
Expand Down Expand Up @@ -384,7 +384,7 @@ void shouldResolveInitialRouterAddressUsingCustomResolver() {

var actualComposition = rediscovery
.lookupClusterComposition(
SecurityPlan.INSECURE,
SecurityPlans.unencrypted(),
table,
connectionProviderGetter,
emptySet(),
Expand Down Expand Up @@ -418,7 +418,7 @@ void shouldPropagateFailureWhenResolverFails() {

Throwable error = assertThrows(CompletionException.class, () -> rediscovery
.lookupClusterComposition(
SecurityPlan.INSECURE,
SecurityPlans.unencrypted(),
table,
connectionProviderGetter,
emptySet(),
Expand Down Expand Up @@ -450,7 +450,7 @@ void shouldRecordAllErrorsWhenNoRouterRespond() {

Throwable e = assertThrows(CompletionException.class, () -> rediscovery
.lookupClusterComposition(
SecurityPlan.INSECURE,
SecurityPlans.unencrypted(),
table,
connectionProviderGetter,
emptySet(),
Expand Down Expand Up @@ -486,7 +486,7 @@ void shouldUseInitialRouterAfterDiscoveryReturnsNoWriters() {

var composition2 = rediscovery
.lookupClusterComposition(
SecurityPlan.INSECURE,
SecurityPlans.unencrypted(),
table,
connectionProviderGetter,
emptySet(),
Expand Down Expand Up @@ -514,7 +514,7 @@ void shouldUseInitialRouterToStartWith() {

var composition = rediscovery
.lookupClusterComposition(
SecurityPlan.INSECURE,
SecurityPlans.unencrypted(),
table,
connectionProviderGetter,
Collections.emptySet(),
Expand Down Expand Up @@ -545,7 +545,7 @@ void shouldUseKnownRoutersWhenInitialRouterFails() {

var composition = rediscovery
.lookupClusterComposition(
SecurityPlan.INSECURE,
SecurityPlans.unencrypted(),
table,
connectionProviderGetter,
Collections.emptySet(),
Expand Down Expand Up @@ -582,7 +582,7 @@ void shouldNotLogWhenSingleRetryAttemptFails() {

Throwable e = assertThrows(CompletionException.class, () -> rediscovery
.lookupClusterComposition(
SecurityPlan.INSECURE,
SecurityPlans.unencrypted(),
table,
connectionProviderGetter,
Collections.emptySet(),
Expand Down Expand Up @@ -639,7 +639,7 @@ void shouldFailImmediatelyOnAuthTokenManagerExecutionException() {

Throwable actualException = assertThrows(CompletionException.class, () -> rediscovery
.lookupClusterComposition(
SecurityPlan.INSECURE,
SecurityPlans.unencrypted(),
table,
connectionProviderGetter,
Collections.emptySet(),
Expand Down Expand Up @@ -668,7 +668,7 @@ void shouldFailImmediatelyOnUnsupportedFeatureException() {

Throwable actualException = assertThrows(CompletionException.class, () -> rediscovery
.lookupClusterComposition(
SecurityPlan.INSECURE,
SecurityPlans.unencrypted(),
table,
connectionProviderGetter,
Collections.emptySet(),
Expand Down Expand Up @@ -718,7 +718,7 @@ void shouldLogScopedIPV6AddressWithStringFormattingLogger() throws UnknownHostEx
// WHEN & THEN
Throwable e = assertThrows(CompletionException.class, () -> rediscovery
.lookupClusterComposition(
SecurityPlan.INSECURE,
SecurityPlans.unencrypted(),
table,
connectionProviderGetter,
Collections.emptySet(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@
import org.neo4j.driver.internal.bolt.api.ClusterComposition;
import org.neo4j.driver.internal.bolt.api.DatabaseName;
import org.neo4j.driver.internal.bolt.api.SecurityPlan;
import org.neo4j.driver.internal.bolt.api.SecurityPlans;
import org.neo4j.driver.internal.bolt.api.exception.BoltServiceUnavailableException;
import org.neo4j.driver.internal.bolt.routedimpl.ClusterCompositionLookupResult;
import org.neo4j.driver.internal.bolt.routedimpl.Rediscovery;
Expand Down Expand Up @@ -120,7 +121,7 @@ void acquireShouldUpdateRoutingTableWhenKnownRoutingTableIsStale() {

var handler = newRoutingTableHandler(routingTable, rediscovery, connectionPool);
assertNotNull(handler.ensureRoutingTable(
SecurityPlan.INSECURE,
SecurityPlans.unencrypted(),
READ,
Collections.emptySet(),
() -> CompletableFuture.completedStage(AuthTokens.custom(Collections.emptyMap())),
Expand Down Expand Up @@ -209,7 +210,7 @@ public Optional<RoutingTableHandler> getRoutingTableHandler(DatabaseName databas
newRoutingTableHandler(routingTable, rediscovery, connectionPool, registry, addressesToRetainRef::set);

var actual = handler.ensureRoutingTable(
SecurityPlan.INSECURE,
SecurityPlans.unencrypted(),
READ,
Collections.emptySet(),
() -> CompletableFuture.completedStage(AuthTokens.custom(Collections.emptyMap())),
Expand All @@ -236,7 +237,7 @@ void shouldRemoveRoutingTableHandlerIfFailedToLookup() {

var handler = newRoutingTableHandler(routingTable, rediscovery, connectionPool, registry);
assertThrows(RuntimeException.class, () -> handler.ensureRoutingTable(
SecurityPlan.INSECURE,
SecurityPlans.unencrypted(),
READ,
Collections.emptySet(),
() -> CompletableFuture.completedStage(AuthTokens.custom(Collections.emptyMap())),
Expand Down Expand Up @@ -277,7 +278,7 @@ private void testRediscoveryWhenStale(AccessMode mode) {

var handler = newRoutingTableHandler(routingTable, rediscovery, connectionProviderGetter);
var actual = handler.ensureRoutingTable(
SecurityPlan.INSECURE,
SecurityPlans.unencrypted(),
mode,
Collections.emptySet(),
() -> CompletableFuture.completedStage(AuthTokens.custom(Collections.emptyMap())),
Expand Down Expand Up @@ -322,7 +323,7 @@ private void testNoRediscoveryWhenNotStale(AccessMode staleMode, AccessMode notS
var handler = newRoutingTableHandler(routingTable, rediscovery, connectionProviderGetter);

assertNotNull(handler.ensureRoutingTable(
SecurityPlan.INSECURE,
SecurityPlans.unencrypted(),
notStaleMode,
Collections.emptySet(),
() -> CompletableFuture.completedStage(AuthTokens.custom(Collections.emptyMap())),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@
import org.neo4j.driver.internal.bolt.api.BoltProtocolVersion;
import org.neo4j.driver.internal.bolt.api.BoltServerAddress;
import org.neo4j.driver.internal.bolt.api.DatabaseName;
import org.neo4j.driver.internal.bolt.api.SecurityPlan;
import org.neo4j.driver.internal.bolt.api.SecurityPlans;
import org.neo4j.driver.internal.bolt.routedimpl.Rediscovery;
import org.neo4j.driver.internal.bolt.routedimpl.RoutingTable;
import org.neo4j.driver.internal.bolt.routedimpl.impl.NoopLoggingProvider;
Expand Down Expand Up @@ -100,7 +100,7 @@ void shouldCreateRoutingTableHandlerIfAbsentWhenFreshRoutingTable(String databas
// When
var database = database(databaseName);
routingTables.ensureRoutingTable(
SecurityPlan.INSECURE,
SecurityPlans.unencrypted(),
CompletableFuture.completedFuture(database),
AccessMode.READ,
Collections.emptySet(),
Expand Down Expand Up @@ -131,7 +131,7 @@ void shouldReturnExistingRoutingTableHandlerWhenFreshRoutingTable(String databas
// When
var actual = routingTables
.ensureRoutingTable(
SecurityPlan.INSECURE,
SecurityPlans.unencrypted(),
CompletableFuture.completedFuture(database),
AccessMode.READ,
Collections.emptySet(),
Expand All @@ -145,7 +145,7 @@ void shouldReturnExistingRoutingTableHandlerWhenFreshRoutingTable(String databas
// Then it is the one we put in map that is picked up.
verify(handler)
.ensureRoutingTable(
SecurityPlan.INSECURE,
SecurityPlans.unencrypted(),
AccessMode.READ,
Collections.emptySet(),
authStageSupplier,
Expand All @@ -169,7 +169,7 @@ void shouldReturnFreshRoutingTable(AccessMode mode) {
// When
routingTables
.ensureRoutingTable(
SecurityPlan.INSECURE,
SecurityPlans.unencrypted(),
CompletableFuture.completedFuture(defaultDatabase()),
mode,
Collections.emptySet(),
Expand All @@ -183,7 +183,7 @@ void shouldReturnFreshRoutingTable(AccessMode mode) {
// Then
verify(handler)
.ensureRoutingTable(
SecurityPlan.INSECURE,
SecurityPlans.unencrypted(),
mode,
Collections.emptySet(),
authStageSupplier,
Expand Down
8 changes: 8 additions & 0 deletions bolt-api/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,14 @@
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk18on</artifactId>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcpkix-jdk18on</artifactId>
</dependency>
</dependencies>

<build>
Expand Down
1 change: 1 addition & 0 deletions bolt-api/src/main/java/module-info.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,5 @@
exports org.neo4j.driver.internal.bolt.api.exception;
exports org.neo4j.driver.internal.bolt.api.summary;
exports org.neo4j.driver.internal.bolt.api.values;
exports org.neo4j.driver.internal.bolt.api.ssl;
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
* A SecurityPlan consists of encryption and trust details.
*/
public interface SecurityPlan {
SecurityPlan INSECURE = new SecurityPlanImpl(false, false, null, false);

@SuppressWarnings("SameReturnValue")
boolean requiresEncryption();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
/**
* A SecurityPlan consists of encryption and trust details.
*/
public record SecurityPlanImpl(
record SecurityPlanImpl(
boolean requiresEncryption,
boolean requiresClientAuth,
SSLContext sslContext,
Expand Down
Loading