Search Apps Documentation Source Content File Folder Download Copy Actions Download

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}