casbin

package module
v0.4.0 Latest Latest
Warning

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

Go to latest
Published: Jun 23, 2026 License: MIT Imports: 4 Imported by: 0

README

casbin

Another casbin implementation in golang.

Installation

go get github.com/sdcxtech/casbin

Quick start

package main

import (
	"fmt"
	"strings"

	"github.com/sdcxtech/casbin"
	"github.com/sdcxtech/casbin/core"
	"github.com/sdcxtech/casbin/effector"
	"github.com/sdcxtech/casbin/load"
)

func main() {
	policy, _ := core.NewAssertionSchema("sub, obj, act")
	request, _ := core.NewAssertionSchema("sub, obj, act")

	roles := core.RolesSchema{
		"g": {Type: core.RoleTypeWithoutDomain},
	}

	matchers, _ := core.MatchersConfig{
		Roles: roles,
		Define: map[string]string{
			"m": "g(r.sub, p.sub) && r.obj == p.obj && r.act == p.act",
		},
	}.New()

	model := core.NewModel(policy, request, roles, effector.NewAllowOverride(), matchers)

	policies := strings.NewReader(`
p, staff, order, get
g, admin, staff
`)

	enforcer, _ := casbin.NewEnforcer(model, load.NewCSVIterator(policies))
	allow, _ := enforcer.Enforce(casbin.Request("admin", "order", "get"))

	fmt.Println(allow) // true
}

Model config

Models can also be loaded from a viper.Viper instance, so the concrete file format can be TOML, YAML, JSON, or anything else Viper supports.

[request_definition]
r = "sub, dom, obj, act"

[policy_definition]
p = "sub, obj, act, eft"

[role_definition]
g = "_, _, _"
g1 = "_, _"

[policy_effect]
type = "allow-and-deny"
key = "eft"

[matchers]
m = "g(r.sub, p.sub, r.dom) && r.obj == p.obj && r.act == p.act"
model, err := load.ModelFromViper(v)

Supported effect types:

  • allow-override: allow when any policy matches. No effect field is required.
  • deny-override: allow unless a matched policy has effect deny.
  • allow-and-deny: allow when a policy with effect allow matches and no matched policy has effect deny.

deny-override and allow-and-deny require policy_effect.key to name a policy field whose value is allow or deny.

Policies

Use load.NewCSVIterator to load policy and role rows from an io.Reader. The first CSV column is the section key, such as p for policies or g for a role relation. Lines starting with # are comments.

p, staff, order, get
g, admin, staff

For a role definition with domain (g = "_, _, _"), role rows use from, to, domain:

g, alice, admin, tenant1

Matchers

Matchers are CEL expressions. Request values are available as r.<field>, policy values are available as p.<field>, and role functions use the names from [role_definition].

You can register string match helpers as CEL extension functions:

model, err := load.ModelFromViper(
	v,
	load.ExtensionFuncs(
		keymatch.ToExtensionFunc("globMatch", keymatch.GlobMatch),
		keymatch.ToExtensionFunc("regexMatch", keymatch.NewRegexMatch()),
		keymatch.ToExtensionFunc("ipMatch", keymatch.IPMatch),
	),
)

Then use them from a matcher:

[matchers]
m = "g(r.sub, p.sub) && globMatch(r.obj, p.obj) && r.act == p.act"

Per-request options

Enforce accepts options for one call without changing the enforcer:

  • casbin.UseMatcher(name) selects a matcher other than the default m.
  • casbin.WithRawPolicies(rows) injects extra raw policies for this call.
  • casbin.WithPolicies(policies) injects parsed policies for this call.
  • casbin.OnlyInjectedPolicies() ignores the enforcer's loaded policies.
  • casbin.WithRoleGraphs(key, graphs...) injects role graphs for this call.

Difference with the official casbin implementation

  • Use google Common Expression Language as the matcher expression language.
  • Assertion field in policy and request only can be string type. So there is no support for ABAC model.
  • Only implement the core feature checking permissions. Not include policies and roles management which should be implemented in a different Bounded Context.

License

Released under the MIT License.

Documentation

Index

Constants

This section is empty.

Variables

View Source
var ErrEmptyMatcherName = errors.New("matcher name can not be empty")

Functions

func Request

func Request(rvals ...string) []string

Types

type EnforceOption

type EnforceOption interface {
	// contains filtered or unexported methods
}

EnforceOption is an option for calling enforce on an enforcer.

func OnlyInjectedPolicies added in v0.2.0

func OnlyInjectedPolicies() EnforceOption

OnlyInjectedPolicies make enforcer don't use global policies.

func UseMatcher

func UseMatcher(name string) EnforceOption

UseMatcher use the specified matcher instead of the default matcher named 'm'.

func WithPolicies added in v0.2.0

func WithPolicies(policies []core.Assertion) EnforceOption

WithPolicies inject per-calling policies.

func WithRawPolicies added in v0.2.0

func WithRawPolicies(policies [][]string) EnforceOption

WithPolicies inject per-calling raw policies.

func WithRoleGraphs

func WithRoleGraphs(gKey string, graphs ...*graph.Graph) EnforceOption

WithRoleGraphs inject per-calling role mapping graphs.

Find in these grpahs first, then the global role mapping graph.

type Enforcer

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

Enforcer check if a user has requested permission.

Default to use matcher with name 'm', can be changed by option.

func NewEnforcer

func NewEnforcer(
	model *core.Model,
	policyItr core.LoadIterator,
) (enforcer *Enforcer, err error)

NewEnforcer new an enforcer by a model and a policy iterator.

func (*Enforcer) Enforce

func (e *Enforcer) Enforce(requestValues []string, options ...EnforceOption) (allow bool, err error)

Enforce check if the requested permissions assertion is allowed.

Directories

Path Synopsis
internal

Jump to

Keyboard shortcuts

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