Commit 32c6bf5e authored by Piotr Gawron's avatar Piotr Gawron
Browse files

privilege is serialized by default serializer

parent 921dfcc9
......@@ -5,6 +5,10 @@ import java.util.Objects;
import javax.persistence.*;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
@Entity
@Table(uniqueConstraints = @UniqueConstraint(columnNames = { "type", "objectId" }))
public class Privilege implements Serializable {
......@@ -13,12 +17,15 @@ public class Privilege implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@JsonIgnore
private Integer id;
@Enumerated(EnumType.STRING)
@Column(nullable = false)
@JsonProperty("privilegeType")
private PrivilegeType type;
@JsonProperty("objectId")
private String objectId;
protected Privilege() {
......@@ -66,6 +73,7 @@ public class Privilege implements Serializable {
}
}
@JsonIgnore
public boolean isObjectPrivilege() {
return objectId != null;
}
......
......@@ -2,6 +2,7 @@ package lcsb.mapviewer.api.users;
import java.io.IOException;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
......@@ -28,9 +29,9 @@ import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import lcsb.mapviewer.api.BaseController;
import lcsb.mapviewer.api.OperationNotAllowedException;
import lcsb.mapviewer.common.Configuration;
import lcsb.mapviewer.common.exception.InvalidStateException;
import lcsb.mapviewer.common.exception.NotImplementedException;
import lcsb.mapviewer.model.user.ConfigurationElementType;
import lcsb.mapviewer.model.user.User;
import lcsb.mapviewer.services.InvalidTokenException;
......@@ -133,8 +134,15 @@ public class UserController extends BaseController {
@PreAuthorize("hasAuthority('IS_ADMIN')")
@DeleteMapping(value = "/users/{login:.+}")
public Map<String, Object> removeUser(@PathVariable(value = "login") String login) throws Exception {
return userRest.removeUser(login);
public Object removeUser(@PathVariable(value = "login") String login) throws Exception {
User user = userService.getUserByLogin(login);
if (user == null) {
throw new ObjectNotFoundException("user doesn't exists");
} else if (user.getLogin().equals(Configuration.ANONYMOUS_LOGIN)) {
throw new OperationNotAllowedException("guest account cannot be removed");
}
userService.deleteUser(user);
return new HashMap<>();
}
@PostMapping(value = "/users/{login}:requestResetPassword")
......
......@@ -75,7 +75,7 @@ public class UserRestImpl extends BaseRestImpl {
public Map<String, Object> getUser(String login, String columns)
throws ObjectNotFoundException {
Set<String> columnSet = createUserColumnSet(columns);
User user = getUserService().getUserByLogin(login);
User user = getUserService().getUserByLogin(login, true);
if (user == null) {
throw new ObjectNotFoundException("User doesn't exist");
}
......@@ -161,7 +161,7 @@ public class UserRestImpl extends BaseRestImpl {
value = ldapAvailable;
break;
case "privileges":
value = preparePrivileges(user);
value = user.getPrivileges();
break;
case "preferences":
value = preparePreferences(user);
......@@ -519,30 +519,10 @@ public class UserRestImpl extends BaseRestImpl {
return result;
}
private List<Map<String, Object>> preparePrivileges(User user) {
List<Map<String, Object>> result = new ArrayList<>();
List<Privilege> privileges = new ArrayList<>(user.getPrivileges());
for (Privilege privilege : privileges) {
result.add(preparePrivilege(privilege));
}
return result;
}
private Map<String, Object> preparePrivilege(Privilege privilege) {
Map<String, Object> result = new TreeMap<>();
if (privilege.getClass().equals(Privilege.class)) {
result.put("privilegeType", privilege.getType());
result.put("objectId", privilege.getObjectId());
return result;
} else {
throw new InvalidArgumentException("Don't know how to handle class: " + privilege.getClass());
}
}
public List<Map<String, Object>> getUsers(String columns) {
Set<String> columnSet = createUserColumnSet(columns);
List<Map<String, Object>> result = new ArrayList<>();
List<User> users = getUserService().getUsers();
List<User> users = getUserService().getUsers(true);
Map<String, Boolean> ldapAvailability = getUserService().ldapAccountExistsForLogin(users);
for (User user : users) {
result.add(prepareUse(user, columnSet, ldapAvailability.get(user.getLogin())));
......@@ -762,19 +742,4 @@ public class UserRestImpl extends BaseRestImpl {
return getUser(login, "");
}
public Map<String, Object> removeUser(String login) throws QueryException, IOException {
User user = getUserService().getUserByLogin(login);
if (user == null) {
throw new ObjectNotFoundException("user doesn't exists");
} else if (user.getLogin().equals(Configuration.ANONYMOUS_LOGIN)) {
throw new OperationNotAllowedException("guest account cannot be removed");
}
List<ProjectBackground> backgrounds = projectBackgroundService.getProjectBackgroundsByUser(user);
for (ProjectBackground background : backgrounds) {
projectBackgroundService.removeProjectBackground(background, null);
}
getUserService().deleteUser(user);
return okStatus();
}
}
......@@ -46,55 +46,6 @@ public class ProjectBackgroundService implements IProjectBackgroundService {
this.configurationService = configurationService;
}
@Override
public void removeProjectBackground(ProjectBackground background, final String homeDir) {
final String dir;
if (homeDir != null) {
if (background.getProject().getDirectory() != null) {
dir = homeDir + "/../map_images/" + background.getProject().getDirectory() + "/";
} else {
dir = homeDir + "/../map_images/";
}
} else {
dir = null;
}
String projectId = background.getProject().getProjectId();
final String email;
User user = background.getCreator();
if (user != null) {
email = user.getEmail();
} else {
email = null;
}
background.getProject().removeProjectBackground(background);
projectBackgroundDao.delete(background);
logger.info("Data overlay " + background.getId() + " removed");
if (email != null) {
Thread sendEmailThread = new Thread(() -> {
try {
sendSuccesfullRemoveEmail(projectId, background.getName(), email);
} catch (MessagingException e) {
logger.error(e);
}
});
sendEmailThread.start();
}
Thread removeFilesThread = new Thread(() -> {
MapGenerator generator = new MapGenerator();
try {
generator.removeProjectBackground(background, dir);
} catch (IOException e) {
logger.error(e);
}
});
removeFilesThread.start();
}
@Override
public void updateProjectBackground(ProjectBackground projectBackground) {
projectBackgroundDao.update(projectBackground);
......
......@@ -7,6 +7,7 @@ import javax.mail.MessagingException;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.hibernate.Hibernate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
......@@ -15,11 +16,13 @@ import com.unboundid.ldap.sdk.LDAPException;
import lcsb.mapviewer.commands.ColorExtractor;
import lcsb.mapviewer.common.geometry.ColorParser;
import lcsb.mapviewer.model.map.layout.ProjectBackground;
import lcsb.mapviewer.model.security.Privilege;
import lcsb.mapviewer.model.security.PrivilegeType;
import lcsb.mapviewer.model.user.*;
import lcsb.mapviewer.persist.dao.ProjectDao;
import lcsb.mapviewer.persist.dao.map.DataOverlayDao;
import lcsb.mapviewer.persist.dao.map.ProjectBackgroundDao;
import lcsb.mapviewer.persist.dao.user.ResetPasswordTokenDao;
import lcsb.mapviewer.persist.dao.user.UserDao;
import lcsb.mapviewer.services.InvalidTokenException;
......@@ -38,6 +41,7 @@ public class UserService implements IUserService {
private IConfigurationService configurationService;
private IPrivilegeService privilegeService;
private ProjectDao projectDao;
private ProjectBackgroundDao projectBackgroundDao;
private ResetPasswordTokenDao resetPasswordTokenDao;
private EmailSender emailSender;
......@@ -49,7 +53,8 @@ public class UserService implements IUserService {
ProjectDao projectDao,
ResetPasswordTokenDao resetPasswordTokenDao,
EmailSender emailSender,
DataOverlayDao dataOverlayDao) {
DataOverlayDao dataOverlayDao,
ProjectBackgroundDao projectBackgroundDao) {
this.userDao = userDao;
this.ldapService = ldapService;
this.configurationService = configurationService;
......@@ -58,6 +63,7 @@ public class UserService implements IUserService {
this.resetPasswordTokenDao = resetPasswordTokenDao;
this.emailSender = emailSender;
this.dataOverlayDao = dataOverlayDao;
this.projectBackgroundDao = projectBackgroundDao;
}
@Override
......@@ -74,6 +80,10 @@ public class UserService implements IUserService {
@Override
public void deleteUser(User user) {
String login = user.getLogin();
List<ProjectBackground> backgrounds = projectBackgroundDao.getProjectBackgroundsByUser(user);
for (ProjectBackground background : backgrounds) {
projectBackgroundDao.delete(background);
}
dataOverlayDao.deleteDataOverlays(dataOverlayDao.getDataOverlayByOwner(user));
userDao.delete(user);
logger.info("User " + login + " removed successfully");
......@@ -85,8 +95,14 @@ public class UserService implements IUserService {
}
@Override
public List<User> getUsers() {
return userDao.getAll();
public List<User> getUsers(boolean loadLazy) {
List<User> users = userDao.getAll();
if (loadLazy) {
for (User user : users) {
Hibernate.initialize(user.getPrivileges());
}
}
return users;
}
@Override
......@@ -127,7 +143,7 @@ public class UserService implements IUserService {
@Override
public void grantPrivilegeToAllUsersWithDefaultAccess(PrivilegeType type, String objectId) {
getUsers().stream()
getUsers(false).stream()
.filter(u -> u.getPrivileges().contains(new Privilege(type, "*")))
.forEach(u -> grantUserPrivilege(u, type, objectId));
}
......@@ -195,21 +211,21 @@ public class UserService implements IUserService {
private void grantPrivilegesForDefaultConfigurationElementType(User user, ConfigurationElementType type) {
switch (type) {
case DEFAULT_CAN_CREATE_OVERLAYS:
grantUserPrivilege(user, PrivilegeType.CAN_CREATE_OVERLAYS);
break;
case DEFAULT_READ_PROJECT:
grantUserPrivilege(user, PrivilegeType.READ_PROJECT, "*");
projectDao.getAll()
.forEach(project -> grantUserPrivilege(user, PrivilegeType.READ_PROJECT, project.getProjectId()));
break;
case DEFAULT_WRITE_PROJECT:
grantUserPrivilege(user, PrivilegeType.WRITE_PROJECT, "*");
projectDao.getAll()
.forEach(project -> grantUserPrivilege(user, PrivilegeType.WRITE_PROJECT, project.getProjectId()));
break;
default:
throw new IllegalArgumentException("The configuration element type '+" + type + "' is not handled.");
case DEFAULT_CAN_CREATE_OVERLAYS:
grantUserPrivilege(user, PrivilegeType.CAN_CREATE_OVERLAYS);
break;
case DEFAULT_READ_PROJECT:
grantUserPrivilege(user, PrivilegeType.READ_PROJECT, "*");
projectDao.getAll()
.forEach(project -> grantUserPrivilege(user, PrivilegeType.READ_PROJECT, project.getProjectId()));
break;
case DEFAULT_WRITE_PROJECT:
grantUserPrivilege(user, PrivilegeType.WRITE_PROJECT, "*");
projectDao.getAll()
.forEach(project -> grantUserPrivilege(user, PrivilegeType.WRITE_PROJECT, project.getProjectId()));
break;
default:
throw new IllegalArgumentException("The configuration element type '+" + type + "' is not handled.");
}
}
......@@ -250,4 +266,13 @@ public class UserService implements IUserService {
resetPasswordTokenDao.delete(resetToken);
}
@Override
public User getUserByLogin(String login, boolean loadLazy) {
User user = getUserByLogin(login);
if (loadLazy) {
Hibernate.initialize(user.getPrivileges());
}
return user;
}
}
package lcsb.mapviewer.services.interfaces;
import java.io.IOException;
import java.util.List;
import lcsb.mapviewer.model.Project;
......@@ -17,8 +16,6 @@ import lcsb.mapviewer.services.utils.EmailSender;
*/
public interface IProjectBackgroundService {
void removeProjectBackground(ProjectBackground background, String homeDir) throws IOException;
void updateProjectBackground(ProjectBackground background);
EmailSender getEmailSender();
......@@ -30,7 +27,7 @@ public interface IProjectBackgroundService {
List<ProjectBackground> getProjectBackgroundsByProject(String projectId);
ProjectBackground getProjectBackgroundById(Integer backgroundId);
ProjectBackground getProjectBackgroundById(String projectId, Integer backgroundId) throws ObjectNotFoundException;
List<ProjectBackground> getProjectBackgroundsByUser(User user);
......
......@@ -18,8 +18,9 @@ public interface IUserService {
void deleteUser(User user);
User getUserByLogin(String login);
User getUserByLogin(String login, boolean loadLazy);
List<User> getUsers();
List<User> getUsers(boolean loadLazy);
void grantUserPrivilege(User user, PrivilegeType type);
......
......@@ -40,7 +40,7 @@ public class SpringSecurityLdapIntegrationTest extends ControllerIntegrationTest
@Test
public void testInvalidLoginFromLdap() throws Exception {
int count = userService.getUsers().size();
int count = userService.getUsers(false).size();
RequestBuilder request = post("/api/doLogin")
.param("login", LdapServiceTestConfiguration.TEST_LOGIN)
......@@ -49,7 +49,7 @@ public class SpringSecurityLdapIntegrationTest extends ControllerIntegrationTest
.andExpect(status().is4xxClientError());
assertEquals("No users should be added to the system after failed login attempt",
count, userService.getUsers().size());
count, userService.getUsers(false).size());
}
@Test
......@@ -69,7 +69,7 @@ public class SpringSecurityLdapIntegrationTest extends ControllerIntegrationTest
@Test
public void testLoginCaseInsensitiveFromLdap() throws Exception {
int count = userService.getUsers().size();
int count = userService.getUsers(false).size();
RequestBuilder request = post("/api/doLogin")
.param("login", LdapServiceTestConfiguration.TEST_LOGIN)
......@@ -90,7 +90,7 @@ public class SpringSecurityLdapIntegrationTest extends ControllerIntegrationTest
.andExpect(status().is2xxSuccessful());
assertEquals("LDAP login is case insensitive and no new user should be added for different cases",
count + 1, userService.getUsers().size());
count + 1, userService.getUsers(false).size());
}
@Test
......
......@@ -783,7 +783,7 @@ public class UserControllerIntegrationTest extends ControllerIntegrationTest {
userColumListRequestParam(),
responseFields(fieldWithPath("[]")
.description("list of available input formats")
.type("array")).andWithPrefix("[].", getUserResponseFields())))
.type(JsonFieldType.ARRAY)).andWithPrefix("[].", getUserResponseFields())))
.andExpect(status().is2xxSuccessful());
}
......@@ -844,16 +844,16 @@ public class UserControllerIntegrationTest extends ControllerIntegrationTest {
fieldWithPath("privileges")
.description("list of user privileges")
.optional()
.type("array"),
.type(JsonFieldType.ARRAY),
fieldWithPath("privileges[].objectId")
.description("object id to which project has privilege")
.optional()
.type("string"),
.type(JsonFieldType.STRING),
fieldWithPath("privileges[].privilegeType")
.description(
"type of privilege, available values: " + projectSnippets.getOptionsAsString(PrivilegeType.class))
.optional()
.type("string"));
.type(JsonFieldType.STRING));
}
private List<ParameterDescriptor> getUserRequestFieldsWithoutLogin() {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment