diff --git a/src/main/java/eu/hbp/mip/configuration/SecurityConfiguration.java b/src/main/java/eu/hbp/mip/configuration/SecurityConfiguration.java index e257ac9bd7cff40acb31fbd98f34ab59dc7b9a7d..89f5133a835817f11da8be3f191c4726351bc4aa 100644 --- a/src/main/java/eu/hbp/mip/configuration/SecurityConfiguration.java +++ b/src/main/java/eu/hbp/mip/configuration/SecurityConfiguration.java @@ -4,6 +4,7 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.google.gson.Gson; import eu.hbp.mip.model.User; +import eu.hbp.mip.model.UserInfo; import eu.hbp.mip.repositories.UserRepository; import eu.hbp.mip.utils.CORSFilter; import eu.hbp.mip.utils.CustomLoginUrlAuthenticationEntryPoint; @@ -25,7 +26,6 @@ import org.springframework.http.ResponseEntity; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.core.Authentication; -import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.oauth2.client.OAuth2ClientContext; import org.springframework.security.oauth2.client.OAuth2RestTemplate; import org.springframework.security.oauth2.client.filter.OAuth2ClientAuthenticationProcessingFilter; @@ -33,7 +33,6 @@ import org.springframework.security.oauth2.client.filter.OAuth2ClientContextFilt import org.springframework.security.oauth2.client.resource.OAuth2ProtectedResourceDetails; import org.springframework.security.oauth2.client.token.grant.code.AuthorizationCodeResourceDetails; import org.springframework.security.oauth2.config.annotation.web.configuration.EnableOAuth2Client; -import org.springframework.security.oauth2.provider.OAuth2Authentication; import org.springframework.security.web.access.channel.ChannelProcessingFilter; import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler; import org.springframework.security.web.authentication.logout.LogoutHandler; @@ -79,6 +78,9 @@ public class SecurityConfiguration extends WebSecurityConfigurerAdapter { @Autowired private UserRepository userRepository; + @Autowired + private UserInfo userInfo; + /** * Enable HBP collab authentication (1) or disable it (0). Default is 1 */ @@ -137,7 +139,7 @@ public class SecurityConfiguration extends WebSecurityConfigurerAdapter { http.antMatcher("/**") .authorizeRequests() .antMatchers("/**").permitAll().and().csrf().disable(); - User user = getUser(); + User user = userInfo.getUser(); userRepository.save(user); } } @@ -198,52 +200,12 @@ public class SecurityConfiguration extends WebSecurityConfigurerAdapter { return repository; } - private String getUserInfos() { - OAuth2Authentication oAuth2Authentication = (OAuth2Authentication) SecurityContextHolder.getContext().getAuthentication(); - Authentication userAuthentication = oAuth2Authentication.getUserAuthentication(); - return userAuthentication.getDetails().toString(); - } - - /** - * returns the user for the current session. - * <p> - * the "synchronized" keyword is there to avoid a bug that the transaction is supposed to protect me from. - * To test if your solution to removing it works, do the following: - * - clean DB from scratch - * - restart DB and backend (no session or anything like that) - * - log in using the front end - * - check you have no 500 error in the network logs. - * - * @return the user for the current session - */ - public synchronized User getUser() { - User user; - - if (!authentication) - { - user = new User(); - user.setUsername("anonymous"); - user.setFullname("anonymous"); - user.setPicture("images/users/default_user.png"); - } - else - { - user = new User(getUserInfos()); - } - User foundUser = userRepository.findOne(user.getUsername()); - if (foundUser != null) { - user.setAgreeNDA(foundUser.getAgreeNDA()); - } - userRepository.save(user); - return user; - } - @RequestMapping(path = "/user", method = RequestMethod.GET) public Object user(Principal principal, HttpServletResponse response) { ObjectMapper mapper = new ObjectMapper(); try { - String userJSON = mapper.writeValueAsString(getUser()); + String userJSON = mapper.writeValueAsString(userInfo.getUser()); Cookie cookie = new Cookie("user", URLEncoder.encode(userJSON, "UTF-8")); cookie.setSecure(true); cookie.setPath("/"); @@ -268,7 +230,7 @@ public class SecurityConfiguration extends WebSecurityConfigurerAdapter { @RequestMapping(path = "/user", method = RequestMethod.POST) public ResponseEntity<Void> postUser(@ApiParam(value = "Has the user agreed on the NDA") @RequestParam(value = "agreeNDA") Boolean agreeNDA) { - User user = getUser(); + User user = userInfo.getUser(); if (user != null) { user.setAgreeNDA(agreeNDA); userRepository.save(user); diff --git a/src/main/java/eu/hbp/mip/controllers/AppsApi.java b/src/main/java/eu/hbp/mip/controllers/AppsApi.java index c46081989c91e5d08bac630dec1f27c18a6efbf1..29e8118bee75b7532025901078b4fa4955a651b5 100644 --- a/src/main/java/eu/hbp/mip/controllers/AppsApi.java +++ b/src/main/java/eu/hbp/mip/controllers/AppsApi.java @@ -5,12 +5,12 @@ package eu.hbp.mip.controllers; import eu.hbp.mip.configuration.SecurityConfiguration; +import eu.hbp.mip.model.UserInfo; import eu.hbp.mip.repositories.AppRepository; import io.swagger.annotations.*; import eu.hbp.mip.model.App; import eu.hbp.mip.model.User; import eu.hbp.mip.model.Vote; -import eu.hbp.mip.repositories.UserRepository; import eu.hbp.mip.repositories.VoteRepository; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -43,7 +43,7 @@ public class AppsApi { private VoteRepository voteRepository; @Autowired - private UserRepository userRepository; + private UserInfo userInfo; @ApiOperation(value = "Get apps", response = App.class, responseContainer = "List") @RequestMapping(method = RequestMethod.GET) @@ -62,7 +62,7 @@ public class AppsApi { ) { LOGGER.info("Post a vote"); - User user = userRepository.findOne(securityConfiguration.getUser().getUsername()); + User user = userInfo.getUser(); App app = appRepository.findOne(id); Vote vote; diff --git a/src/main/java/eu/hbp/mip/controllers/ArticlesApi.java b/src/main/java/eu/hbp/mip/controllers/ArticlesApi.java index 70f85a7088eeea5fe0fde775470612a4f4aa3458..3b567b102c182f529006f055a11112efd5c749a7 100644 --- a/src/main/java/eu/hbp/mip/controllers/ArticlesApi.java +++ b/src/main/java/eu/hbp/mip/controllers/ArticlesApi.java @@ -6,9 +6,9 @@ package eu.hbp.mip.controllers; import com.github.slugify.Slugify; -import eu.hbp.mip.configuration.SecurityConfiguration; import eu.hbp.mip.model.Article; import eu.hbp.mip.model.User; +import eu.hbp.mip.model.UserInfo; import eu.hbp.mip.repositories.ArticleRepository; import io.swagger.annotations.*; import org.slf4j.Logger; @@ -33,7 +33,7 @@ public class ArticlesApi { private static final Logger LOGGER = LoggerFactory.getLogger(ArticlesApi.class); @Autowired - private SecurityConfiguration securityConfiguration; + private UserInfo userInfo; @Autowired private ArticleRepository articleRepository; @@ -46,7 +46,7 @@ public class ArticlesApi { ) { LOGGER.info("Get articles"); - User user = securityConfiguration.getUser(); + User user = userInfo.getUser(); Iterable<Article> articles; if(own != null && own) @@ -82,7 +82,7 @@ public class ArticlesApi { ) { LOGGER.info("Create an article"); - User user = securityConfiguration.getUser(); + User user = userInfo.getUser(); article.setCreatedAt(new Date()); if ("published".equals(article.getStatus())) { @@ -143,7 +143,7 @@ public class ArticlesApi { ) { LOGGER.info("Get an article"); - User user = securityConfiguration.getUser(); + User user = userInfo.getUser(); Article article; article = articleRepository.findOne(slug); @@ -171,7 +171,7 @@ public class ArticlesApi { ) { LOGGER.info("Update an article"); - User user = securityConfiguration.getUser(); + User user = userInfo.getUser(); String author = articleRepository.findOne(slug).getCreatedBy().getUsername(); diff --git a/src/main/java/eu/hbp/mip/controllers/ExperimentApi.java b/src/main/java/eu/hbp/mip/controllers/ExperimentApi.java index 8ffd66a7759e319a08cfcfda6a4af6899aac01df..5e4620f9cec3b368d569003e921f9a1edaabc07c 100644 --- a/src/main/java/eu/hbp/mip/controllers/ExperimentApi.java +++ b/src/main/java/eu/hbp/mip/controllers/ExperimentApi.java @@ -5,15 +5,10 @@ import com.google.common.collect.Lists; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import eu.hbp.mip.akka.WokenClientController; -import eu.hbp.mip.configuration.SecurityConfiguration; -import eu.hbp.mip.model.AlgorithmParam; -import eu.hbp.mip.model.Experiment; -import eu.hbp.mip.model.ExperimentQuery; -import eu.hbp.mip.model.User; +import eu.hbp.mip.model.*; import eu.hbp.mip.repositories.ExperimentRepository; import eu.hbp.mip.repositories.ModelRepository; import eu.hbp.mip.utils.HTTPUtil; -import eu.hbp.mip.utils.JSONUtil; import ch.chuv.lren.woken.messages.query.QueryResult; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; @@ -58,7 +53,7 @@ public class ExperimentApi extends WokenClientController { public String miningExaremeQueryUrl; @Autowired - private SecurityConfiguration securityConfiguration; + private UserInfo userInfo; @Autowired private ModelRepository modelRepository; @@ -73,7 +68,7 @@ public class ExperimentApi extends WokenClientController { Experiment experiment = new Experiment(); experiment.setUuid(UUID.randomUUID()); - User user = securityConfiguration.getUser(); + User user = userInfo.getUser(); experiment.setAlgorithms(gson.toJson(expQuery.getAlgorithms())); experiment.setValidations(gson.toJson(expQuery.getValidations())); @@ -126,7 +121,7 @@ public class ExperimentApi extends WokenClientController { Experiment experiment; UUID experimentUuid; - User user = securityConfiguration.getUser(); + User user = userInfo.getUser(); try { experimentUuid = UUID.fromString(uuid); } catch (IllegalArgumentException iae) { @@ -202,7 +197,7 @@ public class ExperimentApi extends WokenClientController { boolean mine, String modelSlug ) { - User user = securityConfiguration.getUser(); + User user = userInfo.getUser(); Iterable<Experiment> myExperiments = experimentRepository.findByCreatedBy(user); List<Experiment> expList = Lists.newLinkedList(myExperiments); @@ -233,7 +228,7 @@ public class ExperimentApi extends WokenClientController { private ResponseEntity<String> doMarkExperimentAsShared(String uuid, boolean shared) { Experiment experiment; UUID experimentUuid; - User user = securityConfiguration.getUser(); + User user = userInfo.getUser(); try { experimentUuid = UUID.fromString(uuid); } catch (IllegalArgumentException iae) { @@ -256,7 +251,7 @@ public class ExperimentApi extends WokenClientController { } private void sendExperiment(final Experiment experiment) { - User user = securityConfiguration.getUser(); + User user = userInfo.getUser(); // this runs in the background. For future optimization: use a thread pool final ch.chuv.lren.woken.messages.query.ExperimentQuery experimentQuery = experiment.prepareQuery(user.getUsername()); diff --git a/src/main/java/eu/hbp/mip/controllers/FilesAPI.java b/src/main/java/eu/hbp/mip/controllers/FilesAPI.java index f39f1e6c6af951ef9ea03d29773896e25ba001fa..d79717062874418824d305a908926f1c61075255 100644 --- a/src/main/java/eu/hbp/mip/controllers/FilesAPI.java +++ b/src/main/java/eu/hbp/mip/controllers/FilesAPI.java @@ -1,6 +1,6 @@ package eu.hbp.mip.controllers; -import eu.hbp.mip.configuration.SecurityConfiguration; +import eu.hbp.mip.model.UserInfo; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; @@ -29,7 +29,7 @@ public class FilesAPI { private static final Logger LOGGER = LoggerFactory.getLogger(FilesAPI.class); @Autowired - private SecurityConfiguration securityConfiguration; + private UserInfo userInfo; @ApiOperation(value = "Get protected files") @RequestMapping(value = "/{filename:.+}" , method = RequestMethod.GET) @@ -39,7 +39,7 @@ public class FilesAPI { LOGGER.info("Get protected file"); String filepath = "/protected/" + filename; - String user = securityConfiguration.getUser().getUsername(); + String user = userInfo.getUser().getUsername(); String time = LocalDateTime.now().toString(); LOGGER.info("User " + user + " downloaded " + filepath + " at "+ time); diff --git a/src/main/java/eu/hbp/mip/controllers/MiningApi.java b/src/main/java/eu/hbp/mip/controllers/MiningApi.java index 625b45279fc357cc6b3dc7be189cff253e28d6a6..cd0577bd0fd55cd44c25764be3dd2f3ec100dac6 100644 --- a/src/main/java/eu/hbp/mip/controllers/MiningApi.java +++ b/src/main/java/eu/hbp/mip/controllers/MiningApi.java @@ -2,10 +2,10 @@ package eu.hbp.mip.controllers; import com.google.gson.Gson; import eu.hbp.mip.akka.WokenClientController; -import eu.hbp.mip.configuration.SecurityConfiguration; import eu.hbp.mip.model.ExaremeQuery; import eu.hbp.mip.model.Mining; import eu.hbp.mip.model.User; +import eu.hbp.mip.model.UserInfo; import eu.hbp.mip.utils.HTTPUtil; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; @@ -21,7 +21,6 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; import scala.Option; -import scala.Some; import java.io.IOException; import java.sql.Date; @@ -40,7 +39,7 @@ public class MiningApi extends WokenClientController { private static final Gson gson = new Gson(); @Autowired - private SecurityConfiguration securityConfiguration; + private UserInfo userInfo; @Value("#{'${services.query.miningExaremeUrl:http://localhost:9090/mining/query}'}") public String queryUrl; @@ -53,7 +52,7 @@ public class MiningApi extends WokenClientController { @RequestMapping(method = RequestMethod.POST) public ResponseEntity runAlgorithm(@RequestBody eu.hbp.mip.model.MiningQuery query) { LOGGER.info("Run an algorithm"); - User user = securityConfiguration.getUser(); + User user = userInfo.getUser(); if (isExaremeAlgo(query)) { LOGGER.info("isExaremeAlgo"); diff --git a/src/main/java/eu/hbp/mip/controllers/ModelsApi.java b/src/main/java/eu/hbp/mip/controllers/ModelsApi.java index 4685056465170049ace7bee3c89268bb0951b70d..9000271a9dfa9f0624ea3e26cc310c84a34279c0 100644 --- a/src/main/java/eu/hbp/mip/controllers/ModelsApi.java +++ b/src/main/java/eu/hbp/mip/controllers/ModelsApi.java @@ -9,9 +9,9 @@ import ch.chuv.lren.woken.messages.query.filters.FilterRule; import com.github.slugify.Slugify; import com.google.gson.Gson; import com.google.gson.JsonObject; -import eu.hbp.mip.configuration.SecurityConfiguration; import eu.hbp.mip.model.Model; import eu.hbp.mip.model.User; +import eu.hbp.mip.model.UserInfo; import eu.hbp.mip.model.Variable; import eu.hbp.mip.repositories.*; import eu.hbp.mip.utils.DataUtil; @@ -38,7 +38,7 @@ public class ModelsApi { private static final Logger LOGGER = LoggerFactory.getLogger(ModelsApi.class); @Autowired - private SecurityConfiguration securityConfiguration; + private UserInfo userInfo; @Autowired private DatasetRepository datasetRepository; @@ -68,7 +68,7 @@ public class ModelsApi { ) { LOGGER.info("Get models"); - User user = securityConfiguration.getUser(); + User user = userInfo.getUser(); Iterable<Model> models; if(own != null && own) @@ -112,7 +112,7 @@ public class ModelsApi { LOGGER.info("Create a model"); - User user = securityConfiguration.getUser(); + User user = userInfo.getUser(); model.setTitle(model.getConfig().getTitle().get("text")); model.setCreatedBy(user); @@ -203,7 +203,7 @@ public class ModelsApi { ) { LOGGER.info("Get a model"); - User user = securityConfiguration.getUser(); + User user = userInfo.getUser(); Model model = modelRepository.findOne(slug); @@ -235,7 +235,7 @@ public class ModelsApi { ) { LOGGER.info("Update a model"); - User user = securityConfiguration.getUser(); + User user = userInfo.getUser(); Model oldModel = modelRepository.findOne(slug); if(!user.getUsername().equals(oldModel.getCreatedBy().getUsername())) diff --git a/src/main/java/eu/hbp/mip/model/UserInfo.java b/src/main/java/eu/hbp/mip/model/UserInfo.java new file mode 100644 index 0000000000000000000000000000000000000000..3bc14553b56f3c1538cc6669a8605dbe008bb4e4 --- /dev/null +++ b/src/main/java/eu/hbp/mip/model/UserInfo.java @@ -0,0 +1,66 @@ +package eu.hbp.mip.model; + +import eu.hbp.mip.repositories.UserRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Scope; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.oauth2.provider.OAuth2Authentication; +import org.springframework.stereotype.Component; + +@Component +@Scope("session") +public class UserInfo { + + @Autowired + private UserRepository userRepository; + + /** + * Enable HBP collab authentication (1) or disable it (0). Default is 1 + */ + @Value("#{'${hbp.authentication.enabled:1}'}") + private boolean authentication; + + private User user; + + /** + * returns the user for the current session. + * <p> + * the "synchronized" keyword is there to avoid a bug that the transaction is supposed to protect me from. + * To test if your solution to removing it works, do the following: + * - clean DB from scratch + * - restart DB and backend (no session or anything like that) + * - log in using the front end + * - check you have no 500 error in the network logs. + * + * @return the user for the current session + */ + public User getUser() { + if (user == null) { + + if (!authentication) { + user = new User(); + user.setUsername("anonymous"); + user.setFullname("anonymous"); + user.setPicture("images/users/default_user.png"); + } else { + user = new User(getUserInfos()); + } + User foundUser = userRepository.findOne(user.getUsername()); + if (foundUser != null) { + user.setAgreeNDA(foundUser.getAgreeNDA()); + } + userRepository.save(user); + } + + return user; + } + + private String getUserInfos() { + OAuth2Authentication oAuth2Authentication = (OAuth2Authentication) SecurityContextHolder.getContext().getAuthentication(); + Authentication userAuthentication = oAuth2Authentication.getUserAuthentication(); + return userAuthentication.getDetails().toString(); + } + +}