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

grant/revoke privilege for project

parent b25bdb73
......@@ -63,12 +63,27 @@ public abstract class BaseController {
return new ResponseEntity<Object>(new Gson().toJson(response), httpHeaders, status);
}
public Map parseBody(String body) throws IOException {
if (body == null || body.isEmpty()) {
return new TreeMap<>();
public Map parseBody(String body) throws QueryException {
try {
if (body == null || body.isEmpty()) {
return new TreeMap<>();
}
ObjectNode result = mapper.readValue(body, ObjectNode.class);
return mapper.convertValue(result, Map.class);
} catch (IOException e) {
throw new QueryException("Cannot parse body", e);
}
}
public Map[] extractListBody(String body) throws QueryException {
try {
if (body == null || body.isEmpty()) {
return new Map[0];
}
return mapper.readValue(body, Map[].class);
} catch (IOException e) {
throw new QueryException("Cannot parse body", e);
}
ObjectNode result = mapper.readValue(body, ObjectNode.class);
return mapper.convertValue(result, Map.class);
}
protected Map getData(Map<String, Object> node, String objectName) {
......
......@@ -6,7 +6,6 @@ import java.util.Map;
import javax.servlet.ServletContext;
import lcsb.mapviewer.model.security.Privilege;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
......@@ -48,20 +47,38 @@ public class ProjectController extends BaseController {
@PatchMapping(value = "/{projectId:.+}")
public Map<String, Object> updateProject(
@RequestBody String body,
@PathVariable(value = "projectId") String projectId
) throws IOException, QueryException {
@PathVariable(value = "projectId") String projectId) throws IOException, QueryException {
Map<String, Object> node = parseBody(body);
Map<String, Object> data = getData(node, "project");
return projectController.updateProject(projectId, data);
}
@PreAuthorize("hasAuthority('IS_ADMIN') "
+ "or (hasAuthority('IS_CURATOR') and hasAuthority('WRITE_PROJECT:' + #projectId))")
@PatchMapping(value = "/{projectId:.+}:grantPrivileges")
public Map<String, Object> grantPrivileges(
@RequestBody String body,
@PathVariable(value = "projectId") String projectId) throws IOException, QueryException {
Map[] data = extractListBody(body);
return projectController.grantPrivilegesProject(projectId, data);
}
@PreAuthorize("hasAuthority('IS_ADMIN') "
+ "or (hasAuthority('IS_CURATOR') and hasAuthority('WRITE_PROJECT:' + #projectId))")
@PatchMapping(value = "/{projectId:.+}:revokePrivileges")
public Map<String, Object> revokePrivileges(
@RequestBody String body,
@PathVariable(value = "projectId") String projectId) throws IOException, QueryException {
Map[] data = extractListBody(body);
return projectController.revokePrivilegesProject(projectId, data);
}
@PreAuthorize("hasAnyAuthority('IS_ADMIN', 'IS_CURATOR')")
@PostMapping(value = "/{projectId:.+}")
public Map<String, Object> addProject(
Authentication authentication,
@RequestBody MultiValueMap<String, Object> formData,
@PathVariable(value = "projectId") String projectId
) throws IOException, QueryException, SecurityException {
@PathVariable(value = "projectId") String projectId) throws IOException, QueryException, SecurityException {
if (projectId.equals("*")) {
throw new QueryException("No.");
}
......@@ -127,8 +144,7 @@ public class ProjectController extends BaseController {
@RequestParam(value = "length", defaultValue = "10") Integer length,
@RequestParam(value = "sortColumn", defaultValue = "id") String sortColumn,
@RequestParam(value = "sortOrder", defaultValue = "asc") String sortOrder,
@RequestParam(value = "search", defaultValue = "") String search
) throws QueryException {
@RequestParam(value = "search", defaultValue = "") String search) throws QueryException {
return projectController.getLogs(projectId, level, start, length, sortColumn, sortOrder, search);
}
......
......@@ -30,11 +30,13 @@ import lcsb.mapviewer.model.map.model.Model;
import lcsb.mapviewer.model.map.model.SubmodelType;
import lcsb.mapviewer.model.map.reaction.Reaction;
import lcsb.mapviewer.model.map.species.Element;
import lcsb.mapviewer.model.security.PrivilegeType;
import lcsb.mapviewer.model.user.ConfigurationElementType;
import lcsb.mapviewer.model.user.User;
import lcsb.mapviewer.persist.dao.ProjectDao;
import lcsb.mapviewer.persist.dao.cache.UploadedFileEntryDao;
import lcsb.mapviewer.services.interfaces.IProjectService;
import lcsb.mapviewer.services.interfaces.IUserService;
import lcsb.mapviewer.services.utils.CreateProjectParams;
@Transactional
......@@ -49,6 +51,7 @@ public class ProjectRestImpl extends BaseRestImpl {
private PublicationsRestImpl publicationsRestImpl;
private IProjectService projectService;
private IUserService userService;
private MeSHParser meshParser;
......@@ -60,11 +63,13 @@ public class ProjectRestImpl extends BaseRestImpl {
IProjectService projectService,
ProjectDao projectDao,
UploadedFileEntryDao uploadedFileEntryDao,
IUserService userService,
MeSHParser meshParser) {
this.publicationsRestImpl = publicationsRestImpl;
this.projectService = projectService;
this.projectDao = projectDao;
this.meshParser = meshParser;
this.userService = userService;
this.uploadedFileEntryDao = uploadedFileEntryDao;
}
......@@ -673,4 +678,47 @@ public class ProjectRestImpl extends BaseRestImpl {
return result;
}
public Map<String, Object> grantPrivilegesProject(String projectId, Map[] data) throws QueryException {
for (Map m : data) {
PrivilegeType privilege = getPrivilegeType(m);
User user = getUser(m);
userService.grantUserPrivilege(user, privilege, projectId);
}
return null;
}
private User getUser(Map m) throws QueryException {
if (!(m.get("login") instanceof String)) {
throw new QueryException("Invalid login: " + m.get("login"));
}
String login = (String) m.get("login");
User result = userService.getUserByLogin(login);
if (result == null) {
throw new ObjectNotFoundException("User doesn't exist: " + login);
}
return result;
}
public Map<String, Object> revokePrivilegesProject(String projectId, Map[] data) throws QueryException {
for (Map m : data) {
PrivilegeType privilege = getPrivilegeType(m);
User user = getUser(m);
userService.revokeUserPrivilege(user, privilege, projectId);
}
return null;
}
private PrivilegeType getPrivilegeType(Map m) throws QueryException {
if (!(m.get("privilegeType") instanceof String)) {
throw new QueryException("Invalid privilegeType: " + m.get("privilegeType"));
}
String type = (String) m.get("privilegeType");
try {
PrivilegeType result = PrivilegeType.valueOf(type);
return result;
} catch (Exception e) {
throw new QueryException("Invalid privilegeType: " + type, e);
}
}
}
......@@ -20,6 +20,7 @@ import org.springframework.transaction.annotation.Transactional;
import com.google.gson.JsonParser;
import lcsb.mapviewer.model.Project;
import lcsb.mapviewer.model.security.Privilege;
import lcsb.mapviewer.model.security.PrivilegeType;
import lcsb.mapviewer.model.user.User;
import lcsb.mapviewer.persist.dao.ProjectDao;
......@@ -136,4 +137,49 @@ public class ProjectControllerIntegrationTest extends ControllerIntegrationTest
.andExpect(status().is2xxSuccessful());
}
@Test
public void testGrantPrivilege() throws Exception {
Project project = new Project(TEST_PROJECT);
projectDao.add(project);
MockHttpSession session = createSession(ADMIN_LOGIN, ADMIN_PASSWORD);
String body = "[{"
+ "\"privilegeType\":\"" + PrivilegeType.READ_PROJECT + "\", "
+ "\"login\":\"" + CURATOR_LOGIN + "\""
+ "}]";
RequestBuilder request = patch("/projects/" + TEST_PROJECT + ":grantPrivileges")
.content(body)
.session(session);
mockMvc.perform(request)
.andExpect(status().is2xxSuccessful());
assertTrue(curator.getPrivileges().contains(new Privilege(PrivilegeType.READ_PROJECT, TEST_PROJECT)));
}
@Test
public void testRevokePrivilege() throws Exception {
Project project = new Project(TEST_PROJECT);
projectDao.add(project);
userService.grantUserPrivilege(curator, PrivilegeType.READ_PROJECT, project.getProjectId());
MockHttpSession session = createSession(ADMIN_LOGIN, ADMIN_PASSWORD);
String body = "[{"
+ "\"privilegeType\":\"" + PrivilegeType.READ_PROJECT + "\", "
+ "\"login\":\"" + CURATOR_LOGIN + "\""
+ "}]";
RequestBuilder request = patch("/projects/" + TEST_PROJECT + ":revokePrivileges")
.content(body)
.session(session);
mockMvc.perform(request)
.andExpect(status().is2xxSuccessful());
assertFalse(curator.getPrivileges().contains(new Privilege(PrivilegeType.READ_PROJECT, TEST_PROJECT)));
}
}
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