Files
edx-platform/xmodule/util/sandboxing.py
Taylor Payne 16d96565e3 refactor: move production defaults to common modules (#37045)
In the effort to simplify settings in edx-platform, as discussed in ADR 22 -
Settings Simplification, this PR brings some of the production defaults defined
in `lms/envs/production.py` and `cms/envs/production.py` up to
`openedx/envs/common.py` or `lms/envs/common.py` and `cms/envs/common.py` as
appropriate.

Bringing these defaults up from the `production.py` settings modules caused
changes in the rendered settings of the `test.py` modules, and so I have
settings to the `test.py` modules to bring the rendered settings back in line
with what is has been. I have not deeply looked at which settings are needed
for tests to pass or not, but just the differences between the rendered
settings between `master` and this branch.

ADR 22: https://github.com/openedx/edx-platform/blob/master/docs/decisions/0022-settings-simplification.rst
Fixes https://github.com/openedx/edx-platform/issues/36892.
2025-08-04 17:06:16 -04:00

77 lines
2.8 KiB
Python

# lint-amnesty, pylint: disable=missing-module-docstring
import re
from django.conf import settings
DEFAULT_PYTHON_LIB_FILENAME = 'python_lib.zip'
def course_code_library_asset_name():
"""
Return the asset name to use for course code libraries, defaulting to python_lib.zip.
"""
return getattr(settings, 'PYTHON_LIB_FILENAME', DEFAULT_PYTHON_LIB_FILENAME)
def can_execute_unsafe_code(course_id):
"""
Determine if this course is allowed to run unsafe code.
For use from the ModuleStore. Checks the `course_id` against a list of whitelisted
regexes.
Returns a boolean, true if the course can run outside the sandbox.
"""
# To decide if we can run unsafe code, we check the course id against
# a list of regexes configured on the server.
# If this is not defined in the environment variables then default to the most restrictive, which
# is 'no unsafe courses'
# TODO: This should be a database configuration, where we can mark individual courses as being
# safe/unsafe. Someone in the future should switch us over to that rather than using regexes
# in a settings file
# To others using this: the code as-is is brittle and likely to be changed in the future,
# as per the TODO, so please consider carefully before adding more values to COURSES_WITH_UNSAFE_CODE
for regex in getattr(settings, 'COURSES_WITH_UNSAFE_CODE', []):
if re.match(regex, str(course_id)):
return True
return False
def get_python_lib_zip(contentstore, course_id):
"""Return the bytes of the course code library file, if it exists."""
python_lib_filename = course_code_library_asset_name()
asset_key = course_id.make_asset_key("asset", python_lib_filename)
zip_lib = contentstore().find(asset_key, throw_on_not_found=False)
if zip_lib is not None:
return zip_lib.data
else:
return None
class SandboxService:
"""
A service which provides utilities for executing sandboxed Python code, for example, inside custom Python questions.
Args:
contentstore(function): function which creates an instance of xmodule.content.ContentStore
course_id(string or CourseLocator): identifier for the course
"""
def __init__(self, contentstore, course_id, **kwargs):
super().__init__(**kwargs)
self.contentstore = contentstore
self.course_id = course_id
def can_execute_unsafe_code(self):
"""
Returns a boolean, true if the course can run outside the sandbox.
"""
return can_execute_unsafe_code(self.course_id)
def get_python_lib_zip(self):
"""
Return the bytes of the course code library file, if it exists.
"""
return get_python_lib_zip(self.contentstore, self.course_id)