Skip to content

Commit

Permalink
Refactor the way we freeze SecurityContext
Browse files Browse the repository at this point in the history
This enables the enterprise classes to get the correct types.
Also fixes a test that did not have the correct assertions.
  • Loading branch information
fickludd committed Oct 21, 2016
1 parent b69b131 commit 148f5eb
Show file tree
Hide file tree
Showing 11 changed files with 188 additions and 46 deletions.
Expand Up @@ -151,7 +151,7 @@ class ExecutionEngine(val queryService: GraphDatabaseQueryService, logProvider:

// Temporarily change access mode during query planning
// NOTE: This will force read allowance if the current transaction did not have it
val revertable = tc.restrictCurrentTransaction(SecurityContext.frozen(tc.securityContext, AccessMode.Static.READ))
val revertable = tc.restrictCurrentTransaction(tc.securityContext.freeze(AccessMode.Static.READ))

val ((plan: ExecutionPlan, extractedParameters), touched) = try {
// fetch plan cache
Expand Down
Expand Up @@ -55,6 +55,18 @@ public AuthSubject subject()
return AuthSubject.ANONYMOUS;
}

@Override
public SecurityContext freeze()
{
return this;
}

@Override
public SecurityContext freeze( AccessMode mode )
{
return new Frozen( subject(), mode );
}

@Override
public AccessMode mode()
{
Expand Down
Expand Up @@ -25,6 +25,9 @@ public interface SecurityContext
AccessMode mode();
AuthSubject subject();

SecurityContext freeze();
SecurityContext freeze( AccessMode mode );

default String defaultString( String name )
{
return String.format( "%s{ securityContext=%s, allowance=%s }", name, subject().username(), mode() );
Expand All @@ -50,34 +53,53 @@ public AuthSubject subject()
{
return AuthSubject.AUTH_DISABLED;
}

@Override
public SecurityContext freeze()
{
return this;
}

@Override
public SecurityContext freeze( AccessMode mode )
{
return new Frozen( subject(), mode );
}
};

static SecurityContext frozen( SecurityContext context, AccessMode accessMode )
class Frozen implements SecurityContext
{
return frozen( context.subject(), accessMode );
}
private final AuthSubject subject;
private final AccessMode mode;

static SecurityContext frozen( AuthSubject subject, AccessMode accessMode )
{
return new SecurityContext()
public Frozen( AuthSubject subject, AccessMode mode )
{
this.subject = subject;
this.mode = mode;
}

@Override
public AccessMode mode()
{
return mode;
}

@Override
public AuthSubject subject()
{
@Override
public AccessMode mode()
{
return accessMode;
}
return subject;
}

@Override
public AuthSubject subject()
{
return subject;
}
@Override
public SecurityContext freeze()
{
return this;
}

@Override
public String toString()
{
return defaultString( "frozen-security-context" );
}
};
@Override
public SecurityContext freeze( AccessMode mode )
{
return new Frozen( subject, mode );
}
}
}
Expand Up @@ -229,7 +229,7 @@ public KernelTransactionImplementation initialize(
this.lastTransactionTimestampWhenStarted = lastTimeStamp;
this.transactionEvent = tracer.beginTransaction();
assert transactionEvent != null : "transactionEvent was null!";
this.securityContext = securityContext;
this.securityContext = securityContext.freeze();
this.transactionId = NOT_COMMITTED_TRANSACTION_ID;
this.commitTime = NOT_COMMITTED_TRANSACTION_COMMIT_TIME;
this.currentTransactionOperations = timeoutMillis > 0 ? operationContainer.guardedParts() : operationContainer.nonGuarderParts();
Expand Down
Expand Up @@ -1553,7 +1553,7 @@ private RawIterator<Object[],ProcedureException> callProcedure(
{
statement.assertOpen();

final SecurityContext procedureSecurityContext = SecurityContext.frozen( tx.securityContext(), override );
final SecurityContext procedureSecurityContext = tx.securityContext().freeze( override );
final RawIterator<Object[],ProcedureException> procedureCall;
try ( KernelTransaction.Revertable ignore = tx.overrideWith( procedureSecurityContext ) )
{
Expand Down Expand Up @@ -1609,7 +1609,7 @@ private Object callFunction(
{
statement.assertOpen();

try ( KernelTransaction.Revertable ignore = tx.overrideWith( SecurityContext.frozen( tx.securityContext(), mode )) )
try ( KernelTransaction.Revertable ignore = tx.overrideWith( tx.securityContext().freeze( mode ) ) )
{
BasicContext ctx = new BasicContext();
ctx.put( Context.KERNEL_TRANSACTION, tx );
Expand Down
Expand Up @@ -118,6 +118,18 @@ public AuthSubject subject()
return authSubject;
}

@Override
public SecurityContext freeze()
{
return this;
}

@Override
public SecurityContext freeze( AccessMode mode )
{
return new Frozen( authSubject, mode );
}

@Override
public AccessMode mode()
{
Expand Down
Expand Up @@ -28,8 +28,26 @@
*/
public interface EnterpriseSecurityContext extends SecurityContext, CouldBeAdmin
{
@Override
EnterpriseSecurityContext freeze();

@Override
EnterpriseSecurityContext freeze( AccessMode mode );

EnterpriseSecurityContext AUTH_DISABLED = new EnterpriseSecurityContext()
{
@Override
public EnterpriseSecurityContext freeze()
{
return this;
}

@Override
public EnterpriseSecurityContext freeze( AccessMode mode )
{
return new Frozen( subject(), mode, isAdmin() );
}

@Override
public AuthSubject subject()
{
Expand All @@ -54,4 +72,48 @@ public boolean isAdmin()
return true;
}
};

class Frozen implements EnterpriseSecurityContext
{
private final AuthSubject subject;
private final AccessMode mode;
private final boolean isAdmin;

public Frozen( AuthSubject subject, AccessMode mode, boolean isAdmin )
{
this.subject = subject;
this.mode = mode;
this.isAdmin = isAdmin;
}

@Override
public boolean isAdmin()
{
return isAdmin;
}

@Override
public AccessMode mode()
{
return mode;
}

@Override
public AuthSubject subject()
{
return subject;
}

@Override
public EnterpriseSecurityContext freeze()
{
return this;
}

@Override
public EnterpriseSecurityContext freeze( AccessMode mode )
{
return new EnterpriseSecurityContext.Frozen( subject, mode, isAdmin );
}
}
}
Expand Up @@ -23,7 +23,6 @@
import java.util.List;
import java.util.Set;

import org.neo4j.graphdb.security.AuthorizationViolationException;
import org.neo4j.kernel.api.KernelTransaction;
import org.neo4j.kernel.api.KernelTransactionHandle;
import org.neo4j.kernel.api.bolt.BoltConnectionTracker;
Expand All @@ -38,7 +37,6 @@
import org.neo4j.server.security.enterprise.log.SecurityLog;

import static java.util.Collections.emptyList;
import static org.neo4j.graphdb.security.AuthorizationViolationException.PERMISSION_DENIED;

@SuppressWarnings( "WeakerAccess" )
public class AuthProceduresBase
Expand Down
Expand Up @@ -83,6 +83,18 @@ public String toString()
return defaultString( "enterprise-security-context" );
}

@Override
public EnterpriseSecurityContext freeze()
{
return new Frozen( neoShiroSubject, mode(), isAdmin() );
}

@Override
public EnterpriseSecurityContext freeze( AccessMode mode )
{
return new Frozen( neoShiroSubject, mode, isAdmin() );
}

private static class StandardAccessMode implements AccessMode
{
private final boolean allowsReads;
Expand Down
Expand Up @@ -96,6 +96,18 @@ private EnterpriseSecurityContext createFakeAnonymousEnterpriseSecurityContext()
{
return new EnterpriseSecurityContext()
{
@Override
public EnterpriseSecurityContext freeze()
{
return this;
}

@Override
public EnterpriseSecurityContext freeze( AccessMode mode )
{
return new EnterpriseSecurityContext.Frozen( subject(), mode, isAdmin() );
}

AnonymousContext inner = AnonymousContext.none();

@Override
Expand Down

0 comments on commit 148f5eb

Please sign in to comment.