Search Apps Documentation Source Content File Folder Download Copy Actions Download

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}