Skip to content

Commit

Permalink
Fixed bugs in neo4j-admin set-password and added IT
Browse files Browse the repository at this point in the history
  • Loading branch information
craigtaverner committed Aug 12, 2016
1 parent d3d9103 commit 23da4f8
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 13 deletions.
Expand Up @@ -44,10 +44,10 @@

public class SetPasswordCommand implements AdminCommand
{
public class Provider extends AdminCommand.Provider
public static class Provider extends AdminCommand.Provider
{

protected Provider()
public Provider()
{
super( "set-password" );
}
Expand Down
@@ -0,0 +1 @@
org.neo4j.commandline.admin.security.SetPasswordCommand$Provider
Expand Up @@ -24,9 +24,15 @@
import org.junit.rules.RuleChain;

import java.io.File;
import java.io.IOException;
import java.nio.file.Path;

import org.neo4j.commandline.admin.AdminTool;
import org.neo4j.commandline.admin.CommandFailed;
import org.neo4j.commandline.admin.CommandLocator;
import org.neo4j.commandline.admin.IncorrectUsage;
import org.neo4j.commandline.admin.OutsideWorld;
import org.neo4j.kernel.api.security.exception.InvalidArgumentsException;
import org.neo4j.logging.NullLogProvider;
import org.neo4j.server.security.auth.Credential;
import org.neo4j.server.security.auth.FileUserRepository;
Expand All @@ -38,10 +44,15 @@
import static org.hamcrest.Matchers.not;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.fail;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;

public class SetPasswordCommandTest
{
private TargetDirectory.TestDirectory testDir = TargetDirectory.testDirForTest( getClass() );
private static String password_change_required = "password_change_required";

@Rule
public RuleChain ruleChain = RuleChain.outerRule( testDir );
Expand Down Expand Up @@ -104,26 +115,96 @@ public void shouldFailWitNonExistingUser() throws Exception
public void shouldRunSetPasswordCommand() throws Throwable
{
// Given - new user that requires password change
String password_change_required = "password_change_required";
File graphDir = testDir.graphDbDir();
File authFile = new File( new File( new File( graphDir, "data" ), "dbms" ), "auth.db" );
FileUserRepository beforeUsers = new FileUserRepository( authFile.toPath(), NullLogProvider.getInstance() );
User before = new User.Builder( "neo4j", Credential.forPassword( "neo4j" ) ).withRequiredPasswordChange( true )
.build();
beforeUsers.create( before );
assertThat( "User should require password change", before.getFlags(), hasItem( password_change_required ) );
createTestUser("neo4j", "neo4j");
assertUserRequiresPasswordChange( "neo4j" );

// When - the admin command sets the password
File confDir = new File( graphDir, "conf" );
SetPasswordCommand setPasswordCommand = new SetPasswordCommand( graphDir.toPath(), confDir.toPath() );
setPasswordCommand.execute( new String[]{"neo4j", "abc"} );

// Then - the new user no longer requires a password change
FileUserRepository afterUsers = new FileUserRepository( authFile.toPath(), NullLogProvider.getInstance() );
assertUserDoesNotRequirePasswordChange( "neo4j" );
}

@Test
public void shouldRunAdminToolWithSetPasswordCommandAndNoArgs() throws Throwable
{
// Given a user that requires password change
createTestUser("neo4j", "neo4j");
assertUserRequiresPasswordChange( "neo4j" );

// When running the neo4j-admin tool with incorrect parameters
Path homeDir = testDir.graphDbDir().toPath();
Path configDir = testDir.directory( "conf" ).toPath();
OutsideWorld out = mock( OutsideWorld.class );
AdminTool tool = new AdminTool( CommandLocator.fromServiceLocator(), out, true );
tool.execute( homeDir, configDir, "set-password" );

// Then we get error output and user still requires password change
verify( out, times( 0 ) ).stdOutLine( anyString() );
verify( out ).stdErrLine( "neo4j-admin set-password <username> <password>" );
verify( out ).stdErrLine( " Sets the password for the specified user and removes the password change " );
verify( out ).stdErrLine( " requirement" );
verify( out ).stdErrLine( "Missing arguments: expected username and password" );
assertUserRequiresPasswordChange( "neo4j" );
}

@Test
public void shouldRunAdminToolWithSetPasswordCommandAndCorrectArgs() throws Throwable
{
// Given a user that requires password change
createTestUser("neo4j", "neo4j");
assertUserRequiresPasswordChange( "neo4j" );

// When running the neo4j-admin tool with correct parameters
Path homeDir = testDir.graphDbDir().toPath();
Path configDir = testDir.directory( "conf" ).toPath();
OutsideWorld out = mock( OutsideWorld.class );
AdminTool tool = new AdminTool( CommandLocator.fromServiceLocator(), out, true );
tool.execute( homeDir, configDir, "set-password", "neo4j", "abc" );

// Then we get no error output and the user no longer requires password change
verify( out, times( 0 ) ).stdOutLine( anyString() );
verify( out, times( 0 ) ).stdErrLine( anyString() );
verify( out ).exit(0);
assertUserDoesNotRequirePasswordChange( "neo4j" );
}

private File authFile()
{
return new File( new File( new File( testDir.graphDbDir(), "data" ), "dbms" ), "auth.db" );
}

private User createTestUser(String username, String password) throws IOException, InvalidArgumentsException
{
FileUserRepository users = new FileUserRepository( authFile().toPath(), NullLogProvider.getInstance() );
User user = new User.Builder( username, Credential.forPassword( password ) ).withRequiredPasswordChange( true )
.build();
users.create( user );
return user;
}

private User getUser(String username) throws Throwable
{
FileUserRepository afterUsers = new FileUserRepository( authFile().toPath(), NullLogProvider.getInstance() );
afterUsers.start(); // load users from disk
User after = afterUsers.getUserByName( "neo4j" );
assertThat( "User should require password change", after.getFlags(),
not( hasItem( password_change_required ) ) );
return afterUsers.getUserByName( username );
}

private void assertUserRequiresPasswordChange(String username) throws Throwable
{
User user = getUser( username );
assertThat( "User should require password change", user.getFlags(), hasItem( password_change_required ) );

}

private void assertUserDoesNotRequirePasswordChange(String username) throws Throwable
{
User user = getUser( username );
assertThat( "User should not require password change", user.getFlags(),
not( hasItem( password_change_required ) ) );

}
}

0 comments on commit 23da4f8

Please sign in to comment.