111 lines
2.3 KiB
Go
111 lines
2.3 KiB
Go
|
package rbac
|
||
|
|
||
|
import (
|
||
|
"context"
|
||
|
"fmt"
|
||
|
"github.com/samber/lo"
|
||
|
"strings"
|
||
|
"uauth/model"
|
||
|
)
|
||
|
|
||
|
func (u *RBAC) 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 s, err
|
||
|
}
|
||
|
|
||
|
return s, nil
|
||
|
}
|
||
|
|
||
|
func (u *RBAC) 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 *RBAC) 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 r, err
|
||
|
}
|
||
|
|
||
|
return r, nil
|
||
|
}
|
||
|
|
||
|
func (u *RBAC) 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 *RBAC) 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 p, err
|
||
|
}
|
||
|
|
||
|
return p, nil
|
||
|
}
|
||
|
|
||
|
func (u *RBAC) newUser(ctx context.Context, target *model.User) (*model.User, error) {
|
||
|
result := u.store.Session(ctx).
|
||
|
Create(target)
|
||
|
if result.Error != nil {
|
||
|
return nil, result.Error
|
||
|
}
|
||
|
|
||
|
if result.RowsAffected != 1 {
|
||
|
return nil, fmt.Errorf("invalid rows affected")
|
||
|
}
|
||
|
|
||
|
return target, nil
|
||
|
}
|