Exemple #1
0
 def post(self, request, user_id):  # pylint: disable=unused-argument
     """
     Deletes all user data for the particular user_id
     from all configured backends
     """
     if not request.user.has_perm('accounts.can_retire_user'):
         return Response(status=403)
     results = {}
     code = 200
     seen = set()
     # pylint: disable=no-member
     attempts = ProctoredExamStudentAttempt.objects.filter(user_id=user_id).select_related('proctored_exam')
     if attempts:
         for attempt in attempts:
             backend_name = attempt.proctored_exam.backend
             if backend_name in seen or not attempt.taking_as_proctored:
                 continue
             backend_user_id = obscured_user_id(user_id, backend_name)
             LOG.info(u'retiring user %s from %s', user_id, backend_name)
             try:
                 result = get_backend_provider(name=backend_name).retire_user(backend_user_id)
             except ProctoredBaseException:
                 LOG.exception(u'attempting to delete %s (%s) from %s', user_id, backend_user_id, backend_name)
                 result = False
             if result is not None:
                 results[backend_name] = result
                 if not result:
                     code = 500
             seen.add(backend_name)
     return Response(data=results, status=code)
Exemple #2
0
 def post(self, request, user_id):  # pylint: disable=unused-argument
     """
     Deletes all user data for the particular user_id
     from all configured backends
     """
     if not request.user.has_perm('accounts.can_retire_user'):
         return Response(status=403)
     from django.apps import apps
     choices = apps.get_app_config('edx_proctoring').get_backend_choices()
     results = {}
     code = 200
     if ProctoredExamStudentAttempt.objects.filter(user_id=user_id):
         for backend_name, verbose_name in choices:
             backend_user_id = obscured_user_id(user_id, backend_name)
             LOG.info('retiring user %s from %s', user_id, backend_name)
             try:
                 result = get_backend_provider(name=backend_name).retire_user(backend_user_id)
             except ProctoredBaseException:
                 LOG.exception('attempting to delete %s (%s) from %s', user_id, backend_user_id, verbose_name)
                 result = False
             if result is not None:
                 results[backend_name] = result
                 if not result:
                     code = 500
     return Response(data=results, status=code)
Exemple #3
0
 def post(self, request, user_id):  # pylint: disable=unused-argument
     """
     Deletes all user data for the particular user_id
     from all configured backends
     """
     if not request.user.has_perm('accounts.can_retire_user'):
         return Response(status=403)
     results = {}
     code = 200
     seen = set()
     attempts = ProctoredExamStudentAttempt.objects.filter(user_id=user_id).select_related('proctored_exam')
     if attempts:
         for attempt in attempts:
             backend_name = attempt.proctored_exam.backend
             if backend_name in seen or not attempt.taking_as_proctored:
                 continue
             backend_user_id = obscured_user_id(user_id, backend_name)
             LOG.info('retiring user %s from %s', user_id, backend_name)
             try:
                 result = get_backend_provider(name=backend_name).retire_user(backend_user_id)
             except ProctoredBaseException:
                 LOG.exception('attempting to delete %s (%s) from %s', user_id, backend_user_id, backend_name)
                 result = False
             if result is not None:
                 results[backend_name] = result
                 if not result:
                     code = 500
             seen.add(backend_name)
     return Response(data=results, status=code)
Exemple #4
0
    def get(self, request, course_id, exam_id=None):
        """
        Redirect to dashboard for a given course and optional exam_id
        """
        exam = None
        attempt_id = None
        ext_exam_id = None
        show_configuration_dashboard = False

        if exam_id:
            exam = get_exam_by_id(exam_id)
            # the exam_id in the url is our database id (for ease of lookups)
            # but the backend needs its external id for the instructor dashboard
            ext_exam_id = exam['external_id']
            attempt_id = request.GET.get('attempt', None)

            # only show the configuration dashboard if an exam_id is passed in
            show_configuration_dashboard = request.GET.get('config', '').lower() == 'true'

        else:
            found_backend = None
            for exam in get_all_exams_for_course(course_id, True):
                exam_backend = exam['backend'] or settings.PROCTORING_BACKENDS.get('DEFAULT', None)
                if found_backend and exam_backend != found_backend:
                    # In this case, what are we supposed to do?!
                    # It should not be possible to get in this state, because
                    # course teams will be prevented from updating the backend after the course start date
                    error_message = "Multiple backends for course %r %r != %r" % (course_id,
                                                                                  found_backend,
                                                                                  exam['backend'])
                    return Response(data=error_message, status=400)
                else:
                    found_backend = exam_backend
        if exam is None:
            error = _('No exams in course {course_id}.').format(course_id=course_id)
        else:
            backend = get_backend_provider(exam)
            if backend:
                user = {
                    'id': obscured_user_id(request.user.id, exam['backend']),
                    'full_name': request.user.get_full_name(),
                    'email': request.user.email
                }

                url = backend.get_instructor_url(
                    exam['course_id'],
                    user,
                    exam_id=ext_exam_id,
                    attempt_id=attempt_id,
                    show_configuration_dashboard=show_configuration_dashboard
                )
                if url:
                    return redirect(url)
                else:
                    error = _('No instructor dashboard for {proctor_service}').format(
                        proctor_service=backend.verbose_name)
            else:
                error = _('No proctored exams in course {course_id}').format(course_id=course_id)
        return Response(data=error, status=404, headers={'X-Frame-Options': 'sameorigin'})
Exemple #5
0
    def get(self, request, course_id, exam_id=None):
        """
        Redirect to dashboard for a given course and optional exam_id
        """
        exam = None
        attempt_id = None
        ext_exam_id = None
        show_configuration_dashboard = False

        if exam_id:
            exam = get_exam_by_id(exam_id)
            # the exam_id in the url is our database id (for ease of lookups)
            # but the backend needs its external id for the instructor dashboard
            ext_exam_id = exam['external_id']
            attempt_id = request.GET.get('attempt', None)

            # only show the configuration dashboard if an exam_id is passed in
            show_configuration_dashboard = request.GET.get('config', '').lower() == 'true'

        else:
            found_backend = None
            for exam in get_all_exams_for_course(course_id, True):
                exam_backend = exam['backend'] or settings.PROCTORING_BACKENDS.get('DEFAULT', None)
                if found_backend and exam_backend != found_backend:
                    # In this case, what are we supposed to do?!
                    # It should not be possible to get in this state, because
                    # course teams will be prevented from updating the backend after the course start date
                    error_message = "Multiple backends for course %r %r != %r" % (course_id,
                                                                                  found_backend,
                                                                                  exam['backend'])
                    return Response(data=error_message, status=400)
                else:
                    found_backend = exam_backend
        if exam is None:
            error = _('No exams in course {course_id}.').format(course_id=course_id)
        else:
            backend = get_backend_provider(exam)
            if backend:
                user = {
                    'id': obscured_user_id(request.user.id, exam['backend']),
                    'full_name': request.user.get_full_name(),
                    'email': request.user.email
                }

                url = backend.get_instructor_url(
                    exam['course_id'],
                    user,
                    exam_id=ext_exam_id,
                    attempt_id=attempt_id,
                    show_configuration_dashboard=show_configuration_dashboard
                )
                if url:
                    return redirect(url)
                else:
                    error = _('No instructor dashboard for {proctor_service}').format(
                        proctor_service=backend.verbose_name)
            else:
                error = _('No proctored exams in course {course_id}').format(course_id=course_id)
        return Response(data=error, status=404, headers={'X-Frame-Options': 'sameorigin'})
Exemple #6
0
    def get(self, request, course_id, exam_id=None):
        """
        Redirect to dashboard for a given course and optional exam_id
        """
        exam = None
        backend = None
        ext_exam_id = None
        attempt_id = None
        show_configuration_dashboard = False

        if exam_id:
            exam = get_exam_by_id(exam_id)
            backend = get_backend_provider(exam=exam)
            # the exam_id in the url is our database id (for ease of lookups)
            # but the backend needs its external id for the instructor dashboard
            ext_exam_id = exam['external_id']
            attempt_id = request.GET.get('attempt', None)

            # only show the configuration dashboard if an exam_id is passed in
            show_configuration_dashboard = request.GET.get('config', '').lower() == 'true'
        else:
            existing_backend_name = None
            for exam in get_all_exams_for_course(course_id, True):
                if not exam.get('is_proctored'):
                    # We should only get backends of exams which are configured to be proctored
                    continue

                exam_backend_name = exam.get('backend')
                backend = get_backend_provider(name=exam_backend_name)
                if existing_backend_name and exam_backend_name != existing_backend_name:
                    # In this case, what are we supposed to do?!
                    # It should not be possible to get in this state, because
                    # course teams will be prevented from updating the backend after the course start date
                    error_message = u"Multiple backends for course %r %r != %r" % (
                        course_id,
                        existing_backend_name,
                        exam_backend_name
                    )
                    return Response(data=error_message, status=400)
                else:
                    existing_backend_name = exam_backend_name

        if not exam:
            return Response(
                data=_(u'No exams in course {course_id}.').format(course_id=course_id),
                status=404,
                headers={'X-Frame-Options': 'sameorigin'}
            )
        if not backend:
            return Response(
                data=_(u'No proctored exams in course {course_id}').format(course_id=course_id),
                status=404,
                headers={'X-Frame-Options': 'sameorigin'}
            )
        user = {
            'id': obscured_user_id(request.user.id, exam['backend']),
            'full_name': request.user.profile.name,
            'email': request.user.email
        }

        url = backend.get_instructor_url(
            exam['course_id'],
            user,
            exam_id=ext_exam_id,
            attempt_id=attempt_id,
            show_configuration_dashboard=show_configuration_dashboard
        )
        if not url:
            return Response(
                data=_(u'No instructor dashboard for {proctor_service}').format(
                    proctor_service=backend.verbose_name
                ),
                status=404,
                headers={'X-Frame-Options': 'sameorigin'}
            )
        return redirect(url)
 def test_obscured_user_id(self):
     user_id = 32432455
     expected_obscured_user_id = '9b82efd5d28f1a170b23b8f648c3093e75a0a0ca'
     self.assertEqual(expected_obscured_user_id, obscured_user_id(user_id))