acl

package module
Version: v1.0.0 Latest Latest
Warning

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

Go to latest
Published: Oct 31, 2018 License: MIT Imports: 2 Imported by: 0

README

WIP

ACL

Codacy Badge Build Status

TL;DR;

acl is a lightweight acl manager for go.

Features

  • Design simple & reusable roles to empower your application.
  • Acquire the rights of other roles to build a powerful set of permissions.
  • Resolve possible roles by examine them in an unified way.

Example

type User struct {
    isAdmin bool
}

func main() {
    // first of all: create a new manager instance to register all your roles in one place
    manager := acl.NewManager()

    // now you can use `Ensure` to guarantee that the role with the passed identifier is present
    user := manager.Ensure("user").Grant("profile.edit")
    // use `Grant`, `Revoke` and `AcquireFrom` to extend the right stack
    editor := manager.Ensure("editor").Grant("news.list", "news.create", "news.edit").AcquireFrom(user)

    // you can also use NewRole to create a Role manually
    admin := acl.NewRole("admin").Grant("news.delete").AcquireFrom(editor)
    // note, that you have to register the role by yourself
    manager.Register(admin)

    // to check if a right was granted to a role you can use:
    var hasAccess bool
    hasAccess = admin.Has("some.right")

    // to check if at least one of the expected rights is present:
    hasAccess = admin.HasOneOf("news.list", "news.create")

    // ... and finally, to check that all the expected rights are present, use:
    hasAccess = admin.HasAllOf("news.delete", "news.list")

    // a role can be extended with an examiner to determine whether a role can be added
    // to a `ResultSet`
    admin.SetExaminer(func (payload interface{}) bool {
        user := payload.(User)
        return user.isAdmin
    })

    // to get a result set you can use the managers `Examine` function
    rs := manager.Examine(User{isAdmin: true})

    // a result set contains "Has", "HasOneOf" and "HasAllOf" as described above and...
    // `GetRole` to grab specific roles from the result set
    expectedRole := rs.GetRole("admin")

    // you can also check if a role was added to a result set using:
    if rs.HasRole("admin") {
        // ...
    }
}

Possible enhancements

  • Conditional IsAllowed (combine AND/OR queries into a ConditionGroup).

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type ExaminerFunc

type ExaminerFunc = func(payload interface{}) bool

ExaminerFunc a function to determine whether a role can be added to a `ResultSet`.

type Manager

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

Manager contains all registered roles.

func NewManager

func NewManager() *Manager

NewManager creates a new manager instance.

func (*Manager) Ensure

func (manager *Manager) Ensure(id string) *Role

Ensure returns or creates a role with the given id.

func (*Manager) Examine

func (manager *Manager) Examine(payload interface{}) *ResultSet

Examine starts the examining process to determine the available roles.

func (*Manager) Get

func (manager *Manager) Get(id string) *Role

Get returns the role with the given id.

func (*Manager) Register

func (manager *Manager) Register(roles ...*Role) (*Manager, error)

Register transfers the given roles into the Manager registry.

func main() {
    m := NewManager().Register(NewRole("a").Grant("b"), NewRole("c").Grant("d"))
}

Note, that each role MUST contain an unique identifier.

type ResultSet

type ResultSet struct {
	Matches map[string]*Role
}

func NewResultSet

func NewResultSet(roles ...*Role) *ResultSet

NewResultSet creates a new `ResultSet` instance

func (*ResultSet) GetRole

func (result *ResultSet) GetRole(id string) *Role

GetRole returns the role with the given identifier or nil.

func (*ResultSet) Has

func (result *ResultSet) Has(right string) bool

Has checks that at least one role contains the given right.

func (*ResultSet) HasAllOf

func (result *ResultSet) HasAllOf(rights ...string) bool

HasAllOf verifies that all specified rights are present.

func (*ResultSet) HasOneOf

func (result *ResultSet) HasOneOf(rights ...string) bool

HasOneOf checks that at least one role contains at least one of the given rights.

func (*ResultSet) HasRole

func (result *ResultSet) HasRole(id string) bool

HasRole determines whether a role is present.

type Role

type Role struct {
	Id string
	// contains filtered or unexported fields
}

Role contains all necessary information about one set of granted rights.

Each role requires an identifier. It is possible to define multiple roles with the same identifier as long as each manager contains an unique set of identifiers.

func NewRole

func NewRole(id string) *Role

NewRole returns a new role instance.

func (*Role) AcquireFrom

func (role *Role) AcquireFrom(roles ...*Role) *Role

AcquireFrom grabs the rights from the given roles to add them.

	   func main() {
        r1 := NewRole("r1").Grant("right.a")
        r2 := NewRole("r2").AcquireFrom(r1).Grant("right.b")
    }

func (*Role) Grant

func (role *Role) Grant(rights ...string) *Role

Grant adds the given right(s) to the role.

	   func main() {
        r := NewRole("a")
        r.Grant("right.a", "right.b")
    }

Note, that duplications will be ignored.

func (*Role) Has

func (role *Role) Has(right string) bool

Has checks that the given right has been granted.

To resolve whether a right is available or not, the function uses a binary search to determine the actual index of the given right(s). Therefore, the array of granted rights is always sorted alphabetically.

func (*Role) HasAllOf

func (role *Role) HasAllOf(rights ...string) bool

HasAllOf verifies that all specified rights are present.

func main() {
    r := NewRole("r").Grant("a", "b", "c")
    r.HasAllOf("a", b", "c")
}

func (*Role) HasOneOf

func (role *Role) HasOneOf(rights ...string) bool

HasOneOf checks that at least one of the given rights has been granted.

func main() {
    r := NewRole("r")
    r.Grant("right.a")
    r.HasOneOf("right.a", "right.b")
}

func (*Role) Revoke

func (role *Role) Revoke(rights ...string) *Role

Revoke removes the given right(s) from the role.

	   func main() {
        r := NewRole("a")
        r.Grant("right.a", "right.b")
        r.Revoke("right.a")
    }

func (*Role) SetExaminer

func (role *Role) SetExaminer(examiner ExaminerFunc) *Role

SetExaminer sets / overwrites the examiner.

The examiner is used to determine whether a role can be added to a `ResultSet`.

type User struct {
    isAdmin bool
}

func main() {
    r := NewRole("admin").Grant("godmode").SetExaminer(func (payload interface{}) bool {
        user := payload.(User)
        return user.isAdmin
    })

    rs := NewManager().Register(r).Examine(User{isAdmin: true})
}

Jump to

Keyboard shortcuts

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