Skip to content
Snippets Groups Projects
Commit a357c562 authored by Ludovic Claude's avatar Ludovic Claude
Browse files

Fix deadlock on getUser()

parent ae678d8f
No related branches found
No related tags found
No related merge requests found
......@@ -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);
......
......@@ -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;
......
......@@ -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();
......
......@@ -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());
......
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);
......
......@@ -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");
......
......@@ -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()))
......
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();
}
}
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