structure: 确定基本结构(保持基本形式, 采用组合)

This commit is contained in:
loveuer
2024-11-01 17:47:33 +08:00
parent 9e8a47a7c6
commit 56cfd42bb9
52 changed files with 1003 additions and 176 deletions

View File

@@ -3,7 +3,7 @@ package model
import (
"gorm.io/gorm"
"gorm.io/gorm/clause"
"uauth/internal/tool"
"uauth/tool"
)
func Init(tx *gorm.DB) error {

47
model/privilege.go Normal file
View File

@@ -0,0 +1,47 @@
package model
import (
"fmt"
"strings"
)
// platform:module:class:action
// admin:*:*:*
// admin:audit:*:*
// admin:audit:flow:*
// admin:audit:flow:operate
type Privilege struct {
CreatedAt int64 `json:"created_at" gorm:"column:created_at;autoCreateTime:milli"`
UpdatedAt int64 `json:"updated_at" gorm:"column:updated_at;autoUpdateTime:milli"`
DeletedAt int64 `json:"deleted_at" gorm:"index;column:deleted_at;default:0"`
Code string `json:"code" gorm:"column:code;primaryKey"`
Label string `json:"label" gorm:"column:label"`
Parent string `json:"parent" gorm:"column:parent"`
Scope string `json:"scope" gorm:"column:scope"`
}
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
}

74
model/privilege_test.go Normal file
View File

@@ -0,0 +1,74 @@
package model
import (
"testing"
"uauth/internal/util"
)
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()
}
}

13
model/role.go Normal file
View File

@@ -0,0 +1,13 @@
package model
import "uauth/pkg/sqlType"
type Role struct {
CreatedAt int64 `json:"created_at" gorm:"column:created_at;autoCreateTime:milli"`
UpdatedAt int64 `json:"updated_at" gorm:"column:updated_at;autoUpdateTime:milli"`
DeletedAt int64 `json:"deleted_at" gorm:"index;column:deleted_at;default:0"`
Code string `json:"code" gorm:"primaryKey;column:code"`
Label string `json:"label" gorm:"column:label"`
Parent string `json:"parent" gorm:"column:parent"`
PrivilegeCodes sqlType.StrSlice `json:"privilege_codes" gorm:"column:privilege_codes"`
}

11
model/scope.go Normal file
View File

@@ -0,0 +1,11 @@
package model
// 用户权限作用域
type Scope struct {
Code string `json:"code" gorm:"column:code;type:varchar(8);not null;primaryKey"`
CreatedAt int64 `json:"created_at" gorm:"column:created_at;autoCreateTime:milli"`
UpdatedAt int64 `json:"updated_at" gorm:"column:updated_at;autoUpdateTime:milli"`
DeletedAt int64 `json:"deleted_at" gorm:"index;column:deleted_at;default:0"`
Label string `json:"label" gorm:"column:label;type:varchar(64)"`
Parent string `json:"parent" gorm:"column:parent;type:varchar(8)"`
}

View File

@@ -6,9 +6,15 @@ import (
"github.com/loveuer/nf/nft/log"
"time"
"uauth/internal/opt"
"uauth/pkg/sqlType"
)
type Status int64
type Status string
const (
StatusActive Status = "active"
StatusDisabled Status = "disabled"
)
type User struct {
Id uint64 `json:"id" gorm:"primaryKey;column:id"`
@@ -19,7 +25,7 @@ type User struct {
Username string `json:"username" gorm:"column:username;type:varchar(64);unique"`
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)"`
Avatar string `json:"avatar" gorm:"column:avatar;type:varchar(256)"`
@@ -29,6 +35,9 @@ type User struct {
CreatedByName string `json:"created_by_name" gorm:"column:created_by_name;type:varchar(64)"`
LoginAt int64 `json:"login_at" gorm:"-"`
Roles []*Role `json:"-" gorm:"-"`
RoleNames sqlType.StrSlice `json:"role_names" column:"role_names"`
}
func (u *User) JwtEncode() (token string, err error) {
@@ -40,6 +49,7 @@ func (u *User) JwtEncode() (token string, err error) {
"username": u.Username,
"nickname": u.Nickname,
"status": u.Status,
"avatar": u.Avatar,
"login_at": now.UnixMilli(),
})