diff --git a/src/main/java/org/wise/portal/domain/authentication/impl/BatchStudentChangePasswordParameters.java b/src/main/java/org/wise/portal/domain/authentication/impl/BatchStudentChangePasswordParameters.java index 11742000a..f6c99c06d 100644 --- a/src/main/java/org/wise/portal/domain/authentication/impl/BatchStudentChangePasswordParameters.java +++ b/src/main/java/org/wise/portal/domain/authentication/impl/BatchStudentChangePasswordParameters.java @@ -36,4 +36,8 @@ public class BatchStudentChangePasswordParameters extends ChangePasswordParamete @Getter @Setter private Long groupId; + + @Getter + @Setter + private Long runId; } diff --git a/src/main/java/org/wise/portal/presentation/web/controllers/teacher/management/BatchStudentChangePasswordController.java b/src/main/java/org/wise/portal/presentation/web/controllers/teacher/management/BatchStudentChangePasswordController.java index 82fa15bbb..603bae4d2 100644 --- a/src/main/java/org/wise/portal/presentation/web/controllers/teacher/management/BatchStudentChangePasswordController.java +++ b/src/main/java/org/wise/portal/presentation/web/controllers/teacher/management/BatchStudentChangePasswordController.java @@ -89,12 +89,14 @@ public class BatchStudentChangePasswordController { @RequestMapping(method = RequestMethod.GET) public String initializeForm(ModelMap model, HttpServletRequest request) throws Exception { User user = ControllerUtil.getSignedInUser(); - Run run = runService.retrieveById(Long.parseLong(request.getParameter("runId"))); + Long runId = Long.parseLong(request.getParameter("runId")); + Run run = runService.retrieveById(runId); if (user.isAdmin() || aclService.hasPermission(run, BasePermission.ADMINISTRATION, user) || aclService.hasPermission(run, BasePermission.WRITE, user)) { BatchStudentChangePasswordParameters params = new BatchStudentChangePasswordParameters(); + params.setRunId(runId); params.setGroupId(Long.parseLong(request.getParameter(GROUPID_PARAM_NAME))); params.setTeacherUser(user); model.addAttribute("batchStudentChangePasswordParameters", params); @@ -116,7 +118,7 @@ public String initializeForm(ModelMap model, HttpServletRequest request) throws protected String onSubmit( @ModelAttribute("batchStudentChangePasswordParameters") BatchStudentChangePasswordParameters batchStudentChangePasswordParameters, BindingResult bindingResult, - SessionStatus sessionStatus) { + SessionStatus sessionStatus) throws NotAuthorizedException { String view = ""; try { changePasswordParametersValidator.validate(batchStudentChangePasswordParameters, bindingResult); @@ -125,6 +127,7 @@ protected String onSubmit( view = formView; } else { Long groupId = batchStudentChangePasswordParameters.getGroupId(); + assertCanChangeGroupPasswords(batchStudentChangePasswordParameters.getRunId(), groupId); Group group = groupService.retrieveById(groupId); Iterator membersIter = group.getMembers().iterator(); User member; @@ -143,4 +146,27 @@ protected String onSubmit( } return view; } + + /** + * Verify that the signed-in teacher may change the passwords of the students in the + * given group. The teacher must own the run and the group must be one of that run's + * periods, so a teacher cannot reset the passwords of another teacher's students by + * submitting a group id that belongs to a run they do not own. + */ + private void assertCanChangeGroupPasswords(Long runId, Long groupId) + throws ObjectNotFoundException, NotAuthorizedException { + if (runId == null || groupId == null) { + throw new NotAuthorizedException("You are not authorized to change these passwords."); + } + User teacher = ControllerUtil.getSignedInUser(); + Run run = runService.retrieveById(runId); + boolean canManageRun = teacher.isAdmin() + || aclService.hasPermission(run, BasePermission.ADMINISTRATION, teacher) + || aclService.hasPermission(run, BasePermission.WRITE, teacher); + boolean groupBelongsToRun = run.getPeriods().stream() + .anyMatch(period -> groupId.equals(period.getId())); + if (!canManageRun || !groupBelongsToRun) { + throw new NotAuthorizedException("You are not authorized to change these passwords."); + } + } }