Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: adds TenantAwareLinkRenderStarted filter #32014

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 24 additions & 1 deletion cms/djangoapps/contentstore/views/assets.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
from django.views.decorators.csrf import ensure_csrf_cookie
from django.views.decorators.http import require_http_methods, require_POST
from opaque_keys.edx.keys import AssetKey, CourseKey
from openedx_filters.learning.filters import TenantAwareLinkRenderStarted
from pymongo import ASCENDING, DESCENDING

from common.djangoapps.edxmako.shortcuts import render_to_response
Expand Down Expand Up @@ -598,7 +599,21 @@ def _get_asset_json(display_name, content_type, date, location, thumbnail_locati
Helper method for formatting the asset information to send to client.
'''
asset_url = StaticContent.serialize_asset_key_with_slash(location)
external_url = urljoin(configuration_helpers.get_value('LMS_ROOT_URL', settings.LMS_ROOT_URL), asset_url)
lms_root = configuration_helpers.get_value('LMS_ROOT_URL', settings.LMS_ROOT_URL)

try:
## .. filter_implemented_name: TenantAwareLinkRenderStarted
## .. filter_type: org.openedx.learning.tenant_aware_link.render.started.v1
lms_root = TenantAwareLinkRenderStarted.run_filter(
context=lms_root,
org=location.org,
val_name='LMS_ROOT_URL',
default=settings.LMS_ROOT_URL
)
except TenantAwareLinkRenderStarted.PreventTenantAwarelinkRender as exc:
raise TenantAwareRenderNotAllowed(str(exc)) from exc

external_url = urljoin(lms_root, asset_url)
portable_url = StaticContent.get_static_path_from_location(location)
return {
'display_name': display_name,
Expand All @@ -613,3 +628,11 @@ def _get_asset_json(display_name, content_type, date, location, thumbnail_locati
# needed for Backbone delete/update.
'id': str(location)
}


class TenantAwareRenderException(Exception):
pass


class TenantAwareRenderNotAllowed(TenantAwareRenderException):
pass
25 changes: 24 additions & 1 deletion common/djangoapps/util/course.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from django.conf import settings
from opaque_keys.edx.keys import CourseKey, UsageKey

from openedx_filters.learning.filters import TenantAwareLinkRenderStarted
from openedx.core.djangoapps.site_configuration import helpers as configuration_helpers

log = logging.getLogger(__name__)
Expand Down Expand Up @@ -54,14 +55,36 @@ def get_link_for_about_page(course):
elif settings.FEATURES.get('ENABLE_MKTG_SITE') and getattr(course, 'marketing_url', None):
course_about_url = course.marketing_url
else:
about_base = configuration_helpers.get_value('LMS_ROOT_URL', settings.LMS_ROOT_URL)

try:
## .. filter_implemented_name: TenantAwareLinkRenderStarted
## .. filter_type: org.openedx.learning.tenant_aware_link.render.started.v1
about_base = TenantAwareLinkRenderStarted.run_filter(
context=about_base,
org=course.id.org,
val_name='LMS_ROOT_URL',
default=settings.LMS_ROOT_URL
)
except TenantAwareLinkRenderStarted.PreventTenantAwarelinkRender as exc:
raise TenantAwareRenderNotAllowed(str(exc)) from exc

course_about_url = '{about_base_url}/courses/{course_key}/about'.format(
about_base_url=configuration_helpers.get_value('LMS_ROOT_URL', settings.LMS_ROOT_URL),
about_base_url=about_base,
course_key=str(course.id),
)

return course_about_url


class TenantAwareRenderException(Exception):
pass


class TenantAwareRenderNotAllowed(TenantAwareRenderException):
pass


def has_certificates_enabled(course):
"""
Arguments:
Expand Down
126 changes: 126 additions & 0 deletions common/djangoapps/util/tests/test_filters.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
"""
Test that various filters are fired for models/views in the student app.
"""
from django.http import HttpResponse
from django.test import override_settings
from common.djangoapps.util import course
from openedx_filters import PipelineStep
from openedx_filters.learning.filters import TenantAwareLinkRenderStarted
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
from xmodule.modulestore.tests.factories import CourseFactory

from common.djangoapps.util.course import TenantAwareRenderNotAllowed
from openedx.core.djangolib.testing.utils import skip_unless_lms


class TestTenantAwareRenderPipelineStep(PipelineStep):
"""
Utility class used when getting steps for pipeline.
"""

def run_filter(self, context, org, val_name, default): # pylint: disable=arguments-differ
"""Pipeline step that modifies tenant aware links."""
context = "https://tenant-aware-link"
return {
"context": context
}


class TestTenantAwareFilterPrevent(PipelineStep):
"""
Utility class used when getting steps for pipeline.
"""

def run_filter(self, context, org, val_name, default): # pylint: disable=arguments-differ
"""Pipeline step that changes dashboard view response before the dashboard is rendered."""
response = HttpResponse("This is a custom response.")
raise TenantAwareLinkRenderStarted.PreventTenantAwarelinkRender(
"Can't render tenant aware link.",
response=response,
)


@skip_unless_lms
class TenantAwareLinkFiltersTest(ModuleStoreTestCase):
"""
Tests for the Open edX Filters associated with the Tenant aware link process.

This class guarantees that the following filters are triggered during the microsite render:

- TenantAwareLinkRenderStarted
"""

def setUp(self): # pylint: disable=arguments-differ
super().setUp()
self.course = CourseFactory.create()
self.org = "test"
self.val_name = 'LMS_ROOT_URL'
self.default = "https://lms-base"

@override_settings(
OPEN_EDX_FILTERS_CONFIG={
"org.openedx.learning.tenant_aware_link.render.started.v1": {
"pipeline": [
"common.djangoapps.util.tests.test_filters.TestTenantAwareRenderPipelineStep",
],
"fail_silently": False,
},
},
)
def test_tenant_aware_filter_executed(self):
"""
Test whether the tenant aware link filter is triggered before the user's
render site process.

Expected result:
- TenantAwareLinkRenderStarted is triggered and executes TestTenantAwareRenderPipelineStep.
- The arguments that the receiver gets are the arguments used by the filter.
"""
course_about_url = course.get_link_for_about_page(self.course)

expected_course_about = '{about_base_url}/courses/{course_key}/about'.format(
about_base_url='https://tenant-aware-link',
course_key=str(self.course.id),
)

self.assertEqual(expected_course_about, course_about_url)

@override_settings(
OPEN_EDX_FILTERS_CONFIG={
"org.openedx.learning.tenant_aware_link.render.started.v1": {
"pipeline": [
"common.djangoapps.util.tests.test_filters.TestTenantAwareFilterPrevent",
],
"fail_silently": False,
},
},
)
def test_tenant_aware_filter_prevent(self):
"""
Test prevent the tenant aware link filter through a pipeline step.

Expected result:
- TenantAwareLinkRenderStarted is triggered and executes TestTenantAwareFilterPrevent.
- The user can't get tenant aware links.
"""
with self.assertRaises(TenantAwareRenderNotAllowed):
course.get_link_for_about_page(self.course)

@override_settings(OPEN_EDX_FILTERS_CONFIG={}, LMS_ROOT_URL="https://lms-base")
def test_enrollment_without_filter_configuration(self):
"""
Test usual get link for about page process, without filter's intervention.

Expected result:
- Returns the course sharing url, this can be one of course's social sharing url, marketing url, or
lms course about url.
- The get process ends successfully.
"""
course_about_url = course.get_link_for_about_page(self.course)

expected_course_about = '{about_base_url}/courses/{course_key}/about'.format(
about_base_url='https://lms-base',
course_key=str(self.course.id),
)

self.assertEqual(expected_course_about, course_about_url)
2 changes: 1 addition & 1 deletion requirements/edx/base.in
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ openedx-calc # Library supporting mathematical calculatio
openedx-django-require
# openedx-events 3.1.0 introduces producer API
openedx-events>=3.1.0 # Open edX Events from Hooks Extension Framework (OEP-50)
openedx-filters # Open edX Filters from Hooks Extension Framework (OEP-50)
git+https://github.com/eduNEXT/openedx-filters.git@JDB/add_tenant_aware_filter #openedx-filters Open edX Filters from Hooks Extension Framework (OEP-50)
openedx-mongodbproxy
optimizely-sdk # Optimizely full stack SDK for Python
ora2>=4.5.0
Expand Down
3 changes: 1 addition & 2 deletions requirements/edx/base.txt
Original file line number Diff line number Diff line change
Expand Up @@ -778,8 +778,7 @@ openedx-events==8.0.0
# via
# -r requirements/edx/base.in
# edx-event-bus-kafka
# edx-event-bus-redis
openedx-filters==1.3.0
git+https://github.com/eduNEXT/openedx-filters.git@JDB/add_tenant_aware_filter
# via
# -r requirements/edx/base.in
# lti-consumer-xblock
Expand Down
3 changes: 1 addition & 2 deletions requirements/edx/development.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1036,8 +1036,7 @@ openedx-events==8.0.0
# via
# -r requirements/edx/testing.txt
# edx-event-bus-kafka
# edx-event-bus-redis
openedx-filters==1.3.0
git+https://github.com/eduNEXT/openedx-filters.git@JDB/add_tenant_aware_filter
# via
# -r requirements/edx/testing.txt
# lti-consumer-xblock
Expand Down
3 changes: 1 addition & 2 deletions requirements/edx/testing.txt
Original file line number Diff line number Diff line change
Expand Up @@ -983,8 +983,7 @@ openedx-events==8.0.0
# via
# -r requirements/edx/base.txt
# edx-event-bus-kafka
# edx-event-bus-redis
openedx-filters==1.3.0
git+https://github.com/eduNEXT/openedx-filters.git@JDB/add_tenant_aware_filter
# via
# -r requirements/edx/base.txt
# lti-consumer-xblock
Expand Down