From 3022eb75e62e55442ccd2a87b71ca307d11ac4f7 Mon Sep 17 00:00:00 2001 From: Amir Tadrisi Date: Sat, 27 Jan 2024 16:32:56 -0500 Subject: [PATCH 1/4] feat: Add Mandrill Subaccount support --- .../settings/settings/production_common.py | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/openedx/core/djangoapps/appsembler/settings/settings/production_common.py b/openedx/core/djangoapps/appsembler/settings/settings/production_common.py index 20f544f0dc83..bdd911e8a286 100644 --- a/openedx/core/djangoapps/appsembler/settings/settings/production_common.py +++ b/openedx/core/djangoapps/appsembler/settings/settings/production_common.py @@ -48,7 +48,22 @@ def plugin_settings(settings): "MANDRILL_API_KEY": settings.MANDRILL_API_KEY, } settings.INSTALLED_APPS += ['anymail'] - + # Mandrill Subaccount Support + settings.MANDRILL_SUBACCOUNT = settings.ENV_TOKENS.get("MANDRILL_SUBACCOUNT") + if settings.MANDRILL_SUBACCOUNT: + subaccount_settings = { + "MANDRILL_SEND_DEFAULTS": { + "esp_extra": { + "message": { + "subaccount": settings.MANDRILL_SUBACCOUNT + } + } + } + } + if settings.ANYMAIL: + settings.ANYMAIL.update(subaccount_settings) + else: + settings.ANYMAIL = subaccount_settings # Sentry settings.SENTRY_DSN = settings.AUTH_TOKENS.get('SENTRY_DSN', False) if settings.SENTRY_DSN: From b131eb054d3a6e4ff6395dc272f8e4d142e4f204 Mon Sep 17 00:00:00 2001 From: Vladyslav Tymofeiev <“vladyslavty@softwareplanetgroup.com”> Date: Tue, 2 Jul 2024 18:56:10 +0300 Subject: [PATCH 2/4] Add sanitize function for redirect parameter next --- common/djangoapps/student/helpers.py | 18 ++++++++++++++ .../djangoapps/student/tests/test_helpers.py | 24 ++++++++++++++++++- 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/common/djangoapps/student/helpers.py b/common/djangoapps/student/helpers.py index 3c47510b5af1..4c2fcf7efd6c 100644 --- a/common/djangoapps/student/helpers.py +++ b/common/djangoapps/student/helpers.py @@ -6,6 +6,7 @@ import json import logging import mimetypes +import re import urllib.parse from collections import OrderedDict from datetime import datetime @@ -65,6 +66,8 @@ EMAIL_EXISTS_MSG_FMT = _("An account with the Email '{email}' already exists.") USERNAME_EXISTS_MSG_FMT = _("An account with the Public Username '{username}' already exists.") +COURSE_URL_PATTERN = re.compile(r'courses/course-v1:[^/]+/course') + log = logging.getLogger(__name__) @@ -301,6 +304,7 @@ def _get_redirect_to(request_host, request_headers, request_params, request_is_h redirect url if safe else None """ redirect_to = request_params.get('next') + redirect_to = sanitize_next_parameter(redirect_to) header_accept = request_headers.get('HTTP_ACCEPT', '') accepts_text_html = any( mime_type in header_accept @@ -700,3 +704,17 @@ def get_resume_urls_for_enrollments(user, enrollments): url_to_block = '' resume_course_urls[enrollment.course_id] = url_to_block return resume_course_urls + + +def sanitize_next_parameter(next_param): + """ + Check the next parameter pattern and update the + symbol to its ASCII equivalent. + """ + if not next_param: + return next_param + + if COURSE_URL_PATTERN.match(next_param): + sanitized_next_parameter = re.sub(r'\+', '%2B', next_param) + return sanitized_next_parameter + + return next_param diff --git a/common/djangoapps/student/tests/test_helpers.py b/common/djangoapps/student/tests/test_helpers.py index 655d9b763b36..8231503c8a55 100644 --- a/common/djangoapps/student/tests/test_helpers.py +++ b/common/djangoapps/student/tests/test_helpers.py @@ -14,7 +14,7 @@ from testfixtures import LogCapture from openedx.core.djangoapps.site_configuration.tests.test_util import with_site_configuration_context -from student.helpers import get_next_url_for_login_page +from student.helpers import get_next_url_for_login_page, sanitize_next_parameter LOGGER_NAME = "student.helpers" @@ -156,3 +156,25 @@ def test_custom_tahoe_site_redirect_lms(self): 'LOGIN_REDIRECT_URL': '' # Falsy or empty URLs should not be used }): assert '/dashboard' == get_next_url_for_login_page(request), 'Falsy url should default to dashboard' + + def test_sanitize_next_param(self): + # Valid URL with plus - change the plus symbol to ASCII code + next_param = 'courses/course-v1:abc-sandbox+ACC-PTF+C/course' + expected_result = 'courses/course-v1:abc-sandbox%2BACC-PTF%2BC/course' + self.assertEqual(sanitize_next_parameter(next_param), expected_result) + + # Valid URL without plus - keep the next_param as it is + next_param = 'courses/course-v1:abc-sandbox/course' + self.assertEqual(sanitize_next_parameter(next_param), next_param) + + # Empty string - keep the next_param as it is + next_param = '' + self.assertEqual(sanitize_next_parameter(next_param), next_param) + + # None input - keep the next_param as it is + next_param = None + self.assertEqual(sanitize_next_parameter(next_param), next_param) + + # Invalid pattern - keep the next_param as it is + next_param = 'some/other/path' + self.assertEqual(sanitize_next_parameter(next_param), next_param) From 96c39fa59869e426eb37ecf2a493d68bb24522aa Mon Sep 17 00:00:00 2001 From: Vladyslav Tymofeiev <“vladyslavty@softwareplanetgroup.com”> Date: Mon, 15 Jul 2024 17:36:11 +0300 Subject: [PATCH 3/4] Change upstream_repo variable to actual value --- .github/workflows/report_conflicts.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/report_conflicts.yml b/.github/workflows/report_conflicts.yml index 3c1b5e9e8baa..96ff1955f55d 100644 --- a/.github/workflows/report_conflicts.yml +++ b/.github/workflows/report_conflicts.yml @@ -7,7 +7,7 @@ jobs: uses: appsembler/action-conflict-counter/.github/workflows/report-via-comment.yml@main with: local_base_branch: ${{ github.base_ref }} - upstream_repo: 'https://github.com/edx/edx-platform.git' + upstream_repo: 'https://github.com/openedx/edx-platform.git' upstream_branches: 'open-release/nutmeg.master,master' exclude_paths: 'cms/static/js/,conf/locale/,lms/static/js/,package.json,package-lock.json,.github/' secrets: From da69fb92c8aa09169bc48e2b0523fa8da432b561 Mon Sep 17 00:00:00 2001 From: Vladyslav Tymofeiev <“vladyslavty@softwareplanetgroup.com”> Date: Tue, 16 Jul 2024 12:21:58 +0300 Subject: [PATCH 4/4] Add trusted host workaround for tests workflow --- .github/workflows/tests.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 989a259d4ecc..b96fe22dde49 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -34,6 +34,8 @@ jobs: uses: actions/setup-python@v2 with: python-version: ${{ matrix.python-version }} + env: + PIP_TRUSTED_HOST: "pypi.python.org pypi.org files.pythonhosted.org" - name: Install dependencies # TODO: Remove tox-pip-version once we upgrade to Koa+, or whenever we have addressed pip 20.3 strict issues. run: |