README

goRBAC

Build Status GoDoc Coverage Status

goRBAC provides a lightweight role-based access control implementation in Golang.

For the purposes of this package:

* an identity has one or more roles.
* a role requests access to a permission.
* a permission is given to a role.

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).

Version

Currently, goRBAC has two versions:

Version 1 is the original design which will only mantain to fix bugs.

Version 2 is the newly design which will continually mantain with a stable API.

While the master branch will be under developing with new API and can be changed without notice.

Install

Install the package:

$ go get gopkg.in/mikespook/gorbac.v2

Usage

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

  1. Preparing

  2. Checking

Preparing

Import the library:

import "github.com/mikespook/gorbac"

Get a new instance of RBAC:

rbac := gorbac.New()

Get some new roles:

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

Get some new permissions:

pA := gorbac.NewStdPermission("permission-a")
pB := gorbac.NewStdPermission("permission-b")
pC := gorbac.NewStdPermission("permission-c")
pD := gorbac.NewStdPermission("permission-d")
pE := gorbac.NewStdPermission("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 initailization, 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: InherCircle, AnyGranted, AllGranted. Please open an issue for the new built-in requriement.

E.g.:

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

Persistence

The mose asked question is how to persist the goRBAC instance. Please check the post HOW TO PERSIST GORBAC INSTANCE for the details.

Patches

2016-03-03

gofmt -w -r 'AssignPermission -> Assign' .
gofmt -w -r 'RevokePermission -> Revoke' .

Authors

Open Source - MIT Software License

See LICENSE.

Documentation

Overview

    Package gorbac provides a lightweight role-based access control implementation in Golang.

    For the purposes of this package:

    * an identity has one or more roles.
    * a role requests access to a permission.
    * a permission is given to a role.
    

    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 parent roles.
    

    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 = fmt.Errorf("Found circle")
    )

    Functions

    func AllGranted

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

      AllGranted checks if all roles have the permission.

      func AnyGranted

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

        AnyGranted checks if any role has the permission.

        func InherCircle

        func InherCircle(rbac *RBAC) (err error)

          InherCircle 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 LayerPermission

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

                LayerPermission 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 (*LayerPermission) ID

                func (p *LayerPermission) ID() string

                  ID returns the identity of permission

                  func (*LayerPermission) Match

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

                    Match another permission

                    type Permission

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

                      Permission exports `Id` and `Match`

                      func NewLayerPermission

                      func NewLayerPermission(id string) Permission

                        NewLayerPermission returns an instance of layered permission with `id`

                        func NewStdPermission

                        func NewStdPermission(id string) Permission

                          NewStdPermission 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) Get

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

                                    Get the role by `id` and a slice of its parents id.

                                    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) 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) 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
                                                }

                                                  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 StdPermission

                                                    type StdPermission struct {
                                                    	IDStr string
                                                    }

                                                      StdPermission only checks if the Ids are fully matching.

                                                      func (*StdPermission) ID

                                                      func (p *StdPermission) ID() string

                                                        ID returns the identity of permission

                                                        func (*StdPermission) Match

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

                                                          Match another permission

                                                          type StdRole

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

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

                                                            func NewStdRole

                                                            func NewStdRole(id string) *StdRole

                                                              NewStdRole is the default role factory function. It matches the declaration to RoleFactoryFunc.

                                                              func (*StdRole) Assign

                                                              func (role *StdRole) Assign(p Permission) error

                                                                Assign a permission to the role.

                                                                func (*StdRole) ID

                                                                func (role *StdRole) ID() string

                                                                  ID returns the role's identity name.

                                                                  func (*StdRole) Permissions

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

                                                                    Permissions returns all permissions into a slice.

                                                                    func (*StdRole) Permit

                                                                    func (role *StdRole) Permit(p Permission) (rslt bool)

                                                                      Permit returns true if the role has specific permission.

                                                                      func (*StdRole) Revoke

                                                                      func (role *StdRole) 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
                                                                          user-defined
                                                                          User-defined gorbac example
                                                                          User-defined gorbac example