Commit 1d4248fb authored by Matija Obreza's avatar Matija Obreza

Merge branch '317-subsets-api-and-acl' into 'master'

Resolve "Subsets API and ACL"

Closes #317

See merge request genesys-pgr/genesys-server!219
parents 424c8e37 1658eedd
......@@ -22,8 +22,6 @@ import java.util.Map;
import java.util.Set;
import java.util.UUID;
import javax.servlet.http.HttpServletRequest;
import org.genesys.blocks.model.JsonViews;
import org.genesys.catalog.api.FilteredPage;
import org.genesys.catalog.model.dataset.Dataset;
......@@ -47,8 +45,14 @@ import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.http.MediaType;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.HandlerMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
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;
import com.fasterxml.jackson.annotation.JsonView;
import com.fasterxml.jackson.core.JsonParseException;
......@@ -111,13 +115,10 @@ public class AccessionController {
* @param uuid the uuid
* @return the subset
*/
@RequestMapping(value = "/10.{dummy:[0-9]+}/**", method = RequestMethod.GET, produces = { MediaType.APPLICATION_JSON_VALUE })
@RequestMapping(value = "/10.{doi1:[0-9]+}/{doi2:.+}", method = RequestMethod.GET, produces = { MediaType.APPLICATION_JSON_VALUE })
@JsonView({ JsonViews.Protected.class })
public Accession getByDoi(HttpServletRequest request) {
final String fullpath = (String) request.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE);
final String doi = fullpath.substring(API_BASE.length() + 1);
return accessionService.getByDoi(doi);
public Accession getByDoi(@PathVariable("doi1") String doi1, @PathVariable("doi2") String doi2) {
return accessionService.getByDoi("10." + doi1 + "/" + doi2);
}
/**
......@@ -172,6 +173,7 @@ public class AccessionController {
/**
* Converts AccessionIdentifiers to UUID
*
* @param identifiers accession identifiers to lookup in DB
* @return map with UUIDs and related AccessionIdentifiers
*/
......@@ -180,18 +182,14 @@ public class AccessionController {
return accessionService.toUUID(identifiers);
}
@RequestMapping(value = "/details/10.{dummy:[0-9]+}/**}", method = RequestMethod.GET, produces = { MediaType.APPLICATION_JSON_VALUE })
@RequestMapping(value = "/details/10.{doi1:[0-9]+}/{doi2:.+}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
@JsonView(JsonViews.Public.class)
public AccessionDetailsJson getAccessionDetailsByDoi(HttpServletRequest request) {
final String fullPath = (String) request.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE);
final String doi = fullPath.substring(API_BASE.length() + 1);
Accession accession = accessionService.getByDoi(doi);
public AccessionDetailsJson getAccessionDetailsByDoi(@PathVariable("doi1") String doi1, @PathVariable("doi2") String doi2) {
Accession accession = accessionService.getByDoi("10." + doi1 + "/" + doi2);
return getAccessionDetails(accession);
}
@GetMapping(value="/details/{UUID}", produces = MediaType.APPLICATION_JSON_VALUE)
@GetMapping(value = "/details/{UUID:\\w{8}\\-\\w{4}.+}", produces = MediaType.APPLICATION_JSON_VALUE)
@JsonView(JsonViews.Public.class)
public AccessionDetailsJson getAccessionDetailsByUUID(@PathVariable("UUID") final UUID uuid) {
Accession accession = accessionService.getByUuid(uuid);
......
......@@ -135,6 +135,33 @@ public class SubsetController {
return new FilteredPage<>(filterCode, filter, subsetService.list(filter, new PageRequest(page, Integer.min(pageSize, 100), direction, sort)));
}
/**
* My subsets.
*
* @param page the page
* @param pageSize the page size
* @param direction the direction
* @param sort the sort
* @param filter the descriptor filter
* @return the page
* @throws IOException
*/
@PostMapping(value = "/list-mine")
public FilteredPage<Subset> mySubsets(@RequestParam(name = "p", required = false, defaultValue = "0") final int page,
@RequestParam(name = "l", required = false, defaultValue = "50") final int pageSize,
@RequestParam(name = "d", required = false, defaultValue = "DESC") final Sort.Direction direction,
@RequestParam(name = "s", required = false, defaultValue = "lastModifiedDate") final String[] sort,
@RequestParam(name = "f", required = false) String filterCode,
@RequestBody(required = false) SubsetFilter filter) throws IOException {
if (filterCode != null) {
filter = shortFilterService.filterByCode(filterCode, SubsetFilter.class);
} else {
filterCode = shortFilterService.getCode(filter);
}
return new FilteredPage<>(filterCode, filter, subsetService.listSubsetsForCurrentUser(filter, new PageRequest(page, Integer.min(pageSize, 100), direction, sort)));
}
/**
* Remove accessions form subset.
*
......
......@@ -32,6 +32,7 @@ import javax.persistence.PrePersist;
import javax.persistence.PreUpdate;
import javax.persistence.Table;
import org.genesys.blocks.model.JsonViews;
import org.genesys.blocks.model.SelfCleaning;
import org.genesys.blocks.model.UuidModel;
import org.genesys.blocks.security.model.AclAwareModel;
......@@ -41,6 +42,7 @@ import org.hibernate.annotations.Type;
import com.fasterxml.jackson.annotation.JsonIdentityReference;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonView;
// TODO: Auto-generated Javadoc
/**
......@@ -82,8 +84,7 @@ public class Subset extends UuidModel implements AclAwareModel, SelfCleaning {
/** The institute. */
@ManyToOne(cascade = {}, optional = false)
@JoinColumn(name = "institute_id", updatable = false)
// @JsonView({ JsonViews.Public.class })
@JsonIgnore
@JsonView({ JsonViews.Public.class })
private FaoInstitute institute;
/** The accessions. */
......
......@@ -40,6 +40,15 @@ public interface SubsetService {
*/
Page<Subset> list(SubsetFilter filter, Pageable page);
/**
* List current user's subsets matching the filter.
*
* @param filter filter data
* @param page Pageable
* @return list of Subset
*/
Page<Subset> listSubsetsForCurrentUser(SubsetFilter filter, Pageable page);
/**
* Method creating Subset.
*
......
......@@ -16,6 +16,7 @@
package org.genesys2.server.service.impl;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.UUID;
......@@ -27,6 +28,7 @@ import org.genesys2.server.model.PublishState;
import org.genesys2.server.model.UserRole;
import org.genesys2.server.model.genesys.AccessionData;
import org.genesys2.server.model.genesys.AccessionId;
import org.genesys2.server.model.impl.FaoInstitute;
import org.genesys2.server.model.impl.QSubset;
import org.genesys2.server.model.impl.Subset;
import org.genesys2.server.persistence.AccessionRepository;
......@@ -35,14 +37,17 @@ import org.genesys2.server.persistence.SubsetRepository;
import org.genesys2.server.security.SecurityUtils;
import org.genesys2.server.service.SubsetService;
import org.genesys2.server.service.filter.SubsetFilter;
import org.genesys2.util.JPAUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.ConcurrencyFailureException;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.security.access.prepost.PostAuthorize;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.acls.domain.BasePermission;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
......@@ -84,11 +89,27 @@ public class SubsetServiceImpl implements SubsetService {
return subsetRepository.findAll(published, page);
}
@Override
@PreAuthorize("hasRole('ADMINISTRATOR') or isAuthenticated()")
public Page<Subset> listSubsetsForCurrentUser(SubsetFilter filter, Pageable page) {
Pageable markdownSortPageRequest = JPAUtils.toMarkdownSort(page, "title");
if (securityUtils.hasRole(UserRole.ADMINISTRATOR)) {
Page<Subset> res = subsetRepository.findAll(filter.buildQuery(), markdownSortPageRequest);
return new PageImpl<>(res.getContent(), page, res.getTotalElements());
} else {
final HashSet<Long> instituteIds = new HashSet<>(securityUtils.listObjectIdentityIdsForCurrentUser(FaoInstitute.class, BasePermission.WRITE));
Page<Subset> res = subsetRepository.findAll(QSubset.subset.institute.id.in(instituteIds).and(filter.buildQuery()), markdownSortPageRequest);
return new PageImpl<>(res.getContent(), page, res.getTotalElements());
}
}
/**
* {@inheritDoc}
*/
@Override
@Transactional
@PreAuthorize("hasRole('ADMINISTRATOR') or hasPermission(#source, 'WRITE')")
public Subset create(final Subset source) {
LOG.info("Create Subset.");
final Subset subset = new Subset();
......@@ -197,6 +218,7 @@ public class SubsetServiceImpl implements SubsetService {
*/
@Override
@Transactional
@PreAuthorize("hasRole('ADMINISTRATOR') or hasPermission(#source, 'WRITE')")
public Subset update(final Subset source) {
LOG.info("Update Subset.");
final Subset subset = loadSubset(source);
......@@ -213,6 +235,7 @@ public class SubsetServiceImpl implements SubsetService {
*/
@Override
@Transactional
@PreAuthorize("hasRole('ADMINISTRATOR') or hasPermission(#subset, 'WRITE')")
public Subset delete(final Subset subset) {
subsetRepository.delete(subset);
subset.setId(null);
......@@ -224,6 +247,7 @@ public class SubsetServiceImpl implements SubsetService {
*/
@Override
@Transactional
@PreAuthorize("hasRole('ADMINISTRATOR') or hasPermission(#input, 'WRITE')")
public Subset removeAccessions(final Subset input, final Set<UUID> accessionsUuids) {
LOG.info("Remove accessions of subset {}.", input);
final Subset subset = loadSubset(input);
......@@ -246,6 +270,7 @@ public class SubsetServiceImpl implements SubsetService {
*/
@Override
@Transactional
@PreAuthorize("hasRole('ADMINISTRATOR') or hasPermission(#input, 'WRITE')")
public Subset addAccessions(final Subset input, final Set<UUID> accessionsUuids) {
LOG.info("Add accessions to Subset. Input accessions {}", input);
final Subset subset = loadSubset(input);
......
......@@ -34,6 +34,7 @@ log4j.category.liquibase=debug
#log4j.category.org.hibernate.cfg.Configuration=debug
#log4j.category.org.hibernate.search=debug
#log4j.category.org.apache.tomcat.jdbc.pool=debug
#log4j.category.org.springframework.web.servlet.mvc=trace
#log4j.category.org.springframework.jdbc.core.JdbcTemplate=debug
#log4j.category.org.springframework.security.oauth2=trace
#log4j.category.org.springframework.security.access=trace
......
......@@ -184,6 +184,7 @@ public class SubsetRestControllerTest extends AbstractApiTest {
storedSubset.getAccessionIds().add(accessionId);
assertThat(storedSubset.getAccessionIds().size(), is(1));
storedSubset.getInstitute().setSettings(null);
final String s = verboseMapper.writeValueAsString(storedSubset);
/*@formatter:off*/
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment