permission

package module
v0.0.0-...-862a7a8 Latest Latest
Warning

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

Go to latest
Published: Mar 4, 2016 License: MIT Imports: 5 Imported by: 0

README

Permission

Build Status GoDoc License MIT

Permission is a low-level Go package that allows to easily manage permissions.

Install

$ go get -u github.com/asdine/permission

Usage

// Define the permissions
def := permission.Definitions{
	{
		Name:          "user",
		Subset:        []string{"edit", "profile", "email", "friends", "about"},
		DefaultSubset: []string{"profile", "about"},
	},
	{
		Name:          "playlist",
		Subset:        []string{"edit", "share", "read"},
		DefaultSubset: []string{"read", "share"},
	}
}

// Require specific permissions and test it against a scope
def.Require("user.edit", "user.profile,user.about,user.email")
// -> false


// User permissions
p, _ := permission.Parse("user.edit")

q, _ := permission.Parse("user")
// q has user:profile and user:about

// Required permission
required := permission.Permission{Name: "user", Sub: "edit"}

// Compare
allowed := def[0].Allowed(required, p)
fmt.Println(allowed)
// -> true

allowed = def[0].Allowed(required, q)
fmt.Println(allowed)
// -> false

Permission

Permission is the primitive that defines a single permission.

p, _ := permission.Parse("read")

You can specify a sub Permission by adding a .

p, _ := permission.Parse("user.edit")

The . delimiter can be changed by setting the global package delimiter

permission.Delimiter(":")

p, _ := permission.Parse("user:edit")

The variable returned by permission.Parse is a Permission primitive than can be easily manipulated and marshalled.

p, _ := permission.Parse("user.edit")
q, _ := permission.Parse("user.edit")

fmt.Println(p.Name)
// user

fmt.Println(p.Sub)
// edit

fmt.Println(p.Equal(q))
// true

fmt.Println(p)
// user.edit

The primitive can be Unmarshalled from JSON ...

type Access struct {
	Name       string
	Permission permission.Permission
}

a := Access{}

input := []byte(`{"Name":"Edit User","Permission":"user.edit"}`)
json.Unmarshal(input, &a)

fmt.Println(a.Permission.Name)
// user
fmt.Println(a.Permission.Sub)
// edit

... and marshalled to JSON

output, _ := json.Marshal(a)
fmt.Println(output)
// {"Name":"Edit User","Permission":"user.edit"}

Scope

A Scope is a set of permissions. It can be used to describe multiple permissions.

s, _ := permission.ParseScope("read,write,edit,user.email")

The , separator can be changed by setting the global package separator

permission.Separator(" ")

s, _ := permission.ParseScope("read write edit user.email")

The variable returned by permission.ParseScope is a Scope primitive helper to manipulate sets of Permissions.

s, _ := permission.ParseScope("read,write,user.email")

fmt.Println(len(s))
// 3

fmt.Println(s[0].Name)
// read

fmt.Println(s[2].Sub)
// email

fmt.Println(s)
// read,write,edit,user.email

JSON example

type Role struct {
  Name        string
  Permissions permission.Scope
}

r := Role{}

input := []byte(`{"Name":"Admin","Permission":"read,write,user.email"}`)
json.Unmarshal(input, &r)

fmt.Println(len(r.Permissions))
// 3

fmt.Println(r.Permissions[0].Name)
// read

fmt.Println(a.Permissions[2].Sub)
// edit

output, _ := json.Marshal(r)
fmt.Println(output)
// {"Name":"Admin","Permission":"read,write,user.email"}

Definition

Definition is a way of defining permission attributes and rules.

def := permission.Definition{
	Name:          "playlist",
	Subset:        []string{"edit", "share", "read"},
	DefaultSubset: []string{"read", "share"},
}

Once a definition is created you can test permissions against it to see if they match

p, _ := permission.Parse("playlist.edit")

fmt.Println(def.Match(p))
// true

You can also compare two permissions and test them against the definition. It is useful when you have a permission that has default sub permissions.

required, _ := permission.Parse("playlist")
// required gets granted the DefaultSubset list of permissions.
// It is equivalent to playlist.read and playlist.share

p, _ := permission.Parse("playlist.share")

fmt.Println(def.Allowed(required, p))
// true

The given permission can also benefit of the DefaultSubset

required, _ := permission.Parse("playlist.read")

p, _ := permission.Parse("playlist")
// required gets granted the DefaultSubset list of permissions.
// It is equivalent to playlist.read and playlist.share

fmt.Println(def.Allowed(required, p))
// true

License

MIT

Author

Asdine El Hrychy

Documentation

Overview

Package permission is a low-level Go package that allows to easily manage permissions

Example
package main

import (
	"encoding/json"
	"fmt"

	"github.com/asdine/permission"
)

func main() {
	p := permission.Permission{
		Name: "user",
		Sub:  "edit",
	}

	data, _ := json.Marshal(p)
	fmt.Printf("%s\n", data)

	p = permission.Permission{}
	json.Unmarshal(data, &p)
	fmt.Println(p.Name)
	fmt.Println(p.Sub)

	def := permission.Definition{
		Name:          "user",
		Subset:        []string{"edit", "profile", "email", "friends", "about"},
		DefaultSubset: []string{"profile", "about"},
	}

	required, _ := permission.Parse("user.edit")
	allowed := def.Allowed(required, p)
	fmt.Println(allowed)
}
Output:

"user.edit"
user
edit
true

Index

Examples

Constants

This section is empty.

Variables

View Source
var (
	ErrEmptyName  = errors.New("The permission name is empty")
	ErrEmptyInput = errors.New("The given input is an empty string")
	ErrBadFormat  = errors.New("The given input is not in the correct format")
)

Errors

Functions

func Delimiter

func Delimiter(delim string)

Delimiter is a thread-safe function that sets a global delimiter for Permissions. Defaults to "."

Example
package main

import (
	"fmt"

	"github.com/asdine/permission"
)

func main() {
	permission.Delimiter(":")
	defer permission.Delimiter(".")
	perm := permission.Permission{Name: "user", Sub: "edit"}
	fmt.Println(perm)
}
Output:

user:edit

func InStringSlice

func InStringSlice(haystack []string, needle string) bool

InStringSlice checks if the given string is in the given slice of string

func Separator

func Separator(sep string)

Separator is a thread-safe function that sets a global separator for a set of Permissions. Defaults to ","

Types

type Definition

type Definition struct {
	// Name is the name of the Permission
	Name string

	// Subset is a list of all allowed sub permissions
	Subset []string

	// DefaultSubset is a list of sub permissions allowed when only the name of the permission is specified
	DefaultSubset []string
}

Definition defines a Permission and its subset. It allows to explicitly define the rules of a permission and to test permissions against the definition.

Example
package main

import (
	"fmt"

	"github.com/asdine/permission"
)

func main() {
	def := permission.Definition{
		Name:          "file",
		Subset:        []string{"read", "write", "execute"},
		DefaultSubset: []string{"read", "execute"},
	}

	required, _ := permission.Parse("file.read")

	p, _ := permission.Parse("file.read")
	fmt.Println(def.Allowed(required, p))

	p, _ = permission.Parse("file.execute")
	fmt.Println(def.Allowed(required, p))

	p, _ = permission.Parse("file") // file = file.read,file.execute
	fmt.Println(def.Allowed(required, p))

	required, _ = permission.Parse("file.write")

	p, _ = permission.Parse("file") // file = file.read,file.execute
	fmt.Println(def.Allowed(required, p))
}
Output:

true
false
true
false

func (*Definition) Allowed

func (def *Definition) Allowed(required, given Permission) bool

Allowed checks wether given respects required and the definition

func (*Definition) Match

func (def *Definition) Match(perm Permission) bool

Match detects if the given permission matches the Definition

Example
package main

import (
	"fmt"

	"github.com/asdine/permission"
)

func main() {
	defs := []permission.Definition{
		permission.Definition{
			Name:          "repo",
			Subset:        []string{"read", "write"},
			DefaultSubset: []string{"read"},
		},
		permission.Definition{
			Name:          "user",
			Subset:        []string{"profile", "edit", "friends", "email"},
			DefaultSubset: []string{"profile", "friends"},
		},
		permission.Definition{
			Name:          "playlist",
			Subset:        []string{"edit", "share", "read"},
			DefaultSubset: []string{"read", "share"},
		},
	}

	p, _ := permission.Parse("user.edit")

	for _, def := range defs {
		if def.Match(p) {
			fmt.Println(def.Name)
		}
	}
}
Output:

user

type Definitions

type Definitions []Definition

Definitions are a group of Definition

func (Definitions) Definition

func (d Definitions) Definition(p Permission) *Definition

Definition returns the Definition that matches the Permission

func (Definitions) Require

func (d Definitions) Require(required, scope string) bool

Require checks wether the given scope matches the required permission and is listed in the definitions. Returns false if the parsing fails

type Permission

type Permission struct {
	// Name of the permission
	Name string

	// Sub permission is optional
	Sub string
}

Permission is a simple permission structure. It is meant to describe a single specific permission. A Sub permission can be specified. It can safely be converted back and forth to json

Example
package main

import (
	"fmt"

	"github.com/asdine/permission"
)

func main() {
	// Simple Permission
	perm := permission.Permission{Name: "read"}
	fmt.Println(perm)
}
Output:

read
Example (SubPermission)
package main

import (
	"fmt"

	"github.com/asdine/permission"
)

func main() {
	// Sub Permission
	perm := permission.Permission{Name: "user", Sub: "edit"}
	fmt.Println(perm)
}
Output:

user.edit

func Parse

func Parse(repr string) (Permission, error)

Parse takes a string representation and returns the corresponding Permission

Example
package main

import (
	"fmt"

	"github.com/asdine/permission"
)

func main() {
	perm, _ := permission.Parse("user.edit")

	fmt.Println(perm.Name)
	fmt.Println(perm.Sub)
	fmt.Println(perm)
}
Output:

user
edit
user.edit

func (Permission) Equal

func (p Permission) Equal(q Permission) bool

Equal reports whether p and q represents the same permission

Example
package main

import (
	"fmt"

	"github.com/asdine/permission"
)

func main() {
	p, _ := permission.Parse("user.edit")
	q, _ := permission.Parse("user.edit")

	fmt.Println(p.Equal(q))
}
Output:

true

func (Permission) IsZero

func (p Permission) IsZero() bool

IsZero reports wether the permission is a zero value

func (Permission) MarshalText

func (p Permission) MarshalText() (text []byte, err error)

MarshalText implements the encoding.TextMarshaler interface

func (Permission) String

func (p Permission) String() string

String returns the string representation of the Permission

func (*Permission) UnmarshalText

func (p *Permission) UnmarshalText(text []byte) error

UnmarshalText implements the encoding.TextUnmarshaler interface

type Scope

type Scope []Permission

Scope is a set of Permissions. It can safely be converted back and forth to json

Example
package main

import (
	"fmt"

	"github.com/asdine/permission"
)

func main() {
	perms := permission.Scope{
		permission.Permission{Name: "user", Sub: "edit"},
		permission.Permission{Name: "profile"},
		permission.Permission{Name: "friends"},
	}

	text, _ := perms.MarshalText()
	fmt.Println(string(text))
}
Output:

user.edit,profile,friends

func ParseScope

func ParseScope(repr string) (Scope, error)

ParseScope takes a string representation and returns the corresponding Scope

Example
package main

import (
	"fmt"

	"github.com/asdine/permission"
)

func main() {
	perms, _ := permission.ParseScope("user.edit,profile,friends")

	fmt.Println(len(perms))
	fmt.Println(perms[0].Name)
	fmt.Println(perms[0].Sub)
	fmt.Println(perms[1].Name)
	fmt.Println(perms[2].Name)
}
Output:

3
user
edit
profile
friends

func (*Scope) Has

func (s *Scope) Has(repr string) bool

Has checks if the scope has the given permission

func (*Scope) HasPermission

func (s *Scope) HasPermission(p Permission) bool

HasPermission checks if the scope has the given permission

func (Scope) MarshalText

func (s Scope) MarshalText() (text []byte, err error)

MarshalText implements the encoding.TextMarshaler interface

func (*Scope) UnmarshalText

func (s *Scope) UnmarshalText(text []byte) error

UnmarshalText implements the encoding.TextUnmarshaler interface

Jump to

Keyboard shortcuts

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