Skip to content

Commit

Permalink
Merge pull request #7815 from boggle/3.1-authprocs-cleanup
Browse files Browse the repository at this point in the history
Add requirePasswordChange with a default of true to all procedures that enable access for a user
  • Loading branch information
craigtaverner committed Aug 31, 2016
2 parents 2e27f92 + 534686f commit 1f22cd0
Show file tree
Hide file tree
Showing 22 changed files with 223 additions and 98 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -56,13 +56,12 @@ public AuthenticationResult authenticate( Map<String,Object> authToken ) throws
{
if ( !SCHEME.equals( authToken.get( SCHEME_KEY ) ) )
{
throw new AuthenticationException( Status.Security.Unauthorized,
"Missing username and password" );
throw new AuthenticationException( Status.Security.Unauthorized, "Missing username and password" );
}

if ( authToken.containsKey( NEW_CREDENTIALS ) )
{
return update( authToken );
return update( authToken, false );
}
else
{
Expand Down Expand Up @@ -96,7 +95,8 @@ private AuthenticationResult doAuthenticate( Map<String,Object> authToken ) thro
}
}

private AuthenticationResult update( Map<String,Object> authToken ) throws AuthenticationException
private AuthenticationResult update( Map<String,Object> authToken, boolean requiresPasswordChange )
throws AuthenticationException
{
try
{
Expand All @@ -107,7 +107,7 @@ private AuthenticationResult update( Map<String,Object> authToken ) throws Authe
case SUCCESS:
case PASSWORD_CHANGE_REQUIRED:
String newPassword = AuthToken.safeCast( NEW_CREDENTIALS, authToken );
authSubject.setPassword( newPassword );
authSubject.setPassword( newPassword, requiresPasswordChange );
break;
default:
throw new AuthenticationException( Status.Security.Unauthorized );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,11 @@ public interface AuthSubject extends AccessMode
/**
* Set the password for the AuthSubject
* @param password The new password
* @param requirePasswordChange
* @throws IOException If the new credentials cannot be serialized to disk.
* @throws InvalidArgumentsException If the new password is invalid.
*/
void setPassword( String password ) throws IOException, InvalidArgumentsException;
void setPassword( String password, boolean requirePasswordChange ) throws IOException, InvalidArgumentsException;

/**
* Implementation to use when authentication has not yet been performed. Allows nothing.
Expand All @@ -56,7 +57,8 @@ public AuthenticationResult getAuthenticationResult()
}

@Override
public void setPassword( String password ) throws IOException, InvalidArgumentsException
public void setPassword( String password, boolean requirePasswordChange )
throws IOException, InvalidArgumentsException
{
throw new AuthorizationViolationException( "Anonymous cannot change password" );
}
Expand Down Expand Up @@ -151,7 +153,8 @@ public AuthenticationResult getAuthenticationResult()
}

@Override
public void setPassword( String password ) throws IOException, InvalidArgumentsException
public void setPassword( String password, boolean requirePasswordChange )
throws IOException, InvalidArgumentsException
{
}
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;

import org.neo4j.commandline.admin.AdminCommand;
Expand Down Expand Up @@ -98,6 +99,7 @@ public void execute( String[] args ) throws IncorrectUsage, CommandFailed
String command = parsedArgs.orphans().size() > 0 ? parsedArgs.orphans().get( 0 ) : null;
String username = parsedArgs.orphans().size() > 1 ? parsedArgs.orphans().get( 1 ) : null;
String password = parsedArgs.orphans().size() > 2 ? parsedArgs.orphans().get( 2 ) : null;
boolean requiresPasswordChange = !hasFlagWithValue( parsedArgs, "requires-password-change", "false" );

try
{
Expand All @@ -112,23 +114,20 @@ public void execute( String[] args ) throws IncorrectUsage, CommandFailed
throw new IncorrectUsage(
"Missing arguments: 'users set-password' expects username and password arguments" );
}
setPassword( username, password );
setPassword( username, password, requiresPasswordChange );
break;
case "create":
if ( username == null || password == null )
{
throw new IncorrectUsage(
"Missing arguments: 'users create' expects username and password arguments" );
}
boolean requiresPasswordChange = !parsedArgs.asMap().containsKey( "requires-password-change" ) || (
parsedArgs.asMap().get( "requires-password-change" ).toLowerCase().equals( "true" ));
createUser( username, password, requiresPasswordChange );
break;
case "delete":
if ( username == null )
{
throw new IncorrectUsage(
"Missing arguments: 'users delete' expects username argument" );
throw new IncorrectUsage( "Missing arguments: 'users delete' expects username argument" );
}
deleteUser( username );
break;
Expand All @@ -151,6 +150,12 @@ public void execute( String[] args ) throws IncorrectUsage, CommandFailed
}
}

private boolean hasFlagWithValue( Args parsedArgs, String key, String expectedValue )
{
Map<String,String> argsMap = parsedArgs.asMap();
return argsMap.containsKey( key ) && (argsMap.get( key ).trim().toLowerCase().equals( expectedValue ));
}

private void listUsers( String contains ) throws Throwable
{
getAuthManager(); // ensure defaults are created
Expand Down Expand Up @@ -185,10 +190,10 @@ private void deleteUser( String username ) throws Throwable
}
}

private void setPassword( String username, String password ) throws Throwable
private void setPassword( String username, String password, boolean requirePasswordChange ) throws Throwable
{
BasicAuthManager authManager = getAuthManager();
authManager.setUserPassword( username, password );
authManager.setUserPassword( username, password, requirePasswordChange );
outsideWorld.stdOutLine( "Changed password for user '" + username + "'" );
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,17 +40,19 @@ public class AuthProcedures
public AuthSubject authSubject;

@Description( "Create a user." )
@Procedure( name = "dbms.createUser", mode = DBMS )
public void createUser( @Name( "username" ) String username, @Name( "password" ) String password,
@Name( "requirePasswordChange" ) boolean requirePasswordChange )
@Procedure( name = "dbms.security.createUser", mode = DBMS )
public void createUser(
@Name( "username" ) String username,
@Name( "password" ) String password,
@Name( value = "requirePasswordChange", defaultValue = "true") boolean requirePasswordChange )
throws InvalidArgumentsException, IOException
{
BasicAuthSubject subject = BasicAuthSubject.castOrFail( authSubject );
subject.getAuthManager().newUser( username, password, requirePasswordChange );
}

@Description( "Delete the user." )
@Procedure( name = "dbms.deleteUser", mode = DBMS )
@Procedure( name = "dbms.security.deleteUser", mode = DBMS )
public void deleteUser( @Name( "username" ) String username ) throws InvalidArgumentsException, IOException
{
BasicAuthSubject subject = BasicAuthSubject.castOrFail( authSubject );
Expand All @@ -62,20 +64,21 @@ public void deleteUser( @Name( "username" ) String username ) throws InvalidArgu
}

@Deprecated
@Description( "Change the user password." )
@Description( "Change the user password. Deprecated by dbms.security.changePassword." )
@Procedure( name = "dbms.changePassword", mode = DBMS, deprecatedBy = "dbms.security.changePassword" )
public void changePasswordDeprecated( @Name( "password" ) String password ) throws InvalidArgumentsException, IOException
{
authSubject.setPassword( password );
authSubject.setPassword( password, false );
}

@Description( "Change the user password." )
@Procedure( name = "dbms.security.changePassword", mode = DBMS )
public void changePassword( @Name( "password" ) String password ) throws InvalidArgumentsException, IOException
{
authSubject.setPassword( password );
authSubject.setPassword( password, false );
}

@Procedure( name = "dbms.showCurrentUser", mode = DBMS )
@Procedure( name = "dbms.security.showCurrentUser", mode = DBMS )
public Stream<UserResult> showCurrentUser() throws InvalidArgumentsException, IOException
{
BasicAuthSubject subject = BasicAuthSubject.castOrFail( authSubject );
Expand All @@ -85,7 +88,7 @@ public Stream<UserResult> showCurrentUser() throws InvalidArgumentsException, IO
) );
}

@Procedure( name = "dbms.listUsers", mode = DBMS )
@Procedure( name = "dbms.security.listUsers", mode = DBMS )
public Stream<UserResult> listUsers() throws InvalidArgumentsException, IOException
{
BasicAuthSubject subject = BasicAuthSubject.castOrFail( authSubject );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,8 @@ public BasicAuthSubject login( Map<String,Object> authToken ) throws InvalidAuth
}

@Override
public User newUser( String username, String initialPassword, boolean requirePasswordChange ) throws IOException,
InvalidArgumentsException
public User newUser( String username, String initialPassword, boolean requirePasswordChange )
throws IOException, InvalidArgumentsException
{
assertValidUsername( username );

Expand Down Expand Up @@ -144,8 +144,8 @@ public User getUser( String username ) throws InvalidArgumentsException
return user;
}

public void setPassword( AuthSubject authSubject, String username, String password ) throws IOException,
InvalidArgumentsException
public void setPassword( AuthSubject authSubject, String username, String password, boolean requirePasswordChange )
throws IOException, InvalidArgumentsException
{
BasicAuthSubject basicAuthSubject = BasicAuthSubject.castOrFail( authSubject );

Expand All @@ -154,12 +154,12 @@ public void setPassword( AuthSubject authSubject, String username, String passwo
throw new AuthorizationViolationException( "Invalid attempt to change the password for user " + username );
}

setUserPassword( username, password );
setUserPassword( username, password, requirePasswordChange );
}

@Override
public void setUserPassword( String username, String password ) throws IOException,
InvalidArgumentsException
public void setUserPassword( String username, String password, boolean requirePasswordChange )
throws IOException, InvalidArgumentsException
{
User existingUser = getUser( username );

Expand All @@ -180,7 +180,7 @@ public void setUserPassword( String username, String password ) throws IOExcepti
} catch ( ConcurrentModificationException e )
{
// try again
setUserPassword( username, password );
setUserPassword( username, password, requirePasswordChange );
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,13 +81,15 @@ public AuthenticationResult getAuthenticationResult()
* Sets a new password for the BasicAuthSubject.
*
* @param password The new password
* @param requirePasswordChange
* @throws IOException If the new user credentials cannot be stored on disk.
* @throws InvalidArgumentsException If password is invalid, e.g. if the new password is the same as the current.
*/
@Override
public void setPassword( String password ) throws IOException, InvalidArgumentsException
public void setPassword( String password, boolean requirePasswordChange )
throws IOException, InvalidArgumentsException
{
authManager.setPassword( this, user.name(), password );
authManager.setPassword( this, user.name(), password, requirePasswordChange );

// Make user authenticated if successful
if ( authenticationResult == PASSWORD_CHANGE_REQUIRED )
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,15 @@

public interface UserManager
{
User newUser( String username, String initialPassword, boolean requirePasswordChange ) throws IOException,
InvalidArgumentsException;
User newUser( String username, String initialPassword, boolean requirePasswordChange )
throws IOException, InvalidArgumentsException;

boolean deleteUser( String username ) throws IOException, InvalidArgumentsException;

User getUser( String username ) throws InvalidArgumentsException;

void setUserPassword( String username, String password ) throws IOException, InvalidArgumentsException;
void setUserPassword( String username, String password, boolean requirePasswordChange )
throws IOException, InvalidArgumentsException;

Set<String> getAllUsernames();
}

0 comments on commit 1f22cd0

Please sign in to comment.