示例#1
0
def _compose_message_reverification_email(
        course_key, user_id, related_assessment_location, status, request
):  # pylint: disable=invalid-name
    """
    Compose subject and message for photo reverification email.

    Args:
        course_key(CourseKey): CourseKey object
        user_id(str): User Id
        related_assessment_location(str): Location of reverification XBlock
        photo_verification(QuerySet): Queryset of SoftwareSecure objects
        status(str): Approval status
        is_secure(Bool): Is running on secure protocol or not

    Returns:
        None if any error occurred else Tuple of subject and message strings
    """
    try:
        usage_key = UsageKey.from_string(related_assessment_location)
        reverification_block = modulestore().get_item(usage_key)

        course = modulestore().get_course(course_key)
        redirect_url = get_redirect_url(course_key, usage_key.replace(course_key=course_key))

        subject = "Re-verification Status"
        context = {
            "status": status,
            "course_name": course.display_name_with_default,
            "assessment": reverification_block.related_assessment
        }

        # Allowed attempts is 1 if not set on verification block
        allowed_attempts = reverification_block.attempts + 1
        used_attempts = VerificationStatus.get_user_attempts(user_id, course_key, related_assessment_location)
        left_attempts = allowed_attempts - used_attempts
        is_attempt_allowed = left_attempts > 0
        verification_open = True
        if reverification_block.due:
            verification_open = timezone.now() <= reverification_block.due

        context["left_attempts"] = left_attempts
        context["is_attempt_allowed"] = is_attempt_allowed
        context["verification_open"] = verification_open
        context["due_date"] = get_default_time_display(reverification_block.due)

        context['platform_name'] = settings.PLATFORM_NAME
        context["used_attempts"] = used_attempts
        context["allowed_attempts"] = allowed_attempts
        context["support_link"] = microsite.get_value('email_from_address', settings.CONTACT_EMAIL)

        re_verification_link = reverse(
            'verify_student_incourse_reverify',
            args=(
                unicode(course_key),
                related_assessment_location
            )
        )

        context["course_link"] = request.build_absolute_uri(redirect_url)
        context["reverify_link"] = request.build_absolute_uri(re_verification_link)

        message = render_to_string('emails/reverification_processed.txt', context)
        log.info(
            "Sending email to User_Id=%s. Attempts left for this user are %s. "
            "Allowed attempts %s. "
            "Due Date %s",
            str(user_id), left_attempts, allowed_attempts, str(reverification_block.due)
        )
        return subject, message
    # Catch all exception to avoid raising back to view
    except:  # pylint: disable=bare-except
        log.exception("The email for re-verification sending failed for user_id %s", user_id)
示例#2
0
    def post(self, request, course_id, checkpoint_name, usage_id):
        """Submits the re-verification attempt to SoftwareSecure

        Args:
            request(HttpRequest): HttpRequest object
            course_id(str): Course Id
            checkpoint_name(str): Checkpoint name

        Returns:
            HttpResponse with status_code 400 if photo is missing or any error
            or redirect to verify_student_verify_later url if initial verification doesn't exist otherwise
            HttpsResponse with status code 200
        """
        # Check the in-course re-verification is enabled or not
        incourse_reverify_enabled = InCourseReverificationConfiguration.current().enabled
        if not incourse_reverify_enabled:
            raise Http404

        user = request.user
        try:
            course_key = CourseKey.from_string(course_id)
            usage_key = UsageKey.from_string(usage_id).replace(course_key=course_key)
        except InvalidKeyError:
            raise Http404(u"Invalid course_key or usage_key")
        course = modulestore().get_course(course_key)
        checkpoint = VerificationCheckpoint.get_verification_checkpoint(course_key, checkpoint_name)
        if checkpoint is None:
            log.error("Checkpoint is not defined. Could not submit verification attempt for user %s",
                      request.user.id)
            context = {
                'course_key': unicode(course_key),
                'course_name': course.display_name_with_default,
                'checkpoint_name': checkpoint_name,
                'error': True,
                'errorMsg': _("No checkpoint found"),
                'platform_name': settings.PLATFORM_NAME,
                'usage_id': usage_id
            }
            return render_to_response("verify_student/incourse_reverify.html", context)
        init_verification = SoftwareSecurePhotoVerification.get_initial_verification(user)
        if not init_verification:
            log.error("Could not submit verification attempt for user %s", request.user.id)
            return redirect(reverse('verify_student_verify_later', kwargs={'course_id': unicode(course_key)}))

        try:
            attempt = SoftwareSecurePhotoVerification.submit_faceimage(
                request.user, request.POST['face_image'], init_verification.photo_id_key
            )
            checkpoint.add_verification_attempt(attempt)
            VerificationStatus.add_verification_status(checkpoint, user, "submitted")

            # emit the reverification event
            self._track_reverification_events(
                EVENT_NAME_USER_SUBMITTED_INCOURSE_REVERIFY, user.id, course_id, checkpoint_name
            )

            try:
                redirect_url = get_redirect_url(course_key, usage_key)
            except (ItemNotFoundError, NoPathToItem):
                redirect_url = reverse("courseware", args=(unicode(course_key),))

            return JsonResponse({'url': redirect_url})
        except Http404 as expt:
            log.exception("Invalid location during photo verification.")
            return HttpResponseBadRequest(expt.message)
        except IndexError:
            log.exception("Invalid image data during photo verification.")
            return HttpResponseBadRequest(_("Invalid image data during photo verification."))
        except Exception:  # pylint: disable=broad-except
            log.exception("Could not submit verification attempt for user %s.", request.user.id)
            msg = _("Could not submit photos")
            return HttpResponseBadRequest(msg)
示例#3
0
    def post(self, request, course_id, usage_id):
        """Submits the re-verification attempt to SoftwareSecure.

        Args:
            request(HttpRequest): HttpRequest object
            course_id(str): Course Id
            usage_id(str): Location of Reverification XBlock in courseware

        Returns:
            HttpResponse with status_code 400 if photo is missing or any error
            or redirect to the verification flow if initial verification
            doesn't exist otherwise HttpResponse with status code 200
        """
        # Check the in-course re-verification is enabled or not
        incourse_reverify_enabled = InCourseReverificationConfiguration.current().enabled
        if not incourse_reverify_enabled:
            raise Http404

        user = request.user
        try:
            course_key = CourseKey.from_string(course_id)
            usage_key = UsageKey.from_string(usage_id).replace(course_key=course_key)
        except InvalidKeyError:
            raise Http404(u"Invalid course_key or usage_key")

        course = modulestore().get_course(course_key)
        if course is None:
            log.error(u"Invalid course id '%s'", course_id)
            return HttpResponseBadRequest(_("Invalid course location."))

        checkpoint = VerificationCheckpoint.get_verification_checkpoint(course_key, usage_id)
        if checkpoint is None:
            log.error(
                u"Checkpoint is not defined. Could not submit verification attempt"
                u" for user '%s', course '%s' and checkpoint location '%s'.",
                request.user.id, course_key, usage_id
            )
            return HttpResponseBadRequest(_("Invalid checkpoint location."))

        init_verification = SoftwareSecurePhotoVerification.get_initial_verification(user)
        if not init_verification:
            return self._redirect_no_initial_verification(user, course_key)

        try:
            attempt = SoftwareSecurePhotoVerification.submit_faceimage(
                request.user, request.POST['face_image'], init_verification.photo_id_key
            )
            checkpoint.add_verification_attempt(attempt)
            VerificationStatus.add_verification_status(checkpoint, user, "submitted")

            # emit the reverification event
            self._track_reverification_events(
                'edx.bi.reverify.submitted',
                user.id, course_id, checkpoint.checkpoint_name
            )

            redirect_url = get_redirect_url(course_key, usage_key)
            response = JsonResponse({'url': redirect_url})

        except (ItemNotFoundError, NoPathToItem):
            log.warning(u"Could not find redirect URL for location %s in course %s", course_key, usage_key)
            redirect_url = reverse("courseware", args=(unicode(course_key),))
            response = JsonResponse({'url': redirect_url})

        except Http404 as expt:
            log.exception("Invalid location during photo verification.")
            response = HttpResponseBadRequest(expt.message)

        except IndexError:
            log.exception("Invalid image data during photo verification.")
            response = HttpResponseBadRequest(_("Invalid image data during photo verification."))

        except Exception:  # pylint: disable=broad-except
            log.exception("Could not submit verification attempt for user %s.", request.user.id)
            msg = _("Could not submit photos")
            response = HttpResponseBadRequest(msg)

        return response