Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@
*/
package org.dspace.scripts.filepreview;

import java.sql.SQLException;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;
import java.util.UUID;
import javax.naming.AuthenticationException;

import org.apache.commons.cli.ParseException;
import org.apache.commons.lang3.StringUtils;
Expand Down Expand Up @@ -58,8 +60,8 @@ public class FilePreview extends DSpaceRunnable<FilePreviewConfiguration> {
*/
private String specificItemUUID = null;

private String email = null;
private String password = null;
private String epersonMail = null;
private String epersonPassword = null;

@Override
public FilePreviewConfiguration getScriptConfiguration() {
Expand All @@ -83,12 +85,11 @@ public void setup() throws ParseException {
specificItemUUID);
}

if (commandLine.hasOption('e')) {
email = commandLine.getOptionValue('e');
}
epersonMail = commandLine.getOptionValue('e');
epersonPassword = commandLine.getOptionValue('p');

if (commandLine.hasOption('p')) {
password = commandLine.getOptionValue('p');
if (getEpersonIdentifier() == null && (epersonMail == null || epersonPassword == null)) {
throw new ParseException("Provide both -e/--email and -p/--password when no eperson is supplied.");
}
}

Expand All @@ -101,30 +102,8 @@ public void internalRun() throws Exception {

Context context = new Context();
try {
if (StringUtils.isBlank(email)) {
handler.logError("Email is required for authentication.");
return;
}
if (StringUtils.isBlank(password)) {
handler.logError("Password is required for authentication.");
return;
}

EPerson eperson = ePersonService.findByEmail(context, email);
if (eperson == null) {
handler.logError("No EPerson found for this email: " + email);
return;
}

int authenticated = authenticateService.authenticate(context, email, password, null, null);
if (AuthenticationMethod.SUCCESS != authenticated) {
handler.logError("Authentication failed for email: " + email);
return;
} else {
handler.logInfo("Authentication successful for email: " + email);
}

context.setCurrentUser(eperson);
context.setCurrentUser(getAuthenticatedEperson((context)));
handler.logInfo("Authentication by user: " + context.getCurrentUser().getEmail());
if (StringUtils.isNotBlank(specificItemUUID)) {
// Generate the preview only for a specific item
generateItemFilePreviews(context, UUID.fromString(specificItemUUID));
Expand Down Expand Up @@ -203,4 +182,37 @@ public void printHelp() {
" -p, --password Password for authentication\n");

}

/**
* Retrieves an EPerson object either by its identifier or by performing an email-based lookup.
* It then authenticates the EPerson using the provided email and password.
* If the authentication is successful, it returns the EPerson object; otherwise,
* it throws an AuthenticationException.
*
* @param context The Context object used for interacting with the DSpace database and service layer.
* @return The authenticated EPerson object corresponding to the provided email,
* if authentication is successful.
* @throws SQLException If a database error occurs while retrieving or interacting with the EPerson data.
* @throws AuthenticationException If no EPerson is found for the provided email
* or if the authentication fails.
*/
private EPerson getAuthenticatedEperson(Context context) throws SQLException, AuthenticationException {
if (getEpersonIdentifier() != null) {
return ePersonService.find(context, getEpersonIdentifier());
}
String msg;
EPerson ePerson = ePersonService.findByEmail(context, epersonMail);
if (ePerson == null) {
msg = "No EPerson found for this email: " + epersonMail;
handler.logError(msg);
throw new AuthenticationException(msg);
}
int authenticated = authenticateService.authenticate(context, epersonMail, epersonPassword, null, null);
if (AuthenticationMethod.SUCCESS != authenticated) {
msg = "Authentication failed for email: " + epersonMail;
handler.logError(msg);
throw new AuthenticationException(msg);
}
return ePerson;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import static org.hamcrest.Matchers.empty;
import static org.hamcrest.Matchers.hasItem;
import static org.hamcrest.Matchers.hasSize;
import static org.junit.Assert.assertEquals;

import java.io.InputStream;
import java.sql.SQLException;
Expand Down Expand Up @@ -86,32 +87,29 @@ public void testUnauthorizedEmail() throws Exception {
// Run the script
TestDSpaceRunnableHandler testDSpaceRunnableHandler = new TestDSpaceRunnableHandler();
String[] args = new String[] { "file-preview"};
ScriptLauncher.handleScript(args, ScriptLauncher.getConfig(kernelImpl), testDSpaceRunnableHandler, kernelImpl);

List<String> messages = testDSpaceRunnableHandler.getErrorMessages();
assertThat(messages, hasSize(1));
assertThat(messages, hasItem(containsString("Email is required for authentication.")));
int run = ScriptLauncher.handleScript(args, ScriptLauncher.getConfig(kernelImpl),
testDSpaceRunnableHandler, kernelImpl);
assertEquals(1, run); // Since a ParseException was caught, expect return code 1
}

@Test
public void testUnauthorizedPassword() throws Exception {
// Run the script
TestDSpaceRunnableHandler testDSpaceRunnableHandler = new TestDSpaceRunnableHandler();
String[] args = new String[] { "file-preview", "-e", eperson.getEmail()};
ScriptLauncher.handleScript(args, ScriptLauncher.getConfig(kernelImpl), testDSpaceRunnableHandler, kernelImpl);

List<String> messages = testDSpaceRunnableHandler.getErrorMessages();
assertThat(messages, hasSize(1));
assertThat(messages, hasItem(containsString("Password is required for authentication.")));
int run = ScriptLauncher.handleScript(args, ScriptLauncher.getConfig(kernelImpl),
testDSpaceRunnableHandler, kernelImpl);
assertEquals(1, run); // Since a ParseException was caught, expect return code 1
}

@Test
public void testWhenNoFilesRun() throws Exception {
TestDSpaceRunnableHandler testDSpaceRunnableHandler = new TestDSpaceRunnableHandler();

String[] args = new String[] { "file-preview", "-e", eperson.getEmail(), "-p", PASSWORD };
ScriptLauncher.handleScript(args, ScriptLauncher.getConfig(kernelImpl), testDSpaceRunnableHandler, kernelImpl);

int run = ScriptLauncher.handleScript(args, ScriptLauncher.getConfig(kernelImpl),
testDSpaceRunnableHandler, kernelImpl);
assertEquals(0, run);
checkNoError(testDSpaceRunnableHandler);
}

Expand All @@ -121,8 +119,9 @@ public void testForSpecificItem() throws Exception {
TestDSpaceRunnableHandler testDSpaceRunnableHandler = new TestDSpaceRunnableHandler();
String[] args = new String[] { "file-preview", "-u", item.getID().toString(),
"-e", eperson.getEmail(), "-p", PASSWORD};
ScriptLauncher.handleScript(args, ScriptLauncher.getConfig(kernelImpl), testDSpaceRunnableHandler, kernelImpl);

int run = ScriptLauncher.handleScript(args, ScriptLauncher.getConfig(kernelImpl),
testDSpaceRunnableHandler, kernelImpl);
assertEquals(0, run);
// There should be no errors or warnings
checkNoError(testDSpaceRunnableHandler);

Expand All @@ -132,16 +131,17 @@ public void testForSpecificItem() throws Exception {
assertThat(messages, hasItem(containsString("Generate the file previews for the specified item with " +
"the given UUID: " + item.getID())));
assertThat(messages,
hasItem(containsString("Authentication successful for email: " + eperson.getEmail())));
hasItem(containsString("Authentication by user: " + eperson.getEmail())));
}

@Test
public void testForAllItem() throws Exception {
// Run the script
TestDSpaceRunnableHandler testDSpaceRunnableHandler = new TestDSpaceRunnableHandler();
String[] args = new String[] { "file-preview", "-e", eperson.getEmail(), "-p", PASSWORD};
ScriptLauncher.handleScript(args, ScriptLauncher.getConfig(kernelImpl), testDSpaceRunnableHandler, kernelImpl);

int run = ScriptLauncher.handleScript(args, ScriptLauncher.getConfig(kernelImpl),
testDSpaceRunnableHandler, kernelImpl);
assertEquals(0, run);
// There should be no errors or warnings
checkNoError(testDSpaceRunnableHandler);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

import java.util.LinkedList;
import java.util.List;
import java.util.Objects;

import org.apache.commons.cli.Option;
import org.apache.commons.collections4.CollectionUtils;
Expand Down Expand Up @@ -36,6 +37,13 @@ public ScriptRest convert(ScriptConfiguration scriptConfiguration, Projection pr

List<ParameterRest> parameterRestList = new LinkedList<>();
for (Option option : CollectionUtils.emptyIfNull(scriptConfiguration.getOptions().getOptions())) {
if ("file-preview".equalsIgnoreCase(scriptConfiguration.getName())
&& (Objects.equals(option.getOpt(), "e")
|| Objects.equals(option.getOpt(), "p")
|| Objects.equals(option.getLongOpt(), "email")
|| Objects.equals(option.getLongOpt(), "password"))) {
continue;
}
ParameterRest parameterRest = new ParameterRest();
parameterRest.setDescription(option.getDescription());
parameterRest.setName((option.getOpt() != null ? "-" + option.getOpt() : "--" + option.getLongOpt()));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -579,8 +579,56 @@ public void postProcessAndVerifyOutput() throws Exception {
}
}

@Test
public void postFilePreviewProcess() throws Exception {
LinkedList<DSpaceCommandLineParameter> parameters = new LinkedList<>();

List<ParameterValueRest> list = parameters.stream()
.map(dSpaceCommandLineParameter -> dSpaceRunnableParameterConverter
.convert(dSpaceCommandLineParameter, Projection.DEFAULT))
.collect(Collectors.toList());

String token = getAuthToken(admin.getEmail(), password);
List<ProcessStatus> acceptableProcessStatuses = new LinkedList<>();
acceptableProcessStatuses.addAll(Arrays.asList(ProcessStatus.SCHEDULED,
ProcessStatus.RUNNING,
ProcessStatus.COMPLETED));

AtomicReference<Integer> idRef = new AtomicReference<>();

try {
getClient(token)
.perform(multipart("/api/system/scripts/file-preview/processes")
.param("properties", new ObjectMapper().writeValueAsString(list)))
.andExpect(status().isAccepted())
.andExpect(jsonPath("$", is(
ProcessMatcher.matchProcess("file-preview",
String.valueOf(admin.getID()),
parameters,
acceptableProcessStatuses))))
.andDo(result -> idRef
.set(read(result.getResponse().getContentAsString(), "$.processId")));

Process process = processService.find(context, idRef.get());
Bitstream bitstream = processService.getBitstream(context, process, Process.OUTPUT_TYPE);
MvcResult mvcResult = getClient(token)
.perform(get("/api/core/bitstreams/" + bitstream.getID() + "/content")).andReturn();
String content = mvcResult.getResponse().getContentAsString();

getClient(token).perform(get("/api/system/processes/" + idRef.get() + "/output"))
.andExpect(status().isOk());
assertThat(content, CoreMatchers
.containsString("INFO file-preview - " + process.getID() + " @ The script has started"));
assertThat(content,
CoreMatchers.containsString(
"INFO file-preview - " + process.getID() +
" @ Authentication by user: " + admin.getEmail()));
assertThat(content, CoreMatchers
.containsString("INFO file-preview - " + process.getID() + " @ The script has completed"));
} finally {
ProcessBuilder.deleteProcess(idRef.get());
}
}

@Test
public void postProcessAdminWithWrongContentTypeBadRequestException() throws Exception {
Expand Down