Example #1
0
 def post(self, request):
     """
     Unenrolls the specified user from all courses.
     """
     try:
         # Get the username from the request.
         username = request.data['username']
         # Ensure that a retirement request status row exists for this username.
         UserRetirementStatus.get_retirement_for_retirement_action(username)
         enrollments = api.get_enrollments(username)
         active_enrollments = [
             enrollment for enrollment in enrollments
             if enrollment['is_active']
         ]
         if len(active_enrollments) < 1:
             return Response(status=status.HTTP_204_NO_CONTENT)
         return Response(api.unenroll_user_from_all_courses(username))
     except KeyError:
         return Response(u'Username not specified.',
                         status=status.HTTP_404_NOT_FOUND)
     except UserRetirementStatus.DoesNotExist:
         return Response(u'No retirement request status for username.',
                         status=status.HTTP_404_NOT_FOUND)
     except Exception as exc:  # pylint: disable=broad-except
         return Response(text_type(exc),
                         status=status.HTTP_500_INTERNAL_SERVER_ERROR)
Example #2
0
    def get(self, request, username_or_email):
        """
        Returns a list of enrollments for the given user, along with
        information about previous manual enrollment changes.
        """
        try:
            user = User.objects.get(Q(username=username_or_email) | Q(email=username_or_email))
        except User.DoesNotExist:
            return JsonResponse([])

        enrollments = get_enrollments(user.username, include_inactive=True)

        for enrollment in enrollments:
            # Folds the course_details field up into the main JSON object.
            enrollment.update(**enrollment.pop('course_details'))
            course_key = CourseKey.from_string(enrollment['course_id'])
            # Get the all courses modes and replace with existing modes.
            enrollment['course_modes'] = self.get_course_modes(course_key)
            # Add the price of the course's verified mode.
            self.include_verified_mode_info(enrollment, course_key)
            # Add manual enrollment history, if it exists
            enrollment['manual_enrollment'] = self.manual_enrollment_data(enrollment, course_key)

        if enterprise_enabled():
            enterprise_enrollments_by_course_id = self._enterprise_course_enrollments_by_course_id(user)
            for enrollment in enrollments:
                enterprise_course_enrollments = enterprise_enrollments_by_course_id.get(enrollment['course_id'], [])
                enrollment['enterprise_course_enrollments'] = enterprise_course_enrollments

        return JsonResponse(enrollments)
Example #3
0
def is_user_enrolled_in_program_type(user, program_type_slug, paid_modes_only=False, enrollments=None, entitlements=None):  # lint-amnesty, pylint: disable=line-too-long
    """
    This method will look at the learners Enrollments and Entitlements to determine
    if a learner is enrolled in a Program of the given type.

    NOTE: This method relies on the Program Cache right now. The goal is to move away from this
    in the future.

    Arguments:
        user (User): The user we are looking for.
        program_type_slug (str): The slug of the Program type we are looking for.
        paid_modes_only (bool): Request if the user is enrolled in a Program in a paid mode, False by default.
        enrollments (List[Dict]): Takes a serialized list of CourseEnrollments linked to the user
        entitlements (List[CourseEntitlement]): Take a list of CourseEntitlement objects linked to the user

        NOTE: Both enrollments and entitlements will be collected if they are not passed in. They are available
        as parameters in case they were already collected, to save duplicate queries in high traffic areas.

    Returns:
        bool: True is the user is enrolled in programs of the requested type
    """
    course_runs = set()
    course_uuids = set()
    programs = get_programs_by_type(Site.objects.get_current(),
                                    program_type_slug)
    if not programs:
        return False

    for program in programs:
        for course in program.get('courses', []):
            course_uuids.add(course.get('uuid'))
            for course_run in course.get('course_runs', []):
                course_runs.add(course_run['key'])

    # Check Entitlements first, because there will be less Course Entitlements than
    # Course Run Enrollments.
    student_entitlements = entitlements if entitlements is not None else get_active_entitlement_list_for_user(
        user)
    for entitlement in student_entitlements:
        if str(entitlement.course_uuid) in course_uuids:
            return True

    student_enrollments = enrollments if enrollments is not None else get_enrollments(
        user.username)
    for enrollment in student_enrollments:
        course_run_id = enrollment['course_details']['course_id']
        if paid_modes_only:
            course_run_key = CourseKey.from_string(course_run_id)
            paid_modes = [
                mode.slug for mode in get_paid_modes_for_course(course_run_key)
            ]
            if enrollment[
                    'mode'] in paid_modes and course_run_id in course_runs:
                return True
        elif course_run_id in course_runs:
            return True
    return False
Example #4
0
def is_user_enrolled_in_program_type(user,
                                     program_type,
                                     paid_modes=False,
                                     enrollments=None,
                                     entitlements=None):
    """
    This method will Look at the learners Enrollments and Entitlements to determine
    if a learner is enrolled in a Program of the given type.

    NOTE: This method relies on the Program Cache right now. The goal is to move away from this
    in the future.

    Arguments:
        user (User): The user we are looking for.
        program_type (String): The Program type we are looking for.
        paid_modes (bool): Request if the user is enrolled in a Program in a paid mode, False by default.

    Returns:
        bool: True is the user is enrolled in programs of the requested Type
    """
    course_runs = set()
    course_uuids = set()
    programs = get_programs_by_type(Site.objects.get_current(), program_type)
    if not programs:
        return False

    for program in programs:
        for course in program.get('courses', []):
            course_uuids.add(course.get('uuid'))
            for course_run in course.get('course_runs', []):
                course_runs.add(course_run['key'])

    # Check Entitlements first, because there will be less Course Entitlements than
    # Course Run Enrollments.
    student_entitlements = entitlements if entitlements is not None else get_active_entitlement_list_for_user(
        user)
    for entitlement in student_entitlements:
        if str(entitlement.course_uuid) in course_uuids:
            return True

    student_enrollments = enrollments if enrollments is not None else get_enrollments(
        user.username)
    for enrollment in student_enrollments:
        course_run_id = enrollment['course_details']['course_id']
        if paid_modes:
            course_run_key = CourseKey.from_string(course_run_id)
            paid_modes = [
                mode.slug
                for mode in CourseMode.paid_modes_for_course(course_run_key)
            ]
            if enrollment[
                    'mode'] in paid_modes and course_run_id in course_runs:
                return True
        elif course_run_id in course_runs:
            return True
    return False
Example #5
0
 def test_get_all_enrollments(self, enrollments):
     for enrollment in enrollments:
         fake_data_api.add_course(enrollment['course_id'], course_modes=enrollment['course_modes'])
         api.add_enrollment(self.USERNAME, enrollment['course_id'], enrollment['mode'])
     result = api.get_enrollments(self.USERNAME)
     self.assertEqual(len(enrollments), len(result))
     for result_enrollment in result:
         self.assertIn(
             result_enrollment['course']['course_id'],
             [enrollment['course_id'] for enrollment in enrollments]
         )
Example #6
0
 def test_get_all_enrollments(self, enrollments):
     for enrollment in enrollments:
         fake_data_api.add_course(enrollment['course_id'],
                                  course_modes=enrollment['course_modes'])
         api.add_enrollment(self.USERNAME, enrollment['course_id'],
                            enrollment['mode'])
     result = api.get_enrollments(self.USERNAME)
     assert len(enrollments) == len(result)
     for result_enrollment in result:
         assert result_enrollment['course']['course_id'] in [
             enrollment['course_id'] for enrollment in enrollments
         ]
Example #7
0
 def post(self, request):
     """
     Unenrolls the specified user from all courses.
     """
     try:
         # Get the username from the request.
         username = request.data['username']
         # Ensure that a retirement request status row exists for this username.
         UserRetirementStatus.get_retirement_for_retirement_action(username)
         enrollments = api.get_enrollments(username)
         active_enrollments = [enrollment for enrollment in enrollments if enrollment['is_active']]
         if len(active_enrollments) < 1:
             return Response(status=status.HTTP_204_NO_CONTENT)
         return Response(api.unenroll_user_from_all_courses(username))
     except KeyError:
         return Response(u'Username not specified.', status=status.HTTP_404_NOT_FOUND)
     except UserRetirementStatus.DoesNotExist:
         return Response(u'No retirement request status for username.', status=status.HTTP_404_NOT_FOUND)
     except Exception as exc:  # pylint: disable=broad-except
         return Response(text_type(exc), status=status.HTTP_500_INTERNAL_SERVER_ERROR)
Example #8
0
    def get(self, request, username_or_email):
        """
        Returns a list of enrollments for the given user, along with
        information about previous manual enrollment changes.
        """
        try:
            user = User.objects.get(Q(username=username_or_email) | Q(email=username_or_email))
        except User.DoesNotExist:
            return JsonResponse([])

        enrollments = get_enrollments(user.username, include_inactive=True)
        for enrollment in enrollments:
            # Folds the course_details field up into the main JSON object.
            enrollment.update(**enrollment.pop('course_details'))
            course_key = CourseKey.from_string(enrollment['course_id'])
            # get the all courses modes and replace with existing modes.
            enrollment['course_modes'] = self.get_course_modes(course_key)
            # Add the price of the course's verified mode.
            self.include_verified_mode_info(enrollment, course_key)
            # Add manual enrollment history, if it exists
            enrollment['manual_enrollment'] = self.manual_enrollment_data(enrollment, course_key)
        return JsonResponse(enrollments)
Example #9
0
    def get(self, request):
        """Gets a list of all course enrollments for a user.

        Returns a list for the currently logged in user, or for the user named by the 'user' GET
        parameter. If the username does not match that of the currently logged in user, only
        courses for which the currently logged in user has the Staff or Admin role are listed.
        As a result, a course team member can find out which of his or her own courses a particular
        learner is enrolled in.

        Only the Staff or Admin role (granted on the Django administrative console as the staff
        or instructor permission) in individual courses gives the requesting user access to
        enrollment data. Permissions granted at the organizational level do not give a user
        access to enrollment data for all of that organization's courses.

        Users who have the global staff permission can access all enrollment data for all
        courses.
        """
        username = request.GET.get('user', request.user.username)
        try:
            enrollment_data = api.get_enrollments(username)
        except CourseEnrollmentError:
            return Response(
                status=status.HTTP_400_BAD_REQUEST,
                data={
                    "message":
                    (u"An error occurred while retrieving enrollments for user '{username}'"
                     ).format(username=username)
                })
        if username == request.user.username or GlobalStaff().has_user(request.user) or \
                self.has_api_key_permissions(request):
            return Response(enrollment_data)
        filtered_data = []
        for enrollment in enrollment_data:
            course_key = CourseKey.from_string(
                enrollment["course_details"]["course_id"])
            if user_has_role(request.user, CourseStaffRole(course_key)):
                filtered_data.append(enrollment)
        return Response(filtered_data)
Example #10
0
    def get(self, request):
        """Gets a list of all course enrollments for a user.

        Returns a list for the currently logged in user, or for the user named by the 'user' GET
        parameter. If the username does not match that of the currently logged in user, only
        courses for which the currently logged in user has the Staff or Admin role are listed.
        As a result, a course team member can find out which of his or her own courses a particular
        learner is enrolled in.

        Only the Staff or Admin role (granted on the Django administrative console as the staff
        or instructor permission) in individual courses gives the requesting user access to
        enrollment data. Permissions granted at the organizational level do not give a user
        access to enrollment data for all of that organization's courses.

        Users who have the global staff permission can access all enrollment data for all
        courses.
        """
        username = request.GET.get('user', request.user.username)
        try:
            enrollment_data = api.get_enrollments(username)
        except CourseEnrollmentError:
            return Response(
                status=status.HTTP_400_BAD_REQUEST,
                data={
                    "message": (
                        u"An error occurred while retrieving enrollments for user '{username}'"
                    ).format(username=username)
                }
            )
        if username == request.user.username or GlobalStaff().has_user(request.user) or \
                self.has_api_key_permissions(request):
            return Response(enrollment_data)
        filtered_data = []
        for enrollment in enrollment_data:
            course_key = CourseKey.from_string(enrollment["course_details"]["course_id"])
            if user_has_role(request.user, CourseStaffRole(course_key)):
                filtered_data.append(enrollment)
        return Response(filtered_data)
Example #11
0
    def get(self, request, username_or_email):
        """
        * Example Request:
            - GET /support/onboarding_status/<username_or_email>

        * Example Response:
            {
                "verified_in": {
                    "onboarding_status": "verified",
                    "onboarding_link": "/courses/<course_id>/jump_to/<block_id>",
                    "expiration_date": null,
                    "onboarding_past_due": false,
                    "onboarding_release_date": "2016-01-01T00:00:00+00:00",
                    "review_requirements_url": "",
                    "course_id": "<course_id>",
                    "enrollment_date": "2021-12-29T14:30:18.895435Z",
                    "instructor_dashboard_link": "/courses/<course_id>/instructor#view-special_exams"
                },
                "current_status": {
                    "onboarding_status": "other_course_approved",
                    "onboarding_link": "/courses/<course_id>/jump_to/<block_id>",
                    "expiration_date": "2023-12-29T15:52:28.245Z",
                    "onboarding_past_due": false,
                    "onboarding_release_date": "2020-01-01T00:00:00+00:00",
                    "review_requirements_url": "",
                    "course_id": "<course_id>",
                    "enrollment_date": "2021-12-29T15:58:29.489916Z",
                    "instructor_dashboard_link": "/courses/<course_id>/instructor#view-special_exams"
                }
            }
        """
        # return dict
        onboarding_status = {'verified_in': None, 'current_status': None}

        # make object mutable
        request.GET = request.GET.copy()

        try:
            user = User.objects.get(
                Q(username=username_or_email) | Q(email=username_or_email))
        except User.DoesNotExist:
            return JsonResponse(onboarding_status, status=404)

        request.GET['username'] = user.username
        enrollments = get_enrollments(user.username)

        enrollments = sorted(enrollments,
                             key=lambda enrollment: enrollment['created'],
                             reverse=True)
        enrollments = filter(
            lambda enrollment: enrollment['mode'] in
            [CourseMode.VERIFIED, CourseMode.PROFESSIONAL], enrollments)

        for enrollment in enrollments:
            request.GET['course_id'] = enrollment['course_details'][
                'course_id']

            status = StudentOnboardingStatusView().get(request).data

            if 'onboarding_status' in status:
                status['course_id'] = enrollment['course_details']['course_id']
                status['enrollment_date'] = enrollment['created']
                status['instructor_dashboard_link'] = \
                    '/courses/{}/instructor#view-special_exams'.format(status['course_id'])

                # set most recent status only at first iteration
                if onboarding_status['current_status'] is None:
                    onboarding_status['current_status'] = status

                # stay in loop to find original verified enrollment. Expensive!
                if status[
                        'onboarding_status'] == ProctoredExamStudentAttemptStatus.verified:
                    onboarding_status['verified_in'] = status
                    break

        return JsonResponse(onboarding_status)