Skip to content

Commit

Permalink
Split SecurityContext into LoginContext and SecurityContext
Browse files Browse the repository at this point in the history
The LoginContext holds authentication information, which is needed to
begin a transaction. It does not hold authorization information however,
this is acquired just before the transaction begins, and stored in the
SecurityContext.
  • Loading branch information
OliviaYtterbrink committed Feb 5, 2018
1 parent 3a284f5 commit 5b27ae1
Show file tree
Hide file tree
Showing 132 changed files with 872 additions and 751 deletions.
Expand Up @@ -19,20 +19,20 @@
*/
package org.neo4j.bolt.security.auth;

import org.neo4j.internal.kernel.api.security.SecurityContext;
import org.neo4j.internal.kernel.api.security.LoginContext;

public interface AuthenticationResult
{
SecurityContext getSecurityContext();
LoginContext getLoginContext();

boolean credentialsExpired();

AuthenticationResult AUTH_DISABLED = new AuthenticationResult()
{
@Override
public SecurityContext getSecurityContext()
public LoginContext getLoginContext()
{
return SecurityContext.AUTH_DISABLED;
return LoginContext.AUTH_DISABLED;
}

@Override
Expand Down
Expand Up @@ -23,11 +23,11 @@
import java.util.Map;

import org.neo4j.graphdb.security.AuthorizationViolationException;
import org.neo4j.internal.kernel.api.security.LoginContext;
import org.neo4j.kernel.api.exceptions.Status;
import org.neo4j.kernel.api.security.AuthManager;
import org.neo4j.kernel.api.security.AuthToken;
import org.neo4j.kernel.api.exceptions.InvalidArgumentsException;
import org.neo4j.internal.kernel.api.security.SecurityContext;
import org.neo4j.kernel.api.security.UserManagerSupplier;
import org.neo4j.kernel.api.security.exception.InvalidAuthTokenException;

Expand All @@ -53,7 +53,7 @@ public AuthenticationResult authenticate( Map<String,Object> authToken ) throws
{
if ( authToken.containsKey( NEW_CREDENTIALS ) )
{
return update( authToken, false );
return update( authToken );
}
else
{
Expand All @@ -65,9 +65,9 @@ private AuthenticationResult doAuthenticate( Map<String,Object> authToken ) thro
{
try
{
SecurityContext securityContext = authManager.login( authToken );
LoginContext loginContext = authManager.login( authToken );

switch ( securityContext.subject().getAuthenticationResult() )
switch ( loginContext.subject().getAuthenticationResult() )
{
case SUCCESS:
case PASSWORD_CHANGE_REQUIRED:
Expand All @@ -78,36 +78,36 @@ private AuthenticationResult doAuthenticate( Map<String,Object> authToken ) thro
throw new AuthenticationException( Status.Security.Unauthorized );
}

return new BasicAuthenticationResult( securityContext );
return new BasicAuthenticationResult( loginContext );
}
catch ( InvalidAuthTokenException e )
{
throw new AuthenticationException( e.status(), e.getMessage() );
}
}

private AuthenticationResult update( Map<String,Object> authToken, boolean requiresPasswordChange )
private AuthenticationResult update( Map<String,Object> authToken )
throws AuthenticationException
{
try
{
SecurityContext securityContext = authManager.login( authToken );
LoginContext loginContext = authManager.login( authToken );

switch ( securityContext.subject().getAuthenticationResult() )
switch ( loginContext.subject().getAuthenticationResult() )
{
case SUCCESS:
case PASSWORD_CHANGE_REQUIRED:
String newPassword = AuthToken.safeCast( NEW_CREDENTIALS, authToken );
String username = AuthToken.safeCast( PRINCIPAL, authToken );
userManagerSupplier.getUserManager( securityContext )
.setUserPassword( username, newPassword, requiresPasswordChange );
securityContext.subject().setPasswordChangeNoLongerRequired();
userManagerSupplier.getUserManager( loginContext.subject(), false )
.setUserPassword( username, newPassword, false );
loginContext.subject().setPasswordChangeNoLongerRequired();
break;
default:
throw new AuthenticationException( Status.Security.Unauthorized );
}

return new BasicAuthenticationResult( securityContext );
return new BasicAuthenticationResult( loginContext );
}
catch ( AuthorizationViolationException | InvalidArgumentsException | InvalidAuthTokenException e )
{
Expand Down
Expand Up @@ -19,27 +19,27 @@
*/
package org.neo4j.bolt.security.auth;

import org.neo4j.internal.kernel.api.security.SecurityContext;
import org.neo4j.internal.kernel.api.security.LoginContext;

public class BasicAuthenticationResult implements AuthenticationResult
{
private SecurityContext securityContext;
private LoginContext loginContext;

public BasicAuthenticationResult( SecurityContext securityContext )
public BasicAuthenticationResult( LoginContext loginContext )
{
this.securityContext = securityContext;
this.loginContext = loginContext;
}

@Override
public SecurityContext getSecurityContext()
public LoginContext getLoginContext()
{
return securityContext;
return loginContext;
}

@Override
public boolean credentialsExpired()
{
return securityContext.subject().getAuthenticationResult() ==
return loginContext.subject().getAuthenticationResult() ==
org.neo4j.internal.kernel.api.security.AuthenticationResult.PASSWORD_CHANGE_REQUIRED;
}
}
Expand Up @@ -31,8 +31,8 @@
import org.neo4j.function.ThrowingAction;
import org.neo4j.function.ThrowingConsumer;
import org.neo4j.graphdb.TransactionTerminatedException;
import org.neo4j.internal.kernel.api.security.LoginContext;
import org.neo4j.internal.kernel.api.exceptions.KernelException;
import org.neo4j.internal.kernel.api.security.SecurityContext;
import org.neo4j.kernel.api.KernelTransaction;
import org.neo4j.kernel.api.exceptions.Status;
import org.neo4j.kernel.api.exceptions.TransactionFailureException;
Expand Down Expand Up @@ -195,7 +195,7 @@ State run( MutableTransactionState ctx, SPI spi, String statement,
{
if ( BEGIN.matcher( statement ).matches() )
{
ctx.currentTransaction = spi.beginTransaction( ctx.securityContext );
ctx.currentTransaction = spi.beginTransaction( ctx.loginContext );

Bookmark bookmark = Bookmark.fromParamsOrNull( params );
if ( bookmark != null )
Expand Down Expand Up @@ -241,7 +241,7 @@ else if ( ROLLBACK.matcher( statement ).matches() )
}
else
{
ctx.currentTransaction = spi.beginTransaction( ctx.securityContext );
ctx.currentTransaction = spi.beginTransaction( ctx.loginContext );
BoltResultHandle resultHandle = execute( ctx, spi, statement, params );
ctx.currentResultHandle = resultHandle;
ctx.currentResult = resultHandle.start();
Expand Down Expand Up @@ -407,7 +407,7 @@ private static BoltResultHandle executeQuery( MutableTransactionState ctx, SPI s
MapValue params, ThrowingAction<KernelException> onFail )
throws QueryExecutionKernelException
{
return spi.executeQuery( ctx.querySource, ctx.securityContext, statement, params, onFail );
return spi.executeQuery( ctx.querySource, ctx.loginContext, statement, params, onFail );
}

/**
Expand All @@ -424,7 +424,7 @@ interface BoltResultHandle
static class MutableTransactionState
{
/** The current session security context to be used for starting transactions */
final SecurityContext securityContext;
final LoginContext loginContext;

/** The current transaction, if present */
KernelTransaction currentTransaction;
Expand Down Expand Up @@ -455,7 +455,7 @@ public String[] fieldNames()
private MutableTransactionState( AuthenticationResult authenticationResult, Clock clock )
{
this.clock = clock;
this.securityContext = authenticationResult.getSecurityContext();
this.loginContext = authenticationResult.getLoginContext();
}
}

Expand All @@ -465,7 +465,7 @@ interface SPI

long newestEncounteredTxId();

KernelTransaction beginTransaction( SecurityContext securityContext );
KernelTransaction beginTransaction( LoginContext loginContext );

void bindTransactionToCurrentThread( KernelTransaction tx );

Expand All @@ -474,7 +474,7 @@ interface SPI
boolean isPeriodicCommit( String query );

BoltResultHandle executeQuery( BoltQuerySource querySource,
SecurityContext securityContext,
LoginContext loginContext,
String statement,
MapValue params,
ThrowingAction<KernelException> onFail ) throws QueryExecutionKernelException;
Expand Down
Expand Up @@ -28,12 +28,12 @@
import org.neo4j.cypher.internal.javacompat.ExecutionResult;
import org.neo4j.cypher.result.QueryResult;
import org.neo4j.function.ThrowingAction;
import org.neo4j.internal.kernel.api.security.LoginContext;
import org.neo4j.kernel.AvailabilityGuard;
import org.neo4j.kernel.GraphDatabaseQueryService;
import org.neo4j.kernel.api.KernelTransaction;
import org.neo4j.internal.kernel.api.exceptions.KernelException;
import org.neo4j.kernel.api.exceptions.TransactionFailureException;
import org.neo4j.internal.kernel.api.security.SecurityContext;
import org.neo4j.kernel.api.txtracking.TransactionIdTracker;
import org.neo4j.kernel.impl.core.ThreadToStatementContextBridge;
import org.neo4j.kernel.impl.coreapi.InternalTransaction;
Expand Down Expand Up @@ -97,9 +97,9 @@ public long newestEncounteredTxId()
}

@Override
public KernelTransaction beginTransaction( SecurityContext securityContext )
public KernelTransaction beginTransaction( LoginContext loginContext )
{
db.beginTransaction( KernelTransaction.Type.explicit, securityContext );
db.beginTransaction( KernelTransaction.Type.explicit, loginContext );
return txBridge.getKernelTransactionBoundToThisThread( false );
}

Expand All @@ -123,11 +123,11 @@ public boolean isPeriodicCommit( String query )

@Override
public BoltResultHandle executeQuery( BoltQuerySource querySource,
SecurityContext securityContext,
LoginContext loginContext,
String statement,
MapValue params, ThrowingAction<KernelException> onFail ) throws QueryExecutionKernelException
{
InternalTransaction internalTransaction = queryService.beginTransaction( implicit, securityContext );
InternalTransaction internalTransaction = queryService.beginTransaction( implicit, loginContext );
ClientConnectionInfo sourceDetails = new BoltConnectionInfo( querySource.principalName,
querySource.clientName,
querySource.connectionDescriptor.clientAddress(),
Expand Down
Expand Up @@ -60,8 +60,7 @@ public void shouldNotDoAnythingOnSuccess() throws Exception
authentication.authenticate( map( "scheme", "basic", "principal", "mike", "credentials", "secret2" ) );

// Then
assertThat(result.getSecurityContext().mode(), equalTo( AccessMode.Static.FULL));
assertThat( result.getSecurityContext().subject().username(), equalTo( "mike" ) );
assertThat( result.getLoginContext().subject().username(), equalTo( "mike" ) );
}

@Test
Expand Down
Expand Up @@ -32,9 +32,9 @@
import org.neo4j.graphdb.Result;
import org.neo4j.graphdb.Transaction;
import org.neo4j.helpers.collection.Pair;
import org.neo4j.internal.kernel.api.security.LoginContext;
import org.neo4j.kernel.GraphDatabaseQueryService;
import org.neo4j.kernel.api.KernelTransaction;
import org.neo4j.internal.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, SecurityContext.AUTH_DISABLED ) )
try ( InternalTransaction tx = graph.beginTransaction( KernelTransaction.Type.implicit, LoginContext.AUTH_DISABLED ) )
{
Result result = db.execute( query );
result.close();
Expand Down
Expand Up @@ -28,9 +28,9 @@

import org.neo4j.cypher.internal.CommunityCompatibilityFactory;
import org.neo4j.graphdb.Result;
import org.neo4j.internal.kernel.api.security.LoginContext;
import org.neo4j.kernel.GraphDatabaseQueryService;
import org.neo4j.kernel.api.KernelTransaction;
import org.neo4j.internal.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 @@ -66,7 +66,7 @@ public void shouldConvertListsAndMapsWhenPassingFromScalaToJava() throws Excepti

Result result;
try ( InternalTransaction tx = graph
.beginTransaction( KernelTransaction.Type.implicit, SecurityContext.AUTH_DISABLED ) )
.beginTransaction( KernelTransaction.Type.implicit, LoginContext.AUTH_DISABLED ) )
{
String query = "RETURN { key : 'Value' , collectionKey: [{ inner: 'Map1' }, { inner: 'Map2' }]}";
TransactionalContext tc = createTransactionContext( graph, tx, query );
Expand Down
Expand Up @@ -26,7 +26,7 @@ import java.util.concurrent.atomic.AtomicBoolean
import org.neo4j.cypher.internal.{CommunityCompatibilityFactory, ExecutionEngine}
import org.neo4j.graphdb.{TransactionTerminatedException, TransientTransactionFailureException}
import org.neo4j.internal.kernel.api.Transaction.Type
import org.neo4j.internal.kernel.api.security.SecurityContext.AUTH_DISABLED
import org.neo4j.internal.kernel.api.security.LoginContext.AUTH_DISABLED
import org.neo4j.kernel.impl.coreapi.PropertyContainerLocker
import org.neo4j.kernel.impl.query.clientconnection.ClientConnectionInfo
import org.neo4j.kernel.impl.query.{Neo4jTransactionalContextFactory, TransactionalContext, TransactionalContextFactory}
Expand Down
Expand Up @@ -38,7 +38,7 @@ import org.neo4j.cypher.internal.v3_4.expressions.{LabelToken, PropertyKeyToken,
import org.neo4j.cypher.internal.v3_4.logical.plans.SingleQueryExpression
import org.neo4j.graphdb._
import org.neo4j.internal.kernel.api.Transaction.Type
import org.neo4j.internal.kernel.api.security.SecurityContext
import org.neo4j.internal.kernel.api.security.LoginContext
import org.neo4j.kernel.GraphDatabaseQueryService
import org.neo4j.kernel.impl.core.ThreadToStatementContextBridge
import org.neo4j.kernel.impl.coreapi.{InternalTransaction, PropertyContainerLocker}
Expand Down Expand Up @@ -344,7 +344,7 @@ class ActualCostCalculationTest extends CypherFunSuite {
val gds = graph.asInstanceOf[GraphDatabaseCypherService].getGraphDatabaseService

def withTx[T](f: InternalTransaction => T): T = {
val tx = graph.beginTransaction(Type.explicit, SecurityContext.AUTH_DISABLED)
val tx = graph.beginTransaction(Type.explicit, LoginContext.AUTH_DISABLED)
try {
val result = f(tx)
tx.success()
Expand Down
Expand Up @@ -24,7 +24,6 @@ import org.neo4j.cypher.internal.compatibility.v3_4.WrappedMonitors
import org.neo4j.cypher.internal.compatibility.v3_4.runtime._
import org.neo4j.cypher.internal.compatibility.v3_4.runtime.executionplan.procs.ProcedureCallOrSchemaCommandExecutionPlanBuilder
import org.neo4j.cypher.internal.compatibility.v3_4.runtime.phases.CompilationState
import org.neo4j.cypher.internal.planner.v3_4.spi.PlanningAttributes.{Cardinalities, Solveds}
import org.neo4j.cypher.internal.compiler.v3_4._
import org.neo4j.cypher.internal.compiler.v3_4.phases.{CompilationContains, LogicalPlanState}
import org.neo4j.cypher.internal.compiler.v3_4.planner.logical.idp.{IDPQueryGraphSolver, IDPQueryGraphSolverMonitor, SingleComponentPlanner, cartesianProductsOrValueJoins}
Expand All @@ -37,16 +36,17 @@ import org.neo4j.cypher.internal.frontend.v3_4.phases._
import org.neo4j.cypher.internal.frontend.v3_4.prettifier.{ExpressionStringifier, Prettifier}
import org.neo4j.cypher.internal.frontend.v3_4.semantics.SemanticState
import org.neo4j.cypher.internal.javacompat.GraphDatabaseCypherService
import org.neo4j.cypher.internal.planner.v3_4.spi.PlanningAttributes.{Cardinalities, Solveds}
import org.neo4j.cypher.internal.planner.v3_4.spi.{IDPPlannerName, PlanContext, PlannerNameFor}
import org.neo4j.cypher.internal.queryReduction.DDmin.Oracle
import org.neo4j.cypher.internal.runtime.interpreted.TransactionBoundQueryContext.IndexSearchMonitor
import org.neo4j.cypher.internal.runtime.interpreted.{TransactionBoundPlanContext, TransactionBoundQueryContext, TransactionalContextWrapper, ValueConversion}
import org.neo4j.cypher.internal.runtime.{InternalExecutionResult, NormalMode}
import org.neo4j.cypher.internal.util.v3_4.attribution.{IdGen, SequentialIdGen}
import org.neo4j.cypher.internal.util.v3_4.attribution.SequentialIdGen
import org.neo4j.cypher.internal.util.v3_4.test_helpers.{CypherFunSuite, CypherTestSupport}
import org.neo4j.cypher.internal.{CompilerEngineDelegator, ExecutionPlan, RewindableExecutionResult}
import org.neo4j.internal.kernel.api.Transaction
import org.neo4j.internal.kernel.api.security.SecurityContext
import org.neo4j.internal.kernel.api.security.LoginContext
import org.neo4j.kernel.impl.coreapi.{InternalTransaction, PropertyContainerLocker}
import org.neo4j.kernel.impl.query.clientconnection.ClientConnectionInfo.EMBEDDED_CONNECTION
import org.neo4j.kernel.impl.query.{Neo4jTransactionalContextFactory, TransactionalContextFactory}
Expand Down Expand Up @@ -148,8 +148,8 @@ trait CypherReductionSupport extends CypherTestSupport with GraphIcing {
statement: Statement,
parsingBaseState: BaseState,
executeBefore: Option[String]): InternalExecutionResult = {
val explicitTx = graph.beginTransaction(Transaction.Type.explicit, SecurityContext.AUTH_DISABLED)
val implicitTx = graph.beginTransaction(Transaction.Type.`implicit`, SecurityContext.AUTH_DISABLED)
val explicitTx = graph.beginTransaction(Transaction.Type.explicit, LoginContext.AUTH_DISABLED)
val implicitTx = graph.beginTransaction(Transaction.Type.`implicit`, LoginContext.AUTH_DISABLED)
try {
executeBefore match {
case None =>
Expand Down

0 comments on commit 5b27ae1

Please sign in to comment.