Skip to content Search Apps Documentation Source Content File Folder Download Copy Actions State String Boolean Number Struct Map Slice Pointer Function Closure Reference Nil Package Type Interface Unknown

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}