rbac

package module
v0.0.0-...-22f5d2b Latest Latest
Warning

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

Go to latest
Published: May 20, 2019 License: MIT Imports: 11 Imported by: 3

README

RBAC

(Hierarchical Role Based Access Control)

Build Status Go Report Card codecov GoDoc

Motivation

We needed hierarchical role based access control for Protocol One projects based on Go. We have some specific requirements which could`nt be covered by casin itself:

  • support for regexp matching rules for domains
  • support for storing resource based permissions for each role
  • support for given users role to all owner resources or just given resources And also we want to support all casbin features like adapters for storing policy and data, using watcher to synchronize data across application instances. For more details look at our default model description.

Installation

go get github.com/ProtocolOne/rbac

Default model

In Protocol One most of projects use hybrid mode for access control — RBAC with domain for each role there domain is user business class in the system. Domain is vendor, merchant, system, etc. Right now we don`t use tenants but it could be simple added to the model.

After domains the most important in the RBAC is object. In our terms it is resource with attached actions and resource unique identity. By default each policy define role with wildcard as resource id or use pre-defined word skip to ignore advances check for object owners.

Owners in our case is user who create and own resources. The simplest analogy is a project. So each owner in each domain is kind of project with set of resources and permissions.

Each owner could delegate role to user for all it's resources or just for selected resources. Also role could be delegated with restrictions for selected resources by they identity. Such permission models usually could be done with storing such information in external storage. We want to store all role related information in casbin groups.

The model based on access effects - we deny all that not allowed.

Resource

Depends on. It could be something like com string service.method or something more simple like shop, user management, games and so on. In general it's one business or logic function which controlled by role. And action here is a list of possible operation on resource. Like read, write, (create)|(delete) and so on.

We also use custom role manager on base of casbin role manager to support wildcards in domain.

Roles

For example we have table like this in RBAC with domain:

Role vendor merchant Resource UUID Action Effect
admin х Games * (read) (write)
admin х Games 1 read allow
manager х Analytic.* skip read allow
support х х * skip read allow

And our requirements:

  1. Admin in domain vendor could read and write any Games.
  2. Admin in domain merchant could only read Game wih identity 1.
  3. Manager in domain merchant could read any Analytic related resources.
  4. Admin in domain merchant inherits Manager.
  5. Support in any domain could read anything without any permission limits.

In terms of casbin we should define it in this way:

p, admin, vendor, games, *, (read)|(write), allow
p, admin, merchant, games, 1, read, allow
p, manager, merchant, analytics.*, skip, read, deny
p, support, *, *, *, any, allow

# Now inheritance 
g, admin,manager,merchant 

# Roles
g,max,admin,vendor
g,tom,admin,merchant

In structure like this we can't handle request like "Alise want delegates role Admin to Max in domain vendor only for own resources and just for all resources related to identity 4". In our case all resources of owner Alice based on base object - Game. We say "Any resource of Alise relates to one or other game". To support such feature we use special group g2 for storing restrictions:

g,max,admin,vendor
g2,max,alise/*/4

Which works as

  1. Max has role Admin in domain vendor.
  2. Max role Admin works only for games of Alise
  3. Max could operates any resources related to game with identity 4.

License

This project is licensed under the MIT.

Documentation

Index

Constants

View Source
const (
	// AllowAccess should be used as effect for policies that allow access.
	AllowAccess = "allow"

	// SkipResourceId should be used for policies that should skip
	// resource identity check in permissions.
	SkipResourceId = "skip"
)

Variables

This section is empty.

Functions

func BothSideMatchKeys

func BothSideMatchKeys(name1, name2 string) bool

func BothSideMatchKeysFunc

func BothSideMatchKeysFunc(args ...interface{}) (interface{}, error)

func MatchKeys

func MatchKeys(name1, name2 string) bool

MatchKeys determines whether key1 matches the pattern of key2 (similar to RESTful path), key2 can contain a *. For example, "/foo/bar" matches "/foo/*"

func MatchKeysFunc

func MatchKeysFunc(args ...interface{}) (interface{}, error)

MatchKeysFunc is wrapper for MatchKeys

func NewRoleManager

func NewRoleManager(maxHierarchyLevel int) casbin_rbac.RoleManager

NewRoleManager is the constructor for creating an instance of the default RoleManager implementation.

Types

type Context

type Context struct {
	User          string `json:"user"`
	Domain        string `json:"domain"`
	Resource      string `json:"resource"`
	ResourceId    string `json:"resourceId"`
	ResourceOwner string `json:"resourceOwner"`
	Action        string `json:"action"`
}

Context used to identity enforce request.

type CustomFunction

type CustomFunction func(args ...interface{}) (interface{}, error)

CustomFunction used to add custom functions to match.

type EnforceFunction

type EnforceFunction func(args ...interface{}) (interface{}, error)

type Enforcer

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

Enforcer. By default role modelText in Qilin role manager works with RBAC with domains for all users. We also uses elements of ABAC to check specific policy rules for resources and users.

func NewEnforcer

func NewEnforcer(params ...interface{}) *Enforcer

Enforcer create and init then Enforcer instance.

func (*Enforcer) AddFunction

func (rm *Enforcer) AddFunction(name string, function CustomFunction)

AddFunction adds a customized function.

func (*Enforcer) AddPolicy

func (rm *Enforcer) AddPolicy(p Policy) bool

AddPolicy adds an authorization rule to the current policy. If the rule already exists, the function returns false and the rule will not be added. Otherwise the function returns true by adding the new rule.

func (*Enforcer) AddRestrictionToUser

func (rm *Enforcer) AddRestrictionToUser(user string, r *Restriction) bool

AddRestrictionToUser add the resource identity to `g2` grouping policy. This used to implement access filtering for special resources in domain role. By default each role in domain have full access to all resources in domain. This restrictions allow to restrict access just for given resources.

func (*Enforcer) AddRole

func (rm *Enforcer) AddRole(rr Role) bool

AddRole adds a role for a user inside a domain with given permissions. Returns false if the user already has the role (aka not affected).

func (*Enforcer) DeleteUser

func (rm *Enforcer) DeleteUser(user string) bool

DeleteUser deletes a user. Returns false if the user does not exist (aka not affected).

func (*Enforcer) Enforce

func (rm *Enforcer) Enforce(pr Context) bool

Enforce decides whether a "subject" in "domain" can access a "resource" with the operation "action", input parameters are usually: (subject, domain, resource, action).

func (*Enforcer) GetPermissionsForUser

func (rm *Enforcer) GetPermissionsForUser(user, domain string, filters ...interface{}) *UserPermissions

GetPermissionsForUser returns all the allow and deny permissions for a user

func (*Enforcer) GetRolesForUser

func (rm *Enforcer) GetRolesForUser(user, domain string) []string

GetRolesForUser gets the roles that a user has inside a domain.

func (*Enforcer) GetUserRestrictions

func (rm *Enforcer) GetUserRestrictions(user string) []*Restriction

GetUserRestrictions return unassigned list of restrictions

func (*Enforcer) GetUsersForRole

func (rm *Enforcer) GetUsersForRole(role string, domain string, filters ...interface{}) []string

GetUsersForRole gets the users that has a role inside a domain with given filtering. By default you could provide onwer, role and uuid as string of pass *Restriction to check.

func (rm *Enforcer) HasLink(role1, role2, domain string) bool

HasLink determines whether a role inheritance rule exists.

func (*Enforcer) LinkRoles

func (rm *Enforcer) LinkRoles(role1, role2, domain string) bool

LinkRoles adds a role inheritance rule to the current policy in domain. If the rule already exists, the function returns false and the rule will not be added. Otherwise the function returns true by adding the new rule.

func (*Enforcer) RemovePolicy

func (rm *Enforcer) RemovePolicy(p Policy) bool

RemovePolicy removes an authorization rule from the current policy.

func (*Enforcer) RemoveRestrictionFromUser

func (rm *Enforcer) RemoveRestrictionFromUser(user string, r *Restriction) bool

RemoveRestrictionFromUser removes a role inheritance rule from the `g2` named policy.

func (*Enforcer) RemoveRole

func (rm *Enforcer) RemoveRole(rr Role) bool

RemoveRole deletes a role for a user inside a domain. Returns false if the user does not have the role (aka not affected).

func (*Enforcer) Save

func (rm *Enforcer) Save() error

func (*Enforcer) UnlinkRoles

func (rm *Enforcer) UnlinkRoles(role1, role2, domain string) bool

UnlinkRoles removes a role inheritance rule from the current policy in domain. If the rule not exists, the function returns false and the rule will not be deleted. Otherwise the function returns true by deleting the rule.

type MatchingFunc

type MatchingFunc func(arg1, arg2 string) bool

type Policy

type Policy struct {
	Role         string `json:"role"`
	Domain       string `json:"domain"`
	ResourceType string `json:"resourceType"`
	ResourceId   string `json:"resourceId"`
	Action       string `json:"action"`
	Effect       string `json:"effect"`
}

Policy used to declare new RBAC model policy in casbin.

type RbacRole

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

RbacRole represents the data structure for a role in RBAC.

type Restriction

type Restriction struct {
	Owner string `json:"owner"`
	Role  string `json:"role"`
	UUID  string `json:"uuid"`
}

Restriction define one permission rule.

func (*Restriction) GetRaw

func (ur *Restriction) GetRaw() string

GetRaw return raw string for permission in `g2`

type Role

type Role struct {
	User                 string   `json:"user"`
	Role                 string   `json:"role"`
	Domain               string   `json:"domain"`
	Owner                string   `json:"owner"`
	RestrictedResourceId []string `json:"restrictedResourceId"`
}

Role used to add new roles for user with given restrictions to resource.

type RoleManager

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

RoleManager provides a default implementation for the RoleManager interface. Based on default casbin role manager for RBAC with domains.

func (rm *RoleManager) AddLink(name1 string, name2 string, domain ...string) error

AddLink adds the inheritance link between role: name1 and role: name2. aka role: name1 inherits role: name2. domain is a prefix to the roles.

func (*RoleManager) Clear

func (rm *RoleManager) Clear() error

Clear clears all stored data and resets the role manager to the initial state.

func (rm *RoleManager) DeleteLink(name1 string, name2 string, domain ...string) error

DeleteLink deletes the inheritance link between role: name1 and role: name2. aka role: name1 does not inherit role: name2 any more. domain is a prefix to the roles.

func (*RoleManager) GetRoles

func (rm *RoleManager) GetRoles(name string, domain ...string) ([]string, error)

GetRoles gets the roles that a subject inherits. domain is a prefix to the roles.

func (*RoleManager) GetUsers

func (rm *RoleManager) GetUsers(name string, domain ...string) ([]string, error)

GetUsers gets the users that inherits a subject. domain is an unreferenced parameter here, may be used in other implementations.

func (rm *RoleManager) HasLink(name1 string, name2 string, domain ...string) (bool, error)

HasLink determines whether role: name1 inherits role: name2. domain is a prefix to the roles.

func (*RoleManager) PrintRoles

func (rm *RoleManager) PrintRoles() error

PrintRoles prints all the roles to log.

type UserPermission

type UserPermission struct {
	Role     string `json:"role"`
	Domain   string `json:"domain"`
	Resource string `json:"resource"`
	UUID     string `json:"uuid"`
	Action   string `json:"action"`
	Allowed  bool   `json:"allowed"`
	// Restrictions  defines all permissions and restriction for given user and role.
	Restrictions []*Restriction `json:"restrictions"`
}

UserPermission defines a single permission.

type UserPermissions

type UserPermissions struct {
	User                  string            `json:"user"`
	Domain                string            `json:"domain"`
	Permissions           []*UserPermission `json:"permissions"`
	UnmatchedRestrictions []*Restriction    `json:"unmatchedRestrictions"`
}

UserPermissions contains detailed information about user roles and permissions.

Jump to

Keyboard shortcuts

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