Skip to content

Commit

Permalink
Ensure set-password respects same default user behaviour as server
Browse files Browse the repository at this point in the history
  • Loading branch information
craigtaverner committed Aug 18, 2016
1 parent ecc06ab commit ba0c85a
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 30 deletions.
Expand Up @@ -87,7 +87,6 @@ private void configure( GraphDatabaseBuilder builder, File storeDir )
super.configure( builder ); super.configure( builder );
// Reduce the default page cache memory size to 8 mega-bytes for test databases. // Reduce the default page cache memory size to 8 mega-bytes for test databases.
builder.setConfig( GraphDatabaseSettings.pagecache_memory, "8m" ); builder.setConfig( GraphDatabaseSettings.pagecache_memory, "8m" );
builder.setConfig( GraphDatabaseSettings.auth_store, tempFile( "auth" ).toString() );
builder.setConfig( GraphDatabaseSettings.logs_directory, new File( storeDir, "logs" ).getAbsolutePath() ); builder.setConfig( GraphDatabaseSettings.logs_directory, new File( storeDir, "logs" ).getAbsolutePath() );
} }


Expand Down
Expand Up @@ -107,6 +107,7 @@ public void execute( String[] args ) throws IncorrectUsage, CommandFailed
userRepository.start(); userRepository.start();
PasswordPolicy passwordPolicy = new BasicPasswordPolicy(); PasswordPolicy passwordPolicy = new BasicPasswordPolicy();
BasicAuthManager authManager = new BasicAuthManager( userRepository, passwordPolicy, systemUTC() ); BasicAuthManager authManager = new BasicAuthManager( userRepository, passwordPolicy, systemUTC() );
authManager.start(); // required to setup default users
try try
{ {
authManager.setUserPassword( username, password ); authManager.setUserPassword( username, password );
Expand Down
Expand Up @@ -113,14 +113,30 @@ public void shouldFailWitNonExistingUser() throws Exception
} }


@Test @Test
public void shouldRunSetPasswordCommandWithExistinguser() throws Throwable public void shouldRunSetPasswordCommandWithDefaultUser() throws Throwable
{ {
// Given - new user that requires password change // Given - no created user

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

// Then - the default user does not require a password change
assertUserDoesNotRequirePasswordChange( "neo4j" );
}

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


// When - the admin command sets the password // When - the admin command sets the password
File graphDir = testDir.graphDbDir();
File confDir = new File( graphDir, "conf" ); File confDir = new File( graphDir, "conf" );
SetPasswordCommand setPasswordCommand = SetPasswordCommand setPasswordCommand =
new SetPasswordCommand( graphDir.toPath(), confDir.toPath(), mock( OutsideWorld.class ) ); new SetPasswordCommand( graphDir.toPath(), confDir.toPath(), mock( OutsideWorld.class ) );
Expand All @@ -134,9 +150,9 @@ public void shouldRunSetPasswordCommandWithExistinguser() throws Throwable
public void shouldRunSetPasswordCommandWithoutExistingUser() throws Throwable public void shouldRunSetPasswordCommandWithoutExistingUser() throws Throwable
{ {
// Given - no user // Given - no user
File graphDir = testDir.graphDbDir();


// When - the admin command sets the password // When - the admin command sets the password
File graphDir = testDir.graphDbDir();
File confDir = new File( graphDir, "conf" ); File confDir = new File( graphDir, "conf" );
SetPasswordCommand setPasswordCommand = SetPasswordCommand setPasswordCommand =
new SetPasswordCommand( graphDir.toPath(), confDir.toPath(), mock( OutsideWorld.class ) ); new SetPasswordCommand( graphDir.toPath(), confDir.toPath(), mock( OutsideWorld.class ) );
Expand All @@ -150,11 +166,11 @@ public void shouldRunSetPasswordCommandWithoutExistingUser() throws Throwable
public void shouldFailToRunSetPasswordCommandWithoutExistingUser() throws Throwable public void shouldFailToRunSetPasswordCommandWithoutExistingUser() throws Throwable
{ {
// Given - no user // Given - no user
File graphDir = testDir.graphDbDir();


// When - the admin command sets the password // When - the admin command sets the password
try try
{ {
File graphDir = testDir.graphDbDir();
File confDir = new File( graphDir, "conf" ); File confDir = new File( graphDir, "conf" );
SetPasswordCommand setPasswordCommand = SetPasswordCommand setPasswordCommand =
new SetPasswordCommand( graphDir.toPath(), confDir.toPath(), mock( OutsideWorld.class ) ); new SetPasswordCommand( graphDir.toPath(), confDir.toPath(), mock( OutsideWorld.class ) );
Expand All @@ -170,9 +186,7 @@ public void shouldFailToRunSetPasswordCommandWithoutExistingUser() throws Throwa
@Test @Test
public void shouldRunAdminToolWithSetPasswordCommandAndNoArgs() throws Throwable public void shouldRunAdminToolWithSetPasswordCommandAndNoArgs() throws Throwable
{ {
// Given a user that requires password change // Given only default user
createTestUser("neo4j", "neo4j");
assertUserRequiresPasswordChange( "neo4j" );


// When running the neo4j-admin tool with incorrect parameters // When running the neo4j-admin tool with incorrect parameters
Path homeDir = testDir.graphDbDir().toPath(); Path homeDir = testDir.graphDbDir().toPath();
Expand All @@ -189,7 +203,6 @@ public void shouldRunAdminToolWithSetPasswordCommandAndNoArgs() throws Throwable
verify( out ).stdErrLine( " you specify the option --create=true." ); verify( out ).stdErrLine( " you specify the option --create=true." );
verify( out ).stdErrLine( "Missing arguments: expected username and password" ); verify( out ).stdErrLine( "Missing arguments: expected username and password" );
verify( out ).exit( 1 ); verify( out ).exit( 1 );
assertUserRequiresPasswordChange( "neo4j" );
} }


@Test @Test
Expand All @@ -202,11 +215,11 @@ public void shouldRunAdminToolWithSetPasswordCommandAndArgsButNoUser() throws Th
Path configDir = testDir.directory( "conf" ).toPath(); Path configDir = testDir.directory( "conf" ).toPath();
OutsideWorld out = mock( OutsideWorld.class ); OutsideWorld out = mock( OutsideWorld.class );
AdminTool tool = new AdminTool( CommandLocator.fromServiceLocator(), out, true ); AdminTool tool = new AdminTool( CommandLocator.fromServiceLocator(), out, true );
tool.execute( homeDir, configDir, "set-password", "neo4j", "abc" ); tool.execute( homeDir, configDir, "set-password", "another", "abc" );


// Then we get error output and user still requires password change // Then we get error output and user still requires password change
verify( out, times( 0 ) ).stdOutLine( anyString() ); verify( out, times( 0 ) ).stdOutLine( anyString() );
verify( out ).stdErrLine( "command failed: Failed to set password for 'neo4j': User 'neo4j' does not exist" ); verify( out ).stdErrLine( "command failed: Failed to set password for 'another': User 'another' does not exist" );
verify( out ).exit( 1 ); verify( out ).exit( 1 );
} }


Expand All @@ -220,20 +233,18 @@ public void shouldRunAdminToolWithSetPasswordCommandAndArgsButNoUserAndCreateFal
Path configDir = testDir.directory( "conf" ).toPath(); Path configDir = testDir.directory( "conf" ).toPath();
OutsideWorld out = mock( OutsideWorld.class ); OutsideWorld out = mock( OutsideWorld.class );
AdminTool tool = new AdminTool( CommandLocator.fromServiceLocator(), out, true ); AdminTool tool = new AdminTool( CommandLocator.fromServiceLocator(), out, true );
tool.execute( homeDir, configDir, "set-password", "neo4j", "abc", "--create=false" ); tool.execute( homeDir, configDir, "set-password", "another", "abc", "--create=false" );


// Then we get error output and user still requires password change // Then we get error output and user still requires password change
verify( out, times( 0 ) ).stdOutLine( anyString() ); verify( out, times( 0 ) ).stdOutLine( anyString() );
verify( out ).stdErrLine( "command failed: Failed to set password for 'neo4j': User 'neo4j' does not exist" ); verify( out ).stdErrLine( "command failed: Failed to set password for 'another': User 'another' does not exist" );
verify( out ).exit( 1 ); verify( out ).exit( 1 );
} }


@Test @Test
public void shouldRunAdminToolWithSetPasswordCommandAndExistingUser() throws Throwable public void shouldRunAdminToolWithSetPasswordCommandAndDefaultUser() throws Throwable
{ {
// Given a user that requires password change // Given default state (only default user)
createTestUser("neo4j", "neo4j");
assertUserRequiresPasswordChange( "neo4j" );


// When running the neo4j-admin tool with correct parameters // When running the neo4j-admin tool with correct parameters
Path homeDir = testDir.graphDbDir().toPath(); Path homeDir = testDir.graphDbDir().toPath();
Expand All @@ -249,6 +260,27 @@ public void shouldRunAdminToolWithSetPasswordCommandAndExistingUser() throws Thr
assertUserDoesNotRequirePasswordChange( "neo4j" ); assertUserDoesNotRequirePasswordChange( "neo4j" );
} }


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

// 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", "another", "abc" );

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

@Test @Test
public void shouldRunAdminToolWithSetPasswordCommandAndNoExistingUser() throws Throwable public void shouldRunAdminToolWithSetPasswordCommandAndNoExistingUser() throws Throwable
{ {
Expand All @@ -259,13 +291,13 @@ public void shouldRunAdminToolWithSetPasswordCommandAndNoExistingUser() throws T
Path configDir = testDir.directory( "conf" ).toPath(); Path configDir = testDir.directory( "conf" ).toPath();
OutsideWorld out = mock( OutsideWorld.class ); OutsideWorld out = mock( OutsideWorld.class );
AdminTool tool = new AdminTool( CommandLocator.fromServiceLocator(), out, true ); AdminTool tool = new AdminTool( CommandLocator.fromServiceLocator(), out, true );
tool.execute( homeDir, configDir, "set-password", "--create=true", "neo4j", "abc" ); tool.execute( homeDir, configDir, "set-password", "--create=true", "another", "abc" );


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


@Test @Test
Expand Down
Expand Up @@ -202,8 +202,8 @@ public void shouldDefaultToCorrectValueForAuthStoreLocation() throws IOException
.build(); .build();
Config config = configLoader.loadConfig( Optional.of( folder.getRoot() ), configFile ); Config config = configLoader.loadConfig( Optional.of( folder.getRoot() ), configFile );


assertThat( config.get( GraphDatabaseSettings.auth_store ), assertThat( config.get( DatabaseManagementSystemSettings.auth_store_directory ),
is( new File( folder.getRoot(), "data/dbms/auth" ).getAbsoluteFile() ) ); is( new File( folder.getRoot(), "data/dbms" ).getAbsoluteFile() ) );
} }


@Test @Test
Expand All @@ -214,8 +214,8 @@ public void shouldSetAValueForAuthStoreLocation() throws IOException
.build(); .build();
Config config = configLoader.loadConfig( Optional.of( folder.getRoot() ), configFile ); Config config = configLoader.loadConfig( Optional.of( folder.getRoot() ), configFile );


assertThat( config.get( GraphDatabaseSettings.auth_store ), assertThat( config.get( DatabaseManagementSystemSettings.auth_store_directory ),
is( new File( folder.getRoot(), "the-data-dir/dbms/auth" ).getAbsoluteFile() ) ); is( new File( folder.getRoot(), "the-data-dir/dbms" ).getAbsoluteFile() ) );
} }


@Test @Test
Expand Down
Expand Up @@ -132,10 +132,24 @@ public void start() throws Throwable
userRepository.start(); userRepository.start();
roleRepository.start(); roleRepository.start();


ensureDefaultUsersAndRoles(); ensureDefaultUsers();
ensureDefaultRoles();
} }


private void ensureDefaultUsersAndRoles() throws IOException, InvalidArgumentsException /* Adds neo4j user if no users exist */
private void ensureDefaultUsers() throws IOException, InvalidArgumentsException
{
if ( authenticationEnabled || authorizationEnabled )
{
if ( numberOfUsers() == 0 )
{
newUser( "neo4j", "neo4j", true );
}
}
}

/* Builds all predefined roles if no roles exist. Adds 'neo4j' to admin role if no admin is assigned */
private void ensureDefaultRoles() throws IOException, InvalidArgumentsException
{ {
if ( authenticationEnabled || authorizationEnabled ) if ( authenticationEnabled || authorizationEnabled )
{ {
Expand All @@ -146,11 +160,12 @@ private void ensureDefaultUsersAndRoles() throws IOException, InvalidArgumentsEx
newRole( role ); newRole( role );
} }
} }
if ( numberOfUsers() == 0 ) if ( this.getUsernamesForRole( PredefinedRolesBuilder.ADMIN ).size() == 0 )
{ {
newUser( "neo4j", "neo4j", true ); if ( getAllUsernames().contains( "neo4j" ) )
// Make the default user admin for now {
addUserToRole( "neo4j", PredefinedRolesBuilder.ADMIN ); addUserToRole( "neo4j", PredefinedRolesBuilder.ADMIN );
}
} }
} }
} }
Expand Down

0 comments on commit ba0c85a

Please sign in to comment.