Commit f17da18e authored by Piotr Gawron's avatar Piotr Gawron
Browse files

userRestImpl remvoed

parent e7c359de
......@@ -2,11 +2,14 @@ package lcsb.mapviewer.api.users;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.TreeMap;
import java.util.stream.Collectors;
......@@ -14,6 +17,7 @@ import javax.mail.MessagingException;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.hibernate.exception.ConstraintViolationException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.http.converter.json.MappingJacksonValue;
......@@ -37,12 +41,18 @@ import com.fasterxml.jackson.databind.ser.impl.SimpleFilterProvider;
import lcsb.mapviewer.api.BaseController;
import lcsb.mapviewer.api.OperationNotAllowedException;
import lcsb.mapviewer.api.UpdateConflictException;
import lcsb.mapviewer.common.Configuration;
import lcsb.mapviewer.common.exception.InvalidStateException;
import lcsb.mapviewer.model.security.Privilege;
import lcsb.mapviewer.model.security.PrivilegeType;
import lcsb.mapviewer.model.user.ConfigurationElementType;
import lcsb.mapviewer.model.user.User;
import lcsb.mapviewer.model.user.UserAnnotationSchema;
import lcsb.mapviewer.model.user.UserClassAnnotators;
import lcsb.mapviewer.model.user.UserClassRequiredAnnotations;
import lcsb.mapviewer.model.user.UserClassValidAnnotations;
import lcsb.mapviewer.model.user.UserGuiPreference;
import lcsb.mapviewer.modelutils.serializer.CustomExceptFilter;
import lcsb.mapviewer.modelutils.serializer.model.security.PrivilegeKeyDeserializer;
import lcsb.mapviewer.services.InvalidTokenException;
......@@ -50,6 +60,7 @@ import lcsb.mapviewer.services.ObjectExistsException;
import lcsb.mapviewer.services.ObjectNotFoundException;
import lcsb.mapviewer.services.QueryException;
import lcsb.mapviewer.services.interfaces.IConfigurationService;
import lcsb.mapviewer.services.interfaces.IProjectService;
import lcsb.mapviewer.services.interfaces.IUserService;
import lcsb.mapviewer.services.utils.EmailSender;
......@@ -60,18 +71,18 @@ public class UserController extends BaseController {
Logger logger = LogManager.getLogger();
private IUserService userService;
private IProjectService projectService;
private IConfigurationService configurationService;
private UserRestImpl userRest;
private PasswordEncoder passwordEncoder;
private EmailSender emailSender;
@Autowired
public UserController(IUserService userService, UserRestImpl userRest, PasswordEncoder passwordEncoder, EmailSender emailSender,
IConfigurationService configurationService) {
public UserController(IUserService userService, PasswordEncoder passwordEncoder, EmailSender emailSender,
IConfigurationService configurationService, IProjectService projectService) {
this.userService = userService;
this.userRest = userRest;
this.passwordEncoder = passwordEncoder;
this.emailSender = emailSender;
this.projectService = projectService;
this.configurationService = configurationService;
}
......@@ -93,7 +104,18 @@ public class UserController extends BaseController {
public MappingJacksonValue getUser(
@PathVariable(value = "login") String login,
@RequestParam(value = "columns", defaultValue = "") String columns) throws ObjectNotFoundException {
return createResponseWithColumns(columns, userRest.getUser(login, columns));
Set<String> columnSet = createUserColumnSet(columns);
User user = userService.getUserByLogin(login, true);
if (user == null) {
throw new ObjectNotFoundException("User doesn't exist");
}
Boolean ldapAvailable = false;
if (columnSet.contains("ldapAccountAvailable")) {
List<User> userList = new ArrayList<>();
userList.add(user);
ldapAvailable = userService.ldapAccountExistsForLogin(userList).get(login);
}
return createResponseWithColumns(columns, new UserDTO(user, ldapAvailable == true));
}
public static class UserPrivilegesDTO {
......@@ -106,7 +128,38 @@ public class UserController extends BaseController {
public MappingJacksonValue updatePrivileges(
@RequestBody UserPrivilegesDTO data,
@PathVariable(value = "login") String login) throws IOException, QueryException {
return createResponseWithColumns("", userRest.updatePrivileges(login, data.privileges));
if (data == null) {
throw new QueryException("Privileges not defined");
}
User user = userService.getUserByLogin(login);
if (user == null) {
throw new QueryException("User does not exist.");
}
for (Privilege privilege : data.privileges.keySet()) {
boolean grant;
try {
grant = (boolean) data.privileges.get(privilege);
} catch (ClassCastException e) {
throw new QueryException("Privilege can only be set to true (grant) or false (revoke).", e);
}
if (privilege.isObjectPrivilege()) {
if (grant) {
userService.grantUserPrivilege(user, privilege.getType(), privilege.getObjectId());
} else {
userService.revokeUserPrivilege(user, privilege.getType(), privilege.getObjectId());
}
} else {
if (grant) {
userService.grantUserPrivilege(user, privilege.getType());
} else {
userService.revokeUserPrivilege(user, privilege.getType());
}
}
}
return getUser(login, "");
}
@PreAuthorize("hasAuthority('IS_ADMIN') or #login == authentication.name")
......@@ -114,7 +167,120 @@ public class UserController extends BaseController {
public UserPreferencesDTO updatePreferences(
@RequestBody UserPreferencesDTO body,
@PathVariable(value = "login") String login) throws IOException, QueryException {
return userRest.updatePreferences(login, body.preferences);
if (body.preferences == null) {
throw new QueryException("Preferences not defined");
}
try {
User modifiedUser = userService.getUserByLogin(login);
if (modifiedUser == null) {
throw new ObjectNotFoundException("User doesn't exist");
}
UserAnnotationSchema schema = projectService.prepareUserAnnotationSchema(modifiedUser, true);
if (body.preferences.getValidateMiriamTypes() != null) {
schema.setValidateMiriamTypes(body.preferences.getValidateMiriamTypes());
}
if (body.preferences.getAnnotateModel() != null) {
schema.setAnnotateModel(body.preferences.getAnnotateModel());
}
if (body.preferences.getCacheData() != null) {
schema.setCacheData(body.preferences.getCacheData());
}
if (body.preferences.getAutoResizeMap() != null) {
schema.setAutoResizeMap(body.preferences.getAutoResizeMap());
}
if (body.preferences.getSemanticZoomContainsMultipleOverlays()) {
schema.setSemanticZoomContainsMultipleOverlays(body.preferences.getSemanticZoomContainsMultipleOverlays());
}
if (body.preferences.getSbgnFormat() != null) {
schema.setSbgnFormat(body.preferences.getSbgnFormat());
}
updateElementAnnotators(schema, body.preferences);
updateValidAnnotations(schema, body.preferences);
updateRequiredAnnotations(schema, body.preferences);
updateGuiPreferences(schema, body.preferences);
modifiedUser.setAnnotationSchema(schema);
userService.updateUser(modifiedUser);
return new UserPreferencesDTO(userService.getUserByLogin(login, true).getAnnotationSchema());
} catch (IllegalArgumentException e) {
throw new QueryException("Invalid input", e);
} catch (Exception e) {
if (e.getCause() instanceof ConstraintViolationException) {
// postgres
if (e.getCause().getCause().getMessage().contains("duplicate key value violates unique constraint")) {
throw new UpdateConflictException("Conflict when updating preferences.", e);
// hsqldb
} else if (e.getCause().getCause().getMessage().contains("unique constraint or index violation")) {
throw new UpdateConflictException("Conflict when updating preferences.", e);
}
}
throw e;
}
}
private void updateValidAnnotations(UserAnnotationSchema schema, UserAnnotationSchema newData) {
for (UserClassValidAnnotations annotations : newData.getClassValidAnnotators()) {
UserClassValidAnnotations annotator = null;
for (UserClassValidAnnotations userClassAnnotators : schema.getClassValidAnnotators()) {
if (userClassAnnotators.getClassName().equals(annotations.getClassName())) {
annotator = userClassAnnotators;
}
}
if (annotator == null) {
annotator = new UserClassValidAnnotations(annotations.getClass(), annotations.getValidMiriamTypes());
schema.addClassValidAnnotations(annotator);
} else {
annotator.setValidMiriamTypes(annotations.getValidMiriamTypes());
}
}
}
private void updateGuiPreferences(UserAnnotationSchema schema, UserAnnotationSchema newData) {
for (UserGuiPreference preference : newData.getGuiPreferences()) {
schema.setGuiPreference(preference.getKey(), preference.getValue());
}
}
private void updateRequiredAnnotations(UserAnnotationSchema schema, UserAnnotationSchema newData) throws QueryException {
for (UserClassRequiredAnnotations newAnnotator : newData.getClassRequiredAnnotators()) {
UserClassRequiredAnnotations annotator = null;
for (UserClassRequiredAnnotations userClassAnnotators : schema.getClassRequiredAnnotators()) {
if (userClassAnnotators.getClassName().equals(newAnnotator.getClassName())) {
annotator = userClassAnnotators;
}
}
if (annotator == null) {
annotator = new UserClassRequiredAnnotations();
schema.addClassRequiredAnnotations(annotator);
annotator.setClassName(annotator.getClassName());
annotator.setRequiredMiriamTypes(newAnnotator.getRequiredMiriamTypes());
} else {
if (newAnnotator.getRequireAtLeastOneAnnotation() != null) {
annotator.setRequireAtLeastOneAnnotation(newAnnotator.getRequireAtLeastOneAnnotation());
}
}
annotator.setRequireAtLeastOneAnnotation(newAnnotator.getRequireAtLeastOneAnnotation());
}
}
private void updateElementAnnotators(UserAnnotationSchema schema, UserAnnotationSchema newData) throws QueryException {
for (UserClassAnnotators newClassAnnotator : newData.getClassAnnotators()) {
UserClassAnnotators annotator = null;
for (UserClassAnnotators userClassAnnotators : schema.getClassAnnotators()) {
if (userClassAnnotators.getClassName().equals(newClassAnnotator.getClassName())) {
annotator = userClassAnnotators;
}
}
if (annotator == null) {
annotator = new UserClassAnnotators(newClassAnnotator.getClass(), newClassAnnotator.getAnnotators());
schema.addClassAnnotator(annotator);
} else {
annotator.setAnnotators(newClassAnnotator.getAnnotators());
}
}
}
@PreAuthorize("hasAnyAuthority('IS_ADMIN', 'IS_CURATOR')")
......@@ -139,7 +305,7 @@ public class UserController extends BaseController {
if (!columns.trim().isEmpty()) {
provider.addFilter("userFilter", new CustomExceptFilter(columns.split(",")));
} else {
provider.addFilter("userFilter", new CustomExceptFilter(userRest.createUserColumnSet(columns)));
provider.addFilter("userFilter", new CustomExceptFilter(createUserColumnSet(columns)));
}
result.setFilters(provider);
return result;
......@@ -285,4 +451,28 @@ public class UserController extends BaseController {
}
}
public Set<String> createUserColumnSet(String columns) {
Set<String> columnsSet = new LinkedHashSet<>();
if (columns.equals("")) {
columnsSet.add("id");
columnsSet.add("login");
columnsSet.add("name");
columnsSet.add("surname");
columnsSet.add("email");
columnsSet.add("minColor");
columnsSet.add("maxColor");
columnsSet.add("neutralColor");
columnsSet.add("simpleColor");
columnsSet.add("removed");
columnsSet.add("privileges");
columnsSet.add("termsOfUseConsent");
columnsSet.add("connectedToLdap");
columnsSet.add("ldapAccountAvailable");
} else {
columnsSet.addAll(Arrays.asList(columns.split(",")));
}
return columnsSet;
}
}
\ No newline at end of file
package lcsb.mapviewer.api.users;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.hibernate.exception.ConstraintViolationException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import lcsb.mapviewer.api.BaseRestImpl;
import lcsb.mapviewer.api.UpdateConflictException;
import lcsb.mapviewer.model.security.Privilege;
import lcsb.mapviewer.model.user.User;
import lcsb.mapviewer.model.user.UserAnnotationSchema;
import lcsb.mapviewer.model.user.UserClassAnnotators;
import lcsb.mapviewer.model.user.UserClassRequiredAnnotations;
import lcsb.mapviewer.model.user.UserClassValidAnnotations;
import lcsb.mapviewer.model.user.UserGuiPreference;
import lcsb.mapviewer.services.ObjectNotFoundException;
import lcsb.mapviewer.services.QueryException;
@Transactional(rollbackFor = UpdateConflictException.class)
@Service
public class UserRestImpl extends BaseRestImpl {
/**
* Default class logger.
*/
@SuppressWarnings("unused")
private Logger logger = LogManager.getLogger();
public UserDTO getUser(String login, String columns)
throws ObjectNotFoundException {
Set<String> columnSet = createUserColumnSet(columns);
User user = getUserService().getUserByLogin(login, true);
if (user == null) {
throw new ObjectNotFoundException("User doesn't exist");
}
Boolean ldapAvailable = false;
if (columnSet.contains("ldapAccountAvailable")) {
List<User> userList = new ArrayList<>();
userList.add(user);
ldapAvailable = getUserService().ldapAccountExistsForLogin(userList).get(login);
}
return new UserDTO(user, ldapAvailable == true);
}
public Set<String> createUserColumnSet(String columns) {
Set<String> columnsSet = new LinkedHashSet<>();
if (columns.equals("")) {
columnsSet.add("id");
columnsSet.add("login");
columnsSet.add("name");
columnsSet.add("surname");
columnsSet.add("email");
columnsSet.add("minColor");
columnsSet.add("maxColor");
columnsSet.add("neutralColor");
columnsSet.add("simpleColor");
columnsSet.add("removed");
columnsSet.add("privileges");
columnsSet.add("termsOfUseConsent");
columnsSet.add("connectedToLdap");
columnsSet.add("ldapAccountAvailable");
} else {
columnsSet.addAll(Arrays.asList(columns.split(",")));
}
return columnsSet;
}
private void updateValidAnnotations(UserAnnotationSchema schema, UserAnnotationSchema newData) {
for (UserClassValidAnnotations annotations : newData.getClassValidAnnotators()) {
UserClassValidAnnotations annotator = null;
for (UserClassValidAnnotations userClassAnnotators : schema.getClassValidAnnotators()) {
if (userClassAnnotators.getClassName().equals(annotations.getClassName())) {
annotator = userClassAnnotators;
}
}
if (annotator == null) {
annotator = new UserClassValidAnnotations(annotations.getClass(), annotations.getValidMiriamTypes());
schema.addClassValidAnnotations(annotator);
} else {
annotator.setValidMiriamTypes(annotations.getValidMiriamTypes());
}
}
}
private void updateGuiPreferences(UserAnnotationSchema schema, UserAnnotationSchema newData) {
for (UserGuiPreference preference : newData.getGuiPreferences()) {
schema.setGuiPreference(preference.getKey(), preference.getValue());
}
}
private void updateRequiredAnnotations(UserAnnotationSchema schema, UserAnnotationSchema newData) throws QueryException {
for (UserClassRequiredAnnotations newAnnotator : newData.getClassRequiredAnnotators()) {
UserClassRequiredAnnotations annotator = null;
for (UserClassRequiredAnnotations userClassAnnotators : schema.getClassRequiredAnnotators()) {
if (userClassAnnotators.getClassName().equals(newAnnotator.getClassName())) {
annotator = userClassAnnotators;
}
}
if (annotator == null) {
annotator = new UserClassRequiredAnnotations();
schema.addClassRequiredAnnotations(annotator);
annotator.setClassName(annotator.getClassName());
annotator.setRequiredMiriamTypes(newAnnotator.getRequiredMiriamTypes());
} else {
if (newAnnotator.getRequireAtLeastOneAnnotation() != null) {
annotator.setRequireAtLeastOneAnnotation(newAnnotator.getRequireAtLeastOneAnnotation());
}
}
annotator.setRequireAtLeastOneAnnotation(newAnnotator.getRequireAtLeastOneAnnotation());
}
}
private void updateElementAnnotators(UserAnnotationSchema schema, UserAnnotationSchema newData) throws QueryException {
for (UserClassAnnotators newClassAnnotator : newData.getClassAnnotators()) {
UserClassAnnotators annotator = null;
for (UserClassAnnotators userClassAnnotators : schema.getClassAnnotators()) {
if (userClassAnnotators.getClassName().equals(newClassAnnotator.getClassName())) {
annotator = userClassAnnotators;
}
}
if (annotator == null) {
annotator = new UserClassAnnotators(newClassAnnotator.getClass(), newClassAnnotator.getAnnotators());
schema.addClassAnnotator(annotator);
} else {
annotator.setAnnotators(newClassAnnotator.getAnnotators());
}
}
}
public UserDTO updatePrivileges(String login, Map<Privilege, Boolean> data) throws QueryException {
if (data == null) {
throw new QueryException("Privileges not defined");
}
User user = getUserService().getUserByLogin(login);
if (user == null) {
throw new QueryException("User does not exist.");
}
for (Privilege privilege : data.keySet()) {
boolean grant;
try {
grant = (boolean) data.get(privilege);
} catch (ClassCastException e) {
throw new QueryException("Privilege can only be set to true (grant) or false (revoke).", e);
}
if (privilege.isObjectPrivilege()) {
if (grant) {
getUserService().grantUserPrivilege(user, privilege.getType(), privilege.getObjectId());
} else {
getUserService().revokeUserPrivilege(user, privilege.getType(), privilege.getObjectId());
}
} else {
if (grant) {
getUserService().grantUserPrivilege(user, privilege.getType());
} else {
getUserService().revokeUserPrivilege(user, privilege.getType());
}
}
}
return getUser(login, "");
}
public UserPreferencesDTO updatePreferences(String login, UserAnnotationSchema preferencesData)
throws QueryException {
if (preferencesData == null) {
throw new QueryException("Preferences not defined");
}
try {
User modifiedUser = getUserService().getUserByLogin(login);
if (modifiedUser == null) {
throw new ObjectNotFoundException("User doesn't exist");
}
UserAnnotationSchema schema = getProjectService().prepareUserAnnotationSchema(modifiedUser);
if (preferencesData.getValidateMiriamTypes() != null) {
schema.setValidateMiriamTypes(preferencesData.getValidateMiriamTypes());
}
if (preferencesData.getAnnotateModel() != null) {
schema.setAnnotateModel(preferencesData.getAnnotateModel());
}
if (preferencesData.getCacheData() != null) {
schema.setCacheData(preferencesData.getCacheData());
}
if (preferencesData.getAutoResizeMap() != null) {
schema.setAutoResizeMap(preferencesData.getAutoResizeMap());
}
if (preferencesData.getSemanticZoomContainsMultipleOverlays()) {
schema.setSemanticZoomContainsMultipleOverlays(preferencesData.getSemanticZoomContainsMultipleOverlays());
}
if (preferencesData.getSbgnFormat() != null) {
schema.setSbgnFormat(preferencesData.getSbgnFormat());
}
updateElementAnnotators(schema, preferencesData);
updateValidAnnotations(schema, preferencesData);
updateRequiredAnnotations(schema, preferencesData);
updateGuiPreferences(schema, preferencesData);
modifiedUser.setAnnotationSchema(schema);
getUserService().updateUser(modifiedUser);
return new UserPreferencesDTO(getUser(login, "preferences").getAnnotationSchema());
} catch (IllegalArgumentException e) {
throw new QueryException("Invalid input", e);
} catch (Exception e) {
if (e.getCause() instanceof ConstraintViolationException) {
// postgres
if (e.getCause().getCause().getMessage().contains("duplicate key value violates unique constraint")) {
throw new UpdateConflictException("Conflict when updating preferences.", e);
// hsqldb
} else if (e.getCause().getCause().getMessage().contains("unique constraint or index violation")) {
throw new UpdateConflictException("Conflict when updating preferences.", e);
}
}
throw e;
}
}
}
......@@ -509,7 +509,7 @@ public class ProjectService implements IProjectService {
@Override
public TreeNode createClassAnnotatorTree(User user) {
UserAnnotationSchema annotationSchema = prepareUserAnnotationSchema(user);
UserAnnotationSchema annotationSchema = prepareUserAnnotationSchema(user, false);
ElementUtils elementUtils = new ElementUtils();
......@@ -605,7 +605,8 @@ public class ProjectService implements IProjectService {
* for this users {@link UserAnnotationSchema} will be prepared
* @return {@link UserAnnotationSchema} for {@link User}
*/
public UserAnnotationSchema prepareUserAnnotationSchema(User user) {
@Override
public UserAnnotationSchema prepareUserAnnotationSchema(User user, boolean initializeLazy) {
UserAnnotationSchema annotationSchema = null;
if (user != null) {
annotationSchema = userDao.getById(user.getId()).getAnnotationSchema();
......@@ -644,6 +645,9 @@ public class ProjectService implements IProjectService {
userDao.update(dbUser);
}
}
if (user != null) {
return userService.getUserByLogin(user.getLogin(), initializeLazy).getAnnotationSchema();
}
return annotationSchema;
}
......
......@@ -111,7 +111,7 @@ public interface IProjectService {
*/
void updateProject(Project project);
UserAnnotationSchema prepareUserAnnotationSchema(User user);
UserAnnotationSchema prepareUserAnnotationSchema(User user, boolean initializeLazy);
void removeBackground(ProjectBackground projectBackground);
......
......@@ -54,9 +54,9 @@ import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import lcsb.mapviewer.annotation.services.annotators.UniprotAnnotator;
import lcsb.mapviewer.api.users.UserController;
import lcsb.mapviewer.api.users.UserController.UserPrivilegesDTO;
import lcsb.mapviewer.api.users.UserPreferencesDTO;
import lcsb.mapviewer.api.users.UserRestImpl;
import lcsb.mapviewer.model.Project;
import lcsb.mapviewer.model.map.BioEntity;
import lcsb.mapviewer.model.map.MiriamType;
......@@ -121,7 +121,7 @@ public class UserControllerIntegrationTest extends ControllerIntegrationTest {
private ProjectSnippets projectSnippets;
@Autowired
private UserRestImpl userRestImpl;
private UserController userController;
@Before
public void setup() throws Exception {
......@@ -347,7 +347,7 @@ public class UserControllerIntegrationTest extends ControllerIntegrationTest {