688 lines
31 KiB
Java
Raw Normal View History

/*
2022-03-17 18:47:34 -03:00
* Copyright [2022] [wisemapping]
2020-11-07 11:56:38 -08:00
*
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
* It is basically the Apache License, Version 2.0 (the "License") plus the
* "powered by wisemapping" text requirement on every single page;
* you may not use this file except in compliance with the License.
* You may obtain a copy of the license at
*
* http://www.wisemapping.org/license
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
2012-02-12 21:57:11 -03:00
package com.wisemapping.rest;
import com.wisemapping.exceptions.*;
import com.wisemapping.model.*;
import com.wisemapping.rest.model.*;
import com.wisemapping.security.Utils;
import com.wisemapping.service.*;
import com.wisemapping.validator.MapInfoValidator;
2024-02-07 18:44:33 -08:00
import com.wisemapping.view.MindMapBean;
2024-01-15 07:59:04 -08:00
import jakarta.servlet.http.HttpServletResponse;
2022-02-14 19:59:36 -08:00
import org.apache.commons.validator.routines.EmailValidator;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
2012-06-09 22:49:54 -03:00
import org.springframework.beans.factory.annotation.Qualifier;
2022-04-11 17:50:19 -03:00
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
2022-03-23 10:56:57 -03:00
import org.springframework.http.ResponseEntity;
2023-07-28 22:46:38 -07:00
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.BeanPropertyBindingResult;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
2012-02-12 21:57:11 -03:00
import java.io.IOException;
2020-11-07 11:56:38 -08:00
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.stream.Collectors;
2012-02-12 21:57:11 -03:00
2023-11-27 21:08:28 -08:00
@RestController
2024-02-04 21:10:48 -08:00
@RequestMapping("/api/restful/maps")
public class MindmapController extends BaseController {
2023-11-22 16:50:56 -08:00
private final Logger logger = LogManager.getLogger();
2012-09-30 17:15:01 -03:00
2020-11-06 21:35:54 -08:00
private static final String LATEST_HISTORY_REVISION = "latest";
2012-09-30 17:15:01 -03:00
2012-06-09 22:49:54 -03:00
@Qualifier("mindmapService")
@Autowired
2012-02-12 21:57:11 -03:00
private MindmapService mindmapService;
@Qualifier("labelService")
@Autowired
private LabelService labelService;
@Qualifier("userService")
@Autowired
private UserService userService;
2024-02-19 00:28:05 -08:00
@Value("${app.accounts.max-inactive:20}")
2022-04-11 17:50:19 -03:00
private int maxAccountsInactive;
2023-11-22 16:50:56 -08:00
@PreAuthorize("isAuthenticated() and hasRole('ROLE_USER')")
2024-02-07 00:04:06 -08:00
@RequestMapping(method = RequestMethod.GET, value = "/{id}", produces = {"application/json"})
2012-02-12 21:57:11 -03:00
@ResponseBody
public RestMindmap retrieve(@PathVariable int id) throws WiseMappingException {
2024-02-17 11:18:43 -08:00
final Account user = Utils.getUser(true);
2013-03-29 21:09:28 -03:00
final Mindmap mindMap = findMindmapById(id);
return new RestMindmap(mindMap, user);
2012-02-12 21:57:11 -03:00
}
2024-03-25 22:45:21 -07:00
@PreAuthorize("permitAll()")
2024-02-07 00:04:06 -08:00
@RequestMapping(method = RequestMethod.GET, value = "/{id}/metadata", produces = {"application/json"})
@ResponseBody
2024-02-07 18:44:33 -08:00
public RestMindmapMetadata retrieveMetadata(@PathVariable int id) throws WiseMappingException {
2024-03-25 22:47:37 -07:00
final Account user = Utils.getUser(false);
2024-02-07 18:44:33 -08:00
final Mindmap mindmap = findMindmapById(id);
final MindMapBean mindMapBean = new MindMapBean(mindmap, user);
// Is the mindmap locked ?.
boolean isLocked = false;
final LockManager lockManager = this.mindmapService.getLockManager();
String lockFullName = null;
if (lockManager.isLocked(mindmap) && !lockManager.isLockedBy(mindmap, user)) {
final LockInfo lockInfo = lockManager.getLockInfo(mindmap);
isLocked = true;
lockFullName = lockInfo.getUser().getFullName();
}
2024-02-19 21:47:49 -08:00
return new RestMindmapMetadata(mindmap.getTitle(), mindMapBean.getProperties(), mindmap.getCreator().getFullName(), isLocked, lockFullName);
2024-02-07 00:04:06 -08:00
}
2023-11-22 16:50:56 -08:00
@PreAuthorize("isAuthenticated() and hasRole('ROLE_USER')")
2024-02-04 10:42:16 -08:00
@RequestMapping(method = RequestMethod.GET, value = "/", produces = {"application/json"})
public RestMindmapList retrieveList(@RequestParam(required = false) String q) {
2024-02-17 11:18:43 -08:00
final Account user = Utils.getUser(true);
final MindmapFilter filter = MindmapFilter.parse(q);
2022-01-18 13:16:39 -08:00
List<Mindmap> mindmaps = mindmapService.findMindmapsByUser(user);
mindmaps = mindmaps
.stream()
2023-08-10 23:18:59 -07:00
.filter(m -> filter.accept(m, user)).toList();
2012-05-23 21:54:03 -03:00
return new RestMindmapList(mindmaps, user);
}
2023-11-22 16:50:56 -08:00
@PreAuthorize("isAuthenticated() and hasRole('ROLE_USER')")
2024-02-04 10:42:16 -08:00
@RequestMapping(method = RequestMethod.GET, value = "/{id}/history/", produces = {"application/json"})
2022-01-27 19:06:51 -08:00
public RestMindmapHistoryList fetchHistory(@PathVariable int id) {
2012-06-17 19:16:39 -03:00
final List<MindMapHistory> histories = mindmapService.findMindmapHistory(id);
2012-06-17 02:51:01 -03:00
final RestMindmapHistoryList result = new RestMindmapHistoryList();
for (MindMapHistory history : histories) {
result.addHistory(new RestMindmapHistory(history));
2012-06-09 22:49:54 -03:00
}
return result;
}
2024-02-04 10:42:16 -08:00
@RequestMapping(method = RequestMethod.PUT, value = "/{id}/document", consumes = {"application/json"}, produces = {"application/json"})
2022-03-23 23:32:19 -03:00
@ResponseStatus(value = HttpStatus.NO_CONTENT)
2023-11-22 16:50:56 -08:00
@PreAuthorize("isAuthenticated() and hasRole('ROLE_USER')")
2022-03-23 23:32:19 -03:00
public void updateDocument(@RequestBody RestMindmap restMindmap, @PathVariable int id, @RequestParam(required = false) boolean minor) throws WiseMappingException, IOException {
2013-03-29 21:09:28 -03:00
final Mindmap mindmap = findMindmapById(id);
2024-02-17 11:18:43 -08:00
final Account user = Utils.getUser(true);
// Validate arguments ...
final String properties = restMindmap.getProperties();
if (properties == null) {
throw new IllegalArgumentException("Map properties can not be null");
}
2022-03-17 19:25:33 -03:00
// Have permissions ?
2022-03-22 08:35:47 -03:00
final LockManager lockManager = mindmapService.getLockManager();
2022-03-23 23:32:19 -03:00
lockManager.lock(mindmap, user);
2012-09-30 17:15:01 -03:00
// Update collaboration properties ...
final CollaborationProperties collaborationProperties = mindmap.findCollaborationProperties(user);
collaborationProperties.setMindmapProperties(properties);
// Validate content ...
final String xml = restMindmap.getXml();
mindmap.setXmlStr(xml);
// Update map ...
saveMindmapDocument(minor, mindmap, user);
}
2023-11-22 16:50:56 -08:00
@PreAuthorize("isAuthenticated() and hasRole('ROLE_USER')")
2024-02-04 10:42:16 -08:00
@RequestMapping(value = "/{id}/history/{hid}", method = RequestMethod.POST)
2023-11-22 16:50:56 -08:00
@ResponseStatus(value = HttpStatus.NO_CONTENT)
public void updateRevertMindmap(@PathVariable int id, @PathVariable String hid) throws WiseMappingException, IOException {
final Mindmap mindmap = findMindmapById(id);
2024-02-17 11:18:43 -08:00
final Account user = Utils.getUser(true);
2023-11-22 16:50:56 -08:00
if (LATEST_HISTORY_REVISION.equals(hid)) {
// Revert to the latest stored version ...
List<MindMapHistory> mindmapHistory = mindmapService.findMindmapHistory(id);
if (mindmapHistory.size() > 0) {
final MindMapHistory mindMapHistory = mindmapHistory.get(0);
mindmap.setZippedXml(mindMapHistory.getZippedXml());
saveMindmapDocument(true, mindmap, user);
}
} else {
mindmapService.revertChange(mindmap, Integer.parseInt(hid));
}
}
2023-08-10 23:18:59 -07:00
@PreAuthorize("permitAll()")
2024-02-04 10:42:16 -08:00
@RequestMapping(method = RequestMethod.GET, value = {"/{id}/document/xml", "/{id}/document/xml-pub"}, consumes = {"text/plain"}, produces = {"application/xml; charset=UTF-8"})
2013-01-31 22:50:21 -03:00
@ResponseBody
2013-02-03 12:51:12 -03:00
public byte[] retrieveDocument(@PathVariable int id, @NotNull HttpServletResponse response) throws WiseMappingException, IOException {
2013-03-29 21:09:28 -03:00
final Mindmap mindmap = findMindmapById(id);
String xmlStr = mindmap.getXmlStr();
2020-11-07 11:56:38 -08:00
return xmlStr.getBytes(StandardCharsets.UTF_8);
2013-01-31 22:50:21 -03:00
}
2023-11-22 16:50:56 -08:00
@PreAuthorize("isAuthenticated() and hasRole('ROLE_USER')")
2024-02-04 10:42:16 -08:00
@RequestMapping(method = RequestMethod.PUT, value = {"/{id}/document/xml"}, consumes = {"text/plain"})
2014-01-25 04:21:59 -03:00
@ResponseBody
2024-02-04 10:42:16 -08:00
public void updateDocument(@PathVariable int id, @RequestBody String xmlDoc) throws WiseMappingException {
2014-01-25 04:21:59 -03:00
final Mindmap mindmap = findMindmapById(id);
2024-02-17 11:18:43 -08:00
final Account user = Utils.getUser(true);
2014-01-25 04:21:59 -03:00
mindmap.setXmlStr(xmlDoc);
2022-01-18 13:16:39 -08:00
saveMindmapDocument(false, mindmap, user);
2014-01-25 04:21:59 -03:00
}
2023-11-22 16:50:56 -08:00
@PreAuthorize("isAuthenticated() and hasRole('ROLE_USER')")
2024-02-04 10:42:16 -08:00
@RequestMapping(method = RequestMethod.GET, value = {"/{id}/{hid}/document/xml"}, consumes = {"text/plain"}, produces = {"application/xml; charset=UTF-8"})
2013-02-13 22:46:45 -03:00
@ResponseBody
2013-03-31 15:33:00 -03:00
public byte[] retrieveDocument(@PathVariable int id, @PathVariable int hid, @NotNull HttpServletResponse response) throws WiseMappingException, IOException {
2013-02-13 22:46:45 -03:00
final MindMapHistory mindmapHistory = mindmapService.findMindmapHistory(id, hid);
2013-02-13 22:51:55 -03:00
return mindmapHistory.getUnzipXml();
2013-02-13 22:46:45 -03:00
}
2012-05-23 20:05:16 -03:00
/**
* The intention of this method is the update of several properties at once ...
*/
2023-11-22 16:50:56 -08:00
@PreAuthorize("isAuthenticated() and hasRole('ROLE_USER')")
2024-02-04 10:42:16 -08:00
@RequestMapping(method = RequestMethod.PUT, value = "/{id}", consumes = {"application/json"}, produces = {"application/json"})
2012-05-23 20:05:16 -03:00
@ResponseStatus(value = HttpStatus.NO_CONTENT)
public void updateProperties(@RequestBody RestMindmap restMindmap, @PathVariable int id, @RequestParam(required = false) boolean minor) throws IOException, WiseMappingException {
2012-05-23 20:05:16 -03:00
2013-03-29 21:09:28 -03:00
final Mindmap mindmap = findMindmapById(id);
2024-02-17 11:18:43 -08:00
final Account user = Utils.getUser(true);
2012-05-23 20:05:16 -03:00
final String xml = restMindmap.getXml();
2013-03-31 15:33:00 -03:00
if (xml != null && !xml.isEmpty()) {
mindmap.setXmlStr(xml);
2012-05-23 20:05:16 -03:00
}
// Update title ...
final String title = restMindmap.getTitle();
if (title != null && !title.equals(mindmap.getTitle())) {
2012-05-23 20:05:16 -03:00
if (mindmapService.getMindmapByTitle(title, user) != null) {
2024-02-10 13:53:44 -08:00
throw buildValidationException("You already have a map with this title");
2012-05-23 20:05:16 -03:00
}
mindmap.setTitle(title);
2012-05-23 20:05:16 -03:00
}
// Update description ...
final String description = restMindmap.getDescription();
if (description != null) {
mindmap.setDescription(description);
2012-05-23 20:05:16 -03:00
}
// Update document properties ...
final String properties = restMindmap.getProperties();
if (properties != null) {
final CollaborationProperties collaborationProperties = mindmap.findCollaborationProperties(user);
collaborationProperties.setMindmapProperties(properties);
2012-05-23 20:05:16 -03:00
}
// Update map ...
saveMindmapDocument(minor, mindmap, user);
2012-05-23 20:05:16 -03:00
}
2013-03-29 21:09:28 -03:00
@NotNull
private Mindmap findMindmapById(int id) throws MapCouldNotFoundException, AccessDeniedSecurityException {
// Has enough permissions ?
2024-02-17 11:18:43 -08:00
final Account user = Utils.getUser();
if (!mindmapService.hasPermissions(user, id, CollaborationRole.VIEWER)) {
throw new AccessDeniedSecurityException(id, user);
}
// Does the map exists ?
final Mindmap result = mindmapService.findMindmapById(id);
2013-03-31 15:33:00 -03:00
if (result == null) {
2013-03-29 21:09:28 -03:00
throw new MapCouldNotFoundException("Map could not be found. Id:" + id);
}
return result;
}
2023-11-22 16:50:56 -08:00
@PreAuthorize("isAuthenticated() and hasRole('ROLE_USER')")
2024-02-04 10:42:16 -08:00
@RequestMapping(method = RequestMethod.PUT, value = "/{id}/title", consumes = {"text/plain"}, produces = {"application/json"})
@ResponseStatus(value = HttpStatus.NO_CONTENT)
public void updateTitle(@RequestBody String title, @PathVariable int id) throws WiseMappingException {
2013-03-29 21:09:28 -03:00
final Mindmap mindMap = findMindmapById(id);
2024-02-17 11:18:43 -08:00
final Account user = Utils.getUser(true);
// Is there a map with the same name ?
if (mindmapService.getMindmapByTitle(title, user) != null) {
2024-02-10 13:53:44 -08:00
throw buildValidationException("You already have a mindmap with this title");
}
// Update map ...
2013-03-29 21:09:28 -03:00
final Mindmap mindmap = findMindmapById(id);
mindmap.setTitle(title);
2020-11-07 11:56:38 -08:00
mindmapService.updateMindmap(mindMap, false);
}
2023-11-22 16:50:56 -08:00
@PreAuthorize("isAuthenticated() and hasRole('ROLE_USER')")
2024-02-04 10:42:16 -08:00
@RequestMapping(method = RequestMethod.POST, value = "/{id}/collabs/", consumes = {"application/json"}, produces = {"application/json"})
2012-06-09 15:49:19 -03:00
@ResponseStatus(value = HttpStatus.NO_CONTENT)
public void updateCollabs(@PathVariable int id, @NotNull @RequestBody RestCollaborationList restCollabs) throws CollaborationException, MapCouldNotFoundException, AccessDeniedSecurityException, InvalidEmailException, TooManyInactiveAccountsExceptions {
2013-03-29 21:09:28 -03:00
final Mindmap mindMap = findMindmapById(id);
2012-06-12 11:23:47 -03:00
// Only owner can change collaborators...
2024-02-17 11:18:43 -08:00
final Account user = Utils.getUser();
2012-06-12 11:23:47 -03:00
if (!mindMap.hasPermissions(user, CollaborationRole.OWNER)) {
2012-06-09 22:49:54 -03:00
throw new IllegalArgumentException("No enough permissions");
}
// Do not allow more than 20 collabs not active
verifyActiveCollabs(restCollabs, user);
2012-06-09 22:49:54 -03:00
// Compare one by one if some of the elements has been changed ....
final Set<Collaboration> collabsToRemove = new HashSet<>(mindMap.getCollaborations());
2012-06-09 22:49:54 -03:00
for (RestCollaboration restCollab : restCollabs.getCollaborations()) {
2022-02-14 19:59:36 -08:00
final String email = restCollab.getEmail();
// Is a valid email address ?
if (!EmailValidator.getInstance().isValid(email)) {
2022-03-22 20:44:07 -03:00
throw new InvalidEmailException(email);
2022-02-14 19:59:36 -08:00
}
final Collaboration collaboration = mindMap.findCollaboration(email);
2012-06-09 22:55:55 -03:00
// Validate role format ...
String roleStr = restCollab.getRole();
if (roleStr == null) {
throw new IllegalArgumentException(roleStr + " is not a valid role");
}
2012-06-09 22:49:54 -03:00
2022-03-22 20:44:07 -03:00
// Remove from the list of pending to remove ...
if (collaboration != null) {
collabsToRemove.remove(collaboration);
}
2012-06-09 22:55:55 -03:00
// Is owner ?
final CollaborationRole role = CollaborationRole.valueOf(roleStr.toUpperCase());
if (role != CollaborationRole.OWNER) {
2012-06-16 11:37:40 -03:00
mindmapService.addCollaboration(mindMap, restCollab.getEmail(), role, restCollabs.getMessage());
2012-06-09 22:49:54 -03:00
}
}
// Remove all collaborations that no applies anymore ..
for (final Collaboration collaboration : collabsToRemove) {
2012-06-13 23:04:29 -03:00
mindmapService.removeCollaboration(mindMap, collaboration);
2012-06-09 22:49:54 -03:00
}
2012-06-09 15:49:19 -03:00
}
2023-11-22 16:50:56 -08:00
@PreAuthorize("isAuthenticated() and hasRole('ROLE_USER')")
2024-02-04 10:42:16 -08:00
@RequestMapping(method = RequestMethod.PUT, value = "/{id}/collabs/", consumes = {"application/json"}, produces = {"application/json"})
@ResponseStatus(value = HttpStatus.NO_CONTENT)
2022-10-21 18:37:33 -07:00
public void addCollab(@PathVariable int id, @NotNull @RequestBody RestCollaborationList restCollabs) throws CollaborationException, MapCouldNotFoundException, AccessDeniedSecurityException, InvalidEmailException, TooManyInactiveAccountsExceptions, OwnerCannotChangeException {
final Mindmap mindMap = findMindmapById(id);
// Only owner can change collaborators...
2024-02-17 11:18:43 -08:00
final Account user = Utils.getUser();
if (!mindMap.hasPermissions(user, CollaborationRole.OWNER)) {
2022-03-24 00:14:38 -03:00
throw new AccessDeniedSecurityException("User must be owner to share mindmap");
}
// Do not allow more than 20 collabs not active
verifyActiveCollabs(restCollabs, user);
2022-02-14 19:59:36 -08:00
// Is valid email address ?
final EmailValidator emailValidator = EmailValidator.getInstance();
2022-03-24 00:14:38 -03:00
final Set<String> invalidEmails = restCollabs
2022-02-14 19:59:36 -08:00
.getCollaborations()
2022-03-24 00:14:38 -03:00
.stream()
.map(RestCollaboration::getEmail)
.filter(e -> !emailValidator.isValid(e)).collect(Collectors.toSet());
if (!invalidEmails.isEmpty()) {
throw new InvalidEmailException(String.join(", ", invalidEmails));
}
2022-02-14 19:59:36 -08:00
// Has any role changed ?. Just removed it.
final Map<String, Collaboration> collabByEmail = mindMap
.getCollaborations()
.stream()
.collect(Collectors.toMap(collaboration -> collaboration.getCollaborator().getEmail(), collaboration -> collaboration));
// Great, let's add all the collabs again ...
for (RestCollaboration restCollab : restCollabs.getCollaborations()) {
// Validate newRole format ...
final String roleStr = restCollab.getRole();
if (roleStr == null) {
throw new IllegalArgumentException(roleStr + " is not a valid newRole");
}
// Had the newRole changed ?. Otherwise, don't touch it.
final CollaborationRole newRole = CollaborationRole.valueOf(roleStr.toUpperCase());
final String collabEmail = restCollab.getEmail();
final Collaboration currentCollab = collabByEmail.get(collabEmail);
if (currentCollab == null || currentCollab.getRole() != newRole) {
// Are we trying to change the owner ...
if (currentCollab != null && currentCollab.getRole() == CollaborationRole.OWNER) {
2022-10-21 18:37:33 -07:00
throw new OwnerCannotChangeException(collabEmail);
}
// Role can not be changed ...
if (newRole == CollaborationRole.OWNER) {
2022-10-21 18:37:33 -07:00
throw new OwnerCannotChangeException(collabEmail);
}
// This is collaboration that with different newRole, try to change it ...
if (currentCollab != null) {
mindmapService.removeCollaboration(mindMap, currentCollab);
}
mindmapService.addCollaboration(mindMap, collabEmail, newRole, restCollabs.getMessage());
}
}
}
2023-11-22 16:50:56 -08:00
@PreAuthorize("isAuthenticated() and hasRole('ROLE_USER')")
2024-02-04 10:42:16 -08:00
@RequestMapping(method = RequestMethod.GET, value = "/{id}/collabs", produces = {"application/json"})
2022-03-14 15:08:31 -03:00
public RestCollaborationList retrieveList(@PathVariable int id) throws MapCouldNotFoundException, AccessDeniedSecurityException {
2013-03-29 21:09:28 -03:00
final Mindmap mindMap = findMindmapById(id);
2012-06-09 15:49:19 -03:00
final Set<Collaboration> collaborations = mindMap.getCollaborations();
final List<RestCollaboration> collabs = new ArrayList<>();
2012-06-09 22:49:54 -03:00
for (Collaboration collaboration : collaborations) {
collabs.add(new RestCollaboration(collaboration));
}
final RestCollaborationList result = new RestCollaborationList();
result.setCollaborations(collabs);
2012-06-09 15:49:19 -03:00
return result;
2012-06-09 15:49:19 -03:00
}
2023-11-22 16:50:56 -08:00
@PreAuthorize("isAuthenticated() and hasRole('ROLE_USER')")
2024-02-04 10:42:16 -08:00
@RequestMapping(method = RequestMethod.PUT, value = "/{id}/description", consumes = {"text/plain"}, produces = {"application/json"})
@ResponseStatus(value = HttpStatus.NO_CONTENT)
public void updateDescription(@RequestBody String description, @PathVariable int id) throws WiseMappingException {
2013-03-29 21:09:28 -03:00
final Mindmap mindmap = findMindmapById(id);
mindmap.setDescription(description);
2022-03-14 15:08:31 -03:00
mindmapService.updateMindmap(mindmap, false);
}
2023-11-22 16:50:56 -08:00
@PreAuthorize("isAuthenticated() and hasRole('ROLE_USER')")
2024-02-04 10:42:16 -08:00
@RequestMapping(method = RequestMethod.PUT, value = "/{id}/publish", consumes = {"text/plain"}, produces = {"application/json"})
2012-05-20 21:46:55 -03:00
@ResponseStatus(value = HttpStatus.NO_CONTENT)
public void updatePublishState(@RequestBody String value, @PathVariable int id) throws WiseMappingException {
2012-05-20 21:46:55 -03:00
2013-03-29 21:09:28 -03:00
final Mindmap mindMap = findMindmapById(id);
2012-05-20 21:46:55 -03:00
2024-02-17 11:18:43 -08:00
final Account user = Utils.getUser();
if (!mindMap.hasPermissions(user, CollaborationRole.OWNER)) {
2012-05-20 21:46:55 -03:00
throw new IllegalArgumentException("No enough to execute this operation");
}
// Update map status ...
mindMap.setPublic(Boolean.parseBoolean(value));
2020-11-07 11:56:38 -08:00
mindmapService.updateMindmap(mindMap, false);
2012-05-20 21:46:55 -03:00
}
2012-03-15 01:21:46 -03:00
2023-11-22 16:50:56 -08:00
@PreAuthorize("isAuthenticated() and hasRole('ROLE_USER')")
2024-02-04 10:42:16 -08:00
@RequestMapping(method = RequestMethod.DELETE, value = "/{id}")
2012-09-30 17:15:01 -03:00
@ResponseStatus(value = HttpStatus.NO_CONTENT)
2024-02-04 10:42:16 -08:00
public void deleteMapById(@PathVariable int id) throws WiseMappingException {
2024-02-17 11:18:43 -08:00
final Account user = Utils.getUser();
2013-03-29 21:09:28 -03:00
final Mindmap mindmap = findMindmapById(id);
2012-09-30 17:15:01 -03:00
mindmapService.removeMindmap(mindmap, user);
}
2023-11-22 16:50:56 -08:00
@PreAuthorize("isAuthenticated() and hasRole('ROLE_USER')")
2024-02-04 10:42:16 -08:00
@RequestMapping(method = RequestMethod.DELETE, value = "/{id}/collabs")
@ResponseStatus(value = HttpStatus.NO_CONTENT)
2024-02-04 10:42:16 -08:00
public void deleteCollabByEmail(@PathVariable int id, @RequestParam(required = false) String email) throws WiseMappingException {
logger.debug("Deleting permission for email:" + email);
2022-02-14 19:59:36 -08:00
// Is a valid email address ?
final EmailValidator emailValidator = EmailValidator.getInstance();
if (!emailValidator.isValid(email)) {
2022-03-22 20:44:07 -03:00
throw new InvalidEmailException(email);
2022-02-14 19:59:36 -08:00
}
final Mindmap mindmap = findMindmapById(id);
2024-02-17 11:18:43 -08:00
final Account user = Utils.getUser();
// Only owner can change collaborators...
if (!mindmap.hasPermissions(user, CollaborationRole.OWNER)) {
throw new IllegalArgumentException("No enough permissions");
}
final Collaboration collab = mindmap.findCollaboration(email);
2022-01-18 13:16:39 -08:00
if (collab != null) {
CollaborationRole role = collab.getRole();
// Owner collab can not be removed ...
if (role == CollaborationRole.OWNER) {
throw new IllegalArgumentException("Can not remove owner collab");
}
mindmapService.removeCollaboration(mindmap, collab);
}
}
2023-11-22 16:50:56 -08:00
@PreAuthorize("isAuthenticated() and hasRole('ROLE_USER')")
2024-02-04 10:42:16 -08:00
@RequestMapping(method = RequestMethod.PUT, value = "/{id}/starred", consumes = {"text/plain"}, produces = {"application/json"})
@ResponseStatus(value = HttpStatus.NO_CONTENT)
public void updateStarredState(@RequestBody String value, @PathVariable int id) throws WiseMappingException {
logger.debug("Update starred:" + value);
2013-03-29 21:09:28 -03:00
final Mindmap mindmap = findMindmapById(id);
2024-02-17 11:18:43 -08:00
final Account user = Utils.getUser();
// Update map status ...
final boolean starred = Boolean.parseBoolean(value);
2022-01-18 13:16:39 -08:00
final Optional<Collaboration> collaboration = mindmap.findCollaboration(user);
2024-02-10 13:53:44 -08:00
if (collaboration.isEmpty()) {
throw new WiseMappingException("No enough permissions.");
}
2022-01-18 13:16:39 -08:00
collaboration.get().getCollaborationProperties().setStarred(starred);
mindmapService.updateCollaboration(user, collaboration.get());
}
2023-11-22 16:50:56 -08:00
@PreAuthorize("isAuthenticated() and hasRole('ROLE_USER')")
2024-02-04 10:42:16 -08:00
@RequestMapping(method = RequestMethod.GET, value = "/{id}/starred", produces = {"text/plain"})
2022-10-21 17:26:19 -07:00
@ResponseBody
public String fetchStarred(@PathVariable int id) throws WiseMappingException {
final Mindmap mindmap = findMindmapById(id);
2024-02-17 11:18:43 -08:00
final Account user = Utils.getUser();
2022-10-21 17:26:19 -07:00
final Optional<Collaboration> collaboration = mindmap.findCollaboration(user);
2024-02-10 13:53:44 -08:00
if (collaboration.isEmpty()) {
2022-10-21 17:26:19 -07:00
throw new WiseMappingException("No enough permissions.");
}
boolean result = collaboration.get().getCollaborationProperties().getStarred();
return Boolean.toString(result);
}
2023-11-22 16:50:56 -08:00
@PreAuthorize("isAuthenticated() and hasRole('ROLE_USER')")
2024-02-04 10:42:16 -08:00
@RequestMapping(method = RequestMethod.DELETE, value = "/batch")
2012-04-06 17:05:42 -03:00
@ResponseStatus(value = HttpStatus.NO_CONTENT)
2024-02-04 10:42:16 -08:00
public void batchDelete(@RequestParam() String ids) throws WiseMappingException {
2024-02-17 11:18:43 -08:00
final Account user = Utils.getUser();
final String[] mapsIds = ids.split(",");
2022-03-28 08:15:46 -03:00
try {
for (final String mapId : mapsIds) {
final Mindmap mindmap = findMindmapById(Integer.parseInt(mapId));
mindmapService.removeMindmap(mindmap, user);
}
} catch (Exception e) {
final AccessDeniedSecurityException accessDenied = new AccessDeniedSecurityException("Map could not be deleted. Maps to be deleted:" + ids);
accessDenied.initCause(e);
throw accessDenied;
2012-04-06 17:05:42 -03:00
}
}
2022-02-14 19:59:36 -08:00
2023-11-22 16:50:56 -08:00
@PreAuthorize("isAuthenticated() and hasRole('ROLE_USER')")
2024-02-04 10:42:16 -08:00
@RequestMapping(method = RequestMethod.POST, value = "", consumes = {"application/xml", "application/json"})
@ResponseStatus(value = HttpStatus.CREATED)
2024-02-04 10:42:16 -08:00
public void createMap(@RequestBody(required = false) String mapXml, @NotNull HttpServletResponse response, @RequestParam(required = false) String title, @RequestParam(required = false) String description) throws WiseMappingException {
2012-06-06 00:48:46 -03:00
2022-02-09 19:13:09 -08:00
final Mindmap mindmap = new Mindmap();
2012-06-06 00:48:46 -03:00
if (title != null && !title.isEmpty()) {
2022-02-09 19:13:09 -08:00
mindmap.setTitle(title);
2012-06-06 00:48:46 -03:00
}
2022-02-09 16:49:48 -08:00
2022-02-09 19:13:09 -08:00
if (description != null && !description.isEmpty()) {
mindmap.setDescription(description);
}
// Validate ...
2022-02-09 19:13:09 -08:00
final BindingResult result = new BeanPropertyBindingResult(mindmap, "");
new MapInfoValidator(mindmapService).validate(mindmap, result);
if (result.hasErrors()) {
throw new ValidationException(result);
}
// If the user has not specified the xml content, add one ...
2022-02-09 19:13:09 -08:00
if (mapXml == null || mapXml.isEmpty()) {
mapXml = Mindmap.getDefaultMindmapXml(mindmap.getTitle());
}
2022-02-09 19:13:09 -08:00
mindmap.setXmlStr(mapXml);
// Add new mindmap ...
2024-02-17 11:18:43 -08:00
final Account user = Utils.getUser(true);
2022-02-09 19:13:09 -08:00
mindmapService.addMindmap(mindmap, user);
// Return the new created map ...
2024-02-04 21:10:48 -08:00
response.setHeader("Location", "/api/restful/maps/" + mindmap.getId());
2022-02-09 19:13:09 -08:00
response.setHeader("ResourceId", Integer.toString(mindmap.getId()));
}
2023-11-22 16:50:56 -08:00
@PreAuthorize("isAuthenticated() and hasRole('ROLE_USER')")
2024-02-04 10:42:16 -08:00
@RequestMapping(method = RequestMethod.POST, value = "/{id}", consumes = {"application/json"}, produces = {"application/json", "text/plain"})
2012-03-15 21:13:47 -03:00
@ResponseStatus(value = HttpStatus.CREATED)
2024-02-04 10:42:16 -08:00
public void createDuplicate(@RequestBody RestMindmapInfo restMindmap, @PathVariable int id, @NotNull HttpServletResponse response) throws WiseMappingException {
2012-05-20 21:46:55 -03:00
// Validate ...
2012-04-07 20:05:50 -03:00
final BindingResult result = new BeanPropertyBindingResult(restMindmap, "");
new MapInfoValidator(mindmapService).validate(restMindmap.getDelegated(), result);
if (result.hasErrors()) {
throw new ValidationException(result);
2012-03-15 21:13:47 -03:00
}
// Some basic validations ...
2024-02-17 11:18:43 -08:00
final Account user = Utils.getUser();
2012-03-15 21:13:47 -03:00
// Create a shallowCopy of the map ...
2013-03-29 21:09:28 -03:00
final Mindmap mindMap = findMindmapById(id);
final Mindmap clonedMap = mindMap.shallowClone();
2012-03-15 21:13:47 -03:00
clonedMap.setTitle(restMindmap.getTitle());
clonedMap.setDescription(restMindmap.getDescription());
// Add new mindmap ...
mindmapService.addMindmap(clonedMap, user);
// Return the new created map ...
2024-02-04 21:10:48 -08:00
response.setHeader("Location", "/api/restful/maps/" + clonedMap.getId());
response.setHeader("ResourceId", Integer.toString(clonedMap.getId()));
2012-03-15 21:13:47 -03:00
}
2012-06-06 00:48:46 -03:00
2022-01-18 13:16:39 -08:00
2023-11-22 16:50:56 -08:00
@PreAuthorize("isAuthenticated() and hasRole('ROLE_USER')")
2024-02-04 10:42:16 -08:00
@RequestMapping(method = RequestMethod.DELETE, value = "/{id}/labels/{lid}")
@ResponseStatus(value = HttpStatus.NO_CONTENT)
2022-02-09 14:17:28 -08:00
public void removeLabelFromMap(@PathVariable int id, @PathVariable int lid) throws WiseMappingException {
2024-02-17 11:18:43 -08:00
final Account user = Utils.getUser();
final Mindmap mindmap = findMindmapById(id);
2024-02-17 11:18:43 -08:00
final MindmapLabel label = labelService.findLabelById(lid, user);
2022-01-18 13:16:39 -08:00
if (label == null) {
throw new LabelCouldNotFoundException("Label could not be found. Id: " + lid);
}
mindmap.removeLabel(label);
2022-02-09 16:49:48 -08:00
mindmapService.updateMindmap(mindmap, false);
}
2023-11-22 16:50:56 -08:00
@PreAuthorize("isAuthenticated() and hasRole('ROLE_USER')")
2024-02-04 10:42:16 -08:00
@RequestMapping(method = RequestMethod.POST, value = "/{id}/labels", consumes = {"application/json"})
2014-02-05 21:44:30 -03:00
@ResponseStatus(value = HttpStatus.OK)
2022-01-18 13:16:39 -08:00
public void updateLabel(@PathVariable int id, @RequestBody int lid) throws WiseMappingException {
2024-02-17 11:18:43 -08:00
final Account user = Utils.getUser();
final MindmapLabel label = labelService.findLabelById(lid, user);
2022-01-18 13:16:39 -08:00
if (label == null) {
throw new LabelCouldNotFoundException("Label could not be found. Id: " + lid);
}
2022-01-18 13:16:39 -08:00
final Mindmap mindmap = findMindmapById(id);
mindmap.addLabel(label);
2022-02-09 16:49:48 -08:00
mindmapService.updateMindmap(mindmap, false);
2022-01-18 13:16:39 -08:00
}
2022-03-17 19:25:33 -03:00
2023-11-22 16:50:56 -08:00
@PreAuthorize("isAuthenticated() and hasRole('ROLE_USER')")
2024-02-04 10:42:16 -08:00
@RequestMapping(method = RequestMethod.PUT, value = "/{id}/lock", consumes = {"text/plain"}, produces = {"application/json"})
2022-03-23 23:32:19 -03:00
public ResponseEntity<RestLockInfo> lockMindmap(@RequestBody String value, @PathVariable int id) throws WiseMappingException {
2024-02-17 11:18:43 -08:00
final Account user = Utils.getUser();
2022-03-23 23:32:19 -03:00
final LockManager lockManager = mindmapService.getLockManager();
final Mindmap mindmap = findMindmapById(id);
2022-03-17 19:25:33 -03:00
2022-03-23 23:32:19 -03:00
ResponseEntity<RestLockInfo> result = new ResponseEntity<>(null, HttpStatus.NO_CONTENT);
if (Boolean.parseBoolean(value)) {
final LockInfo lockInfo = lockManager.lock(mindmap, user);
final RestLockInfo restLockInfo = new RestLockInfo(lockInfo, user);
result = new ResponseEntity<>(restLockInfo, HttpStatus.OK);
} else {
lockManager.unlock(mindmap, user);
}
return result;
}
2023-11-22 16:50:56 -08:00
2024-02-17 11:18:43 -08:00
private void saveMindmapDocument(boolean minor, @NotNull final Mindmap mindMap, @NotNull final Account user) throws WiseMappingException {
2023-11-22 16:50:56 -08:00
final Calendar now = Calendar.getInstance();
mindMap.setLastModificationTime(now);
mindMap.setLastEditor(user);
mindmapService.updateMindmap(mindMap, !minor);
}
2024-02-10 13:53:44 -08:00
private ValidationException buildValidationException(@NotNull String message) throws WiseMappingException {
2023-11-22 16:50:56 -08:00
final BindingResult result = new BeanPropertyBindingResult(new RestMindmap(), "");
2024-02-10 13:53:44 -08:00
result.rejectValue("title", "error.not-specified", null, message);
2023-11-22 16:50:56 -08:00
return new ValidationException(result);
}
2024-02-17 11:18:43 -08:00
private void verifyActiveCollabs(@NotNull RestCollaborationList restCollabs, Account user) throws TooManyInactiveAccountsExceptions {
// Do not allow more than 20 new accounts per mindmap...
final List<Mindmap> userMindmaps = mindmapService.findMindmapsByUser(user);
final Set<String> allEmails = userMindmaps
.stream()
.filter(m -> m.hasPermissions(user, CollaborationRole.OWNER))
.map(Mindmap::getCollaborations)
.flatMap(Collection::stream)
.map(c -> c.getCollaborator().getEmail())
.collect(Collectors.toSet());
allEmails.addAll(restCollabs
.getCollaborations().stream()
.map(RestCollaboration::getEmail)
.collect(Collectors.toSet()));
long inactiveAccounts = allEmails.stream().filter(e -> userService.getUserBy(e) == null).count();
2022-04-11 17:50:19 -03:00
if (inactiveAccounts > maxAccountsInactive) {
throw new TooManyInactiveAccountsExceptions(inactiveAccounts);
}
}
2012-02-12 21:57:11 -03:00
}