Search Apps Documentation Source Content File Folder Download Copy Actions Download 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}