rbac.gno
3.42 Kb · 145 lines
1package rbac
2
3import (
4 "chain"
5
6 "gno.land/r/gnoswap/access"
7
8 prbac "gno.land/p/gnoswap/rbac"
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,
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// - roleName: name of the role to register
42// - roleAddress: address to assign to the role
43//
44// Only callable by admin or governance.
45func RegisterRole(cur realm, roleName string, roleAddress address) {
46 prev := cur.Previous()
47 caller := prev.Address()
48 assertIsAdminOrGovernance(caller)
49 assertIsValidRoleName(roleName)
50 assertIsValidAddress(roleAddress)
51
52 err := manager.RegisterRole(roleName, roleAddress)
53 if err != nil {
54 if err.Error() == "role already exists" {
55 panic(ufmt.Sprintf("role %s already exists", roleName))
56 }
57 panic(makeErrorWithDetails(
58 errInvalidRoleName,
59 ufmt.Sprintf("role name: %s", roleName),
60 ))
61 }
62
63 // Set the role in access control
64 access.SetRoleAddress(cross(cur), roleName, roleAddress)
65 chain.Emit(
66 "RegisterRole",
67 "prevAddr", caller.String(),
68 "prevRealm", prev.PkgPath(),
69 "roleName", roleName,
70 "roleAddress", roleAddress.String(),
71 )
72}
73
74// UpdateRoleAddress updates the address assigned to a role.
75//
76// Parameters:
77// - roleName: name of the role
78// - addr: new address for the role
79//
80// Only callable by admin or governance.
81func UpdateRoleAddress(cur realm, roleName string, addr address) {
82 prev := cur.Previous()
83 caller := prev.Address()
84 assertIsAdminOrGovernance(caller)
85
86 assertIsValidRoleName(roleName)
87 assertIsValidAddress(addr)
88 assertNotAdminRole(roleName)
89
90 err := manager.UpdateRoleAddress(roleName, addr)
91 if err != nil {
92 panic(makeErrorWithDetails(
93 err,
94 ufmt.Sprintf("role name: %s, address: %s", roleName, addr.String()),
95 ))
96 }
97
98 // Set the role address in access control
99 access.SetRoleAddress(cross(cur), roleName, addr)
100
101 chain.Emit(
102 "UpdateRoleAddress",
103 "prevAddr", caller.String(),
104 "prevRealm", prev.PkgPath(),
105 "roleName", roleName,
106 "roleAddress", addr.String(),
107 )
108}
109
110// RemoveRole removes a role from the RBAC system.
111//
112// Parameters:
113// - roleName: name of the role to remove
114//
115// Only callable by admin or governance.
116func RemoveRole(cur realm, roleName string) {
117 prev := cur.Previous()
118 caller := prev.Address()
119 assertIsAdminOrGovernance(caller)
120 assertIsValidRoleName(roleName)
121 assertNotAdminRole(roleName)
122
123 err := manager.RemoveRole(roleName)
124 if err != nil {
125 panic(makeErrorWithDetails(
126 err,
127 ufmt.Sprintf("role name: %s", roleName),
128 ))
129 }
130
131 // Remove the role from access control
132 access.RemoveRole(cross(cur), roleName)
133 chain.Emit(
134 "RemoveRole",
135 "prevAddr", caller.String(),
136 "prevRealm", prev.PkgPath(),
137 "roleName", roleName,
138 "roleAddress", "",
139 )
140}
141
142// GetRoleAddress returns the address assigned to roleName.
143func GetRoleAddress(roleName string) (address, error) {
144 return manager.GetRoleAddress(roleName)
145}