package eu.europeana.cloud.service.mcs.rest; import static eu.europeana.cloud.common.web.ParamConstants.F_PROVIDER; import static eu.europeana.cloud.common.web.ParamConstants.P_CLOUDID; import static eu.europeana.cloud.common.web.ParamConstants.P_REPRESENTATIONNAME; import javax.ws.rs.Consumes; import javax.ws.rs.DELETE; import javax.ws.rs.FormParam; import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import javax.ws.rs.core.UriInfo; import com.qmino.miredot.annotations.ReturnType; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Scope; import org.springframework.security.access.prepost.PostAuthorize; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.acls.domain.BasePermission; import org.springframework.security.acls.domain.ObjectIdentityImpl; import org.springframework.security.acls.domain.PrincipalSid; import org.springframework.security.acls.model.MutableAcl; import org.springframework.security.acls.model.MutableAclService; import org.springframework.security.acls.model.ObjectIdentity; import org.springframework.stereotype.Component; import eu.europeana.cloud.common.model.Record; import eu.europeana.cloud.common.model.Representation; import eu.europeana.cloud.service.aas.authentication.SpringUserUtils; import eu.europeana.cloud.service.mcs.RecordService; import eu.europeana.cloud.service.mcs.exception.ProviderNotExistsException; import eu.europeana.cloud.service.mcs.exception.RecordNotExistsException; import eu.europeana.cloud.service.mcs.exception.RepresentationNotExistsException; /** * Resource to manage representations. */ @Path("/records/{" + P_CLOUDID + "}/representations/{" + P_REPRESENTATIONNAME + "}") @Component @Scope("request") public class RepresentationResource { @Autowired private RecordService recordService; @Autowired private MutableAclService mutableAclService; private final String RECORD_CLASS_NAME = Record.class.getName(); private final String REPRESENTATION_CLASS_NAME = Representation.class .getName(); /** * Returns the latest persistent version of a given representation . * <strong>Read permissions required.</strong> * * @summary get a representation * @param globalId cloud id of the record which contains the representation . * @param schema name of the representation . * * @return requested representation in its latest persistent version. * @throws RepresentationNotExistsException * representation does not exist or no persistent version of * this representation exists. */ @GET @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) @PostAuthorize("hasPermission" + "( " + " (#globalId).concat('/').concat(#schema).concat('/').concat(returnObject.version) ," + " 'eu.europeana.cloud.common.model.Representation', read" + ")") @ReturnType("eu.europeana.cloud.common.model.Representation") public Representation getRepresentation(@Context UriInfo uriInfo, @PathParam(P_CLOUDID) String globalId, @PathParam(P_REPRESENTATIONNAME) String schema) throws RepresentationNotExistsException { Representation info = recordService.getRepresentation(globalId, schema); prepare(uriInfo, info); return info; } /** * Deletes representation with all of its versions for a given cloudId. * <strong>Admin permissions required.</strong> * @summary Delete a representation. * * @param globalId cloud id of the record which all the representations will be deleted (required) * @param schema name of the representation to be deleted (required) * @throws RepresentationNotExistsException * Representation does not exist. */ @DELETE @PreAuthorize("hasRole('ROLE_ADMIN')") public void deleteRepresentation(@PathParam(P_CLOUDID) String globalId, @PathParam(P_REPRESENTATIONNAME) String schema) throws RepresentationNotExistsException { recordService.deleteRepresentation(globalId, schema); } /** * Creates a new representation version. Url of the created representation version * will be returned in response. * * <strong>User permissions required.</strong> * * @summary Creates a new representation version. * * @param globalId cloud id of the record in which the new representation will be created (required). * @param schema name of the representation to be created (required). * @param providerId * provider id of this representation version. * @return The url of the created representation. * @throws RecordNotExistsException * provided id is not known to Unique Identifier Service. * @throws ProviderNotExistsException * no provider with given id exists * @statuscode 201 object has been created. */ @POST @Consumes(MediaType.APPLICATION_FORM_URLENCODED) @PreAuthorize("isAuthenticated()") public Response createRepresentation(@Context UriInfo uriInfo, @PathParam(P_CLOUDID) String globalId, @PathParam(P_REPRESENTATIONNAME) String schema, @FormParam(F_PROVIDER) String providerId) throws RecordNotExistsException, ProviderNotExistsException { ParamUtil.require(F_PROVIDER, providerId); Representation version = recordService.createRepresentation(globalId, schema, providerId); EnrichUriUtil.enrich(uriInfo, version); String creatorName = SpringUserUtils.getUsername(); if (creatorName != null) { ObjectIdentity versionIdentity = new ObjectIdentityImpl( REPRESENTATION_CLASS_NAME, globalId + "/" + schema + "/" + version.getVersion()); MutableAcl versionAcl = mutableAclService .createAcl(versionIdentity); versionAcl.insertAce(0, BasePermission.READ, new PrincipalSid( creatorName), true); versionAcl.insertAce(1, BasePermission.WRITE, new PrincipalSid( creatorName), true); versionAcl.insertAce(2, BasePermission.DELETE, new PrincipalSid( creatorName), true); versionAcl.insertAce(3, BasePermission.ADMINISTRATION, new PrincipalSid(creatorName), true); mutableAclService.updateAcl(versionAcl); } return Response.created(version.getUri()).build(); } private void prepare(UriInfo uriInfo, Representation representation) { EnrichUriUtil.enrich(uriInfo, representation); } }