-
Notifications
You must be signed in to change notification settings - Fork 4
/
README.INTERNALS
104 lines (78 loc) · 4.46 KB
/
README.INTERNALS
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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
Here is the chain of function calls that are made (or can be made) when an
interface calls a core routine.
interface ->
argument marshaller (in Parser.pm) ->
Majordomo::dispatch (does common checks, etc.) ->
Core function ->
(access check) -> (can stop here, perhaps generating a token)
(bottom half) ->
(do stuff) ->
(return stuff) ->
Format.pm (format results for humans).
This looks extremely complex, but consider these requirements:
* There must be a clean break between the core and the interface. The core
must not assume anything about how the data will be displayed, and it
should do no formatting.
* All calls from the interface must go through security validation.
Nothing that comes from the interface is to be trusted. The core
functions may need to pass different parameters to the security checker.
(This explains why the core dispatch function calls the core function and
not the security checker directly. Actually, it's possible that some
functions don't do any special checking and can be eliminated.)
* Any request must be able to be stalled indefinitely and completed at a
later time when the owner or requester has verified that it is OK for the
request to proceed.
(This explains the complicated path through the Token routines, and the
reason that those routines can also call the bottom half of the core
routines directly. It's also the reason for most of the real complexity.)
Here goes:
The interface can call the parser to pick out a set of commands and call
the dispatch routine, or call the dispatch routine directly. Both the
interface and the parser may call core utility functions to retrieve config
variables and the list of lists. The parser will provide the default list
if it is known, and also maintain state for default password/list.
---- The core/interface junction is here. ----
The core dispatch function calls the appropriate core function.
The core function calls global/list_access_check to check passwords and
such.
List_access_check makes use of master_password and the passwords table to
determine whether the given password (if any) is valid. If no password was
given, it calls the appropriate routine from the pre-parsed access_rules
data, takes the result, and calls the appropriate internal access checking
routine.
The internal access checking routine will wither return a result, consult
other config variables and return a result, or call either Token::confirm
or consult.
Token::confirm/consult generate a token and sent it to the appropriate
address/addresses, then return to the internal access checking routine.
The internal access checking routine will either return (to
list_access_check) 1 for success, 0 for failure, or -1 for a conditional
success: one that requires either confirmation or consultation and this
cannot be immediately completed. (The latter is called a stall.) It can
also return a message which comes from the access_rules routine.
List_access_check returns directly to the core function.
The core function then decides if the request should be completed and if
not it returns (-1 or 0 and the message) to the dispatch function.
Otherwise it calls its bottom half function.
The bottom half function returns 1 and its data, or 0 and a message if
something goes wrong.
The core function returns those results immediately.
The core dispatch function then calls the inform routine appropriately so
the request (and its success/failure/stall) is duly logged and the
appropriate people are informed.
---- Back across the core/interface junction ----
The parser or interface then takes the return and calls the appropriate
formatting function.
The formatting function takes the data from the core function and turns it
into something the user can understand. The formatter can make more calls
to the core to retrieve additional data, so that huge lists or files do not
have to be buffered entirely on both sides of the link.
Note that in the case of a stall, the token acceptance routine will call
into the core and the core will then call the bottom half function on its
own. The acceptance routine must then take these results and call the
formatter to present the results to the user. This is how _any_ request
can be sent off for confirmation and completed at an arbitrary time in the
future. The token database stores all of the information required to allow
the core to complete the request later. Note that the interface which
accepts the token does not have to be the interface that made the request.
- J<