diff --git a/src/main/java/org/genesys/catalog/api/v0/LanguagesController.java b/src/main/java/org/genesys/catalog/api/v0/LanguagesController.java new file mode 100644 index 0000000000000000000000000000000000000000..b5023930b1b3176d371c4c3920127135df1b195f --- /dev/null +++ b/src/main/java/org/genesys/catalog/api/v0/LanguagesController.java @@ -0,0 +1,104 @@ +/* + * Copyright 2018 Global Crop Diversity Trust + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.genesys.catalog.api.v0; + +import java.io.IOException; +import java.util.Collections; +import java.util.List; +import java.util.UUID; + +import org.genesys.catalog.model.vocab.VocabularyTerm; +import org.genesys.catalog.service.VocabularyService; +import org.genesys.catalog.service.worker.ISO639VocabularyUpdater; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.MediaType; +import org.springframework.security.access.prepost.PreAuthorize; +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.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; + +/** + * The Class LanguagesController. + * + * @author Maxym Borodenko + */ +@RestController +@RequestMapping(LanguagesController.API_BASE) +@PreAuthorize("isAuthenticated()") +public class LanguagesController { + + /** The Constant API_BASE. */ + protected static final String API_BASE = "/api/v0/lang"; + + /** The Constant ISO639_3. */ + public static final UUID ISO639_3 = ISO639VocabularyUpdater.ISO639_3; + + private static final Logger LOG = LoggerFactory.getLogger(LanguagesController.class); + + @Autowired + private ISO639VocabularyUpdater iso639VocabularyUpdater; + + @Autowired + private VocabularyService vocabularyService; + + /** + * Update languages. + * + * @return the string + * @throws IOException Signals that an I/O exception has occurred. + */ + @PreAuthorize("hasRole('ADMINISTRATOR')") + @PostMapping(value = "/update") + public @ResponseBody String updateLanguages() throws IOException { + LOG.info("Updating ISO language codes"); + vocabularyService.autoUpdateOrCreateVocabulary(ISO639_3, iso639VocabularyUpdater.getISO639Vocabulary()); + return "OK"; + } + + /** + * Gets the. + * + * @param code the code + * @return the vocabulary term + */ + @GetMapping(value = "/{code}", produces = MediaType.APPLICATION_JSON_VALUE) + public VocabularyTerm get(@PathVariable("code") final String code) { + return vocabularyService.getVocabularyTerm(ISO639_3, code); + } + + /** + * Autocomplete. + * + * @param text the text + * @return the list + * @throws IOException Signals that an I/O exception has occurred. + */ + @GetMapping(value = "/autocomplete", produces = MediaType.APPLICATION_JSON_VALUE) + public List autocomplete(@RequestParam("l") final String text) throws IOException { + if (text.length() < 3) { + return Collections.emptyList(); + } + + return vocabularyService.autocompleteTerms(ISO639_3, text); + } + +} diff --git a/src/main/java/org/genesys/catalog/api/v0/WiewsController.java b/src/main/java/org/genesys/catalog/api/v0/WiewsController.java new file mode 100644 index 0000000000000000000000000000000000000000..d24c679379375146ba3207c1a47cfb6cb9db8df1 --- /dev/null +++ b/src/main/java/org/genesys/catalog/api/v0/WiewsController.java @@ -0,0 +1,106 @@ +/* + * Copyright 2018 Global Crop Diversity Trust + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.genesys.catalog.api.v0; + +import java.io.IOException; +import java.util.Collections; +import java.util.List; +import java.util.UUID; + +import org.genesys.catalog.model.vocab.VocabularyTerm; +import org.genesys.catalog.service.VocabularyService; +import org.genesys.catalog.service.worker.WiewsVocabularyUpdater; +import org.genesys2.server.model.impl.FaoInstitute; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.MediaType; +import org.springframework.security.access.prepost.PreAuthorize; +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.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; + +/** + * The Class WiewsController. + * + * TODO Use {@link FaoInstitute} here? + * + * @author Maxym Borodenko + */ +@RestController("wiewsApi0") +@RequestMapping(WiewsController.API_BASE) +@PreAuthorize("isAuthenticated()") +public class WiewsController { + + /** The Constant API_BASE. */ + public static final String API_BASE = "/api/v0/wiews"; + + /** The Constant FAO_WIEWS_UUID. */ + public static final UUID FAO_WIEWS_UUID = WiewsVocabularyUpdater.FAO_WIEWS_UUID; + + private static final Logger LOG = LoggerFactory.getLogger(WiewsController.class); + + @Autowired + private VocabularyService vocabularyService; + + @Autowired + private WiewsVocabularyUpdater wiewsVocabularyUpdater; + + /** + * Update languages. + * + * @return the string + * @throws IOException Signals that an I/O exception has occurred. + */ + @PreAuthorize("hasRole('ADMINISTRATOR')") + @PostMapping(value = "/update") + public @ResponseBody String updateLanguages() throws IOException { + LOG.info("Updating FAO WIEWS codes"); + vocabularyService.autoUpdateOrCreateVocabulary(FAO_WIEWS_UUID, wiewsVocabularyUpdater.getWiewsVocabulary()); + return "OK"; + } + + /** + * Gets the. + * + * @param code the code + * @return the vocabulary term + */ + @GetMapping(value = "/{code}", produces = MediaType.APPLICATION_JSON_VALUE) + public VocabularyTerm get(@PathVariable("code") final String code) { + return vocabularyService.getVocabularyTerm(FAO_WIEWS_UUID, code); + } + + /** + * Autocomplete. + * + * @param text the text + * @return the list + * @throws IOException Signals that an I/O exception has occurred. + */ + @GetMapping(value = "/autocomplete", produces = MediaType.APPLICATION_JSON_VALUE) + public List autocomplete(@RequestParam("term") final String text) throws IOException { + if (text.length() < 3) { + return Collections.emptyList(); + } + + return vocabularyService.autocompleteTerms(FAO_WIEWS_UUID, text); + } +} diff --git a/src/main/java/org/genesys2/server/api/ApiBaseController.java b/src/main/java/org/genesys2/server/api/ApiBaseController.java new file mode 100644 index 0000000000000000000000000000000000000000..393d7a664a29c5e13c86842f4743bfef1ed16908 --- /dev/null +++ b/src/main/java/org/genesys2/server/api/ApiBaseController.java @@ -0,0 +1,39 @@ +/** + * Copyright 2014 Global Crop Diversity Trust + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +package org.genesys2.server.api; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; + +/// Base class for API controllers +public abstract class ApiBaseController { + protected final Logger LOG = LoggerFactory.getLogger(getClass()); + + protected static final ApiResult JSON_OK = new ApiResult(true); + + @Value("${paginator.api.maxPageSize}") + protected int maxPageSize; + + public ApiBaseController() { + super(); + } + + public void setMaxPageSize(int maxPageSize) { + this.maxPageSize = maxPageSize; + } +} diff --git a/src/main/java/org/genesys2/server/api/ApiResult.java b/src/main/java/org/genesys2/server/api/ApiResult.java new file mode 100644 index 0000000000000000000000000000000000000000..8d7e9034aa6e022aed31143e2b5282d4b1625c29 --- /dev/null +++ b/src/main/java/org/genesys2/server/api/ApiResult.java @@ -0,0 +1,27 @@ +/* + * Copyright 2018 Global Crop Diversity Trust + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.genesys2.server.api; + +/** + * Used sometimes + */ +public class ApiResult { + public boolean result = false; + + public ApiResult(boolean b) { + result = b; + } +} diff --git a/src/main/java/org/genesys2/server/api/RestController.java b/src/main/java/org/genesys2/server/api/RestController.java deleted file mode 100644 index 6536d847b89909c4caa8c5021c37f3f0fab4e6e0..0000000000000000000000000000000000000000 --- a/src/main/java/org/genesys2/server/api/RestController.java +++ /dev/null @@ -1,108 +0,0 @@ -/** - * Copyright 2014 Global Crop Diversity Trust - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - **/ - -package org.genesys2.server.api; - -import java.io.IOException; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.genesys2.server.exception.NotFoundElement; -import org.genesys2.server.service.impl.RESTApiException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.http.HttpStatus; -import org.springframework.security.access.AccessDeniedException; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.security.core.userdetails.UserDetails; -import org.springframework.web.HttpRequestMethodNotSupportedException; -import org.springframework.web.bind.annotation.ExceptionHandler; -import org.springframework.web.bind.annotation.ResponseBody; -import org.springframework.web.bind.annotation.ResponseStatus; - -public abstract class RestController { - protected final Logger LOG = LoggerFactory.getLogger(getClass()); - - protected static final ApiResult JSON_OK = new ApiResult(true); - - @Value("${paginator.api.maxPageSize}") - protected int maxPageSize; - - public static class ApiResult { - public boolean result = false; - - public ApiResult(boolean b) { - result=b; - } - } - - public RestController() { - super(); - } - - public void setMaxPageSize(int maxPageSize) { - this.maxPageSize = maxPageSize; - } - - @ExceptionHandler(Exception.class) - @ResponseBody - public ExceptionJson handleIOException(Exception ex, HttpServletRequest request, HttpServletResponse response) throws IOException { - LOG.error(ex.getMessage(), ex); - response.setStatus(400); // ? - return new ExceptionJson(ex); - } - - @ExceptionHandler(AccessDeniedException.class) - @ResponseBody - public ExceptionJson handleAccessDeniedException(Exception ex, HttpServletRequest request, HttpServletResponse response) throws IOException { - final Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); - LOG.warn("{} {} for {}", request.getRequestURI(), ex.getMessage(), (authentication != null ? ((UserDetails) authentication.getPrincipal()).getUsername() : "null")); - response.setStatus(404); // ? - return new ExceptionJson(ex); - } - - @ExceptionHandler(HttpRequestMethodNotSupportedException.class) - @ResponseBody - public ExceptionJson handleHttpRequestMethodNotSupportedException(Exception ex, HttpServletRequest request, HttpServletResponse response) - throws IOException { - final Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); - LOG.warn("{} {} for {}", request.getRequestURI(), ex.getMessage(), (authentication != null ? ((UserDetails) authentication.getPrincipal()).getUsername() : "null")); - response.setStatus(400); // ? - return new ExceptionJson(ex); - } - - @ExceptionHandler(RESTApiException.class) - @ResponseBody - public ExceptionJson handleRESTApiException(Exception ex, HttpServletRequest request, HttpServletResponse response) { - final Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); - LOG.warn("{} {} for {}", request.getRequestURI(), ex.getMessage(), (authentication != null ? ((UserDetails) authentication.getPrincipal()).getUsername() : "null")); - response.setStatus(400); // ? - return new ExceptionJson(ex); - } - - @ResponseStatus(code = HttpStatus.NOT_FOUND) - @ExceptionHandler(NotFoundElement.class) - @ResponseBody - public ExceptionJson handleNotFound(final Exception e, final HttpServletRequest request) { - final Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); - LOG.warn("{} {} for {}", request.getRequestURI(), e.getMessage(), (authentication != null ? ((UserDetails) authentication.getPrincipal()).getUsername() : "null")); - return new ExceptionJson(e); - } - -} diff --git a/src/main/java/org/genesys2/server/api/v0/AccessionController.java b/src/main/java/org/genesys2/server/api/v0/AccessionController.java index c7b732226217f9801e26a9f981355da9734afe91..19c13ad2a68befd5b031c85b4c4fc82365258742 100644 --- a/src/main/java/org/genesys2/server/api/v0/AccessionController.java +++ b/src/main/java/org/genesys2/server/api/v0/AccessionController.java @@ -26,8 +26,8 @@ import javax.persistence.RollbackException; import org.apache.commons.lang3.RandomUtils; import org.apache.commons.lang3.StringUtils; +import org.genesys2.server.api.ApiBaseController; import org.genesys2.server.api.PleaseRetryException; -import org.genesys2.server.api.RestController; import org.genesys2.server.api.model.AccessionHeaderJson; import org.genesys2.server.exception.InvalidApiUsageException; import org.genesys2.server.model.elastic.AccessionDetails; @@ -59,7 +59,6 @@ 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.stereotype.Controller; import org.springframework.transaction.TransactionException; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; @@ -68,6 +67,7 @@ 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.ResponseBody; +import org.springframework.web.bind.annotation.RestController; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonNode; @@ -75,10 +75,10 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.ObjectNode; -@Controller("restAccessionController") +@RestController("accessionApi0") @PreAuthorize("isAuthenticated()") @RequestMapping(value = { "/api/v0/acn", "/json/v0/acn" }) -public class AccessionController extends RestController { +public class AccessionController extends ApiBaseController { private static final int UPLOAD_RETRIES = 10; private final ObjectMapper mapper = new ObjectMapper(); diff --git a/src/main/java/org/genesys2/server/api/v0/CacheController.java b/src/main/java/org/genesys2/server/api/v0/CacheController.java index 4a47b303c76c82873fd52a69d3bda062ba78f122..0e4cb8cdaae4f9099018c432a1191845d036ae75 100644 --- a/src/main/java/org/genesys2/server/api/v0/CacheController.java +++ b/src/main/java/org/genesys2/server/api/v0/CacheController.java @@ -21,7 +21,7 @@ import java.util.HashMap; import java.util.List; import java.util.Set; -import org.genesys2.server.api.RestController; +import org.genesys2.server.api.ApiBaseController; import org.genesys2.server.service.MappingService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cache.Cache; @@ -42,7 +42,7 @@ import com.hazelcast.monitor.LocalMapStats; @Controller("restCacheController") @PreAuthorize("isAuthenticated()") @RequestMapping(value = { "/api/v0/cache", "/json/v0/cache" }) -public class CacheController extends RestController { +public class CacheController extends ApiBaseController { @Autowired private MappingService mappingService; diff --git a/src/main/java/org/genesys2/server/api/v0/CropsController.java b/src/main/java/org/genesys2/server/api/v0/CropsController.java index 471b50401a87ded1fc7f4061cb63f1a77fa7006a..8f6ed96eb2fdafde46260c97c768701cd377a276 100644 --- a/src/main/java/org/genesys2/server/api/v0/CropsController.java +++ b/src/main/java/org/genesys2/server/api/v0/CropsController.java @@ -20,9 +20,10 @@ import java.util.List; import javax.xml.bind.ValidationException; +import org.genesys2.server.api.ApiBaseController; +import org.genesys2.server.api.ApiResult; import org.genesys2.server.api.ModelValidationException; import org.genesys2.server.api.OAuth2Cleanup; -import org.genesys2.server.api.RestController; import org.genesys2.server.exception.AuthorizationException; import org.genesys2.server.model.genesys.Parameter; import org.genesys2.server.model.impl.Crop; @@ -38,20 +39,20 @@ import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.http.MediaType; import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.PathVariable; 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.ResponseBody; +import org.springframework.web.bind.annotation.RestController; import net.sf.oval.ConstraintViolation; import net.sf.oval.Validator; -@Controller +@RestController("cropApi0") @PreAuthorize("isAuthenticated()") @RequestMapping(value = { "/api/v0/crops", "/json/v0/crops" }) -public class CropsController extends RestController { +public class CropsController extends ApiBaseController { @Autowired GenesysService genesysService; diff --git a/src/main/java/org/genesys2/server/api/v0/DatasetController.java b/src/main/java/org/genesys2/server/api/v0/DatasetController.java index f5584fcec3cfd29bb379ee39f1b43162be6144b5..36951e95b1e4d8f07ed255224f85b6bc1cb5e520 100644 --- a/src/main/java/org/genesys2/server/api/v0/DatasetController.java +++ b/src/main/java/org/genesys2/server/api/v0/DatasetController.java @@ -27,16 +27,9 @@ import java.util.Map.Entry; import javax.xml.bind.ValidationException; -import net.sf.oval.ConstraintViolation; -import net.sf.oval.Validator; -import net.sf.oval.constraint.MaxLength; -import net.sf.oval.constraint.MinLength; -import net.sf.oval.constraint.NotBlank; -import net.sf.oval.constraint.NotNull; - +import org.genesys2.server.api.ApiBaseController; import org.genesys2.server.api.ModelValidationException; import org.genesys2.server.api.OAuth2Cleanup; -import org.genesys2.server.api.RestController; import org.genesys2.server.exception.AuthorizationException; import org.genesys2.server.model.genesys.Accession; import org.genesys2.server.model.genesys.Metadata; @@ -54,20 +47,26 @@ import org.genesys2.spring.ResourceNotFoundException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.MediaType; import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.PathVariable; 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.ResponseBody; +import org.springframework.web.bind.annotation.RestController; import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -@Controller("restDatasetController") +import net.sf.oval.ConstraintViolation; +import net.sf.oval.Validator; +import net.sf.oval.constraint.MaxLength; +import net.sf.oval.constraint.MinLength; +import net.sf.oval.constraint.NotBlank; +import net.sf.oval.constraint.NotNull; + +@RestController("datasetApi0") @PreAuthorize("isAuthenticated()") @RequestMapping(value = { "/api/v0/datasets", "/json/v0/datasets" }) -public class DatasetController extends RestController { +public class DatasetController extends ApiBaseController { @Autowired DatasetService datasetService; diff --git a/src/main/java/org/genesys2/server/api/v0/GeoController.java b/src/main/java/org/genesys2/server/api/v0/GeoRegionController.java similarity index 94% rename from src/main/java/org/genesys2/server/api/v0/GeoController.java rename to src/main/java/org/genesys2/server/api/v0/GeoRegionController.java index f35d3d3cd5faa8242b8055227c666b3acbe63b38..121a967d0858699ce766f0c27bc9ddcccd2d790c 100644 --- a/src/main/java/org/genesys2/server/api/v0/GeoController.java +++ b/src/main/java/org/genesys2/server/api/v0/GeoRegionController.java @@ -3,7 +3,7 @@ package org.genesys2.server.api.v0; import java.util.ArrayList; import java.util.List; -import org.genesys2.server.api.RestController; +import org.genesys2.server.api.ApiBaseController; import org.genesys2.server.api.model.GeoJsData; import org.genesys2.server.model.impl.GeoRegion; import org.genesys2.server.persistence.CountryRepository; @@ -12,16 +12,16 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.MessageSource; import org.springframework.context.i18n.LocaleContextHolder; import org.springframework.http.MediaType; -import org.springframework.stereotype.Controller; 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.ResponseBody; +import org.springframework.web.bind.annotation.RestController; -@Controller +@RestController("geoRegionApi0") @RequestMapping(value = {"/api/v0/geo/regions", "/json/v0/geo/regions"}) -public class GeoController extends RestController { +public class GeoRegionController extends ApiBaseController { @Autowired GeoRegionService geoRegionService; diff --git a/src/main/java/org/genesys2/server/api/v0/InstituteGalleriesController.java b/src/main/java/org/genesys2/server/api/v0/InstituteGalleriesController.java index 76d21db965d2dd326294a46d2b56ba2af6c00436..da5b5e2d6700cd9c8abca9ea69de47c6010cc6be 100644 --- a/src/main/java/org/genesys2/server/api/v0/InstituteGalleriesController.java +++ b/src/main/java/org/genesys2/server/api/v0/InstituteGalleriesController.java @@ -29,7 +29,7 @@ import org.genesys.filerepository.InvalidRepositoryPathException; import org.genesys.filerepository.NoSuchRepositoryFileException; import org.genesys.filerepository.model.ImageGallery; import org.genesys.filerepository.model.RepositoryImage; -import org.genesys2.server.api.RestController; +import org.genesys2.server.api.ApiBaseController; import org.genesys2.server.model.genesys.Accession; import org.genesys2.server.model.impl.FaoInstitute; import org.genesys2.server.service.GenesysService; @@ -59,7 +59,7 @@ import org.springframework.web.bind.annotation.ResponseBody; @Controller @PreAuthorize("isAuthenticated()") @RequestMapping(value = { InstituteGalleriesController.CONTROLLER_URL }) -public class InstituteGalleriesController extends RestController { +public class InstituteGalleriesController extends ApiBaseController { public static final Logger LOG = LoggerFactory.getLogger(InstituteGalleriesController.class); diff --git a/src/main/java/org/genesys2/server/api/v0/KPIController.java b/src/main/java/org/genesys2/server/api/v0/KPIController.java index 4c46c328e547f110ddca447d05c95067634774d0..3679e4820015fb5c99dd16435fc9ff6033ba0c44 100644 --- a/src/main/java/org/genesys2/server/api/v0/KPIController.java +++ b/src/main/java/org/genesys2/server/api/v0/KPIController.java @@ -27,7 +27,7 @@ import net.sf.oval.ConstraintViolation; import net.sf.oval.Validator; import org.genesys2.server.api.ModelValidationException; -import org.genesys2.server.api.RestController; +import org.genesys2.server.api.ApiBaseController; import org.genesys2.server.api.model.ExecutionDimensionJson; import org.genesys2.server.api.model.ExecutionJson; import org.genesys2.server.exception.AuthorizationException; @@ -53,7 +53,7 @@ import org.springframework.web.bind.annotation.ResponseBody; @Controller @PreAuthorize("isAuthenticated()") @RequestMapping(value = { "/api/v0/kpi", "/json/v0/kpi" }) -public class KPIController extends RestController { +public class KPIController extends ApiBaseController { @Autowired private KPIService kpiService; diff --git a/src/main/java/org/genesys2/server/api/v0/LookupController.java b/src/main/java/org/genesys2/server/api/v0/LookupController.java index 38795eb17898c8feb8a70035ec2c2325adf4dc32..7889ef7f142e8e34c69d9ff37606ac44eb24f451 100644 --- a/src/main/java/org/genesys2/server/api/v0/LookupController.java +++ b/src/main/java/org/genesys2/server/api/v0/LookupController.java @@ -22,7 +22,7 @@ import java.util.Map; import java.util.TreeMap; import org.apache.commons.lang3.StringUtils; -import org.genesys2.server.api.RestController; +import org.genesys2.server.api.ApiBaseController; import org.genesys2.server.model.impl.Country; import org.genesys2.server.service.GenesysService; import org.genesys2.server.service.GeoService; @@ -40,7 +40,7 @@ import org.springframework.web.bind.annotation.ResponseBody; @Controller @PreAuthorize("isAuthenticated()") @RequestMapping(value = { "/api/v0/lookup", "/json/v0/lookup" }) -public class LookupController extends RestController { +public class LookupController extends ApiBaseController { @Autowired GenesysService genesysService; diff --git a/src/main/java/org/genesys2/server/api/v0/OrganizationController.java b/src/main/java/org/genesys2/server/api/v0/OrganizationController.java index eebf5eb68fd76d215ebf1ac025ac25d3d6669f40..fe8b6b191ecc856be35cfcb3a68c33552d05970c 100644 --- a/src/main/java/org/genesys2/server/api/v0/OrganizationController.java +++ b/src/main/java/org/genesys2/server/api/v0/OrganizationController.java @@ -27,7 +27,7 @@ import javax.xml.bind.ValidationException; import com.fasterxml.jackson.core.JsonProcessingException; import org.genesys2.server.api.ModelValidationException; -import org.genesys2.server.api.RestController; +import org.genesys2.server.api.ApiBaseController; import org.genesys2.server.exception.AuthorizationException; import org.genesys2.server.model.impl.Article; import org.genesys2.server.model.impl.FaoInstitute; @@ -53,7 +53,7 @@ import net.sf.oval.Validator; @Controller("restOrganizationController") @PreAuthorize("isAuthenticated()") @RequestMapping(value = { "/api/v0/org", "/json/v0/org" }) -public class OrganizationController extends RestController { +public class OrganizationController extends ApiBaseController { @Autowired private OrganizationService organizationService; diff --git a/src/main/java/org/genesys2/server/api/v0/PermissionController.java b/src/main/java/org/genesys2/server/api/v0/PermissionController.java index 89c42909aea41eb5292c6c854a27e1406d518b3f..166b77a9e31d99b56168103400c38b4989461389 100644 --- a/src/main/java/org/genesys2/server/api/v0/PermissionController.java +++ b/src/main/java/org/genesys2/server/api/v0/PermissionController.java @@ -24,7 +24,7 @@ import org.genesys.blocks.oauth.service.OAuthClientDetailsService; import org.genesys.blocks.security.model.AclObjectIdentity; import org.genesys.blocks.security.model.AclSid; import org.genesys.blocks.security.service.CustomAclService; -import org.genesys2.server.api.RestController; +import org.genesys2.server.api.ApiBaseController; import org.genesys2.server.model.impl.User; import org.genesys2.server.service.UserService; import org.genesys2.server.servlet.model.PermissionJson; @@ -41,7 +41,7 @@ import org.springframework.web.bind.annotation.ResponseBody; @Controller @PreAuthorize("isAuthenticated()") @RequestMapping(value = { "/api/v0/permission", "/json/v0/permission" }) -public class PermissionController extends RestController { +public class PermissionController extends ApiBaseController { @Autowired protected CustomAclService aclService; diff --git a/src/main/java/org/genesys2/server/api/v0/RequestsController.java b/src/main/java/org/genesys2/server/api/v0/RequestsController.java index 14a2fd02bdfb11833eb570892de3236f8f7eac80..e786223303fe6472c8d022eacc1e053a9b52920d 100644 --- a/src/main/java/org/genesys2/server/api/v0/RequestsController.java +++ b/src/main/java/org/genesys2/server/api/v0/RequestsController.java @@ -16,7 +16,7 @@ package org.genesys2.server.api.v0; -import org.genesys2.server.api.RestController; +import org.genesys2.server.api.ApiBaseController; import org.genesys2.server.model.genesys.MaterialRequest; import org.genesys2.server.model.genesys.MaterialSubRequest; import org.genesys2.server.model.impl.FaoInstitute; @@ -41,7 +41,7 @@ import org.springframework.web.bind.annotation.ResponseBody; @Controller @PreAuthorize("isAuthenticated()") @RequestMapping(value = { "/api/v0" }) -public class RequestsController extends RestController { +public class RequestsController extends ApiBaseController { private static final int PAGE_SIZE = 10; diff --git a/src/main/java/org/genesys2/server/api/v0/TraitsController.java b/src/main/java/org/genesys2/server/api/v0/TraitsController.java index 258ee9532dbafb4ce9f817a241bd1a83530777af..c77a1d645b7f3d21071395344c3231d49e53feb1 100644 --- a/src/main/java/org/genesys2/server/api/v0/TraitsController.java +++ b/src/main/java/org/genesys2/server/api/v0/TraitsController.java @@ -29,7 +29,7 @@ import net.sf.oval.constraint.NotNull; import org.genesys2.server.api.ModelValidationException; import org.genesys2.server.api.OAuth2Cleanup; -import org.genesys2.server.api.RestController; +import org.genesys2.server.api.ApiBaseController; import org.genesys2.server.exception.AuthorizationException; import org.genesys2.server.model.genesys.Method; import org.genesys2.server.model.genesys.Parameter; @@ -53,7 +53,7 @@ import org.springframework.web.bind.annotation.ResponseBody; @Controller @PreAuthorize("isAuthenticated()") @RequestMapping(value = { "/api/v0", "/json/v0" }) -public class TraitsController extends RestController { +public class TraitsController extends ApiBaseController { @Autowired GenesysService genesysService; diff --git a/src/main/java/org/genesys2/server/api/v0/UserController.java b/src/main/java/org/genesys2/server/api/v0/UserController.java index 40624f496a625b5866b6dbbde2a0bb54d4ab0cc8..7c4af2759d31aaa20528b44b36034ce61af4e716 100644 --- a/src/main/java/org/genesys2/server/api/v0/UserController.java +++ b/src/main/java/org/genesys2/server/api/v0/UserController.java @@ -18,17 +18,11 @@ package org.genesys2.server.api.v0; import java.util.List; -import net.sf.oval.ConstraintViolation; -import net.sf.oval.Validator; -import net.sf.oval.constraint.MinLength; -import net.sf.oval.constraint.NotBlank; -import net.sf.oval.constraint.NotNull; - import org.genesys.blocks.security.NoUserFoundException; import org.genesys2.server.ServiceEndpoints; +import org.genesys2.server.api.ApiBaseController; import org.genesys2.server.api.ModelValidationException; import org.genesys2.server.api.OAuth2Cleanup; -import org.genesys2.server.api.RestController; import org.genesys2.server.exception.AuthorizationException; import org.genesys2.server.model.impl.User; import org.genesys2.server.service.InstituteService; @@ -38,17 +32,27 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Sort; import org.springframework.http.MediaType; import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.stereotype.Controller; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationDetails; +import org.springframework.security.oauth2.provider.token.ConsumerTokenServices; import org.springframework.web.bind.annotation.PathVariable; 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.ResponseBody; +import org.springframework.web.bind.annotation.RestController; + +import net.sf.oval.ConstraintViolation; +import net.sf.oval.Validator; +import net.sf.oval.constraint.MinLength; +import net.sf.oval.constraint.NotBlank; +import net.sf.oval.constraint.NotNull; -@Controller +@RestController("meApi0") @PreAuthorize("isAuthenticated()") @RequestMapping(value = { "/api/v0", "/json/v0" }) -public class UserController extends RestController { +public class UserController extends ApiBaseController { @Autowired protected UserService userService; @@ -59,6 +63,36 @@ public class UserController extends RestController { @Autowired protected InstituteService instituteService; + @Autowired(required = false) + private ConsumerTokenServices tokenServices; + + /** + * Delete provided token + * + * TODO Get current token from security context! + * @param token -- current access token + * @return the object + */ + @RequestMapping("/me/logout") + public Object logout() { + final Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + + Object authDetails = authentication.getDetails(); + if (authDetails instanceof OAuth2AuthenticationDetails) { + OAuth2AuthenticationDetails oauthDetails = (OAuth2AuthenticationDetails) authDetails; + String token = oauthDetails.getTokenValue(); + if (tokenServices != null) { + tokenServices.revokeToken(token); + } else { + LOG.info("ConsumerTokenServices not available"); + } + SecurityContextHolder.getContext().setAuthentication(null); + return token; + } else { + throw new RuntimeException("Not OAuth2 authenticated"); + } + } + /** * Returns logged in user's profile * @@ -71,7 +105,7 @@ public class UserController extends RestController { final User user = userService.getMe(); return OAuth2Cleanup.clean(user); } - + @RequestMapping(value = "/me/institutes", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) public @ResponseBody Object listInstitutes() { diff --git a/src/main/java/org/genesys2/server/api/v0/UsersController.java b/src/main/java/org/genesys2/server/api/v0/UsersController.java index 22e364f1d6407b6ff5bf52f9da4163dea05d0455..a7e3ddaf75ca5654e2a1d27bb010f371b59cf91b 100644 --- a/src/main/java/org/genesys2/server/api/v0/UsersController.java +++ b/src/main/java/org/genesys2/server/api/v0/UsersController.java @@ -23,7 +23,8 @@ import org.apache.commons.lang3.StringUtils; import org.genesys.blocks.security.NotUniqueUserException; import org.genesys.blocks.security.UserException; import org.genesys.blocks.security.service.PasswordPolicy.PasswordPolicyException; -import org.genesys2.server.api.RestController; +import org.genesys2.server.api.ApiBaseController; +import org.genesys2.server.api.ApiResult; import org.genesys2.server.api.model.UserChangedDataJson; import org.genesys2.server.model.impl.User; import org.genesys2.server.service.EMailVerificationService; @@ -35,19 +36,19 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.http.MediaType; import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.PathVariable; 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.ResponseBody; +import org.springframework.web.bind.annotation.RestController; -@Controller("restUsersController") +@RestController("userApi0") @PreAuthorize("isAuthenticated() && hasRole('ADMINISTRATOR')") @RequestMapping(value = {"/api/v0/users", "/json/v0/users"}) -public class UsersController extends RestController { +public class UsersController extends ApiBaseController { @Value("${base.url}") private String baseUrl; diff --git a/src/main/java/org/genesys2/server/api/v1/PermissionController.java b/src/main/java/org/genesys2/server/api/v1/PermissionController.java index 714087d748d144e6666ecaf92a4c803d98217189..9b0c96c1ee537f60e929739708df0f7229d40688 100644 --- a/src/main/java/org/genesys2/server/api/v1/PermissionController.java +++ b/src/main/java/org/genesys2/server/api/v1/PermissionController.java @@ -52,7 +52,7 @@ import com.fasterxml.jackson.annotation.JsonView; * @author Andrey Lugovskoy * @author Matija Obreza */ -@RestController("permissionControllerV1") +@RestController("permissionApi1") @RequestMapping(value = { "/api/v1/permission" }) public class PermissionController { diff --git a/src/main/java/org/genesys2/server/api/v1/SubsetRestController.java b/src/main/java/org/genesys2/server/api/v1/SubsetRestController.java index d59bc3bb10ca957f93c9d58191d1522da64d2481..21248a8f4dca94e2a3b5e720bb030879715c6294 100644 --- a/src/main/java/org/genesys2/server/api/v1/SubsetRestController.java +++ b/src/main/java/org/genesys2/server/api/v1/SubsetRestController.java @@ -19,7 +19,6 @@ package org.genesys2.server.api.v1; import java.util.Set; import java.util.UUID; -import org.genesys2.server.api.RestController; import org.genesys2.server.model.impl.Subset; import org.genesys2.server.service.SubsetService; import org.genesys2.server.service.filter.SubsetFilter; @@ -36,6 +35,7 @@ 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.RequestParam; +import org.springframework.web.bind.annotation.RestController; import io.swagger.annotations.Api; @@ -44,11 +44,11 @@ import io.swagger.annotations.Api; * * @author Maxym Borodenko */ -@org.springframework.web.bind.annotation.RestController +@RestController("subsetApi1") @PreAuthorize("isAuthenticated()") @RequestMapping(SubsetRestController.API_BASE) @Api(tags = { "subset" }) -public class SubsetRestController extends RestController { +public class SubsetRestController { /** The Constant API_BASE. */ public static final String API_BASE = "/api/v1/subset"; diff --git a/src/main/java/org/genesys2/spring/config/OAuth2ServerConfig.java b/src/main/java/org/genesys2/spring/config/OAuth2ServerConfig.java index 7f35731436a7b0733fa2acd876d213f8eb6b6e53..d93f11331559719aa115ccfde3e6ed9b2524b137 100644 --- a/src/main/java/org/genesys2/spring/config/OAuth2ServerConfig.java +++ b/src/main/java/org/genesys2/spring/config/OAuth2ServerConfig.java @@ -41,7 +41,6 @@ import org.springframework.security.oauth2.provider.ClientDetailsService; import org.springframework.security.oauth2.provider.approval.ApprovalStore; import org.springframework.security.oauth2.provider.approval.TokenApprovalStore; import org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler; -import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices; import org.springframework.security.oauth2.provider.token.DefaultTokenServices; import org.springframework.security.oauth2.provider.token.TokenStore; @@ -108,9 +107,6 @@ public class OAuth2ServerConfig { @Qualifier("userService") private UserDetailsService userDetailsService; - @Autowired - private Stuff stuff; - @Autowired @Qualifier("authenticationManagerBean") private AuthenticationManager authenticationManager; @@ -118,10 +114,23 @@ public class OAuth2ServerConfig { @Autowired @Qualifier("oauthService") private ClientDetailsService clientDetailsService; - + @Autowired public PasswordEncoder passwordEncoder; + @Value("${default.oauth.accessToken.validity}") + private int accessTokenValiditySeconds; + + @Value("${default.oauth.refreshToken.validity}") + private int refreshTokenValiditySeconds; + + @Bean + public ApprovalStore approvalStore() throws Exception { + final TokenApprovalStore store = new TokenApprovalStore(); + store.setTokenStore(tokenStore); + return store; + } + /** * Token services. * @@ -129,8 +138,16 @@ public class OAuth2ServerConfig { */ @Bean @Primary - public AuthorizationServerTokenServices tokenServices() { - return stuff.tokenServices(); + public DefaultTokenServices tokenServices() { + final DefaultTokenServices defaultTokenServices = new DefaultTokenServices(); + defaultTokenServices.setTokenStore(tokenStore); + defaultTokenServices.setSupportRefreshToken(true); + defaultTokenServices.setAuthenticationManager(authenticationManager); + defaultTokenServices.setClientDetailsService(clientDetailsService); + defaultTokenServices.setAccessTokenValiditySeconds(accessTokenValiditySeconds); + defaultTokenServices.setRefreshTokenValiditySeconds(refreshTokenValiditySeconds); + // defaultTokenServices.setTokenEnhancer(tokenEnhancer()); + return defaultTokenServices; } @Override @@ -145,41 +162,9 @@ public class OAuth2ServerConfig { @Override public void configure(final AuthorizationServerSecurityConfigurer oauthServer) throws Exception { - oauthServer.allowFormAuthenticationForClients().checkTokenAccess("permitAll()").realm(APPLICATION_RESOURCE_ID + "/client") - .passwordEncoder(passwordEncoder); // added encoder - } - - } - - @Configuration - protected static class Stuff { - - @Autowired - @Qualifier("oauthService") - private TokenStore tokenStore; - - @Value("${default.oauth.accessToken.validity}") - private int accessTokenValiditySeconds; - - @Value("${default.oauth.refreshToken.validity}") - private int refreshTokenValiditySeconds; - - @Bean - public ApprovalStore approvalStore() throws Exception { - final TokenApprovalStore store = new TokenApprovalStore(); - store.setTokenStore(tokenStore); - return store; + oauthServer.allowFormAuthenticationForClients().checkTokenAccess("permitAll()").realm(APPLICATION_RESOURCE_ID + "/client").passwordEncoder(passwordEncoder); // added + // encoder } - @Bean - @Primary - public AuthorizationServerTokenServices tokenServices() { - final DefaultTokenServices defaultTokenServices = new DefaultTokenServices(); - defaultTokenServices.setTokenStore(tokenStore); - defaultTokenServices.setSupportRefreshToken(true); - defaultTokenServices.setAccessTokenValiditySeconds(accessTokenValiditySeconds); - defaultTokenServices.setRefreshTokenValiditySeconds(refreshTokenValiditySeconds); - return defaultTokenServices; - } } }