rbac.gno
3.46 Kb ยท 146 lines
1package rbac
2
3import (
4 "chain"
5 "chain/runtime"
6
7 "gno.land/r/gnoswap/access"
8
9 prbac "gno.land/p/gnoswap/rbac"
10 "gno.land/p/nt/ufmt"
11)
12
13var manager *prbac.RBAC
14
15func init() {
16 initRbac()
17}
18
19// initRbac initializes RBAC manager with default admin and role mappings.
20func initRbac() {
21 manager = prbac.NewRBACWithAddress(ADMIN)
22
23 // Prepare initial roles for one-time initialization
24 for role, addr := range DefaultRoleAddresses {
25 roleName := role.String()
26 err := manager.RegisterRole(roleName, addr)
27 if err != nil {
28 panic(makeErrorWithDetails(
29 err,
30 ufmt.Sprintf("role name: %s, address: %s", roleName, addr.String()),
31 ))
32 }
33
34 // Update access package with the role address
35 access.SetRoleAddress(cross, roleName, addr)
36 }
37}
38
39// RegisterRole registers a new role in the RBAC system.
40//
41// Parameters:
42// - roleName: name of the role to register
43// - roleAddress: address to assign to the role
44//
45// Only callable by admin or governance.
46func RegisterRole(cur realm, roleName string, roleAddress address) {
47 prevRealm := runtime.PreviousRealm()
48 caller := prevRealm.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, roleName, roleAddress)
66 chain.Emit(
67 "RegisterRole",
68 "prevAddr", caller.String(),
69 "prevRealm", prevRealm.PkgPath(),
70 "roleName", roleName,
71 "roleAddress", roleAddress.String(),
72 )
73}
74
75// UpdateRoleAddress updates the address assigned to a role.
76//
77// Parameters:
78// - roleName: name of the role
79// - addr: new address for the role
80//
81// Only callable by admin or governance.
82func UpdateRoleAddress(cur realm, roleName string, addr address) {
83 prevRealm := runtime.PreviousRealm()
84 caller := prevRealm.Address()
85 assertIsAdminOrGovernance(caller)
86
87 assertIsValidRoleName(roleName)
88 assertIsValidAddress(addr)
89 assertNotAdminRole(roleName)
90
91 err := manager.UpdateRoleAddress(roleName, addr)
92 if err != nil {
93 panic(makeErrorWithDetails(
94 err,
95 ufmt.Sprintf("role name: %s, address: %s", roleName, addr.String()),
96 ))
97 }
98
99 // Set the role address in access control
100 access.SetRoleAddress(cross, roleName, addr)
101
102 chain.Emit(
103 "UpdateRoleAddress",
104 "prevAddr", caller.String(),
105 "prevRealm", prevRealm.PkgPath(),
106 "roleName", roleName,
107 "roleAddress", addr.String(),
108 )
109}
110
111// RemoveRole removes a role from the RBAC system.
112//
113// Parameters:
114// - roleName: name of the role to remove
115//
116// Only callable by admin or governance.
117func RemoveRole(cur realm, roleName string) {
118 prevRealm := runtime.PreviousRealm()
119 caller := prevRealm.Address()
120 assertIsAdminOrGovernance(caller)
121 assertIsValidRoleName(roleName)
122 assertNotAdminRole(roleName)
123
124 err := manager.RemoveRole(roleName)
125 if err != nil {
126 panic(makeErrorWithDetails(
127 err,
128 ufmt.Sprintf("role name: %s", roleName),
129 ))
130 }
131
132 // Remove the role from access control
133 access.RemoveRole(cross, roleName)
134 chain.Emit(
135 "RemoveRole",
136 "prevAddr", caller.String(),
137 "prevRealm", prevRealm.PkgPath(),
138 "roleName", roleName,
139 "roleAddress", "",
140 )
141}
142
143// GetRoleAddress returns the address assigned to roleName.
144func GetRoleAddress(roleName string) (address, error) {
145 return manager.GetRoleAddress(roleName)
146}