Package rbac provides a simple address-based Role-Based Access Control (RBAC) system for Gno smart contracts. It enables dynamic registration, update, and removal of roles with assigned addresses.
## Overview
The RBAC package provides a manager that maintains an internal registry of roles. Each role is identified by a unique name and is associated with a single address. Authorization is performed by checking if a given address matches the role's assigned address.
Key components of this package include:
- **Role**: Represents a role with a name and an assigned address.
- **RBAC Manager**: The core type (RBAC) that manages role registration, address assignment, authorization verification, and role removal.
- **Ownable2Step**: Provides two-step ownership transfer functionality integrated into the RBAC manager.
## Key Features
- **Dynamic Role Management**: Roles can be registered, updated, and removed at runtime without requiring contract redeployment.
- **Address-Based Authorization**: Each role is associated with a single address, and authorization is verified by address matching.
- **System Roles**: Predefined system roles (admin, devops, pool, etc.) that cannot be removed to ensure system integrity.
- **Two-Step Ownership Transfer**: Built-in secure ownership transfer mechanism requiring explicit acceptance by the new owner.
- **Encapsulation**: Internal state (roles registry) is encapsulated within the RBAC manager, preventing unintended external modifications.
## Workflow
Typical usage of the RBAC package includes the following steps:
- **Initialization**: Create a new RBAC manager using `New()` or `NewRBACWithAddress(addr)`.
- **Role Registration**: Register roles using `RegisterRole(roleName, address)`.
- **Authorization Check**: Verify if an address is authorized for a role using `IsAuthorized(roleName, address)`.
- **Role Management**: Update role addresses with `UpdateRoleAddress` or remove non-system roles with `RemoveRole`.
## Example Usage
The following example demonstrates how to use the RBAC package:
```gno package main
import (
Example
1"gno.land/p/gnoswap/rbac"
)
Example
1func main() {
2 // Create a new RBAC manager (origin caller becomes owner)
3 manager := rbac.New()
4
5 // Define example addresses
6 adminAddr := address("g1...")
7 userAddr := address("g1...")
8
9 // Register an "admin" role with adminAddr
10 if err := manager.RegisterRole("admin", adminAddr); err != nil {
11 panic(err)
12 }
13
14 // Register a custom "editor" role with userAddr
15 if err := manager.RegisterRole("editor", userAddr); err != nil {
16 panic(err)
17 }
18
19 // Check if adminAddr is authorized for the "admin" role
20 if manager.IsAuthorized("admin", adminAddr) {
21 println("Admin access granted")
22 }
23
24 // Check if userAddr is authorized for the "admin" role
25 if !manager.IsAuthorized("admin", userAddr) {
26 println("User does not have admin access")
27 }
28
29 // Update the editor role to a different address
30 newEditorAddr := address("g1...")
31 if err := manager.UpdateRoleAddress("editor", newEditorAddr); err != nil {
32 panic(err)
33 }
34
35 // Get all role addresses
36 allRoles := manager.GetAllRoleAddresses()
37 for roleName, addr := range allRoles {
38 println(roleName, "->", addr.String())
39 }
40}
```
## System Roles
The package defines several system roles that cannot be removed:
- admin: System administrator role
- devops: DevOps operations role
- community_pool: Community pool management role
- governance: Governance system role
- gov_staker: Governance staker role
- xgns: xGNS token role
- pool: Pool management role
- position: Position management role
- router: Router role
- staker: Staker role
- emission: Emission management role
- launchpad: Launchpad role
- protocol_fee: Protocol fee management role
## Error Handling
The package defines several error types:
- ErrRoleAlreadyExists: Attempting to register a role that already exists. - ErrRoleDoesNotExist: Attempting to access or modify a non-existent role. - ErrCannotRemoveSystemRole: Attempting to remove a system role. - ErrInvalidAddress: Providing an invalid or empty address. - ErrUnauthorized: Caller is not the owner when owner permission is required. - ErrNoPendingOwner: Attempting to accept ownership when no transfer is pending. - ErrPendingUnauthorized: Caller is not the pending owner when accepting ownership.
## Ownership Management
The RBAC manager includes built-in two-step ownership transfer functionality:
- Current owner calls TransferOwnershipBy to initiate transfer.
- New owner calls AcceptOwnershipBy to complete the transfer.
- Owner can drop ownership entirely using DropOwnershipBy.
## Limitations and Considerations
- Each role can only have one assigned address. For multi-address authorization, consider creating multiple roles or implementing a wrapper.
- System roles are protected and cannot be removed to ensure system stability.
- Address validation checks for empty strings and calls IsValid() method.
Package rbac is intended for use in Gno smart contracts requiring simple, address-based access control with role management capabilities.