README ¶
gocbac
Simple Golang Content Based Access Control system
Usage
// declare types
type Access string
type Content uint64
type User string
// declare accesses
const (
AccessCanView Access = "can_view"
AccessCanEdit Access = "can_edit"
AccessCanDelete Access = "can_delete"
)
// declare setter
func policiesSetter(
ContentList []Content,
User User,
RequestedAccesses []Access,
) (AccessSetter[Access, Content], error) {
// do content preparation for the list content, users and accesses (e.g. DB queries etc)
contentPublic := map[Content]bool{
1: true,
}
contentOwners := map[Content]string{
1: "foo@bar.com",
2: "bar@foo.com",
}
// then fill the access depending on the content
return func(Content Content, access Access) bool {
switch access {
case AccessCanView:
if _, ok := contentPublic[Content]; ok {
return true
} else if user, ok := contentOwners[Content]; ok {
return owner == User;
}
return false
case AccessCanEdit, AccessCanDelete:
if user, ok := contentOwners[Content]; ok {
return owner == User;
}
return false
}
}, nil
}
func main() {
// init cbac
var cbac = InitCBAC(
policiesSetter,
AccessCanView,
AccessCanEdit,
AccessCanDelete,
)
// use it
// by list
policies, err := cbac.GetPolicies([]Content{1, 2}, "foo@bar.com")
if err != nil {
// error handling
}
for _, policy := range policies {
if policy[AccessCanView] {
// do something
}
}
// by policy
policy, err := cbac.GetPolicy([]Content{1, 2}, "foo@bar.com", AccessCanView, AccessCanEdit)
if err != nil {
// error handling
}
if policy[AccessCanView] || policy[AccessCanEdit] {
// do something
}
// by access
has, err := cbac.GetAccess(1, "foo@bar.com", AccessCanView)
if err != nil {
// error handling
}
if has {
// user has AccessCanView access to the content
} else {
// otherwise
}
}
Documentation ¶
Index ¶
Constants ¶
This section is empty.
Variables ¶
var ( ErrNoContent = errors.New("no such content") ErrNoAccess = errors.New("no such access") )
Possible errors ErrNoContent in case there is no such content in the policy ErrNoAccess in case there is no such access in the policy(s)
Functions ¶
func MapFill ¶
func MapFill[M ~map[K]V, K comparable, V any](dict M, keys []K, val V) M
fill map with same values
func SliceToBoolMap ¶
func SliceToBoolMap[S ~[]K, K comparable](slice S) map[K]bool
convert slice to the map where each element of a slice is the key and values is bool
Types ¶
type AccessSetter ¶
type AccessSetter[A, C comparable] func(content C, access A) bool
PoliciesSetter function which populates policies for the list of content, error will be passed to the executor (e.g. GetPolicies) AccessSetter function which populates access for the peace of content
type CBAC ¶
type CBAC[A, C comparable, O any] interface { GetPolicies(ContentList []C, On O, Accesses ...A) (Policies[A, C], error) GetPolicy(Content C, On O, Accesses ...A) (Policy[A], error) GetAccess(Content C, On O, Access A) (bool, error) }
GetPolicies get the list of policies for the list of content on On instance (optionally for the list of accesses) GetPolicy get the policy for the content on On instance (optionally for the list of accesses) GetAccess get the access for the content on On instance for the specific access
func InitCBAC ¶
func InitCBAC[A, C comparable, O any](Setter PoliciesSetter[A, C, O], Accesses ...A) CBAC[A, C, O]
Init CBAC where: A - type of access C - type of content O - type of instance of which access should be checked Setter - policies setter function Accesses - list of needed accesses
type Policies ¶
type Policies[A comparable, C comparable] map[C]Policy[A]
type PoliciesSetter ¶
type PoliciesSetter[A, C comparable, O any] func(ContentList []C, On O, requestedAccesses []A) (AccessSetter[A, C], error)
PoliciesSetter function which populates policies for the list of content, error will be passed to the executor (e.g. GetPolicies) AccessSetter function which populates access for the peace of content
type Policy ¶
type Policy[A comparable] map[A]bool
policy is the simple map of accesses and their bool values