Index: lams_central/src/java/org/lamsfoundation/lams/web/qb/QbCollectionController.java =================================================================== diff -u -r03d284a4bdb2a2f2d6f57d0810e465f437c25155 -r3cae79ba78db6b0e9282a3135bbda429181a6546 --- lams_central/src/java/org/lamsfoundation/lams/web/qb/QbCollectionController.java (.../QbCollectionController.java) (revision 03d284a4bdb2a2f2d6f57d0810e465f437c25155) +++ lams_central/src/java/org/lamsfoundation/lams/web/qb/QbCollectionController.java (.../QbCollectionController.java) (revision 3cae79ba78db6b0e9282a3135bbda429181a6546) @@ -22,6 +22,7 @@ package org.lamsfoundation.lams.web.qb; +import java.io.IOException; import java.util.Collection; import java.util.List; import java.util.Map; @@ -88,7 +89,12 @@ } @RequestMapping("/showOne") - public String showOneCollection(@RequestParam long collectionUid, Model model) throws Exception { + public String showOneCollection(@RequestParam long collectionUid, Model model, HttpServletResponse response) + throws Exception { + if (!hasUserAccessToCollection(collectionUid)) { + response.sendError(HttpServletResponse.SC_FORBIDDEN, "The user does not have access to given collection"); + return null; + } model.addAttribute("collection", qbService.getCollection(collectionUid)); int userId = getUserId(); model.addAttribute("userId", userId); @@ -101,7 +107,11 @@ @RequestMapping(path = "/getCollectionGridData") @ResponseBody public String getCollectionGridData(@RequestParam long collectionUid, @RequestParam String view, - HttpServletRequest request, HttpServletResponse response) { + HttpServletRequest request, HttpServletResponse response) throws IOException { + if (!hasUserAccessToCollection(collectionUid)) { + response.sendError(HttpServletResponse.SC_FORBIDDEN, "The user does not have access to given collection"); + return null; + } response.setContentType("application/xml;charset=UTF-8"); int page = WebUtil.readIntParam(request, CommonConstants.PARAM_PAGE); @@ -130,78 +140,25 @@ return toGridXML(questions, 1, 1, questions.size(), view); } - private String toGridXML(List questions, int page, int maxPages, int totalCount, String view) { - try { - Document document = WebUtil.getDocument(); - - // root element - Element rootElement = document.createElement(CommonConstants.ELEMENT_ROWS); - - Element pageElement = document.createElement(CommonConstants.ELEMENT_PAGE); - pageElement.appendChild(document.createTextNode(String.valueOf(page))); - rootElement.appendChild(pageElement); - - Element totalPageElement = document.createElement(CommonConstants.ELEMENT_TOTAL); - totalPageElement.appendChild(document.createTextNode(String.valueOf(maxPages))); - rootElement.appendChild(totalPageElement); - - Element recordsElement = document.createElement(CommonConstants.ELEMENT_RECORDS); - recordsElement.appendChild(document.createTextNode(String.valueOf(totalCount))); - rootElement.appendChild(recordsElement); - - for (QbQuestion question : questions) { - String uid = question.getUid().toString(); - Element rowElement = document.createElement(CommonConstants.ELEMENT_ROW); - rowElement.setAttribute(CommonConstants.ELEMENT_ID, uid); - - // the last cell is for creating stats button - String usage = !view.equalsIgnoreCase("list") ? String.valueOf( - view.equalsIgnoreCase("version") ? qbService.getCountQuestionActivitiesByUid(question.getUid()) - : qbService.getCountQuestionActivitiesByQuestionId(question.getQuestionId())) - : null; - boolean hasVersions = qbService.countQuestionVersions(question.getQuestionId()) > 1; - String learningOutcomes = view.equalsIgnoreCase("single") - ? outcomeService.getOutcomeMappings(null, null, null, question.getQuestionId()).stream() - .map(m -> m.getOutcome().getName()).collect(Collectors.joining("
")) - : null; - - String[] data = { question.getQuestionId().toString(), - WebUtil.removeHTMLtags(question.getName()).trim(), - view.equalsIgnoreCase("version") ? null : question.getType().toString(), - question.getVersion().toString(), learningOutcomes, usage, uid, String.valueOf(hasVersions) }; - - for (String cell : data) { - Element cellElement = document.createElement(CommonConstants.ELEMENT_CELL); - if (cell == null) { - cell = ""; - } - cellElement.appendChild(document.createTextNode(cell)); - rowElement.appendChild(cellElement); - } - rootElement.appendChild(rowElement); - } - - document.appendChild(rootElement); - - return WebUtil.getStringFromDocument(document); - - } catch (Exception e) { - log.error("Error while generating Question Bank collection jqGrid XML data", e); - } - - return null; - } - @RequestMapping(path = "/removeCollectionQuestion", method = RequestMethod.POST) @ResponseBody - public void removeCollectionQuestion(@RequestParam long collectionUid, @RequestParam int qbQuestionId) { + public void removeCollectionQuestion(@RequestParam long collectionUid, @RequestParam int qbQuestionId, + HttpServletResponse response) throws IOException { + if (!hasUserAccessToCollection(collectionUid)) { + response.sendError(HttpServletResponse.SC_FORBIDDEN, "The user does not have access to given collection"); + return; + } qbService.removeQuestionFromCollectionByQuestionId(collectionUid, qbQuestionId, true); } @RequestMapping(path = "/removeCollectionQuestions", method = RequestMethod.POST) @ResponseBody - public String removeCollectionQuestionS(@RequestParam long collectionUid, - @RequestParam("qbQuestionIds[]") int[] qbQuestionIds) { + public String removeCollectionQuestions(@RequestParam long collectionUid, + @RequestParam("qbQuestionIds[]") int[] qbQuestionIds, HttpServletResponse response) throws IOException { + if (!hasUserAccessToCollection(collectionUid)) { + response.sendError(HttpServletResponse.SC_FORBIDDEN, "The user does not have access to given collection"); + return null; + } boolean allQuestionsRemoved = true; for (int qbQuestionId : qbQuestionIds) { allQuestionsRemoved &= qbService.removeQuestionFromCollectionByQuestionId(collectionUid, qbQuestionId, @@ -214,10 +171,14 @@ @RequestMapping(path = "/addCollectionQuestion", method = RequestMethod.POST) @ResponseBody public void addCollectionQuestion(@RequestParam long targetCollectionUid, @RequestParam boolean copy, - @RequestParam int qbQuestionId) { + @RequestParam int qbQuestionId, HttpServletResponse response) throws IOException { if (!Configuration.getAsBoolean(ConfigurationKeys.QB_COLLECTIONS_TRANSFER_ALLOW)) { throw new SecurityException("Transfering questions between collections is disabled"); } + if (!hasUserAccessToCollection(targetCollectionUid)) { + response.sendError(HttpServletResponse.SC_FORBIDDEN, "The user does not have access to given collection"); + return; + } qbService.addQuestionToCollection(targetCollectionUid, qbQuestionId, copy); } @@ -233,7 +194,11 @@ @RequestMapping(path = "/changeCollectionName", method = RequestMethod.POST) @ResponseBody public String changeCollectionName(@RequestParam(name = "pk") long collectionUid, - @RequestParam(name = "value") String name) { + @RequestParam(name = "value") String name, HttpServletResponse response) throws IOException { + if (!hasUserAccessToCollection(collectionUid)) { + response.sendError(HttpServletResponse.SC_FORBIDDEN, "The user does not have access to given collection"); + return null; + } Collection collections = qbService.getUserCollections(getUserId()); name = name.trim(); for (QbCollection collection : collections) { @@ -253,25 +218,110 @@ @RequestMapping(path = "/removeCollection", method = RequestMethod.POST) @ResponseBody - public void removeCollection(@RequestParam long collectionUid) { + public void removeCollection(@RequestParam long collectionUid, HttpServletResponse response) throws IOException { + if (!hasUserAccessToCollection(collectionUid)) { + response.sendError(HttpServletResponse.SC_FORBIDDEN, "The user does not have access to given collection"); + return; + } qbService.removeCollection(collectionUid); } @RequestMapping(path = "/shareCollection", method = RequestMethod.POST) @ResponseBody - public void shareCollection(@RequestParam long collectionUid, @RequestParam int organisationId) { + public void shareCollection(@RequestParam long collectionUid, @RequestParam int organisationId, + HttpServletResponse response) throws IOException { + if (!hasUserAccessToCollection(collectionUid)) { + response.sendError(HttpServletResponse.SC_FORBIDDEN, "The user does not have access to given collection"); + return; + } qbService.shareCollection(collectionUid, organisationId); } @RequestMapping(path = "/unshareCollection", method = RequestMethod.POST) @ResponseBody - public void unshareCollection(@RequestParam long collectionUid, @RequestParam int organisationId) { + public void unshareCollection(@RequestParam long collectionUid, @RequestParam int organisationId, + HttpServletResponse response) throws IOException { + if (!hasUserAccessToCollection(collectionUid)) { + response.sendError(HttpServletResponse.SC_FORBIDDEN, "The user does not have access to given collection"); + return; + } qbService.unshareCollection(collectionUid, organisationId); } + private String toGridXML(List questions, int page, int maxPages, int totalCount, String view) { + try { + Document document = WebUtil.getDocument(); + + // root element + Element rootElement = document.createElement(CommonConstants.ELEMENT_ROWS); + + Element pageElement = document.createElement(CommonConstants.ELEMENT_PAGE); + pageElement.appendChild(document.createTextNode(String.valueOf(page))); + rootElement.appendChild(pageElement); + + Element totalPageElement = document.createElement(CommonConstants.ELEMENT_TOTAL); + totalPageElement.appendChild(document.createTextNode(String.valueOf(maxPages))); + rootElement.appendChild(totalPageElement); + + Element recordsElement = document.createElement(CommonConstants.ELEMENT_RECORDS); + recordsElement.appendChild(document.createTextNode(String.valueOf(totalCount))); + rootElement.appendChild(recordsElement); + + for (QbQuestion question : questions) { + String uid = question.getUid().toString(); + Element rowElement = document.createElement(CommonConstants.ELEMENT_ROW); + rowElement.setAttribute(CommonConstants.ELEMENT_ID, uid); + + // the last cell is for creating stats button + String usage = !view.equalsIgnoreCase("list") ? String.valueOf( + view.equalsIgnoreCase("version") ? qbService.getCountQuestionActivitiesByUid(question.getUid()) + : qbService.getCountQuestionActivitiesByQuestionId(question.getQuestionId())) + : null; + boolean hasVersions = qbService.countQuestionVersions(question.getQuestionId()) > 1; + String learningOutcomes = view.equalsIgnoreCase("single") + ? outcomeService.getOutcomeMappings(null, null, null, question.getQuestionId()).stream() + .map(m -> m.getOutcome().getName()).collect(Collectors.joining("
")) + : null; + + String[] data = { question.getQuestionId().toString(), + WebUtil.removeHTMLtags(question.getName()).trim(), + view.equalsIgnoreCase("version") ? null : question.getType().toString(), + question.getVersion().toString(), learningOutcomes, usage, uid, String.valueOf(hasVersions) }; + + for (String cell : data) { + Element cellElement = document.createElement(CommonConstants.ELEMENT_CELL); + if (cell == null) { + cell = ""; + } + cellElement.appendChild(document.createTextNode(cell)); + rowElement.appendChild(cellElement); + } + rootElement.appendChild(rowElement); + } + + document.appendChild(rootElement); + + return WebUtil.getStringFromDocument(document); + + } catch (Exception e) { + log.error("Error while generating Question Bank collection jqGrid XML data", e); + } + + return null; + } + private Integer getUserId() { HttpSession ss = SessionManager.getSession(); UserDTO user = (UserDTO) ss.getAttribute(AttributeNames.USER); return user != null ? user.getUserID() : null; } + + private boolean hasUserAccessToCollection(long collectionUid) { + Integer userId = getUserId(); + if (userId == null) { + return false; + } + Collection collections = qbService.getUserCollections(userId); + return collections.stream().map(QbCollection::getUid).anyMatch(uid -> uid.equals(collectionUid)); + } } \ No newline at end of file Index: lams_central/web/WEB-INF/web.xml =================================================================== diff -u -rb098c386af442a5029a53edc1416b19f11a646ce -r3cae79ba78db6b0e9282a3135bbda429181a6546 --- lams_central/web/WEB-INF/web.xml (.../web.xml) (revision b098c386af442a5029a53edc1416b19f11a646ce) +++ lams_central/web/WEB-INF/web.xml (.../web.xml) (revision 3cae79ba78db6b0e9282a3135bbda429181a6546) @@ -699,9 +699,11 @@ - Add lesson + Monitor access /addLesson.jsp /lti/addLesson.jsp + /qb/collection/* + /qb/stats/* GET POST