rbac.gno
4.16 Kb · 155 lines
1package rbac
2
3import (
4 "chain"
5
6 "gno.land/r/gnoswap/access/v1"
7
8 prbac "gno.land/p/gnoswap/rbac/v1"
9 ufmt "gno.land/p/nt/ufmt/v0"
10)
11
12var manager *prbac.RBAC
13
14func init(cur realm) {
15 initRbac(cur)
16}
17
18// initRbac initializes RBAC manager with default admin and role mappings.
19func initRbac(cur realm) {
20 manager = prbac.NewRBACWithAddress(ADMIN)
21
22 // Prepare initial roles for one-time initialization
23 for role, addr := range _defaultRoleAddresses {
24 roleName := role.String()
25 err := manager.RegisterRole(roleName, addr)
26 if err != nil {
27 panic(makeErrorWithDetails(
28 err.Error(),
29 ufmt.Sprintf("role name: %s, address: %s", roleName, addr.String()),
30 ))
31 }
32
33 // Update access package with the role address
34 access.SetRoleAddress(cross(cur), roleName, addr)
35 }
36}
37
38// RegisterRole registers a new role in the RBAC system.
39//
40// Parameters:
41// - cur: Current realm context; callers use cross(cur) when crossing into this realm.
42// - roleName: nonempty role name to register in the RBAC manager.
43// - roleAddress: address assigned to the new role and mirrored in access control.
44//
45// Only callable by admin or governance.
46func RegisterRole(cur realm, roleName string, roleAddress address) {
47 prev := cur.Previous()
48 caller := prev.Address()
49 assertIsAdminOrGovernance(caller)
50 assertIsValidRoleName(roleName)
51 assertIsValidAddress(roleAddress)
52
53 err := manager.RegisterRole(roleName, roleAddress)
54 if err != nil {
55 if err.Error() == "role already exists" {
56 panic(ufmt.Sprintf("role %s already exists", roleName))
57 }
58 panic(makeErrorWithDetails(
59 errInvalidRoleName,
60 ufmt.Sprintf("role name: %s", roleName),
61 ))
62 }
63
64 // Set the role in access control
65 access.SetRoleAddress(cross(cur), roleName, roleAddress)
66 chain.Emit(
67 "RegisterRole",
68 "prevAddr", caller.String(),
69 "prevRealm", prev.PkgPath(),
70 "roleName", roleName,
71 "roleAddress", roleAddress.String(),
72 )
73}
74
75// UpdateRoleAddress updates the address assigned to a role.
76//
77// Parameters:
78// - cur: Current realm context; callers use cross(cur) when crossing into this realm.
79// - roleName: existing non-admin role name whose address is changed.
80// - addr: valid replacement address assigned to the role and access-control mapping.
81//
82// Only callable by admin or governance.
83func UpdateRoleAddress(cur realm, roleName string, addr address) {
84 prev := cur.Previous()
85 caller := prev.Address()
86 assertIsAdminOrGovernance(caller)
87
88 assertIsValidRoleName(roleName)
89 assertIsValidAddress(addr)
90 assertNotAdminRole(roleName)
91
92 err := manager.UpdateRoleAddress(roleName, addr)
93 if err != nil {
94 panic(makeErrorWithDetails(
95 err.Error(),
96 ufmt.Sprintf("role name: %s, address: %s", roleName, addr.String()),
97 ))
98 }
99
100 // Set the role address in access control
101 access.SetRoleAddress(cross(cur), roleName, addr)
102
103 chain.Emit(
104 "UpdateRoleAddress",
105 "prevAddr", caller.String(),
106 "prevRealm", prev.PkgPath(),
107 "roleName", roleName,
108 "roleAddress", addr.String(),
109 )
110}
111
112// RemoveRole removes a role from the RBAC system.
113//
114// Parameters:
115// - cur: Current realm context; callers use cross(cur) when crossing into this realm.
116// - roleName: existing non-admin role name to remove from RBAC and access control.
117//
118// Only callable by admin or governance.
119func RemoveRole(cur realm, roleName string) {
120 prev := cur.Previous()
121 caller := prev.Address()
122 assertIsAdminOrGovernance(caller)
123 assertIsValidRoleName(roleName)
124 assertNotAdminRole(roleName)
125
126 err := manager.RemoveRole(roleName)
127 if err != nil {
128 panic(makeErrorWithDetails(
129 err.Error(),
130 ufmt.Sprintf("role name: %s", roleName),
131 ))
132 }
133
134 // Remove the role from access control
135 access.RemoveRole(cross(cur), roleName)
136 chain.Emit(
137 "RemoveRole",
138 "prevAddr", caller.String(),
139 "prevRealm", prev.PkgPath(),
140 "roleName", roleName,
141 "roleAddress", "",
142 )
143}
144
145// GetRoleAddress returns the address assigned to roleName.
146//
147// Parameters:
148// - roleName: exact role name to look up in the RBAC manager.
149//
150// Returns:
151// - roleAddress: address assigned to roleName, or the empty address when absent.
152// - error: nil when roleName exists; otherwise the manager's role-not-found error.
153func GetRoleAddress(roleName string) (address, error) {
154 return manager.GetRoleAddress(roleName)
155}