Open fxnn opened 8 years ago
Adding functionality to existing workflows calls for hooks. A hook is an executable, e.g. a shell script, placed inside a special directory structure inside the .gone
directory (cf. #27). It is executed instead of gones regular request processing, receiving some information about the HTTP request via commandline / environment variables, and having it's output sent back as HTTP response.
gone will provide different types of hooks, which differ in the kind of activation criteria.
GET
requests without any further parameters imply the read
action. Creating or updating files is done using create
or edit
actions and POST
requests, while the respective UI is displayed using GET
requests. With hooks, the admin can have executables invoked only for specific actions, and thus overwrite predefined actions or create new ones.Depending on the hook's type, you would define them in different directories: .gone/hook-by-action
, .gone/hook-by-extension
or .gone/hook-by-mime
. Below, you can place the executables (or symlinks to executables), possibly in subdirectories. However, naming and exact placement of the executable has an impact of when it gets called.
GET
, POST
, PUT
), and on the other hand the action/extension/MIME type (depending on the trigger type). An action trigger post-create.sh
is invoked on POST requests for the create
action, the extension trigger get-md.sh
could specify another Markdown renderer, and get-application-xml.sh
might implement some XSL transformation.
listener
flag makes the HTTP response completely independent of the hook output. gone will apply its regular request processing, and might invoke the hook synchronously or asynchronously to request processing. There may be multiple listener
hooks per request.precondition
flag makes gone apply its regular request processing, but only after the hook was invoked and returned exit code 0
. Otherwise, gone will not process the request furtherly and respond with an HTTP error code. Especially, gone will not write any files due to create
or edit
request. It's unclear, whether gone should respond with a 400
or 500
status code in case of failure.postcondition
flag makes gone apply its regular request processing in any case. Additionally, before sending a response, it invokes the hook. If that returns a non-zero exit code, gone will send an HTTP error response.virtual
flag tells gone not to check whether the HTTP request path matches a file, i.e. the hook is also executed for non-existant files or directories. gone will never respond with 404
in that case..request-path-glob.allow.filter
file. Every line may contain a glob pattern matched against the HTTP request path, e.g. /path/to/file.ext
. If the file exists, hooks from that directory or any directory below will only be applied to a given request, if at least one glob in the file matches. Consequently, an empty file of that name completely disables the directory..request-path-glob.deny.filter
file, with the opposite semantics: no hook from that directory or any directory below will be applied to a given request as soon as at least one glob in the file matches..user.allow.filter
and .user.deny.filter
contain a login username per line, enabling or disabling hooks for the given users as described above. The special line *
matches any user being logged in..group.allow.filter
and .group.deny.filter
contain a group name per line, enabling or disabling hooks for users of the given groups as described above. You will be able to assign users to groups using a .htgroup
file.CGI scripts are invoked directly by giving their path and name as HTTP request URL, e.g. http://example.com/cgi-bin/some-cgi-script.pl
. This makes file system internas publicy available and has a high risk of misconfiguration. For example, a common problem with CGI scripts is that attackers manage to download the script's sourcecode, thus being able to find security holes.
gones hooks are strictly separated from the content root. The contents of the hook directory will never be modified by gone, nor will they be displayed to a client. gone will only execute hooks that were explicitly defined to be executed in a special situation, they can not be executed by file name.
The following new attack vectors arise. Besides, I sketch potential risk mitigation strategies.
login
hookIt's unclear to me whether we should allow overwriting the login
hook. The only possible scenario I can imagine is deactivating gones user and permission management, and possibly redirecting login
requests to a different application instead.
I can't see, why we should forbid this kind of action.
In other words, a script that's executable by the gone process, but not world executable will only get invoked in course of the action of a user being logged in.
At the beginning, it will not be possible for a hook to tell gone to render it's output using a template, or using the Markdown parser. A hook's output will directly be used as HTTP body.
If a hook returns a non-zero exit code, by default, gone will deliver a HTTP 500 without any further information about the hook or it's output. However, relevant information will be logged.
I want to make gone an application that fits many purposes, yet as simple as possible. Therefore, we need extension points (Open Closed Principle). This could include the possibility to call completely new functionality from the UI. Such a concept would greatly complement with the customizeable UI templates.
Stories
git commit -a
everytime a file is saved.