Commit 1a8b1d81 by Cliff Dyer Committed by GitHub

Merge pull request #48 from edx/cdyer/django-integration

Fixing django integration.
parents e88c7120 d367a6f8
......@@ -19,3 +19,5 @@ Primary codejail exports.
from .exceptions import CodeJailException, JailError, SafeExecException
from .jail import configure, is_configured, get_codejail
from .languages import python2, python3, other
__version__ = u'1.1'
......@@ -4,10 +4,10 @@ Code to glue codejail into a Django environment.
"""
from django.conf import settings as django_settings
from django.core.exceptions import MiddlewareNotUsed
from django.conf import settings
import codejail.limits
from .integration import configure_from_settings
class ConfigureCodeJailMiddleware(object):
......@@ -20,13 +20,5 @@ class ConfigureCodeJailMiddleware(object):
"""
def __init__(self):
python_bin = settings.CODE_JAIL.get('python_bin')
if python_bin:
user = settings.CODE_JAIL['user']
codejail.jail_code.configure("python", python_bin, user=user)
limits = settings.CODE_JAIL.get('limits', {})
for name, value in limits.items():
codejail.limits.set_limit(name, value)
configure_from_settings(django_settings)
raise MiddlewareNotUsed
"""
Integrate with application settings files.
"""
from __future__ import absolute_import
from . import jail
from . import limits
def configure_from_settings(settings):
"""
Configure a set of code jails and limits from a django settings file of the
form:
import codejail.languages
CODE_JAIL = {
'jails': [
{
'command': 'python',
'bin_path': '/edx/app/edxapp/venvs/edxapp-sandbox/bin/python',
'user': 'sandbox',
'lang': codejail.languages.python2,
},
{
'command': 'jail3',
'bin_path': '/edx/app/edxapp/venvs/edxapp-sandbox3/bin/python3',
'user': 'sandbox',
'lang': codejail.languages.python3,
},
],
'limits': {
'CPU': 1,
}
}
Each item in `CODE_JAIL['jails']` is a dict of kwargs for a `codejail.jail.Jail` object.
"""
if 'jails' in settings.CODE_JAIL:
for jail_config in settings.CODE_JAIL['jails']:
jail.configure(**jail_config)
requested_limits = settings.CODE_JAIL.get('limits', {})
for name, value in requested_limits.items():
limits.set_limit(name, value)
else:
legacy_configure_from_settings(settings)
def legacy_configure_from_settings(settings):
"""
Configure a "python" code jail and limits from a django settings file where
the settings look like this:
CODE_JAIL = {
"python_bin": "/edx/app/edxapp/venvs/edxapp-sandbox/bin/python",
"user": "sandbox",
"limits": {"CPU": 1},
}
"""
python_bin = settings.CODE_JAIL.get('python_bin')
if python_bin:
user = settings.CODE_JAIL['user']
jail.configure("python", python_bin, user=user)
requested_limits = settings.CODE_JAIL.get('limits', {})
for name, value in requested_limits.items():
limits.set_limit(name, value)
"""
Test configuring code jails from settings objects.
"""
from unittest import TestCase
from codejail import django_integration, jail, languages
class FakeJailSettings(object):
def __init__(self, setting_value):
self.CODE_JAIL = setting_value # pylint: disable=invalid-name
class TestDjangoIntegration(TestCase):
def setUp(self):
super(TestDjangoIntegration, self).setUp()
self.existing_commands = jail.COMMANDS
jail.COMMANDS = {}
def tearDown(self):
jail.COMMANDS = self.existing_commands
super(TestDjangoIntegration, self).tearDown()
def test_configure_jail(self):
codejail_setting = FakeJailSettings({
'jails': [
{
'command': 'fakey-fakey',
'user': 'nobody',
'bin_path': '/usr/bin/python',
'lang': languages.python3,
}
]
})
django_integration.configure_from_settings(codejail_setting)
self.assertTrue(jail.is_configured('fakey-fakey'))
def test_configure_legacy_jail(self):
codejail_setting = FakeJailSettings({
'python_bin': '/usr/bin/python',
'user': 'abc',
})
django_integration.configure_from_settings(codejail_setting)
codejail = jail.get_codejail('python')
self.assertEqual(codejail.command, 'python')
self.assertEqual(codejail.bin_path, '/usr/bin/python')
self.assertEqual(codejail.user, 'abc')
self.assertEqual(codejail.lang, languages.python2)
......@@ -153,6 +153,14 @@ class TestFeatures(JailCodeMixin, unittest.TestCase):
self.assertEqual(res.stdout, 'Look: Hello there.\n\n')
def test_directories_are_copied(self):
# The existence of pyc files makes the test dependent on whether the
# code in pylib/ has been executed or not. Removing them makes the
# test more deterministic.
pyc = os.path.join(os.path.dirname(__file__), './pylib/module.pyc')
if os.path.exists(pyc):
os.unlink(pyc)
res = jailpy(
code="""\
import os
......@@ -167,7 +175,7 @@ class TestFeatures(JailCodeMixin, unittest.TestCase):
self.assertResultOk(res)
self.assertEqual(res.stdout, textwrap.dedent("""\
('.', ['pylib', 'tmp'], ['hello.txt', 'jailed_code'])
('./pylib', [], ['module.py', 'module.pyc'])
('./pylib', [], ['module.py'])
('./tmp', [], [])
"""))
......
......@@ -6,7 +6,7 @@ from setuptools import setup
setup(
name="codejail",
version="1.0",
version="1.1",
packages=['codejail'],
description="Manages execution of untrusted code in secure sandboxes.",
license="Apache Software License, version 2.0",
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment