Ejemplo n.º 1
0
    def filtered_list(cls):
        """
        Filter fields based on feature flag, i.e. enabled, disabled.
        """
        # Copy the filtered list to avoid permanently changing the class attribute.
        filtered_list = list(cls.FILTERED_LIST)

        # Do not show giturl if feature is not enabled.
        if not settings.FEATURES.get('ENABLE_EXPORT_GIT'):
            filtered_list.append('giturl')

        # Do not show edxnotes if the feature is disabled.
        if not settings.FEATURES.get('ENABLE_EDXNOTES'):
            filtered_list.append('edxnotes')

        # Do not show video_upload_pipeline if the feature is disabled.
        if not settings.FEATURES.get('ENABLE_VIDEO_UPLOAD_PIPELINE'):
            filtered_list.append('video_upload_pipeline')

        # Do not show social sharing url field if the feature is disabled.
        if (not hasattr(settings, 'SOCIAL_SHARING_SETTINGS')
                or not getattr(settings, 'SOCIAL_SHARING_SETTINGS',
                               {}).get("CUSTOM_COURSE_URLS")):
            filtered_list.append('social_sharing_url')

        # Do not show teams configuration if feature is disabled.
        if not settings.FEATURES.get('ENABLE_TEAMS'):
            filtered_list.append('teams_configuration')

        if not settings.FEATURES.get('ENABLE_VIDEO_BUMPER'):
            filtered_list.append('video_bumper')

        # Do not show enable_ccx if feature is not enabled.
        if not settings.FEATURES.get('CUSTOM_COURSES_EDX'):
            filtered_list.append('enable_ccx')
            filtered_list.append('ccx_connector')

        # Do not show "Issue Open Badges" in Studio Advanced Settings
        # if the feature is disabled.
        if not settings.FEATURES.get('ENABLE_OPENBADGES'):
            filtered_list.append('issue_badges')

        # If the XBlockStudioConfiguration table is not being used, there is no need to
        # display the "Allow Unsupported XBlocks" setting.
        if not XBlockStudioConfigurationFlag.is_enabled():
            filtered_list.append('allow_unsupported_xblocks')

        # TODO: https://openedx.atlassian.net/browse/EDUCATOR-736
        # Before we roll out the auto-certs feature, move this to a good, shared
        # place such that we're not repeating code found in LMS.
        switches = WaffleSwitchNamespace(name=u'certificates',
                                         log_prefix=u'Certificates: ')
        if not switches.is_enabled(u'instructor_paced_only'):
            filtered_list.append('certificate_available_date')

        return filtered_list
Ejemplo n.º 2
0
    def filtered_list(cls):
        """
        Filter fields based on feature flag, i.e. enabled, disabled.
        """
        # Copy the filtered list to avoid permanently changing the class attribute.
        filtered_list = list(cls.FILTERED_LIST)

        # Do not show giturl if feature is not enabled.
        if not settings.FEATURES.get('ENABLE_EXPORT_GIT'):
            filtered_list.append('giturl')

        # Do not show edxnotes if the feature is disabled.
        if not settings.FEATURES.get('ENABLE_EDXNOTES'):
            filtered_list.append('edxnotes')

        # Do not show video_upload_pipeline if the feature is disabled.
        if not settings.FEATURES.get('ENABLE_VIDEO_UPLOAD_PIPELINE'):
            filtered_list.append('video_upload_pipeline')

        # Do not show social sharing url field if the feature is disabled.
        if (not hasattr(settings, 'SOCIAL_SHARING_SETTINGS') or
                not getattr(settings, 'SOCIAL_SHARING_SETTINGS', {}).get("CUSTOM_COURSE_URLS")):
            filtered_list.append('social_sharing_url')

        # Do not show teams configuration if feature is disabled.
        if not settings.FEATURES.get('ENABLE_TEAMS'):
            filtered_list.append('teams_configuration')

        if not settings.FEATURES.get('ENABLE_VIDEO_BUMPER'):
            filtered_list.append('video_bumper')

        # Do not show enable_ccx if feature is not enabled.
        if not settings.FEATURES.get('CUSTOM_COURSES_EDX'):
            filtered_list.append('enable_ccx')
            filtered_list.append('ccx_connector')

        # Do not show "Issue Open Badges" in Studio Advanced Settings
        # if the feature is disabled.
        if not settings.FEATURES.get('ENABLE_OPENBADGES'):
            filtered_list.append('issue_badges')

        # If the XBlockStudioConfiguration table is not being used, there is no need to
        # display the "Allow Unsupported XBlocks" setting.
        if not XBlockStudioConfigurationFlag.is_enabled():
            filtered_list.append('allow_unsupported_xblocks')

        # TODO: https://openedx.atlassian.net/browse/EDUCATOR-736
        # Before we roll out the auto-certs feature, move this to a good, shared
        # place such that we're not repeating code found in LMS.
        switches = WaffleSwitchNamespace(name=u'certificates', log_prefix=u'Certificates: ')
        if not switches.is_enabled(u'instructor_paced_only'):
            filtered_list.append('certificate_available_date')

        return filtered_list
Ejemplo n.º 3
0
    def test_create_schedule(self):
        """ A schedule should be created for every new enrollment if the switch is active. """

        SWITCH_NAME = 'enable-create-schedule-receiver'
        switch_namesapce = WaffleSwitchNamespace('schedules')

        with switch_namesapce.override(SWITCH_NAME, True):
            enrollment = CourseEnrollmentFactory()
            self.assertIsNotNone(enrollment.schedule)

        with switch_namesapce.override(SWITCH_NAME, False):
            enrollment = CourseEnrollmentFactory()
            with self.assertRaises(Schedule.DoesNotExist):
                enrollment.schedule
Ejemplo n.º 4
0
def create_schedule(sender, **kwargs):
    if WaffleSwitchNamespace('schedules').is_enabled(
            'enable-create-schedule-receiver') and kwargs['created']:
        enrollment = kwargs['instance']
        upgrade_deadline = _get_upgrade_deadline(enrollment)
        Schedule.objects.create(enrollment=enrollment,
                                start=timezone.now(),
                                upgrade_deadline=upgrade_deadline)
Ejemplo n.º 5
0
    def setUp(self):
        """
        Add courses with the end date set to various values
        """
        super(TestCourseIndexArchived, self).setUp()

        # Base course has no end date (so is active)
        self.course.end = None
        self.course.display_name = 'Active Course 1'
        self.ORG = self.course.location.org
        self.save_course()

        # Active course has end date set to tomorrow
        self.active_course = CourseFactory.create(
            display_name='Active Course 2',
            org=self.ORG,
            end=self.TOMORROW,
        )

        # Archived course has end date set to yesterday
        self.archived_course = CourseFactory.create(
            display_name='Archived Course',
            org=self.ORG,
            end=self.YESTERDAY,
        )

        # Base user has global staff access
        self.assertTrue(GlobalStaff().has_user(self.user))

        # Staff user just has course staff access
        self.staff, self.staff_password = self.create_non_staff_user()
        for course in (self.course, self.active_course, self.archived_course):
            CourseStaffRole(course.id).add_users(self.staff)

        # Make sure we've cached data which could change the query counts
        # depending on test execution order
        WaffleSwitchNamespace(name=COURSE_WAFFLE_NAMESPACE).is_enabled(
            u'enable_global_staff_optimization')
        WaffleSwitchNamespace(
            name=STUDIO_WAFFLE_NAMESPACE).is_enabled(u'enable_policy_page')
        WaffleSwitchNamespace(name=DJANGO_UTILS_NAMESPACE).is_enabled(
            u'enable_memory_middleware')
Ejemplo n.º 6
0
def waffle():
    """
    Returns the namespaced, cached, audited Waffle class for open_edx_util.
    """
    return WaffleSwitchNamespace(name=WAFFLE_NAMESPACE,
                                 log_prefix=u'OpenEdX Util: ')
Ejemplo n.º 7
0
def waffle_switch():
    """
    Returns the namespaced, cached, audited Waffle class for course experience.
    """
    return WaffleSwitchNamespace(name=WAFFLE_NAMESPACE, log_prefix='course_experience: ')
Ejemplo n.º 8
0
def waffle():
    """
    Returns the namespaced, cached, audited Waffle Switch class for Studio pages.
    """
    return WaffleSwitchNamespace(name=WAFFLE_NAMESPACE, log_prefix=u'Studio: ')
Ejemplo n.º 9
0
"""
This module contains various configuration settings via
waffle switches for the instructor_task app.
"""

from openedx.core.djangoapps.waffle_utils import WaffleFlagNamespace, WaffleSwitchNamespace

WAFFLE_NAMESPACE = u'instructor_task'
INSTRUCTOR_TASK_WAFFLE_FLAG_NAMESPACE = WaffleFlagNamespace(
    name=WAFFLE_NAMESPACE)
WAFFLE_SWITCHES = WaffleSwitchNamespace(name=WAFFLE_NAMESPACE)

# Waffle switches
OPTIMIZE_GET_LEARNERS_FOR_COURSE = u'optimize_get_learners_for_course'
GENERATE_GRADE_REPORT_VERIFIED_ONLY = u'generate_grade_report_for_verified_only'


def waffle_flags():
    """
    Returns the namespaced, cached, audited Waffle flags dictionary for Grades.
    """
    return {}


def optimize_get_learners_switch_enabled():
    """
    Returns True if optimize get learner switch is enabled, otherwise False.
    """
    return WAFFLE_SWITCHES.is_enabled(OPTIMIZE_GET_LEARNERS_FOR_COURSE)

Ejemplo n.º 10
0
def waffle():
    """
    Returns the namespaced, cached, audited shared Waffle Switch class.
    """
    return WaffleSwitchNamespace(name=WAFFLE_NAMESPACE, log_prefix=u'Course Experience: ')
Ejemplo n.º 11
0
"""
Platform support for Programs.

This package is a thin wrapper around interactions with the Programs service,
supporting learner- and author-facing features involving that service
if and only if the service is deployed in the Open edX installation.

To ensure maximum separation of concerns, and a minimum of interdependencies,
this package should be kept small, thin, and stateless.
"""
from openedx.core.djangoapps.waffle_utils import (WaffleSwitch,
                                                  WaffleSwitchNamespace)

PROGRAMS_WAFFLE_SWITCH_NAMESPACE = WaffleSwitchNamespace(name='programs')

# This is meant to be enabled until https://openedx.atlassian.net/browse/LEARNER-5573 needs to be resolved
ALWAYS_CALCULATE_PROGRAM_PRICE_AS_ANONYMOUS_USER = WaffleSwitch(
    PROGRAMS_WAFFLE_SWITCH_NAMESPACE,
    'always_calculate_program_price_as_anonymous_user')
Ejemplo n.º 12
0
def waffle():
    """
    Returns the namespaced, cached, audited Waffle class for user_api.
    """
    return WaffleSwitchNamespace(name=WAFFLE_NAMESPACE,
                                 log_prefix=u'UserAPI: ')
Ejemplo n.º 13
0
def waffle():
    """
    Returns the namespaced, cached, audited Waffle class for completion.
    """
    return WaffleSwitchNamespace(name=WAFFLE_NAMESPACE,
                                 log_prefix='completion: ')
 def _is_enabled(self):
     """
     Returns whether this middleware is enabled.
     """
     return WaffleSwitchNamespace(
         name=WAFFLE_NAMESPACE).is_enabled(u'enable_memory_middleware')
Ejemplo n.º 15
0
""" Course API """

from openedx.core.djangoapps.waffle_utils import WaffleSwitch, WaffleSwitchNamespace

WAFFLE_SWITCH_NAMESPACE = WaffleSwitchNamespace(
    name='course_list_api_rate_limit')

# .. toggle_name: course_list_api_rate_limit.rate_limit_2
# .. toggle_implementation: WaffleSwitch
# .. toggle_default: False
# .. toggle_description: Waffle switch to enable the throttling of 2 requests/minute to the course API. For staff
#   users, this limit is 10 requests/minute.
# .. toggle_use_cases: circuit_breaker
# .. toggle_creation_date: 2018-06-12
# .. toggle_tickets: https://openedx.atlassian.net/browse/LEARNER-5527
USE_RATE_LIMIT_2_FOR_COURSE_LIST_API = WaffleSwitch(WAFFLE_SWITCH_NAMESPACE,
                                                    'rate_limit_2', __name__)
# .. toggle_name: course_list_api_rate_limit.rate_limit_10
# .. toggle_implementation: WaffleSwitch
# .. toggle_default: False
# .. toggle_description: Waffle switch to enable the throttling of 10 requests/minute to the course API. For staff
#   users, this limit is 20 requests/minute.
# .. toggle_use_cases: circuit_breaker
# .. toggle_creation_date: 2018-06-12
# .. toggle_tickets: https://openedx.atlassian.net/browse/LEARNER-5527
USE_RATE_LIMIT_10_FOR_COURSE_LIST_API = WaffleSwitch(WAFFLE_SWITCH_NAMESPACE,
                                                     'rate_limit_10', __name__)
Ejemplo n.º 16
0
    def _create_courseware_context(self, request):
        """
        Returns and creates the rendering context for the courseware.
        Also returns the table of contents for the courseware.
        """
        course_url_name = default_course_url_name(self.course.id)
        course_url = reverse(
            course_url_name,
            kwargs={'course_id': six.text_type(self.course.id)})
        show_search = (
            settings.FEATURES.get('ENABLE_COURSEWARE_SEARCH') or
            (settings.FEATURES.get('ENABLE_COURSEWARE_SEARCH_FOR_COURSE_STAFF')
             and self.is_staff))
        staff_access = self.is_staff

        reset_deadlines_url = reverse(
            'openedx.course_experience.reset_course_deadlines',
            kwargs={'course_id': six.text_type(self.course.id)})

        allow_anonymous = allow_public_access(self.course,
                                              [COURSE_VISIBILITY_PUBLIC])
        display_reset_dates_banner = False
        if not allow_anonymous and RELATIVE_DATES_FLAG.is_enabled(
                self.course.id):  # pylint: disable=too-many-nested-blocks
            course_overview = CourseOverview.objects.get(
                id=str(self.course_key))
            end_date = getattr(course_overview, 'end_date')
            if course_overview.self_paced and (not end_date
                                               or timezone.now() < end_date):
                if (CourseEnrollment.objects.filter(
                        course=course_overview,
                        user=request.user,
                        mode=CourseMode.VERIFIED).exists()):
                    course_block_tree = get_course_outline_block_tree(
                        request, str(self.course_key), request.user)
                    course_sections = course_block_tree.get('children', [])
                    for section in course_sections:
                        if display_reset_dates_banner:
                            break
                        for subsection in section.get('children', []):
                            if (not subsection.get('complete', True)
                                    and subsection.get(
                                        'due',
                                        timezone.now() + timedelta(1)) <
                                    timezone.now()):
                                display_reset_dates_banner = True
                                break

        courseware_context = {
            'csrf':
            csrf(self.request)['csrf_token'],
            'course':
            self.course,
            'course_url':
            course_url,
            'chapter':
            self.chapter,
            'section':
            self.section,
            'init':
            '',
            'fragment':
            Fragment(),
            'staff_access':
            staff_access,
            'can_masquerade':
            self.can_masquerade,
            'masquerade':
            self.masquerade,
            'supports_preview_menu':
            True,
            'studio_url':
            get_studio_url(self.course, 'course'),
            'xqa_server':
            settings.FEATURES.get('XQA_SERVER', "http://your_xqa_server.com"),
            'bookmarks_api_url':
            reverse('bookmarks'),
            'language_preference':
            self._get_language_preference(),
            'disable_optimizely':
            not WaffleSwitchNamespace('RET').is_enabled(
                'enable_optimizely_in_courseware'),
            'section_title':
            None,
            'sequence_title':
            None,
            'disable_accordion':
            COURSE_OUTLINE_PAGE_FLAG.is_enabled(self.course.id),
            'show_search':
            show_search,
            'relative_dates_is_enabled':
            RELATIVE_DATES_FLAG.is_enabled(self.course.id),
            'reset_deadlines_url':
            reset_deadlines_url,
            'display_reset_dates_banner':
            display_reset_dates_banner,
        }
        courseware_context.update(
            get_experiment_user_metadata_context(
                self.course,
                self.effective_user,
            ))
        table_of_contents = toc_for_course(
            self.effective_user,
            self.request,
            self.course,
            self.chapter_url_name,
            self.section_url_name,
            self.field_data_cache,
        )
        courseware_context['accordion'] = render_accordion(
            self.request,
            self.course,
            table_of_contents['chapters'],
        )

        courseware_context['course_sock_fragment'] = CourseSockFragmentView(
        ).render_to_fragment(request, course=self.course_overview)

        # entrance exam data
        self._add_entrance_exam_to_context(courseware_context)

        if self.section:
            # chromeless data
            if self.section.chrome:
                chrome = [
                    s.strip() for s in self.section.chrome.lower().split(",")
                ]
                if 'accordion' not in chrome:
                    courseware_context['disable_accordion'] = True
                if 'tabs' not in chrome:
                    courseware_context['disable_tabs'] = True

            # default tab
            if self.section.default_tab:
                courseware_context['default_tab'] = self.section.default_tab

            # section data
            courseware_context[
                'section_title'] = self.section.display_name_with_default
            section_context = self._create_section_context(
                table_of_contents['previous_of_active_section'],
                table_of_contents['next_of_active_section'],
            )
            courseware_context['fragment'] = self.section.render(
                self.view, section_context)

            if self.section.position and self.section.has_children:
                self._add_sequence_title_to_context(courseware_context)

        # Courseware MFE link
        if show_courseware_mfe_link(request.user, staff_access,
                                    self.course.id):
            if self.section:
                try:
                    unit_key = UsageKey.from_string(
                        request.GET.get('activate_block_id', ''))
                    # `activate_block_id` is typically a Unit (a.k.a. Vertical),
                    # but it can technically be any block type. Do a check to
                    # make sure it's really a Unit before we use it for the MFE.
                    if unit_key.block_type != 'vertical':
                        unit_key = None
                except InvalidKeyError:
                    unit_key = None

                courseware_context[
                    'microfrontend_link'] = get_microfrontend_url(
                        self.course.id, self.section.location, unit_key)
            else:
                courseware_context[
                    'microfrontend_link'] = get_microfrontend_url(
                        self.course.id)
        else:
            courseware_context['microfrontend_link'] = None

        return courseware_context
Ejemplo n.º 17
0
"""
Waffle flags and switches for user authn.
"""

from openedx.core.djangoapps.waffle_utils import WaffleSwitch, WaffleSwitchNamespace

_WAFFLE_NAMESPACE = u'user_authn'
_WAFFLE_SWITCH_NAMESPACE = WaffleSwitchNamespace(name=_WAFFLE_NAMESPACE,
                                                 log_prefix=u'UserAuthN: ')

# .. toggle_name: user_authn.enable_login_using_thirdparty_auth_only
# .. toggle_implementation: WaffleSwitch
# .. toggle_default: False
# .. toggle_description: When enabled, users must be sign in using their allowed domain SSO account. This includes sign-
#   ins to the Django admin dashboard at "/admin".
# .. toggle_use_cases: temporary
# .. toggle_creation_date: 2019-11-20
# .. toggle_target_removal_date: 2020-01-31
# .. toggle_warnings: Requires THIRD_PARTY_AUTH_ONLY_DOMAIN to also be set.
# .. toggle_tickets: ENT-2461
ENABLE_LOGIN_USING_THIRDPARTY_AUTH_ONLY = WaffleSwitch(
    _WAFFLE_SWITCH_NAMESPACE, 'enable_login_using_thirdparty_auth_only',
    __name__)
Ejemplo n.º 18
0
 def _is_switch_enabled(name):
     return WaffleSwitchNamespace(name=WAFFLE_NAMESPACE).is_enabled(name)
Ejemplo n.º 19
0
def waffle():
    """
    Returns the namespaced, cached, audited Waffle class for Accessibility Accomodation Request Page.
    """
    return WaffleSwitchNamespace(name=WAFFLE_NAMESPACE, log_prefix=u'Accessibility: ')
Ejemplo n.º 20
0
    def _create_courseware_context(self, request):
        """
        Returns and creates the rendering context for the courseware.
        Also returns the table of contents for the courseware.
        """
        course_url_name = default_course_url_name(request)
        course_url = reverse(course_url_name,
                             kwargs={'course_id': unicode(self.course.id)})
        courseware_context = {
            'csrf':
            csrf(self.request)['csrf_token'],
            'course':
            self.course,
            'course_url':
            course_url,
            'chapter':
            self.chapter,
            'section':
            self.section,
            'init':
            '',
            'fragment':
            Fragment(),
            'staff_access':
            self.is_staff,
            'masquerade':
            self.masquerade,
            'supports_preview_menu':
            True,
            'studio_url':
            get_studio_url(self.course, 'course'),
            'xqa_server':
            settings.FEATURES.get('XQA_SERVER', "http://your_xqa_server.com"),
            'bookmarks_api_url':
            reverse('bookmarks'),
            'language_preference':
            self._get_language_preference(),
            'disable_optimizely':
            not WaffleSwitchNamespace('RET').is_enabled(
                'enable_optimizely_in_courseware'),
            'section_title':
            None,
            'sequence_title':
            None,
            'disable_accordion':
            waffle.flag_is_active(request, UNIFIED_COURSE_VIEW_FLAG),
            # TODO: (Experimental Code). See https://openedx.atlassian.net/wiki/display/RET/2.+In-course+Verification+Prompts
            'upgrade_link':
            check_and_get_upgrade_link(request, self.effective_user,
                                       self.course.id),
            'upgrade_price':
            get_cosmetic_verified_display_price(self.course),
            # ENDTODO
        }
        table_of_contents = toc_for_course(
            self.effective_user,
            self.request,
            self.course,
            self.chapter_url_name,
            self.section_url_name,
            self.field_data_cache,
        )
        courseware_context['accordion'] = render_accordion(
            self.request,
            self.course,
            table_of_contents['chapters'],
        )

        courseware_context['course_sock_fragment'] = CourseSockFragmentView(
        ).render_to_fragment(request, course=self.course)

        # entrance exam data
        self._add_entrance_exam_to_context(courseware_context)

        # staff masquerading data
        if not is_course_open_for_learner(self.effective_user, self.course):
            # Disable student view button if user is staff and
            # course is not yet visible to students.
            courseware_context['disable_student_access'] = True
            courseware_context['supports_preview_menu'] = False

        if self.section:
            # chromeless data
            if self.section.chrome:
                chrome = [
                    s.strip() for s in self.section.chrome.lower().split(",")
                ]
                if 'accordion' not in chrome:
                    courseware_context['disable_accordion'] = True
                if 'tabs' not in chrome:
                    courseware_context['disable_tabs'] = True

            # default tab
            if self.section.default_tab:
                courseware_context['default_tab'] = self.section.default_tab

            # section data
            courseware_context[
                'section_title'] = self.section.display_name_with_default
            section_context = self._create_section_context(
                table_of_contents['previous_of_active_section'],
                table_of_contents['next_of_active_section'],
            )
            courseware_context['fragment'] = self.section.render(
                STUDENT_VIEW, section_context)
            if self.section.position and self.section.has_children:
                display_items = self.section.get_display_items()
                if display_items:
                    try:
                        courseware_context['sequence_title'] = display_items[self.section.position - 1] \
                            .display_name_with_default
                    except IndexError:
                        log.exception(
                            "IndexError loading courseware for user %s, course %s, section %s, position %d. Total items: %d. URL: %s",
                            self.real_user.username,
                            self.course.id,
                            self.section.display_name_with_default,
                            self.section.position,
                            len(display_items),
                            self.url,
                        )
                        raise
        return courseware_context
Ejemplo n.º 21
0
"""
Feature toggle code for oauth_dispatch.
"""

from __future__ import absolute_import

from edx_rest_framework_extensions.config import OAUTH_TOGGLE_NAMESPACE, SWITCH_ENFORCE_JWT_SCOPES

from openedx.core.djangoapps.waffle_utils import WaffleSwitch, WaffleSwitchNamespace

ENFORCE_JWT_SCOPES = WaffleSwitch(
    WaffleSwitchNamespace(name=OAUTH_TOGGLE_NAMESPACE),
    SWITCH_ENFORCE_JWT_SCOPES)
Ejemplo n.º 22
0
"""
This module contains various configuration settings via
waffle switches for the course_details view.
"""

from openedx.core.djangoapps.waffle_utils import (CourseWaffleFlag,
                                                  WaffleFlagNamespace,
                                                  WaffleSwitchNamespace)

COURSE_DETAIL_WAFFLE_NAMESPACE = 'course_detail'
COURSE_DETAIL_WAFFLE_FLAG_NAMESPACE = WaffleFlagNamespace(
    name=COURSE_DETAIL_WAFFLE_NAMESPACE)
WAFFLE_SWITCHES = WaffleSwitchNamespace(name=COURSE_DETAIL_WAFFLE_NAMESPACE)

# Course Override Flag
COURSE_DETAIL_UPDATE_CERTIFICATE_DATE = u'course_detail_update_certificate_date'


def waffle_flags():
    """
    Returns the namespaced, cached, audited Waffle flags dictionary for course detail.
    """
    return {
        COURSE_DETAIL_UPDATE_CERTIFICATE_DATE:
        CourseWaffleFlag(
            waffle_namespace=COURSE_DETAIL_WAFFLE_NAMESPACE,
            flag_name=COURSE_DETAIL_UPDATE_CERTIFICATE_DATE,
            flag_undefined_default=False,
        )
    }
Ejemplo n.º 23
0
    def _create_courseware_context(self, request):
        """
        Returns and creates the rendering context for the courseware.
        Also returns the table of contents for the courseware.
        """
        from lms.urls import RESET_COURSE_DEADLINES_NAME

        course_url_name = default_course_url_name(self.course.id)
        course_url = reverse(
            course_url_name,
            kwargs={'course_id': six.text_type(self.course.id)})
        show_search = (
            settings.FEATURES.get('ENABLE_COURSEWARE_SEARCH') or
            (settings.FEATURES.get('ENABLE_COURSEWARE_SEARCH_FOR_COURSE_STAFF')
             and self.is_staff))
        staff_access = self.is_staff

        allow_anonymous = check_public_access(self.course,
                                              [COURSE_VISIBILITY_PUBLIC])
        display_reset_dates_banner = False
        if not allow_anonymous and RELATIVE_DATES_FLAG.is_enabled(
                self.course.id):
            display_reset_dates_banner = reset_deadlines_banner_should_display(
                self.course_key, request)

        reset_deadlines_url = reverse(RESET_COURSE_DEADLINES_NAME
                                      ) if display_reset_dates_banner else None

        reset_deadlines_redirect_url_base = COURSE_HOME_VIEW_NAME if reset_deadlines_url else None

        courseware_context = {
            'csrf':
            csrf(self.request)['csrf_token'],
            'course':
            self.course,
            'course_url':
            course_url,
            'chapter':
            self.chapter,
            'section':
            self.section,
            'init':
            '',
            'fragment':
            Fragment(),
            'staff_access':
            staff_access,
            'can_masquerade':
            self.can_masquerade,
            'masquerade':
            self.masquerade,
            'supports_preview_menu':
            True,
            'studio_url':
            get_studio_url(self.course, 'course'),
            'xqa_server':
            settings.FEATURES.get('XQA_SERVER', "http://your_xqa_server.com"),
            'bookmarks_api_url':
            reverse('bookmarks'),
            'language_preference':
            self._get_language_preference(),
            'disable_optimizely':
            not WaffleSwitchNamespace('RET').is_enabled(
                'enable_optimizely_in_courseware'),
            'section_title':
            None,
            'sequence_title':
            None,
            'disable_accordion':
            COURSE_OUTLINE_PAGE_FLAG.is_enabled(self.course.id),
            'show_search':
            show_search,
            'relative_dates_is_enabled':
            RELATIVE_DATES_FLAG.is_enabled(self.course.id),
            'display_reset_dates_banner':
            display_reset_dates_banner,
            'reset_deadlines_url':
            reset_deadlines_url,
            'reset_deadlines_redirect_url_base':
            reset_deadlines_redirect_url_base,
            'reset_deadlines_redirect_url_id_dict': {
                'course_id': str(self.course.id)
            },
        }
        courseware_context.update(
            get_experiment_user_metadata_context(
                self.course,
                self.effective_user,
            ))
        table_of_contents = toc_for_course(
            self.effective_user,
            self.request,
            self.course,
            self.chapter_url_name,
            self.section_url_name,
            self.field_data_cache,
        )
        courseware_context['accordion'] = render_accordion(
            self.request,
            self.course,
            table_of_contents['chapters'],
        )

        courseware_context['course_sock_fragment'] = CourseSockFragmentView(
        ).render_to_fragment(request, course=self.course)

        # entrance exam data
        self._add_entrance_exam_to_context(courseware_context)

        if self.section:
            # chromeless data
            if self.section.chrome:
                chrome = [
                    s.strip() for s in self.section.chrome.lower().split(",")
                ]
                if 'accordion' not in chrome:
                    courseware_context['disable_accordion'] = True
                if 'tabs' not in chrome:
                    courseware_context['disable_tabs'] = True

            # default tab
            if self.section.default_tab:
                courseware_context['default_tab'] = self.section.default_tab

            # section data
            courseware_context[
                'section_title'] = self.section.display_name_with_default
            section_context = self._create_section_context(
                table_of_contents['previous_of_active_section'],
                table_of_contents['next_of_active_section'],
            )
            courseware_context['fragment'] = self.section.render(
                self.view, section_context)

            if self.section.position and self.section.has_children:
                self._add_sequence_title_to_context(courseware_context)

        # Courseware MFE link
        if show_courseware_mfe_link(request.user, staff_access,
                                    self.course.id):
            courseware_context['microfrontend_link'] = self.microfrontend_url
        else:
            courseware_context['microfrontend_link'] = None

        return courseware_context
def waffle():
    """
    Returns the namespaced and cached Waffle class for BlockStructures.
    """
    return WaffleSwitchNamespace(name=WAFFLE_NAMESPACE,
                                 log_prefix=u'BlockStructure: ')
Ejemplo n.º 25
0
from opaque_keys.edx.keys import CourseKey
from openedx.core.djangoapps.user_api.accounts.image_helpers import (
    _get_default_profile_image_urls, _get_profile_image_urls,
    _make_profile_image_name, get_profile_image_storage)
from openedx.core.djangoapps.user_api.accounts.serializers import PROFILE_IMAGE_KEY_PREFIX
from openedx.core.djangoapps.waffle_utils import WaffleSwitchNamespace
from PIL import Image
from rest_framework.exceptions import ParseError
from student.roles import CourseObserverRole, CourseRole

USER_METRICS_CACHE_TTL = 60 * 60
COURSE_METRICS_CACHE_TTL = 30 * 60

COHORT_NAMESPACE = 'course_groups'
COHORT_SWITCH = 'enable_apros_integration'
WAFFLE_COHORT_SWITCHES = WaffleSwitchNamespace(name=COHORT_NAMESPACE)


def address_exists_in_network(ip_address, net_n_bits):
    """
    return True if the ip address exists in the subnet address
    otherwise return False
    """
    ip_address = struct.unpack('<L', socket.inet_aton(ip_address))[0]
    net, bits = net_n_bits.split('/')
    net_address = struct.unpack('<L', socket.inet_aton(net))[0]
    net_mask = ((1 << int(bits)) - 1)
    return ip_address & net_mask == net_address & net_mask


def get_client_ip_address(request):
Ejemplo n.º 26
0
    def _create_courseware_context(self, request):
        """
        Returns and creates the rendering context for the courseware.
        Also returns the table of contents for the courseware.
        """
        course_url_name = default_course_url_name(self.course.id)
        course_url = reverse(course_url_name,
                             kwargs={'course_id': unicode(self.course.id)})

        courseware_context = {
            'csrf':
            csrf(self.request)['csrf_token'],
            'course':
            self.course,
            'course_url':
            course_url,
            'chapter':
            self.chapter,
            'section':
            self.section,
            'init':
            '',
            'fragment':
            Fragment(),
            'staff_access':
            self.is_staff,
            'masquerade':
            self.masquerade,
            'supports_preview_menu':
            True,
            'studio_url':
            get_studio_url(self.course, 'course'),
            'xqa_server':
            settings.FEATURES.get('XQA_SERVER', "http://your_xqa_server.com"),
            'bookmarks_api_url':
            reverse('bookmarks'),
            'language_preference':
            self._get_language_preference(),
            'disable_optimizely':
            not WaffleSwitchNamespace('RET').is_enabled(
                'enable_optimizely_in_courseware'),
            'section_title':
            None,
            'sequence_title':
            None,
            'disable_accordion':
            COURSE_OUTLINE_PAGE_FLAG.is_enabled(self.course.id),
        }
        courseware_context.update(
            get_experiment_user_metadata_context(
                self.course,
                self.effective_user,
            ))
        table_of_contents = toc_for_course(
            self.effective_user,
            self.request,
            self.course,
            self.chapter_url_name,
            self.section_url_name,
            self.field_data_cache,
        )
        courseware_context['accordion'] = render_accordion(
            self.request,
            self.course,
            table_of_contents['chapters'],
        )

        courseware_context['course_sock_fragment'] = CourseSockFragmentView(
        ).render_to_fragment(request, course=self.course)

        # entrance exam data
        self._add_entrance_exam_to_context(courseware_context)

        if self.section:
            # chromeless data
            if self.section.chrome:
                chrome = [
                    s.strip() for s in self.section.chrome.lower().split(",")
                ]
                if 'accordion' not in chrome:
                    courseware_context['disable_accordion'] = True
                if 'tabs' not in chrome:
                    courseware_context['disable_tabs'] = True

            # default tab
            if self.section.default_tab:
                courseware_context['default_tab'] = self.section.default_tab

            # section data
            courseware_context[
                'section_title'] = self.section.display_name_with_default
            section_context = self._create_section_context(
                table_of_contents['previous_of_active_section'],
                table_of_contents['next_of_active_section'],
            )

            courseware_context['fragment'] = self.section.render(
                self.view, section_context)

            if self.section.position and self.section.has_children:
                self._add_sequence_title_to_context(courseware_context)

        return courseware_context
Ejemplo n.º 27
0
"""
Contains configuration for schedules app
"""

from openedx.core.djangoapps.waffle_utils import (
    WaffleFlagNamespace,
    CourseWaffleFlag,
    WaffleFlag,
    WaffleSwitch,
    WaffleSwitchNamespace,
)

WAFFLE_FLAG_NAMESPACE = WaffleFlagNamespace(name=u'schedules')
WAFFLE_SWITCH_NAMESPACE = WaffleSwitchNamespace(name=u'schedules')

CREATE_SCHEDULE_WAFFLE_FLAG = CourseWaffleFlag(
    waffle_namespace=WAFFLE_FLAG_NAMESPACE,
    flag_name=u'create_schedules_for_course',
)

COURSE_UPDATE_WAFFLE_FLAG = CourseWaffleFlag(
    waffle_namespace=WAFFLE_FLAG_NAMESPACE,
    flag_name=u'send_updates_for_course',
)

DEBUG_MESSAGE_WAFFLE_FLAG = WaffleFlag(WAFFLE_FLAG_NAMESPACE,
                                       u'enable_debugging')

COURSE_UPDATE_SHOW_UNSUBSCRIBE_WAFFLE_SWITCH = WaffleSwitch(
    WAFFLE_SWITCH_NAMESPACE, u'course_update_show_unsubscribe')
Ejemplo n.º 28
0
"""
Enrollment API helpers and settings
"""
from openedx.core.djangoapps.waffle_utils import (WaffleSwitch,
                                                  WaffleSwitchNamespace)

WAFFLE_SWITCH_NAMESPACE = WaffleSwitchNamespace(
    name='enrollment_api_rate_limit')

USE_RATE_LIMIT_400_FOR_STAFF_FOR_ENROLLMENT_API = WaffleSwitch(
    WAFFLE_SWITCH_NAMESPACE, 'staff_rate_limit_400')
USE_RATE_LIMIT_100_FOR_STAFF_FOR_ENROLLMENT_API = WaffleSwitch(
    WAFFLE_SWITCH_NAMESPACE, 'staff_rate_limit_100')
USE_RATE_LIMIT_40_FOR_ENROLLMENT_API = WaffleSwitch(WAFFLE_SWITCH_NAMESPACE,
                                                    'rate_limit_40')
Ejemplo n.º 29
0
"""
Student app helpers and settings
"""
from __future__ import absolute_import

from openedx.core.djangoapps.waffle_utils import WaffleSwitchNamespace

# Namespace for student app waffle switches
STUDENT_WAFFLE_NAMESPACE = WaffleSwitchNamespace(name='student')
Ejemplo n.º 30
0
def waffle():
    """
    Returns the namespaced, cached, audited Waffle class for Certificates.
    """
    return WaffleSwitchNamespace(name=WAFFLE_NAMESPACE,
                                 log_prefix=u'Certificates: ')
Ejemplo n.º 31
0
"""
Waffle flags and switches for user authn.
"""
from __future__ import absolute_import

from openedx.core.djangoapps.waffle_utils import WaffleSwitchNamespace

WAFFLE_NAMESPACE = u'user_authn'

# If this switch is enabled then users must be sign in using their allowed domain SSO account
ENABLE_LOGIN_USING_THIRDPARTY_AUTH_ONLY = 'enable_login_using_thirdparty_auth_only'

waffle = WaffleSwitchNamespace(name=WAFFLE_NAMESPACE,
                               log_prefix=u'UserAuthN: ')