diff --git a/cypher-shell/src/main/java/org/neo4j/shell/Main.java b/cypher-shell/src/main/java/org/neo4j/shell/Main.java index 44b36d1f..84bb2fd0 100644 --- a/cypher-shell/src/main/java/org/neo4j/shell/Main.java +++ b/cypher-shell/src/main/java/org/neo4j/shell/Main.java @@ -22,6 +22,7 @@ import static org.neo4j.shell.ShellRunner.isInputInteractive; import static org.neo4j.shell.ShellRunner.isOutputInteractive; +import static org.neo4j.shell.util.Versions.isPasswordChangeRequiredException; public class Main { static final String NEO_CLIENT_ERROR_SECURITY_UNAUTHORIZED = "Neo.ClientError.Security.Unauthorized"; @@ -172,7 +173,7 @@ private void connectMaybeInteractively( @Nonnull CypherShell shell, promptForUsernameAndPassword(connectionConfig, outputInteractive); didPrompt = true; } catch (Neo4jException e) { - if (passwordChangeRequiredException(e)) { + if (isPasswordChangeRequiredException(e)) { promptForPasswordChange(connectionConfig, outputInteractive); shell.changePassword(connectionConfig); didPrompt = true; @@ -183,10 +184,6 @@ private void connectMaybeInteractively( @Nonnull CypherShell shell, } } - private boolean passwordChangeRequiredException(Neo4jException e) { - return "Neo.ClientError.Security.CredentialsExpired".equalsIgnoreCase(e.code()); - } - private void promptForUsernameAndPassword(ConnectionConfig connectionConfig, boolean outputInteractive) throws Exception { OutputStream promptOutputStream = getOutputStreamForInteractivePrompt(); ConsoleReader consoleReader = new ConsoleReader(in, promptOutputStream); diff --git a/cypher-shell/src/main/java/org/neo4j/shell/state/BoltStateHandler.java b/cypher-shell/src/main/java/org/neo4j/shell/state/BoltStateHandler.java index 33656435..3112fe96 100644 --- a/cypher-shell/src/main/java/org/neo4j/shell/state/BoltStateHandler.java +++ b/cypher-shell/src/main/java/org/neo4j/shell/state/BoltStateHandler.java @@ -25,6 +25,7 @@ import org.neo4j.driver.Value; import org.neo4j.driver.Values; import org.neo4j.driver.exceptions.ClientException; +import org.neo4j.driver.exceptions.Neo4jException; import org.neo4j.driver.exceptions.SessionExpiredException; import org.neo4j.driver.internal.Scheme; import org.neo4j.driver.summary.DatabaseInfo; @@ -38,6 +39,7 @@ import org.neo4j.shell.exception.CommandException; import org.neo4j.shell.log.NullLogging; +import static org.neo4j.shell.util.Versions.isPasswordChangeRequiredException; import static org.neo4j.shell.util.Versions.majorVersion; /** @@ -218,10 +220,32 @@ else if ( systemBookmark != null ) session = driver.session( builder.build() ); - ThrowingAction action = command != null ? command : getPing(); - resetActualDbName(); // Set this to null first in case run throws an exception - action.apply(); + connect(command); + } + + private void connect( ThrowingAction command) throws CommandException + { + ThrowingAction toCall = command == null ? getPing() : () -> + { + try + { + command.apply(); + } + catch ( Neo4jException e ) + { + //If we need to update password we need to call the apply + //to set the server version and such. + if (isPasswordChangeRequiredException( e )) + { + getPing().apply(); + } + throw e; + } + }; + + //execute + toCall.apply(); } private ThrowingAction getPing() { @@ -401,6 +425,7 @@ public void reset() { public void disconnect() { reset(); silentDisconnect(); + version = null; } List getTransactionStatements() { diff --git a/cypher-shell/src/main/java/org/neo4j/shell/util/Versions.java b/cypher-shell/src/main/java/org/neo4j/shell/util/Versions.java index 657a6aad..796d41d9 100644 --- a/cypher-shell/src/main/java/org/neo4j/shell/util/Versions.java +++ b/cypher-shell/src/main/java/org/neo4j/shell/util/Versions.java @@ -1,5 +1,7 @@ package org.neo4j.shell.util; +import org.neo4j.driver.exceptions.Neo4jException; + import static java.lang.Integer.parseInt; import static java.lang.String.format; @@ -47,4 +49,8 @@ public static Version version(String version) { format("%s is not a proper version string, it should be of the form X.Y.Z ", version)); } } + + public static boolean isPasswordChangeRequiredException( Neo4jException e) { + return "Neo.ClientError.Security.CredentialsExpired".equalsIgnoreCase(e.code()); + } }