Skip to content Search Apps Documentation Source Content File Folder Download Copy Actions State String Boolean Number Struct Map Slice Pointer Function Closure Reference Nil Package Type Interface Unknown

Community realm. Read the code first. Community realm, deployed by its author. Read the code before you interact or send coins.

access_control_test.gno

6.59 Kb · 267 lines
  1package accesscontrol
  2
  3import (
  4	"testing"
  5
  6	"gno.land/p/nt/testutils/v0"
  7	"gno.land/p/nt/uassert/v0"
  8)
  9
 10var (
 11	testAdmin    = testutils.TestAddress("acAdmin")
 12	testOperator = testutils.TestAddress("acOperator")
 13	testUser     = testutils.TestAddress("acUser")
 14	testOther    = testutils.TestAddress("acOther")
 15)
 16
 17func testIsAdmin(addr address) bool {
 18	return addr == testAdmin
 19}
 20
 21func testIsOperator(addr address) bool {
 22	return addr == testOperator
 23}
 24
 25func probeMustGetAdminCaller(cur realm, isAdmin AuthCheck) address {
 26	return MustGetAdminCaller(0, cur, isAdmin)
 27}
 28
 29func probeAssertIsAdmin(cur realm, isAdmin AuthCheck) address {
 30	AssertIsAdmin(0, cur, isAdmin)
 31	return ""
 32}
 33
 34func probeMustGetUserCaller(cur realm) address {
 35	return MustGetUserCaller(0, cur)
 36}
 37
 38func probeMustGetAdminOrOperatorCaller(cur realm, isAdmin AuthCheck, isOperator AuthCheck) address {
 39	return MustGetAdminOrOperatorCaller(0, cur, isAdmin, isOperator)
 40}
 41
 42func probeAssertIsAdminOrOperator(cur realm, isAdmin AuthCheck, isOperator AuthCheck) address {
 43	AssertIsAdminOrOperator(0, cur, isAdmin, isOperator)
 44	return ""
 45}
 46
 47func TestAccessControl(cur realm, t *testing.T) {
 48	tests := []struct {
 49		label      string
 50		setup      func(realm) realm
 51		call       func(realm, realm) address
 52		panicKind  string
 53		panicMsg   string
 54		wantCaller address
 55	}{
 56		{
 57			label: "current realm",
 58			setup: func(cur realm) realm {
 59				return cur
 60			},
 61			call: func(cur realm, rlm realm) address {
 62				AssertCurrentRealm(0, rlm)
 63				return ""
 64			},
 65		},
 66		{
 67			label: "stale realm",
 68			setup: func(cur realm) realm {
 69				testing.SetRealm(testing.NewCodeRealm("gno.land/r/akkadia/beta/accesscontrol_stale_probe"))
 70				return cur.Previous()
 71			},
 72			call: func(cur realm, rlm realm) address {
 73				AssertCurrentRealm(0, rlm)
 74				return ""
 75			},
 76			panicKind: "panic",
 77			panicMsg:  "spoofed realm",
 78		},
 79		{
 80			label: "admin caller",
 81			setup: func(cur realm) realm {
 82				testing.SetRealm(testing.NewUserRealm(testAdmin))
 83				return nil
 84			},
 85			call: func(cur realm, rlm realm) address {
 86				return probeMustGetAdminCaller(cross(cur), testIsAdmin)
 87			},
 88			wantCaller: testAdmin,
 89		},
 90		{
 91			label: "assert admin caller",
 92			setup: func(cur realm) realm {
 93				testing.SetRealm(testing.NewUserRealm(testAdmin))
 94				return nil
 95			},
 96			call: func(cur realm, rlm realm) address {
 97				return probeAssertIsAdmin(cross(cur), testIsAdmin)
 98			},
 99		},
100		{
101			label: "unauthorized admin caller",
102			setup: func(cur realm) realm {
103				testing.SetRealm(testing.NewUserRealm(testOther))
104				return nil
105			},
106			call: func(cur realm, rlm realm) address {
107				return probeMustGetAdminCaller(cross(cur), testIsAdmin)
108			},
109			panicKind: "abort",
110			panicMsg:  "admin access required",
111		},
112		{
113			label: "direct user caller",
114			setup: func(cur realm) realm {
115				testing.SetRealm(testing.NewUserRealm(testUser))
116				return nil
117			},
118			call: func(cur realm, rlm realm) address {
119				return probeMustGetUserCaller(cross(cur))
120			},
121			wantCaller: testUser,
122		},
123		{
124			label: "code realm rejected as user caller",
125			setup: func(cur realm) realm {
126				testing.SetRealm(testing.NewCodeRealm("gno.land/r/akkadia/beta/accesscontrol_relay"))
127				return nil
128			},
129			call: func(cur realm, rlm realm) address {
130				return probeMustGetUserCaller(cross(cur))
131			},
132			panicKind: "abort",
133			panicMsg:  "contract calls not allowed: function must be called directly by user",
134		},
135		{
136			label: "admin caller for admin or operator",
137			setup: func(cur realm) realm {
138				testing.SetRealm(testing.NewUserRealm(testAdmin))
139				return nil
140			},
141			call: func(cur realm, rlm realm) address {
142				return probeMustGetAdminOrOperatorCaller(cross(cur), testIsAdmin, testIsOperator)
143			},
144			wantCaller: testAdmin,
145		},
146		{
147			label: "operator caller for admin or operator",
148			setup: func(cur realm) realm {
149				testing.SetRealm(testing.NewUserRealm(testOperator))
150				return nil
151			},
152			call: func(cur realm, rlm realm) address {
153				return probeMustGetAdminOrOperatorCaller(cross(cur), testIsAdmin, testIsOperator)
154			},
155			wantCaller: testOperator,
156		},
157		{
158			label: "assert admin or operator",
159			setup: func(cur realm) realm {
160				testing.SetRealm(testing.NewUserRealm(testOperator))
161				return nil
162			},
163			call: func(cur realm, rlm realm) address {
164				return probeAssertIsAdminOrOperator(cross(cur), testIsAdmin, testIsOperator)
165			},
166		},
167		{
168			label: "unauthorized admin or operator caller",
169			setup: func(cur realm) realm {
170				testing.SetRealm(testing.NewUserRealm(testOther))
171				return nil
172			},
173			call: func(cur realm, rlm realm) address {
174				return probeMustGetAdminOrOperatorCaller(cross(cur), testIsAdmin, testIsOperator)
175			},
176			panicKind: "abort",
177			panicMsg:  "admin or operator access required",
178		},
179		{
180			label: "admin origin",
181			setup: func(cur realm) realm {
182				testing.SetOriginCaller(testAdmin)
183				return nil
184			},
185			call: func(cur realm, rlm realm) address {
186				return MustGetAdminOrigin(testIsAdmin)
187			},
188			wantCaller: testAdmin,
189		},
190		{
191			label: "assert admin origin",
192			setup: func(cur realm) realm {
193				testing.SetOriginCaller(testAdmin)
194				return nil
195			},
196			call: func(cur realm, rlm realm) address {
197				AssertIsAdminOrigin(testIsAdmin)
198				return ""
199			},
200		},
201		{
202			label: "unauthorized admin origin",
203			setup: func(cur realm) realm {
204				testing.SetOriginCaller(testOther)
205				return nil
206			},
207			call: func(cur realm, rlm realm) address {
208				return MustGetAdminOrigin(testIsAdmin)
209			},
210			panicKind: "panic",
211			panicMsg:  "admin access required",
212		},
213		{
214			label: "nil admin check",
215			setup: func(cur realm) realm {
216				return cur
217			},
218			call: func(cur realm, rlm realm) address {
219				return MustGetAdminCaller(0, rlm, nil)
220			},
221			panicKind: "panic",
222			panicMsg:  "admin auth check is nil",
223		},
224		{
225			label: "nil origin admin check",
226			setup: func(cur realm) realm {
227				return nil
228			},
229			call: func(cur realm, rlm realm) address {
230				return MustGetAdminOrigin(nil)
231			},
232			panicKind: "panic",
233			panicMsg:  "admin auth check is nil",
234		},
235		{
236			label: "nil operator check",
237			setup: func(cur realm) realm {
238				return cur
239			},
240			call: func(cur realm, rlm realm) address {
241				return MustGetAdminOrOperatorCaller(0, rlm, testIsAdmin, nil)
242			},
243			panicKind: "panic",
244			panicMsg:  "operator auth check is nil",
245		},
246	}
247
248	for _, tt := range tests {
249		rlm := tt.setup(cur)
250		call := func() {
251			got := tt.call(cur, rlm)
252			if tt.wantCaller != "" {
253				uassert.Equal(t, tt.wantCaller.String(), got.String())
254			}
255		}
256
257		if tt.panicKind == "panic" {
258			uassert.PanicsWithMessage(t, cur, tt.panicMsg, call)
259			continue
260		}
261		if tt.panicKind == "abort" {
262			uassert.AbortsWithMessage(t, cur, tt.panicMsg, call)
263			continue
264		}
265		call()
266	}
267}