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
|
#!/usr/bin/perl
use strict;
use warnings;
# see bottom of this file for instructons and IMPORTANT WARNINGS!
# ----------------------------------------------------------------------
my $rule = $ARGV[7];
die "\n\nFATAL: GL_REFEX_EXPR_ doesn't exist\n(your admin probably forgot the rc file change needed for this to work)\n\n"
unless exists $ENV{ "GL_REFEX_EXPR_" . $rule };
my $res = $ENV{ "GL_REFEX_EXPR_" . $rule } || 0;
print "$ARGV[6] ($res)\n" if $res;
exit 0;
__END__
------------------------------------------------------------------------
IMPORTANT WARNINGS:
* has not been tested heavily
* SO PLEASE TEST YOUR SPECIFIC USE CASE THOROUGHLY!
* read the NOTES section below
* syntax and semantics are to be considered beta and may change as I find
better use cases
------------------------------------------------------------------------
Refex expressions, like VREFs, are best used as additional "deny" rules, to
deny combinations that the normal ruleset cannot detect.
To enable this, uncomment 'refex-expr' in the ENABLE list in the rc file.
It allows you to say things like "don't allow users u3 and u4 to change the
Makefile in the master branch" (i.e., they can change any other file in
master, or the Makefile in any other branch, but not that specific combo).
repo foo
RW+ = u1 u2 # line 1
RW+ master = u3 u4 # line 2
RW+ = u3 u4 # line 3
RW+ VREF/NAME/Makefile = u3 u4 # line 4
- master and VREF/NAME/Makefile = u3 u4 # line 5
Line 5 is a "refex expression". Here are the rules:
* for each refex in the expression ("master" and "VREF/NAME/Makefile" in
this example), a count is kept of the number of times the EXACT refex was
matched and allowed in the *normal* rules (here, lines 2 and 4) during
this push.
* the expression is evaluated based on these counts. 0 is false, and
any non-zero is true (see more examples later). The truth value of the
expression determines whether the refex expression matched.
You can use any logical or arithmetic expression using refexes as operands
and using these operators:
not and or xor + - == -lt -gt -eq -le -ge -ne
Parens are not allowed. Precedence is as you might expect for those
operators. It's actually perl that is evaluating it (you can guess what
the '-lt' etc., get translated to) so if in doubt, check 'man perlop'.
* the refexes that form the terms of the expression (in this case, lines 2
and 4) MUST come before the expression itself (i.e., line 5).
* note the words "EXACT refex was matched" above.
Let's say you add "u3" to line 1. Then the refex expression in line 5
would never match for u3. This is because line 1 prevents line 2 from
matching (being more general *and* appearing earlier), so the count for
the "master" refex would be 0. If "master" is 0 (false), then "master and
<anything>" is also false.
(Same thing is you swap lines 2 and 3; i.e., put the "RW+ = ..." before
the "RW+ master = ...").
Put another way, the terms in the refex expression are refexes, not refs.
Merely pushing the master branch does not mean the count for "master"
increases; it has to *match* on a line that has "master" as the refex.
Here are some more examples:
* user u2 is allowed to push either 'doc/' or 'src/' but not both
repo foo
RW+ = u1 u2 u3
RW+ VREF/NAME/doc/ = u2
RW+ VREF/NAME/src/ = u2
- VREF/NAME/doc/ and VREF/NAME/src/ = u2
* user u3 is allowed to push at most 2 files to conf/
repo foo
RW+ = u1 u2 u3
RW+ VREF/NAME/conf/ = u3
- VREF/NAME/conf/ -gt 2 = u3
|