diff --git a/dspace-api/src/main/java/org/dspace/content/PreviewContentServiceImpl.java b/dspace-api/src/main/java/org/dspace/content/PreviewContentServiceImpl.java index 793b4ffb5065..a29e05e8aefe 100644 --- a/dspace-api/src/main/java/org/dspace/content/PreviewContentServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/content/PreviewContentServiceImpl.java @@ -155,21 +155,26 @@ public List findAll(Context context) throws SQLException { @Override public boolean canPreview(Context context, Bitstream bitstream, boolean authorization) throws SQLException, AuthorizeException { - try { - // Check it is allowed by configuration - boolean isAllowedByCfg = configurationService.getBooleanProperty("file.preview.enabled", true); - if (!isAllowedByCfg) { - return false; - } - - // Check it is allowed by license - if (authorization) { + // Check it is allowed by configuration + boolean isAllowedByCfg = configurationService.getBooleanProperty("file.preview.enabled", true); + if (!isAllowedByCfg) { + return false; + } + if (authorization) { + // Verify that bitstream policy allows user to READ the bitstream. + // If not, the preview content is disabled. + try { authorizeService.authorizeAction(context, bitstream, Constants.READ); + } catch (AuthorizeException e) { + // In case the license agreement(for bitstream downloading) is needed, + // the MissingLicenseAgreementException, that extends AuthorizeException, is thrown. + // For this case we also disable the content preview. + // Otherwise, user could see the content of some files without accepting the agreement, + // which could cause a security issue. + return false; } - return true; - } catch (MissingLicenseAgreementException e) { - return false; } + return true; } @Override @@ -178,13 +183,16 @@ public List getFilePreviewContent(Context context, Bitstream bitstream File file = null; try { - file = bitstreamService.retrieveFile(context, bitstream, false); // Retrieve the file + file = bitstreamService.retrieveFile(context, bitstream, true); // Retrieve the file if (Objects.nonNull(file)) { fileInfos = processFileToFilePreview(context, bitstream, file); } } catch (MissingLicenseAgreementException e) { - log.error("Missing license agreement: ", e); + log.warn("File Preview disabled: Missing license agreement!"); + throw e; + } catch (AuthorizeException e) { + log.warn("File Preview disabled: Authorization error!"); throw e; } catch (IOException e) { log.error("IOException during file processing: ", e); diff --git a/dspace-api/src/test/java/org/dspace/scripts/filepreview/FilePreviewIT.java b/dspace-api/src/test/java/org/dspace/scripts/filepreview/FilePreviewIT.java index d03384c25d7b..aeb8e050e9ef 100644 --- a/dspace-api/src/test/java/org/dspace/scripts/filepreview/FilePreviewIT.java +++ b/dspace-api/src/test/java/org/dspace/scripts/filepreview/FilePreviewIT.java @@ -13,6 +13,7 @@ import static org.hamcrest.Matchers.hasItem; import static org.hamcrest.Matchers.hasSize; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; @@ -60,7 +61,8 @@ public class FilePreviewIT extends AbstractIntegrationTestWithDatabase { Collection collection; Item item; - EPerson eperson; + // avoid using eperson created in superclass + EPerson ePerson; String PASSWORD = "test"; @Before @@ -68,7 +70,7 @@ public void setup() throws SQLException, AuthorizeException { InputStream previewZipIs = getClass().getResourceAsStream("preview-file-test.zip"); context.turnOffAuthorisationSystem(); - eperson = EPersonBuilder.createEPerson(context) + ePerson = EPersonBuilder.createEPerson(context) .withEmail("test@test.edu").withPassword(PASSWORD).build(); Community community = CommunityBuilder.createCommunity(context).withName("Com").build(); collection = CollectionBuilder.createCollection(context, community).withName("Col").build(); @@ -106,7 +108,7 @@ public void testUnauthorizedEmail() throws Exception { public void testUnauthorizedPassword() throws Exception { // Run the script TestDSpaceRunnableHandler testDSpaceRunnableHandler = new TestDSpaceRunnableHandler(); - String[] args = new String[] { "file-preview", "-e", eperson.getEmail()}; + String[] args = new String[] { "file-preview", "-e", ePerson.getEmail()}; int run = ScriptLauncher.handleScript(args, ScriptLauncher.getConfig(kernelImpl), testDSpaceRunnableHandler, kernelImpl); assertEquals(1, run); // Since a ParseException was caught, expect return code 1 @@ -116,7 +118,7 @@ public void testUnauthorizedPassword() throws Exception { public void testWhenNoFilesRun() throws Exception { TestDSpaceRunnableHandler testDSpaceRunnableHandler = new TestDSpaceRunnableHandler(); - String[] args = new String[] { "file-preview", "-e", eperson.getEmail(), "-p", PASSWORD }; + String[] args = new String[] { "file-preview", "-e", ePerson.getEmail(), "-p", PASSWORD }; int run = ScriptLauncher.handleScript(args, ScriptLauncher.getConfig(kernelImpl), testDSpaceRunnableHandler, kernelImpl); assertEquals(0, run); @@ -125,53 +127,68 @@ public void testWhenNoFilesRun() throws Exception { @Test public void testForSpecificItem() throws Exception { + Item item2 = createOtherWorkspaceItemWithBitstream(ePerson, 0); // Run the script - runScriptForItemWithBitstreams(item); + runScriptForItemWithBitstreams(item2, ePerson, PASSWORD); + + Bitstream b = bitstreamService.findAll(context).stream() + .filter(bitstream -> bitstream.getName().equals("logos.tgz")) + .findFirst().orElse(null); + + assertNotNull(b); + assertEquals("logos.tgz", b.getName()); + + // the preview content was created since the item was created by the same user as the script was run + assertTrue("Expects preview content created.", previewContentService.hasPreview(context, b)); + assertEquals(2, previewContentService.getPreview(context, b).size()); } @Test - public void testPreviewWithSyncStorage() throws Exception { - configurationService.setProperty("sync.storage.service.enabled", true); + public void testWhenScriptCannotCreateFilePreview() throws Exception { + Item item2 = createOtherWorkspaceItemWithBitstream(eperson, 0); + // Run the script as another user, without admin rights + runScriptForItemWithBitstreams(item2, ePerson, PASSWORD); - context.turnOffAuthorisationSystem(); + Bitstream b = bitstreamService.findAll(context).stream() + .filter(bitstream -> bitstream.getName().equals("logos.tgz")) + .findFirst().orElse(null); - WorkspaceItem wItem2; - try (InputStream tgzFile = getClass().getResourceAsStream("logos.tgz")) { - wItem2 = WorkspaceItemBuilder.createWorkspaceItem(context, collection) - .withBitstream("logos.tgz", "/local/path/logos.tgz", tgzFile, SYNC_STORE_NUMBER) - .build(); - } + assertNotNull(b); + assertEquals("logos.tgz", b.getName()); - context.restoreAuthSystemState(); + // the preview content cannot be created since the item was created by another user (eperson) + // than the user (ePerson) who runs the script + assertFalse("Expects preview content not created.", previewContentService.hasPreview(context, b)); - // Get the item and its bitstream - Item item2 = wItem2.getItem(); - List bundles = item2.getBundles(); - Bitstream bitstream2 = bundles.get(0).getBitstreams().get(0); + // Run the script as admin user + runScriptForItemWithBitstreams(item2, admin, password); - // Set the bitstream format to application/zip - BitstreamFormat bitstreamFormat = bitstreamFormatService.findByMIMEType(context, "application/x-gtar"); - bitstream2.setFormat(context, bitstreamFormat); - bitstreamService.update(context, bitstream2); - context.commit(); - context.reloadEntity(bitstream2); - context.reloadEntity(item2); + // now the preview content was created since the script was run by admin user + assertTrue("Expects preview content created.", previewContentService.hasPreview(context, b)); + assertEquals(2, previewContentService.getPreview(context, b).size()); + } - runScriptForItemWithBitstreams(item2); + @Test + public void testPreviewWithSyncStorage() throws Exception { + configurationService.setProperty("sync.storage.service.enabled", true); + Item item2 = createOtherWorkspaceItemWithBitstream(ePerson, SYNC_STORE_NUMBER); + // Run the script + runScriptForItemWithBitstreams(item2, ePerson, PASSWORD); - Bitstream b2 = bitstreamService.findAll(context).stream() - .filter(b -> b.getStoreNumber() == SYNC_STORE_NUMBER) + Bitstream b = bitstreamService.findAll(context).stream() + .filter(bitstream -> bitstream.getStoreNumber() == SYNC_STORE_NUMBER) .findFirst().orElse(null); - assertNotNull(b2); - assertTrue("Expects preview content created and stored.", previewContentService.hasPreview(context, b2)); + assertNotNull(b); + assertEquals("logos.tgz", b.getName()); + assertTrue("Expects preview content created and stored.", previewContentService.hasPreview(context, b)); } @Test public void testForAllItem() throws Exception { // Run the script TestDSpaceRunnableHandler testDSpaceRunnableHandler = new TestDSpaceRunnableHandler(); - String[] args = new String[] { "file-preview", "-e", eperson.getEmail(), "-p", PASSWORD}; + String[] args = new String[] { "file-preview", "-e", ePerson.getEmail(), "-p", PASSWORD}; int run = ScriptLauncher.handleScript(args, ScriptLauncher.getConfig(kernelImpl), testDSpaceRunnableHandler, kernelImpl); assertEquals(0, run); @@ -184,11 +201,11 @@ private void checkNoError(TestDSpaceRunnableHandler testDSpaceRunnableHandler) { assertThat(testDSpaceRunnableHandler.getWarningMessages(), empty()); } - private void runScriptForItemWithBitstreams(Item item) throws Exception { + private void runScriptForItemWithBitstreams(Item item, EPerson user, String password) throws Exception { // Run the script TestDSpaceRunnableHandler testDSpaceRunnableHandler = new TestDSpaceRunnableHandler(); String[] args = new String[] { "file-preview", "-u", item.getID().toString(), - "-e", eperson.getEmail(), "-p", PASSWORD}; + "-e", user.getEmail(), "-p", password}; int run = ScriptLauncher.handleScript(args, ScriptLauncher.getConfig(kernelImpl), testDSpaceRunnableHandler, kernelImpl); assertEquals(0, run); @@ -201,6 +218,32 @@ private void runScriptForItemWithBitstreams(Item item) 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 by user: " + eperson.getEmail()))); + hasItem(containsString("Authentication by user: " + user.getEmail()))); + } + + private Item createOtherWorkspaceItemWithBitstream(EPerson user, int storageNumber) throws Exception { + context.turnOffAuthorisationSystem(); + context.setCurrentUser(user); + WorkspaceItem wItem2; + try (InputStream tgzFile = getClass().getResourceAsStream("logos.tgz")) { + wItem2 = WorkspaceItemBuilder.createWorkspaceItem(context, collection) + .withBitstream("logos.tgz", "/local/path/logos.tgz", tgzFile, storageNumber) + .build(); + } + context.restoreAuthSystemState(); + + Item item2 = wItem2.getItem(); + List bundles = item2.getBundles(); + Bitstream bitstream2 = bundles.get(0).getBitstreams().get(0); + + // Set the bitstream format to application/zip + BitstreamFormat bitstreamFormat = bitstreamFormatService.findByMIMEType(context, "application/x-gtar"); + bitstream2.setFormat(context, bitstreamFormat); + bitstreamService.update(context, bitstream2); + context.commit(); + context.reloadEntity(bitstream2); + context.reloadEntity(item2); + + return item2; } } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/MetadataBitstreamRestRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/MetadataBitstreamRestRepository.java index 008635fbeeee..296dd870bf9a 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/MetadataBitstreamRestRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/MetadataBitstreamRestRepository.java @@ -22,6 +22,7 @@ import org.dspace.app.rest.exception.UnprocessableEntityException; import org.dspace.app.rest.model.MetadataBitstreamWrapperRest; import org.dspace.app.rest.model.wrapper.MetadataBitstreamWrapper; +import org.dspace.authorize.AuthorizeException; import org.dspace.content.Bitstream; import org.dspace.content.Bundle; import org.dspace.content.DSpaceObject; @@ -108,7 +109,7 @@ public Page findByHandle(@Parameter(value = "handl for (Bitstream bitstream : bitstreams) { String url = previewContentService.composePreviewURL(context, item, bitstream, contextPath); List fileInfos = new ArrayList<>(); - boolean canPreview = previewContentService.canPreview(context, bitstream, false); + boolean canPreview = previewContentService.canPreview(context, bitstream, true); String mimeType = bitstream.getFormat(context).getMIMEType(); // HTML content could be longer than the limit, so we do not store it in the DB. // It has to be generated even if property is false. @@ -119,7 +120,12 @@ public Page findByHandle(@Parameter(value = "handl boolean allowComposePreviewContent = configurationService.getBooleanProperty ("create.file-preview.on-item-page-load", false); if (allowComposePreviewContent) { - fileInfos.addAll(previewContentService.getFilePreviewContent(context, bitstream)); + try { + fileInfos.addAll(previewContentService.getFilePreviewContent(context, bitstream)); + } catch (AuthorizeException e) { + log.warn("Cannot create preview content for bitstream: {} because: {}", + bitstream.getID(), e.getMessage()); + } // Do not store HTML content in the database because it could be longer than the limit // of the database column if (!fileInfos.isEmpty() && diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/MetadataBitstreamRestRepositoryIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/MetadataBitstreamRestRepositoryIT.java index 544240beffcc..2b344b9862cf 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/MetadataBitstreamRestRepositoryIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/MetadataBitstreamRestRepositoryIT.java @@ -9,6 +9,7 @@ import static org.dspace.app.rest.utils.Utils.DEFAULT_PAGE_SIZE; import static org.hamcrest.Matchers.hasItem; +import static org.hamcrest.Matchers.hasSize; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.notNullValue; import static org.junit.Assert.assertFalse; @@ -21,29 +22,43 @@ import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.sql.SQLException; +import java.util.Set; import org.apache.commons.codec.CharEncoding; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils; import org.dspace.app.rest.test.AbstractControllerIntegrationTest; import org.dspace.app.util.Util; +import org.dspace.authorize.AuthorizeException; import org.dspace.authorize.service.AuthorizeService; import org.dspace.builder.BitstreamBuilder; +import org.dspace.builder.ClarinLicenseBuilder; +import org.dspace.builder.ClarinLicenseLabelBuilder; import org.dspace.builder.CollectionBuilder; import org.dspace.builder.CommunityBuilder; +import org.dspace.builder.EPersonBuilder; import org.dspace.builder.ItemBuilder; import org.dspace.content.Bitstream; import org.dspace.content.Collection; import org.dspace.content.Item; +import org.dspace.content.clarin.ClarinLicense; +import org.dspace.content.clarin.ClarinLicenseLabel; +import org.dspace.content.factory.ClarinServiceFactory; import org.dspace.content.service.BundleService; import org.dspace.content.service.PreviewContentService; +import org.dspace.content.service.clarin.ClarinLicenseLabelService; import org.dspace.content.service.clarin.ClarinLicenseResourceMappingService; +import org.dspace.content.service.clarin.ClarinLicenseService; import org.dspace.core.Constants; +import org.dspace.eperson.EPerson; +import org.dspace.eperson.Group; +import org.dspace.eperson.service.GroupService; import org.dspace.services.ConfigurationService; import org.hamcrest.Matchers; import org.junit.Before; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.web.servlet.MockMvc; public class MetadataBitstreamRestRepositoryIT extends AbstractControllerIntegrationTest { @@ -71,9 +86,19 @@ public class MetadataBitstreamRestRepositoryIT extends AbstractControllerIntegra @Autowired PreviewContentService previewContentService; + @Autowired + private GroupService groupService; + + EPerson ePerson; + String PASSWORD = "test"; + @Before public void setup() throws Exception { context.turnOffAuthorisationSystem(); + + ePerson = EPersonBuilder.createEPerson(context) + .withEmail("test@test.edu").withPassword(PASSWORD).build(); + parentCommunity = CommunityBuilder.createCommunity(context) .withName("Parent Community") .build(); @@ -259,6 +284,165 @@ public void searchMethodsExist() throws Exception { .andExpect(jsonPath("$._links.byHandle", notNullValue())); } + @Test + public void previewDisabledByReadPermission() throws Exception { + context.turnOffAuthorisationSystem(); + Collection col = CollectionBuilder.createCollection(context, parentCommunity).withName("Collection2").build(); + Item item = ItemBuilder.createItem(context, col).withAuthor(AUTHOR).build(); + + try { + // create bitstream with ADMIN reader group, + // so the non admin user cannot read the bitstream and preview content is not available for non admin user + try (InputStream is = getClass().getResourceAsStream("assetstore/logos.tgz")) { + BitstreamBuilder. + createBitstream(context, item, is) + .withName("Bitstream") + .withDescription("Description") + .withMimeType("application/x-gtar") + .withReaderGroup(groupService.findByName(context, Group.ADMIN)) + .build(); + } + context.restoreAuthSystemState(); + + // Admin user can preview the archive file because the bitstream has the ADMIN read permission, + // and also the fileInfo should be generated for admin user. + checkFilePreviewAsAdmin(item, true, 2); + + // Non admin user cannot preview the archive file because the bitstream has only ADMIN read permission, + // and also the fileInfo should be empty in this case. + // Note that file preview was generated in the previous check, but it's not visible for non-authorized user. + checkFilePreview(item, false, 0); + } finally { + ItemBuilder.deleteItem(item.getID()); + CollectionBuilder.deleteCollection(col.getID()); + } + } + + @Test + public void previewDisabledForHtmlFileByReadPermission() throws Exception { + context.turnOffAuthorisationSystem(); + Collection col = CollectionBuilder.createCollection(context, parentCommunity).withName("Collection2").build(); + Item item = ItemBuilder.createItem(context, col).withAuthor(AUTHOR).build(); + + try { + // create bitstream with ADMIN reader group, + // so the non admin user cannot read the bitstream and preview content is not available for non admin user + try (InputStream is = getClass().getResourceAsStream("assetstore/hello.html")) { + BitstreamBuilder. + createBitstream(context, item, is) + .withName("hello.html") + .withDescription("HTML file") + .withMimeType("text/html") + .withReaderGroup(groupService.findByName(context, Group.ADMIN)) + .build(); + } + context.restoreAuthSystemState(); + + // Admin user can preview the html file because the bitstream has the ADMIN read permission, + // and also the fileInfo should be generated for admin user. + checkFilePreviewAsAdmin(item, true, 1); + + // Non admin user cannot preview the html file because the bitstream has only ADMIN read permission, + // and also the fileInfo should be empty in this case. + checkFilePreview(item, false, 0); + } finally { + ItemBuilder.deleteItem(item.getID()); + CollectionBuilder.deleteCollection(col.getID()); + } + } + + @Test + public void previewEnabledForHtmlFile() throws Exception { + context.turnOffAuthorisationSystem(); + Collection col = CollectionBuilder.createCollection(context, parentCommunity).withName("Collection2").build(); + Item item = ItemBuilder.createItem(context, col).withAuthor(AUTHOR).build(); + + try { + // create bitstream with ADMIN reader group, + // so the non admin user cannot read the bitstream and preview content is not available for non admin user + try (InputStream is = getClass().getResourceAsStream("assetstore/hello.html")) { + BitstreamBuilder. + createBitstream(context, item, is) + .withName("hello.html") + .withDescription("HTML file") + .withMimeType("text/html") + .build(); + } + context.restoreAuthSystemState(); + // user can preview the html file because the bitstream has read permission + checkFilePreview(item, true, 1); + } finally { + ItemBuilder.deleteItem(item.getID()); + CollectionBuilder.deleteCollection(col.getID()); + } + } + + @Test + public void previewNotAllowedWhenClarinLicenceAgreementIsNeeded() throws Exception { + context.turnOffAuthorisationSystem(); + Collection col = CollectionBuilder.createCollection(context, parentCommunity).withName("Collection2").build(); + Item item = ItemBuilder.createItem(context, col).withAuthor(AUTHOR).build(); + + ClarinLicenseService clarinLicenseService = ClarinServiceFactory.getInstance().getClarinLicenseService(); + ClarinLicense clarinLicense = addClarinLicenseThatNeedsConfirmation(clarinLicenseService, item); + + try { + Bitstream bitstream; + try (InputStream is = getClass().getResourceAsStream("assetstore/logos.tgz")) { + bitstream = BitstreamBuilder. + createBitstream(context, item, is) + .withName("Bitstream") + .withDescription("Description") + .withMimeType("application/x-gtar") + .build(); + } + + clarinLicenseService.addClarinLicenseToBitstream(context, item, bitstream.getBundles().get(0), bitstream); + + context.restoreAuthSystemState(); + // Non admin user cannot preview the archive file when the license agreement is needed. + checkFilePreview(item, false, 0); + } finally { + ItemBuilder.deleteItem(item.getID()); + CollectionBuilder.deleteCollection(col.getID()); + ClarinLicenseBuilder.deleteClarinLicense(clarinLicense.getID()); + ClarinLicenseLabelBuilder.deleteClarinLicenseLabel(clarinLicense.getLicenseLabels().get(0).getID()); + } + } + + @Test + public void previewNotAllowedForHtmlFileWhenLicenceAgreementIsNeeded() throws Exception { + context.turnOffAuthorisationSystem(); + Collection col = CollectionBuilder.createCollection(context, parentCommunity).withName("Collection2").build(); + Item item = ItemBuilder.createItem(context, col).withAuthor(AUTHOR).build(); + + ClarinLicenseService clarinLicenseService = ClarinServiceFactory.getInstance().getClarinLicenseService(); + ClarinLicense clarinLicense = addClarinLicenseThatNeedsConfirmation(clarinLicenseService, item); + + try { + Bitstream bitstream; + try (InputStream is = getClass().getResourceAsStream("assetstore/hello.html")) { + bitstream = BitstreamBuilder. + createBitstream(context, item, is) + .withName("Hello.html") + .withDescription("HTML file") + .withMimeType("text/html") + .build(); + } + + clarinLicenseService.addClarinLicenseToBitstream(context, item, bitstream.getBundles().get(0), bitstream); + + context.restoreAuthSystemState(); + // Non admin user cannot preview the html file when the license agreement is needed. + checkFilePreview(item, false, 0); + } finally { + ItemBuilder.deleteItem(item.getID()); + CollectionBuilder.deleteCollection(col.getID()); + ClarinLicenseBuilder.deleteClarinLicense(clarinLicense.getID()); + ClarinLicenseLabelBuilder.deleteClarinLicenseLabel(clarinLicense.getLicenseLabels().get(0).getID()); + } + } + private void composeURL() { String identifier = null; if (publicItem != null && publicItem.getHandle() != null) { @@ -285,4 +469,64 @@ private void composeURL() { url += "&isAllowed=" + isAllowed; } + + /** + * Create a license that needs confirmation and set this license to the item, + * so the user has to confirm the license agreement before downloading the file(s). + * + * @param clarinLicenseService ClarinLicenseService + * @param item Item + * @return ClarinLicense that needs confirmation + * @throws SQLException SQLException + * @throws AuthorizeException AuthorizeException + */ + private ClarinLicense addClarinLicenseThatNeedsConfirmation(ClarinLicenseService clarinLicenseService, Item item) + throws SQLException, AuthorizeException { + + ClarinLicenseLabelService clarinLicenseLabelService = + ClarinServiceFactory.getInstance().getClarinLicenseLabelService(); + + ClarinLicenseLabel clarinLicenseLabel = ClarinLicenseLabelBuilder.createClarinLicenseLabel(context).build(); + clarinLicenseLabel.setLabel("CLL"); + clarinLicenseLabel.setTitle("CLL Title"); + clarinLicenseLabelService.update(context, clarinLicenseLabel); + + ClarinLicense clarinLicense = ClarinLicenseBuilder.createClarinLicense(context).build(); + clarinLicense.setName("CL Name"); + clarinLicense.setConfirmation(ClarinLicense.Confirmation.ASK_ALWAYS); + clarinLicense.setDefinition("CL Definition"); + clarinLicense.setRequiredInfo("CL Req"); + clarinLicense.setLicenseLabels(Set.of(clarinLicenseLabel)); + + clarinLicenseService.addLicenseMetadataToItem(context, clarinLicense, item); + clarinLicenseService.update(context, clarinLicense); + + return clarinLicense; + } + + private void checkFilePreview(Item item, boolean filePreviewExpected, int expectedFileInfoSize) throws Exception { + MockMvc client = getClient(getAuthToken(ePerson.getEmail(), PASSWORD)); + performCheck(client, item, filePreviewExpected, expectedFileInfoSize); + } + + private void checkFilePreviewAsAdmin(Item item, boolean filePreviewExpected, int expectedFileInfoSize) + throws Exception { + MockMvc client = getClient(getAuthToken(admin.getEmail(), password)); + performCheck(client, item, filePreviewExpected, expectedFileInfoSize); + } + + private void performCheck(MockMvc client, Item item, boolean filePreviewExpected, int expectedFileInfoSize) + throws Exception { + client.perform(get(METADATABITSTREAM_SEARCH_BY_HANDLE_ENDPOINT) + .param("handle", item.getHandle()) + .param("fileGrpType", FILE_GRP_TYPE)) + .andExpect(status().isOk()) + .andExpect(content().contentType(contentType)) + .andExpect(jsonPath("$._embedded.metadatabitstreams").exists()) + .andExpect(jsonPath("$._embedded.metadatabitstreams").isArray()) + .andExpect(jsonPath("$._embedded.metadatabitstreams", hasSize(1))) + .andExpect(jsonPath("$._embedded.metadatabitstreams[0].canPreview").value(filePreviewExpected)) + .andExpect(jsonPath("$._embedded.metadatabitstreams[0].fileInfo").isArray()) + .andExpect(jsonPath("$._embedded.metadatabitstreams[0].fileInfo", hasSize(expectedFileInfoSize))); + } } diff --git a/dspace-server-webapp/src/test/resources/org/dspace/app/rest/assetstore/hello.html b/dspace-server-webapp/src/test/resources/org/dspace/app/rest/assetstore/hello.html new file mode 100644 index 000000000000..f2e613f8368b --- /dev/null +++ b/dspace-server-webapp/src/test/resources/org/dspace/app/rest/assetstore/hello.html @@ -0,0 +1,10 @@ + + + + + Hello + + +

Hello

+ + \ No newline at end of file