Help us shape the future of Go! Take the 2026 Go Developer Survey

gorbac

package module
v0.0.4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 6, 2019 License: MIT Imports: 4 Imported by: 0

README

RBAC

Build Status Maintainability Test Coverage codecov Go Report Card

Role-Based Access Control

Thus, RBAC has the following model:

  • many to many relationship between identities and roles.
  • many to many relationship between roles and permissions.
  • roles can have a parent role (inheriting permissions).

Install

go get -u github.com/efureev/go.rbac

Usage

Although you can adjust the RBAC instance anytime and it's absolutely safe, the library is designed for use with two phases:

  • Preparing
  • Checking
Preparing

Import the library:

import "github.com/efureev/go.rbac"

Get a new instance of RBAC:

rbac := gorbac.New()

Get some new roles:

rA := gorbac.NewRole("role-a")
rB := gorbac.NewRole("role-b")
rC := gorbac.NewRole("role-c")
rD := gorbac.NewRole("role-d")
rE := gorbac.NewRole("role-e")

Get some new permissions:

pA := gorbac.NewPermission("permission-a")
pB := gorbac.NewPermission("permission-b")
pC := gorbac.NewPermission("permission-c")
pD := gorbac.NewPermission("permission-d")
pE := gorbac.NewPermission("permission-e")

Add the permissions to roles:

rA.Assign(pA)
rB.Assign(pB)
rC.Assign(pC)
rD.Assign(pD)
rE.Assign(pE)

Also, you can implement gorbac.Role and gorbac.Permission for your own data structure.

After initialization, add the roles to the RBAC instance:

rbac.Add(rA)
rbac.Add(rB)
rbac.Add(rC)
rbac.Add(rD)
rbac.Add(rE)

And set the inheritance:

rbac.SetParent("role-a", "role-b")
rbac.SetParents("role-b", []string{"role-c", "role-d"})
rbac.SetParent("role-e", "role-d")
Checking

Checking the permission is easy:

if rbac.IsGranted("role-a", pA, nil) &&
	rbac.IsGranted("role-a", pB, nil) &&
	rbac.IsGranted("role-a", pC, nil) &&
	rbac.IsGranted("role-a", pD, nil) {
	fmt.Println("The role-a has been granted permis-a, b, c and d.")
}

And there are some built-in util-functions: InheritanceCircle, AnyGranted, AllGranted. Please open an issue for the new built-in requirement.

E.g.:

rbac.SetParent("role-c", "role-a")
if err := gorbac.InheritanceCircle(rbac); err != nil {
	fmt.Println("A circle inheratance occurred.")
}

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrRoleNotExist occurred if a role cann't be found
	ErrRoleNotExist = errors.New("role does not exist")
	// ErrRoleExist occurred if a role shouldn't be found
	ErrRoleExist = errors.New("role has already existed")
)
View Source
var (
	// ErrFoundCircle throw error about looping into roles
	ErrFoundCircle = fmt.Errorf(`found circle`)
)

Functions

func AllGranted

func AllGranted(rbac *RBAC, roles []string, permission Permission, assert AssertionFunc) (res bool)

AllGranted checks if all roles have the permission.

func AnyGranted

func AnyGranted(rbac *RBAC, roles []string, permission Permission, assert AssertionFunc) (res bool)

AnyGranted checks if any role has the permission.

func InheritanceCircle

func InheritanceCircle(rbac *RBAC) (err error)

InheritanceCircle returns an error when detecting any circle inheritance.

func Walk

func Walk(rbac *RBAC, h WalkHandler) (err error)

Walk passes each Role to WalkHandler

Types

type AssertionFunc

type AssertionFunc func(*RBAC, string, Permission) bool

AssertionFunc supplies more fine-grained permission controls.

type DeepPermission

type DeepPermission struct {
	IDStr string `json:"id"`
	Sep   string `json:"sep"`
}

DeepPermission firstly checks the Id of permission. If the Id is matched, it can be considered having the permission. Otherwise, it checks every layers of permission. A role which has an upper layer granted, will be granted sub-layers permissions.

func (*DeepPermission) ID

func (p *DeepPermission) ID() string

ID returns the identity of permission

func (*DeepPermission) Match

func (p *DeepPermission) Match(a Permission) bool

Match another permission

type Permission

type Permission interface {
	ID() string
	Match(Permission) bool
}

Permission exports `Id` and `Match`

func NewDeepPermission

func NewDeepPermission(id string) Permission

NewDeepPermission returns an instance of layered permission with `id`

func NewPermission

func NewPermission(id string) Permission

NewPermission returns a Permission instance with `id`

type Permissions

type Permissions map[string]Permission

Permissions is a map

type RBAC

type RBAC struct {
	// contains filtered or unexported fields
}

RBAC object, in most cases it should be used as a singleton.

func New

func New() *RBAC

New returns a RBAC structure. The default role structure will be used.

func (*RBAC) Add

func (rbac *RBAC) Add(r Role) (err error)

Add a role `r`.

func (*RBAC) GetParents

func (rbac *RBAC) GetParents(id string) ([]string, error)

GetParents return `parents` of the role `id`. If the role is not existing, an error will be returned. Or the role doesn't have any parents, a nil slice will be returned.

func (*RBAC) GetRole

func (rbac *RBAC) GetRole(id string) (r Role, parents []string, err error)

GetRole by `id` and a slice of its parents id.

func (*RBAC) GetRoles

func (rbac *RBAC) GetRoles() []Role

GetRoles returns role list

func (*RBAC) IsGranted

func (rbac *RBAC) IsGranted(id string, p Permission, assert AssertionFunc) (rslt bool)

IsGranted tests if the role `id` has Permission `p` with the condition `assert`.

func (*RBAC) Permissions

func (rbac *RBAC) Permissions(id string) Permissions

Permissions get list of all permissions

func (*RBAC) Remove

func (rbac *RBAC) Remove(id string) (err error)

Remove the role by `id`.

func (*RBAC) RemoveParent

func (rbac *RBAC) RemoveParent(id string, parent string) error

RemoveParent unbind the `parent` with the role `id`. If the role or the parent is not existing, an error will be returned.

func (*RBAC) SetParent

func (rbac *RBAC) SetParent(id string, parent string) error

SetParent bind the `parent` to the role `id`. If the role or the parent is not existing, an error will be returned.

func (*RBAC) SetParents

func (rbac *RBAC) SetParents(id string, parents []string) error

SetParents bind `parents` to the role `id`. If the role or any of parents is not existing, an error will be returned.

type Role

type Role interface {
	ID() string
	Permit(Permission) bool
	Permissions() []Permission
}

Role is an interface. You should implement this interface for your own role structures.

type Roles

type Roles map[string]Role

Roles is a map

type SimplePermission

type SimplePermission struct {
	IDStr string
}

SimplePermission only checks if the Ids are fully matching.

func (*SimplePermission) ID

func (p *SimplePermission) ID() string

ID returns the identity of permission

func (*SimplePermission) Match

func (p *SimplePermission) Match(a Permission) bool

Match another permission

type SimpleRole

type SimpleRole struct {
	sync.RWMutex
	// IDStr is the identity of role
	IDStr string `json:"id"`
	// contains filtered or unexported fields
}

SimpleRole is the default role implement. You can combine this struct into your own Role implement.

func NewRole

func NewRole(id string) *SimpleRole

NewRole is the default role factory function.

func (*SimpleRole) Assign

func (role *SimpleRole) Assign(p Permission) *SimpleRole

Assign a permission to the role.

func (*SimpleRole) ID

func (role *SimpleRole) ID() string

ID returns the role's identity name.

func (*SimpleRole) Permissions

func (role *SimpleRole) Permissions() []Permission

Permissions returns all permissions into a slice.

func (*SimpleRole) Permit

func (role *SimpleRole) Permit(p Permission) (res bool)

Permit returns true if the role has specific permission.

func (*SimpleRole) Revoke

func (role *SimpleRole) Revoke(p Permission) error

Revoke the specific permission.

type WalkHandler

type WalkHandler func(Role, []string) error

WalkHandler is a function defined by user to handle role

Directories

Path Synopsis
examples
simple command

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL