fix: Drop other references to studiofrontend.

Drop tooling to load studio-frontend components into mako templates and
XSS testing features related to it.
This commit is contained in:
Feanil Patel
2025-10-16 15:19:56 -04:00
parent 1ebe64db56
commit 28ab2ceb67
10 changed files with 1 additions and 151 deletions

View File

@@ -58,7 +58,6 @@ pull_translations: clean_translations ## pull translations via atlas
make pull_plugin_translations
atlas pull $(ATLAS_OPTIONS) \
translations/edx-platform/conf/locale:conf/locale \
translations/studio-frontend/src/i18n/messages:conf/plugins-locale/studio-frontend
python manage.py lms compilemessages
python manage.py lms compilejsi18n
python manage.py cms compilejsi18n

View File

@@ -1423,8 +1423,6 @@ ELASTIC_FIELD_MAPPINGS = {
XBLOCK_FS_STORAGE_BUCKET = None
XBLOCK_FS_STORAGE_PREFIX = None
STUDIO_FRONTEND_CONTAINER_URL = None
############################ Global Database Configuration #####################
DATABASE_ROUTERS = [

View File

@@ -36,10 +36,6 @@ from openedx.core.djangolib.markup import HTML, Text
<%static:include path="common/templates/image-modal.underscore" />
</script>
<link rel="stylesheet" type="text/css" href="${static.url('js/vendor/timepicker/jquery.timepicker.css')}" />
% if not settings.STUDIO_FRONTEND_CONTAINER_URL:
<link rel="stylesheet" type="text/css" href="${static.url('common/css/vendor/common.min.css')}" />
<link rel="stylesheet" type="text/css" href="${static.url('common/css/vendor/editImageModal.min.css')}" />
% endif
</%block>
<%block name="page_bundle">

View File

@@ -98,13 +98,6 @@ from openedx.core.release import RELEASE_LINE
<%static:include path="common/templates/image-modal.underscore" />
</script>
<link rel="stylesheet" type="text/css" href="${static.url('js/vendor/timepicker/jquery.timepicker.css')}" />
## The following stylesheets are included for studio-frontend debugging.
## Remove this as part of studio frontend deprecation.
## https://github.com/openedx/studio-frontend/issues/381
% if not settings.STUDIO_FRONTEND_CONTAINER_URL:
<link rel="stylesheet" type="text/css" href="${static.url('common/css/vendor/common.min.css')}" />
<link rel="stylesheet" type="text/css" href="${static.url('common/css/vendor/editImageModal.min.css')}" />
% endif
</head>
<body class="${static.dir_rtl()} is-signedin course container view-container lang_${LANGUAGE_CODE}">

View File

@@ -77,10 +77,6 @@ from openedx.core.release import RELEASE_LINE
<%static:include path="common/templates/image-modal.underscore" />
</script>
% if not settings.STUDIO_FRONTEND_CONTAINER_URL:
<link rel="stylesheet" type="text/css" href="${static.url('common/css/vendor/common.min.css')}" />
<link rel="stylesheet" type="text/css" href="${static.url('common/css/vendor/editImageModal.min.css')}" />
% endif
<link rel="stylesheet" type="text/css" href="${static.url('js/vendor/timepicker/jquery.timepicker.css')}" />
% for _, resource in resources:
% if resource['kind'] == 'url' and resource['mimetype'] == 'text/css':

View File

@@ -1,41 +0,0 @@
"""
Helpers for studio-frontend.
Contains code that gets run inside our mako template
Debugging python-in-mako is terrible, so we've moved the actual code out to its own file
"""
import logging
from django.conf import settings
from django.utils.translation import to_locale
log = logging.getLogger(__name__)
def load_sfe_i18n_messages(language):
"""
Loads i18n data from studio-frontend's published files.
This loads the i18n files pulled by the `make pull_translations` command.
Returns:
str: unparsed i18n locale JSON file content as a string.
"""
messages = '{}'
# because en is the default, studio-frontend will have it loaded by default
if language != 'en':
locale = to_locale(language) # fr-ca --> fr_CA format to match the file name in studio-frontend
messages_path = settings.REPO_ROOT / 'conf/plugins-locale/studio-frontend' / f'{locale}.json'
if messages_path.exists():
try:
with open(messages_path) as messages_file:
messages = messages_file.read()
except OSError:
log.error(f"Error loading studiofrontend language files for langauge '{language}'", exc_info=True)
else:
log.warning(f"studiofrontend language files for langauge '{language}' was not found.")
return messages

View File

@@ -4,7 +4,6 @@ import logging
import json
from django.contrib.staticfiles.storage import staticfiles_storage
from common.djangoapps.pipeline_mako import compressed_css, compressed_js
from common.djangoapps.pipeline_mako.helpers.studiofrontend import load_sfe_i18n_messages
from django.utils.translation import get_language_bidi
from mako.exceptions import TemplateLookupException
from common.djangoapps.edxmako.shortcuts import marketing_link
@@ -108,37 +107,6 @@ if not source:
%>${source | n, decode.utf8}</%def>
<%def name="studiofrontend(entry)">
<%doc>
Loads a studio-frontend page, with the necessary context. Context is expected
as a dictionary in the body of this tag.
</%doc>
<%
body = capture(caller.body)
body_dict = json.loads(body)
locale = body_dict['lang']
messages = load_sfe_i18n_messages(locale)
%>
<script type="application/json" id="SFE_i18n_data">
{
"locale": "${ locale | n, decode.utf8}",
"messages": ${ messages | n, decode.utf8}
}
</script>
<script type="application/javascript" id='courseContext'>
var studioContext = ${ body | n, decode.utf8};
</script>
<div id="root" class="SFE"></div>
% if settings.STUDIO_FRONTEND_CONTAINER_URL:
<script type="text/javascript" src="${settings.STUDIO_FRONTEND_CONTAINER_URL}/${entry}.js"></script>
% else:
<script type="text/javascript" src="${url('common/js/vendor/runtime.min.js')}"></script>
<script type="text/javascript" src="${url('common/js/vendor/common.min.js')}"></script>
<script type="text/javascript" src="${url('common/js/vendor/{}.min.js'.format(entry))}"></script>
% endif
</%def>
<%def name="webpack(entry, extension=None, config='DEFAULT', attrs='')">
<%doc>
Loads Javascript onto your page from a Webpack-generated bundle.

View File

@@ -1,51 +0,0 @@
"""
Tests for the studiofrontend helper module.
"""
import logging
import os
import pytest
from ..helpers import studiofrontend
def test_messages_file_not_found(tmpdir, settings, caplog):
"""
Ensure load_sfe_i18n_messages returns an empty json string when the messages file is not found.
"""
caplog.set_level(logging.INFO)
settings.REPO_ROOT = tmpdir
assert studiofrontend.load_sfe_i18n_messages('ar') == '{}'
assert 'studiofrontend language files for langauge \'ar\' was not found' in caplog.text
def test_messages_file_error(tmpdir, settings, caplog):
"""
Ensure load_sfe_i18n_messages returns an empty json string when the messages file is not found.
"""
caplog.set_level(logging.INFO)
settings.REPO_ROOT = tmpdir
# create a directory to cause an OSError when attempting to read it as a file
os.makedirs(tmpdir / 'conf/plugins-locale/studio-frontend/ar.json')
assert studiofrontend.load_sfe_i18n_messages('ar') == '{}'
assert 'Error loading studiofrontend language files for langauge' in caplog.text
@pytest.mark.parametrize('language', ['jp-jp', 'jp_JP'])
def test_messages_file_found(tmpdir, settings, caplog, language):
"""
Ensure load_sfe_i18n_messages finds the right language file and returns its content as string.
django.utils.translation.get_language() returns 'jp-jp' or 'fr-ca' instead of 'jp_JP' or 'fr_CA' respectively.
This test checks load_sfe_i18n_messages on both formats.
"""
caplog.set_level(logging.INFO)
settings.REPO_ROOT = tmpdir
studio_frontend_messages_dir = tmpdir / 'conf/plugins-locale/studio-frontend'
os.makedirs(studio_frontend_messages_dir)
messages_path = studio_frontend_messages_dir / 'jp_JP.json'
messages_path.write_text('{"homepage": "Homepage"}', encoding='utf-8')
assert studiofrontend.load_sfe_i18n_messages(language) == '{"homepage": "Homepage"}'
assert caplog.text == ''

View File

@@ -1244,22 +1244,16 @@ class TestMakoTemplateLinter(TestLinter):
${x | h}
</%static:require_module>
${x | h}
<%static:studiofrontend page="${x}">
${x | h}
</%static:studiofrontend>
${x | h}
""")
linter._check_mako_file_is_safe(mako_template, results)
assert len(results.violations) == 7
assert len(results.violations) == 5
assert results.violations[0].rule == MAKO_LINTER_RULESET.mako_unwanted_html_filter
assert results.violations[1].rule == MAKO_LINTER_RULESET.mako_invalid_js_filter
assert results.violations[2].rule == MAKO_LINTER_RULESET.mako_unwanted_html_filter
assert results.violations[3].rule == MAKO_LINTER_RULESET.mako_invalid_js_filter
assert results.violations[4].rule == MAKO_LINTER_RULESET.mako_unwanted_html_filter
assert results.violations[5].rule == MAKO_LINTER_RULESET.mako_invalid_js_filter
assert results.violations[6].rule == MAKO_LINTER_RULESET.mako_unwanted_html_filter
def test_check_mako_expressions_javascript_strings(self):
"""

View File

@@ -1359,8 +1359,6 @@ class MakoTemplateLinter(BaseLinter):
</%static:require_module(_async)?> | # require js script tag end (optionally the _async version)
<%static:webpack.*(?<!/)> | # webpack script tag start
</%static:webpack> | # webpack script tag end
<%static:studiofrontend.*?(?<!/)> | # studiofrontend script tag start
</%static:studiofrontend> | # studiofrontend script tag end
<%block[ ]*name=['"]requirejs['"]\w*(?<!/)> | # require js tag start
</%block> # require js tag end
""",