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 FilterTenantAwareLinksFromStudio in filters pipeline #219

Merged
merged 4 commits into from
Jan 27, 2025
Merged
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
2 changes: 1 addition & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jobs:
strategy:
max-parallel: 2
matrix:
python-version: ["3.8", "3.11"]
python-version: ["3.11"]
django: ["42"]
steps:
- name: Checkout
Expand Down
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,16 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [v13.0.0](https://github.com/eduNEXT/eox-tenant/compare/v12.1.0...v13.0.0) - (2025-01-20)

#### Features

- add FilterTenantAwareLinksFromStudio in filters pipeline ([2b82024](https://github.com/eduNEXT/eox-tenant/commit/2b820245433f8889448e70390b5b9efed9aa0dba))

#### Removed

- removed support for Python 3.8. New releases are no longer compatible with Quince.

## [v12.1.0](https://github.com/eduNEXT/eox-core/compare/v12.0.0...v12.1.0) - (2024-11-18)

### Changed
Expand Down
2 changes: 1 addition & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ Compatibility Notes
+------------------+------------------+
| Palm | >= v11.7.0 < 12.0|
+------------------+------------------+
| Quince | >= v11.7.0 |
| Quince | >= v11.7.0 < 13.0|
+------------------+------------------+
| Redwood | >= v11.7.0 |
+------------------+------------------+
Expand Down
2 changes: 1 addition & 1 deletion eox_tenant/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
"""
Init for eox-tenant.
"""
__version__ = '12.1.0'
__version__ = '13.0.0'
10 changes: 8 additions & 2 deletions eox_tenant/filters/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,14 @@ Filters steps list:
-------------------

* `FilterUserCourseEnrollmentsByTenant`_: Filters the course enrollments of a user from the tenant site where the request is made.

.. _FilterUserCourseEnrollmentsByTenant: ./pipeline.py#L9
* `FilterRenderCertificatesByOrg`_: Stop certificate generation process raising a exception if course org is different to tenant orgs.
* `OrgAwareLMSURLStudio`_: Generates a new LMS URL for asset URL generation based on the course organization settings.
* `OrgAwareCourseAboutPageURL`_: Generates a new course about URL based on the course organization settings.

.. _FilterUserCourseEnrollmentsByTenant: ./pipeline.py#L12
.. _FilterRenderCertificatesByOrg: ./pipeline.py#L35
.. _OrgAwareLMSURLStudio: ./pipeline.py#L66
.. _OrgAwareCourseAboutPageURL: ./pipeline#L93

How to add a new Filter Step:
-----------------------------
Expand Down
62 changes: 62 additions & 0 deletions eox_tenant/filters/pipeline.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
"""
The pipeline module defines custom Filters functions that are used in openedx-filters.
"""
from django.conf import settings
from openedx_filters import PipelineStep
from openedx_filters.learning.filters import CertificateRenderStarted

from eox_tenant.edxapp_wrapper.site_configuration_module import get_configuration_helpers
from eox_tenant.organizations import get_organizations
from eox_tenant.tenant_aware_functions.enrollments import filter_enrollments

configuration_helpers = get_configuration_helpers()


class FilterUserCourseEnrollmentsByTenant(PipelineStep):
"""
Expand Down Expand Up @@ -57,3 +61,61 @@ def run_filter(self, context, custom_template, *args, **kwargs): # pylint: disa
raise CertificateRenderStarted.RenderAlternativeInvalidCertificate(
"You can't generate a certificate from this site.",
)


class OrgAwareLMSURLStudio(PipelineStep):
"""
Generates a new LMS URL for asset URL generation based on the course organization settings.
"""

def run_filter(self, url, org): # pylint: disable=arguments-differ,unused-argument
"""
Filter especific tenant aware link form Studio to the LMS.
Example Usage:
Add the following configurations to you configuration file
"OPEN_EDX_FILTERS_CONFIG": {
"org.openedx.course_authoring.lms.page.url.requested.v1": {
"fail_silently": false,
"pipeline": [
"eox_tenant.filters.pipeline.OrgAwareLMSURLStudio"
]
}
}
jignaciopm marked this conversation as resolved.
Show resolved Hide resolved
"""
lms_root = configuration_helpers.get_value_for_org(
org,
'LMS_ROOT_URL',
settings.LMS_ROOT_URL
)
return {"url": lms_root, "org": org}


class OrgAwareCourseAboutPageURL(PipelineStep):
"""
Generates a new course about URL based on the course organization settings.
"""

def run_filter(self, url, org): # pylint: disable=arguments-differ,unused-argument
"""
The url looks like this:
<LMS_ROOT>/courses/course-v1:org+course+number/about

This method will filter the url to be tenant aware.
Example Usage:
Add the following configurations to you configuration file
"OPEN_EDX_FILTERS_CONFIG": {
"org.openedx.learning.course_about.page.url.requested.v1": {
"fail_silently": false,
"pipeline": [
"eox_tenant.filters.pipeline.OrgAwareCourseAboutPageURL"
]
},
}
jignaciopm marked this conversation as resolved.
Show resolved Hide resolved
"""
lms_root = configuration_helpers.get_value_for_org(
org,
'LMS_ROOT_URL',
settings.LMS_ROOT_URL
)
course_about_url = url.replace(settings.LMS_ROOT_URL, lms_root)
return {"url": course_about_url, "org": org}
86 changes: 85 additions & 1 deletion eox_tenant/filters/test/test_pipeline.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from django.test import TestCase, override_settings
from openedx_filters.learning.filters import CertificateRenderStarted, CourseEnrollmentQuerysetRequested

from eox_tenant.filters.pipeline import FilterRenderCertificatesByOrg
from eox_tenant.filters.pipeline import FilterRenderCertificatesByOrg, OrgAwareCourseAboutPageURL, OrgAwareLMSURLStudio
from eox_tenant.tenant_aware_functions.enrollments import filter_enrollments


Expand Down Expand Up @@ -161,3 +161,87 @@ def test_filter_render_certificates_by_org(self, organizations, render, mock_get
else:
FilterRenderCertificatesByOrg.run_filter(self, context, {})
mock_get_organizations.assert_called_once()


class OrgAwareLMSURLStudioTestCase(TestCase):
"""
Test OrgAwareLMSURLStudioTestCase that generates a new LMS URL for asset URL generation
based on the course organization settings.
"""

def setUp(self):
"""This method initializes the URL and ORG variables for the pipeline"""

self.url = "https://lms-base"
self.org = "test"

@override_settings(
LMS_ROOT_URL="https://lms-base"
)
@mock.patch('eox_tenant.filters.pipeline.configuration_helpers')
def test_get_lms_url_based_for_org(self, configuration_helpers_mock):
"""
Test that filter get new LMS URL for asset URL generation
based on the course organization settings for org.

Args:
configuration_helpers_mock (patch): mock for configuration_helpers method.

Expected result:
- The url return is equal to expected.
- The org return is equal to expected.
"""
results_get_value = "https://test-tenant-aware-link"

configuration_helpers_mock.get_value_for_org.return_value = results_get_value

result = OrgAwareLMSURLStudio.run_filter(
self,
url=self.url,
org=self.org,
)

self.assertEqual(results_get_value, result.get("url"))
self.assertEqual(result.get("org"), self.org)


class OrgAwareCourseAboutPageURLTestCase(TestCase):
"""
Test OrgAwareCourseAboutPageURLTestCase that generates a new course about URL based
on the course organization settings.
"""

def setUp(self):
"""This method initializes the URL and ORG variables for the pipeline"""

self.url = "https://lms-base"
self.org = "test"

@override_settings(
LMS_ROOT_URL="https://lms-base"
)
@mock.patch('eox_tenant.filters.pipeline.configuration_helpers')
def test_get_course_about_url_based_for_org(self, configuration_helpers_mock):
"""
Test that filter get new course about URL based
on the course organization settings for org.

Args:
configuration_helpers_mock (patch): mock for configuration_helpers method.

Expected result:
- The url return is equal to expected.
- The org return is equal to expected.
"""
results_get_value = "https://test-tenant-aware-link"

configuration_helpers_mock.get_value_for_org.return_value = results_get_value

result = OrgAwareCourseAboutPageURL.run_filter(
self,
url=self.url,
org=self.org,
)

self.assertEqual(results_get_value, result.get("url"))
self.assertEqual(result.get("org"), self.org)
47 changes: 21 additions & 26 deletions requirements/base.txt
Original file line number Diff line number Diff line change
@@ -1,35 +1,30 @@
#
# This file is autogenerated by pip-compile with Python 3.8
# This file is autogenerated by pip-compile with Python 3.11
# by the following command:
#
# make upgrade
#
asgiref==3.8.1
# via django
backports-zoneinfo==0.2.1 ; python_version < "3.9"
# via
# -c requirements/constraints.txt
# django
# djangorestframework
certifi==2024.8.30
certifi==2024.12.14
# via requests
cffi==1.17.1
# via
# cryptography
# pynacl
charset-normalizer==3.4.0
charset-normalizer==3.4.1
# via requests
click==8.1.7
click==8.1.8
# via edx-django-utils
cryptography==43.0.3
cryptography==44.0.0
# via
# pyjwt
# social-auth-core
defusedxml==0.8.0rc2
# via
# python3-openid
# social-auth-core
django==4.2.16
django==4.2.18
# via
# -c https://raw.githubusercontent.com/openedx/edx-lint/master/edx_lint/files/common_constraints.txt
# -r requirements/base.in
Expand All @@ -50,7 +45,7 @@ django-crum==0.7.9
# edx-django-utils
django-model-utils==5.0.0
# via edx-organizations
django-mysql==4.14.0
django-mysql==4.15.0
# via -r requirements/base.in
django-simple-history==3.0.0
# via
Expand All @@ -66,11 +61,11 @@ djangorestframework==3.15.2
# drf-jwt
# edx-drf-extensions
# edx-organizations
dnspython==2.6.1
dnspython==2.7.0
# via pymongo
drf-jwt==1.19.2
# via edx-drf-extensions
edx-django-utils==7.0.0
edx-django-utils==7.1.0
# via edx-drf-extensions
edx-drf-extensions==10.5.0
# via
Expand All @@ -87,23 +82,23 @@ idna==3.10
# via requests
jsonfield==3.1.0
# via -r requirements/base.in
newrelic==10.2.0
newrelic==10.4.0
# via edx-django-utils
oauthlib==3.2.2
# via
# requests-oauthlib
# social-auth-core
openedx-filters==1.9.0
openedx-filters==1.12.0
# via -r requirements/base.in
pbr==6.1.0
# via stevedore
pillow==10.4.0
pillow==11.1.0
# via edx-organizations
psutil==6.1.0
psutil==6.1.1
# via edx-django-utils
pycparser==2.22
# via cffi
pyjwt[crypto]==2.9.0
pyjwt[crypto]==2.10.1
# via
# drf-jwt
# edx-drf-extensions
Expand All @@ -123,22 +118,22 @@ requests-oauthlib==2.0.0
# via social-auth-core
semantic-version==2.10.0
# via edx-drf-extensions
six==1.16.0
six==1.17.0
# via -r requirements/base.in
social-auth-core==4.5.4
# via -r requirements/base.in
sqlparse==0.5.2
sqlparse==0.5.3
# via django
stevedore==5.3.0
stevedore==5.4.0
# via
# edx-django-utils
# edx-opaque-keys
typing-extensions==4.12.2
# via
# asgiref
# edx-opaque-keys
# via edx-opaque-keys
urllib3==2.2.3
# via requests
# via
# -c https://raw.githubusercontent.com/openedx/edx-lint/master/edx_lint/files/common_constraints.txt
# requests

# The following packages are considered to be unsafe in a requirements file:
# setuptools
7 changes: 0 additions & 7 deletions requirements/constraints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,3 @@

# Common constraints for Open edX repos
-c https://raw.githubusercontent.com/openedx/edx-lint/master/edx_lint/files/common_constraints.txt

# backports.zoneinfo is only needed for Python < 3.9
backports.zoneinfo; python_version<'3.9'

# Versions >= 3.3.0 drop support for Python 3.8
# Ensures a consistent pylint version across all Python environments to avoid triggering varying warnings
pylint<3.3.0
2 changes: 1 addition & 1 deletion requirements/django42.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
django==4.2.16
django==4.2.18
Loading
Loading