From b6ff150cfe01c8da387e7b95480437f8caf68181 Mon Sep 17 00:00:00 2001 From: Stefan Plantikow Date: Wed, 7 Sep 2016 12:12:47 +0200 Subject: [PATCH] Add testing of built in procedure support to ha and core|edge edition modules --- .../impl/factory/CommunityEditionModule.java | 5 +- .../kernel/impl/factory/DataSourceModule.java | 2 +- .../kernel/impl/factory/EditionModule.java | 2 +- enterprise/core-edge/pom.xml | 6 ++ .../core/EnterpriseCoreEditionModule.java | 4 +- .../edge/EnterpriseEdgeEditionModule.java | 8 +- .../scenarios/ClusterFormationIT.java | 41 ++++++++ .../factory/HighlyAvailableEditionModule.java | 5 +- .../api/security/EnterpriseAuthSubject.java | 93 +++++++++++++++++++ .../enterprise/EnterpriseEditionModule.java | 9 +- .../java/org/neo4j/ha/HAClusterStartupIT.java | 41 ++++++++ 11 files changed, 203 insertions(+), 13 deletions(-) diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/factory/CommunityEditionModule.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/factory/CommunityEditionModule.java index 56baa284e1990..1c559b0a5f600 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/factory/CommunityEditionModule.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/factory/CommunityEditionModule.java @@ -256,9 +256,10 @@ protected void registerRecovery( final DatabaseInfo databaseInfo, LifeSupport li } @Override - public void registerProcedures( Procedures procedures ) throws KernelException + public void setupProcedures( Procedures procedures ) throws KernelException { - procedures.registerProcedure( BuiltInProcedures.class ); + // If you change this, don't forget to update the HA and Core|Edge editions, too + procedures.registerProcedure( org.neo4j.kernel.builtinprocs.BuiltInProcedures.class ); registerProceduresFromProvider( "auth-procedures-provider", procedures ); } diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/factory/DataSourceModule.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/factory/DataSourceModule.java index 6ba8c75a6a0e1..c593feeadfe34 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/factory/DataSourceModule.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/factory/DataSourceModule.java @@ -411,7 +411,7 @@ private Procedures setupProcedures( PlatformModule platform, EditionModule editi // Edition procedures try { - editionModule.registerProcedures( procedures ); + editionModule.setupProcedures( procedures ); } catch ( KernelException e ) { diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/factory/EditionModule.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/factory/EditionModule.java index d527ec80a43a5..ba59cd37ead51 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/factory/EditionModule.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/factory/EditionModule.java @@ -68,7 +68,7 @@ */ public abstract class EditionModule { - public abstract void registerProcedures( Procedures procedures ) throws KernelException; + public abstract void setupProcedures( Procedures procedures ) throws KernelException; protected Log authManagerLog() { diff --git a/enterprise/core-edge/pom.xml b/enterprise/core-edge/pom.xml index 8f5bfc735f8b5..7948d187434ae 100644 --- a/enterprise/core-edge/pom.xml +++ b/enterprise/core-edge/pom.xml @@ -109,6 +109,12 @@ test-jar test + + org.neo4j + neo4j-cypher + ${project.version} + test + org.neo4j diff --git a/enterprise/core-edge/src/main/java/org/neo4j/coreedge/core/EnterpriseCoreEditionModule.java b/enterprise/core-edge/src/main/java/org/neo4j/coreedge/core/EnterpriseCoreEditionModule.java index dd84dd75387a3..87b155400832f 100644 --- a/enterprise/core-edge/src/main/java/org/neo4j/coreedge/core/EnterpriseCoreEditionModule.java +++ b/enterprise/core-edge/src/main/java/org/neo4j/coreedge/core/EnterpriseCoreEditionModule.java @@ -110,7 +110,7 @@ public enum RaftLogImplementation } @Override - public void registerProcedures( Procedures procedures ) throws KernelException + public void setupProcedures( Procedures procedures ) throws KernelException { try { @@ -118,6 +118,8 @@ public void registerProcedures( Procedures procedures ) throws KernelException registerProceduresFromProvider( "auth-procedures-provider", procedures ); registerProceduresFromProvider( "enterprise-auth-procedures-provider", procedures ); + procedures.registerProcedure( org.neo4j.kernel.builtinprocs.BuiltInProcedures.class ); + procedures.registerProcedure( org.neo4j.kernel.enterprise.builtinprocs.BuiltInProcedures.class ); procedures.register( new DiscoverEndpointAcquisitionServersProcedure( topologyService, logProvider ) ); procedures.register( new AcquireEndpointsProcedure( topologyService, consensusModule.raftMachine(), logProvider ) ); procedures.register( new ClusterOverviewProcedure( topologyService, consensusModule.raftMachine(), logProvider ) ); diff --git a/enterprise/core-edge/src/main/java/org/neo4j/coreedge/edge/EnterpriseEdgeEditionModule.java b/enterprise/core-edge/src/main/java/org/neo4j/coreedge/edge/EnterpriseEdgeEditionModule.java index 3b519021d9392..8ac19522c6261 100644 --- a/enterprise/core-edge/src/main/java/org/neo4j/coreedge/edge/EnterpriseEdgeEditionModule.java +++ b/enterprise/core-edge/src/main/java/org/neo4j/coreedge/edge/EnterpriseEdgeEditionModule.java @@ -20,7 +20,6 @@ package org.neo4j.coreedge.edge; import java.io.File; -import java.io.IOException; import java.time.Clock; import java.util.concurrent.TimeUnit; import java.util.function.Supplier; @@ -52,7 +51,6 @@ import org.neo4j.kernel.DatabaseAvailability; import org.neo4j.kernel.api.bolt.BoltConnectionTracker; import org.neo4j.kernel.api.exceptions.KernelException; -import org.neo4j.kernel.api.exceptions.ProcedureException; import org.neo4j.kernel.configuration.Config; import org.neo4j.kernel.impl.api.CommitProcessFactory; import org.neo4j.kernel.impl.api.ReadOnlyTransactionCommitProcess; @@ -85,6 +83,7 @@ import org.neo4j.kernel.internal.DefaultKernelData; import org.neo4j.kernel.lifecycle.LifeSupport; import org.neo4j.kernel.lifecycle.LifecycleStatus; +import org.neo4j.logging.Log; import org.neo4j.logging.LogProvider; import org.neo4j.storageengine.api.StorageEngine; import org.neo4j.time.Clocks; @@ -103,9 +102,12 @@ public class EnterpriseEdgeEditionModule extends EditionModule private SecurityLog securityLog; @Override - public void registerProcedures( Procedures procedures ) throws KernelException + public void setupProcedures( Procedures procedures ) throws KernelException { + procedures.registerProcedure( org.neo4j.kernel.builtinprocs.BuiltInProcedures.class ); + procedures.registerProcedure( org.neo4j.kernel.enterprise.builtinprocs.BuiltInProcedures.class ); procedures.register( new EdgeRoleProcedure() ); + procedures.registerComponent( SecurityLog.class, (ctx) -> securityLog ); registerProceduresFromProvider( "auth-procedures-provider" , procedures ); registerProceduresFromProvider( "enterprise-auth-procedures-provider", procedures ); diff --git a/enterprise/core-edge/src/test/java/org/neo4j/coreedge/scenarios/ClusterFormationIT.java b/enterprise/core-edge/src/test/java/org/neo4j/coreedge/scenarios/ClusterFormationIT.java index 74c80a9369f4d..af41751ca4255 100644 --- a/enterprise/core-edge/src/test/java/org/neo4j/coreedge/scenarios/ClusterFormationIT.java +++ b/enterprise/core-edge/src/test/java/org/neo4j/coreedge/scenarios/ClusterFormationIT.java @@ -23,16 +23,25 @@ import org.junit.Rule; import org.junit.Test; +import java.util.Collections; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; +import java.util.stream.Stream; import org.neo4j.coreedge.core.CoreGraphDatabase; import org.neo4j.coreedge.core.consensus.roles.Role; import org.neo4j.coreedge.discovery.Cluster; +import org.neo4j.coreedge.discovery.CoreClusterMember; +import org.neo4j.coreedge.discovery.EdgeClusterMember; +import org.neo4j.graphdb.Result; import org.neo4j.graphdb.Transaction; +import org.neo4j.kernel.api.KernelTransaction; +import org.neo4j.kernel.enterprise.api.security.EnterpriseAuthSubject; +import org.neo4j.kernel.impl.coreapi.InternalTransaction; import org.neo4j.test.coreedge.ClusterRule; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; public class ClusterFormationIT { @@ -49,6 +58,38 @@ public void setup() throws Exception cluster = clusterRule.startCluster(); } + @Test + public void shouldSupportBuiltInProcedures() throws Exception + { + cluster.addEdgeMemberWithId( 0 ).start(); + + Stream.concat( + cluster.edgeMembers().stream().map(EdgeClusterMember::database), + cluster.coreMembers().stream().map(CoreClusterMember::database) + ).forEach( gdb -> + { + // (1) BuiltInProcedures from community + { + Result result = gdb.execute( "CALL dbms.procedures()" ); + assertTrue( result.hasNext() ); + result.close(); + } + + // (2) BuiltInProcedures from enterprise + try( InternalTransaction tx = gdb.beginTransaction( + KernelTransaction.Type.explicit, + EnterpriseAuthSubject.AUTH_DISABLED + ) ) + { + Result result = gdb.execute( tx, "CALL dbms.listQueries()", Collections.emptyMap() ); + assertTrue( result.hasNext() ); + result.close(); + + tx.success(); + } + } ); + } + @Test public void shouldBeAbleToAddAndRemoveCoreMembers() throws Exception { diff --git a/enterprise/ha/src/main/java/org/neo4j/kernel/ha/factory/HighlyAvailableEditionModule.java b/enterprise/ha/src/main/java/org/neo4j/kernel/ha/factory/HighlyAvailableEditionModule.java index 5244c8cf23625..cd20d4395adc4 100644 --- a/enterprise/ha/src/main/java/org/neo4j/kernel/ha/factory/HighlyAvailableEditionModule.java +++ b/enterprise/ha/src/main/java/org/neo4j/kernel/ha/factory/HighlyAvailableEditionModule.java @@ -194,8 +194,11 @@ protected Log authManagerLog() } @Override - public void registerProcedures( Procedures procedures ) throws KernelException + public void setupProcedures( Procedures procedures ) throws KernelException { + procedures.registerProcedure( org.neo4j.kernel.builtinprocs.BuiltInProcedures.class ); + procedures.registerProcedure( org.neo4j.kernel.enterprise.builtinprocs.BuiltInProcedures.class ); + procedures.registerComponent( SecurityLog.class, (ctx) -> securityLog ); registerProceduresFromProvider( "auth-procedures-provider", procedures ); registerProceduresFromProvider( "enterprise-auth-procedures-provider", procedures ); diff --git a/enterprise/kernel/src/main/java/org/neo4j/kernel/enterprise/api/security/EnterpriseAuthSubject.java b/enterprise/kernel/src/main/java/org/neo4j/kernel/enterprise/api/security/EnterpriseAuthSubject.java index 04135a7fb795c..945271c7b5c4a 100644 --- a/enterprise/kernel/src/main/java/org/neo4j/kernel/enterprise/api/security/EnterpriseAuthSubject.java +++ b/enterprise/kernel/src/main/java/org/neo4j/kernel/enterprise/api/security/EnterpriseAuthSubject.java @@ -19,7 +19,12 @@ */ package org.neo4j.kernel.enterprise.api.security; +import java.io.IOException; + +import org.neo4j.graphdb.security.AuthorizationViolationException; import org.neo4j.kernel.api.security.AuthSubject; +import org.neo4j.kernel.api.security.AuthenticationResult; +import org.neo4j.kernel.api.security.exception.InvalidArgumentsException; /** * A logged in user. @@ -44,4 +49,92 @@ static T castOrFail( Class clazz, AuthSubje } return clazz.cast( authSubject ); } + + EnterpriseAuthSubject AUTH_DISABLED = new EnterpriseAuthSubject() + { + @Override + public boolean allowsReads() + { + return AuthSubject.AUTH_DISABLED.allowsReads(); + } + + @Override + public boolean allowsWrites() + { + return AuthSubject.AUTH_DISABLED.allowsWrites(); + } + + @Override + public boolean allowsSchemaWrites() + { + return AuthSubject.AUTH_DISABLED.allowsSchemaWrites(); + } + + @Override + public boolean overrideOriginalMode() + { + return AuthSubject.AUTH_DISABLED.overrideOriginalMode(); + } + + @Override + public AuthorizationViolationException onViolation( String msg ) + { + return AuthSubject.AUTH_DISABLED.onViolation( msg ); + } + + @Override + public String name() + { + return AuthSubject.AUTH_DISABLED.name(); + } + + @Override + public boolean isAdmin() + { + return true; + } + + @Override + public void logout() + { + AuthSubject.AUTH_DISABLED.logout(); + } + + @Override + public AuthenticationResult getAuthenticationResult() + { + return AuthSubject.AUTH_DISABLED.getAuthenticationResult(); + } + + @Override + public void setPassword( String password, boolean requirePasswordChange ) + throws IOException, InvalidArgumentsException + { + AuthSubject.AUTH_DISABLED.setPassword( password, requirePasswordChange ); + } + + @Override + public boolean allowsProcedureWith( String[] roleNames ) throws InvalidArgumentsException + { + return AuthSubject.AUTH_DISABLED.allowsProcedureWith( roleNames ); + } + + @Override + public String username() + { + return AuthSubject.AUTH_DISABLED.username(); + } + + @Override + public boolean hasUsername( String username ) + { + return AuthSubject.AUTH_DISABLED.hasUsername( username ); + } + + @Override + public void ensureUserExistsWithName( String username ) throws InvalidArgumentsException + { + AuthSubject.AUTH_DISABLED.ensureUserExistsWithName( username ); + } + }; } diff --git a/enterprise/kernel/src/main/java/org/neo4j/kernel/impl/enterprise/EnterpriseEditionModule.java b/enterprise/kernel/src/main/java/org/neo4j/kernel/impl/enterprise/EnterpriseEditionModule.java index 76e9e45c02c30..3c9962a4dad3b 100644 --- a/enterprise/kernel/src/main/java/org/neo4j/kernel/impl/enterprise/EnterpriseEditionModule.java +++ b/enterprise/kernel/src/main/java/org/neo4j/kernel/impl/enterprise/EnterpriseEditionModule.java @@ -25,7 +25,6 @@ import org.neo4j.kernel.api.bolt.BoltConnectionTracker; import org.neo4j.kernel.api.exceptions.KernelException; import org.neo4j.kernel.configuration.Config; -import org.neo4j.kernel.enterprise.builtinprocs.BuiltInProcedures; import org.neo4j.kernel.impl.constraints.ConstraintSemantics; import org.neo4j.kernel.impl.enterprise.id.EnterpriseIdTypeConfigurationProvider; import org.neo4j.kernel.impl.enterprise.transaction.log.checkpoint.ConfigurableIOLimiter; @@ -51,13 +50,15 @@ public class EnterpriseEditionModule extends CommunityEditionModule { @Override - public void registerProcedures( Procedures procedures ) throws KernelException + public void setupProcedures( Procedures procedures ) throws KernelException { - super.registerProcedures( procedures ); - procedures.registerProcedure( BuiltInProcedures.class ); + // If you change this, don't forget to update the HA and Core|Edge editions, too + procedures.registerProcedure( org.neo4j.kernel.enterprise.builtinprocs.BuiltInProcedures.class ); + procedures.registerComponent( SecurityLog.class, (ctx) -> securityLog ); registerProceduresFromProvider( "enterprise-auth-procedures-provider", procedures ); } + private SecurityLog securityLog; public EnterpriseEditionModule( PlatformModule platformModule ) diff --git a/integrationtests/src/test/java/org/neo4j/ha/HAClusterStartupIT.java b/integrationtests/src/test/java/org/neo4j/ha/HAClusterStartupIT.java index b946e11ff003d..1649859e665e7 100644 --- a/integrationtests/src/test/java/org/neo4j/ha/HAClusterStartupIT.java +++ b/integrationtests/src/test/java/org/neo4j/ha/HAClusterStartupIT.java @@ -28,18 +28,24 @@ import java.io.File; import java.io.IOException; import java.nio.file.Files; +import java.util.Collections; import org.neo4j.consistency.checking.full.ConsistencyCheckIncompleteException; import org.neo4j.graphdb.GraphDatabaseService; +import org.neo4j.graphdb.Result; import org.neo4j.graphdb.Transaction; import org.neo4j.graphdb.factory.EnterpriseGraphDatabaseFactory; import org.neo4j.io.fs.FileUtils; +import org.neo4j.kernel.api.KernelTransaction; +import org.neo4j.kernel.enterprise.api.security.EnterpriseAuthSubject; import org.neo4j.kernel.ha.HighlyAvailableGraphDatabase; +import org.neo4j.kernel.impl.coreapi.InternalTransaction; import org.neo4j.kernel.impl.ha.ClusterManager; import org.neo4j.kernel.impl.storemigration.LogFiles; import org.neo4j.test.ha.ClusterRule; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; import static org.neo4j.consistency.store.StoreAssertions.assertConsistentStore; import static org.neo4j.kernel.impl.ha.ClusterManager.allSeesAllAsAvailable; import static org.neo4j.kernel.impl.ha.ClusterManager.clusterOfSize; @@ -79,6 +85,41 @@ public void setup() throws Throwable assertAllStoreConsistent( cluster ); } + @Test + public void allClusterNodesShouldSupportTheBuiltInProcedures() throws Throwable + { + ClusterManager.ManagedCluster cluster = clusterRule.startCluster(); + try + { + for ( HighlyAvailableGraphDatabase gdb : cluster.getAllMembers() ) + { + // (1) BuiltInProcedures from community + { + Result result = gdb.execute( "CALL dbms.procedures()" ); + assertTrue( result.hasNext() ); + result.close(); + } + + // (2) BuiltInProcedures from enterprise + try( InternalTransaction tx = gdb.beginTransaction( + KernelTransaction.Type.explicit, + EnterpriseAuthSubject.AUTH_DISABLED + ) ) + { + Result result = gdb.execute( tx, "CALL dbms.listQueries()", Collections.emptyMap() ); + assertTrue( result.hasNext() ); + result.close(); + + tx.success(); + } + } + } + finally + { + cluster.shutdown(); + } + } + @Test public void aSlaveWithoutAnyGraphDBFilesShouldBeAbleToJoinACluster() throws Throwable {