Example #1
0
    def test_masquerade_in_holdback(self, mock_get_course_run_details):
        mock_get_course_run_details.return_value = {'weeks_to_complete': 12}
        audit_student = UserFactory(username='******')
        CourseEnrollmentFactory.create(user=audit_student,
                                       course_id=self.course.id,
                                       mode='audit')
        ExperimentData.objects.create(
            user=audit_student,
            experiment_id=EXPERIMENT_ID,
            key=EXPERIMENT_DATA_HOLDBACK_KEY.format(audit_student),
            value='True')
        CourseDurationLimitConfig.objects.create(
            enabled=True,
            course=CourseOverview.get_from_id(self.course.id),
            enabled_as_of=self.course.start,
        )

        instructor = UserFactory.create(username='******')
        CourseEnrollmentFactory.create(user=instructor,
                                       course_id=self.course.id,
                                       mode='audit')
        CourseInstructorRole(self.course.id).add_users(instructor)
        self.client.login(username=instructor.username, password='******')

        self.update_masquerade(username='******')

        course_home_url = reverse('openedx.course_experience.course_home',
                                  args=[unicode(self.course.id)])
        response = self.client.get(course_home_url, follow=True)
        self.assertEqual(response.status_code, 200)
        self.assertItemsEqual(response.redirect_chain, [])
        banner_text = 'Your access to this course expires on'
        self.assertNotIn(banner_text, response.content)
Example #2
0
    def enabled_for_enrollment(cls, enrollment=None, user=None, course_key=None):
        """
        Return whether Content Type Gating is enabled for this enrollment.

        Content Type Gating is enabled for an enrollment if it is enabled for
        the course being enrolled in (either specifically, or via a containing context,
        such as the org, site, or globally), and if the configuration is specified to be
        ``enabled_as_of`` before the enrollment was created.

        Only one of enrollment and (user, course_key) may be specified at a time.

        Arguments:
            enrollment: The enrollment being queried.
            user: The user being queried.
            course_key: The CourseKey of the course being queried.
        """
        if CONTENT_TYPE_GATING_FLAG.is_enabled():
            return True

        if enrollment is not None and (user is not None or course_key is not None):
            raise ValueError('Specify enrollment or user/course_key, but not both')

        if enrollment is None and (user is None or course_key is None):
            raise ValueError('Both user and course_key must be specified if no enrollment is provided')

        if enrollment is None and user is None and course_key is None:
            raise ValueError('At least one of enrollment or user and course_key must be specified')

        if course_key is None:
            course_key = enrollment.course_id

        if enrollment is None:
            enrollment = CourseEnrollment.get_enrollment(user, course_key)

        # enrollment might be None if the user isn't enrolled. In that case,
        # return enablement as if the user enrolled today
        if enrollment is None:
            return cls.enabled_for_course(course_key=course_key, target_datetime=timezone.now())
        else:
            # TODO: clean up as part of REV-100
            experiment_data_holdback_key = EXPERIMENT_DATA_HOLDBACK_KEY.format(user)
            is_in_holdback = False
            no_masquerade = get_course_masquerade(user, course_key) is None
            student_masquerade = is_masquerading_as_specific_student(user, course_key)
            if user and (no_masquerade or student_masquerade):
                try:
                    holdback_value = ExperimentData.objects.get(
                        user=user,
                        experiment_id=EXPERIMENT_ID,
                        key=experiment_data_holdback_key,
                    ).value
                    is_in_holdback = holdback_value == 'True'
                except ExperimentData.DoesNotExist:
                    pass
            if is_in_holdback:
                return False
            current_config = cls.current(course_key=enrollment.course_id)
            return current_config.enabled_as_of_datetime(target_datetime=enrollment.created)
    def test_masquerade_in_holdback(self, mock_get_course_run_details):
        mock_get_course_run_details.return_value = {'weeks_to_complete': 12}
        audit_student = UserFactory(username='******')
        CourseEnrollmentFactory.create(
            user=audit_student,
            course_id=self.course.id,
            mode='audit'
        )
        ExperimentData.objects.create(
            user=audit_student,
            experiment_id=EXPERIMENT_ID,
            key=EXPERIMENT_DATA_HOLDBACK_KEY.format(audit_student),
            value='True'
        )
        CourseDurationLimitConfig.objects.create(
            enabled=True,
            course=CourseOverview.get_from_id(self.course.id),
            enabled_as_of=self.course.start,
        )

        instructor = UserFactory.create(username='******')
        CourseEnrollmentFactory.create(
            user=instructor,
            course_id=self.course.id,
            mode='audit'
        )
        CourseInstructorRole(self.course.id).add_users(instructor)
        self.client.login(username=instructor.username, password='******')

        self.update_masquerade(username='******')

        course_home_url = reverse('openedx.course_experience.course_home', args=[unicode(self.course.id)])
        response = self.client.get(course_home_url, follow=True)
        self.assertEqual(response.status_code, 200)
        self.assertItemsEqual(response.redirect_chain, [])
        banner_text = 'Your access to this course expires on'
        self.assertNotIn(banner_text, response.content)
Example #4
0
    def enabled_for_enrollment(cls,
                               enrollment=None,
                               user=None,
                               course_key=None):
        """
        Return whether Content Type Gating is enabled for this enrollment.

        Content Type Gating is enabled for an enrollment if it is enabled for
        the course being enrolled in (either specifically, or via a containing context,
        such as the org, site, or globally), and if the configuration is specified to be
        ``enabled_as_of`` before the enrollment was created.

        Only one of enrollment and (user, course_key) may be specified at a time.

        Arguments:
            enrollment: The enrollment being queried.
            user: The user being queried.
            course_key: The CourseKey of the course being queried.
        """
        if CONTENT_TYPE_GATING_FLAG.is_enabled():
            return True

        if enrollment is not None and (user is not None
                                       or course_key is not None):
            raise ValueError(
                'Specify enrollment or user/course_key, but not both')

        if enrollment is None and (user is None or course_key is None):
            raise ValueError(
                'Both user and course_key must be specified if no enrollment is provided'
            )

        if enrollment is None and user is None and course_key is None:
            raise ValueError(
                'At least one of enrollment or user and course_key must be specified'
            )

        if course_key is None:
            course_key = enrollment.course_id

        if enrollment is None:
            enrollment = CourseEnrollment.get_enrollment(user, course_key)

        if user is None and enrollment is not None:
            user = enrollment.user

        no_masquerade = get_course_masquerade(user, course_key) is None
        student_masquerade = is_masquerading_as_specific_student(
            user, course_key)
        # We can only use the user variable for the code below when the request is not in a masquerade state
        # or is masquerading as a specific user.
        # When a request is not in a masquerade state the user variable represents the correct user.
        # When a request is in a masquerade state and not masquerading as a specific user,
        # then then user variable will be the incorrect (original) user, not the masquerade user.
        # If a request is masquerading as a specific user, the user variable will represent the correct user.
        user_variable_represents_correct_user = (no_masquerade
                                                 or student_masquerade)
        if user and user.id:
            # TODO: Move masquerade checks to enabled_for_enrollment from content_type_gating/partitions.py
            # TODO: Consolidate masquerade checks into shared function like has_staff_roles below
            if user_variable_represents_correct_user and has_staff_roles(
                    user, course_key):
                return False

        # enrollment might be None if the user isn't enrolled. In that case,
        # return enablement as if the user enrolled today
        if enrollment is None:
            return cls.enabled_for_course(course_key=course_key,
                                          target_datetime=timezone.now())
        else:
            # TODO: clean up as part of REV-100
            experiment_data_holdback_key = EXPERIMENT_DATA_HOLDBACK_KEY.format(
                user)
            is_in_holdback = False
            if user and (user_variable_represents_correct_user):
                try:
                    holdback_value = ExperimentData.objects.get(
                        user=user,
                        experiment_id=EXPERIMENT_ID,
                        key=experiment_data_holdback_key,
                    ).value
                    is_in_holdback = holdback_value == 'True'
                except ExperimentData.DoesNotExist:
                    pass
            if is_in_holdback:
                return False
            current_config = cls.current(course_key=enrollment.course_id)
            return current_config.enabled_as_of_datetime(
                target_datetime=enrollment.created)
Example #5
0
    def enabled_for_enrollment(cls, enrollment=None, user=None, course_key=None):
        """
        Return whether Course Duration Limits are enabled for this enrollment.

        Course Duration Limits are enabled for an enrollment if they are enabled for
        the course being enrolled in (either specifically, or via a containing context,
        such as the org, site, or globally), and if the configuration is specified to be
        ``enabled_as_of`` before the enrollment was created.

        Only one of enrollment and (user, course_key) may be specified at a time.

        Arguments:
            enrollment: The enrollment being queried.
            user: The user being queried.
            course_key: The CourseKey of the course being queried.
        """
        if CONTENT_TYPE_GATING_FLAG.is_enabled():
            return True

        if enrollment is not None and (user is not None or course_key is not None):
            raise ValueError('Specify enrollment or user/course_key, but not both')

        if enrollment is None and (user is None or course_key is None):
            raise ValueError('Both user and course_key must be specified if no enrollment is provided')

        if enrollment is None and user is None and course_key is None:
            raise ValueError('At least one of enrollment or user and course_key must be specified')

        if course_key is None:
            course_key = enrollment.course_id

        if enrollment is None:
            enrollment = CourseEnrollment.get_enrollment(user, course_key)

        # if the user is has a role of staff, instructor or beta tester their access should not expire
        if user is None and enrollment is not None:
            user = enrollment.user

        if user:
            course_masquerade = get_course_masquerade(user, course_key)
            if course_masquerade:
                verified_mode_id = settings.COURSE_ENROLLMENT_MODES.get(CourseMode.VERIFIED, {}).get('id')
                is_verified = (course_masquerade.user_partition_id == ENROLLMENT_TRACK_PARTITION_ID
                               and course_masquerade.group_id == verified_mode_id)
                is_full_access = (course_masquerade.user_partition_id == CONTENT_GATING_PARTITION_ID
                                  and course_masquerade.group_id == CONTENT_TYPE_GATE_GROUP_IDS['full_access'])
                is_staff = get_masquerade_role(user, course_key) == 'staff'
                if is_verified or is_full_access or is_staff:
                    return False
            else:
                staff_role = CourseStaffRole(course_key).has_user(user)
                instructor_role = CourseInstructorRole(course_key).has_user(user)
                beta_tester_role = CourseBetaTesterRole(course_key).has_user(user)

                if staff_role or instructor_role or beta_tester_role:
                    return False

        # enrollment might be None if the user isn't enrolled. In that case,
        # return enablement as if the user enrolled today
        if enrollment is None:
            return cls.enabled_for_course(course_key=course_key, target_datetime=timezone.now())
        else:
            # TODO: clean up as part of REV-100
            experiment_data_holdback_key = EXPERIMENT_DATA_HOLDBACK_KEY.format(user)
            is_in_holdback = False
            no_masquerade = get_course_masquerade(user, course_key) is None
            student_masquerade = is_masquerading_as_specific_student(user, course_key)
            if user and (no_masquerade or student_masquerade):
                try:
                    holdback_value = ExperimentData.objects.get(
                        user=user,
                        experiment_id=EXPERIMENT_ID,
                        key=experiment_data_holdback_key,
                    ).value
                    is_in_holdback = holdback_value == 'True'
                except ExperimentData.DoesNotExist:
                    pass
            if is_in_holdback:
                return False
            current_config = cls.current(course_key=enrollment.course_id)
            return current_config.enabled_as_of_datetime(target_datetime=enrollment.created)
Example #6
0
    def enabled_for_enrollment(cls,
                               enrollment=None,
                               user=None,
                               course_key=None):
        """
        Return whether Course Duration Limits are enabled for this enrollment.

        Course Duration Limits are enabled for an enrollment if they are enabled for
        the course being enrolled in (either specifically, or via a containing context,
        such as the org, site, or globally), and if the configuration is specified to be
        ``enabled_as_of`` before the enrollment was created.

        Only one of enrollment and (user, course_key) may be specified at a time.

        Arguments:
            enrollment: The enrollment being queried.
            user: The user being queried.
            course_key: The CourseKey of the course being queried.
        """
        if CONTENT_TYPE_GATING_FLAG.is_enabled():
            return True

        if enrollment is not None and (user is not None
                                       or course_key is not None):
            raise ValueError(
                'Specify enrollment or user/course_key, but not both')

        if enrollment is None and (user is None or course_key is None):
            raise ValueError(
                'Both user and course_key must be specified if no enrollment is provided'
            )

        if enrollment is None and user is None and course_key is None:
            raise ValueError(
                'At least one of enrollment or user and course_key must be specified'
            )

        if course_key is None:
            course_key = enrollment.course_id

        if enrollment is None:
            enrollment = CourseEnrollment.get_enrollment(user, course_key)

        # if the user is has a role of staff, instructor or beta tester their access should not expire
        if user is None and enrollment is not None:
            user = enrollment.user

        if user:
            course_masquerade = get_course_masquerade(user, course_key)
            if course_masquerade:
                verified_mode_id = settings.COURSE_ENROLLMENT_MODES.get(
                    CourseMode.VERIFIED, {}).get('id')
                is_verified = (course_masquerade.user_partition_id
                               == ENROLLMENT_TRACK_PARTITION_ID and
                               course_masquerade.group_id == verified_mode_id)
                is_full_access = (
                    course_masquerade.user_partition_id
                    == CONTENT_GATING_PARTITION_ID
                    and course_masquerade.group_id
                    == CONTENT_TYPE_GATE_GROUP_IDS['full_access'])
                is_staff = get_masquerade_role(user, course_key) == 'staff'
                if is_verified or is_full_access or is_staff:
                    return False
            else:
                staff_role = CourseStaffRole(course_key).has_user(user)
                instructor_role = CourseInstructorRole(course_key).has_user(
                    user)
                beta_tester_role = CourseBetaTesterRole(course_key).has_user(
                    user)

                if staff_role or instructor_role or beta_tester_role:
                    return False

        # enrollment might be None if the user isn't enrolled. In that case,
        # return enablement as if the user enrolled today
        if enrollment is None:
            return cls.enabled_for_course(course_key=course_key,
                                          target_datetime=timezone.now())
        else:
            # TODO: clean up as part of REV-100
            experiment_data_holdback_key = EXPERIMENT_DATA_HOLDBACK_KEY.format(
                user)
            is_in_holdback = False
            no_masquerade = get_course_masquerade(user, course_key) is None
            student_masquerade = is_masquerading_as_specific_student(
                user, course_key)
            if user and (no_masquerade or student_masquerade):
                try:
                    holdback_value = ExperimentData.objects.get(
                        user=user,
                        experiment_id=EXPERIMENT_ID,
                        key=experiment_data_holdback_key,
                    ).value
                    is_in_holdback = holdback_value == 'True'
                except ExperimentData.DoesNotExist:
                    pass
            if is_in_holdback:
                return False
            current_config = cls.current(course_key=enrollment.course_id)
            return current_config.enabled_as_of_datetime(
                target_datetime=enrollment.created)