Pass additional info to script environment.

pull/7/head
Ferry Boender 5 years ago
parent f647538d62
commit c78bb1bb6c
  1. 10
      doc/MANUAL.md
  2. 3
      src/runscript.py
  3. 12
      src/webapp.py
  4. 6
      test/test.py

@ -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.
### <a name="script_env">Environment</a>
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`.
### <a name="script_runas">Execution security policy</a>
Running arbitrary scripts from Scriptform poses somewhat of a security risk.

@ -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)

@ -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.

@ -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):

Loading…
Cancel
Save