rbac: github.com/euroteltr/rbac Index | Files

package rbac

import "github.com/euroteltr/rbac"

Package rbac is role based access control library. At core uses `sync.Map` so, it can be used from multiple goroutines concurrently.package rbac

rbac is dependend on these terms:

- Action	Defines what can possible for a permission
- Permission	Defines permission related to a resource to be accessed
- Role	Defines group of permissions with defined actions

Usage:

Library usage has 2 phases:

- Development
- Runtime

Development Phase

First get an instance for `RBAC`

import "github.com/euroteltr/rbac"

R := rbac.New(nil)
// you can pass a logger to constructor also:
// R := rbac.New(rbac.ConsoleLogger)

During development you will register your permissions for your each resource with valid actions for that permission:

// You can also use rbac.CRUD for those crud actions
usersPerm, err := R.RegisterPermission("users", "User resource", rbac.Create, rbac.Read, rbac.Update, rbac.Delete)
if err != nil {
	panic(err)
}

`userPerm` is defined with CRUD actions, which means that any action not in that list will be invalid. You can define your own actions( like `ApproveAction := rbac.Action("approve")`) and add them also.

Runtime Phase:

At run time we define our roles and permit permissions to them.

adminRole, err := R.RegisterRole("admin", "Admin role")
if err != nil {
	fmt.Printf("can not add admin role, err: %v\n", err)
}
if err = R.Permit(adminRole.ID, usersPerm, rbac.CRUD, ApproveAction); err != nil {
	fmt.Errorf("can not permit crud and ApproveAction actions to role %s\n", adminRole.ID)
}

Now we can check if a role is granted some permission:

if !R.IsGranted(adminRole.ID, usersPerm, rbac.Write) {
	fmt.Printf("admin role does not have write grant on users\n")
}else{
	fmt.Printf("admin role does have write grant on users\n")
}

// You can also check by perm.ID also
if !R.IsGrantedStr("admin", "users", rbac.CRUD) {
	fmt.Printf("admin role does not have CRUD grants on users\n")
}else{
	fmt.Printf("admin role does have CRUD grants on users\n")
}

Persisting and Loading

`rbac.RBAC` is `json` compatible. You can dump all data in `RBAC` instance to JSON:

b, err := json.Marshal(R)
if err != nil {
	fmt.Printf("rback marshall failed with %v\n", err)
}else{
	fmt.Printf("RBAC: %s", b)
}

Also you can use builtin SaveJSON function to save to a io.Writer:

filename := "/tmp/rbac.json"
f, err := os.OpenFile(filename, os.O_CREATE|os.O_WRONLY, 0644)
if err != nil {
	fmt.Printf("can not load json file %s, err: %v\n", filename, err)
	return err
}
defer f.Close()
if err = R.SaveJSON(f); err != nil {
	fmt.Printf("unable to save to json file, err:%v\n", err)
}

And load it from file:

filename := "/tmp/rbac.json"
f, err := os.Open(filename)
if err != nil {
	return err
}
defer f.Close()
if err = R.LoadJSON(f); err != nil {
	fmt.Errorf("unable to load from json file, err:%v\n", err)
}

In dumped JSON root "permissions" part is for reference. Root `roles` is the part you can modify in file and reload it to define `Role`s with `Permission`s.

{
"permissions": [
	{
	"id": "users",
	"description": "User resource",
	"actions": [
		"create",
		"read",
		"update",
		"delete"
	]
	}
],
"roles": [
	{
	"id": "admin",
	"description": "Admin role",
	"grants": {
		"users": [
		"create",
		"read",
		"update",
		"delete"
		]
	},
	"parents": []
	}
]
}

Role inheritance

A `Role` can have parent `Role`s. You can add a parent `Role` like this:

// Add a new role
sysAdmRole, err := R.RegisterRole("sysadm", "System admin role")
if err != nil {
	fmt.Printf("can not add agent role, err: %v\n", err)
}

// Now add adminRole as parent
if err = sysAdmRole.AddParent(adminRole); err != nil {
	fmt.Printf("adding parent role failed with: %v\n", err)
}

// Now all permissions in adminRole will be also valid for sysAdmRole
if R.IsGranted(sysAdmRole.ID, usersPerm, rbac.CRUD) {
	fmt.Printf("sysadmin role has all crud actions granted\n")
}

If circular parent reference is found, you'll get error while running `AddParent`.

Index

Package Files

action.go doc.go logger.go permission.go rbac.go role.go

func SetLogger Uses

func SetLogger(logger Logger)

SetLogger sets rbac logger

type Action Uses

type Action string

Action is permission action

const (
    // None is for empty action
    None Action = ""
    // Create is for create action
    Create Action = "create"
    // Read is for read action
    Read Action = "read"
    // Update is for  update action
    Update Action = "update"
    // Delete is for delete action
    Delete Action = "delete"
    // CRUD is for, create+read+update+delete permissions
    CRUD Action = "crud"
    // Download is for downloading action
    Download = "download"
    // Upload is for uploading action
    Upload = "upload"
)

type ConsoleLogger Uses

type ConsoleLogger struct {
}

ConsoleLogger is console logger

func (*ConsoleLogger) Debugf Uses

func (nl *ConsoleLogger) Debugf(format string, args ...interface{})

Debugf is for debug logging

func (*ConsoleLogger) Errorf Uses

func (nl *ConsoleLogger) Errorf(format string, args ...interface{})

Errorf is for error logging

type Logger Uses

type Logger interface {
    Debugf(format string, args ...interface{})
    Errorf(format string, args ...interface{})
}

Logger is interface for logger to be used in RBAC

func NewConsoleLogger Uses

func NewConsoleLogger() Logger

NewConsoleLogger returns a new ConsoleLogger

func NewNullLogger Uses

func NewNullLogger() Logger

NewNullLogger returns a new NullLogger

type NullLogger Uses

type NullLogger struct {
}

NullLogger is null logger

func (*NullLogger) Debugf Uses

func (nl *NullLogger) Debugf(format string, args ...interface{})

Debugf is for debug logging

func (*NullLogger) Errorf Uses

func (nl *NullLogger) Errorf(format string, args ...interface{})

Errorf is for error logging

type Permission Uses

type Permission struct {
    ID          string
    Description string
    sync.Map    // key action, val nil
}

Permission defines rbac permission

func (*Permission) Actions Uses

func (p *Permission) Actions() []Action

Actions returns list of Actions

func (*Permission) MarshalJSON Uses

func (p *Permission) MarshalJSON() ([]byte, error)

MarshalJSON serializes a Permission to JSON

func (*Permission) String Uses

func (p *Permission) String() string

String returns as string

type RBAC Uses

type RBAC struct {
    sync.Map // key: role.ID, value: role
    // contains filtered or unexported fields
}

RBAC is role bases access control manager

func New Uses

func New(logger Logger) *RBAC

New returns a new RBAC instance

func (*RBAC) AllGrantInherited Uses

func (r *RBAC) AllGrantInherited(roleIDs []string, perm *Permission, action ...Action) bool

AllGrantInherited checks if all roles have the permission.

func (*RBAC) AllGrantInheritedStr Uses

func (r *RBAC) AllGrantInheritedStr(roleIDs []string, permName string, action ...Action) bool

AllGrantedStr checks if all roles have the permission.

func (*RBAC) AllGranted Uses

func (r *RBAC) AllGranted(roleIDs []string, perm *Permission, action ...Action) (res bool)

AllGranted checks if all roles have the permission.

func (*RBAC) AllGrantedStr Uses

func (r *RBAC) AllGrantedStr(roleIDs []string, permName string, action ...Action) (res bool)

AllGrantedStr checks if all roles have the permission.

func (*RBAC) AnyGrantInherited Uses

func (r *RBAC) AnyGrantInherited(roleIDs []string, perm *Permission, action ...Action) (res bool)

AnyGrantInherited checks if any role has the permission.

func (*RBAC) AnyGrantInheritedStr Uses

func (r *RBAC) AnyGrantInheritedStr(roleIDs []string, permName string, action ...Action) (res bool)

AnyGrantInheritedStr checks if any role has the permission.

func (*RBAC) AnyGranted Uses

func (r *RBAC) AnyGranted(roleIDs []string, perm *Permission, action ...Action) (res bool)

AnyGranted checks if any role has the permission.

func (*RBAC) AnyGrantedStr Uses

func (r *RBAC) AnyGrantedStr(roleIDs []string, permName string, action ...Action) (res bool)

AnyGrantedStr checks if any role has the permission.

func (*RBAC) Clone Uses

func (r *RBAC) Clone(roles bool) (trg *RBAC)

Clone clones RBAC instance

func (*RBAC) GetAllPermissions Uses

func (r *RBAC) GetAllPermissions(roleIDs []string) map[string][]Action

GetAllPermissions returns granted permissions for a role(including inherited permissions from parents)

func (*RBAC) GetPermission Uses

func (r *RBAC) GetPermission(permissionID string) *Permission

GetPermission returns the permission if exists. perm is nil if not found.

func (*RBAC) GetRole Uses

func (r *RBAC) GetRole(roleID string) *Role

GetRole finds and returns role from instance, if role is not found returns nil

func (*RBAC) IsGrantInherited Uses

func (r *RBAC) IsGrantInherited(roleID string, perm *Permission, actions ...Action) bool

IsGranted checks if a role with target permission and actions has a grant

func (*RBAC) IsGrantInheritedStr Uses

func (r *RBAC) IsGrantInheritedStr(roleID string, permID string, actions ...Action) bool

IsGrantInheritedStr checks if permID is granted with target actions for role

func (*RBAC) IsGranted Uses

func (r *RBAC) IsGranted(roleID string, perm *Permission, actions ...Action) bool

IsGranted checks if a role with target permission and actions has a grant

func (*RBAC) IsGrantedStr Uses

func (r *RBAC) IsGrantedStr(roleID string, permID string, actions ...Action) bool

IsGrantedStr checks if permID is greanted with target actions for role

func (*RBAC) IsPermissionExist Uses

func (r *RBAC) IsPermissionExist(permissionID string, action Action) (res bool)

IsPermissionExist checks if a permission with target ID and action is defined

func (*RBAC) IsRoleExist Uses

func (r *RBAC) IsRoleExist(roleID string) (res bool)

IsRoleExist checks if a role with target ID is defined

func (*RBAC) LoadJSON Uses

func (r *RBAC) LoadJSON(reader io.Reader) error

LoadJSON loads all data from a reader

func (*RBAC) MarshalJSON Uses

func (r *RBAC) MarshalJSON() ([]byte, error)

MarshalJSON serializes a all roles to JSON

func (*RBAC) Permissions Uses

func (r *RBAC) Permissions() []*Permission

Permissions returns all Permissions

func (*RBAC) Permit Uses

func (r *RBAC) Permit(roleID string, perm *Permission, actions ...Action) error

Permit grants a permission with defined actions to a role

func (*RBAC) RegisterPermission Uses

func (r *RBAC) RegisterPermission(permissionID, description string, actions ...Action) (*Permission, error)

RegisterPermission defines and registers a permission

func (*RBAC) RegisterRole Uses

func (r *RBAC) RegisterRole(roleID string, description string) (*Role, error)

RegisterRole defines and registers a role

func (*RBAC) RemoveRole Uses

func (r *RBAC) RemoveRole(roleID string) error

RemoveRole deletes role from instance

func (*RBAC) Revoke Uses

func (r *RBAC) Revoke(roleID string, perm *Permission, actions ...Action) error

Revoke removes a permission from a role

func (*RBAC) RoleGrants Uses

func (r *RBAC) RoleGrants() []*RoleGrants

RoleGrants returns all roles

func (*RBAC) Roles Uses

func (r *RBAC) Roles() (res []*Role)

Roles reuturns all registered roles

func (*RBAC) SaveJSON Uses

func (r *RBAC) SaveJSON(writer io.Writer) (err error)

SaveJSON saves all to a writer

func (*RBAC) UnmarshalJSON Uses

func (r *RBAC) UnmarshalJSON(b []byte) (err error)

UnmarshalJSON parses RBAC from JSON

type Role Uses

type Role struct {
    ID          string     `json:"id"`
    Description string     `json:"description"`
    sync.Map    `json:"-"` // key: permissionID, values sync.Map[action]=true/false
    // contains filtered or unexported fields
}

Role defines a role

func (*Role) AddParent Uses

func (r *Role) AddParent(parentRole *Role) error

AddParent Adds parent role

func (*Role) HasAncestor Uses

func (r *Role) HasAncestor(parentID string) bool

HasAncestor checks if a role is in parent roles

func (*Role) HasParent Uses

func (r *Role) HasParent(parentID string) bool

HasParent checks if a role is in parent roles

func (*Role) ParentIDs Uses

func (r *Role) ParentIDs() []string

ParentIDs return a list of parent role IDs

func (*Role) Parents Uses

func (r *Role) Parents() []*Role

Parents returns list of parent roles

func (*Role) RemoveParent Uses

func (r *Role) RemoveParent(parentRole *Role) error

RemoveParent removes parent role

type RoleGrants Uses

type RoleGrants struct {
    ID          string    `json:"id"`
    Description string    `json:"description"`
    Grants      grantsMap `json:"grants"`
    Parents     []string  `json:"parents"`
}

RoleGrants is used during JSON Marshalling

Package rbac imports 4 packages (graph). Updated 2019-04-16. Refresh now. Tools for package owners.