Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add "rank" and "description" fields for roles #1

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
13 changes: 9 additions & 4 deletions rbac.go
Expand Up @@ -17,6 +17,7 @@ Thus, RBAC has the following model:
package gorbac

import (
"strconv"
"sync"
)

Expand Down Expand Up @@ -57,7 +58,7 @@ func New() *Rbac {
func RestoreWithFactory(data Map, factory RoleFactoryFunc) *Rbac {
rbac := NewWithFactory(factory)
for role, value := range data {
rbac.Add(role, value[PermissionKey], value[ParentKey])
rbac.Add(value[RankKey].(int), role, value[PermissionKey].([]string), value[ParentKey].([]string), value[DescriptionKey].(string))
}
return rbac
}
Expand All @@ -70,11 +71,13 @@ func Restore(data Map) *Rbac {
// Set a role with `name`. It has `permissions` and `parents`.
// If the role is not existing, a new one will be created.
// This function will cover role's orignal permissions and parents.
func (rbac *Rbac) Set(name string, permissions []string, parents []string) {
func (rbac *Rbac) Set(rank int, name string, permissions, parents []string, description string) {
rbac.mutex.Lock()
defer rbac.mutex.Unlock()
role := rbac.getRole(name)
role.Reset()
role.AddRank(rank)
role.AddDescription(description)
for _, p := range permissions {
role.AddPermission(p)
}
Expand All @@ -87,10 +90,12 @@ func (rbac *Rbac) Set(name string, permissions []string, parents []string) {
// If the role is not existing, a new one will be created.
// This function will add new permissions and parents to the role,
// and keep orignals.
func (rbac *Rbac) Add(name string, permissions []string, parents []string) {
func (rbac *Rbac) Add(rank int, name string, permissions, parents []string, description string) {
rbac.mutex.Lock()
defer rbac.mutex.Unlock()
role := rbac.getRole(name)
role.AddRank(rank)
role.AddDescription(description)
for _, p := range permissions {
role.AddPermission(p)
}
Expand Down Expand Up @@ -146,7 +151,7 @@ func (rbac *Rbac) Dump() Map {
m := make(Map)
for _, role := range rbac.roles {
roleMap := RoleToMap(role)
m[role.Name()] = roleMap
m[strconv.Itoa(role.Rank())+role.Name()] = roleMap
}
return m
}
40 changes: 33 additions & 7 deletions role.go
@@ -1,30 +1,38 @@
package gorbac

const (
ParentKey = "parents"
PermissionKey = "permissions"
NameKey = "name"
ParentKey = "parents"
PermissionKey = "permissions"
NameKey = "name"
RankKey = "rank"
DescriptionKey = "description"
)

// Sometimes, a custom role structure is needed by projects.
// You should define your own role factory function for this purpuse.
type RoleFactoryFunc func(*Rbac, string) Role

// An exportable data structure
type RoleMap map[string][]string
type RoleMap map[string]interface{}

// An interface can't export directly. But you can convert it into a map.
func RoleToMap(role Role) RoleMap {
roleMap := make(RoleMap)
roleMap[PermissionKey] = role.Permissions()
roleMap[ParentKey] = role.Parents()
roleMap[NameKey] = []string{role.Name()}
roleMap[NameKey] = role.Name()
roleMap[RankKey] = role.Rank()
roleMap[DescriptionKey] = role.Description()
return roleMap
}

// Implement this interface for your own role structure.
type Role interface {
Rank() int
Name() string
Description() string
AddRank(int)
AddDescription(string)
AddPermission(string)
HasPermission(string) bool
RevokePermission(string)
Expand All @@ -47,13 +55,19 @@ func newBaseRole(rbac *Rbac, name string) Role {

type baseRole struct {
rbac *Rbac
rank int
name string
description string
permissions map[string]bool
parents map[string]bool
}

func (role *baseRole) Name() string {
return role.name
func (role *baseRole) AddRank(rank int) {
role.rank = rank
}

func (role *baseRole) AddDescription(description string) {
role.description = description
}

func (role *baseRole) AddPermission(permission string) {
Expand Down Expand Up @@ -108,3 +122,15 @@ func (role *baseRole) Parents() []string {
}
return result
}

func (role *baseRole) Rank() int {
return role.rank
}

func (role *baseRole) Name() string {
return role.name
}

func (role *baseRole) Description() string {
return role.description
}