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