summaryrefslogtreecommitdiff
path: root/exam
diff options
context:
space:
mode:
authorPrabhu Ramachandran2011-11-12 10:02:57 +0530
committerPrabhu Ramachandran2011-11-12 10:02:57 +0530
commitfb31dcc7693395c9856fb19c3e867fbfa2e9b4f8 (patch)
tree24b50d4bce7ac5faa5ec6ae98db041766340814b /exam
parentc69bc272c1c3ba02c3f244586b65254036e73de3 (diff)
downloadonline_test-fb31dcc7693395c9856fb19c3e867fbfa2e9b4f8.tar.gz
online_test-fb31dcc7693395c9856fb19c3e867fbfa2e9b4f8.tar.bz2
online_test-fb31dcc7693395c9856fb19c3e867fbfa2e9b4f8.zip
ENH: Running remote code safely via XMLRPC.
Adding a python_server which executes code as nobody safely so users cannot do too much damage.
Diffstat (limited to 'exam')
-rw-r--r--exam/views.py42
-rw-r--r--exam/xmlrpc_clients.py5
2 files changed, 10 insertions, 37 deletions
diff --git a/exam/views.py b/exam/views.py
index 7ee3c53..ed33c91 100644
--- a/exam/views.py
+++ b/exam/views.py
@@ -10,6 +10,7 @@ from django.shortcuts import render_to_response, get_object_or_404, redirect
from django.template import RequestContext
from exam.models import Question, Quiz, Profile, Answer
from exam.forms import UserRegisterForm, UserLoginForm
+from exam.xmlrpc_clients import python_server
def gen_key(no_of_chars):
"""Generate a random key of the number of characters."""
@@ -116,41 +117,6 @@ def question(request, q_id):
return render_to_response('exam/question.html', context,
context_instance=ci)
-def test_python(answer, test_code):
- """Tests given Python function with the test code supplied.
-
- Returns
- -------
-
- A tuple: (success, error message).
-
- """
- success = False
- tb = None
- try:
- submitted = compile(answer, '<string>', mode='exec')
- g = {}
- exec submitted in g
- _tests = compile(test_code, '<string>', mode='exec')
- exec _tests in g
- except AssertionError:
- type, value, tb = sys.exc_info()
- info = traceback.extract_tb(tb)
- fname, lineno, func, text = info[-1]
- text = str(test_code).splitlines()[lineno-1]
- err = "{0} {1} in: {2}".format(type.__name__, str(value), text)
- except:
- type, value = sys.exc_info()[:2]
- err = "Error: {0}".format(repr(value))
- else:
- success = True
- err = 'Correct answer'
- finally:
- del tb
-
- return success, err
-
-
def check(request, q_id):
user = request.user
question = get_object_or_404(Question, pk=q_id)
@@ -162,8 +128,10 @@ def check(request, q_id):
next_q = quiz.skip()
return show_question(request, next_q)
- # Otherwise we were asked to check.
- success, err_msg = test_python(answer, question.test)
+ # Otherwise we were asked to check. We obtain the results via XML-RPC
+ # with the code executed safely in a separate process (the python_server.py)
+ # running as nobody.
+ success, err_msg = python_server.run_code(answer, question.test)
# Add the answer submitted.
new_answer = Answer(question=question, answer=answer.strip())
diff --git a/exam/xmlrpc_clients.py b/exam/xmlrpc_clients.py
new file mode 100644
index 0000000..1bc5513
--- /dev/null
+++ b/exam/xmlrpc_clients.py
@@ -0,0 +1,5 @@
+from xmlrpclib import ServerProxy
+
+# Connect to the python server.
+python_server = ServerProxy('http://localhost:8001')
+ \ No newline at end of file