Ejemplo n.º 1
0
def start_exam_callback(request, attempt_code):  # pylint: disable=unused-argument
    """
    A callback endpoint which is called when SoftwareSecure completes
    the proctoring setup and the exam should be started.

    This is an authenticated endpoint and the attempt_code is passed in
    as part of the URL path

    IMPORTANT: This is an unauthenticated endpoint, so be VERY CAREFUL about extending
    this endpoint
    """
    attempt = get_exam_attempt_by_code(attempt_code)
    if not attempt:
        log.warning(u"Attempt code %r cannot be found.", attempt_code)
        return HttpResponse(
            content='You have entered an exam code that is not valid.',
            status=404
        )
    proctored_exam_id = attempt['proctored_exam']['id']
    attempt_status = attempt['status']
    user_id = attempt['user']['id']
    if attempt_status in [ProctoredExamStudentAttemptStatus.created,
                          ProctoredExamStudentAttemptStatus.download_software_clicked]:
        mark_exam_attempt_as_ready(proctored_exam_id, user_id)

    # if a user attempts to re-enter an exam that has not yet been submitted, submit the exam
    if ProctoredExamStudentAttemptStatus.is_in_progress_status(attempt_status):
        update_attempt_status(proctored_exam_id, user_id, ProctoredExamStudentAttemptStatus.submitted)
    else:
        log.warning(u"Attempted to enter proctored exam attempt {attempt_id} when status was {attempt_status}"
                    .format(
                        attempt_id=attempt['id'],
                        attempt_status=attempt_status,
                    ))

    if switch_is_active(RPNOWV4_WAFFLE_NAME):  # pylint: disable=illegal-waffle-usage
        course_id = attempt['proctored_exam']['course_id']
        content_id = attempt['proctored_exam']['content_id']

        exam_url = ''
        try:
            exam_url = reverse('jump_to', args=[course_id, content_id])
        except NoReverseMatch:
            log.exception(u"BLOCKING ERROR: Can't find course info url for course %s", course_id)
        response = HttpResponseRedirect(exam_url)
        response.set_signed_cookie('exam', attempt['attempt_code'])
        return response

    template = loader.get_template('proctored_exam/proctoring_launch_callback.html')

    return HttpResponse(
        template.render({
            'platform_name': settings.PLATFORM_NAME,
            'link_urls': settings.PROCTORING_SETTINGS.get('LINK_URLS', {})
        })
    )
Ejemplo n.º 2
0
def is_reattempting_exam(from_status, to_status):
    """
    Returns a boolean representing whether or not a user is trying to reattempt an exam.

    Given user's exam is in progress, and he is kicked out due to low bandwidth or
    closes the secure browser. Its expected that the user should not be able to restart
    the exam workflow.
    This behavior is being implemented due to edX's integrity constraints.
    """
    return (
        ProctoredExamStudentAttemptStatus.is_in_progress_status(from_status)
        and ProctoredExamStudentAttemptStatus.is_pre_started_status(to_status))
Ejemplo n.º 3
0
def start_exam_callback(request, attempt_code):  # pylint: disable=unused-argument
    """
    A callback endpoint which is called when SoftwareSecure completes
    the proctoring setup and the exam should be started.

    This is an authenticated endpoint and the attempt_code is passed in
    as part of the URL path

    IMPORTANT: This is an unauthenticated endpoint, so be VERY CAREFUL about extending
    this endpoint
    """
    attempt = get_exam_attempt_by_code(attempt_code)
    if not attempt:
        log.warning('attempt_code={attempt_code} cannot be found.'.format(
            attempt_code=attempt_code))
        return HttpResponse(
            content='You have entered an exam code that is not valid.',
            status=404)
    attempt_status = attempt['status']
    if attempt_status in [
            ProctoredExamStudentAttemptStatus.created,
            ProctoredExamStudentAttemptStatus.download_software_clicked
    ]:
        mark_exam_attempt_as_ready(attempt['id'])

    # if a user attempts to re-enter an exam that has not yet been submitted, submit the exam
    if ProctoredExamStudentAttemptStatus.is_in_progress_status(attempt_status):
        update_attempt_status(attempt['id'],
                              ProctoredExamStudentAttemptStatus.submitted)
    else:
        log.warning(
            'Attempted to enter proctored exam attempt_id={attempt_id} when status={attempt_status}'
            .format(
                attempt_id=attempt['id'],
                attempt_status=attempt_status,
            ))

    course_id = attempt['proctored_exam']['course_id']
    content_id = attempt['proctored_exam']['content_id']

    exam_url = ''
    try:
        exam_url = reverse('jump_to', args=[course_id, content_id])
    except NoReverseMatch:
        log.exception(
            "BLOCKING ERROR: Can't find course info url for course_id=%s",
            course_id)
    response = HttpResponseRedirect(exam_url)
    response.set_signed_cookie('exam', attempt['attempt_code'])
    return response