/**
   * Check if the user is in the workgroup id
   *
   * @param user the user
   * @param workgroupId the workgroup id
   * @return whether the user is in the workgroup
   */
  private boolean isUserInWorkgroupId(User user, Long workgroupId) {
    boolean result = false;

    if (user != null && workgroupId != null) {
      // get all the workgroups this user is in
      List<Workgroup> workgroupsForUser = workgroupService.getWorkgroupsForUser(user);

      Iterator<Workgroup> workgroupsForUserIterator = workgroupsForUser.iterator();

      // loop through all the workgroups this user is in
      while (workgroupsForUserIterator.hasNext()) {
        // get a workgroup
        Workgroup tempWorkgroup = workgroupsForUserIterator.next();

        if (tempWorkgroup != null) {
          // get the workgroup id
          Long tempWorkgroupId = tempWorkgroup.getId();

          // check if the workgroup id matches the one we are searching for
          if (workgroupId.equals(tempWorkgroupId)) {
            // the workgroup id matches so the user is in the workgroup
            result = true;
            break;
          }
        }
      }
    }

    return result;
  }
  private boolean authorize(HttpServletRequest request) {
    String method = request.getMethod();
    User signedInUser = ControllerUtil.getSignedInUser();
    Collection<? extends GrantedAuthority> authorities =
        signedInUser.getUserDetails().getAuthorities();
    Long signedInUserId = null;
    for (GrantedAuthority authority : authorities) {
      if (authority.getAuthority().equals(UserDetailsService.ADMIN_ROLE)) {
        return true;
      } else if (authority.getAuthority().equals(UserDetailsService.TEACHER_ROLE)) {
        // the signed in user is a teacher

        String type = request.getParameter("type");
        if ("cRater".equals(type)) {
          // any teacher can make a cRater request
          return true;
        }

        Run run = null;
        try {
          // get the run object
          run = runService.retrieveById(new Long(request.getParameter("runId")));
        } catch (NumberFormatException e) {
          e.printStackTrace();
        } catch (ObjectNotFoundException e) {
          e.printStackTrace();
        }

        if (run == null) {
          // we could not find the run
          return false;
        } else if (this.runService.hasRunPermission(run, signedInUser, BasePermission.WRITE)) {
          // the teacher has write permission for the run so we will allow authorization
          return true;
        } else if (this.runService.hasRunPermission(run, signedInUser, BasePermission.READ)) {
          // the teacher only has read permission for the run

          if (method.equals("GET")) {
            // we will allow authorization for GET requests
            return true;
          } else if (method.equals("POST")) {
            // we will deny authorization for POST requests since the teacher only has READ
            // permissions
            return false;
          }
        }
      }
    }
    if (method.equals("GET")) {
      String workgroupIdStr = "";

      // only used for annotations
      String fromWorkgroupIdStr = "";

      String type = request.getParameter("type");

      String runIdString = request.getParameter("runId");
      Long runId = null;

      if (runIdString != null) {
        runId = Long.parseLong(runIdString);
      }

      String periodString = request.getParameter("periodId");
      Long period = null;
      if (periodString != null) {
        period = Long.parseLong(periodString);
      }

      if (runId != null) {
        try {
          // get the run
          Run offering = runService.retrieveById(runId);

          // get the workgroup for the signed in user
          List<Workgroup> workgroupListByOfferingAndUser =
              workgroupService.getWorkgroupListByOfferingAndUser(offering, signedInUser);

          // get the workgroup
          Workgroup workgroup = workgroupListByOfferingAndUser.get(0);

          // get the workgroup id
          signedInUserId = workgroup.getId();
        } catch (ObjectNotFoundException e1) {
          e1.printStackTrace();
        }
      }

      // whether this GET request can access other workgroup's data
      boolean canAccessOtherWorkgroups = false;

      if (type == null) {
        workgroupIdStr = request.getParameter("userId");
      } else if (type.equals("flag") || type.equals("inappropriateFlag")) {
        workgroupIdStr = request.getParameter("userId");
        canAccessOtherWorkgroups = true;
      } else if (type.equals("annotation")) {
        String annotationType = request.getParameter("annotationType");
        if ("cRater".equals(annotationType)) {
          // anyone can make a cRater annotation
          return true;
        }
        workgroupIdStr = request.getParameter("toWorkgroup");

        // get the fromWorkgroup id
        fromWorkgroupIdStr = request.getParameter("fromWorkgroup");
        canAccessOtherWorkgroups = true;
      } else if (type.equals("brainstorm")) {
        workgroupIdStr = request.getParameter("userId");
        canAccessOtherWorkgroups = true;
      } else if (type.equals("aggregate")) {
        // student/teacher is trying to get other students' work so that it can be used to show
        // the aggregate view. nodeIds should be passed in.
        // Check that the nodeIds exist and that we can get the student data from them
        // in the VLE.
        if (request.getParameter("nodeIds") == null) {
          canAccessOtherWorkgroups = false;
        } else {
          if (request.getParameter("allStudents") != null
              && Boolean.valueOf(request.getParameter("allStudents"))) {
            return true;
          } else {
            workgroupIdStr = request.getParameter("userId");
            canAccessOtherWorkgroups = true;
          }
        }
      } else if (type.equals("journal")) {
        workgroupIdStr = request.getParameter("workgroupId");
      } else if (type.equals("peerreview")) {
        // return true for now until logic is implemented
        return true;
      } else if (type.equals("xlsexport") || type.equals("specialExport")) {
        // TODO: need to check user permissions
        return true;
      } else if (type.equals("ideaBasket")) {
        return true;
      } else if (type.equals("studentAssetManager")) {
        return true;
      } else if (type.equals("xmppAuthenticate")) {
        return true;
      } else if (type.equals("cRater")) {
        // allow students to make cRater scoring requests
        String cRaterRequestType = request.getParameter("cRaterRequestType");
        if ("scoring".equals(cRaterRequestType)) {
          return true;
        }
      } else if (type.equals("runStatus")) {
        // check if the user is the owner of the run or in the run
        if (isUserOwnerOfRun(signedInUser, runId) || isUserInRun(signedInUser, runId)) {
          return true;
        }
      } else {
        // this should never happen
      }

      if (workgroupIdStr == null || workgroupIdStr.equals("")) {
        return false;
      }
      // split up all the workgroup ids
      String[] workgroupIds = workgroupIdStr.split(":");

      // check if this GET request can access other workgroups
      if (canAccessOtherWorkgroups) {
        // this GET request is allowed to access other workgroup work
        try {
          if (fromWorkgroupIdStr != null
              && !fromWorkgroupIdStr.equals("")
              && fromWorkgroupIdStr.equals(signedInUserId)) {
            /*
             * the signed in user id is the same as the from workgroup id so
             * we will allow it. this basically means the current user is
             * requesting the annotations that he/she wrote.
             */
            return true;
          } else {
            // obtain all the workgroups of the classmates of the current user
            Set<Workgroup> classmateWorkgroups = runService.getWorkgroups(runId, period);

            /*
             * see if the workgroupIds the user is trying to access is
             * in the above set of classmate workgroups, if all the
             * workgroupIds beingaccessed are allowed, it will return
             * true and allow it, otherwise it will return false and
             * deny access
             */
            return elementsInCollection(workgroupIds, classmateWorkgroups);
          }
        } catch (ObjectNotFoundException e) {
          e.printStackTrace();
        }
      } else {
        /*
         * this GET request is not allowed to access other workgroup work
         * it can only access the workgroup the current user is in
         */

        // obtain all the workgroups that the current user is in
        List<Workgroup> workgroupsForUser = workgroupService.getWorkgroupsForUser(signedInUser);

        /*
         * see if the workgroupIds the user is trying to access is in
         * the above list of workgroups, if all the workgroupIds being
         * accessed are allowed, it will return true and allow it,
         * otherwise it will return false and deny access
         */
        return elementsInCollection(workgroupIds, workgroupsForUser);
      }

      return false;
    } else if (method.equals("POST")) {
      return true;
    }
    // other request methods are not authorized at this point
    return false;
  }