示例#1
0
def get_journals(site):
    """Retrieve journals from the discovery service.

    Keyword Arguments:
        site (Site): Site object for the request
        will be returned

    Returns:
        list of dict, representing journals
    """
    if not journals_enabled():
        return []

    api_resource = 'journals'
    orgs = configuration_helpers.get_current_site_orgs()

    cache_key = get_cache_key(
        site_domain=site.domain,
        resource=api_resource,
        orgs=orgs
    )

    # look up in cache
    journals = cache.get(cache_key)

    if not journals:
        api_client = DiscoveryApiClient()
        if not api_client:
            return []
        journals = api_client.get_journals(orgs)
        cache.set(cache_key, journals, JOURNALS_CACHE_TIMEOUT)

    return journals
示例#2
0
def get_journals(site):
    """Retrieve journals from the discovery service.

    Keyword Arguments:
        site (Site): Site object for the request
        will be returned

    Returns:
        list of dict, representing journals
    """
    if not journals_enabled():
        return []

    api_resource = 'journals'
    orgs = configuration_helpers.get_current_site_orgs()

    cache_key = get_cache_key(site_domain=site.domain,
                              resource=api_resource,
                              orgs=orgs)

    # look up in cache
    journals = cache.get(cache_key)

    if not journals:
        api_client = DiscoveryApiClient()
        if not api_client:
            return []
        journals = api_client.get_journals(orgs)
        cache.set(cache_key, journals, JOURNALS_CACHE_TIMEOUT)

    return journals
示例#3
0
def get_visible_courses(org=None, filter_=None):
    """
    Yield the CourseOverviews that should be visible in this branded
    instance.

    Arguments:
        org (string): Optional parameter that allows case-insensitive
            filtering by organization.
        filter_ (dict): Optional parameter that allows custom filtering by
            fields on the course.
    """
    # Import is placed here to avoid model import at project startup.
    from openedx.core.djangoapps.content.course_overviews.models import CourseOverview

    current_site_orgs = configuration_helpers.get_current_site_orgs()

    courses = CourseOverview.objects.none()

    if org:
        # Check the current site's orgs to make sure the org's courses should be displayed
        if not current_site_orgs or org in current_site_orgs:
            courses = CourseOverview.get_all_courses(orgs=[org],
                                                     filter_=filter_)
    elif current_site_orgs:
        # Only display courses that should be displayed on this site
        courses = CourseOverview.get_all_courses(orgs=current_site_orgs,
                                                 filter_=filter_)
    else:
        courses = CourseOverview.get_all_courses(filter_=filter_)

    courses = courses.order_by('id')

    # Filtering can stop here.
    if current_site_orgs:
        return courses

    # See if we have filtered course listings in this domain
    filtered_visible_ids = None

    # this is legacy format, which also handle dev case, which should not filter
    subdomain = configuration_helpers.get_value('subdomain', 'default')
    if hasattr(
            settings, 'COURSE_LISTINGS'
    ) and subdomain in settings.COURSE_LISTINGS and not settings.DEBUG:
        filtered_visible_ids = frozenset([
            CourseKey.from_string(c)
            for c in settings.COURSE_LISTINGS[subdomain]
        ])

    if filtered_visible_ids:
        return courses.filter(id__in=filtered_visible_ids)
    else:
        # Filter out any courses based on current org, to avoid leaking these.
        orgs = configuration_helpers.get_all_orgs()
        return courses.exclude(org__in=orgs)
示例#4
0
def get_visible_courses(org=None, filter_=None):
    """
    Return the set of CourseOverviews that should be visible in this branded
    instance.

    Arguments:
        org (string): Optional parameter that allows case-insensitive
            filtering by organization.
        filter_ (dict): Optional parameter that allows custom filtering by
            fields on the course.
    """
    courses = []
    current_site_orgs = configuration_helpers.get_current_site_orgs()

    if org:
        # Check the current site's orgs to make sure the org's courses should be displayed
        if not current_site_orgs or org in current_site_orgs:
            courses = CourseOverview.get_all_courses(orgs=[org],
                                                     filter_=filter_)
    elif current_site_orgs:
        # Only display courses that should be displayed on this site
        courses = CourseOverview.get_all_courses(orgs=current_site_orgs,
                                                 filter_=filter_)
    else:
        courses = CourseOverview.get_all_courses(filter_=filter_)

    courses = sorted(courses, key=lambda course: course.number)

    # Filtering can stop here.
    if current_site_orgs:
        return courses

    # See if we have filtered course listings in this domain
    filtered_visible_ids = None

    # this is legacy format, which also handle dev case, which should not filter
    subdomain = configuration_helpers.get_value('subdomain', 'default')
    if hasattr(
            settings, 'COURSE_LISTINGS'
    ) and subdomain in settings.COURSE_LISTINGS and not settings.DEBUG:
        filtered_visible_ids = frozenset([
            CourseKey.from_string(c)
            for c in settings.COURSE_LISTINGS[subdomain]
        ])

    if filtered_visible_ids:
        return [
            course for course in courses if course.id in filtered_visible_ids
        ]
    else:
        # Filter out any courses based on current org, to avoid leaking these.
        orgs = configuration_helpers.get_all_orgs()
        return [
            course for course in courses if course.location.org not in orgs
        ]
    def exclude_dictionary(self, **kwargs):
        """
            Exclude any courses defined outside the current org.
        """
        exclude_dictionary = super(LmsSearchFilterGenerator, self).exclude_dictionary(**kwargs)
        course_org_filter = configuration_helpers.get_current_site_orgs()
        # If we have a course filter we are ensuring that we only get those courses above
        if not course_org_filter:
            org_filter_out_set = configuration_helpers.get_all_orgs()
            if org_filter_out_set:
                exclude_dictionary['org'] = list(org_filter_out_set)

        return exclude_dictionary
    def exclude_dictionary(self, **kwargs):
        """
            Exclude any courses defined outside the current org.
        """
        exclude_dictionary = super(LmsSearchFilterGenerator, self).exclude_dictionary(**kwargs)
        course_org_filter = configuration_helpers.get_current_site_orgs()
        # If we have a course filter we are ensuring that we only get those courses above
        if not course_org_filter:
            org_filter_out_set = configuration_helpers.get_all_orgs()
            if org_filter_out_set:
                exclude_dictionary['org'] = list(org_filter_out_set)

        return exclude_dictionary
示例#7
0
def filter_authorized_organizations_from_list(organizations, is_super_user):
    """
    Filter organizations list on the basis of configured site organizations.
    """
    if not is_super_user:
        site_orgs = configuration_helpers.get_current_site_orgs()
        org_names_list = []
        for org in organizations:
            if (org["name"] in site_orgs) or (org["short_name"] in site_orgs):
                org_names_list.append(org["short_name"])
    else:
        org_names_list = [org["short_name"] for org in organizations]

    return org_names_list
示例#8
0
def get_visible_courses(org=None, filter_=None):
    """
    Yield the CourseOverviews that should be visible in this branded
    instance.

    Arguments:
        org (string): Optional parameter that allows case-insensitive
            filtering by organization.
        filter_ (dict): Optional parameter that allows custom filtering by
            fields on the course.
    """
    # Import is placed here to avoid model import at project startup.
    from openedx.core.djangoapps.content.course_overviews.models import CourseOverview

    current_site_orgs = configuration_helpers.get_current_site_orgs()

    courses = CourseOverview.objects.none()

    if org:
        # Check the current site's orgs to make sure the org's courses should be displayed
        if not current_site_orgs or org in current_site_orgs:
            courses = CourseOverview.get_all_courses(orgs=[org], filter_=filter_)
    elif current_site_orgs:
        # Only display courses that should be displayed on this site
        courses = CourseOverview.get_all_courses(orgs=current_site_orgs, filter_=filter_)
    else:
        courses = CourseOverview.get_all_courses(filter_=filter_)

    courses = courses.order_by('id')

    # Filtering can stop here.
    if current_site_orgs:
        return courses

    # See if we have filtered course listings in this domain
    filtered_visible_ids = None

    # this is legacy format, which also handle dev case, which should not filter
    subdomain = configuration_helpers.get_value('subdomain', 'default')
    if hasattr(settings, 'COURSE_LISTINGS') and subdomain in settings.COURSE_LISTINGS and not settings.DEBUG:
        filtered_visible_ids = frozenset(
            [CourseKey.from_string(c) for c in settings.COURSE_LISTINGS[subdomain]]
        )

    if filtered_visible_ids:
        return courses.filter(id__in=filtered_visible_ids)
    else:
        # Filter out any courses based on current org, to avoid leaking these.
        orgs = configuration_helpers.get_all_orgs()
        return courses.exclude(org__in=orgs)
    def field_dictionary(self, **kwargs):
        """ add course if provided otherwise add courses in which the user is enrolled in """
        field_dictionary = super(LmsSearchFilterGenerator, self).field_dictionary(**kwargs)
        if kwargs.get('user'):
            if not kwargs.get('course_id'):
                user_enrollments = self._enrollments_for_user(kwargs['user'])
                field_dictionary['course'] = [unicode(enrollment.course_id) for enrollment in user_enrollments]

        # if we have an org filter, only include results for this org filter
        course_org_filter = configuration_helpers.get_current_site_orgs()
        if course_org_filter:
            field_dictionary['org'] = course_org_filter

        return field_dictionary
    def field_dictionary(self, **kwargs):
        """ add course if provided otherwise add courses in which the user is enrolled in """
        field_dictionary = super(LmsSearchFilterGenerator, self).field_dictionary(**kwargs)
        if not kwargs.get('user'):
            field_dictionary['course'] = []
        elif not kwargs.get('course_id'):
            user_enrollments = self._enrollments_for_user(kwargs['user'])
            field_dictionary['course'] = [six.text_type(enrollment.course_id) for enrollment in user_enrollments]

        # if we have an org filter, only include results for this org filter
        course_org_filter = configuration_helpers.get_current_site_orgs()
        if course_org_filter:
            field_dictionary['org'] = course_org_filter

        return field_dictionary
示例#11
0
def get_visible_courses(org=None, filter_=None):
    """
    Return the set of CourseOverviews that should be visible in this branded
    instance.

    Arguments:
        org (string): Optional parameter that allows case-insensitive
            filtering by organization.
        filter_ (dict): Optional parameter that allows custom filtering by
            fields on the course.
    """
    courses = []
    current_site_orgs = configuration_helpers.get_current_site_orgs()

    if org:
        # Check the current site's orgs to make sure the org's courses should be displayed
        if not current_site_orgs or org in current_site_orgs:
            courses = CourseOverview.get_all_courses(orgs=[org], filter_=filter_)
    elif current_site_orgs:
        # Only display courses that should be displayed on this site
        courses = CourseOverview.get_all_courses(orgs=current_site_orgs, filter_=filter_)
    else:
        courses = CourseOverview.get_all_courses(filter_=filter_)

    courses = sorted(courses, key=lambda course: course.number)

    # Filtering can stop here.
    if current_site_orgs:
        return courses

    # See if we have filtered course listings in this domain
    filtered_visible_ids = None

    # this is legacy format, which also handle dev case, which should not filter
    subdomain = configuration_helpers.get_value('subdomain', 'default')
    if hasattr(settings, 'COURSE_LISTINGS') and subdomain in settings.COURSE_LISTINGS and not settings.DEBUG:
        filtered_visible_ids = frozenset(
            [SlashSeparatedCourseKey.from_deprecated_string(c) for c in settings.COURSE_LISTINGS[subdomain]]
        )

    if filtered_visible_ids:
        return [course for course in courses if course.id in filtered_visible_ids]
    else:
        # Filter out any courses based on current org, to avoid leaking these.
        orgs = configuration_helpers.get_all_orgs()
        return [course for course in courses if course.location.org not in orgs]
示例#12
0
    def exclude_dictionary(self, **kwargs):
        """
            Exclude any courses defined outside the current org.
        """
        exclude_dictionary = super().exclude_dictionary(**kwargs)
        course_org_filter = configuration_helpers.get_current_site_orgs()
        # If we have a course filter we are ensuring that we only get those courses above
        if not course_org_filter:
            org_filter_out_set = configuration_helpers.get_all_orgs()
            if org_filter_out_set:
                exclude_dictionary['org'] = list(org_filter_out_set)

        if not getattr(settings, "SEARCH_SKIP_INVITATION_ONLY_FILTERING",
                       True):
            exclude_dictionary['invitation_only'] = True
        if not getattr(settings, "SEARCH_SKIP_SHOW_IN_CATALOG_FILTERING",
                       True):
            exclude_dictionary['catalog_visibility'] = 'none'

        return exclude_dictionary
示例#13
0
def validate_org(course_id):
    """
    Validate the course organization against all possible orgs for the site

    To determine if the Org is valid we must look at 3 things
    1 Orgs in the current site
    2 Orgs in other sites
    3 flag EOX_CORE_USER_ENABLE_MULTI_TENANCY
    """

    if not settings.EOX_CORE_USER_ENABLE_MULTI_TENANCY:
        return True

    course_key = get_valid_course_key(course_id)
    current_site_orgs = get_current_site_orgs() or []

    if not current_site_orgs:
        if course_key.org in get_all_orgs():
            return False
        return True
    else:
        return course_key.org in current_site_orgs
示例#14
0
def get_org_black_and_whitelist_for_site():
    """
    Returns the org blacklist and whitelist for the current site.

    Returns:
        (org_whitelist, org_blacklist): A tuple of lists of orgs that serve as
            either a blacklist or a whitelist of orgs for the current site. The
            whitelist takes precedence, and the blacklist is used if the
            whitelist is None.
    """
    # Default blacklist is empty.
    org_blacklist = None
    # Whitelist the orgs configured for the current site.  Each site outside
    # of edx.org has a list of orgs associated with its configuration.
    org_whitelist = configuration_helpers.get_current_site_orgs()

    if not org_whitelist:
        # If there is no whitelist, the blacklist will include all orgs that
        # have been configured for any other sites. This applies to edx.org,
        # where it is easier to blacklist all other orgs.
        org_blacklist = configuration_helpers.get_all_orgs()

    return org_whitelist, org_blacklist
示例#15
0
def get_org_black_and_whitelist_for_site():
    """
    Returns the org blacklist and whitelist for the current site.

    Returns:
        (org_whitelist, org_blacklist): A tuple of lists of orgs that serve as
            either a blacklist or a whitelist of orgs for the current site. The
            whitelist takes precedence, and the blacklist is used if the
            whitelist is None.
    """
    # Default blacklist is empty.
    org_blacklist = None
    # Whitelist the orgs configured for the current site.  Each site outside
    # of edx.org has a list of orgs associated with its configuration.
    org_whitelist = configuration_helpers.get_current_site_orgs()

    if not org_whitelist:
        # If there is no whitelist, the blacklist will include all orgs that
        # have been configured for any other sites. This applies to edx.org,
        # where it is easier to blacklist all other orgs.
        org_blacklist = configuration_helpers.get_all_orgs()

    return org_whitelist, org_blacklist
示例#16
0
    def inner(request, *args, **kwargs):
        if not request.user.is_authenticated and not configuration_helpers.get_value(
                'SHOW_COURSES_TO_ANONYMOUS_USERS',
                settings.SHOW_COURSES_TO_ANONYMOUS_USERS
            ):
            raise Http404
        course_key = kwargs.get('course_key_string') or kwargs.get('course_id')
        if course_key is not None:
            try:
                CourseKey.from_string(course_key)
                courselike_key = CourseKey.from_string(course_key)
                library = isinstance(courselike_key, LibraryLocator)
                if not library:
                    site_orgs = configuration_helpers.get_current_site_orgs()
                    linked_courses = OrganizationCourse.objects.filter(course_id=course_key,
                                                                    organization__name__in=site_orgs,
                                                                    active=True)
                    if not linked_courses:
                        raise Http404
            except InvalidKeyError:
                raise Http404

        response = view_func(request, *args, **kwargs)
        return response
示例#17
0
    def get_queryset(self):
        site_organizations = configuration_helpers.get_current_site_orgs()

        return User.objects.select_related('profile').filter(
            Q(edly_profile__edly_sub_organizations__slug__in=site_organizations
              ))
示例#18
0
 def test_get_current_site_orgs(self):
     test_orgs = test_config_multi_org['course_org_filter']
     six.assertCountEqual(
         self, list(configuration_helpers.get_current_site_orgs()),
         test_orgs)
示例#19
0
def _record_feedback_in_zendesk(realname,
                                email,
                                subject,
                                details,
                                tags,
                                additional_info,
                                group_name=None,
                                require_update=False,
                                support_email=None,
                                custom_fields=None):
    """
    Create a new user-requested Zendesk ticket.

    Once created, the ticket will be updated with a private comment containing
    additional information from the browser and server, such as HTTP headers
    and user state. Returns a boolean value indicating whether ticket creation
    was successful, regardless of whether the private comment update succeeded.

    If `group_name` is provided, attaches the ticket to the matching Zendesk group.

    If `require_update` is provided, returns False when the update does not
    succeed. This allows using the private comment to add necessary information
    which the user will not see in followup emails from support.

    If `custom_fields` is provided, submits data to those fields in Zendesk.
    """
    zendesk_api = _ZendeskApi()

    additional_info_string = (u"Additional information:\n\n" + u"\n".join(
        u"%s: %s" % (key, value)
        for (key, value) in additional_info.items() if value is not None))

    # Tag all issues with LMS to distinguish channel in Zendesk; requested by student support team
    zendesk_tags = list(tags.values()) + ["LMS"]

    # Per edX support, we would like to be able to route feedback items by site via tagging
    current_site_orgs = configuration_helpers.get_current_site_orgs()
    if current_site_orgs:
        for org in current_site_orgs:
            zendesk_tags.append("whitelabel_{org}".format(org=org))

    new_ticket = {
        "ticket": {
            "requester": {
                "name": realname,
                "email": email
            },
            "subject": subject,
            "comment": {
                "body": details
            },
            "tags": zendesk_tags
        }
    }

    if custom_fields:
        new_ticket["ticket"]["custom_fields"] = custom_fields

    group = None
    if group_name is not None:
        group = zendesk_api.get_group(group_name)
        if group is not None:
            new_ticket['ticket']['group_id'] = group['id']
    if support_email is not None:
        # If we do not include the `recipient` key here, Zendesk will default to using its default reply
        # email address when support agents respond to tickets. By setting the `recipient` key here,
        # we can ensure that WL site users are responded to via the correct Zendesk support email address.
        new_ticket['ticket']['recipient'] = support_email
    try:
        ticket_id = zendesk_api.create_ticket(new_ticket)
        if group_name is not None and group is None:
            # Support uses Zendesk groups to track tickets. In case we
            # haven't been able to correctly group this ticket, log its ID
            # so it can be found later.
            log.warning(
                'Unable to find group named %s for Zendesk ticket with ID %s.',
                group_name, ticket_id)
    except zendesk.ZendeskError:
        log.exception("Error creating Zendesk ticket")
        return False

    # Additional information is provided as a private update so the information
    # is not visible to the user.
    ticket_update = {
        "ticket": {
            "comment": {
                "public": False,
                "body": additional_info_string
            }
        }
    }
    try:
        zendesk_api.update_ticket(ticket_id, ticket_update)
    except zendesk.ZendeskError:
        log.exception("Error updating Zendesk ticket with ID %s.", ticket_id)
        # The update is not strictly necessary, so do not indicate
        # failure to the user unless it has been requested with
        # `require_update`.
        if require_update:
            return False
    return True
示例#20
0
def _record_feedback_in_zendesk(
        realname,
        email,
        subject,
        details,
        tags,
        additional_info,
        group_name=None,
        require_update=False,
        support_email=None,
        custom_fields=None
):
    """
    Create a new user-requested Zendesk ticket.

    Once created, the ticket will be updated with a private comment containing
    additional information from the browser and server, such as HTTP headers
    and user state. Returns a boolean value indicating whether ticket creation
    was successful, regardless of whether the private comment update succeeded.

    If `group_name` is provided, attaches the ticket to the matching Zendesk group.

    If `require_update` is provided, returns False when the update does not
    succeed. This allows using the private comment to add necessary information
    which the user will not see in followup emails from support.

    If `custom_fields` is provided, submits data to those fields in Zendesk.
    """
    zendesk_api = _ZendeskApi()

    additional_info_string = (
        u"Additional information:\n\n" +
        u"\n".join(u"%s: %s" % (key, value) for (key, value) in additional_info.items() if value is not None)
    )

    # Tag all issues with LMS to distinguish channel in Zendesk; requested by student support team
    zendesk_tags = list(tags.values()) + ["LMS"]

    # Per edX support, we would like to be able to route feedback items by site via tagging
    current_site_orgs = configuration_helpers.get_current_site_orgs()
    if current_site_orgs:
        for org in current_site_orgs:
            zendesk_tags.append("whitelabel_{org}".format(org=org))

    new_ticket = {
        "ticket": {
            "requester": {"name": realname, "email": email},
            "subject": subject,
            "comment": {"body": details},
            "tags": zendesk_tags
        }
    }

    if custom_fields:
        new_ticket["ticket"]["custom_fields"] = custom_fields

    group = None
    if group_name is not None:
        group = zendesk_api.get_group(group_name)
        if group is not None:
            new_ticket['ticket']['group_id'] = group['id']
    if support_email is not None:
        # If we do not include the `recipient` key here, Zendesk will default to using its default reply
        # email address when support agents respond to tickets. By setting the `recipient` key here,
        # we can ensure that WL site users are responded to via the correct Zendesk support email address.
        new_ticket['ticket']['recipient'] = support_email
    try:
        ticket_id = zendesk_api.create_ticket(new_ticket)
        if group_name is not None and group is None:
            # Support uses Zendesk groups to track tickets. In case we
            # haven't been able to correctly group this ticket, log its ID
            # so it can be found later.
            log.warning('Unable to find group named %s for Zendesk ticket with ID %s.', group_name, ticket_id)
    except zendesk.ZendeskError:
        log.exception("Error creating Zendesk ticket")
        return False

    # Additional information is provided as a private update so the information
    # is not visible to the user.
    ticket_update = {"ticket": {"comment": {"public": False, "body": additional_info_string}}}
    try:
        zendesk_api.update_ticket(ticket_id, ticket_update)
    except zendesk.ZendeskError:
        log.exception("Error updating Zendesk ticket with ID %s.", ticket_id)
        # The update is not strictly necessary, so do not indicate
        # failure to the user unless it has been requested with
        # `require_update`.
        if require_update:
            return False
    return True
示例#21
0
 def test_get_current_site_orgs(self):
     test_orgs = test_config_multi_org['course_org_filter']
     self.assertItemsEqual(
         list(configuration_helpers.get_current_site_orgs()),
         test_orgs
     )