wip: rbac - 01

This commit is contained in:
loveuer
2024-11-04 18:09:39 +08:00
parent cef1775811
commit 0fabeb69d6
8 changed files with 322 additions and 102 deletions

96
rbac/create.go Normal file
View File

@ -0,0 +1,96 @@
package rbac
import (
"context"
"fmt"
"github.com/samber/lo"
"strings"
"uauth/model"
)
func (u *Urbac) newScope(ctx context.Context, code, label, parent string) (*model.Scope, error) {
s := &model.Scope{Code: code, Label: label, Parent: parent}
if err := u.store.Session(ctx).Create(s).Error; err != nil {
return nil, err
}
return s, nil
}
func (u *Urbac) GetScopeGroup(ctx context.Context, name string) (*model.Scope, error) {
scope := new(model.Scope)
err := u.store.Session(ctx).Where("name = ?", name).Take(scope).Error
return scope, err
}
func (u *Urbac) newRole(ctx context.Context, code, label, parent string, privileges ...*model.Privilege) (*model.Role, error) {
ps := lo.FilterMap(
privileges,
func(p *model.Privilege, _ int) (string, bool) {
if p == nil {
return "", false
}
return p.Code, p.Code != ""
},
)
r := &model.Role{
Code: code,
Label: label,
Parent: parent,
PrivilegeCodes: ps,
}
if err := u.store.Session(ctx).Create(r).Error; err != nil {
return nil, err
}
return r, nil
}
func (u *Urbac) GetRole(ctx context.Context, name string) (*model.Role, error) {
var r model.Role
if err := u.store.Session(ctx).Take(&r, "name = ?", name).Error; err != nil {
return nil, err
}
return &r, nil
}
func (u *Urbac) newPrivilege(ctx context.Context, code, label string, parent string, scope string) (*model.Privilege, error) {
p := &model.Privilege{Code: code, Label: label, Parent: parent, Scope: scope}
codes := strings.SplitN(code, ":", 4)
if len(codes) != 4 {
return nil, fmt.Errorf("invalid code format")
}
wailcard := false
for _, item := range codes {
if item == "*" {
wailcard = true
}
if wailcard && item != "*" {
return nil, fmt.Errorf("invalid code format")
}
if len(item) > 8 {
return nil, fmt.Errorf("invalid code format: code snippet too long")
}
}
if codes[0] != "*" {
if _, err := u.GetScopeGroup(ctx, codes[0]); err != nil {
return nil, err
}
}
if err := u.store.Session(ctx).Create(p).Error; err != nil {
return nil, err
}
return p, nil
}

View File

@ -3,12 +3,16 @@ package rbac
import (
"fmt"
"strings"
"uauth/internal/interfaces"
"uauth/internal/store/cache"
"uauth/internal/store/db"
"uauth/internal/tool"
"uauth/model"
)
type Urbac struct {
cache cache.Cache
store store.Store
cache interfaces.Cacher
store interfaces.Store
}
type Option func(u *Urbac)
@ -17,9 +21,9 @@ func New(opts ...Option) (*Urbac, error) {
var (
err error
u = &Urbac{}
rootPrivilege *Privilege
rootRole *Role
rootScope *Scope
rootPrivilege *model.Privilege
rootRole *model.Role
rootScope *model.Scope
)
for _, opt := range opts {
@ -27,22 +31,18 @@ func New(opts ...Option) (*Urbac, error) {
}
if u.store == nil {
if u.store, err = store.NewSqliteStore("sqlite.db"); err != nil {
return nil, err
}
u.store = db.Default
}
if u.cache == nil {
if u.cache, err = cache.NewRedisCache("redis://10.220.10.15:6379"); err != nil {
return nil, err
}
u.cache = cache.Client
}
if err = u.store.Session(tool.Timeout()).AutoMigrate(&Scope{}, &Privilege{}, &Role{}); err != nil {
if err = u.store.Session(tool.Timeout()).AutoMigrate(&model.Scope{}, &model.Privilege{}, &model.Role{}); err != nil {
return nil, fmt.Errorf("urbac migrate err: %w", err)
}
if rootPrivilege, err = u.newPrivilege(tool.Timeout(), "*:*:*:*", "admin", 0, "*"); err != nil {
if rootPrivilege, err = u.newPrivilege(tool.Timeout(), "*:*:*:*", "admin", "", "*"); err != nil {
if !strings.Contains(strings.ToLower(err.Error()), "unique") {
return nil, err
}