Skip to content

Commit

Permalink
Refactor procedure call operations
Browse files Browse the repository at this point in the history
Procedures have their own way of dealing with access control, and are
not served well by the access check made when acquiring the *Operations
interfaces. This commit moves the procedure call methods to a dedicated
interface, which can be acquired by any caller.
  • Loading branch information
Mats-SX committed Oct 5, 2016
1 parent e56d12d commit eae7dec
Show file tree
Hide file tree
Showing 19 changed files with 213 additions and 90 deletions.
Expand Up @@ -617,10 +617,10 @@ final class TransactionBoundQueryContext(val transactionalContext: Transactional
}

override def callReadOnlyProcedure(name: QualifiedProcedureName, args: Seq[Any]) =
callProcedure(name, args, transactionalContext.statement.readOperations().procedureCallRead)
callProcedure(name, args, transactionalContext.statement.procedureCallOperations().procedureCallRead)

override def callReadWriteProcedure(name: QualifiedProcedureName, args: Seq[Any]) =
callProcedure(name, args, transactionalContext.statement.dataWriteOperations().procedureCallWrite)
callProcedure(name, args, transactionalContext.statement.procedureCallOperations().procedureCallWrite)

override def callDbmsProcedure(name: QualifiedProcedureName, args: Seq[Any]) =
callProcedure(name, args, transactionalContext.dbmsOperations.procedureCallDbms(_,_,transactionalContext.accessMode))
Expand Down
Expand Up @@ -590,29 +590,29 @@ final class TransactionBoundQueryContext(val transactionalContext: Transactional
override def callReadOnlyProcedure(name: QualifiedName, args: Seq[Any], allowed: Array[String]) = {
val call: KernelProcedureCall = transactionalContext.accessMode match {
case a: AuthSubject if a.allowsProcedureWith(allowed) =>
transactionalContext.statement.readOperations().procedureCallRead(_, _, AccessMode.Static.OVERRIDE_READ)
transactionalContext.statement.procedureCallOperations.procedureCallRead(_, _, AccessMode.Static.OVERRIDE_READ)
case _ =>
transactionalContext.statement.readOperations().procedureCallRead(_, _)
transactionalContext.statement.procedureCallOperations.procedureCallRead(_, _)
}
callProcedure(name, args, call)
}

override def callReadWriteProcedure(name: QualifiedName, args: Seq[Any], allowed: Array[String]) = {
val call: KernelProcedureCall = transactionalContext.accessMode match {
case a: AuthSubject if a.allowsProcedureWith(allowed) =>
transactionalContext.statement.dataWriteOperations().procedureCallWrite(_, _, AccessMode.Static.OVERRIDE_WRITE)
transactionalContext.statement.procedureCallOperations.procedureCallWrite(_, _, AccessMode.Static.OVERRIDE_WRITE)
case _ =>
transactionalContext.statement.dataWriteOperations().procedureCallWrite(_, _)
transactionalContext.statement.procedureCallOperations.procedureCallWrite(_, _)
}
callProcedure(name, args, call)
}

override def callSchemaWriteProcedure(name: QualifiedName, args: Seq[Any], allowed: Array[String]) = {
val call: KernelProcedureCall = transactionalContext.accessMode match {
case a: AuthSubject if a.allowsProcedureWith(allowed) =>
transactionalContext.statement.schemaWriteOperations().procedureCallSchema(_, _, AccessMode.Static.OVERRIDE_SCHEMA)
transactionalContext.statement.procedureCallOperations.procedureCallSchema(_, _, AccessMode.Static.OVERRIDE_SCHEMA)
case _ =>
transactionalContext.statement.schemaWriteOperations().procedureCallSchema(_, _)
transactionalContext.statement.procedureCallOperations.procedureCallSchema(_, _)
}
callProcedure(name, args, call)
}
Expand Down
Expand Up @@ -149,10 +149,4 @@ void relationshipRemoveFromLegacyIndex( String indexName, long relationship )
void nodeLegacyIndexDrop( String indexName ) throws LegacyIndexNotFoundKernelException;

void relationshipLegacyIndexDrop( String indexName ) throws LegacyIndexNotFoundKernelException;

/** Invoke a read/write procedure by name */
RawIterator<Object[], ProcedureException> procedureCallWrite( QualifiedName name, Object[] input ) throws ProcedureException;

RawIterator<Object[], ProcedureException> procedureCallWrite( QualifiedName name, Object[] input, AccessMode override )
throws ProcedureException;
}
@@ -0,0 +1,95 @@
/*
* Copyright (c) 2002-2016 "Neo Technology,"
* Network Engine for Objects in Lund AB [http://neotechnology.com]
*
* This file is part of Neo4j.
*
* Neo4j is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.neo4j.kernel.api;

import org.neo4j.collection.RawIterator;
import org.neo4j.kernel.api.exceptions.ProcedureException;
import org.neo4j.kernel.api.proc.QualifiedName;
import org.neo4j.kernel.api.security.AccessMode;

/**
* Specifies procedure call operations for the three types of procedure calls that can be made.
*/
public interface ProcedureCallOperations
{
/**
* Invoke a read-only procedure by name.
* @param name the name of the procedure.
* @param arguments the procedure arguments.
* @return an iterator containing the procedure results.
* @throws ProcedureException if there was an exception thrown during procedure execution.
*/
RawIterator<Object[], ProcedureException> procedureCallRead( QualifiedName name, Object[] arguments )
throws ProcedureException;

/**
* Invoke a read-only procedure by name, and override the transaction's access mode with
* the given access mode for the duration of the procedure execution.
* @param name the name of the procedure.
* @param arguments the procedure arguments.
* @param override the access mode to be used for the execution of the procedure.
* @return an iterator containing the procedure results.
* @throws ProcedureException if there was an exception thrown during procedure execution.
*/
RawIterator<Object[], ProcedureException> procedureCallRead( QualifiedName name, Object[] arguments, AccessMode override )
throws ProcedureException;

/**
* Invoke a read/write procedure by name.
* @param name the name of the procedure.
* @param arguments the procedure arguments.
* @return an iterator containing the procedure results.
* @throws ProcedureException if there was an exception thrown during procedure execution.
*/
RawIterator<Object[], ProcedureException> procedureCallWrite( QualifiedName name, Object[] arguments )
throws ProcedureException;
/**
* Invoke a read/write procedure by name, and override the transaction's access mode with
* the given access mode for the duration of the procedure execution.
* @param name the name of the procedure.
* @param arguments the procedure arguments.
* @param override the access mode to be used for the execution of the procedure.
* @return an iterator containing the procedure results.
* @throws ProcedureException if there was an exception thrown during procedure execution.
*/
RawIterator<Object[], ProcedureException> procedureCallWrite( QualifiedName name, Object[] arguments, AccessMode override )
throws ProcedureException;

/**
* Invoke a schema write procedure by name.
* @param name the name of the procedure.
* @param arguments the procedure arguments.
* @return an iterator containing the procedure results.
* @throws ProcedureException if there was an exception thrown during procedure execution.
*/
RawIterator<Object[], ProcedureException> procedureCallSchema( QualifiedName name, Object[] arguments )
throws ProcedureException;
/**
* Invoke a schema write procedure by name, and override the transaction's access mode with
* the given access mode for the duration of the procedure execution.
* @param name the name of the procedure.
* @param arguments the procedure arguments.
* @param override the access mode to be used for the execution of the procedure.
* @return an iterator containing the procedure results.
* @throws ProcedureException if there was an exception thrown during procedure execution.
*/
RawIterator<Object[], ProcedureException> procedureCallSchema( QualifiedName name, Object[] arguments, AccessMode override )
throws ProcedureException;
}
Expand Up @@ -567,13 +567,6 @@ DoubleLongRegister indexSample( IndexDescriptor index, DoubleLongRegister target
/** Fetch all registered procedures */
Set<ProcedureSignature> proceduresGetAll();

/** Invoke a read-only procedure by name */
RawIterator<Object[], ProcedureException> procedureCallRead( QualifiedName name, Object[] input )
throws ProcedureException;

RawIterator<Object[], ProcedureException> procedureCallRead( QualifiedName name, Object[] input, AccessMode override )
throws ProcedureException;

/** Invoke a read-only procedure by name */
Object functionCall( QualifiedName name, Object[] input ) throws ProcedureException;
}
Expand Up @@ -65,11 +65,4 @@ RelationshipPropertyExistenceConstraint relationshipPropertyExistenceConstraintC
* That external job should become an internal job, at which point this operation should go away.
*/
void uniqueIndexDrop( IndexDescriptor descriptor ) throws DropIndexFailureException;

/** Invoke a schema procedure by name */
RawIterator<Object[], ProcedureException> procedureCallSchema( QualifiedName name, Object[] input )
throws ProcedureException;

RawIterator<Object[], ProcedureException> procedureCallSchema( QualifiedName name, Object[] input, AccessMode override )
throws ProcedureException;
}
Expand Up @@ -63,4 +63,9 @@ public interface Statement extends Resource
* @return interface exposing operations for associating metadata with this statement
*/
QueryRegistryOperations queryRegistration();

/**
* @return interface exposing all procedure call operations.
*/
ProcedureCallOperations procedureCallOperations();
}
Expand Up @@ -23,6 +23,7 @@

import org.neo4j.graphdb.NotInTransactionException;
import org.neo4j.graphdb.TransactionTerminatedException;
import org.neo4j.kernel.api.ProcedureCallOperations;
import org.neo4j.kernel.api.DataWriteOperations;
import org.neo4j.kernel.api.ExecutingQuery;
import org.neo4j.kernel.api.QueryRegistryOperations;
Expand Down Expand Up @@ -97,6 +98,12 @@ public ReadOperations readOperations()
return facade;
}

@Override
public ProcedureCallOperations procedureCallOperations()
{
return facade;
}

@Override
public TokenWriteOperations tokenWriteOperations()
{
Expand Down
Expand Up @@ -33,6 +33,7 @@
import org.neo4j.collection.primitive.PrimitiveLongIterator;
import org.neo4j.cursor.Cursor;
import org.neo4j.graphdb.Direction;
import org.neo4j.kernel.api.ProcedureCallOperations;
import org.neo4j.kernel.api.DataWriteOperations;
import org.neo4j.kernel.api.ExecutingQuery;
import org.neo4j.kernel.api.KernelTransaction;
Expand Down Expand Up @@ -101,7 +102,8 @@
import org.neo4j.storageengine.api.schema.PopulationProgress;

public class OperationsFacade
implements ReadOperations, DataWriteOperations, SchemaWriteOperations, QueryRegistryOperations
implements ReadOperations, DataWriteOperations, SchemaWriteOperations, QueryRegistryOperations,
ProcedureCallOperations
{
private final KernelTransaction tx;
private final KernelStatement statement;
Expand Down Expand Up @@ -571,18 +573,6 @@ public Object functionCall( QualifiedName name, Object[] input ) throws Procedur
return callFunction( name, input );
}

@Override
public RawIterator<Object[], ProcedureException> procedureCallRead( QualifiedName name, Object[] input ) throws ProcedureException
{
return callProcedure( name, input, AccessMode.Static.READ );
}

@Override
public RawIterator<Object[], ProcedureException> procedureCallRead( QualifiedName name, Object[] input, AccessMode override ) throws ProcedureException
{
return callProcedure( name, input, override );
}

@Override
public Set<ProcedureSignature> proceduresGetAll()
{
Expand Down Expand Up @@ -1095,19 +1085,6 @@ public Property graphRemoveProperty( int propertyKeyId )
return dataWrite().graphRemoveProperty( statement, propertyKeyId );
}

@Override
public RawIterator<Object[], ProcedureException> procedureCallWrite( QualifiedName name, Object[] input ) throws ProcedureException
{
// FIXME: should this be AccessMode.Static.WRITE instead?
return callProcedure( name, input, AccessMode.Static.FULL );
}

@Override
public RawIterator<Object[], ProcedureException> procedureCallWrite( QualifiedName name, Object[] input, AccessMode override ) throws ProcedureException
{
return callProcedure( name, input, override );
}

// </DataWrite>

// <SchemaWrite>
Expand Down Expand Up @@ -1172,18 +1149,6 @@ public void uniqueIndexDrop( IndexDescriptor descriptor ) throws DropIndexFailur
schemaWrite().uniqueIndexDrop( statement, descriptor );
}

@Override
public RawIterator<Object[], ProcedureException> procedureCallSchema( QualifiedName name, Object[] input ) throws ProcedureException
{
return callProcedure( name, input, AccessMode.Static.FULL );
}

@Override
public RawIterator<Object[], ProcedureException> procedureCallSchema( QualifiedName name, Object[] input, AccessMode override ) throws ProcedureException
{
return callProcedure( name, input, override );
}

// </SchemaWrite>

// <Locking>
Expand Down Expand Up @@ -1528,6 +1493,43 @@ public void unregisterExecutingQuery( ExecutingQuery executingQuery )

// <Procedures>

@Override
public RawIterator<Object[], ProcedureException> procedureCallRead( QualifiedName name, Object[] input ) throws ProcedureException
{
return callProcedure( name, input, AccessMode.Static.READ );
}

@Override
public RawIterator<Object[], ProcedureException> procedureCallRead( QualifiedName name, Object[] input, AccessMode override ) throws ProcedureException
{
return callProcedure( name, input, override );
}

@Override
public RawIterator<Object[], ProcedureException> procedureCallWrite( QualifiedName name, Object[] input ) throws ProcedureException
{
// FIXME: should this be AccessMode.Static.WRITE instead?
return callProcedure( name, input, AccessMode.Static.FULL );
}

@Override
public RawIterator<Object[], ProcedureException> procedureCallWrite( QualifiedName name, Object[] input, AccessMode override ) throws ProcedureException
{
return callProcedure( name, input, override );
}

@Override
public RawIterator<Object[], ProcedureException> procedureCallSchema( QualifiedName name, Object[] input ) throws ProcedureException
{
return callProcedure( name, input, AccessMode.Static.FULL );
}

@Override
public RawIterator<Object[], ProcedureException> procedureCallSchema( QualifiedName name, Object[] input, AccessMode override ) throws ProcedureException
{
return callProcedure( name, input, override );
}

private RawIterator<Object[],ProcedureException> callProcedure(
QualifiedName name, Object[] input, AccessMode mode )
throws ProcedureException
Expand Down
Expand Up @@ -58,7 +58,7 @@ public void testEmptyGraph() throws Throwable

// When
RawIterator<Object[],ProcedureException> stream =
readOperationsInNewTransaction().procedureCallRead( procedureName( "db", "schema" ), new Object[0] );
procedureCallOpsInNewTx().procedureCallRead( procedureName( "db", "schema" ), new Object[0] );

// Then
assertThat( asList( stream ), contains( equalTo( new Object[]{new ArrayList<>(), new ArrayList<>()} ) ) );
Expand All @@ -84,7 +84,7 @@ public void testLabelIndex() throws Throwable

// When
RawIterator<Object[],ProcedureException> stream =
readOperationsInNewTransaction().procedureCallRead( procedureName( "db", "schema" ), new Object[0] );
procedureCallOpsInNewTx().procedureCallRead( procedureName( "db", "schema" ), new Object[0] );

// Then
while ( stream.hasNext() )
Expand Down Expand Up @@ -117,7 +117,7 @@ public void testRelationShip() throws Throwable

// When
RawIterator<Object[],ProcedureException> stream =
readOperationsInNewTransaction().procedureCallRead( procedureName( "db", "schema" ), new Object[0] );
procedureCallOpsInNewTx().procedureCallRead( procedureName( "db", "schema" ), new Object[0] );

// Then
while ( stream.hasNext() )
Expand Down
Expand Up @@ -20,6 +20,7 @@
package org.neo4j.kernel.builtinprocs;

import org.neo4j.kernel.api.DataWriteOperations;
import org.neo4j.kernel.api.ProcedureCallOperations;
import org.neo4j.kernel.api.QueryRegistryOperations;
import org.neo4j.kernel.api.ReadOperations;
import org.neo4j.kernel.api.SchemaWriteOperations;
Expand Down Expand Up @@ -71,4 +72,10 @@ public QueryRegistryOperations queryRegistration()
{
throw new UnsupportedOperationException( "not implemented" );
}

@Override
public ProcedureCallOperations procedureCallOperations()
{
throw new UnsupportedOperationException( "not implemented" );
}
}

0 comments on commit eae7dec

Please sign in to comment.