gorbac

package module
v0.0.0-...-fc69e30 Latest Latest
Warning

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

Go to latest
Published: May 25, 2015 License: MIT Imports: 1 Imported by: 0

README

goRBAC

Build Status GoDoc

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

Install

Install the package:

$ go get github.com/mikespook/gorbac

Usage

Import the package:

import github.com/mikespook/gorbac

Get a goRBAC instance:

rbac := gorbac.New()

gorbac.Role is an interface. That is you can use your own data structure to satisfy this interface.

rbac := gorbac.NewWithFactory(YourOwnFactory)

However, YourOwnFactory should match the declaration of gorabc.RoleFactoryFunc.

Specified permissions and parent roles for a role. If the role is not existing, new one will be created:

rbac.Add("editor", []string{"edit.article"}, nil)	
rbac.Set("master", []string{"del.article"}, []string{"editor"})

The main difference between Add and Set is:

  • Add keeps original permissions and parents which are already existed;
  • Set covers them with new permissions and parents.

Remove a role:

rbac.Remove("guest")

Get a role for more fine-grained controls:

rbac.Get("admin")

Check if a role has a permission:

rbac.IsGranted("editor", "edit.article", nil)

The 3rd param, Assertion function is used for more fine-grained testing:

rbac.IsGranted("editor", "edit.article", 
	func(role, permission string, rbac* Rbac) bool {
		return article.Owner == User.Id
})

Revoke a permission from a role:

rbac.Get("master").RevokePermission("del.article")

Remove a role's parent:

rbac.Get("editor").RemoveParent("auth-user")

In a real case, it is good for checking if a role existed:

if role := rbac.Get("not-exists"); role == nil {
	// Not exists;
} else {
	// Exists. 	
}

Dump and Restore help for data persistence:

m := rbac.Dump()
data, err := json.Marshal(m)
// Handling error or save data

var m gorbac.Map
err := json.Unmarshal(data, &m)
rbac = gorbac.Restore(m)

If you want use user-defined data structures in data persistence, RestoreWithFactory would help you building RBAC instance with your own data structures.

var m gorbac.Map
err := json.Unmarshal(data, &m)
rbac = gorbac.RestoreWithFactory(m, YourOwnFactory)

For more details, please see example_test.go. Also, there are two independent examples. example/http shows accessing RBAC instance through HTTP, and another illustrates how user-defined roles work.

Authors

Open Source - MIT Software License

See LICENSE.

Documentation

Overview

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

Examples

Constants

View Source
const (
	ParentKey     = "parents"
	PermissionKey = "permissions"
	NameKey       = "name"
)

Variables

This section is empty.

Functions

This section is empty.

Types

type AssertionFunc

type AssertionFunc func(string, string, *Rbac) bool

Assertion function supplies more fine-grained permission controls.

type BaseRole

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

func (*BaseRole) AddParent

func (role *BaseRole) AddParent(name string)

func (*BaseRole) AddPermission

func (role *BaseRole) AddPermission(permission string)

func (*BaseRole) HasPermission

func (role *BaseRole) HasPermission(permission string) bool

func (*BaseRole) Name

func (role *BaseRole) Name() string

func (*BaseRole) Parents

func (role *BaseRole) Parents() []string

func (*BaseRole) Permissions

func (role *BaseRole) Permissions() []string

func (*BaseRole) RemoveParent

func (role *BaseRole) RemoveParent(name string)

func (*BaseRole) Reset

func (role *BaseRole) Reset()

func (*BaseRole) RevokePermission

func (role *BaseRole) RevokePermission(permission string)

type Map

type Map map[string]RoleMap

Export RBAC to a structure data

type Rbac

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

RBAC

Example

Suppose:

The role-c is inheriting from role-a, role-b. The role-d is individual. The role-e is inheriting from role-c, role-d. Every roles have thire own permissions.

Thus:

The role-c has been granted permis-a/b/c. The role-e has been granted permis-a/b/c/d.

package main

import (
	"fmt"
	"github.com/mikespook/gorbac"
)

func main() {
	testingcases := map[string]map[string][]string{
		"role-a": map[string][]string{
			"permissions": []string{"permis-a"},
			"parents":     nil,
		},
		"role-b": map[string][]string{
			"permissions": []string{"permis-b"},
			"parents":     nil,
		},
		"role-c": map[string][]string{
			"permissions": []string{"permis-c"},
			"parents":     []string{"role-a", "role-b"},
		},
		"role-d": map[string][]string{
			"permissions": []string{"permis-d"},
			"parents":     nil,
		},
		"role-e": map[string][]string{
			"permissions": nil,
			"parents":     []string{"role-c", "role-d"},
		},
	}
	rbac := gorbac.New()

	for role, testingcase := range testingcases {
		rbac.Add(role, testingcase["permissions"], testingcase["parents"])
	}

	if rbac.IsGranted("role-c", "permis-a", nil) &&
		rbac.IsGranted("role-c", "permis-b", nil) &&
		rbac.IsGranted("role-c", "permis-c", nil) {
		fmt.Println("The role-c has been granted permis-a/b/c.")
	}
	if rbac.IsGranted("role-e", "permis-a", nil) &&
		rbac.IsGranted("role-e", "permis-b", nil) &&
		rbac.IsGranted("role-e", "permis-c", nil) &&
		rbac.IsGranted("role-e", "permis-d", nil) {
		fmt.Println("The role-e has been granted permis-a/b/c/d.")
	}
}
Output:

The role-c has been granted permis-a/b/c.
The role-e has been granted permis-a/b/c/d.

func New

func New() *Rbac

Return a RBAC structure. The default role structure will be used.

func NewWithFactory

func NewWithFactory(factory RoleFactoryFunc) *Rbac

Return a RBAC structure with a specific factory function. Role structure will be generated by the function.

func Restore

func Restore(data Map) *Rbac

Restore rbac from a map, a default role implamentation used

func RestoreWithFactory

func RestoreWithFactory(data Map, factory RoleFactoryFunc) *Rbac

Restore rbac from a map, use factory for your own data structure

func (*Rbac) Add

func (rbac *Rbac) Add(name string, permissions []string, parents []string)

Add a role with `name`. It has `permissions` and `parents`. If the role is not existing, a new one will be created. This function will add new permissions and parents to the role, and keep orignals.

func (*Rbac) Dump

func (rbac *Rbac) Dump() Map

Dump RBAC

func (*Rbac) Get

func (rbac *Rbac) Get(name string) Role

Return a role or nil if not exists.

func (*Rbac) IsGranted

func (rbac *Rbac) IsGranted(name, permission string,
	assert AssertionFunc) bool

Test if the `name` has `permission` in the `assert` condition.

func (*Rbac) Remove

func (rbac *Rbac) Remove(name string)

Remove a role.

func (*Rbac) Set

func (rbac *Rbac) Set(name string, permissions []string, parents []string)

Set a role with `name`. It has `permissions` and `parents`. If the role is not existing, a new one will be created. This function will cover role's orignal permissions and parents.

type Role

type Role interface {
	Name() string
	AddPermission(string)
	HasPermission(string) bool
	RevokePermission(string)
	Permissions() []string
	AddParent(string)
	RemoveParent(string)
	Parents() []string
	Reset()
}

Implement this interface for your own role structure.

func NewBaseRole

func NewBaseRole(rbac *Rbac, name string) Role

type RoleFactoryFunc

type RoleFactoryFunc func(*Rbac, string) Role

Sometimes, a custom role structure is needed by projects. You should define your own role factory function for this purpuse.

type RoleMap

type RoleMap map[string][]string

An exportable data structure

func RoleToMap

func RoleToMap(role Role) RoleMap

An interface can't export directly. But you can convert it into a map.

Directories

Path Synopsis
examples
http
possum & gorbac example
possum & gorbac example
user-defined
User-defined gorbac example
User-defined gorbac example

Jump to

Keyboard shortcuts

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