diff --git a/doc/MANUAL.md b/doc/MANUAL.md
index 525c4fc..d453ca8 100644
--- a/doc/MANUAL.md
+++ b/doc/MANUAL.md
@@ -3,6 +3,10 @@
## Table of Contents
1. [Invocations](#invocations)
+ - [Shell foreground](#invocations_foreground)
+ - [Daemon](#invocations_daemon)
+ - [Init script](#invocations_init)
+ - [Behind Apache](#invocations_apache)
1. [Form config (JSON) files](#form_config)
1. [Field types](#field_types)
- [String](#field_types_string)
@@ -15,28 +19,42 @@
- [Password](#field_types_password)
- [File](#field_types_file)
1. [Output](#output)
+ - [Output types](#output_types)
+ - [Exit codes](#output_exitcodes)
1. [Callbacks](#callbacks)
- [Script callbacks]()
- [Validation]()
- [Field Values]()
- [Python callbacks]()
1. [Users](#users)
+ - [Passwords](#users_passwords)
+ - [Form limiting](#users_formlimit)
+ - [Security considerations](#users_security)
+1. [Troubleshooting](#troubleshooting)
## Invocations
+Upon starting Scriptform, it will change the working directory to the path
+containing the form definition you've sepcified. It will read the form
+definition and perform some basic sanity checks to see if, for instance, the
+scripts you specified exist and are executable.
+
There are multiple ways of running ScriptForm. This chapter outlines the
various methods. They are listed in the order of least to most
pruduction-ready.
-### Shell foreground
+### Shell foreground
+
+Sriptform can be run directly from the shell in the foreground with the `-f`
+(`--foreground`) option. This is most useful for testing and development:
+
+ $ /usr/bin/scriptform -p8000 -f ./formdef.json
-Sriptform can be run directly from the shell in the foreground. This is most
-useful for testing and development.
+### Daemon
-Unless the paths to your scripts are absolute, you should run Scriptform from
-the directory that contains the Form definition file.
+### Init script
-### Behind Apache
+### Behind Apache
Enable Apache modules mod_proxy and mod_proxy_http:
@@ -60,11 +78,16 @@ on an overview page, and the user can select which form they want to fill out.
Structurally, they are made up of the following elements:
- **`title`**: Text to show at the top of each page. **Required**, **String**.
+
- **`forms`**: Dictionary where the key is the form id and the value is a
dictionary that is the definition for a single form. **Required**, **Dictionary**.
+
- **`title`**: Title for the form. **Required**, **String**.
+
- **`description`**: A description of the form. May include HTML tags. **Required**, **String**.
+
- **`submit_title`**: The text on the submit button of the form.
+
- **`script`**: The path to an executable script of binary that will be
called if the form is submitted. See also [[Callbacks]]. If this field is
omitted, Scriptform will instead call a python callable (function,
@@ -72,19 +95,32 @@ Structurally, they are made up of the following elements:
script isn't found, if the script isn't executable or (if the `script`
tag is omitted) if no Python callback is registered to handle this form.
**String**.
+
- **`output`**: Determines how the output of the callback is handled. See
- the *Output types* seciton.
+ the [Output](#output) section.
+
- **`fields`**: List of fields in the form. Each field is a dictionary.
**Required**, **List of dictionaries**.
+
- **`name`**: The name of the field. This is what is passed as an
- environment variable to the callback.
+ environment variable to the callback. **Required**, **String**.
+
- **`title`**: The title for the field, shown just above the actual
- field.
+ field. **Required**, **String**.
+
- **`type`**: Field type. Supported types are: *string*, *integer*,
*float*, *date*, *radio*, *select*, *text*, *password* and *file*.
For more information, see [Field types].
- - **`required`**: Whether the field is required.
+
+ - **`required`**: Whether the field is required. **Optional**,
+ **Boolean**.
+
- **`...`**: Other options, which depend on the type of field.
+ **Optional**.
+
+ - **`allowed_users`**: A list of users that are allowed to view and submit
+ this form. **Optional**, **List of strings**.
+
- **`users`**: A dictionary of users where the key is the username and the
value is the plaintext password. This field is not required. **Dictionary**.
@@ -141,6 +177,7 @@ For example, here's a form config file that contains two forms:
}
}
+Many more examples can be found in the `examples` directory in the source code.
## Field types
@@ -231,18 +268,37 @@ No additional validatikon is done on the file contents.
## Output
-FIXME
+**All output is assumed to be UTF8, regardless of system encoding!**
- If
- its value is `escaped`, the output of the callback will have its HTML
- entities escaped and will be wrapped in PRE elements. This is the
- **default** option. If the value is `html`, the output will not be
- escaped or wrapped in PRE tags, and can thus include HTML markup. If the
- output is `raw`, the output of the script is streamed directly to the
- client's browser. This allows you to output images, binary files, etc to
- the client. The script must include the proper headers and body itself.
+### Output types
-**All output is assumed to be UTF8, regardless of system encoding!**
+Scripts can have a few different output types. The output type is specified in
+the **`output`** field of the form definition. For example, the following form
+definition has a `raw` output type.:
+
+ "display_image" {
+ "title": "Show an image",
+ "description": "Show an image",
+ "script: "job_display_image.sh",
+ "output": "raw",
+ "fields": []
+ }
+
+The following output types are supported:
+
+- **`escaped`**: the output of the callback will have its HTML entities escaped
+ and will be wrapped in PRE elements. This is the **default** option.
+
+- **`html`**: If the value is `html`, the output will not be escaped or wrapped
+ in PRE tags, and can thus include HTML markup.
+
+- **`raw`**: The output of the script is streamed directly to the client's
+ browser. This allows you to output images, binary files, etc to the client.
+ The script must include the proper headers and body itself. Examples of raw
+ script output can be found in the `examples/raw` directory.
+
+
+### Exit codes
If the script's exit code is 0, the output of the script (stdout) is captured
and shown to the user in the browser.
@@ -250,17 +306,9 @@ and shown to the user in the browser.
If a script's exit code is not 0, it is assumed an error occured. Scriptform
will show the script's stderr output (in red) to the user instead of stdin.
-FIXME:
-If the form definition has a `script_raw` field, and its value is `true`,
-Scriptform will pass the output of the script to the browser as-is. This allows
-scripts to show images, stream a file download to the browser or even show
-completely custom HTML output. The script's output must be a valid HTTP
-response, including headers and a body. Examples of raw script output can be
-found in the `examples/raw` directory.
## Callbacks
-
Callbacks are called after the form has been submitted and its values have been
validated. They are the actual implementations of the form's action.
@@ -355,6 +403,8 @@ view the form 'only_some_users'.
}
}
+### Passwords
+
Passwords are unsalted SHA256 hashed passwords. To generate one, you can use
the `--generate-pw` option of Scriptform. This will ask you twice for a
plaintext password and return the hash that can be used in the `users` element.
@@ -369,7 +419,15 @@ the form. This is specified by a `allowed_users` field in the form definition,
as can be seen in the previous form configuration example. Multiple users may
be specified.
-### Security considerations
+### Form limiting
+
+You may specify a `allowed_users` field in a form definition. Only user names
+listed in the field are allowed to see and submit that form. If the user is not
+listed, they won't even see the form as being available.
+
+For an example, see the (beginning of this chapter)[#users].
+
+### Security considerations
- Passwords have no salt. This makes them slightly easier to bruteforce en-mass.
- Scriptform does not natively support secure HTTPS connections. This means
@@ -377,3 +435,5 @@ be specified.
you wish to prevent this, you should put Scriptform behind a proxy that
*does* support Scriptform, such as Apache. For more information on that, see
the "Invocations" chapter.
+
+## Troubleshooting