Add integration test for this feature only. #3363

This commit is contained in:
Mark H. Wood
2021-08-17 11:25:24 -04:00
parent dd40f5ff3c
commit b59790a156
6 changed files with 169 additions and 9 deletions

View File

@@ -920,6 +920,12 @@
<version>6.4.0</version>
</dependency>
<dependency>
<groupId>com.github.stefanbirkner</groupId>
<artifactId>system-rules</artifactId>
<version>1.19.0</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@@ -29,6 +29,8 @@ import org.dspace.authorize.AuthorizeException;
import org.dspace.core.Context;
import org.dspace.eperson.factory.EPersonServiceFactory;
import org.dspace.eperson.service.EPersonService;
import org.dspace.util.ConsoleService;
import org.dspace.util.ConsoleServiceImpl;
public class EPersonCLITool {
@@ -64,10 +66,13 @@ public class EPersonCLITool {
private static final EPersonService ePersonService
= EPersonServiceFactory.getInstance().getEPersonService();
private static ConsoleService consoleService
= new ConsoleServiceImpl();
/**
* Default constructor
*/
private EPersonCLITool() { }
EPersonCLITool() { }
/**
* Tool for manipulating user accounts.
@@ -372,14 +377,11 @@ public class EPersonCLITool {
modified = true;
}
if (command.hasOption(OPT_NEW_PASSWORD.getOpt())) {
// TODO prompt, collect password, verify
char[] password = System.console()
.readPassword("Enter new password for user %s", userName);
char[] password2 = System.console()
.readPassword("Enter new password again to verify");
if (Arrays.equals(password, password2)) {
PasswordHash newHashedPassword = new PasswordHash(String.valueOf(password));
Arrays.fill(password, '\0'); // Obliterate cleartext passwords
char[] password1 = consoleService.readPassword("Enter new password for user %s", userName);
char[] password2 = consoleService.readPassword("Enter new password again to verify");
if (Arrays.equals(password1, password2)) {
PasswordHash newHashedPassword = new PasswordHash(String.valueOf(password1));
Arrays.fill(password1, '\0'); // Obliterate cleartext passwords
Arrays.fill(password2, '\0');
eperson.setPassword(newHashedPassword.getHashString());
eperson.setSalt(newHashedPassword.getSaltString());
@@ -456,4 +458,13 @@ public class EPersonCLITool {
return 0;
}
/**
* Replace the ConsoleService for testing.
*
* @param service new ConsoleService to be used henceforth.
*/
void setConsoleService(ConsoleService service) {
consoleService = service;
}
}

View File

@@ -0,0 +1,17 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.util;
/**
* Make System.console mock-able for testing.
*
* @author Mark H. Wood <mwood@iupui.edu>
*/
public interface ConsoleService {
public char[] readPassword(String prompt, Object... args);
}

View File

@@ -0,0 +1,22 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.util;
/**
* Standard implementation of console IO using {@code System.console()}.
*
* @author Mark H. Wood <mwood@iupui.edu>
*/
public class ConsoleServiceImpl
implements ConsoleService {
@Override
public char[] readPassword(String prompt, Object... args) {
return System.console().readPassword(prompt, args);
}
}

View File

@@ -0,0 +1,64 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.eperson;
import static org.junit.Assert.assertNotEquals;
import org.dspace.AbstractIntegrationTest;
import org.dspace.util.FakeConsoleServiceImpl;
import org.junit.Rule;
import org.junit.Test;
import org.junit.contrib.java.lang.system.ExpectedSystemExit;
/**
*
* @author Mark H. Wood <mwood@iupui.edu>
*/
public class EPersonCLIToolIT
extends AbstractIntegrationTest {
private static final String NEW_PASSWORD = "secret";
// Handle System.exit() from unit under test.
@Rule
public final ExpectedSystemExit exit = ExpectedSystemExit.none();
/**
* Test --modify --newPassword
* @throws Exception passed through.
*/
@Test
@SuppressWarnings("static-access")
public void testSetPassword()
throws Exception {
exit.expectSystemExitWithStatus(0);
System.out.println("main");
// Create a source of "console" input.
FakeConsoleServiceImpl consoleService = new FakeConsoleServiceImpl();
consoleService.setPassword("secret".toCharArray());
// Make certain that we know the eperson's email and old password hash.
String email = eperson.getEmail();
String oldPasswordHash = eperson.getPassword();
// Instantiate the unit under test.
EPersonCLITool instance = new EPersonCLITool();
instance.setConsoleService(consoleService);
// Test!
String[] argv = {
"--modify",
"--email", email,
"--newPassword", NEW_PASSWORD
};
instance.main(argv);
String newPasswordHash = eperson.getPassword();
assertNotEquals("Password hash did not change", oldPasswordHash, newPasswordHash);
}
}

View File

@@ -0,0 +1,40 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.util;
/**
* A test version of ConsoleService which supplies any password input that we
* want.
*
* @author Mark H. Wood <mwood@iupui.edu>
*/
public class FakeConsoleServiceImpl
implements ConsoleService {
private String prompt;
private Object[] args;
private char[] password;
@Override
public char[] readPassword(String prompt, Object... args) {
this.prompt = prompt;
this.args = args;
return this.password;
}
public String getPasswordPrompt() {
return prompt;
}
public Object[] getArgs() {
return this.args;
}
public void setPassword(char[] password) {
this.password = password;
}
}