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