[feat] 添加 resource.WithRolesCondition 方法

This commit is contained in:
what 2023-04-22 17:57:00 +08:00
parent 99df51e259
commit 94364138b7
2 changed files with 103 additions and 7 deletions

View File

@ -2,6 +2,7 @@ package base
import ( import (
"database/sql" "database/sql"
"fmt"
"log" "log"
"reflect" "reflect"
"unicode" "unicode"
@ -10,6 +11,7 @@ import (
"github.com/samber/lo" "github.com/samber/lo"
"git.fsdpf.net/go/contracts" "git.fsdpf.net/go/contracts"
"git.fsdpf.net/go/contracts/helper"
"git.fsdpf.net/go/contracts/res_type" "git.fsdpf.net/go/contracts/res_type"
"git.fsdpf.net/go/db" "git.fsdpf.net/go/db"
) )
@ -142,8 +144,6 @@ func (this Resource) GetDBDriver() string {
} }
func (this Resource) GetAuthDBTable(u contracts.User, params ...any) *db.Builder { func (this Resource) GetAuthDBTable(u contracts.User, params ...any) *db.Builder {
// fmt.Println(this.GetRolesCondition(u).ToSql())
return this.GetDBTable(append(params, u)...) return this.GetDBTable(append(params, u)...)
} }
@ -180,6 +180,8 @@ func (this Resource) GetDBTable(params ...any) *db.Builder {
// 填充保存数据 // 填充保存数据
this.fillSaveValue(data[i], user, db.TYPE_INSERT) this.fillSaveValue(data[i], user, db.TYPE_INSERT)
} }
} else if user != nil {
this.WithRolesCondition(b, t, user.Roles()...)
} }
}) })
@ -200,14 +202,98 @@ func (this Resource) GetDBTable(params ...any) *db.Builder {
return builder.Table(string(this.GetTable()), alias) return builder.Table(string(this.GetTable()), alias)
} }
func (this Resource) WithRolesCondition(b *db.Builder, roles ...string) { func (this Resource) WithRolesCondition(b *db.Builder, t string, roles ...string) error {
isFullRight := false
isFullNot := false
NewOrmModel := do.MustInvoke[helper.NewOrmModel](this.container)
NewOrmJoin := do.MustInvoke[helper.NewOrmJoin](this.container)
GetResRelationResource := do.MustInvoke[GetResRelationResource](this.container)
GetResource := do.MustInvoke[contracts.GetResource](this.container)
GetOrmConditionByRes := do.MustInvoke[GetOrmConditionByRes](this.container)
items := do.MustInvoke[GetResRoles](this.container)(this.GetUuid(), roles...)
subTables := lo.Reduce(items, func(carry string, item ResRole, _ int) string {
db := this.GetDB().Table(string(this.GetTable()), this.GetCode()).Select(db.Raw("`" + this.GetCode() + "`.*"))
joins := lo.Filter(GetResRelations(item.Uuid), func(item ResRelation, _ int) bool {
return item.Type == "inner" || item.Type == "left" || item.Type == "right"
})
for i := 0; i < len(joins); i++ {
oResource, ok := GetResource(joins[i].ResourceCode)
if !ok {
continue
}
rResource, ok := GetResRelationResource(joins[i])
if !ok {
continue
}
join := NewOrmJoin(contracts.RelationType(joins[i].Type), oResource, joins[i].Code, joins[i].RelationResource, joins[i].RelationField, joins[i].RelationForeignKey)
// 关联扩展条件
join.SetCondition(GetOrmConditionByRes(joins[i].Uuid, "关联扩展条件"))
join.Inject(db, NewOrmModel(rResource, rResource.GetCode(), rResource.GetName()))
}
conditions := GetOrmConditionByRes(item.Uuid, "关联扩展条件")
if len(joins) == 0 && conditions.IsEmpty() {
// 无权限, 直接跳过这个 unoin 语句
if carry != "" {
return carry
}
// 第一个无权限除外, 避免所有用户所属角色都是无权限
db.WhereRaw("false")
isFullNot = true
} else if len(joins) == 0 && conditions.IsNotEmpty() && conditions.IsAlwaysRight() /* 1=1 的这种条件*/ {
// 只要有1个满权限, 直接返回单条语句
isFullRight = true
return db.ToSql()
} else if conditions.IsNotEmpty() {
db.WhereRaw(string(conditions.ToSql(nil)))
// 如果前面是无权限的sql查看, 这直接返回本次查询
if isFullNot {
isFullNot = false
return db.ToSql()
}
}
if carry != "" {
carry += " UNION "
}
carry += db.ToSql()
return carry
}, "")
if isFullRight {
return nil
}
// select, delete, update
if isFullNot {
b.WhereRaw("false")
} else if subTables != "" {
if t == db.TYPE_SELECT {
b.Table(subTables, b.TableAlias)
} else {
b.WhereRaw(fmt.Sprintf("id in (SELECT temp.id FROM (%s) as temp)", subTables))
}
}
return nil
} }
// 获取鉴权条件 // 获取鉴权条件
func (this Resource) GetRolesCondition(u contracts.User) *db.Builder { func (this Resource) GetRolesCondition(u contracts.User) *db.Builder {
// isFullRight := false isFullRight := false
// isFullNot := false isFullNot := false
// NewOrmJoin := do.MustInvoke[helper.NewOrmJoin](this.container) // NewOrmJoin := do.MustInvoke[helper.NewOrmJoin](this.container)
// GetResRelations := do.MustInvoke[GetResRelations](this.container) // GetResRelations := do.MustInvoke[GetResRelations](this.container)
@ -277,6 +363,17 @@ func (this Resource) GetRolesCondition(u contracts.User) *db.Builder {
// } else if subTables != "" { // } else if subTables != "" {
// this.GetDB().Table(subTables, this.GetCode()) // this.GetDB().Table(subTables, this.GetCode())
// } // }
// @todo this.GetCode 要换成 alias
if isFullRight {
return this.Route.GetResource().GetDB().Table(string(this.GetTable()), this.GetCode())
} else if isFullNot {
return this.Route.GetResource().GetDB().Table(string(this.GetTable()), this.GetCode()).WhereRaw("false")
} else if subTables != "" {
return this.Route.GetResource().GetDB().Table(subTables, this.GetCode())
}
return this.Route.GetResource().GetDB().Table(string(this.GetTable()), this.GetCode())
return this.GetDB().Table(string(this.GetTable()), this.GetCode()) return this.GetDB().Table(string(this.GetTable()), this.GetCode())
} }

View File

@ -54,8 +54,7 @@ type Resource interface {
GetStruct(extends ...reflect.StructField) any GetStruct(extends ...reflect.StructField) any
GetSliceStruct(extends ...reflect.StructField) any GetSliceStruct(extends ...reflect.StructField) any
WithRolesCondition(b *db.Builder, roles ...string) WithRolesCondition(b *db.Builder, t string, roles ...string) error
// GetRolesCondition(u User)
// 是否虚拟资源 // 是否虚拟资源
IsVirtual() bool IsVirtual() bool