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.gno

2.12 Kb · 78 lines
 1package accesscontrol
 2
 3import "chain/runtime/unsafe"
 4
 5// AuthCheck must be owned by the calling realm/package.
 6// Do not pass callbacks received from untrusted callers.
 7type AuthCheck func(address) bool
 8
 9func AssertCurrentRealm(_ int, rlm realm) {
10	if !rlm.IsCurrent() {
11		panic("spoofed realm")
12	}
13}
14
15func AssertIsAdmin(_ int, rlm realm, isAdmin AuthCheck) {
16	MustGetAdminCaller(0, rlm, isAdmin)
17}
18
19func MustGetAdminCaller(_ int, rlm realm, isAdmin AuthCheck) address {
20	assertAuthCheck(isAdmin, "admin auth check is nil")
21	AssertCurrentRealm(0, rlm)
22
23	caller := rlm.Previous().Address()
24	if !isAdmin(caller) {
25		panic("admin access required")
26	}
27	return caller
28}
29
30func MustGetUserCaller(_ int, rlm realm) address {
31	AssertCurrentRealm(0, rlm)
32
33	prev := rlm.Previous()
34	if !prev.IsUserCall() {
35		panic("contract calls not allowed: function must be called directly by user")
36	}
37	return prev.Address()
38}
39
40// AssertIsAdminOrigin checks the transaction signer, not the direct caller realm.
41// Use it only for explicit delegation APIs that intentionally allow code-realm relays.
42func AssertIsAdminOrigin(isAdmin AuthCheck) {
43	MustGetAdminOrigin(isAdmin)
44}
45
46// MustGetAdminOrigin checks the transaction signer, not the direct caller realm.
47// Use it only for explicit delegation APIs that intentionally allow code-realm relays.
48func MustGetAdminOrigin(isAdmin AuthCheck) address {
49	assertAuthCheck(isAdmin, "admin auth check is nil")
50
51	caller := unsafe.OriginCaller()
52	if !isAdmin(caller) {
53		panic("admin access required")
54	}
55	return caller
56}
57
58func AssertIsAdminOrOperator(_ int, rlm realm, isAdmin AuthCheck, isOperator AuthCheck) {
59	MustGetAdminOrOperatorCaller(0, rlm, isAdmin, isOperator)
60}
61
62func MustGetAdminOrOperatorCaller(_ int, rlm realm, isAdmin AuthCheck, isOperator AuthCheck) address {
63	assertAuthCheck(isAdmin, "admin auth check is nil")
64	assertAuthCheck(isOperator, "operator auth check is nil")
65	AssertCurrentRealm(0, rlm)
66
67	caller := rlm.Previous().Address()
68	if !isAdmin(caller) && !isOperator(caller) {
69		panic("admin or operator access required")
70	}
71	return caller
72}
73
74func assertAuthCheck(check AuthCheck, msg string) {
75	if check == nil {
76		panic(msg)
77	}
78}