From c78bb1bb6c6e5a618ff591b567896f10d5d6d98d Mon Sep 17 00:00:00 2001 From: Ferry Boender Date: Tue, 6 Aug 2019 08:47:31 +0200 Subject: [PATCH] Pass additional info to script environment. --- doc/MANUAL.md | 10 +++++++++- src/runscript.py | 3 +-- src/webapp.py | 12 ++++++++++-- test/test.py | 6 +++--- 4 files changed, 23 insertions(+), 8 deletions(-) diff --git a/doc/MANUAL.md b/doc/MANUAL.md index 0592de7..4e294ed 100644 --- a/doc/MANUAL.md +++ b/doc/MANUAL.md @@ -1333,11 +1333,19 @@ The contents of the file is available in a shell script as: echo "The CSV file has $(expr $ROWS - 1) rows" These temporary files are automatically cleaned up after the script's execution -ends. +ends. Examples of file uploads can be found in the `examples/simple` and `examples/megacorp` directories. +### Environment + +Other than the field values, a few additional values are provided through the +environment to the script: + +* `__SF__FORM`: The name of the form. E.g. `clean_database`. +* `__SF__USER`: The logged in user executing the form. E.g. `admin`. + ### Execution security policy Running arbitrary scripts from Scriptform poses somewhat of a security risk. diff --git a/src/runscript.py b/src/runscript.py index 333b8ea..b04d4e9 100644 --- a/src/runscript.py +++ b/src/runscript.py @@ -59,7 +59,7 @@ def run_as(uid, gid, groups): return set_acc -def run_script(form_def, form_values, stdout=None, stderr=None): +def run_script(form_def, form_values, env, stdout=None, stderr=None): """ Perform a callback for the form `form_def`. This calls a script. `form_values` is a dictionary of validated values as returned by @@ -77,7 +77,6 @@ def run_script(form_def, form_values, stdout=None, stderr=None): raise ValueError(msg) # Pass form values to the script through the environment as strings. - env = os.environ.copy() for key, value in form_values.items(): env[key] = str(value) diff --git a/src/webapp.py b/src/webapp.py index 60dc1e0..edf7c55 100644 --- a/src/webapp.py +++ b/src/webapp.py @@ -447,8 +447,16 @@ class ScriptFormWebApp(RequestHandler): log.info("Vars: %s", censor_form_values(form_def, form_values)) form_def = form_config.get_form_def(form_name) - result = runscript.run_script(form_def, form_values, self.wfile, - self.wfile) + + # Construct base environment. The field values are added in + # run_scripts. + env = os.environ.copy() + env["__SF__FORM"] = form_name + if username is not None: + env["__SF__USER"] = username + + result = runscript.run_script(form_def, form_values, env, + self.wfile, self.wfile) if form_def.output != 'raw': # Ignore everything if we're doing raw output, since it's the # scripts responsibility. diff --git a/test/test.py b/test/test.py index 98f7ea7..81f12c5 100644 --- a/test/test.py +++ b/test/test.py @@ -50,7 +50,7 @@ class FormConfigTestCase(unittest.TestCase): sf = scriptform.ScriptForm('test_formconfig_callback.json') fc = sf.get_form_config() fd = fc.get_form_def('test_store') - res = runscript.run_script(fd, {}) + res = runscript.run_script(fd, {}, {}) self.assertEquals(res['exitcode'], 33) self.assertTrue('stdout' in res['stdout']) self.assertTrue('stderr' in res['stderr']) @@ -62,7 +62,7 @@ class FormConfigTestCase(unittest.TestCase): fd = fc.get_form_def('test_raw') stdout = file('tmp_stdout', 'w+') # can't use StringIO stderr = file('tmp_stderr', 'w+') - exitcode = runscript.run_script(fd, {}, stdout, stderr) + exitcode = runscript.run_script(fd, {}, {}, stdout, stderr) stdout.seek(0) stderr.seek(0) self.assertTrue(exitcode == 33) @@ -74,7 +74,7 @@ class FormConfigTestCase(unittest.TestCase): sf = scriptform.ScriptForm('test_formconfig_callback.json') fc = sf.get_form_config() fd = fc.get_form_def('test_raw') - self.assertRaises(ValueError, runscript.run_script, fd, {}) + self.assertRaises(ValueError, runscript.run_script, fd, {}, {}) class FormDefinitionTest(unittest.TestCase):