Documentation
¶
Overview ¶
Package caskin provides a multi-domain RBAC (Role-Based Access Control) permission management library built on top of casbin.
Overview ¶
caskin extends casbin's RBAC model to support multiple isolated domains, where each domain has its own set of roles, objects, and policies. This allows you to build multi-tenant applications where each tenant (domain) has fully isolated permissions.
Core Concepts ¶
- User: An entity that can be assigned roles within a domain.
- Domain: An isolated permission scope (e.g., a tenant or organization).
- Role: A named set of permissions within a domain; roles can be hierarchical.
- Object: A resource that can be accessed; objects form a tree hierarchy.
- ObjectData: A domain-specific data item associated with an Object type.
- Policy: A tuple of (Role, Object, Domain, Action) granting a role permission to perform an action on an object within a domain.
- Action: One of read, write, or manage.
Quick Start ¶
// 1. Define your own User, Role, Object, Domain types (implement the
// corresponding interfaces), then register them with caskin:
caskin.Register[*MyUser, *MyRole, *MyObject, *MyDomain]()
// 2. Create a service instance:
svc, err := caskin.New(&caskin.Options{
DB: &caskin.DBOption{DSN: "..."},
})
// 3. Use the service to manage permissions:
svc.CreateDomain(domain)
svc.CreateRole(admin, domain, role)
svc.AddUserRole(admin, domain, []*caskin.UserRolePair{{User: user, Role: role}})
Superadmin ¶
caskin has a special "superadmin" role that transcends all domain boundaries. Superadmins can manage any domain and bypass all permission checks. Use IBaseService.AddSuperadmin / IBaseService.DeleteSuperadmin to manage superadmin users.
Directory ¶
Objects can be organized into tree-structured directories. The IDirectoryService provides operations to create, move, copy, and delete directory nodes and their contents.
Index ¶
- Constants
- Variables
- func CasbinModel() (model.Model, error)
- func Check[T any](e IEnforcer, u User, d Domain, one T, action Action) bool
- func Diff[T cmp.Ordered](source, target []T) (add, remove []T)
- func Filter[T any](e IEnforcer, u User, d Domain, action Action, source []T) []T
- func GetByID[T any](db MetaDB, id []uint64) ([]T, error)
- func ID[E idInterface](in []E) []uint64
- func IDMap[E idInterface](in []E) map[uint64]E
- func NewObjectDeleter(children ObjectChildrenGetFunc, delete ObjectDeleteFunc) *objectDeleter
- func NewObjectDirectory(in []*Directory) *objectDirectory
- func NewObjectUpdater(parentGet ObjectParentGetFunc, parentAdd ObjectParentAddFunc, ...) *objectUpdater
- func Register[U User, R Role, O Object, D Domain]()
- func SetWatcher(e casbin.IEnforcer, option *WatcherOption) error
- type Action
- type Backend
- type CountDirectoryItem
- type CreatorObject
- type CreatorPolicy
- type CreatorRole
- type DBOption
- type DictionaryOption
- type Directory
- type DirectoryRequest
- type DirectoryResponse
- type DirectorySearchType
- type Domain
- type EdgeSorter
- type Factory
- type Feature
- type Frontend
- type IBaseService
- type ICreatorDictionary
- type ICurrentService
- type IDictionary
- type IDirectory
- type IDirectoryService
- type IEnforcer
- type IFeatureDictionary
- type IFeatureService
- type IService
- type InheritanceEdge
- type InheritanceGraph
- type MetaDB
- type NamedObject
- func (o *NamedObject) Decode(code string) error
- func (o *NamedObject) Encode() string
- func (o *NamedObject) GetDomainID() uint64
- func (o *NamedObject) GetID() uint64
- func (o *NamedObject) GetObjectType() string
- func (o *NamedObject) GetParentID() uint64
- func (o *NamedObject) SetDomainID(uint64)
- func (o *NamedObject) SetID(uint64)
- func (o *NamedObject) SetParentID(uint64)
- type Object
- type ObjectChildrenGetFunc
- type ObjectData
- type ObjectDeleteFunc
- type ObjectParentAddFunc
- type ObjectParentDelFunc
- type ObjectParentGetFunc
- type ObjectType
- type Option
- type Options
- type Package
- type Policy
- type Role
- type SampleSuperadminDomain
- type SampleSuperadminRole
- func (s *SampleSuperadminRole) Decode(code string) error
- func (s *SampleSuperadminRole) Encode() string
- func (s *SampleSuperadminRole) GetDomainID() uint64
- func (s *SampleSuperadminRole) GetID() uint64
- func (s *SampleSuperadminRole) GetObjectID() uint64
- func (s *SampleSuperadminRole) SetDomainID(uint64)
- func (s *SampleSuperadminRole) SetID(uint64)
- func (s *SampleSuperadminRole) SetObjectID(uint64)
- type UpsertType
- type User
- type UserRolePair
- type WatcherOption
Constants ¶
const ( // ObjectPType is the casbin named-policy type used for object hierarchy // edges (parent→child relationships between Objects). ObjectPType = "g2" // SuperadminRole is the casbin role name reserved for the superadmin role. // It is used in the dedicated superadmin domain and bypasses all normal // permission checks. SuperadminRole = "superadmin" // SuperadminDomain is the casbin domain name reserved for the superadmin // scope. Assignments in this domain confer superadmin privileges. SuperadminDomain = "superdomain" )
Variables ¶
var ( // ErrNil is returned when a required argument is nil. ErrNil = fmt.Errorf("nil data") // ErrEmptyID is returned when an entity has an unset (zero) ID. ErrEmptyID = fmt.Errorf("empty id") // ErrAlreadyExists is returned when trying to create an entity that // already exists (non-deleted) in the database. ErrAlreadyExists = fmt.Errorf("already exists") // ErrNotExists is returned when the target entity cannot be found. ErrNotExists = fmt.Errorf("not exists") // ErrInValidObject is returned when the object reference is invalid or // does not belong to the current domain. ErrInValidObject = fmt.Errorf("invalid object") // ErrInValidObjectType is returned when the object type string is not // registered in the current factory. ErrInValidObjectType = fmt.Errorf("invalid object type") // ErrCantChangeObjectType is returned when an update attempts to change // an existing object's type, which is not allowed. ErrCantChangeObjectType = fmt.Errorf("can't change object type") // ErrCantOperateRootObject is returned when an operation would affect the // root object of a domain, which is protected. ErrCantOperateRootObject = fmt.Errorf("can't operate root object") // ErrParentCanNotBeItself is returned when an object's parent ID is set // to its own ID, which would create a self-loop. ErrParentCanNotBeItself = fmt.Errorf("parent id can't be it self id") // ErrParentToDescendant is returned when moving an object would make its // new parent one of its own descendants, creating a cycle. ErrParentToDescendant = fmt.Errorf("can't change parent to descendant") // ErrInValidRequest is returned when the [DirectoryRequest] parameters // are inconsistent or missing required fields. ErrInValidRequest = fmt.Errorf("invalid request") // ErrNoReadPermission is returned when the caller lacks read access to // the target object/domain. ErrNoReadPermission = fmt.Errorf("no read permission") // ErrNoWritePermission is returned when the caller lacks write access to // the target object/domain. ErrNoWritePermission = fmt.Errorf("no write permission") // ErrNoManagePermission is returned when the caller lacks manage access // to the target object/domain. ErrNoManagePermission = fmt.Errorf("no manage permission") // ErrNoBackendPermission is returned when [IFeatureService.AuthBackend] // determines the caller is not authorised for the given backend endpoint. ErrNoBackendPermission = fmt.Errorf("no backend api permission") // ErrIsNotSuperadmin is returned when a superadmin-only operation is // attempted by a non-superadmin user, or when decoding a superadmin // token fails. ErrIsNotSuperadmin = fmt.Errorf("is not superadmin") // ErrInValidCurrent is returned when [ICurrentService] methods are called // before [ICurrentService.SetCurrent] has been called. ErrInValidCurrent = fmt.Errorf("invalid current api") )
Sentinel errors returned by caskin operations.
Callers should use errors.Is to check for specific errors:
if errors.Is(err, caskin.ErrNoReadPermission) { ... }
var ( // DefaultSuperadminRoleName is the default name for the superadmin role // stored in the casbin policy. Override via [Options.DefaultSuperadminRoleName]. DefaultSuperadminRoleName = "superadmin_role" // DefaultSuperadminDomainName is the default name for the superadmin domain. // Override via [Options.DefaultSuperadminDomainName]. DefaultSuperadminDomainName = "superadmin_domain" )
Default names used when no overrides are provided via Options.
var CasbinModelText string
var (
DefaultFeatureRootName = "github.com/awatercolorpen/caskin::feature"
)
Functions ¶
func CasbinModel ¶
CasbinModel loads the embedded casbin RBAC model configuration and returns a parsed model.Model ready to be passed to a casbin Enforcer.
func ID ¶ added in v0.1.0
func ID[E idInterface](in []E) []uint64
ID extracts the integer IDs from a slice of entities.
func IDMap ¶ added in v0.1.0
func IDMap[E idInterface](in []E) map[uint64]E
IDMap converts a slice of entities into a map keyed by their integer ID.
func NewObjectDeleter ¶ added in v0.1.0
func NewObjectDeleter(children ObjectChildrenGetFunc, delete ObjectDeleteFunc) *objectDeleter
func NewObjectDirectory ¶ added in v0.1.0
func NewObjectDirectory(in []*Directory) *objectDirectory
func NewObjectUpdater ¶ added in v0.1.0
func NewObjectUpdater( parentGet ObjectParentGetFunc, parentAdd ObjectParentAddFunc, parentDel ObjectParentDelFunc) *objectUpdater
func Register ¶ added in v0.1.0
Register wires up the global type factory with the caller's concrete implementations of User, Role, Object, and Domain. It must be called exactly once before creating any caskin service via New.
All four type parameters must be pointer types that implement their respective interfaces:
caskin.Register[*MyUser, *MyRole, *MyObject, *MyDomain]()
func SetWatcher ¶ added in v0.2.0
func SetWatcher(e casbin.IEnforcer, option *WatcherOption) error
SetWatcher attaches a policy watcher to the given casbin enforcer based on the provided WatcherOption. If option is nil, SetWatcher is a no-op.
Supported watcher types:
- "redis": sets up a Redis pub/sub watcher via github.com/casbin/redis-watcher.
- "": or unknown type with AutoLoad > 0 — enables the enforcer's built-in periodic policy reload via StartAutoLoadPolicy.
Types ¶
type Action ¶
type Action = string
Action is a permission verb. caskin defines three built-in actions: Read, Write, and Manage. Custom actions are also supported.
type Backend ¶ added in v0.1.0
type Backend struct {
Path string `json:"path" toml:"path"`
Method string `json:"method" toml:"method"`
Description string `json:"description" toml:"description"`
Group string `json:"group" toml:"group"`
}
Backend it is for backend API
type CountDirectoryItem ¶ added in v0.1.0
CountDirectoryItem is the function signature for per-directory item count callbacks used in DirectoryRequest.
type CreatorObject ¶ added in v0.1.0
type CreatorObject struct {
Name string `json:"name" toml:"name"`
Type string `json:"type" toml:"type"`
Description string `json:"description" toml:"description"`
}
func (*CreatorObject) ToObject ¶ added in v0.1.0
func (c *CreatorObject) ToObject() Object
type CreatorPolicy ¶ added in v0.1.0
type CreatorRole ¶ added in v0.1.0
type CreatorRole struct {
Name string `json:"name" toml:"name"`
Description string `json:"description" toml:"description"`
}
func (*CreatorRole) ToRole ¶ added in v0.1.0
func (c *CreatorRole) ToRole() Role
type DBOption ¶ added in v0.1.0
type DBOption struct {
// DSN is the data source name (connection string) for the database.
DSN string `json:"dsn"`
// Type selects the database driver. Supported values: "sqlite", "mysql"
// (default when empty), and "postgres".
Type string `json:"type"`
}
DBOption holds the configuration for the metadata database connection. Pass it as part of Options when constructing a caskin service via New.
type DictionaryOption ¶ added in v0.1.0
type Directory ¶ added in v0.1.0
type Directory struct {
Object
// AllDirectoryCount is the total number of directory nodes in the subtree.
AllDirectoryCount uint64 `json:"all_directory_count"`
// AllItemCount is the total number of leaf items in the subtree.
AllItemCount uint64 `json:"all_item_count"`
// TopDirectoryCount is the number of direct child directories.
TopDirectoryCount uint64 `json:"top_directory_count"`
// TopItemCount is the number of direct child items.
TopItemCount uint64 `json:"top_item_count"`
}
Directory decorates an Object with aggregate counts that describe the subtree rooted at that object.
type DirectoryRequest ¶ added in v0.1.0
type DirectoryRequest struct {
// To is the target parent object ID for move operations.
To uint64 `json:"to,omitempty"`
// ID is the list of object IDs to operate on.
ID []uint64 `json:"id,omitempty"`
// Type is the ObjectType filter.
Type string `json:"type,omitempty"`
// Policy is an optional policy filter string.
Policy string `json:"policy,omitempty"`
// SearchType controls the scope of the directory traversal;
// see [DirectorySearchAll] and [DirectorySearchTop].
SearchType string `json:"search_type,omitempty"`
// CountDirectory is an optional callback that returns per-directory item counts.
CountDirectory func([]uint64) (map[uint64]uint64, error)
// ActionDirectory is an optional callback that performs a side effect on a set of directories.
ActionDirectory func([]uint64) error
}
DirectoryRequest is the parameter bag for directory operations such as IDirectoryService.GetDirectory, IDirectoryService.MoveDirectory, and IDirectoryService.DeleteDirectory.
type DirectoryResponse ¶ added in v0.1.0
type DirectoryResponse struct {
// DoneDirectoryCount is the number of directories already at the destination.
DoneDirectoryCount uint64 `json:"done_directory_count,omitempty"`
// DoneItemCount is the number of items already at the destination.
DoneItemCount uint64 `json:"done_item_count,omitempty"`
// ToDoDirectoryCount is the number of directories moved/copied.
ToDoDirectoryCount uint64 `json:"to_do_directory_count,omitempty"`
// ToDoItemCount is the number of items moved/copied.
ToDoItemCount uint64 `json:"to_do_item_count,omitempty"`
}
DirectoryResponse summarises the outcome of a directory move or copy operation, reporting how many directories and items were already at the destination ("done") versus still pending ("to-do").
type DirectorySearchType ¶ added in v0.1.0
type DirectorySearchType = string
DirectorySearchType specifies the scope of a directory search. Use DirectorySearchAll to include all descendants, or DirectorySearchTop to include only direct children.
const ( // DirectorySearchAll traverses the entire subtree rooted at the given node. DirectorySearchAll DirectorySearchType = "all" // DirectorySearchTop returns only the direct children of the given node. DirectorySearchTop DirectorySearchType = "top" )
type Domain ¶
type Domain interface {
// contains filtered or unexported methods
}
Domain represents an isolated permission scope such as a tenant or organization. Implementations must provide an integer ID and a string encoding used as the casbin domain token.
func GetSuperadminDomain ¶ added in v0.1.0
func GetSuperadminDomain() Domain
GetSuperadminDomain returns a Domain that encodes to the SuperadminDomain constant. It is used internally alongside GetSuperadminRole for superadmin enforcement.
type EdgeSorter ¶ added in v0.1.0
EdgeSorter maps node values to their topological sort order. It is used to sort slices of InheritanceEdge so that root nodes come first (EdgeSorter.RootFirstSort) or leaf nodes come first (EdgeSorter.LeafFirstSort).
func NewEdgeSorter ¶ added in v0.1.0
func NewEdgeSorter[T cmp.Ordered](order []T) EdgeSorter[T]
NewEdgeSorter builds an EdgeSorter from a topological ordering of node values. Nodes that appear earlier in order are considered closer to the root.
func (EdgeSorter[T]) LeafFirstSort ¶ added in v0.1.0
func (e EdgeSorter[T]) LeafFirstSort(edges []*InheritanceEdge[T])
LeafFirstSort sorts edges so that edges whose destination (V) is closer to the leaves of the graph come first. This is useful for processing children before their parents (e.g. when deleting a subtree).
func (EdgeSorter[T]) RootFirstSort ¶ added in v0.1.0
func (e EdgeSorter[T]) RootFirstSort(edges []*InheritanceEdge[T])
RootFirstSort sorts edges so that edges whose source (U) is closer to the root of the graph come first. This is useful for processing parent nodes before their children.
type Factory ¶ added in v0.1.0
type Factory interface {
// User decodes a casbin subject string into a User.
User(string) (User, error)
// Role decodes a casbin role string into a Role.
Role(string) (Role, error)
// Object decodes a casbin object string into an Object.
Object(string) (Object, error)
// Domain decodes a casbin domain string into a Domain.
Domain(string) (Domain, error)
// NewUser returns a zero-value User of the registered concrete type.
NewUser() User
// NewRole returns a zero-value Role of the registered concrete type.
NewRole() Role
// NewObject returns a zero-value Object of the registered concrete type.
NewObject() Object
// NewDomain returns a zero-value Domain of the registered concrete type.
NewDomain() Domain
// MetadataDB wraps the given GORM database with the registered type
// information and returns a [MetaDB] implementation.
MetadataDB(db *gorm.DB) MetaDB
}
Factory is the type registry used by caskin to instantiate and decode concrete User, Role, Object, and Domain values from their string representations stored in casbin.
Call Register once at program startup with your concrete types, then use DefaultFactory to access the registered factory throughout your application.
type Feature ¶ added in v0.1.0
type Feature struct {
Name string `json:"name" toml:"name"`
Description string `json:"description" toml:"description"`
Group string `json:"group" toml:"group"`
}
Feature it is a package of Backend and Frontend
type Frontend ¶ added in v0.1.0
type Frontend struct {
Name string `json:"name" toml:"name"`
Type string `json:"type" toml:"type"`
Description string `json:"description" toml:"description"`
Group string `json:"group" toml:"group"`
}
Frontend it is for frontend web component
type IBaseService ¶ added in v0.1.0
type IBaseService interface {
// AddSuperadmin adds a superadmin user
AddSuperadmin(User) error
// DeleteSuperadmin deletes a superadmin user
DeleteSuperadmin(User) error
// GetSuperadmin gets all superadmin users
GetSuperadmin() ([]User, error)
// CreateUser creates a new user
CreateUser(User) error
// RecoverUser recovers a deleted user
RecoverUser(User) error
// DeleteUser deletes a user
DeleteUser(User) error
// UpdateUser updates a user
UpdateUser(User) error
// CreateDomain creates a new domain
CreateDomain(Domain) error
// RecoverDomain recovers a deleted domain
RecoverDomain(Domain) error
// DeleteDomain deletes a domain
DeleteDomain(Domain) error
// UpdateDomain updates a domain
UpdateDomain(Domain) error
// GetDomain gets all domains
GetDomain() ([]Domain, error)
// ResetDomain resets a domain to its initial state
ResetDomain(Domain) error
// CreateObject creates a new object in a domain
CreateObject(User, Domain, Object) error
// RecoverObject recovers a deleted object in a domain
RecoverObject(User, Domain, Object) error
// DeleteObject deletes an object in a domain
DeleteObject(User, Domain, Object) error
// UpdateObject updates an object in a domain
UpdateObject(User, Domain, Object) error
// GetObject gets all objects in a domain that the user can perform an action on
GetObject(User, Domain, Action, ...ObjectType) ([]Object, error)
// GetObjectHierarchyLevel gets the hierarchy level of an object in a domain
GetObjectHierarchyLevel(user User, domain Domain, object Object) (int, error)
// CreateRole creates a new role in a domain
CreateRole(User, Domain, Role) error
// RecoverRole recovers a deleted role in a domain
RecoverRole(User, Domain, Role) error
// DeleteRole deletes a role in a domain
DeleteRole(User, Domain, Role) error
// UpdateRole updates a role in a domain
UpdateRole(User, Domain, Role) error
// GetRole gets all roles in a domain
GetRole(User, Domain) ([]Role, error)
// AddUserRole adds user-role pairs in a domain
AddUserRole(User, Domain, []*UserRolePair) error
// RemoveUserRole removes user-role pairs in a domain
RemoveUserRole(User, Domain, []*UserRolePair) error
// AddRoleG adds a role inheritance relation in a domain
AddRoleG(User, Domain, Role, Role) error
// RemoveRoleG removes a role inheritance relation in a domain
RemoveRoleG(User, Domain, Role, Role) error
// GetUserByDomain gets all users in a domain
GetUserByDomain(Domain) ([]User, error)
// GetDomainByUser gets all domains that a user belongs to
GetDomainByUser(User) ([]Domain, error)
// GetUserRole gets all user-role pairs in a domain
GetUserRole(User, Domain) ([]*UserRolePair, error)
// GetUserRoleByUser gets all user-role pairs in a domain for a specific user
GetUserRoleByUser(User, Domain, User) ([]*UserRolePair, error)
// GetUserRoleByRole gets all user-role pairs in a domain for a specific role
GetUserRoleByRole(User, Domain, Role) ([]*UserRolePair, error)
// ModifyUserRolePerUser modifies the user-role pairs in a domain for a specific user
ModifyUserRolePerUser(User, Domain, User, []*UserRolePair) error
// ModifyUserRolePerRole modifies the user-role pairs in a domain for a specific role
ModifyUserRolePerRole(User, Domain, Role, []*UserRolePair) error
// GetPolicy gets all policies in a domain
GetPolicy(User, Domain) ([]*Policy, error)
// GetPolicyByRole gets all policies in a domain for a specific role
GetPolicyByRole(User, Domain, Role) ([]*Policy, error)
// ModifyPolicyPerRole modifies the policies in a domain for a specific role
ModifyPolicyPerRole(User, Domain, Role, []*Policy) error
// CreateObjectData creates a new object data in a domain with an object type
CreateObjectData(User, Domain, ObjectData, ObjectType) error
// RecoverObjectData recovers a deleted object data in a domain
RecoverObjectData(User, Domain, ObjectData) error
// DeleteObjectData deletes an object data in a domain
DeleteObjectData(User, Domain, ObjectData) error
// UpdateObjectData updates an object data in a domain with an object type
UpdateObjectData(User, Domain, ObjectData, ObjectType) error
// CheckCreateObjectData checks if the user can create an object data in a domain with an object type
CheckCreateObjectData(User, Domain, ObjectData, ObjectType) error
// CheckRecoverObjectData checks if the user can recover an object data in a domain
CheckRecoverObjectData(User, Domain, ObjectData) error
// CheckDeleteObjectData checks if the user can delete an object data in a domain
CheckDeleteObjectData(User, Domain, ObjectData) error
// CheckWriteObjectData checks if the user can write an object data in a domain with an object type
CheckWriteObjectData(User, Domain, ObjectData, ObjectType) error
// CheckUpdateObjectData checks if the user can update an object data in a domain with an object type
CheckUpdateObjectData(User, Domain, ObjectData, ObjectType) error
// CheckModifyObjectData checks if the user can modify an object data in a domain
CheckModifyObjectData(User, Domain, ObjectData) error
// CheckGetObjectData checks if the user can get an object data in a domain
CheckGetObjectData(User, Domain, ObjectData) error
}
IBaseService is the interface that defines the basic CRUD operations for users, domains, objects and roles
type ICreatorDictionary ¶ added in v0.1.0
type ICreatorDictionary interface {
// GetCreatorObject returns the object templates to seed into a new domain.
GetCreatorObject() ([]*CreatorObject, error)
// GetCreatorRole returns the role templates to seed into a new domain.
GetCreatorRole() ([]*CreatorRole, error)
// GetCreatorPolicy returns the policy templates to seed into a new domain.
GetCreatorPolicy() ([]*CreatorPolicy, error)
}
ICreatorDictionary provides the seed data used to initialise a new domain. When IBaseService.CreateDomain is called, these objects, roles, and policies are created automatically.
type ICurrentService ¶ added in v0.1.0
type ICurrentService interface {
// SetCurrent sets the current user and domain for the service and returns a new service instance
SetCurrent(User, Domain) IService
// CreateObjectDataWithCurrent creates a new object data in the current domain with an object type
CreateObjectDataWithCurrent(ObjectData, ObjectType) error
// RecoverObjectDataWithCurrent recovers a deleted object data in the current domain
RecoverObjectDataWithCurrent(ObjectData) error
// DeleteObjectDataWithCurrent deletes an object data in the current domain
DeleteObjectDataWithCurrent(ObjectData) error
// UpdateObjectDataWithCurrent updates an object data in the current domain with an object type
UpdateObjectDataWithCurrent(ObjectData, ObjectType) error
// CheckCreateObjectDataWithCurrent checks if the current user can create an object data in the current domain with an object type
CheckCreateObjectDataWithCurrent(ObjectData, ObjectType) error
// CheckRecoverObjectDataWithCurrent checks if the current user can recover an object data in the current domain
CheckRecoverObjectDataWithCurrent(ObjectData) error
// CheckDeleteObjectDataWithCurrent checks if the current user can delete an object data in the current domain
CheckDeleteObjectDataWithCurrent(ObjectData) error
// CheckWriteObjectDataWithCurrent checks if the current user can write an object data in the current domain with an object type
CheckWriteObjectDataWithCurrent(ObjectData, ObjectType) error
// CheckUpdateObjectDataWithCurrent checks if the current user can update an object data in the current domain with an object type
CheckUpdateObjectDataWithCurrent(ObjectData, ObjectType) error
// CheckModifyObjectDataWithCurrent checks if the current user can modify an object data in the current domain
CheckModifyObjectDataWithCurrent(ObjectData) error
// CheckGetObjectDataWithCurrent checks if the current user can get an object data in the current domain
CheckGetObjectDataWithCurrent(ObjectData) error
}
ICurrentService is the interface that defines the current user-related operations
type IDictionary ¶ added in v0.1.0
type IDictionary interface {
IFeatureDictionary
ICreatorDictionary
}
IDictionary combines the feature dictionary and the creator dictionary into a single interface. Implementations provide the static configuration for features (backends, frontends) and the seed data for creator objects, roles, and policies.
func NewDictionary ¶ added in v0.1.0
func NewDictionary(option *DictionaryOption) (IDictionary, error)
type IDirectory ¶ added in v0.1.0
type IDirectory interface {
Search(uint64, DirectorySearchType) []*Directory
}
IDirectory is the interface for directory search backends. It returns the list of Directory nodes reachable from the given root ID according to the specified DirectorySearchType.
type IDirectoryService ¶ added in v0.1.0
type IDirectoryService interface {
// CreateDirectory creates a new directory for an object in a domain
CreateDirectory(User, Domain, Object) error
// UpdateDirectory updates an existing directory for an object in a domain
UpdateDirectory(User, Domain, Object) error
// DeleteDirectory deletes a directory and its subdirectories in a domain based on a request
DeleteDirectory(User, Domain, *DirectoryRequest) error
// GetDirectory gets all directories and their subdirectories in a domain based on a request
GetDirectory(User, Domain, *DirectoryRequest) ([]*Directory, error)
// MoveDirectory moves a directory and its subdirectories to another directory in a domain based on a request and returns the updated directory structure
MoveDirectory(User, Domain, *DirectoryRequest) (*DirectoryResponse, error)
// MoveItem moves an object data to another directory in a domain based on a request and returns the updated directory structure
MoveItem(User, Domain, ObjectData, *DirectoryRequest) (*DirectoryResponse, error)
// CopyItem copies an object data to another directory in a domain based on a request and returns the updated directory structure
CopyItem(User, Domain, ObjectData, *DirectoryRequest) (*DirectoryResponse, error)
}
IDirectoryService is the interface that defines the directory-related operations for objects and object data
type IEnforcer ¶
type IEnforcer interface {
// Enforce checks whether user u can perform action on object o within domain d.
Enforce(User, Object, Domain, Action) (bool, error)
// EnforceRole checks whether son inherits from parent within domain.
EnforceRole(son Role, parent Role, domain Domain) (bool, error)
// EnforceObject checks whether son is a descendant of parent within domain.
EnforceObject(son Object, parent Object, domain Domain) (bool, error)
// IsSuperadmin returns true if user is a global superadmin.
IsSuperadmin(User) (bool, error)
// GetDomainsIncludeUser returns every domain the user belongs to.
GetDomainsIncludeUser(User) []Domain
// GetRolesForUserInDomain returns the roles directly assigned to user in domain.
GetRolesForUserInDomain(User, Domain) []Role
// GetUsersForRoleInDomain returns the users that have role in domain.
GetUsersForRoleInDomain(Role, Domain) []User
// GetParentsForRoleInDomain returns the parent roles of role in domain.
GetParentsForRoleInDomain(Role, Domain) []Role
// GetChildrenForRoleInDomain returns the child roles of role in domain.
GetChildrenForRoleInDomain(Role, Domain) []Role
// GetParentsForObjectInDomain returns the parent objects of object in domain.
GetParentsForObjectInDomain(Object, Domain) []Object
// GetChildrenForObjectInDomain returns the child objects of object in domain.
GetChildrenForObjectInDomain(Object, Domain) []Object
// GetPoliciesForRoleInDomain returns all policies granted to role in domain.
GetPoliciesForRoleInDomain(Role, Domain) []*Policy
// GetPoliciesForObjectInDomain returns all policies that reference object in domain.
GetPoliciesForObjectInDomain(Object, Domain) []*Policy
// RemoveUserInDomain removes all role assignments for user within domain.
RemoveUserInDomain(User, Domain) error
// RemoveRoleInDomain removes all policies, inheritance edges, and user
// assignments associated with role within domain.
RemoveRoleInDomain(Role, Domain) error
// RemoveObjectInDomain removes all policies and hierarchy edges associated
// with object within domain.
RemoveObjectInDomain(Object, Domain) error
// AddPolicyInDomain grants role the given action on object within domain.
AddPolicyInDomain(Role, Object, Domain, Action) error
// RemovePolicyInDomain revokes role's action on object within domain.
RemovePolicyInDomain(Role, Object, Domain, Action) error
// AddRoleForUserInDomain assigns role to user within domain.
AddRoleForUserInDomain(User, Role, Domain) error
// RemoveRoleForUserInDomain unassigns role from user within domain.
RemoveRoleForUserInDomain(User, Role, Domain) error
// AddParentForRoleInDomain makes son inherit from parent within domain.
AddParentForRoleInDomain(Role, Role, Domain) error
// RemoveParentForRoleInDomain removes the son→parent inheritance in domain.
RemoveParentForRoleInDomain(Role, Role, Domain) error
// AddParentForObjectInDomain makes son a child of parent within domain.
AddParentForObjectInDomain(Object, Object, Domain) error
// RemoveParentForObjectInDomain removes the son→parent object edge in domain.
RemoveParentForObjectInDomain(Object, Object, Domain) error
// GetUsersInDomain returns all users that have any role in domain.
GetUsersInDomain(Domain) []User
// GetRolesInDomain returns all roles defined in domain.
GetRolesInDomain(Domain) []Role
// GetObjectsInDomain returns all objects defined in domain.
GetObjectsInDomain(Domain) []Object
// GetPoliciesInDomain returns all policies defined in domain.
GetPoliciesInDomain(Domain) []*Policy
// RemoveUsersInDomain removes all user→role assignments within domain,
// effectively clearing the domain's user membership.
RemoveUsersInDomain(Domain) error
}
IEnforcer is the caskin-internal interface that wraps casbin's enforcer with domain-aware, strongly-typed methods. All parameters and return values use the caskin domain model types (User, Role, Object, Domain, Action, Policy) rather than raw strings.
Obtain an IEnforcer via NewEnforcer.
func GetEnforcer ¶ added in v0.3.0
GetEnforcer extracts the IEnforcer from an IService instance created by New. Returns the enforcer and true on success, or nil and false if s is not a *server.
type IFeatureDictionary ¶ added in v0.1.0
type IFeatureDictionary interface {
// GetFeature returns all registered features.
GetFeature() ([]*Feature, error)
// GetBackend returns all registered backend permission guards.
GetBackend() ([]*Backend, error)
// GetFrontend returns all registered frontend permission guards.
GetFrontend() ([]*Frontend, error)
// GetFeatureByKey looks up a feature by its unique key.
GetFeatureByKey(key string) (*Feature, error)
// GetBackendByKey looks up a backend guard by its unique key.
GetBackendByKey(key string) (*Backend, error)
// GetFrontendByKey looks up a frontend guard by its unique key.
GetFrontendByKey(key string) (*Frontend, error)
// GetPackage returns all feature packages (bundles of features).
GetPackage() ([]*Package, error)
}
IFeatureDictionary provides read access to the feature registry that defines available backends (API endpoints) and frontend (UI element) guards.
type IFeatureService ¶ added in v0.1.0
type IFeatureService interface {
// AuthBackend authenticates a user for a backend in a domain
AuthBackend(User, Domain, *Backend) error
// AuthFrontend authenticates a user for frontends in a domain
AuthFrontend(User, Domain) []*Frontend
// GetFeature gets all features in a domain
GetFeature(User, Domain) ([]*Feature, error)
// GetFeaturePolicy gets all feature policies in a domain
GetFeaturePolicy(User, Domain) ([]*Policy, error)
// GetFeaturePolicyByRole gets all feature policies in a domain for a specific role
GetFeaturePolicyByRole(User, Domain, Role) ([]*Policy, error)
// ModifyFeaturePolicyPerRole modifies the feature policies in a domain for a specific role
ModifyFeaturePolicyPerRole(User, Domain, Role, []*Policy) error
// ResetFeature resets the features in a domain to their initial state
ResetFeature(Domain) error
}
IFeatureService is the interface that defines the feature-related operations for backends, frontends and policies
type IService ¶ added in v0.1.0
type IService interface {
IBaseService // basic CRUD operations for users, domains, objects and roles
IDirectoryService // directory-related operations for objects and object data
IFeatureService // feature-related operations for backends, frontends and policies
ICurrentService // current user-related operations
}
IService is the interface that defines all the methods for caskin service
type InheritanceEdge ¶ added in v0.1.0
InheritanceEdge represents a directed edge in an inheritance graph where U is the parent node and V is the child node. It is used to serialise role/object hierarchy edges for storage and comparison.
func (*InheritanceEdge[T]) Decode ¶ added in v0.1.0
func (i *InheritanceEdge[T]) Decode(in string) error
Decode parses a JSON string produced by InheritanceEdge.Encode back into the edge struct.
func (*InheritanceEdge[T]) Encode ¶ added in v0.1.0
func (i *InheritanceEdge[T]) Encode(u, v T) string
Encode stores the (u, v) pair and returns the JSON string representation.
type InheritanceGraph ¶ added in v0.1.0
InheritanceGraph is an adjacency list representation of a directed graph where each key is a node and the associated slice contains its direct children (nodes it inherits into).
func MergeInheritanceGraph ¶ added in v0.1.0
func MergeInheritanceGraph[T cmp.Ordered](graphs ...InheritanceGraph[T]) InheritanceGraph[T]
MergeInheritanceGraph merges multiple InheritanceGraph values into one, deduplicating adjacency entries and sorting the result. This is useful when combining role/object inheritance rules from multiple sources.
func (InheritanceGraph[T]) Sort ¶ added in v0.1.0
func (g InheritanceGraph[T]) Sort() InheritanceGraph[T]
Sort returns a new InheritanceGraph where the keys and each adjacency list are sorted, making the graph representation deterministic.
func (InheritanceGraph[T]) TopSort ¶ added in v0.1.0
func (g InheritanceGraph[T]) TopSort() []T
TopSort performs a topological sort (Kahn's algorithm / BFS) on the graph and returns the nodes in an order where every parent appears before all of its children. The graph must be a DAG; cycles will cause nodes to be omitted from the result.
type MetaDB ¶
type MetaDB interface {
// Create inserts a new record. The entity must not already exist (not
// soft-deleted). Returns [ErrAlreadyExists] if a live record is found.
Create(any) error
// Recover undeletes a soft-deleted record. Returns [ErrNotExists] if no
// deleted record is found.
Recover(any) error
// Update saves changes to an existing record.
Update(any) error
// UpsertType determines whether the next Upsert will create, recover, or
// update; it does not perform any write itself.
UpsertType(any) UpsertType
// Take loads a single live (not soft-deleted) record by primary key.
Take(any) error
// TakeUnscoped loads a single record regardless of soft-delete status.
TakeUnscoped(any) error
// Find loads all matching records into the destination slice, with optional
// filter conditions forwarded to the underlying ORM.
Find(any, ...any) error
// DeleteByID soft-deletes the record of the given type with the specified ID.
DeleteByID(any, uint64) error
// GetUserByID fetches [User] records for the given IDs.
GetUserByID([]uint64) ([]User, error)
// GetRoleInDomain fetches all [Role] records that belong to the given domain.
GetRoleInDomain(Domain) ([]Role, error)
// GetRoleByID fetches [Role] records for the given IDs.
GetRoleByID([]uint64) ([]Role, error)
// GetObjectInDomain fetches all [Object] records in the given domain,
// optionally filtered by one or more [ObjectType] values.
GetObjectInDomain(Domain, ...ObjectType) ([]Object, error)
// GetObjectByID fetches [Object] records for the given IDs.
GetObjectByID([]uint64) ([]Object, error)
// GetDomainByID fetches [Domain] records for the given IDs.
GetDomainByID([]uint64) ([]Domain, error)
// GetAllDomain fetches every [Domain] record in the database.
GetAllDomain() ([]Domain, error)
}
MetaDB is the storage abstraction used by caskin to persist Users, Roles, Objects, Domains, and ObjectData. Provide a concrete implementation (or use the built-in GORM-backed one via Register) to connect caskin to your database.
The interface deliberately remains generic (operating on any) for Create, Recover, Update, and similar operations so that it can handle all entity types without requiring separate methods per type.
type NamedObject ¶ added in v0.1.0
type NamedObject struct {
Name string `json:"name"`
}
NamedObject is the built-in Object implementation used for special objects such as the superadmin sentinel. Its Encode/Decode methods simply use the Name string, so it can represent objects that exist only in casbin policy strings without corresponding database rows.
func (*NamedObject) Decode ¶ added in v0.1.0
func (o *NamedObject) Decode(code string) error
func (*NamedObject) Encode ¶ added in v0.1.0
func (o *NamedObject) Encode() string
func (*NamedObject) GetDomainID ¶ added in v0.1.0
func (o *NamedObject) GetDomainID() uint64
func (*NamedObject) GetID ¶ added in v0.1.0
func (o *NamedObject) GetID() uint64
func (*NamedObject) GetObjectType ¶ added in v0.1.0
func (o *NamedObject) GetObjectType() string
func (*NamedObject) GetParentID ¶ added in v0.1.0
func (o *NamedObject) GetParentID() uint64
func (*NamedObject) SetDomainID ¶ added in v0.1.0
func (o *NamedObject) SetDomainID(uint64)
func (*NamedObject) SetID ¶ added in v0.1.0
func (o *NamedObject) SetID(uint64)
func (*NamedObject) SetParentID ¶ added in v0.1.0
func (o *NamedObject) SetParentID(uint64)
type Object ¶
type Object interface {
// GetObjectType returns the type tag for this object (e.g. "menu").
GetObjectType() string
// contains filtered or unexported methods
}
Object represents a resource in the permission system. Objects are arranged in a tree: each object may have a parent ([parentInterface]). A user's read/write/manage access to a child object is implicitly determined by the policy set on any ancestor.
type ObjectChildrenGetFunc ¶ added in v0.1.0
type ObjectData ¶
type ObjectData interface {
// GetObjectID returns the ID of the protecting Object.
GetObjectID() uint64
// SetObjectID sets the ID of the protecting Object.
SetObjectID(uint64)
// contains filtered or unexported methods
}
ObjectData represents a domain-specific data record that is protected by an Object. For example, a "document" entity might be protected by a "documents" object. Permission checks are done via the associated object.
type ObjectDeleteFunc ¶ added in v0.1.0
type ObjectParentAddFunc ¶ added in v0.1.0
type ObjectParentDelFunc ¶ added in v0.1.0
type ObjectParentGetFunc ¶ added in v0.1.0
type ObjectType ¶
type ObjectType = string
ObjectType is a string tag that categorises objects (e.g. "role", "menu", "api"). It is used to look up the correct GORM model when performing object-data operations.
const ( // ObjectTypeRole is the built-in ObjectType for Role objects. // Roles are stored as ObjectData with this type. ObjectTypeRole ObjectType = "role" )
type Option ¶
type Option func(*Options)
Option is a functional option that mutates an Options struct. Pass one or more Options to New to customise the service.
type Options ¶
type Options struct {
// DefaultSuperadminDomainName overrides the built-in superadmin domain name
// (default: "superadmin_domain"). Must match the name used in the database.
DefaultSuperadminDomainName string `json:"default_superadmin_domain_name"`
// DefaultSuperadminRoleName overrides the built-in superadmin role name
// (default: "superadmin_role"). Must match the name stored in casbin.
DefaultSuperadminRoleName string `json:"default_superadmin_role_name"`
// Dictionary configures the feature/creator dictionary backend. If nil,
// an empty in-memory dictionary is used.
Dictionary *DictionaryOption `json:"dictionary"`
// DB configures the metadata database connection.
DB *DBOption `json:"db"`
// Watcher configures the optional casbin policy watcher (e.g. Redis).
// When nil, no watcher is set up.
Watcher *WatcherOption `json:"watcher"`
}
Options holds the configuration for creating a caskin IService via New.
type Package ¶ added in v0.1.0
type Policy ¶
type Policy struct {
Role Role `json:"role"`
Object Object `json:"object"`
Domain Domain `json:"domain"`
Action Action `json:"action"`
}
Policy is a 4-tuple of (Role, Object, Domain, Action) that grants the role permission to perform the action on the object within the domain.
func DiffPolicy ¶
DiffPolicy diff policy source, target list to get add, remove list
func (*Policy) Key ¶
Key returns a stable string that uniquely identifies this policy tuple. It is used internally for set-difference operations (e.g. DiffPolicy).
type Role ¶
type Role interface {
ObjectData
// contains filtered or unexported methods
}
Role represents a named permission bundle within a domain. Roles are also ObjectData, meaning they belong to an object type and can be organised in a hierarchy via IBaseService.AddRoleG.
func GetSuperadminRole ¶ added in v0.1.0
func GetSuperadminRole() Role
GetSuperadminRole returns a Role that encodes to the SuperadminRole constant. It is used internally when granting or checking superadmin status.
type SampleSuperadminDomain ¶ added in v0.1.0
SampleSuperadminDomain is the built-in Domain that represents the superadmin scope. Its Encode method always returns SuperadminDomain and Decode accepts only that value.
func (*SampleSuperadminDomain) Decode ¶ added in v0.1.0
func (s *SampleSuperadminDomain) Decode(code string) error
func (*SampleSuperadminDomain) Encode ¶ added in v0.1.0
func (s *SampleSuperadminDomain) Encode() string
func (*SampleSuperadminDomain) GetID ¶ added in v0.1.0
func (s *SampleSuperadminDomain) GetID() uint64
func (*SampleSuperadminDomain) SetID ¶ added in v0.1.0
func (s *SampleSuperadminDomain) SetID(uint64)
type SampleSuperadminRole ¶
SampleSuperadminRole is the built-in Role that identifies the global superadmin. Its Encode method always returns the SuperadminRole constant and Decode accepts only that value, returning ErrIsNotSuperadmin otherwise.
func (*SampleSuperadminRole) Decode ¶
func (s *SampleSuperadminRole) Decode(code string) error
func (*SampleSuperadminRole) Encode ¶
func (s *SampleSuperadminRole) Encode() string
func (*SampleSuperadminRole) GetDomainID ¶
func (s *SampleSuperadminRole) GetDomainID() uint64
func (*SampleSuperadminRole) GetID ¶
func (s *SampleSuperadminRole) GetID() uint64
func (*SampleSuperadminRole) GetObjectID ¶ added in v0.1.0
func (s *SampleSuperadminRole) GetObjectID() uint64
func (*SampleSuperadminRole) SetDomainID ¶
func (s *SampleSuperadminRole) SetDomainID(uint64)
func (*SampleSuperadminRole) SetID ¶
func (s *SampleSuperadminRole) SetID(uint64)
func (*SampleSuperadminRole) SetObjectID ¶
func (s *SampleSuperadminRole) SetObjectID(uint64)
type UpsertType ¶
type UpsertType string
UpsertType describes the outcome of a database upsert operation performed by MetaDB. See UpsertTypeCreate, UpsertTypeRecover, and UpsertTypeUpdate for the possible values.
const ( // UpsertTypeCreate indicates the upsert operation created a new record. UpsertTypeCreate UpsertType = "create" // UpsertTypeRecover indicates the upsert operation recovered a soft-deleted record. UpsertTypeRecover UpsertType = "recover" // UpsertTypeUpdate indicates the upsert operation updated an existing record. UpsertTypeUpdate UpsertType = "update" )
type User ¶
type User interface {
// contains filtered or unexported methods
}
User represents an actor in the permission system. Implementations must provide an integer ID ([idInterface]) and a string encoding ([codeInterface]) used as the casbin subject.
type UserRolePair ¶
UserRolePair binds a user to a role. It is the unit used in IBaseService.AddUserRole and related methods.
type WatcherOption ¶ added in v0.2.0
type WatcherOption struct {
// Type selects the watcher backend. Currently "redis" is supported.
// An empty or unrecognised type falls back to auto-load polling when
// AutoLoad > 0.
Type string `json:"type"`
// Address is the host:port of the watcher backend (e.g. "localhost:6379").
Address string `json:"address"`
// Password is the authentication password for the watcher backend.
Password string `json:"password"`
// Channel is the pub/sub channel name used by the Redis watcher.
Channel string `json:"channel"`
// AutoLoad, when > 0 and Type is not "redis", sets the interval in
// seconds for the enforcer's built-in StartAutoLoadPolicy poller.
AutoLoad int64 `json:"auto_load"`
}
WatcherOption configures an optional casbin policy watcher that keeps multiple enforcer instances in sync when the policy changes.
Source Files
¶
- casbin.go
- constant.go
- dictionary.go
- dictionary_adaptor.go
- dictionary_model.go
- doc.go
- error.go
- inheritance.go
- metadata.go
- metadata_database.go
- metadata_imp.go
- object_deleter.go
- object_directory.go
- object_updater.go
- options.go
- register.go
- schema.go
- schema_buildin.go
- schema_private.go
- server.go
- server_check.go
- server_current.go
- server_directory.go
- server_domain.go
- server_domain_reset.go
- server_feature.go
- server_feature_reset.go
- server_object.go
- server_object_data.go
- server_policy.go
- server_role.go
- server_role_g.go
- server_superadmin.go
- server_user.go
- server_user_domain.go
- server_user_role.go
- service.go