wip: 结构感觉还是要调整
This commit is contained in:
		| @@ -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 | ||||||
| } | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user