wip: 结构感觉还是要调整
This commit is contained in:
parent
0fabeb69d6
commit
48e8d96726
@ -1,10 +1,15 @@
|
|||||||
package model
|
package model
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
// platform:module:class:action
|
// platform:module:class:action
|
||||||
// pro:*:*:*
|
// admin:*:*:*
|
||||||
// pro:content:*:*
|
// admin:audit:*:*
|
||||||
// pro:content:secret_news:*
|
// admin:audit:flow:*
|
||||||
// pro:content:secret_news:upload
|
// admin:audit:flow:operate
|
||||||
|
|
||||||
type Privilege struct {
|
type Privilege struct {
|
||||||
CreatedAt int64 `json:"created_at" gorm:"column:created_at;autoCreateTime:milli"`
|
CreatedAt int64 `json:"created_at" gorm:"column:created_at;autoCreateTime:milli"`
|
||||||
@ -17,5 +22,26 @@ type Privilege struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p *Privilege) Validate() error {
|
func (p *Privilege) Validate() error {
|
||||||
|
ss := strings.Split(p.Code, ":")
|
||||||
|
|
||||||
|
if len(ss) != 4 {
|
||||||
|
return fmt.Errorf("privilege must consist of four parts: (platform:module:class:action)")
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, s := range ss {
|
||||||
|
if len(s) == 0 {
|
||||||
|
return fmt.Errorf("privilege code parts must not be empty")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
code := strings.Clone(p.Code)
|
||||||
|
for strings.HasSuffix(code, ":*") {
|
||||||
|
code = code[:len(code)-2]
|
||||||
|
}
|
||||||
|
|
||||||
|
if code != "*" && strings.Contains(code, "*") {
|
||||||
|
return fmt.Errorf("privilege can only have trailing wildcard search")
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
74
model/privilege_test.go
Normal file
74
model/privilege_test.go
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
"uauth/internal/tool"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestPrivilege_Validate(t *testing.T) {
|
||||||
|
type fields struct {
|
||||||
|
Code string
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
fields fields
|
||||||
|
wantErr bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "全匹配",
|
||||||
|
fields: fields{Code: "*:*:*:*"},
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "部分全匹配1",
|
||||||
|
fields: fields{Code: "user:ok:*:*"},
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "部分全匹配2",
|
||||||
|
fields: fields{Code: "user:ok:nice:*"},
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "中间全匹配1",
|
||||||
|
fields: fields{Code: "user:*:*:ok"},
|
||||||
|
wantErr: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "中间全匹配2",
|
||||||
|
fields: fields{Code: "user:*:nice:*"},
|
||||||
|
wantErr: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "精确权限",
|
||||||
|
fields: fields{Code: "user:1:2:3"},
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
p := &Privilege{
|
||||||
|
Code: tt.fields.Code,
|
||||||
|
}
|
||||||
|
if err := p.Validate(); (err != nil) != tt.wantErr {
|
||||||
|
t.Errorf("Validate() error = %v, wantErr %v", err, tt.wantErr)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkPrivilegeValidate(b *testing.B) {
|
||||||
|
ps := make([]*Privilege, 100000)
|
||||||
|
|
||||||
|
for i := 0; i < 100000; i++ {
|
||||||
|
ps[i] = &Privilege{
|
||||||
|
Code: tool.RandomString(4) + ":" + tool.RandomString(5) + ":" + tool.RandomString(6) + ":" + tool.RandomString(7),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
b.ResetTimer()
|
||||||
|
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
_ = ps[i%100000].Validate()
|
||||||
|
}
|
||||||
|
}
|
@ -9,7 +9,12 @@ import (
|
|||||||
"uauth/internal/sqlType"
|
"uauth/internal/sqlType"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Status int64
|
type Status string
|
||||||
|
|
||||||
|
const (
|
||||||
|
StatusActive Status = "active"
|
||||||
|
StatusDisabled Status = "disabled"
|
||||||
|
)
|
||||||
|
|
||||||
type User struct {
|
type User struct {
|
||||||
Id uint64 `json:"id" gorm:"primaryKey;column:id"`
|
Id uint64 `json:"id" gorm:"primaryKey;column:id"`
|
||||||
@ -20,7 +25,7 @@ type User struct {
|
|||||||
Username string `json:"username" gorm:"column:username;type:varchar(64);unique"`
|
Username string `json:"username" gorm:"column:username;type:varchar(64);unique"`
|
||||||
Password string `json:"-" gorm:"column:password;type:varchar(256)"`
|
Password string `json:"-" gorm:"column:password;type:varchar(256)"`
|
||||||
|
|
||||||
Status Status `json:"status" gorm:"column:status;default:0"`
|
Status Status `json:"status" gorm:"column:status;default:''"`
|
||||||
|
|
||||||
Nickname string `json:"nickname" gorm:"column:nickname;type:varchar(64)"`
|
Nickname string `json:"nickname" gorm:"column:nickname;type:varchar(64)"`
|
||||||
Avatar string `json:"avatar" gorm:"column:avatar;type:varchar(256)"`
|
Avatar string `json:"avatar" gorm:"column:avatar;type:varchar(256)"`
|
||||||
|
11
rbac/rbac.go
11
rbac/rbac.go
@ -24,6 +24,7 @@ func New(opts ...Option) (*Urbac, error) {
|
|||||||
rootPrivilege *model.Privilege
|
rootPrivilege *model.Privilege
|
||||||
rootRole *model.Role
|
rootRole *model.Role
|
||||||
rootScope *model.Scope
|
rootScope *model.Scope
|
||||||
|
rootUser *model.User
|
||||||
)
|
)
|
||||||
|
|
||||||
for _, opt := range opts {
|
for _, opt := range opts {
|
||||||
@ -60,5 +61,15 @@ func New(opts ...Option) (*Urbac, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rootUser = &model.User{
|
||||||
|
Username: "admin",
|
||||||
|
Password: tool.NewPassword("123456"),
|
||||||
|
Status: model.StatusActive,
|
||||||
|
Nickname: "管理员",
|
||||||
|
RoleNames: []string{"admin"},
|
||||||
|
}
|
||||||
|
|
||||||
|
u.newUser()
|
||||||
|
|
||||||
return u, nil
|
return u, nil
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user