summaryrefslogtreecommitdiff
path: root/notes/rules-callouts
blob: a216acd8c2b10e97d61936641d92d1a7ca2fd6ca (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
Callouts in rules application
-----------------------------

When 'gitano/callout' is written to, the current ruleset is pushed onto a stack
and the referenced ruleset is loaded and run.  If execution falls off the end
of that ruleset without returning a result, then execution continues in the
caller at the next instruction.

The value written to gitano/callout is first stripped of any character not in
[A-Za-z0-9:_-] and is then matched against the prefix 'core:' if the prefix
matches then it is also stripped and the location to load rules from is the
gitano-admin:master branch.  Otherwise the location to load rules from is the
current project's refs/gitano/admin branch.

The name of the called rules file is prepended with callouts/ and appended with
.rules, turning 'writers' into 'callouts/writes.rules' Gitano then looks to
load that ruleset and parse it.  A ruleset which does not exist is transformed
into:

Deny("Callout ruleset " .. calloutname .. " not found")

A ruleset which fails to compile is transformed into:

Deny("Callout ruleset " .. calloutname .. " failed to compile")

Otherwise the ruleset is run.

It is recommended that if writing core rulesets, the admin keeps them as simple
and clean as possible and programmes any defensive measures into the start of
the ruleset as is necessary to ensure that the callouts cannot be abused by
other projects.

----

In addition to gitano/callout there is gitano/trycallout which does the same as
the above, but if the callout sets gitano/action then the setting is captured
and put into gitano-action (and gitano/reason is trapped and placed in
gitano-reason) [note - not /, these are mutable by the caller] and control is
returned to the caller at the next instruction.

This allows calling rulesets to then perform rules based on the provided result
and alter their behaviour accordingly.

For example, if the core.rules contained:

Callout "project"

to run callouts/project.rules in the project repository, then if that ruleset
didn't exist, it'd fail the ruleset evaluation immediately.  However if the
core ruleset used TryCallout instead, then it could process the resulting error
and perhaps alter the message to request that the user contact the site admin
(or if the request is a read operation, perhaps permit it according to some
site rules instead).