Ejemplo n.º 1
0
def _listen_for_id_verification_status_changed(sender, user, **kwargs):  # pylint: disable=unused-argument
    """
    Catches a track change signal, determines user status,
    calls fire_ungenerated_certificate_task for passing grades
    """
    if not auto_certificate_generation_enabled():
        return

    user_enrollments = CourseEnrollment.enrollments_for_user(user=user)

    grade_factory = CourseGradeFactory()
    expected_verification_status = IDVerificationService.user_status(user)
    expected_verification_status = expected_verification_status['status']
    for enrollment in user_enrollments:
        if grade_factory.read(user=user, course=enrollment.course_overview).passed:
            if fire_ungenerated_certificate_task(user, enrollment.course_id, expected_verification_status):
                message = (
                    u'Certificate generation task initiated for {user} : {course} via track change ' +
                    u'with verification status of {status}'
                )
                log.info(message.format(
                    user=user.id,
                    course=enrollment.course_id,
                    status=expected_verification_status
                ))
Ejemplo n.º 2
0
def _listen_for_id_verification_status_changed(sender, user, **kwargs):  # pylint: disable=unused-argument
    """
    Listen for a signal indicating that the user's id verification status has changed.

    If needed, generate a certificate task.
    """
    if not auto_certificate_generation_enabled():
        return

    user_enrollments = CourseEnrollment.enrollments_for_user(user=user)

    grade_factory = CourseGradeFactory()
    expected_verification_status = IDVerificationService.user_status(user)
    expected_verification_status = expected_verification_status['status']
    for enrollment in user_enrollments:
        if can_generate_certificate_task(user, enrollment.course_id):
            log.info(
                f'{enrollment.course_id} is using V2 certificates. Attempt will be made to generate a V2 '
                f'certificate for {user.id}. Id verification status is {expected_verification_status}'
            )
            generate_certificate_task(user, enrollment.course_id)
        elif grade_factory.read(user=user,
                                course=enrollment.course_overview).passed:
            if _fire_ungenerated_certificate_task(
                    user, enrollment.course_id, expected_verification_status):
                message = (
                    'Certificate generation task initiated for {user} : {course} via track change '
                    + 'with verification status of {status}')
                log.info(
                    message.format(user=user.id,
                                   course=enrollment.course_id,
                                   status=expected_verification_status))
Ejemplo n.º 3
0
def _listen_for_id_verification_status_changed(sender, user, **kwargs):  # pylint: disable=unused-argument
    """
    Catches a track change signal, determines user status,
    calls _fire_ungenerated_certificate_task for passing grades
    """
    if not auto_certificate_generation_enabled():
        return

    user_enrollments = CourseEnrollment.enrollments_for_user(user=user)

    grade_factory = CourseGradeFactory()
    expected_verification_status = IDVerificationService.user_status(user)
    expected_verification_status = expected_verification_status['status']
    for enrollment in user_enrollments:
        if is_using_certificate_allowlist_and_is_on_allowlist(
                user, enrollment.course_id):
            log.info(
                f'{enrollment.course_id} is using allowlist certificates, and the user {user.id} is on its '
                f'allowlist. Attempt will be made to generate an allowlist certificate. Id verification status '
                f'is {expected_verification_status}')
            generate_allowlist_certificate_task(user, enrollment.course_id)
        elif grade_factory.read(user=user,
                                course=enrollment.course_overview).passed:
            if _fire_ungenerated_certificate_task(
                    user, enrollment.course_id, expected_verification_status):
                message = (
                    u'Certificate generation task initiated for {user} : {course} via track change '
                    + u'with verification status of {status}')
                log.info(
                    message.format(user=user.id,
                                   course=enrollment.course_id,
                                   status=expected_verification_status))
Ejemplo n.º 4
0
 def test_auto_certificate_generation_enabled(self, self_paced_enabled,
                                              instructor_paced_enabled):
     expected_value = self_paced_enabled or instructor_paced_enabled
     with configure_waffle_namespace(self_paced_enabled,
                                     instructor_paced_enabled):
         self.assertEqual(expected_value,
                          api.auto_certificate_generation_enabled())
Ejemplo n.º 5
0
def listen_for_passing_grade(sender, user, course_id, **kwargs):  # pylint: disable=unused-argument
    """
    Listen for a signal indicating that the user has passed a course run.

    If needed, generate a certificate task.
    """
    if not auto_certificate_generation_enabled():
        return

    if can_generate_certificate_task(user, course_id):
        cert = GeneratedCertificate.certificate_for_student(user, course_id)
        if cert is not None and CertificateStatuses.is_passing_status(
                cert.status):
            log.info(
                f'{course_id} is using V2 certificates, and the cert status is already passing for user '
                f'{user.id}. Passing grade signal will be ignored.')
            return
        log.info(
            f'{course_id} is using V2 certificates. Attempt will be made to generate a V2 certificate for '
            f'{user.id} as a passing grade was received.')
        return generate_certificate_task(user, course_id)

    if _fire_ungenerated_certificate_task(user, course_id):
        log.info(
            'Certificate generation task initiated for {user} : {course} via passing grade'
            .format(user=user.id, course=course_id))
Ejemplo n.º 6
0
def _listen_for_certificate_whitelist_append(sender, instance, **kwargs):  # lint-amnesty, pylint: disable=missing-function-docstring, unused-argument
    if not auto_certificate_generation_enabled():
        return

    if fire_ungenerated_certificate_task(instance.user, instance.course_id):
        log.info(
            u'Certificate generation task initiated for {user} : {course} via whitelist'
            .format(user=instance.user.id, course=instance.course_id))
Ejemplo n.º 7
0
def _listen_for_certificate_whitelist_append(sender, instance, **kwargs):  # pylint: disable=unused-argument
    course = CourseOverview.get_from_id(instance.course_id)
    if not auto_certificate_generation_enabled():
        return

    fire_ungenerated_certificate_task(instance.user, instance.course_id)
    log.info(
        u'Certificate generation task initiated for {user} : {course} via whitelist'
        .format(user=instance.user.id, course=instance.course_id))
Ejemplo n.º 8
0
def _listen_for_certificate_whitelist_append(sender, instance, **kwargs):  # pylint: disable=unused-argument
    course = CourseOverview.get_from_id(instance.course_id)
    if not auto_certificate_generation_enabled():
        return

    fire_ungenerated_certificate_task(instance.user, instance.course_id)
    log.info(u'Certificate generation task initiated for {user} : {course} via whitelist'.format(
        user=instance.user.id,
        course=instance.course_id
    ))
Ejemplo n.º 9
0
def _listen_for_certificate_whitelist_append(sender, instance, **kwargs):  # pylint: disable=unused-argument
    """
    Listen for a user being added to or modified on the whitelist (allowlist)
    """
    if not auto_certificate_generation_enabled():
        return

    if fire_ungenerated_certificate_task(instance.user, instance.course_id):
        log.info(
            u'Certificate generation task initiated for {user} : {course} via whitelist'
            .format(user=instance.user.id, course=instance.course_id))
Ejemplo n.º 10
0
def _can_generate_allowlist_certificate(user, course_key):
    """
    Check if an allowlist certificate can be generated (created if it doesn't already exist, or updated if it does
    exist) for this user, in this course run.
    """
    if not is_using_certificate_allowlist(course_key):
        # This course run is not using the allowlist feature
        log.info(
            f'{course_key} is not using the certificate allowlist. Allowlist certificate cannot be generated'
            f'for {user.id}.')
        return False

    if not _is_on_certificate_allowlist(user, course_key):
        log.info(
            f'{user.id} : {course_key} is not on the certificate allowlist. Allowlist certificate cannot be '
            f'generated.')
        return False

    if not auto_certificate_generation_enabled():
        # Automatic certificate generation is globally disabled
        log.info(
            f'Automatic certificate generation is globally disabled. Allowlist certificate cannot be generated'
            f'for {user.id} : {course_key}.')
        return False

    if CertificateInvalidation.has_certificate_invalidation(user, course_key):
        # The invalidation list overrides the allowlist
        log.info(
            f'{user.id} : {course_key} is on the certificate invalidation list. Allowlist certificate cannot be '
            f'generated.')
        return False

    enrollment_mode, __ = CourseEnrollment.enrollment_mode_for_user(
        user, course_key)
    if enrollment_mode is None:
        log.info(
            f'{user.id} : {course_key} does not have an enrollment. Allowlist certificate cannot be generated.'
        )
        return False

    if not modes_api.is_eligible_for_certificate(enrollment_mode):
        log.info(
            f'{user.id} : {course_key} has an enrollment mode of {enrollment_mode}, which is not eligible for an '
            f'allowlist certificate. Certificate cannot be generated.')
        return False

    if not IDVerificationService.user_is_verified(user):
        log.info(
            f'{user.id} does not have a verified id. Allowlist certificate cannot be generated for {course_key}.'
        )
        return False

    log.info(f'{user.id} : {course_key} is on the certificate allowlist')
    return _can_generate_allowlist_certificate_for_status(user, course_key)
Ejemplo n.º 11
0
def listen_for_passing_grade(sender, user, course_id, **kwargs):  # pylint: disable=unused-argument
    """
    Listen for a learner passing a course, send cert generation task,
    downstream signal from COURSE_GRADE_CHANGED
    """
    if not auto_certificate_generation_enabled():
        return

    if fire_ungenerated_certificate_task(user, course_id):
        log.info(
            u'Certificate generation task initiated for {user} : {course} via passing grade'
            .format(user=user.id, course=course_id))
Ejemplo n.º 12
0
def can_generate_allowlist_certificate(user, course_key):
    """
    Check if an allowlist certificate can be generated (created if it doesn't already exist, or updated if it does
    exist) for this user, in this course run.
    """
    if not is_using_certificate_allowlist(course_key):
        # This course run is not using the allowlist feature
        log.info(
            '{course} is not using the certificate allowlist. Certificate cannot be generated.'.format(
                course=course_key
            ))
        return False

    if not auto_certificate_generation_enabled():
        # Automatic certificate generation is globally disabled
        log.info('Automatic certificate generation is globally disabled. Certificate cannot be generated.')
        return False

    if CertificateInvalidation.has_certificate_invalidation(user, course_key):
        # The invalidation list overrides the allowlist
        log.info(
            '{user} : {course} is on the certificate invalidation list. Certificate cannot be generated.'.format(
                user=user.id,
                course=course_key
            ))
        return False

    enrollment_mode, __ = CourseEnrollment.enrollment_mode_for_user(user, course_key)
    if enrollment_mode is None:
        log.info('{user} : {course} does not have an enrollment. Certificate cannot be generated.'.format(
            user=user.id,
            course=course_key
        ))
        return False

    if not IDVerificationService.user_has_ever_been_verified(user):
        log.info(f'{user.id} has not ever had a verified id. Certificate cannot be generated.')
        return False

    if not _is_on_certificate_allowlist(user, course_key):
        log.info('{user} : {course} is not on the certificate allowlist. Certificate cannot be generated.'.format(
            user=user.id,
            course=course_key
        ))
        return False

    log.info('{user} : {course} is on the certificate allowlist'.format(
        user=user.id,
        course=course_key
    ))
    cert = GeneratedCertificate.certificate_for_student(user, course_key)
    return _can_generate_allowlist_certificate_for_status(cert)
Ejemplo n.º 13
0
def _listen_for_passing_grade(sender, user, course_id, **kwargs):  # pylint: disable=unused-argument
    """
    Listen for a learner passing a course, send cert generation task,
    downstream signal from COURSE_GRADE_CHANGED
    """
    course = CourseOverview.get_from_id(course_id)
    if not auto_certificate_generation_enabled():
        return

    if fire_ungenerated_certificate_task(user, course_id):
        log.info(u'Certificate generation task initiated for {user} : {course} via passing grade'.format(
            user=user.id,
            course=course_id
        ))
Ejemplo n.º 14
0
def _listen_for_track_change(sender, user, **kwargs):  # pylint: disable=unused-argument
    """
    Catches a track change signal, determines user status,
    calls fire_ungenerated_certificate_task for passing grades
    """
    if not auto_certificate_generation_enabled():
        return

    user_enrollments = CourseEnrollment.enrollments_for_user(user=user)
    grade_factory = CourseGradeFactory()
    for enrollment in user_enrollments:
        if grade_factory.read(user=user, course=enrollment.course_overview).passed:
            if fire_ungenerated_certificate_task(user, enrollment.course_id):
                log.info(u'Certificate generation task initiated for {user} : {course} via track change'.format(
                    user=user.id,
                    course=enrollment.course_id
                ))
Ejemplo n.º 15
0
def _listen_for_certificate_whitelist_append(sender, instance, **kwargs):  # pylint: disable=unused-argument
    """
    Listen for a user being added to or modified on the whitelist (allowlist)
    """
    if not auto_certificate_generation_enabled():
        return

    if is_using_certificate_allowlist_and_is_on_allowlist(instance.user, instance.course_id):
        log.info(f'{instance.course_id} is using allowlist certificates, and the user {instance.user.id} is now on '
                 f'its allowlist. Attempt will be made to generate an allowlist certificate.')
        return generate_allowlist_certificate_task(instance.user, instance.course_id)

    if _fire_ungenerated_certificate_task(instance.user, instance.course_id):
        log.info('Certificate generation task initiated for {user} : {course} via whitelist'.format(
            user=instance.user.id,
            course=instance.course_id
        ))
Ejemplo n.º 16
0
def _listen_for_track_change(sender, user, **kwargs):  # pylint: disable=unused-argument
    """
    Catches a track change signal, determines user status,
    calls fire_ungenerated_certificate_task for passing grades
    """
    if not auto_certificate_generation_enabled():
        return

    user_enrollments = CourseEnrollment.enrollments_for_user(user=user)
    grade_factory = CourseGradeFactory()
    for enrollment in user_enrollments:
        if grade_factory.read(user=user,
                              course=enrollment.course_overview).passed:
            if fire_ungenerated_certificate_task(user, enrollment.course_id):
                log.info(
                    u'Certificate generation task initiated for {user} : {course} via track change'
                    .format(user=user.id, course=enrollment.course_id))
Ejemplo n.º 17
0
def listen_for_passing_grade(sender, user, course_id, **kwargs):  # pylint: disable=unused-argument
    """
    Listen for a learner passing a course, send cert generation task,
    downstream signal from COURSE_GRADE_CHANGED
    """
    if not auto_certificate_generation_enabled():
        return

    if can_generate_certificate_task(user, course_id):
        log.info(f'{course_id} is using V2 certificates. Attempt will be made to generate a V2 certificate for '
                 f'{user.id} as a passing grade was received.')
        return generate_certificate_task(user, course_id)

    if _fire_ungenerated_certificate_task(user, course_id):
        log.info('Certificate generation task initiated for {user} : {course} via passing grade'.format(
            user=user.id,
            course=course_id
        ))
Ejemplo n.º 18
0
def _can_generate_certificate_common(user, course_key):
    """
    Check if a course certificate can be generated (created if it doesn't already exist, or updated if it does
    exist) for this user, in this course run.

    This method contains checks that are common to both allowlist and V2 regular course certificates.
    """
    if not auto_certificate_generation_enabled():
        # Automatic certificate generation is globally disabled
        log.info(f'Automatic certificate generation is globally disabled. Certificate cannot be generated for '
                 f'{user.id} : {course_key}.')
        return False

    if CertificateInvalidation.has_certificate_invalidation(user, course_key):
        # The invalidation list prevents certificate generation
        log.info(f'{user.id} : {course_key} is on the certificate invalidation list. Certificate cannot be generated.')
        return False

    enrollment_mode, __ = CourseEnrollment.enrollment_mode_for_user(user, course_key)
    if enrollment_mode is None:
        log.info(f'{user.id} : {course_key} does not have an enrollment. Certificate cannot be generated.')
        return False

    if not modes_api.is_eligible_for_certificate(enrollment_mode):
        log.info(f'{user.id} : {course_key} has an enrollment mode of {enrollment_mode}, which is not eligible for a '
                 f'certificate. Certificate cannot be generated.')
        return False

    if not IDVerificationService.user_is_verified(user):
        log.info(f'{user.id} does not have a verified id. Certificate cannot be generated for {course_key}.')
        return False

    if not _can_generate_certificate_for_status(user, course_key):
        return False

    course = _get_course(course_key)
    if not has_html_certificates_enabled(course):
        log.info(f'{course_key} does not have HTML certificates enabled. Certificate cannot be generated for '
                 f'{user.id}.')
        return False

    return True
Ejemplo n.º 19
0
def _listen_for_id_verification_status_changed(sender, user, **kwargs):  # pylint: disable=unused-argument
    """
    Catches a track change signal, determines user status,
    calls fire_ungenerated_certificate_task for passing grades
    """
    if not auto_certificate_generation_enabled():
        return

    user_enrollments = CourseEnrollment.enrollments_for_user(user=user)
    grade_factory = CourseGradeFactory()
    expected_verification_status = IDVerificationService.user_status(user)
    for enrollment in user_enrollments:
        if grade_factory.read(user=user, course=enrollment.course_overview).passed:
            if fire_ungenerated_certificate_task(user, enrollment.course_id, expected_verification_status):
                message = (
                    u'Certificate generation task initiated for {user} : {course} via track change ' +
                    u'with verification status of {status}'
                )
                log.info(message.format(
                    user=user.id,
                    course=enrollment.course_id,
                    status=expected_verification_status['status']
                ))
Ejemplo n.º 20
0
 def test_auto_certificate_generation_enabled(self, feature_enabled):
     with configure_waffle_namespace(feature_enabled):
         self.assertEqual(feature_enabled, api.auto_certificate_generation_enabled())
Ejemplo n.º 21
0
 def test_auto_certificate_generation_enabled(self, feature_enabled):
     with configure_waffle_namespace(feature_enabled):
         assert feature_enabled == api.auto_certificate_generation_enabled()
Ejemplo n.º 22
0
def _can_generate_v2_certificate(user, course_key):
    """
    Check if a v2 course certificate can be generated (created if it doesn't already exist, or updated if it does
    exist) for this user, in this course run.
    """
    if not _is_using_v2_course_certificates(course_key):
        # This course run is not using the v2 course certificate feature
        log.info(
            f'{course_key} is not using v2 course certificates. Certificate cannot be generated.'
        )
        return False

    if not auto_certificate_generation_enabled():
        # Automatic certificate generation is globally disabled
        log.info(
            f'Automatic certificate generation is globally disabled. Certificate cannot be generated for '
            f'{user.id} : {course_key}.')
        return False

    if CertificateInvalidation.has_certificate_invalidation(user, course_key):
        # The invalidation list prevents certificate generation
        log.info(
            f'{user.id} : {course_key} is on the certificate invalidation list. Certificate cannot be generated.'
        )
        return False

    enrollment_mode, __ = CourseEnrollment.enrollment_mode_for_user(
        user, course_key)
    if enrollment_mode is None:
        log.info(
            f'{user.id} : {course_key} does not have an enrollment. Certificate cannot be generated.'
        )
        return False

    if not modes_api.is_eligible_for_certificate(enrollment_mode):
        log.info(
            f'{user.id} : {course_key} has an enrollment mode of {enrollment_mode}, which is not eligible for an '
            f'allowlist certificate. Certificate cannot be generated.')
        return False

    if not IDVerificationService.user_is_verified(user):
        log.info(
            f'{user.id} does not have a verified id. Certificate cannot be generated for {course_key}.'
        )
        return False

    if _is_ccx_course(course_key):
        log.info(
            f'{course_key} is a CCX course. Certificate cannot be generated for {user.id}.'
        )
        return False

    course = modulestore().get_course(course_key, depth=0)
    if _is_beta_tester(user, course):
        log.info(
            f'{user.id} is a beta tester in {course_key}. Certificate cannot be generated.'
        )
        return False

    if not _has_passing_grade(user, course):
        log.info(
            f'{user.id} does not have a passing grade in {course_key}. Certificate cannot be generated.'
        )
        return False

    if not _can_generate_certificate_for_status(user, course_key):
        return False

    log.info(f'V2 certificate can be generated for {user.id} : {course_key}')
    return True