Skip to content

Commit

Permalink
Edit Item's license (#654)
Browse files Browse the repository at this point in the history
* Added authorization for the `Edit Item - License` menu option.

* Created endpoint for updating license of the Item.

* Added functionality only for detaching the license.
  • Loading branch information
milanmajchrak authored May 20, 2024
1 parent 7232e97 commit cae7292
Show file tree
Hide file tree
Showing 2 changed files with 129 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -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;

/**
Expand All @@ -64,6 +75,8 @@
+ "/" + BundleRest.PLURAL_NAME)
public class ItemAddBundleController {

private static final Logger log = LoggerFactory.getLogger(ItemAddBundleController.class);

@Autowired
ConverterService converter;

Expand All @@ -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.
Expand Down Expand Up @@ -111,4 +130,61 @@ public ResponseEntity<RepresentationModel<?>> 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<Bundle> bundles = item.getBundles(Constants.CONTENT_BUNDLE_NAME);
for (Bundle clarinBundle : bundles) {
List<Bitstream> 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());
}
}
Original file line number Diff line number Diff line change
@@ -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
};
}
}

0 comments on commit cae7292

Please sign in to comment.