Skip to content
This repository was archived by the owner on Jul 6, 2023. It is now read-only.

Commit e370117

Browse files
committed
Prompt if not explicitly using --non-interactive
1 parent 3404687 commit e370117

File tree

3 files changed

+55
-34
lines changed

3 files changed

+55
-34
lines changed

cypher-shell/src/integration-test/java/org/neo4j/shell/MainIntegrationTest.java

Lines changed: 32 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ private void ensureDefaultDatabaseStarted() throws Exception {
120120
cliArgs.setPassword("neo", "");
121121
cliArgs.setDatabase("system");
122122
ShellAndConnection sac = getShell(cliArgs);
123-
main.connectMaybeInteractively(sac.shell, sac.connectionConfig, true, false);
123+
main.connectMaybeInteractively(sac.shell, sac.connectionConfig, true, false, true);
124124
sac.shell.execute("START DATABASE " + DatabaseManager.DEFAULT_DEFAULT_DB_NAME);
125125
}
126126

@@ -130,7 +130,7 @@ public void promptsOnWrongAuthenticationIfInteractive() throws Exception {
130130
assertEquals("", connectionConfig.username());
131131
assertEquals("", connectionConfig.password());
132132

133-
main.connectMaybeInteractively(shell, connectionConfig, true, true);
133+
main.connectMaybeInteractively(shell, connectionConfig, true, true, true);
134134

135135
// then
136136
// should be connected
@@ -152,7 +152,7 @@ public void promptsOnPasswordChangeRequired() throws Exception {
152152
// when
153153
inputBuffer.put(String.format("foo%npass%nnewpass%n").getBytes());
154154
baos.reset();
155-
main.connectMaybeInteractively(shell, connectionConfig, true, true);
155+
main.connectMaybeInteractively(shell, connectionConfig, true, true, true);
156156

157157
// then
158158
assertTrue(shell.isConnected());
@@ -235,6 +235,23 @@ public void shouldBePromptedIfRunningNonInteractiveCypherThatDoesntUpdatePasswor
235235
"foo", "pass2", "RETURN 42 AS n" ) ) );
236236
}
237237

238+
@Test
239+
public void shouldNotBePromptedIfRunningWithExplicitNonInteractiveCypherThatDoesntUpdatePassword() throws Exception {
240+
//given a user that require a password change
241+
int majorVersion = getVersionAndCreateUserWithPasswordChangeRequired();
242+
243+
//when
244+
assumeTrue( majorVersion >= 4 );
245+
246+
//when interactively asked for a password use this
247+
inputBuffer.put( String.format( "pass2%n" ).getBytes() );
248+
baos.reset();
249+
CliArgs args = args( DEFAULT_DEFAULT_DB_NAME, "foo", "pass",
250+
"MATCH (n) RETURN n" );
251+
args.setNonInteractive( true );
252+
assertEquals( EXIT_FAILURE, main.runShell( args, shell, mock( Logger.class ) ) );
253+
}
254+
238255
@Test
239256
public void doesNotPromptToStdOutOnWrongAuthenticationIfOutputRedirected() throws Exception {
240257
// when
@@ -250,7 +267,7 @@ public void doesNotPromptToStdOutOnWrongAuthenticationIfOutputRedirected() throw
250267
// Create a Main with the standard in and out
251268
try {
252269
Main realMain = new Main();
253-
realMain.connectMaybeInteractively(shell, connectionConfig, true, false);
270+
realMain.connectMaybeInteractively(shell, connectionConfig, true, false, true);
254271

255272
// then
256273
// should be connected
@@ -282,7 +299,7 @@ public void wrongPortWithBolt() throws Exception
282299

283300
exception.expect( ServiceUnavailableException.class );
284301
exception.expectMessage( "Unable to connect to localhost:1234, ensure the database is running and that there is a working network connection to it" );
285-
main.connectMaybeInteractively( shell, connectionConfig, true, true );
302+
main.connectMaybeInteractively( shell, connectionConfig, true, true, true);
286303
}
287304

288305
@Test
@@ -299,7 +316,7 @@ public void wrongPortWithNeo4j() throws Exception
299316

300317
exception.expect( ServiceUnavailableException.class );
301318
// The error message here may be subject to change and is not stable across versions so let us not assert on it
302-
main.connectMaybeInteractively( shell, connectionConfig, true, true );
319+
main.connectMaybeInteractively( shell, connectionConfig, true, true, true);
303320
}
304321

305322
@Test
@@ -315,7 +332,7 @@ public void shouldAskForCredentialsWhenConnectingWithAFile() throws Exception {
315332
ShellAndConnection sac = getShell(cliArgs);
316333
CypherShell shell = sac.shell;
317334
ConnectionConfig connectionConfig = sac.connectionConfig;
318-
main.connectMaybeInteractively( shell, connectionConfig, true, true );
335+
main.connectMaybeInteractively( shell, connectionConfig, true, true, true);
319336

320337
// then we should have prompted and set the username and password
321338
assertEquals( format( "username: neo4j%npassword: ***%n" ), baos.toString() );
@@ -447,7 +464,7 @@ public void doesNotStartWhenDefaultDatabaseUnavailableIfInteractive() throws Exc
447464
assertEquals("", connectionConfig.password());
448465

449466
// when
450-
main.connectMaybeInteractively(shell, connectionConfig, true, true);
467+
main.connectMaybeInteractively(shell, connectionConfig, true, true, true);
451468

452469
// Multiple databases are only available from 4.0
453470
assumeTrue( majorVersion( shell.getServerVersion() ) >= 4 );
@@ -469,7 +486,7 @@ public void doesNotStartWhenDefaultDatabaseUnavailableIfInteractive() throws Exc
469486
shell.disconnect();
470487

471488
// Should get exception that database is unavailable when trying to connect
472-
main.connectMaybeInteractively(shell, connectionConfig, true, true);
489+
main.connectMaybeInteractively(shell, connectionConfig, true, true, true);
473490
fail("No exception thrown");
474491
} catch(TransientException|ServiceUnavailableException e) {
475492
expectDatabaseUnavailable(e, "neo4j");
@@ -487,7 +504,7 @@ public void startsAgainstSystemDatabaseWhenDefaultDatabaseUnavailableIfInteracti
487504
assertEquals("", connectionConfig.password());
488505

489506
// when
490-
main.connectMaybeInteractively(shell, connectionConfig, true, true);
507+
main.connectMaybeInteractively(shell, connectionConfig, true, true, true);
491508

492509
// Multiple databases are only available from 4.0
493510
assumeTrue( majorVersion( shell.getServerVersion() ) >= 4 );
@@ -517,7 +534,7 @@ public void startsAgainstSystemDatabaseWhenDefaultDatabaseUnavailableIfInteracti
517534
// Use the new shell and connection config from here on
518535
shell = sac.shell;
519536
connectionConfig = sac.connectionConfig;
520-
main.connectMaybeInteractively(shell, connectionConfig, true, false);
537+
main.connectMaybeInteractively(shell, connectionConfig, true, false, true);
521538

522539
// then
523540
assertTrue(shell.isConnected());
@@ -536,7 +553,7 @@ public void switchingToUnavailableDatabaseIfInteractive() throws Exception {
536553
assertEquals("", connectionConfig.password());
537554

538555
// when
539-
main.connectMaybeInteractively(shell, connectionConfig, true, true);
556+
main.connectMaybeInteractively(shell, connectionConfig, true, true, true);
540557

541558
// Multiple databases are only available from 4.0
542559
assumeTrue(majorVersion( shell.getServerVersion() ) >= 4);
@@ -575,7 +592,7 @@ public void switchingToUnavailableDefaultDatabaseIfInteractive() throws Exceptio
575592
assertEquals("", connectionConfig.password());
576593

577594
// when
578-
main.connectMaybeInteractively(shell, connectionConfig, true, true);
595+
main.connectMaybeInteractively(shell, connectionConfig, true, true, true);
579596

580597
// Multiple databases are only available from 4.0
581598
assumeTrue(majorVersion( shell.getServerVersion() ) >= 4);
@@ -648,7 +665,7 @@ private CypherShell interactiveShell( LinePrinter linePrinter ) throws Exception
648665
{
649666
PrettyConfig prettyConfig = new PrettyConfig( new CliArgs() );
650667
CypherShell shell = new CypherShell( linePrinter, prettyConfig, true, new ShellParameterMap() );
651-
main.connectMaybeInteractively( shell, connectionConfig, true, true );
668+
main.connectMaybeInteractively( shell, connectionConfig, true, true, true);
652669
shell.setCommandHelper( new CommandHelper( mock( Logger.class ), Historian.empty, shell) );
653670
return shell;
654671
}
@@ -705,7 +722,7 @@ private CliArgs args(String db, String user, String pass, String cypher)
705722
private int getVersionAndCreateUserWithPasswordChangeRequired() throws Exception {
706723
shell.setCommandHelper( new CommandHelper( mock( Logger.class ), Historian.empty, shell ) );
707724

708-
main.connectMaybeInteractively( shell, connectionConfig, true, true );
725+
main.connectMaybeInteractively( shell, connectionConfig, true, true, true);
709726
String expectedLoginOutput = format( "username: neo4j%npassword: ***%n" );
710727
assertEquals( expectedLoginOutput, baos.toString() );
711728
ensureUser();

cypher-shell/src/main/java/org/neo4j/shell/Main.java

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ int runShell(@Nonnull CliArgs cliArgs, @Nonnull CypherShell shell, Logger logger
107107
connectMaybeInteractively( shell, connectionConfig,
108108
!cliArgs.getNonInteractive() && isInputInteractive(),
109109
!cliArgs.getNonInteractive() && isOutputInteractive(),
110+
!cliArgs.getNonInteractive()/*Don't ask for password if using --non-interactive*/,
110111
() -> shell.execute( cliArgs.getCypher().get() ) );
111112
return EXIT_SUCCESS;
112113
}
@@ -115,7 +116,8 @@ int runShell(@Nonnull CliArgs cliArgs, @Nonnull CypherShell shell, Logger logger
115116
// Can only prompt for password if input has not been redirected
116117
connectMaybeInteractively( shell, connectionConfig,
117118
!cliArgs.getNonInteractive() && isInputInteractive(),
118-
!cliArgs.getNonInteractive() && isOutputInteractive());
119+
!cliArgs.getNonInteractive() && isOutputInteractive(),
120+
!cliArgs.getNonInteractive()/*Don't ask for password if using --non-interactive*/);
119121
// Construct shellrunner after connecting, due to interrupt handling
120122
ShellRunner shellRunner = ShellRunner.getShellRunner( cliArgs, shell, logger, connectionConfig );
121123
CommandHelper commandHelper = new CommandHelper( logger, shellRunner.getHistorian(), shell );
@@ -135,9 +137,10 @@ int runShell(@Nonnull CliArgs cliArgs, @Nonnull CypherShell shell, Logger logger
135137
void connectMaybeInteractively(@Nonnull CypherShell shell,
136138
@Nonnull ConnectionConfig connectionConfig,
137139
boolean inputInteractive,
138-
boolean outputInteractive)
140+
boolean outputInteractive,
141+
boolean shouldPromptForPassword)
139142
throws Exception {
140-
connectMaybeInteractively( shell, connectionConfig, inputInteractive, outputInteractive, null );
143+
connectMaybeInteractively( shell, connectionConfig, inputInteractive, outputInteractive, shouldPromptForPassword, null );
141144
}
142145

143146
/**
@@ -147,6 +150,7 @@ private void connectMaybeInteractively( @Nonnull CypherShell shell,
147150
@Nonnull ConnectionConfig connectionConfig,
148151
boolean inputInteractive,
149152
boolean outputInteractive,
153+
boolean shouldPromptForPassword,
150154
ThrowingAction<CommandException> command )
151155
throws Exception {
152156

@@ -177,7 +181,7 @@ private void connectMaybeInteractively( @Nonnull CypherShell shell,
177181
promptForUsernameAndPassword(connectionConfig, outputInteractive);
178182
didPrompt = true;
179183
} catch (Neo4jException e) {
180-
if (inputInteractive && isPasswordChangeRequiredException(e)) {
184+
if (shouldPromptForPassword && isPasswordChangeRequiredException(e)) {
181185
promptForPasswordChange(connectionConfig, outputInteractive);
182186
shell.changePassword(connectionConfig);
183187
didPrompt = true;

cypher-shell/src/test/java/org/neo4j/shell/MainTest.java

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ public void nonEndedStringFails() throws Exception {
6363
thrown.expectMessage("No text could be read, exiting");
6464

6565
Main main = new Main(inputStream, out);
66-
main.connectMaybeInteractively(shell, connectionConfig, true, true);
66+
main.connectMaybeInteractively(shell, connectionConfig, true, true, true);
6767
verify(shell, times(1)).connect(connectionConfig, null);
6868
}
6969

@@ -75,7 +75,7 @@ public void unrelatedErrorDoesNotPrompt() throws Exception {
7575
thrown.expectMessage("bla");
7676

7777
Main main = new Main(mock(InputStream.class), out);
78-
main.connectMaybeInteractively(shell, connectionConfig, true, true);
78+
main.connectMaybeInteractively(shell, connectionConfig, true, true, true);
7979
verify(shell, times(1)).connect(connectionConfig, null);
8080
}
8181

@@ -90,7 +90,7 @@ public void promptsForUsernameAndPasswordIfNoneGivenIfInteractive() throws Excep
9090
PrintStream ps = new PrintStream(baos);
9191

9292
Main main = new Main(inputStream, ps);
93-
main.connectMaybeInteractively(shell, connectionConfig, true, true);
93+
main.connectMaybeInteractively(shell, connectionConfig, true, true, true);
9494

9595
String out = new String(baos.toByteArray(), StandardCharsets.UTF_8);
9696

@@ -124,7 +124,7 @@ public void promptsSilentlyForUsernameAndPasswordIfNoneGivenIfOutputRedirected()
124124

125125
try {
126126
Main main = new Main();
127-
main.connectMaybeInteractively(shell, connectionConfig, true, false);
127+
main.connectMaybeInteractively(shell, connectionConfig, true, false, true);
128128

129129
String out = new String(baos.toByteArray(), StandardCharsets.UTF_8);
130130

@@ -151,7 +151,7 @@ public void doesNotPromptIfInputRedirected() throws Exception {
151151
Main main = new Main(inputStream, ps);
152152

153153
try {
154-
main.connectMaybeInteractively(shell, connectionConfig, false, true);
154+
main.connectMaybeInteractively(shell, connectionConfig, false, true, true);
155155
fail("Expected auth exception");
156156
} catch (AuthenticationException e) {
157157
verify(shell, times(1)).connect(connectionConfig, null);
@@ -170,7 +170,7 @@ public void promptsForUserIfPassExistsIfInteractive() throws Exception {
170170
PrintStream ps = new PrintStream(baos);
171171

172172
Main main = new Main(inputStream, ps);
173-
main.connectMaybeInteractively(shell, connectionConfig, true, true);
173+
main.connectMaybeInteractively(shell, connectionConfig, true, true, true);
174174

175175
String out = new String(baos.toByteArray(), StandardCharsets.UTF_8);
176176

@@ -203,7 +203,7 @@ public void promptsSilentlyForUserIfPassExistsIfOutputRedirected() throws Except
203203

204204
try {
205205
Main main = new Main();
206-
main.connectMaybeInteractively(shell, connectionConfig, true, false);
206+
main.connectMaybeInteractively(shell, connectionConfig, true, false, true);
207207

208208
String out = new String(baos.toByteArray(), StandardCharsets.UTF_8);
209209

@@ -227,7 +227,7 @@ public void promptsForPassBeforeConnectIfUserExistsIfInteractive() throws Except
227227
PrintStream ps = new PrintStream(baos);
228228

229229
Main main = new Main(inputStream, ps);
230-
main.connectMaybeInteractively(shell, connectionConfig, true, true);
230+
main.connectMaybeInteractively(shell, connectionConfig, true, true, true);
231231

232232
String out = new String(baos.toByteArray(), StandardCharsets.UTF_8);
233233

@@ -260,7 +260,7 @@ public void promptsSilentlyForPassIfUserExistsIfOutputRedirected() throws Except
260260

261261
try {
262262
Main main = new Main();
263-
main.connectMaybeInteractively(shell, connectionConfig, true, false);
263+
main.connectMaybeInteractively(shell, connectionConfig, true, false, true);
264264

265265
String out = new String(baos.toByteArray(), StandardCharsets.UTF_8);
266266

@@ -286,7 +286,7 @@ public void promptsForNewPasswordIfPasswordChangeRequired() throws Exception {
286286
PrintStream ps = new PrintStream(baos);
287287

288288
Main main = new Main(inputStream, ps);
289-
main.connectMaybeInteractively(shell, connectionConfig, true, true);
289+
main.connectMaybeInteractively(shell, connectionConfig, true, true, true);
290290

291291
String out = new String(baos.toByteArray(), StandardCharsets.UTF_8);
292292

@@ -311,7 +311,7 @@ public void promptsForNewPasswordIfPasswordChangeRequiredCannotBeEmpty() throws
311311
PrintStream ps = new PrintStream(baos);
312312

313313
Main main = new Main(inputStream, ps);
314-
main.connectMaybeInteractively(shell, connectionConfig, true, true);
314+
main.connectMaybeInteractively(shell, connectionConfig, true, true, true);
315315

316316
String out = new String(baos.toByteArray(), StandardCharsets.UTF_8);
317317

@@ -334,7 +334,7 @@ public void promptsHandlesBang() throws Exception {
334334
PrintStream ps = new PrintStream(baos);
335335

336336
Main main = new Main(inputStream, ps);
337-
main.connectMaybeInteractively(shell, connectionConfig, true, true);
337+
main.connectMaybeInteractively(shell, connectionConfig, true, true, true);
338338

339339
String out = new String(baos.toByteArray(), StandardCharsets.UTF_8);
340340

@@ -358,7 +358,7 @@ public void triesOnlyOnceIfUserPassExists() throws Exception {
358358
Main main = new Main(inputStream, ps);
359359

360360
try {
361-
main.connectMaybeInteractively(shell, connectionConfig, true, true);
361+
main.connectMaybeInteractively(shell, connectionConfig, true, true, true);
362362
fail("Expected an exception");
363363
} catch (Neo4jException e) {
364364
assertEquals(authException.code(), e.code());
@@ -377,7 +377,7 @@ public void repromptsIfUserIsNotProvidedIfInteractive() throws Exception {
377377
PrintStream ps = new PrintStream(baos);
378378

379379
Main main = new Main(inputStream, ps);
380-
main.connectMaybeInteractively(shell, connectionConfig, true, true);
380+
main.connectMaybeInteractively(shell, connectionConfig, true, true, true);
381381

382382
String out = new String(baos.toByteArray(), StandardCharsets.UTF_8);
383383

@@ -410,7 +410,7 @@ public void doesNotRepromptIfUserIsNotProvidedIfOutputRedirected() throws Except
410410

411411
try {
412412
Main main = new Main();
413-
main.connectMaybeInteractively(shell, connectionConfig, true, false);
413+
main.connectMaybeInteractively(shell, connectionConfig, true, false, true);
414414

415415
String out = new String(baos.toByteArray(), StandardCharsets.UTF_8);
416416

0 commit comments

Comments
 (0)