Skip to content

Commit

Permalink
Introduced SecurityContext that replaces AccessMode
Browse files Browse the repository at this point in the history
  • Loading branch information
fickludd committed Oct 21, 2016
1 parent 8aa5296 commit 263c8ab
Show file tree
Hide file tree
Showing 135 changed files with 970 additions and 1,252 deletions.
Expand Up @@ -32,7 +32,7 @@ public interface AuthenticationResult
@Override
public AuthSubject getAuthSubject()
{
return AuthSubject.AUTH_DISABLED;
return null;
}

@Override
Expand Down
Expand Up @@ -30,7 +30,7 @@
import org.neo4j.graphdb.security.URLAccessValidationError;
import org.neo4j.kernel.GraphDatabaseQueryService;
import org.neo4j.kernel.api.KernelTransaction;
import org.neo4j.kernel.api.security.AccessMode;
import org.neo4j.kernel.api.security.SecurityContext;
import org.neo4j.kernel.impl.coreapi.InternalTransaction;
import org.neo4j.kernel.impl.factory.GraphDatabaseFacade;

Expand Down Expand Up @@ -74,16 +74,16 @@ public Relationship getRelationshipById( long id )
}

@Override
public InternalTransaction beginTransaction( KernelTransaction.Type type, AccessMode accessMode )
public InternalTransaction beginTransaction( KernelTransaction.Type type, SecurityContext securityContext )
{
return graph.beginTransaction( type, accessMode );
return graph.beginTransaction( type, securityContext );
}

@Override
public InternalTransaction beginTransaction( KernelTransaction.Type type, AccessMode accessMode,
public InternalTransaction beginTransaction( KernelTransaction.Type type, SecurityContext securityContext,
long timeout, TimeUnit unit )
{
return graph.beginTransaction( type, accessMode, timeout, unit );
return graph.beginTransaction( type, securityContext, timeout, unit );
}

@Override
Expand Down
Expand Up @@ -30,7 +30,7 @@ import org.neo4j.cypher.internal.tracing.{CompilationTracer, TimingCompilationTr
import org.neo4j.graphdb.config.Setting
import org.neo4j.graphdb.factory.GraphDatabaseSettings
import org.neo4j.kernel.api.ReadOperations
import org.neo4j.kernel.api.security.AccessMode
import org.neo4j.kernel.api.security.{Allowance, SecurityContext}
import org.neo4j.kernel.configuration.Config
import org.neo4j.kernel.impl.query.{QueryExecutionMonitor, TransactionalContext}
import org.neo4j.kernel.{GraphDatabaseQueryService, api, monitoring}
Expand Down Expand Up @@ -150,8 +150,12 @@ class ExecutionEngine(val queryService: GraphDatabaseQueryService, logProvider:
val tc = externalTransactionalContext.getOrBeginNewIfClosed()

// Temporarily change access mode during query planning
// NOTE: This will force read access even if the current transaction did not have it
val revertable = tc.restrictCurrentTransaction(AccessMode.Static.READ)
// NOTE: This will force read allowance if the current transaction did not have it
val revertable = tc.restrictCurrentTransaction(new SecurityContext {
override def name(): String = ""

override def allows(): Allowance = Allowance.Static.READ
})

val ((plan: ExecutionPlan, extractedParameters), touched) = try {
// fetch plan cache
Expand Down
Expand Up @@ -24,7 +24,7 @@ import org.neo4j.graphdb.{Lock, PropertyContainer}
import org.neo4j.kernel.GraphDatabaseQueryService
import org.neo4j.kernel.api.KernelTransaction.Revertable
import org.neo4j.kernel.api.dbms.DbmsOperations
import org.neo4j.kernel.api.security.AccessMode
import org.neo4j.kernel.api.security.{Allowance, SecurityContext}
import org.neo4j.kernel.api.txstate.TxStateHolder
import org.neo4j.kernel.api.{ReadOperations, Statement}
import org.neo4j.kernel.impl.query.TransactionalContext
Expand Down Expand Up @@ -60,7 +60,7 @@ case class TransactionalContextWrapperv3_0(tc: TransactionalContext) extends Que

override def close(success: Boolean) { tc.close(success) }

def restrictCurrentTransaction(accessMode: AccessMode): Revertable = tc.restrictCurrentTransaction(accessMode)
def restrictCurrentTransaction(context: SecurityContext): Revertable = tc.restrictCurrentTransaction(context)

def accessMode: AccessMode = tc.accessMode
def securityContext: SecurityContext = tc.securityContext
}
Expand Up @@ -24,7 +24,7 @@ import org.neo4j.graphdb.{Lock, PropertyContainer}
import org.neo4j.kernel.GraphDatabaseQueryService
import org.neo4j.kernel.api.KernelTransaction.Revertable
import org.neo4j.kernel.api.dbms.DbmsOperations
import org.neo4j.kernel.api.security.AccessMode
import org.neo4j.kernel.api.security.{Allowance, SecurityContext}
import org.neo4j.kernel.api.txstate.TxStateHolder
import org.neo4j.kernel.api.{ReadOperations, Statement}
import org.neo4j.kernel.impl.query.TransactionalContext
Expand Down Expand Up @@ -60,7 +60,7 @@ case class TransactionalContextWrapperv3_1(tc: TransactionalContext) extends Que

override def close(success: Boolean) { tc.close(success) }

def restrictCurrentTransaction(accessMode: AccessMode): Revertable = tc.restrictCurrentTransaction(accessMode)
def restrictCurrentTransaction(context: SecurityContext): Revertable = tc.restrictCurrentTransaction(context)

def accessMode: AccessMode = tc.accessMode
def securityContext: SecurityContext = tc.securityContext
}
Expand Up @@ -623,7 +623,7 @@ final class TransactionBoundQueryContext(val transactionalContext: Transactional
callProcedure(name, args, transactionalContext.statement.procedureCallOperations().procedureCallWrite)

override def callDbmsProcedure(name: QualifiedProcedureName, args: Seq[Any]) =
callProcedure(name, args, transactionalContext.dbmsOperations.procedureCallDbms(_,_,transactionalContext.accessMode))
callProcedure(name, args, transactionalContext.dbmsOperations.procedureCallDbms(_,_,transactionalContext.securityContext))

private def callProcedure(name: QualifiedProcedureName, args: Seq[Any],
call: (QualifiedName, Array[AnyRef]) => RawIterator[Array[AnyRef], ProcedureException]) = {
Expand Down
Expand Up @@ -34,7 +34,7 @@ import org.neo4j.cypher.internal.compiler.v3_1.helpers.JavaConversionSupport
import org.neo4j.cypher.internal.compiler.v3_1.helpers.JavaConversionSupport._
import org.neo4j.cypher.internal.compiler.v3_1.pipes.matching.PatternNode
import org.neo4j.cypher.internal.compiler.v3_1.spi._
import org.neo4j.cypher.internal.frontend.v3_1.{Bound, EntityNotFoundException, FailedIndexException, SemanticDirection, spi => frontend}
import org.neo4j.cypher.internal.frontend.v3_1.{Bound, EntityNotFoundException, FailedIndexException, SemanticDirection}
import org.neo4j.cypher.internal.spi.v3_1.TransactionBoundQueryContext.IndexSearchMonitor
import org.neo4j.cypher.internal.spi.{BeansAPIRelationshipIterator, TransactionalContextWrapperv3_1}
import org.neo4j.cypher.javacompat.internal.GraphDatabaseCypherService
Expand Down Expand Up @@ -590,8 +590,8 @@ final class TransactionBoundQueryContext(val transactionalContext: Transactional
private def shouldElevate(allowed: Array[String]): Boolean = {
// We have to be careful with elevation, since we cannot elevate permissions in a nested procedure call
// above the original allowed procedure mode. We enforce this by checking if mode is already an overridden mode.
val mode = transactionalContext.accessMode
allowed.nonEmpty && !mode.isOverridden && mode.getOriginalAccessMode.allowsProcedureWith(allowed)
val allowance = transactionalContext.securityContext.allows()
allowed.nonEmpty && !allowance.isOverridden && transactionalContext.securityContext.allowsProcedureWith(allowed)
}

override def callReadOnlyProcedure(name: QualifiedName, args: Seq[Any], allowed: Array[String]) = {
Expand Down Expand Up @@ -622,7 +622,7 @@ final class TransactionBoundQueryContext(val transactionalContext: Transactional
}

override def callDbmsProcedure(name: QualifiedName, args: Seq[Any], allowed: Array[String]) = {
callProcedure(name, args, transactionalContext.dbmsOperations.procedureCallDbms(_,_,transactionalContext.accessMode))
callProcedure(name, args, transactionalContext.dbmsOperations.procedureCallDbms(_,_,transactionalContext.securityContext))
}

private def callProcedure(name: QualifiedName, args: Seq[Any], call: KernelProcedureCall) = {
Expand Down
Expand Up @@ -34,7 +34,7 @@
import org.neo4j.helpers.collection.Pair;
import org.neo4j.kernel.GraphDatabaseQueryService;
import org.neo4j.kernel.api.KernelTransaction;
import org.neo4j.kernel.api.security.AccessMode;
import org.neo4j.kernel.api.security.SecurityContext;
import org.neo4j.kernel.impl.coreapi.InternalTransaction;
import org.neo4j.test.rule.EmbeddedDatabaseRule;

Expand Down Expand Up @@ -93,7 +93,7 @@ public void shouldWorkFine() throws Throwable
String query =
format( "MERGE (%s:Person {id: %s}) ON CREATE SET %s.name = \"%s\";", ident, id, ident, name );

try ( InternalTransaction tx = graph.beginTransaction( KernelTransaction.Type.implicit, AccessMode.Static.FULL ) )
try ( InternalTransaction tx = graph.beginTransaction( KernelTransaction.Type.implicit, SecurityContext.Static.FULL ) )
{
Result result = db.execute( query );
result.close();
Expand Down
Expand Up @@ -30,7 +30,7 @@
import org.neo4j.graphdb.Result;
import org.neo4j.kernel.GraphDatabaseQueryService;
import org.neo4j.kernel.api.KernelTransaction;
import org.neo4j.kernel.api.security.AccessMode;
import org.neo4j.kernel.api.security.SecurityContext;
import org.neo4j.kernel.impl.coreapi.InternalTransaction;
import org.neo4j.kernel.impl.coreapi.PropertyContainerLocker;
import org.neo4j.kernel.impl.query.Neo4jTransactionalContextFactory;
Expand Down Expand Up @@ -58,7 +58,7 @@ public void shouldConvertListsAndMapsWhenPassingFromScalaToJava() throws Excepti

Result result;
try ( InternalTransaction tx = graph
.beginTransaction( KernelTransaction.Type.implicit, AccessMode.Static.FULL ) )
.beginTransaction( KernelTransaction.Type.implicit, SecurityContext.Static.FULL ) )
{
String query = "RETURN { key : 'Value' , collectionKey: [{ inner: 'Map1' }, { inner: 'Map2' }]}";
TransactionalContext tc = createTransactionContext( graph, tx, query );
Expand Down
Expand Up @@ -34,7 +34,7 @@ import org.neo4j.graphdb.factory.GraphDatabaseSettings
import org.neo4j.io.fs.FileUtils
import org.neo4j.kernel.NeoStoreDataSource
import org.neo4j.kernel.api.KernelTransaction.Type
import org.neo4j.kernel.api.security.AccessMode
import org.neo4j.kernel.api.security.SecurityContext
import org.neo4j.kernel.impl.coreapi.TopLevelTransaction
import org.neo4j.test.TestGraphDatabaseFactory

Expand Down Expand Up @@ -645,7 +645,7 @@ order by a.COL1""")

// Until we have a clean cut way where statement context is injected into cypher,
// I don't know a non-hairy way to tell if this was done correctly, so here goes:
val tx = graph.beginTransaction( Type.explicit, AccessMode.Static.NONE )
val tx = graph.beginTransaction( Type.explicit, SecurityContext.Static.NONE )
val isTopLevelTx = tx.getClass === classOf[TopLevelTransaction]
tx.close()

Expand Down
Expand Up @@ -23,7 +23,7 @@ import java.util

import org.neo4j.graphdb._
import org.neo4j.kernel.api.KernelTransaction
import org.neo4j.kernel.api.security.AccessMode
import org.neo4j.kernel.api.security.SecurityContext
import org.neo4j.kernel.impl.core.ThreadToStatementContextBridge
import org.scalatest.Assertions

Expand Down Expand Up @@ -397,7 +397,7 @@ class MutatingIntegrationTest extends ExecutionEngineFunSuite with Assertions wi
}

test("failure_only_fails_inner_transaction") {
val tx = graph.beginTransaction( KernelTransaction.Type.explicit, AccessMode.Static.WRITE )
val tx = graph.beginTransaction( KernelTransaction.Type.explicit, SecurityContext.Static.WRITE )
try {
executeWithAllPlanners("match (a) where id(a) = {id} set a.foo = 'bar' return a","id"->"0")
} catch {
Expand Down
Expand Up @@ -23,7 +23,7 @@ import org.neo4j.cypher.internal.frontend.v3_1.test_helpers.CypherFunSuite
import org.neo4j.cypher.javacompat.internal.GraphDatabaseCypherService
import org.neo4j.kernel.NeoStoreDataSource
import org.neo4j.kernel.api.KernelTransaction
import org.neo4j.kernel.api.security.AccessMode
import org.neo4j.kernel.api.security.SecurityContext
import org.neo4j.test.TestGraphDatabaseFactory
import org.scalatest.BeforeAndAfterAll

Expand Down Expand Up @@ -59,7 +59,7 @@ class LastCommittedTxIdProviderTest extends CypherFunSuite with BeforeAndAfterAl
}

private def createNode(): Unit = {
val tx = db.beginTransaction( KernelTransaction.Type.explicit, AccessMode.Static.WRITE )
val tx = db.beginTransaction( KernelTransaction.Type.explicit, SecurityContext.Static.WRITE )
try {
db.createNode()
tx.success()
Expand Down
Expand Up @@ -24,15 +24,15 @@ import org.neo4j.cypher.internal.compiler.v3_1.commands.expressions.Literal
import org.neo4j.cypher.internal.compiler.v3_1.mutation.CreateNode
import org.neo4j.graphdb.Node
import org.neo4j.kernel.api.KernelTransaction
import org.neo4j.kernel.api.security.AccessMode
import org.neo4j.kernel.api.security.SecurityContext

class CreateNodeActionTest extends ExecutionEngineFunSuite {

test("demixed types are not ok") {
val action = CreateNode("id", Map("*" -> Literal(Map("name" -> "Andres", "age" -> 37))), Seq.empty)

val id = graph.inTx {
val tx = graph.beginTransaction( KernelTransaction.Type.explicit, AccessMode.Static.WRITE )
val tx = graph.beginTransaction( KernelTransaction.Type.explicit, SecurityContext.Static.WRITE )
val vec = action.exec(ExecutionContext.empty, QueryStateHelper.queryStateFrom(graph, tx)).toVector
vec.head("id").asInstanceOf[Node].getId
}
Expand Down
Expand Up @@ -25,7 +25,7 @@ import org.neo4j.cypher.GraphDatabaseFunSuite
import org.neo4j.cypher.internal.compiler.v3_1.commands.expressions.{ParameterExpression, Variable}
import org.neo4j.cypher.internal.compiler.v3_1.mutation.{CreateRelationship, RelationshipEndpoint}
import org.neo4j.kernel.api.KernelTransaction
import org.neo4j.kernel.api.security.AccessMode
import org.neo4j.kernel.api.security.SecurityContext

import scala.collection.JavaConverters._

Expand All @@ -41,7 +41,7 @@ class CreateRelationshipTest extends GraphDatabaseFunSuite {
val bEndNode = RelationshipEndpoint(Variable("b"), Map(), Seq.empty)
val relCreator = new CreateRelationship("r", aEndNode, bEndNode, "RELTYPE", Map("*" -> ParameterExpression("props")))

val tx = graph.beginTransaction( KernelTransaction.Type.explicit, AccessMode.Static.WRITE )
val tx = graph.beginTransaction( KernelTransaction.Type.explicit, SecurityContext.Static.WRITE )
try {
val state = QueryStateHelper.queryStateFrom(graph, tx, props)
val ctx = ExecutionContext.from("a" -> a, "b" -> b)
Expand Down
Expand Up @@ -29,7 +29,7 @@ import org.neo4j.cypher.internal.frontend.v3_1.test_helpers.CypherFunSuite
import org.neo4j.cypher.javacompat.internal.GraphDatabaseCypherService
import org.neo4j.graphdb._
import org.neo4j.kernel.api.KernelTransaction
import org.neo4j.kernel.api.security.AccessMode
import org.neo4j.kernel.api.security.SecurityContext
import org.neo4j.test.TestGraphDatabaseFactory

import scala.collection.JavaConverters._
Expand Down Expand Up @@ -68,13 +68,13 @@ class DoubleCheckCreateUniqueTest extends CypherFunSuite {
}

private def withQueryState(f: QueryState => Unit) {
val tx = db.beginTransaction( KernelTransaction.Type.explicit, AccessMode.Static.WRITE )
val tx = db.beginTransaction( KernelTransaction.Type.explicit, SecurityContext.Static.WRITE )
f(QueryStateHelper.queryStateFrom(db, tx))
tx.close()
}

private def createNode(): Node = {
val tx = db.beginTransaction( KernelTransaction.Type.explicit, AccessMode.Static.WRITE )
val tx = db.beginTransaction( KernelTransaction.Type.explicit, SecurityContext.Static.WRITE )
try {
val n = db.createNode()
tx.success()
Expand Down
Expand Up @@ -28,7 +28,7 @@ import org.neo4j.cypher.internal.frontend.v3_1.CypherTypeException
import org.neo4j.cypher.internal.frontend.v3_1.symbols._
import org.neo4j.graphdb.{Node, NotFoundException}
import org.neo4j.kernel.api.KernelTransaction
import org.neo4j.kernel.api.security.AccessMode
import org.neo4j.kernel.api.security.SecurityContext
import org.neo4j.kernel.impl.coreapi.InternalTransaction

import scala.collection.mutable.{Map => MutableMap}
Expand All @@ -43,7 +43,7 @@ class MutationTest extends ExecutionEngineFunSuite {
}

test("create_node") {
val tx = graph.beginTransaction( KernelTransaction.Type.explicit, AccessMode.Static.WRITE )
val tx = graph.beginTransaction( KernelTransaction.Type.explicit, SecurityContext.Static.WRITE )
val start = SingleRowPipe()
val createNode = new ExecuteUpdateCommandsPipe(start, Seq(CreateNode("n", Map("name" -> Literal("Andres")), Seq.empty)))

Expand All @@ -59,7 +59,7 @@ class MutationTest extends ExecutionEngineFunSuite {
}

test("join_existing_transaction_and_rollback") {
val tx = graph.beginTransaction( KernelTransaction.Type.explicit, AccessMode.Static.WRITE )
val tx = graph.beginTransaction( KernelTransaction.Type.explicit, SecurityContext.Static.WRITE )
val start = SingleRowPipe()
val createNode = new ExecuteUpdateCommandsPipe(start, Seq(CreateNode("n", Map("name" -> Literal("Andres")), Seq.empty)))

Expand All @@ -72,7 +72,7 @@ class MutationTest extends ExecutionEngineFunSuite {
}

test("join_existing_transaction_and_commit") {
val tx = graph.beginTransaction( KernelTransaction.Type.explicit, AccessMode.Static.WRITE )
val tx = graph.beginTransaction( KernelTransaction.Type.explicit, SecurityContext.Static.WRITE )
val start = SingleRowPipe()
val createNode = new ExecuteUpdateCommandsPipe(start, Seq(CreateNode("n", Map("name" -> Literal("Andres")), Seq.empty)))

Expand All @@ -91,7 +91,7 @@ class MutationTest extends ExecutionEngineFunSuite {
test("create_rel") {
val a = createNode()
val b = createNode()
val tx = graph.beginTransaction( KernelTransaction.Type.explicit, AccessMode.Static.WRITE )
val tx = graph.beginTransaction( KernelTransaction.Type.explicit, SecurityContext.Static.WRITE )

val createRel = CreateRelationship("r",
RelationshipEndpoint(getNode("a", a), Map(), Seq.empty),
Expand All @@ -113,15 +113,15 @@ class MutationTest extends ExecutionEngineFunSuite {
}

test("throw_exception_if_wrong_stuff_to_delete") {
val tx = graph.beginTransaction( KernelTransaction.Type.explicit, AccessMode.Static.WRITE )
val tx = graph.beginTransaction( KernelTransaction.Type.explicit, SecurityContext.Static.WRITE )
val createRel = DeleteEntityAction(Literal("some text"), forced = false)

intercept[CypherTypeException](createRel.exec(ExecutionContext.empty, createQueryState(tx)))
tx.close()
}

test("delete_node") {
val tx = graph.beginTransaction( KernelTransaction.Type.explicit, AccessMode.Static.WRITE )
val tx = graph.beginTransaction( KernelTransaction.Type.explicit, SecurityContext.Static.WRITE )
val a: Node = createNode()
val node_id: Long = a.getId
val deleteCommand = DeleteEntityAction(getNode("a", a), forced = false)
Expand Down
Expand Up @@ -22,13 +22,13 @@ package org.neo4j.cypher.internal.compiler.v3_1
import org.neo4j.cypher.GraphDatabaseTestSupport
import org.neo4j.cypher.internal.compiler.v3_1.pipes.QueryState
import org.neo4j.kernel.api.KernelTransaction
import org.neo4j.kernel.api.security.AccessMode
import org.neo4j.kernel.api.security.SecurityContext

trait QueryStateTestSupport {
self: GraphDatabaseTestSupport =>

def withQueryState[T](f: QueryState => T) = {
val tx = graph.beginTransaction(KernelTransaction.Type.explicit, AccessMode.Static.FULL)
val tx = graph.beginTransaction(KernelTransaction.Type.explicit, SecurityContext.Static.FULL)
try {
val queryState = QueryStateHelper.queryStateFrom(graph, tx)
f(queryState)
Expand All @@ -38,7 +38,7 @@ trait QueryStateTestSupport {
}

def withCountsQueryState[T](f: QueryState => T) = {
val tx = graph.beginTransaction(KernelTransaction.Type.explicit, AccessMode.Static.FULL)
val tx = graph.beginTransaction(KernelTransaction.Type.explicit, SecurityContext.Static.FULL)
try {
val queryState = QueryStateHelper.countStats(QueryStateHelper.queryStateFrom(graph, tx))
f(queryState)
Expand Down

0 comments on commit 263c8ab

Please sign in to comment.