package eu.dnetlib.uoamonitorservice.controllers; import eu.dnetlib.uoaadmintoolslibrary.handlers.utils.RolesUtils; import eu.dnetlib.uoamonitorservice.dao.*; import eu.dnetlib.uoamonitorservice.entities.*; import eu.dnetlib.uoamonitorservice.handlers.EntityNotFoundException; import eu.dnetlib.uoaadmintoolslibrary.handlers.ForbiddenException; import eu.dnetlib.uoamonitorservice.handlers.PathNotValidException; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.*; import java.util.ArrayList; import java.util.Date; import java.util.Iterator; import java.util.List; @RestController @CrossOrigin(origins = "*") public class TopicController { private final Logger log = LogManager.getLogger(this.getClass()); @Autowired private RolesUtils rolesUtils; @Autowired private StakeholderDAO stakeholderDAO; @Autowired private TopicDAO topicDAO; @Autowired private CategoryController categoryController; @Autowired private CategoryDAO categoryDAO; public Topic buildTopic(Topic topicFull) { Topic topic = new Topic<>(topicFull); List categories = new ArrayList<>(); List categoriesFull = new ArrayList<>(); for(Category category : topicFull.getCategories()) { Category categoryFull = categoryController.buildCategory(category); categoriesFull.add(categoryFull); categories.add(categoryFull.getId()); } topicFull.setCategories(categoriesFull); topic.setCategories(categories); Date date = new Date(); topic.setCreationDate(date); topic.setUpdateDate(date); topicFull.setCreationDate(date); topicFull.setUpdateDate(date); topicDAO.save(topic); topicFull.setId(topic.getId()); return topicFull; } @PreAuthorize("isAuthenticated()") @RequestMapping(value = "/{stakeholderId}/save", method = RequestMethod.POST) public Topic saveTopic(@PathVariable("stakeholderId") String stakeholderId, @RequestBody Topic topicFull) { log.debug("save topic"); log.debug("Alias: "+topicFull.getAlias() + " - Id: "+topicFull.getId()+ " - Stakeholder: "+stakeholderId); Stakeholder stakeholder = stakeholderDAO.findById(stakeholderId); if(stakeholder != null) { if(!rolesUtils.hasUpdateAuthority(stakeholder.getType(), stakeholder.getAlias())) { // EXCEPTION - Access denied throw new ForbiddenException("Save Topic: You are not authorized to update stakeholder with id: "+stakeholderId); } Topic topic = new Topic<>(topicFull); Date date = new Date(); topic.setUpdateDate(date); topicFull.setUpdateDate(date); List categories = new ArrayList<>(); Topic oldTopic = null; if(topicFull.getId() != null) { oldTopic = topicDAO.findById(topicFull.getId()); if(oldTopic == null) { // EXCEPTION - Topic not found throw new EntityNotFoundException("save topic: Topic with id: "+topicFull.getId()+" not found"); } for(String categoryId : oldTopic.getCategories()) { Category category = categoryDAO.findById(categoryId); if (category == null) { // EXCEPTION - Category not found throw new EntityNotFoundException("Save topic: Category with id: "+categoryId+" not found (category exists in topic: "+topic.getId()+")"); } categories.add(category.getId()); } } else { // topic does not exist in DB topic.setCreationDate(date); topicFull.setCreationDate(date); for(Category category : topicFull.getCategories()) { categories.add(category.getId()); } } topic.setCategories(categories); if(stakeholder.getDefaultId() == null) { if(topicFull.getId() == null) { topicDAO.save(topic); onSaveDefaultTopic(topic, stakeholderId); } else { onUpdateDefaultTopic(topic, oldTopic); topicDAO.save(topic); } } else { topicDAO.save(topic); } List topics = stakeholder.getTopics(); int index = topics.indexOf(topic.getId()); if(index == -1) { topics.add(topic.getId()); stakeholderDAO.save(stakeholder); log.debug("Topic saved!"); topicFull.setId(topic.getId()); } } else { // EXCEPTION - Stakeholder not found throw new EntityNotFoundException("Save topic: Stakeholder with id: "+stakeholderId+" not found"); } return topicFull; } public void onSaveDefaultTopic(Topic topic, String stakeholderId) { log.debug("On save default topic"); List stakeholders = stakeholderDAO.findByDefaultId(stakeholderId); for(Stakeholder _stakeholder : stakeholders) { Topic topicNew = new Topic(); topicNew.copyFromDefault(topic); topicDAO.save(topicNew); List topics = _stakeholder.getTopics(); topics.add(topicNew.getId()); stakeholderDAO.save(_stakeholder); } } public void onUpdateDefaultTopic(Topic topic, Topic oldTopic) { log.debug("On update default topic"); List topics = topicDAO.findByDefaultId(topic.getId()); boolean changed = false; for(Topic topicBasedOnDefault : topics) { if(topic.getName() != null && !topic.getName().equals(topicBasedOnDefault.getName()) && (oldTopic.getName() == null || oldTopic.getName().equals(topicBasedOnDefault.getName()))) { topicBasedOnDefault.setName(topic.getName()); topicBasedOnDefault.setAlias(topic.getAlias()); changed = true; } if(topic.getDescription() != null && !topic.getDescription().equals(topicBasedOnDefault.getDescription()) && (oldTopic.getDescription() == null || oldTopic.getDescription().equals(topicBasedOnDefault.getDescription()))) { topicBasedOnDefault.setDescription(topic.getDescription()); changed = true; } if(topic.getIcon() != null && !topic.getIcon().equals(topicBasedOnDefault.getIcon()) && (oldTopic.getIcon() == null || oldTopic.getIcon().equals(topicBasedOnDefault.getIcon()))) { topicBasedOnDefault.setIcon(topic.getIcon()); changed = true; } if(!changed) { continue; } topicBasedOnDefault.setUpdateDate(topic.getUpdateDate()); topicDAO.save(topicBasedOnDefault); } } @PreAuthorize("isAuthenticated()") @RequestMapping(value = "/{stakeholderId}/{topicId}/delete", method = RequestMethod.DELETE) public boolean deleteTopic(@PathVariable("stakeholderId") String stakeholderId, @PathVariable("topicId") String topicId, @RequestParam(required = false) String children) { log.debug("delete topic"); log.debug("Id: "+topicId + " - Stakeholder: "+stakeholderId); Stakeholder stakeholder = stakeholderDAO.findById(stakeholderId); if(stakeholder != null) { if(!rolesUtils.hasUpdateAuthority(stakeholder.getType(), stakeholder.getAlias())) { // EXCEPTION - Access denied throw new ForbiddenException("Delete topic: You are not authorized to update stakeholder with id: "+stakeholderId); } Topic topic = topicDAO.findById(topicId); if(topic != null) { if(topic.getDefaultId() != null && !rolesUtils.hasCreateAndDeleteAuthority(stakeholder.getType())) { // EXCEPTION - Access denied throw new ForbiddenException("Delete topic: You are not authorized to delete a default Topic in stakeholder with id: "+stakeholderId); } List topics = stakeholder.getTopics(); int index = topics.indexOf(topicId); if(index != -1) { // this topic belongs in default profile if(stakeholder.getDefaultId() == null && children != null) { onDeleteDefaultTopic(topicId, stakeholderId, children); } categoryController.deleteTree(topic); topic.setCategories(null); topics.remove(index); stakeholderDAO.save(stakeholder); topicDAO.delete(topicId); log.debug("Topic deleted!"); } else { // EXCEPTION - Topic not found in Stakeholder: stakeholder.getAlias(); throw new PathNotValidException("Delete topic: Topic with id: "+topicId+" not found in Stakeholder: "+stakeholderId); } } else { // EXCEPTION - Topic not found throw new EntityNotFoundException("Delete topic: Topic with id: "+topicId+" not found"); } } else { // EXCEPTION - Stakeholder not found throw new EntityNotFoundException("Delete topic: Stakeholder with id: "+stakeholderId+" not found"); } return true; } public boolean onDeleteDefaultTopic(String defaultTopicId, String defaultStakeholderId, String children) { if(children.equals("delete")) { List stakeholders = stakeholderDAO.findByDefaultId(defaultStakeholderId); List topics = topicDAO.findByDefaultId(defaultTopicId); for(Stakeholder stakeholder : stakeholders) { Iterator topicsIterator = topics.iterator(); while(topicsIterator.hasNext()) { Topic topic = topicsIterator.next(); String topicId = topic.getId(); if(stakeholder.getTopics() != null && stakeholder.getTopics().contains(topicId)) { topicsIterator.remove(); stakeholder.getTopics().remove(topicId); stakeholderDAO.save(stakeholder); categoryController.deleteTree(topic); topicDAO.delete(topicId); log.debug("Topic with id: "+topicId+" deleted!"); break; } } } } else if(children.equals("disconnect")) { List topics = topicDAO.findByDefaultId(defaultTopicId); for(Topic topic : topics) { categoryController.disConnectTree(topic); topic.setDefaultId(null); topicDAO.save(topic); log.debug("DefaultId for Topic with id: "+topic.getId()+" cleared!"); } } return true; } @PreAuthorize("isAuthenticated()") @RequestMapping(value = "/{stakeholderId}/reorder", method = RequestMethod.POST) public List reorderTopics(@PathVariable("stakeholderId") String stakeholderId, @RequestBody List topics) { log.debug("reorder topics"); log.debug("Stakeholder: "+stakeholderId); Stakeholder stakeholder = stakeholderDAO.findById(stakeholderId); if(stakeholder != null) { if(!rolesUtils.hasUpdateAuthority(stakeholder.getType(), stakeholder.getAlias())) { // EXCEPTION - Access denied throw new ForbiddenException("Reorder topics: You are not authorized to update stakeholder with id: "+stakeholderId); } List oldTopics = stakeholder.getTopics(); for (String topicId : oldTopics) { if (!topics.contains(topicId)) { topics.add(topicId); } } stakeholder.setTopics(topics); List topicsFull = new ArrayList<>(); for (String topicId : topics) { Topic topic = topicDAO.findById(topicId); if(topic == null) { // EXCEPTION - Topic not found throw new EntityNotFoundException("Reorder Topics: Topic with id: " + topicId + " not found"); } topicsFull.add(topic); } stakeholderDAO.save(stakeholder); log.debug("Topics reordered!"); return topicsFull; } else { // EXCEPTION - Stakeholder not found throw new EntityNotFoundException("Reorder topics: Stakeholder with id: "+stakeholderId+" not found"); } } @PreAuthorize("isAuthenticated()") @RequestMapping(value = "/{stakeholderId}/{topicId}/change-visibility", method = RequestMethod.POST) public Topic changeTopicVisibility(@PathVariable("stakeholderId") String stakeholderId, @PathVariable("topicId") String topicId, @RequestParam("visibility") Visibility visibility, @RequestParam(required = false) Boolean propagate) { log.debug("change topic visibility: "+visibility + " - toggle propagate: "+((propagate != null && propagate) ? "true" : "false")); log.debug("Stakeholder: "+stakeholderId + " - Topic: "+topicId); Stakeholder stakeholder = stakeholderDAO.findById(stakeholderId); if (stakeholder != null) { if(!rolesUtils.hasUpdateAuthority(stakeholder.getType(), stakeholder.getAlias())) { // EXCEPTION - Access denied throw new ForbiddenException("Toggle topic: You are not authorized to update stakeholder with id: "+stakeholderId); } if (stakeholder.getTopics().contains(topicId)) { return changeVisibilityTree(topicId, visibility, propagate); } else { // EXCEPTION - Topic not found in Stakeholder: stakeholder.getAlias(); throw new PathNotValidException("Toggle topic: Topic with id: "+topicId+" not found in Stakeholder: "+stakeholderId); } } else { // EXCEPTION - Stakeholder not found throw new EntityNotFoundException("Toggle topic: Stakeholder with id: "+stakeholderId+" not found"); } } public Topic changeVisibilityTree(String topicId, Visibility visibility, Boolean propagate) { Topic topic = topicDAO.findById(topicId); if (topic == null) { // EXCEPTION - Topic not found throw new EntityNotFoundException("Change topic visibility: Topic with id: "+topicId+" not found"); } Topic topicFull = new Topic(topic); List categoriesFull = new ArrayList<>(); if(propagate != null && propagate) { for (String categoryId : topic.getCategories()) { categoriesFull.add(categoryController.changeVisibilityTree(categoryId, visibility, propagate)); } } topic.setVisibility(visibility); topicDAO.save(topic); log.debug("Topic toggled!"); topicFull.setVisibility(visibility); topicFull.setCategories(categoriesFull); return topicFull; } public void deleteTree(Stakeholder stakeholder) { List topics = stakeholder.getTopics(); for(String topicId : topics) { Topic topic = topicDAO.findById(topicId); if (topic == null) { // EXCEPTION - Topic not found throw new EntityNotFoundException("Topic delete tree: Topic with id: "+topicId+" not found (topic exists in stakeholder: "+stakeholder.getId()+")"); } categoryController.deleteTree(topic); topicDAO.delete(topicId); } } }