feat:add tree
This commit is contained in:
parent
eb85982ef1
commit
dbdc777ed4
|
@ -26,7 +26,7 @@ import (
|
||||||
type Role struct {
|
type Role struct {
|
||||||
ID primitive.ObjectID `bson:"_id,omitempty"`
|
ID primitive.ObjectID `bson:"_id,omitempty"`
|
||||||
Name string `bson:"name"` // 角色名稱
|
Name string `bson:"name"` // 角色名稱
|
||||||
UID string `bson:"uid"`
|
UID string `bson:"uid"` // 限定角色的管理範圍:例如,只有 UID 對應的使用者可以修改或刪除這個角色。
|
||||||
ClientID string `bson:"client_id"`
|
ClientID string `bson:"client_id"`
|
||||||
Status permission.Status `bson:"status"` // 例如 1: 啟用, 0: 停用
|
Status permission.Status `bson:"status"` // 例如 1: 啟用, 0: 停用
|
||||||
CreateAt int64 `bson:"create_at"`
|
CreateAt int64 `bson:"create_at"`
|
||||||
|
|
|
@ -7,4 +7,4 @@ const (
|
||||||
FrontendUser
|
FrontendUser
|
||||||
)
|
)
|
||||||
|
|
||||||
const AdminRoleUID = "GodDog"
|
const AdminRoleUID = "GD1000001" // 管理員 GodDog 1000001
|
||||||
|
|
|
@ -10,8 +10,8 @@ import (
|
||||||
type RolePermissionRepository interface {
|
type RolePermissionRepository interface {
|
||||||
Get(ctx context.Context, roleID string) ([]*entity.RolePermission, error)
|
Get(ctx context.Context, roleID string) ([]*entity.RolePermission, error)
|
||||||
GetByPermissionID(ctx context.Context, permissionIDs []string) ([]*entity.RolePermission, error)
|
GetByPermissionID(ctx context.Context, permissionIDs []string) ([]*entity.RolePermission, error)
|
||||||
Create(ctx context.Context, entity entity.RolePermission) error
|
Create(ctx context.Context, entity []entity.RolePermission) error
|
||||||
Delete(ctx context.Context, roleID string, permission string) error
|
Delete(ctx context.Context, roleID string, permissions []string) error
|
||||||
RolePermissionIndex
|
RolePermissionIndex
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,5 +3,5 @@ package usecase
|
||||||
import "fmt"
|
import "fmt"
|
||||||
|
|
||||||
var (
|
var (
|
||||||
NotFoundError = fmt.Errorf("permission not found")
|
ErrNotFound = fmt.Errorf("permission not found")
|
||||||
)
|
)
|
||||||
|
|
|
@ -10,12 +10,13 @@ import (
|
||||||
type PermissionUseCase interface {
|
type PermissionUseCase interface {
|
||||||
Insert(ctx context.Context, req CreatePermissionReq) error
|
Insert(ctx context.Context, req CreatePermissionReq) error
|
||||||
Del(ctx context.Context, id string) error
|
Del(ctx context.Context, id string) error
|
||||||
Update(ctx context.Context, req UpdatePermissionReq) error
|
Update(ctx context.Context, id string, req UpdatePermissionReq) error
|
||||||
Get(ctx context.Context, id string) (entity.Permission, error)
|
All(ctx context.Context, status *permission.Status) ([]entity.Permission, error)
|
||||||
List(ctx context.Context, param ListParam) ([]entity.Permission, int64, error)
|
|
||||||
All(ctx context.Context, status *permission.Status)
|
|
||||||
// FilterAll 用樹的結構,使得付節點若關閉,子節點也不會顯示
|
// FilterAll 用樹的結構,使得付節點若關閉,子節點也不會顯示
|
||||||
FilterAll(ctx context.Context) ([]entity.Permission, error)
|
FilterAll(ctx context.Context) ([]entity.Permission, error)
|
||||||
|
|
||||||
|
// Get(ctx context.Context, id string) (entity.Permission, error)
|
||||||
|
// List(ctx context.Context, param ListParam) ([]entity.Permission, int64, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type CreatePermissionReq struct {
|
type CreatePermissionReq struct {
|
||||||
|
|
|
@ -10,19 +10,20 @@ type RoleUseCase interface {
|
||||||
List(ctx context.Context, param ListQuery) ([]Role, int64, error)
|
List(ctx context.Context, param ListQuery) ([]Role, int64, error)
|
||||||
All(ctx context.Context, clientID *string) ([]Role, error)
|
All(ctx context.Context, clientID *string) ([]Role, error)
|
||||||
GetByID(ctx context.Context, id string) (*Role, error)
|
GetByID(ctx context.Context, id string) (*Role, error)
|
||||||
GetByUID(ctx context.Context, uid string) (*Role, error)
|
GetByUID(ctx context.Context, uid string) (*Role, error) // -> 限定角色的管理範圍:查詢誰建立的,用某個角色管理,目前用不到
|
||||||
Create(ctx context.Context, role CreateRoleReq) error
|
Create(ctx context.Context, role CreateRoleReq) error
|
||||||
Update(ctx context.Context, id string, data CreateRoleReq) error
|
Update(ctx context.Context, id string, data CreateRoleReq) error
|
||||||
Delete(ctx context.Context, id string) error
|
Delete(ctx context.Context, id string) error
|
||||||
}
|
}
|
||||||
|
|
||||||
type ListQuery struct {
|
type ListQuery struct {
|
||||||
PageSize int64 // 必填
|
PageSize int64 // 必填
|
||||||
PageIndex int64 // 必填
|
PageIndex int64 // 必填
|
||||||
ClientID *string
|
ClientID *string
|
||||||
UID *string
|
UID *string
|
||||||
Name *string
|
Name *string
|
||||||
Status *permission.Status
|
Status *permission.Status
|
||||||
|
Permission []string
|
||||||
}
|
}
|
||||||
|
|
||||||
type Role struct {
|
type Role struct {
|
||||||
|
|
|
@ -7,12 +7,12 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type RolePermissionUseCase interface {
|
type RolePermissionUseCase interface {
|
||||||
Get(ctx context.Context, roleID string) (permission.Permissions, error)
|
Get(ctx context.Context, roleID string) (permission.Permissions, error) // -> role 有哪些Permission
|
||||||
GetByRoleUID(ctx context.Context, uid string) (permission.Permissions, error)
|
|
||||||
GetByUser(ctx context.Context, uid string) (UserPermission, error)
|
|
||||||
Create(ctx context.Context, roleID string, permissions permission.Permissions) error
|
Create(ctx context.Context, roleID string, permissions permission.Permissions) error
|
||||||
Delete(ctx context.Context, roleID string, permissions permission.Permissions) error
|
Delete(ctx context.Context, roleID string, permissions permission.Permissions) error
|
||||||
List(ctx context.Context, req ListQuery) (RoleResp, error)
|
List(ctx context.Context, req ListQuery) (RoleResp, error)
|
||||||
|
//GetByRoleUID(ctx context.Context, uid string) (permission.Permissions, error)
|
||||||
|
//GetByUser(ctx context.Context, uid string) (UserPermission, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type UserPermission struct {
|
type UserPermission struct {
|
||||||
|
@ -26,6 +26,6 @@ type UserRoleCountResp struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type RoleResp struct {
|
type RoleResp struct {
|
||||||
List []UserRoleCountResp `json:"list"`
|
Roles []Role
|
||||||
Total int64 `json:"total"`
|
Total int64 `json:"total"`
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,26 +59,40 @@ func (repo *RolePermissionRepository) GetByPermissionID(ctx context.Context, per
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (repo *RolePermissionRepository) Create(ctx context.Context, role entity.RolePermission) error {
|
func (repo *RolePermissionRepository) Create(ctx context.Context, roles []entity.RolePermission) error {
|
||||||
if role.ID.IsZero() {
|
if len(roles) == 0 {
|
||||||
now := time.Now().UTC().UnixNano()
|
return nil // 如果 roles 是空的,則不執行任何操作
|
||||||
role.ID = primitive.NewObjectID()
|
|
||||||
role.CreateAt = now
|
|
||||||
role.UpdateAt = now
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := repo.DB.GetClient().InsertOne(ctx, role)
|
now := time.Now().UTC().UnixNano()
|
||||||
|
|
||||||
|
// 將 []entity.RolePermission 轉換為 []interface{}
|
||||||
|
var roleInterfaces []interface{}
|
||||||
|
for i := range roles {
|
||||||
|
if roles[i].ID.IsZero() {
|
||||||
|
roles[i].ID = primitive.NewObjectID()
|
||||||
|
roles[i].CreateAt = now
|
||||||
|
roles[i].UpdateAt = now
|
||||||
|
}
|
||||||
|
roleInterfaces = append(roleInterfaces, roles[i])
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err := repo.DB.GetClient().InsertMany(ctx, roleInterfaces)
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (repo *RolePermissionRepository) Delete(ctx context.Context, roleID string, permission string) error {
|
func (repo *RolePermissionRepository) Delete(ctx context.Context, roleID string, permissions []string) error {
|
||||||
filter := bson.M{
|
if len(permissions) == 0 {
|
||||||
"role_id": roleID,
|
return nil // 如果 permissions 為空,則不執行刪除操作
|
||||||
"permission_id": permission,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := repo.DB.GetClient().DeleteOne(ctx, filter)
|
filter := bson.M{
|
||||||
|
"role_id": roleID,
|
||||||
|
"permission_id": bson.M{"$in": permissions}, // 使用 $in 刪除多個 permission_id
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err := repo.DB.GetClient().DeleteMany(ctx, filter)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,7 +74,7 @@ func TestRolePermissionRepository_Create(t *testing.T) {
|
||||||
|
|
||||||
for _, tc := range testCases {
|
for _, tc := range testCases {
|
||||||
t.Run(tc.name, func(t *testing.T) {
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
err := repo.Create(context.Background(), tc.input)
|
err := repo.Create(context.Background(), []entity.RolePermission{tc.input})
|
||||||
|
|
||||||
if tc.expectErr {
|
if tc.expectErr {
|
||||||
assert.Error(t, err, "應該返回錯誤")
|
assert.Error(t, err, "應該返回錯誤")
|
||||||
|
@ -97,7 +97,7 @@ func TestRolePermissionRepository_Delete(t *testing.T) {
|
||||||
PermissionID: "perm_1",
|
PermissionID: "perm_1",
|
||||||
}
|
}
|
||||||
|
|
||||||
err = repo.Create(context.Background(), existingRolePermission)
|
err = repo.Create(context.Background(), []entity.RolePermission{existingRolePermission})
|
||||||
assert.NoError(t, err, "應該成功插入測試資料")
|
assert.NoError(t, err, "應該成功插入測試資料")
|
||||||
|
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
|
@ -122,7 +122,7 @@ func TestRolePermissionRepository_Delete(t *testing.T) {
|
||||||
|
|
||||||
for _, tc := range testCases {
|
for _, tc := range testCases {
|
||||||
t.Run(tc.name, func(t *testing.T) {
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
err := repo.Delete(context.Background(), tc.roleID, tc.permission)
|
err := repo.Delete(context.Background(), tc.roleID, []string{tc.permission})
|
||||||
|
|
||||||
if tc.expectErr {
|
if tc.expectErr {
|
||||||
assert.Error(t, err, "應該返回錯誤")
|
assert.Error(t, err, "應該返回錯誤")
|
||||||
|
@ -158,7 +158,7 @@ func TestRolePermissionRepository_GetByPermissionID(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, rp := range existingRolePermissions {
|
for _, rp := range existingRolePermissions {
|
||||||
err := repo.Create(context.Background(), rp)
|
err := repo.Create(context.Background(), []entity.RolePermission{rp})
|
||||||
assert.NoError(t, err, "應該成功插入測試資料")
|
assert.NoError(t, err, "應該成功插入測試資料")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -227,7 +227,7 @@ func TestRolePermissionRepository_Get(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, rp := range existingRolePermissions {
|
for _, rp := range existingRolePermissions {
|
||||||
err := repo.Create(context.Background(), rp)
|
err := repo.Create(context.Background(), []entity.RolePermission{rp})
|
||||||
assert.NoError(t, err, "應該成功插入測試資料")
|
assert.NoError(t, err, "應該成功插入測試資料")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1 +1,98 @@
|
||||||
package usecase
|
package usecase
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"code.30cm.net/digimon/app-cloudep-permission-server/pkg/domain/entity"
|
||||||
|
"code.30cm.net/digimon/app-cloudep-permission-server/pkg/domain/permission"
|
||||||
|
"code.30cm.net/digimon/app-cloudep-permission-server/pkg/domain/repository"
|
||||||
|
"code.30cm.net/digimon/app-cloudep-permission-server/pkg/domain/usecase"
|
||||||
|
)
|
||||||
|
|
||||||
|
type PermissionUseCaseParam struct {
|
||||||
|
permissionRepository repository.PermissionRepository
|
||||||
|
}
|
||||||
|
|
||||||
|
type PermissionUseCase struct {
|
||||||
|
PermissionUseCaseParam
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewPermissionUseCase(param PermissionUseCaseParam) usecase.PermissionUseCase {
|
||||||
|
return &PermissionUseCase{
|
||||||
|
PermissionUseCaseParam: param,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (use *PermissionUseCase) Insert(ctx context.Context, req usecase.CreatePermissionReq) error {
|
||||||
|
insert := entity.Permission{
|
||||||
|
Name: req.Name,
|
||||||
|
HTTPMethod: req.HTTPMethod,
|
||||||
|
HTTPPath: req.HTTPPath,
|
||||||
|
Status: req.Status,
|
||||||
|
Type: req.Type,
|
||||||
|
}
|
||||||
|
if req.Parent != nil {
|
||||||
|
insert.Parent = *req.Parent
|
||||||
|
}
|
||||||
|
|
||||||
|
err := use.permissionRepository.Insert(ctx, insert)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (use *PermissionUseCase) Del(ctx context.Context, id string) error {
|
||||||
|
err := use.Del(ctx, id)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (use *PermissionUseCase) Update(ctx context.Context, id string, req usecase.UpdatePermissionReq) error {
|
||||||
|
update := repository.UpdatePermission{
|
||||||
|
Name: req.Name,
|
||||||
|
HTTPMethod: req.HTTPMethod,
|
||||||
|
HTTPPath: req.HTTPPath,
|
||||||
|
Status: req.Status,
|
||||||
|
Type: req.Type,
|
||||||
|
}
|
||||||
|
|
||||||
|
err := use.permissionRepository.Update(ctx, id, update)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (use *PermissionUseCase) All(ctx context.Context, status *permission.Status) ([]entity.Permission, error) {
|
||||||
|
all, err := use.permissionRepository.GetAll(ctx, status)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return all, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (use *PermissionUseCase) FilterAll(ctx context.Context) ([]entity.Permission, error) {
|
||||||
|
all, err := use.permissionRepository.GetAll(ctx, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
nodes, err := GeneratePermissionTree(all).filterOpenNodes()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
result := make([]entity.Permission, 0, len(nodes))
|
||||||
|
for _, item := range nodes {
|
||||||
|
result = append(result, item)
|
||||||
|
}
|
||||||
|
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
|
@ -3,6 +3,8 @@ package usecase
|
||||||
import (
|
import (
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
|
"code.30cm.net/digimon/library-go/errs"
|
||||||
|
|
||||||
"code.30cm.net/digimon/app-cloudep-permission-server/pkg/domain/entity"
|
"code.30cm.net/digimon/app-cloudep-permission-server/pkg/domain/entity"
|
||||||
"code.30cm.net/digimon/app-cloudep-permission-server/pkg/domain/permission"
|
"code.30cm.net/digimon/app-cloudep-permission-server/pkg/domain/permission"
|
||||||
|
|
||||||
|
@ -26,6 +28,8 @@ type PermissionNode struct {
|
||||||
Children []*PermissionNode
|
Children []*PermissionNode
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const rootName = "root"
|
||||||
|
|
||||||
// GeneratePermissionTree 根據扁平權限資料建立樹,並掛在 dummy root 下
|
// GeneratePermissionTree 根據扁平權限資料建立樹,並掛在 dummy root 下
|
||||||
func GeneratePermissionTree(permissions []entity.Permission) *PermissionTree {
|
func GeneratePermissionTree(permissions []entity.Permission) *PermissionTree {
|
||||||
tree := &PermissionTree{
|
tree := &PermissionTree{
|
||||||
|
@ -45,7 +49,7 @@ func GeneratePermissionTree(permissions []entity.Permission) *PermissionTree {
|
||||||
|
|
||||||
// 2. 建立 dummy root 節點
|
// 2. 建立 dummy root 節點
|
||||||
tree.root = &PermissionNode{
|
tree.root = &PermissionNode{
|
||||||
Data: entity.Permission{ID: primitive.NewObjectID(), Name: "root"},
|
Data: entity.Permission{ID: primitive.NewObjectID(), Name: rootName},
|
||||||
Children: []*PermissionNode{},
|
Children: []*PermissionNode{},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -125,106 +129,93 @@ func (tree *PermissionTree) filterOpenNodes() (map[string]entity.Permission, err
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
//// getFullParentPermissionIDs
|
// getFullParentPermission 根據 role permission 找出完整 path permission status
|
||||||
//// 根據傳入的權限狀態 (Permissions) 回傳完整的權限 ID 列表,包含所有祖先。
|
func (tree *PermissionTree) getFullParentPermission(rolePermissions []*entity.RolePermission) permission.Permissions {
|
||||||
//// 如果某個節點為非葉節點,則會檢查其子節點是否有啟用,否則該節點不會被展開。
|
status := permission.Permissions{}
|
||||||
//func (tree *PermissionTree) getFullParentPermissionIDs(permissions permission.Permissions) ([]string, error) {
|
|
||||||
// tree.mu.RLock()
|
|
||||||
// defer tree.mu.RUnlock()
|
|
||||||
//
|
|
||||||
// exist := make(map[string]bool)
|
|
||||||
// var ids []string
|
|
||||||
//
|
|
||||||
// for name, status := range permissions {
|
|
||||||
// if status != permission.OpenPermission {
|
|
||||||
// continue
|
|
||||||
// }
|
|
||||||
// idList, ok := tree.nameToIDs[name]
|
|
||||||
// if !ok {
|
|
||||||
// return nil, NotFoundError
|
|
||||||
// }
|
|
||||||
// for _, pid := range idList {
|
|
||||||
// node, exists := tree.nodes[pid]
|
|
||||||
// if !exists || node == nil {
|
|
||||||
// return nil, NotFoundError
|
|
||||||
// }
|
|
||||||
// // 如果為父節點,檢查其子節點是否有啟用,若都關閉則不展開
|
|
||||||
// if len(node.Children) > 0 {
|
|
||||||
// var childOpen bool
|
|
||||||
// for _, child := range node.Children {
|
|
||||||
// if childStatus, ok := permissions[child.Data.Name]; ok && childStatus == permission.OpenPermission {
|
|
||||||
// childOpen = true
|
|
||||||
// break
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// if !childOpen {
|
|
||||||
// continue
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// // 將該節點及所有祖先(直到 dummy root,不包括 dummy root)加入結果
|
|
||||||
// for cur := node; cur != nil && cur.Data.Name != "root"; cur = cur.Parent {
|
|
||||||
// if !exist[cur.Data.ID.Hex()] {
|
|
||||||
// ids = append(ids, cur.Data.ID.Hex())
|
|
||||||
// exist[cur.Data.ID.Hex()] = true
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// return ids, nil
|
|
||||||
//}
|
|
||||||
|
|
||||||
//// getFullParentPermissionStatus
|
for _, v := range rolePermissions {
|
||||||
//// 根據傳入的權限狀態 (Permissions) 回傳完整的權限狀態,包含所有祖先的名稱設為啟用。
|
node := tree.getNode(v.PermissionID)
|
||||||
//func (tree *PermissionTree) getFullParentPermissionStatus(permissions permission.Permissions) (permission.Permissions, error) {
|
|
||||||
// tree.mu.RLock()
|
if node == nil {
|
||||||
// defer tree.mu.RUnlock()
|
return nil
|
||||||
//
|
}
|
||||||
// result := make(permission.Permissions)
|
|
||||||
// exist := make(map[string]bool)
|
if _, ok := status[node.Data.Name]; ok {
|
||||||
//
|
continue
|
||||||
// for name, status := range permissions {
|
}
|
||||||
// if status != permission.OpenPermission {
|
|
||||||
// continue
|
status[node.Data.Name] = permission.StatusCode(node.Data.Status.String())
|
||||||
// }
|
|
||||||
// idList, ok := tree.nameToIDs[name]
|
// 往上找node(父)
|
||||||
// if !ok {
|
for node.Parent != nil {
|
||||||
// return nil, NotFoundError
|
np := node.Parent
|
||||||
// }
|
if np == nil || np.Data.Name == rootName {
|
||||||
// for _, pid := range idList {
|
break
|
||||||
// node, exists := tree.nodes[pid]
|
}
|
||||||
// if !exists || node == nil {
|
parent := tree.getNode(np.Data.ID.Hex())
|
||||||
// return nil, NotFoundError
|
if parent == nil {
|
||||||
// }
|
continue
|
||||||
// // 將該節點及所有祖先標記為啟用
|
}
|
||||||
// for cur := node; cur != nil && cur.Data.Name != "root"; cur = cur.Parent {
|
|
||||||
// if !exist[cur.Data.ID.Hex()] {
|
status[parent.Data.Name] = permission.StatusCode(parent.Data.Status.String())
|
||||||
// result[cur.Data.Name] = permission.OpenPermission
|
}
|
||||||
// exist[cur.Data.ID.Hex()] = true
|
|
||||||
// }
|
}
|
||||||
// }
|
|
||||||
// }
|
return status
|
||||||
// }
|
}
|
||||||
//
|
|
||||||
// return result, nil
|
// getFullParentPermissionIDs 根據 permissions 找出所有完整 permission
|
||||||
//}
|
// 比如B的父權限是A,給B權限就要回傳A與B權限id
|
||||||
//
|
func (tree *PermissionTree) getFullParentPermissionIDs(permissions permission.Permissions) ([]string, error) {
|
||||||
//// getFullParentPermission
|
exist := make(map[string]bool)
|
||||||
//// 根據角色權限 (RolePermission) 列表,回傳完整的權限狀態(名稱->狀態),包含所有祖先
|
ids := make([]string, 0)
|
||||||
//func (tree *PermissionTree) getFullParentPermission(rolePermissions []entity.RolePermission) permission.Permissions {
|
|
||||||
// tree.mu.RLock()
|
for name, status := range permissions {
|
||||||
// defer tree.mu.RUnlock()
|
if status != permission.OpenPermission {
|
||||||
//
|
continue
|
||||||
// result := make(permission.Permissions)
|
}
|
||||||
// for _, rp := range rolePermissions {
|
|
||||||
// node, ok := tree.nodes[rp.PermissionID]
|
pIDs, ok := tree.names[name]
|
||||||
// if !ok || node == nil {
|
if !ok {
|
||||||
// continue
|
return nil, errs.ResourceNotFound("failed to get node")
|
||||||
// }
|
}
|
||||||
// // 將該節點及所有祖先設為啟用
|
|
||||||
// for cur := node; cur != nil && cur.Data.Name != "root"; cur = cur.Parent {
|
for _, pID := range pIDs {
|
||||||
// result[cur.Data.Name] = permission.OpenPermission
|
node := tree.getNode(pID)
|
||||||
// }
|
if node == nil {
|
||||||
// }
|
return nil, errs.ResourceNotFound("failed to get node")
|
||||||
// return result
|
}
|
||||||
//}
|
|
||||||
|
// 如果有子node代表不是最底層權限而是父node,就必須檢查此父node底下子node權限是否有開啟
|
||||||
|
if len(node.Children) > 0 {
|
||||||
|
var can bool
|
||||||
|
for _, ch := range node.Children {
|
||||||
|
if v, ok := permissions[ch.Data.Name]; ok && v == permission.OpenPermission {
|
||||||
|
can = true
|
||||||
|
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !can {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for node.Parent != nil {
|
||||||
|
np := node.Parent
|
||||||
|
if np == nil || np.Data.Name == rootName {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if _, ok := exist[np.Data.ID.Hex()]; !ok {
|
||||||
|
ids = append(ids, np.Data.ID.Hex())
|
||||||
|
exist[np.Data.ID.Hex()] = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ids, nil
|
||||||
|
}
|
||||||
|
|
|
@ -191,7 +191,6 @@ func (use *RoleUseCase) Update(ctx context.Context, id string, data usecase.Crea
|
||||||
err := use.roleRepository.Update(ctx, repository.UpdateReq{
|
err := use.roleRepository.Update(ctx, repository.UpdateReq{
|
||||||
ID: id,
|
ID: id,
|
||||||
Name: &data.Name,
|
Name: &data.Name,
|
||||||
UID: &data.UID,
|
|
||||||
ClientID: &data.ClientID,
|
ClientID: &data.ClientID,
|
||||||
Status: &data.Status,
|
Status: &data.Status,
|
||||||
})
|
})
|
||||||
|
|
|
@ -3,12 +3,17 @@ package usecase
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
|
"code.30cm.net/digimon/app-cloudep-permission-server/pkg/domain/entity"
|
||||||
"code.30cm.net/digimon/app-cloudep-permission-server/pkg/domain/permission"
|
"code.30cm.net/digimon/app-cloudep-permission-server/pkg/domain/permission"
|
||||||
|
"code.30cm.net/digimon/app-cloudep-permission-server/pkg/domain/repository"
|
||||||
"code.30cm.net/digimon/app-cloudep-permission-server/pkg/domain/usecase"
|
"code.30cm.net/digimon/app-cloudep-permission-server/pkg/domain/usecase"
|
||||||
)
|
)
|
||||||
|
|
||||||
type RolePermissionUseCaseParam struct {
|
type RolePermissionUseCaseParam struct {
|
||||||
//rolePermissionRepository repository.RolePermissionRepository
|
rolePermissionRepository repository.RolePermissionRepository
|
||||||
|
permissionRepository repository.PermissionRepository
|
||||||
|
roleRepository repository.RoleRepository
|
||||||
|
userRoleRepository repository.UserRoleRepository
|
||||||
}
|
}
|
||||||
|
|
||||||
type RolePermissionUseCase struct {
|
type RolePermissionUseCase struct {
|
||||||
|
@ -21,53 +26,144 @@ func NewRolePermissionUseCase(param RolePermissionUseCaseParam) usecase.RolePerm
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get 拿到這個 Role ID 底下有哪些權限是開的
|
||||||
func (use *RolePermissionUseCase) Get(ctx context.Context, roleID string) (permission.Permissions, error) {
|
func (use *RolePermissionUseCase) Get(ctx context.Context, roleID string) (permission.Permissions, error) {
|
||||||
//rolePermissions, err := use.rolePermissionRepository.Get(ctx, roleID)
|
// 拿到這個 role 底下有哪些 Permission
|
||||||
//if err != nil && !errors.Is(err, repository.ErrRecordNotFound) {
|
rolePermission, err := use.rolePermissionRepository.Get(ctx, roleID)
|
||||||
// return nil, usecase.InternalError{Err: fmt.Errorf("permissionRepo.Get error: %w", err)}
|
if err != nil {
|
||||||
//}
|
return nil, err
|
||||||
//
|
}
|
||||||
//permissions, err := uc.PermissionRepo.All(ctx)
|
p, err := use.permissionRepository.GetAll(ctx, nil) // -> 開的關的 permission 都會拿到
|
||||||
//if err != nil && !errors.Is(err, repository.ErrRecordNotFound) {
|
if err != nil {
|
||||||
// return nil, usecase.InternalError{Err: fmt.Errorf("permissionRepo.AllStatus error: %w", err)}
|
return nil, err
|
||||||
//}
|
}
|
||||||
//
|
|
||||||
//// TODO cache http://jira.logintt.com:8080/browse/ESC-2046
|
|
||||||
//return GeneratePermissionTree(permissions).getFullParentPermission(rolePermissions), nil
|
|
||||||
//get, err := use.rolePermissionRepository.Get(ctx, roleID)
|
|
||||||
//if err != nil {
|
|
||||||
// return nil, err
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
//permissions := make(permission.Permissions, len(get))
|
|
||||||
//for _, item := range get {
|
|
||||||
// permissions[item.PermissionID] = item.
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
return permission.Permissions{}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (use *RolePermissionUseCase) GetByRoleUID(ctx context.Context, uid string) (permission.Permissions, error) {
|
return GeneratePermissionTree(p).getFullParentPermission(rolePermission), nil
|
||||||
//TODO implement me
|
|
||||||
panic("implement me")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (use *RolePermissionUseCase) GetByUser(ctx context.Context, uid string) (usecase.UserPermission, error) {
|
|
||||||
//TODO implement me
|
|
||||||
panic("implement me")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (use *RolePermissionUseCase) Create(ctx context.Context, roleID string, permissions permission.Permissions) error {
|
func (use *RolePermissionUseCase) Create(ctx context.Context, roleID string, permissions permission.Permissions) error {
|
||||||
//TODO implement me
|
// 如果加了一個,要把上面的節點都加入才可以
|
||||||
panic("implement me")
|
permissionIDs, err := use.getPermissionIDs(ctx, permissions)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
insert := make([]entity.RolePermission, 0, len(permissions))
|
||||||
|
|
||||||
|
for _, permissionID := range permissionIDs {
|
||||||
|
insert = append(insert, entity.RolePermission{
|
||||||
|
RoleID: roleID,
|
||||||
|
PermissionID: permissionID,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
err = use.rolePermissionRepository.Create(ctx, insert)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (use *RolePermissionUseCase) getPermissionIDs(ctx context.Context, setPermissions permission.Permissions) ([]string, error) {
|
||||||
|
p, err := use.permissionRepository.GetAll(ctx, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return GeneratePermissionTree(p).getFullParentPermissionIDs(setPermissions)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (use *RolePermissionUseCase) Delete(ctx context.Context, roleID string, permissions permission.Permissions) error {
|
func (use *RolePermissionUseCase) Delete(ctx context.Context, roleID string, permissions permission.Permissions) error {
|
||||||
//TODO implement me
|
// 如果加了一個,要把上面的節點都加入才可以
|
||||||
panic("implement me")
|
permissionIDs, err := use.getPermissionIDs(ctx, permissions)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
del := make([]string, 0, len(permissions))
|
||||||
|
for _, permissionID := range permissionIDs {
|
||||||
|
del = append(del, permissionID)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = use.rolePermissionRepository.Delete(ctx, roleID, del)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (use *RolePermissionUseCase) List(ctx context.Context, req usecase.ListQuery) (usecase.RoleResp, error) {
|
func (use *RolePermissionUseCase) List(ctx context.Context, req usecase.ListQuery) (usecase.RoleResp, error) {
|
||||||
//TODO implement me
|
roles, total, err := use.roleRepository.List(ctx, repository.ListQuery{
|
||||||
panic("implement me")
|
PageIndex: req.PageIndex,
|
||||||
|
PageSize: req.PageSize,
|
||||||
|
ClientID: req.ClientID,
|
||||||
|
UID: req.UID,
|
||||||
|
Name: req.Name,
|
||||||
|
Status: req.Status,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return usecase.RoleResp{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
result := make([]usecase.Role, 0, len(roles))
|
||||||
|
for _, item := range roles {
|
||||||
|
result = append(result, usecase.Role{
|
||||||
|
ID: item.ID.Hex(),
|
||||||
|
UID: item.UID,
|
||||||
|
Name: item.Name,
|
||||||
|
Status: item.Status,
|
||||||
|
ClientID: item.ClientID,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return usecase.RoleResp{
|
||||||
|
Total: total,
|
||||||
|
Roles: result,
|
||||||
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//// GetByRoleUID 拿到這個 UID 底下有哪些權限是開的
|
||||||
|
//func (use *RolePermissionUseCase) GetByRoleUID(ctx context.Context, uid string) (permission.Permissions, error) {
|
||||||
|
// permissions := make(permission.Permissions)
|
||||||
|
//
|
||||||
|
// // admin權限
|
||||||
|
// if uid == permission.AdminRoleUID {
|
||||||
|
// data, err := use.permissionRepository.GetAll(ctx, nil)
|
||||||
|
// if err != nil {
|
||||||
|
// return nil, err
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// for _, v := range data {
|
||||||
|
// permissions[v.Name] = permission.OpenPermission
|
||||||
|
// }
|
||||||
|
// } else {
|
||||||
|
// role, err := use.roleRepository.GetByUID(ctx, uid)
|
||||||
|
// if err != nil {
|
||||||
|
// return nil, err
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// permissions, err = use.Get(ctx, role.ID.Hex())
|
||||||
|
// if err != nil {
|
||||||
|
// return nil, err
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// return permissions, nil
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//func (use *RolePermissionUseCase) GetByUser(ctx context.Context, uid string) (usecase.UserPermission, error) {
|
||||||
|
// userRole, err := use.userRoleRepository.GetByUserID(ctx, uid)
|
||||||
|
// if err != nil {
|
||||||
|
// return usecase.UserPermission{}, err
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// p, err := use.Get(ctx, userRole.RoleID)
|
||||||
|
// if err != nil {
|
||||||
|
// return usecase.UserPermission{}, err
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// return usecase.UserPermission{
|
||||||
|
// RoleID: userRole.RoleID,
|
||||||
|
// Permissions: p,
|
||||||
|
// }, nil
|
||||||
|
//}
|
||||||
|
|
Loading…
Reference in New Issue