Skip to content

Commit

Permalink
Refactored away ACCESS_MODE from Procedure Context
Browse files Browse the repository at this point in the history
  • Loading branch information
craigtaverner authored and OliviaYtterbrink committed Jul 5, 2016
1 parent 3da072f commit fbbf891
Show file tree
Hide file tree
Showing 16 changed files with 249 additions and 124 deletions.
Expand Up @@ -26,7 +26,6 @@
import org.neo4j.kernel.api.KernelTransaction;
import org.neo4j.kernel.api.exceptions.ProcedureException;
import org.neo4j.kernel.api.exceptions.Status;
import org.neo4j.kernel.api.security.AccessMode;
import org.neo4j.kernel.api.security.AuthSubject;

public interface CallableProcedure
Expand All @@ -43,7 +42,6 @@ public interface CallableProcedure
interface Context
{
Key<KernelTransaction> KERNEL_TRANSACTION = Key.key( "KernelTransaction", KernelTransaction.class );
Key<AccessMode> ACCESS_MODE = Key.key( "AccessMode", AccessMode.class );
Key<AuthSubject> AUTH_SUBJECT = Key.key( "AuthSubject", AuthSubject.class );
Key<Thread> THREAD = Key.key( "Thread", Thread.class );

Expand Down

This file was deleted.

Expand Up @@ -57,8 +57,5 @@ public void accept( Procedures procs ) throws ProcedureException
procs.register( new ListProceduresProcedure( procedureName( "dbms", "procedures" ) ) );
procs.register( new ListComponentsProcedure( procedureName( "dbms", "components" ), neo4jVersion, neo4jEdition ) );
procs.register( new JmxQueryProcedure( procedureName( "dbms", "queryJmx" ), ManagementFactory.getPlatformMBeanServer() ) );

// These are 'dbms'-namespaced procedures for dealing with authentication and authorization-oriented operations
procs.register( new AlterUserPasswordProcedure( procedureName( "dbms", "changePassword" ) ) );
}
}
Expand Up @@ -43,7 +43,6 @@ public RawIterator<Object[],ProcedureException> procedureCallDbms( ProcedureSign
Object[] input, AccessMode accessMode ) throws ProcedureException
{
CallableProcedure.BasicContext ctx = new CallableProcedure.BasicContext();
ctx.put( CallableProcedure.Context.ACCESS_MODE, accessMode );
if ( accessMode instanceof AuthSubject )
{
AuthSubject subject = (AuthSubject) accessMode;
Expand Down
Expand Up @@ -31,6 +31,7 @@
import org.neo4j.graphdb.Relationship;
import org.neo4j.graphdb.RelationshipType;
import org.neo4j.graphdb.factory.GraphDatabaseSettings;
import org.neo4j.helpers.Service;
import org.neo4j.io.fs.FileSystemAbstraction;
import org.neo4j.io.pagecache.PageCache;
import org.neo4j.kernel.AvailabilityGuard;
Expand All @@ -41,6 +42,7 @@
import org.neo4j.kernel.api.Statement;
import org.neo4j.kernel.api.dbms.DbmsOperations;
import org.neo4j.kernel.api.legacyindex.AutoIndexing;
import org.neo4j.kernel.api.security.AuthSubject;
import org.neo4j.kernel.builtinprocs.BuiltInProcedures;
import org.neo4j.kernel.configuration.Config;
import org.neo4j.kernel.guard.Guard;
Expand Down Expand Up @@ -77,6 +79,7 @@
import org.neo4j.kernel.lifecycle.LifecycleAdapter;
import org.neo4j.logging.Log;

import static org.neo4j.kernel.api.proc.CallableProcedure.Context.AUTH_SUBJECT;
import static org.neo4j.kernel.api.proc.CallableProcedure.Context.KERNEL_TRANSACTION;
import static org.neo4j.kernel.api.proc.Neo4jTypes.NTNode;
import static org.neo4j.kernel.api.proc.Neo4jTypes.NTPath;
Expand Down Expand Up @@ -376,6 +379,14 @@ private Procedures setupProcedures( PlatformModule platform, EditionModule editi
procedures.registerComponent( KernelTransaction.class, ( ctx ) -> ctx.get( KERNEL_TRANSACTION ) );
procedures.registerComponent( GraphDatabaseAPI.class, ( ctx ) -> platform.graphDatabaseFacade );

// Security procedures
procedures.registerComponent( AuthSubject.class, ctx -> ctx.get( AUTH_SUBJECT ) );
for ( ProceduresProvider candidate : Service.load( ProceduresProvider.class ) )
{
candidate.registerProcedures( procedures );
}

// Edition procedures
editionModule.registerProcedures(procedures);

return procedures;
Expand Down
@@ -0,0 +1,27 @@
/*
* 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.impl.factory;

import org.neo4j.kernel.impl.proc.Procedures;

public interface ProceduresProvider
{
void registerProcedures( Procedures procedures );
}
Expand Up @@ -149,7 +149,6 @@ public void shouldListCorrectBuiltinProcedures() throws Throwable
record( "db.labels", "db.labels() :: (label :: STRING?)" ),
record( "db.propertyKeys", "db.propertyKeys() :: (propertyKey :: STRING?)" ),
record( "db.relationshipTypes", "db.relationshipTypes() :: (relationshipType :: STRING?)" ),
record( "dbms.changePassword", "dbms.changePassword(password :: STRING?) :: ()" ),
record( "dbms.components", "dbms.components() :: (name :: STRING?, versions :: LIST? OF STRING?, edition :: STRING?)" ),
record( "dbms.procedures", "dbms.procedures() :: (name :: STRING?, signature :: STRING?)" ),
record( "dbms.queryJmx", "dbms.queryJmx(query :: STRING?) :: (name :: STRING?, description :: STRING?, attributes :: MAP?)")
Expand Down
Expand Up @@ -168,7 +168,6 @@ public void listProcedures() throws Throwable
"STRING?)"} ),
equalTo( new Object[]{"dbms.components", "dbms.components() :: (name :: STRING?, versions :: LIST? OF" +
" STRING?, edition :: STRING?)"} ),
equalTo( new Object[]{"dbms.changePassword", "dbms.changePassword(password :: STRING?) :: ()"} ),
equalTo( new Object[]{"dbms.queryJmx", "dbms.queryJmx(query :: STRING?) :: (name :: STRING?, " +
"description :: STRING?, attributes :: MAP?)"} )
) );
Expand All @@ -191,39 +190,18 @@ public void failWhenCallingListProceduresInDbmsMode() throws Throwable
}

@Test
public void callChangePasswordWithAccessModeInDbmsMode() throws Throwable
{
// Given
Object[] inputArray = new Object[1];
inputArray[0] = "newPassword";
AuthSubject authSubject = mock( AuthSubject.class );

// When
RawIterator<Object[], ProcedureException> stream = dbmsOperations()
.procedureCallDbms( procedureName( "dbms", "changePassword" ), inputArray, authSubject );

// Then
verify( authSubject ).setPassword( (String) inputArray[0] );
assertThat( asList( stream ), emptyIterable() );
}

@Test
public void shouldFailWhenChangePasswordWithStaticAccessModeInDbmsMode() throws Throwable
public void failWhenCallingNonExistingProcedures() throws Throwable
{
try
{
// Given
Object[] inputArray = new Object[1];
inputArray[0] = "newPassword";

// When
dbmsOperations().procedureCallDbms( procedureName( "dbms", "changePassword" ), inputArray, Static.NONE );
fail( "Should have failed." );
dbmsOperations().procedureCallDbms( procedureName( "dbms", "iDoNotExist" ), new Object[0], Static.NONE );
fail( "This should never get here" );
}
catch ( Exception e )
{
// Then
assertThat( e.getClass(), equalTo( AuthorizationViolationException.class ) );
assertThat( e.getClass(), equalTo( ProcedureException.class ) );
}
}

Expand Down
14 changes: 14 additions & 0 deletions community/security/pom.xml
Expand Up @@ -72,6 +72,20 @@ the relevant Commercial Agreement.
</dependency>

<!-- Test dependencies -->
<dependency>
<groupId>org.neo4j</groupId>
<artifactId>neo4j-kernel</artifactId>
<version>${project.version}</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.neo4j</groupId>
<artifactId>neo4j-io</artifactId>
<version>${project.version}</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.neo4j</groupId>
<artifactId>neo4j-logging</artifactId>
Expand Down
@@ -0,0 +1,47 @@
/*
* 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.server.security.auth;

import org.neo4j.helpers.Service;
import org.neo4j.kernel.api.exceptions.KernelException;
import org.neo4j.kernel.impl.factory.ProceduresProvider;
import org.neo4j.kernel.impl.proc.Procedures;

@Service.Implementation( ProceduresProvider.class )
public class AuthProceduresProvider extends Service implements ProceduresProvider
{
public AuthProceduresProvider()
{
super( "auth-procedures-provider" );
}

@Override
public void registerProcedures( Procedures procedures )
{
try
{
procedures.register( UserProcedures.class );
}
catch ( KernelException e )
{
throw new RuntimeException( e );
}
}
}
@@ -0,0 +1,42 @@
/*
* 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.server.security.auth;

import java.io.IOException;

import org.neo4j.kernel.api.security.AuthSubject;
import org.neo4j.kernel.api.security.exception.IllegalCredentialsException;
import org.neo4j.procedure.Context;
import org.neo4j.procedure.Name;
import org.neo4j.procedure.Procedure;

import static org.neo4j.procedure.Procedure.Mode.DBMS;

public class UserProcedures
{
@Context
public AuthSubject authSubject;

@Procedure( name = "dbms.changePassword", mode = DBMS )
public void changePassword( @Name( "password" ) String password ) throws IllegalCredentialsException, IOException
{
authSubject.setPassword( password );
}
}
@@ -0,0 +1 @@
org.neo4j.server.security.auth.AuthProceduresProvider

0 comments on commit fbbf891

Please sign in to comment.