@@ -2,26 +2,120 @@ package authz_test
2
2
3
3
import (
4
4
"fmt"
5
+ "github.com/coder/coder/coderd/authz"
5
6
"github.com/coder/coder/coderd/authz/authztest"
6
7
"math/bits"
8
+ "strings"
7
9
"testing"
8
10
)
9
11
10
12
var nilSet = authztest.Set {nil }
11
13
12
14
func Test_ExhaustiveAuthorize (t * testing.T ) {
13
15
all := authztest .GroupedPermissions (authztest .AllPermissions ())
14
- variants := permissionVariants (all )
15
- for name , v := range variants {
16
+ roleVariants := permissionVariants (all )
17
+
18
+ testCases := []struct {
19
+ Name string
20
+ Objs []authz.Object
21
+ // Action is constant
22
+ // Subject comes from roleVariants
23
+ Result func (pv string ) bool
24
+ }{
25
+ {
26
+ Name : "User:Org" ,
27
+ Objs : authztest .Objects (
28
+ []string {authztest .PermMe , authztest .PermOrgID },
29
+ ),
30
+ Result : func (pv string ) bool {
31
+ return strings .Contains (pv , "+" )
32
+ },
33
+ },
34
+ {
35
+ // All U+/- tests should fail
36
+ Name : "NotUser:Org" ,
37
+ Objs : authztest .Objects (
38
+ []string {"other" , authztest .PermOrgID },
39
+ []string {"" , authztest .PermOrgID },
40
+ ),
41
+ Result : func (pv string ) bool {
42
+ if strings .Contains (pv , "U" ) {
43
+ return false
44
+ }
45
+ return strings .Contains (pv , "+" )
46
+ },
47
+ },
48
+ {
49
+ // All O+/- and U+/- tests should fail
50
+ Name : "NotUser:NotOrg" ,
51
+ Objs : authztest .Objects (
52
+ []string {authztest .PermMe , "non-mem" },
53
+ []string {"other" , "non-mem" },
54
+ []string {"other" , "" },
55
+ []string {"" , "non-mem" },
56
+ []string {"" , "" },
57
+ ),
58
+ Result : func (pv string ) bool {
59
+ if strings .Contains (pv , "U" ) {
60
+ return false
61
+ }
62
+ if strings .Contains (pv , "O" ) {
63
+ return false
64
+ }
65
+ return strings .Contains (pv , "+" )
66
+ },
67
+ },
68
+ // TODO: @emyrk for this one, we should probably pass a custom roles variant
69
+ //{
70
+ // // O+, O- no longer pass judgement. Defer to user level judgement (only somewhat tricky case)
71
+ // Name: "User:NotOrg",
72
+ // Objs: authztest.Objects(
73
+ // []string{authztest.PermMe, ""},
74
+ // ),
75
+ // Result: func(pv string) bool {
76
+ // return strings.Contains(pv, "+")
77
+ // },
78
+ //},
79
+ }
80
+
81
+ var pvars int
82
+ for name , v := range roleVariants {
16
83
fmt .Printf ("%s: %d\n " , name , v .Size ())
84
+ pvars += v .Size ()
85
+ }
86
+ var total int = 0
87
+ for _ , c := range testCases {
88
+ total += len (c .Objs ) * pvars
89
+ }
90
+ fmt .Printf ("pvars=%d, total=%d\n " , pvars , total )
91
+
92
+ var tot int
93
+ for _ , c := range testCases {
94
+ t .Run (c .Name , func (t * testing.T ) {
95
+ for _ , o := range c .Objs {
96
+ for _ , v := range roleVariants {
97
+ v .Each (func (set authztest.Set ) {
98
+ // TODO: Authz.Permissions does allocations at the moment. We should fix that.
99
+ err := authz .AuthorizePermissions (
100
+ authztest .PermMe ,
101
+ set .Permissions (),
102
+ o ,
103
+ authztest .PermAction )
104
+ var _ = err
105
+ tot ++
106
+ })
107
+ v .Reset ()
108
+ }
109
+ }
110
+ })
17
111
}
18
112
}
19
113
20
114
func permissionVariants (all authztest.SetGroup ) map [string ]* authztest.Role {
21
115
// an is any noise above the impactful set
22
- an := abstain
116
+ an := noiseAbstain
23
117
// ln is any noise below the impactful set
24
- ln := positive | negative | abstain
118
+ ln := noisePositive | noiseNegative | noiseAbstain
25
119
26
120
// Cases are X+/- where X indicates the level where the impactful set is.
27
121
// The impactful set determines the result.
@@ -46,26 +140,25 @@ func permissionVariants(all authztest.SetGroup) map[string]*authztest.Role {
46
140
neg (all .Site ()),
47
141
noise (ln , all .Org (), all .User ()),
48
142
),
49
- // TODO: Figure out cross org noise between org:* and org:mem
50
- // Org:*
143
+ // Org:* -- Added org:mem noise
51
144
"O+" : authztest .NewRole (
52
- noise (an , all .Wildcard (), all .Site ()),
145
+ noise (an , all .Wildcard (), all .Site (), all . OrgMem () ),
53
146
pos (all .Org ()),
54
147
noise (ln , all .User ()),
55
148
),
56
149
"O-" : authztest .NewRole (
57
- noise (an , all .Wildcard (), all .Site ()),
150
+ noise (an , all .Wildcard (), all .Site (), all . OrgMem () ),
58
151
neg (all .Org ()),
59
152
noise (ln , all .User ()),
60
153
),
61
- // Org:Mem
154
+ // Org:Mem -- Added org:* noise
62
155
"M+" : authztest .NewRole (
63
- noise (an , all .Wildcard (), all .Site ()),
156
+ noise (an , all .Wildcard (), all .Site (), all . Org () ),
64
157
pos (all .OrgMem ()),
65
158
noise (ln , all .User ()),
66
159
),
67
160
"M-" : authztest .NewRole (
68
- noise (an , all .Wildcard (), all .Site ()),
161
+ noise (an , all .Wildcard (), all .Site (), all . Org () ),
69
162
neg (all .OrgMem ()),
70
163
noise (ln , all .User ()),
71
164
),
@@ -78,16 +171,10 @@ func permissionVariants(all authztest.SetGroup) map[string]*authztest.Role {
78
171
noise (an , all .Wildcard (), all .Site (), all .Org ()),
79
172
neg (all .User ()),
80
173
),
174
+ // TODO: @Emyrk the abstain sets
81
175
}
82
176
}
83
177
84
- func l () {
85
- //authztest.Levels
86
- //noise(an, all.Wildcard()),
87
- // neg(all.Site()),
88
- // noise(ln, all.Org(), all.User()),
89
- }
90
-
91
178
// pos returns the positive impactful variant for a given level. It does not
92
179
// include noise at any other level but the one given.
93
180
func pos (lvl authztest.LevelGroup ) * authztest.Role {
@@ -108,10 +195,10 @@ func neg(lvl authztest.LevelGroup) *authztest.Role {
108
195
type noiseBits uint8
109
196
110
197
const (
111
- none noiseBits = 1 << iota
112
- positive
113
- negative
114
- abstain
198
+ _ noiseBits = 1 << iota
199
+ noisePositive
200
+ noiseNegative
201
+ noiseAbstain
115
202
)
116
203
117
204
func flagMatch (flag , in noiseBits ) bool {
@@ -128,13 +215,13 @@ func noise(f noiseBits, lvls ...authztest.LevelGroup) *authztest.Role {
128
215
for _ , lvl := range lvls {
129
216
sets := make ([]authztest.Iterable , 0 , bits .OnesCount8 (uint8 (f )))
130
217
131
- if flagMatch (positive , f ) {
218
+ if flagMatch (noisePositive , f ) {
132
219
sets = append (sets , authztest .Union (lvl .Positive ()[:1 ], nilSet ))
133
220
}
134
- if flagMatch (negative , f ) {
221
+ if flagMatch (noiseNegative , f ) {
135
222
sets = append (sets , authztest .Union (lvl .Negative ()[:1 ], nilSet ))
136
223
}
137
- if flagMatch (abstain , f ) {
224
+ if flagMatch (noiseAbstain , f ) {
138
225
sets = append (sets , authztest .Union (lvl .Abstain ()[:1 ], nilSet ))
139
226
}
140
227
0 commit comments