diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/ItemAddBundleController.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/ItemAddBundleController.java index 5175dec5e2e3..b3444a739e77 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/ItemAddBundleController.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/ItemAddBundleController.java @@ -11,9 +11,12 @@ import java.io.IOException; import java.sql.SQLException; +import java.util.List; +import java.util.Objects; import java.util.UUID; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import javax.ws.rs.BadRequestException; import com.fasterxml.jackson.databind.ObjectMapper; import org.dspace.app.rest.converter.ConverterService; @@ -26,10 +29,17 @@ import org.dspace.app.rest.utils.ContextUtil; import org.dspace.app.rest.utils.Utils; import org.dspace.authorize.AuthorizeException; +import org.dspace.content.Bitstream; import org.dspace.content.Bundle; import org.dspace.content.Item; +import org.dspace.content.clarin.ClarinLicense; import org.dspace.content.service.ItemService; +import org.dspace.content.service.clarin.ClarinLicenseResourceMappingService; +import org.dspace.content.service.clarin.ClarinLicenseService; +import org.dspace.core.Constants; import org.dspace.core.Context; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.rest.webmvc.ControllerUtils; import org.springframework.data.rest.webmvc.ResourceNotFoundException; @@ -41,6 +51,7 @@ import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; /** @@ -64,6 +75,8 @@ + "/" + BundleRest.PLURAL_NAME) public class ItemAddBundleController { + private static final Logger log = LoggerFactory.getLogger(ItemAddBundleController.class); + @Autowired ConverterService converter; @@ -79,6 +92,12 @@ public class ItemAddBundleController { @Autowired Utils utils; + @Autowired + ClarinLicenseService clarinLicenseService; + + @Autowired + ClarinLicenseResourceMappingService clarinLicenseResourceMappingService; + /** * Method to add a Bundle to an Item with the given UUID in the URL. This will create a Bundle with the * name provided in the request and attach this to the Item that matches the UUID in the URL. @@ -111,4 +130,61 @@ public ResponseEntity> addBundleToItem(@PathVariable UUID return ControllerUtils.toResponseEntity(HttpStatus.CREATED, new HttpHeaders(), bundleResource); } + /** + * Method to update the license for all bitstreams in the bundle of an item with the given UUID in the URL. + * This will remove the old license and attach the new license to all bitstreams in the bundle. + * The license is identified by the licenseID parameter in the request. If the licenseID is not found (-1), the old + * license will be detached, but the new license will not be attached. + * @param uuid + * @param licenseId + * @param request + * @param response + * @return + * @throws SQLException + * @throws AuthorizeException + */ + @RequestMapping(method = RequestMethod.PUT) + @PreAuthorize("hasPermission(#uuid, 'ITEM', 'ADD')") + public ItemRest updateLicenseForBundle(@PathVariable UUID uuid, + @RequestParam("licenseID") Integer licenseId, + HttpServletRequest request, + HttpServletResponse response) + throws SQLException, AuthorizeException { + Context context = ContextUtil.obtainContext(request); + if (Objects.isNull(context)) { + throw new BadRequestException("No context found for current user"); + } + Item item = itemService.find(context, uuid); + + if (item == null) { + throw new ResourceNotFoundException("Could not find item with id " + uuid); + } + + ClarinLicense clarinLicense = clarinLicenseService.find(context, licenseId); + if (Objects.isNull(clarinLicense)) { + log.warn("Cannot find clarin license with id: " + licenseId + ". The old license will be detached, " + + "but the new one will not be attached."); + } + List bundles = item.getBundles(Constants.CONTENT_BUNDLE_NAME); + for (Bundle clarinBundle : bundles) { + List bitstreamList = clarinBundle.getBitstreams(); + for (Bitstream bundleBitstream : bitstreamList) { + // in case bitstream ID exists in license table for some reason .. just remove it + this.clarinLicenseResourceMappingService.detachLicenses(context, bundleBitstream); + if (Objects.nonNull(clarinLicense)) { + // add the license to bitstream + this.clarinLicenseResourceMappingService.attachLicense(context, clarinLicense, bundleBitstream); + } + } + } + clarinLicenseService.clearLicenseMetadataFromItem(context, item); + if (Objects.nonNull(clarinLicense)) { + clarinLicenseService.addLicenseMetadataToItem(context, clarinLicense, item); + } + + itemService.update(context, item); + context.commit(); + + return converter.toRest(item, utils.obtainProjection()); + } } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/authorization/impl/CanManageLicense.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/authorization/impl/CanManageLicense.java new file mode 100644 index 000000000000..a8c4a494ad56 --- /dev/null +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/authorization/impl/CanManageLicense.java @@ -0,0 +1,53 @@ +/** + * 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.app.rest.authorization.impl; + +import java.sql.SQLException; +import java.util.Objects; +import java.util.UUID; + +import org.dspace.app.rest.authorization.AuthorizationFeature; +import org.dspace.app.rest.authorization.AuthorizationFeatureDocumentation; +import org.dspace.app.rest.model.BaseObjectRest; +import org.dspace.app.rest.model.ItemRest; +import org.dspace.authorize.service.AuthorizeService; +import org.dspace.content.Item; +import org.dspace.content.service.ItemService; +import org.dspace.core.Context; +import org.dspace.discovery.SearchServiceException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +@AuthorizationFeatureDocumentation(name = CanManageLicense.NAME, + description = "It can be used to verify if the user can attach/detach a license to an Item") +public class CanManageLicense implements AuthorizationFeature { + + public static final String NAME = "canManageLicense"; + + @Autowired + private ItemService itemService; + @Autowired + private AuthorizeService authorizeService; + + @Override + public boolean isAuthorized(Context context, BaseObjectRest object) throws SQLException, SearchServiceException { + Item item = itemService.find(context, UUID.fromString(((ItemRest) object).getUuid())); + if (Objects.nonNull(item)) { + return authorizeService.isAdmin(context, item); + } + return false; + } + + @Override + public String[] getSupportedTypes() { + return new String[]{ + ItemRest.CATEGORY + "." + ItemRest.NAME + }; + } +}