package privilege import ( "fmt" "strings" "esway/internal/model" "github.com/loveuer/nf" "github.com/loveuer/nf/nft/log" "github.com/loveuer/nf/nft/resp" "github.com/samber/lo" ) type Relation int64 type vf func(user *model.User, ps ...model.Privilege) error const ( RelationAnd Relation = iota + 1 RelationOr ) var ( AndFunc vf = func(user *model.User, ps ...model.Privilege) error { pm := lo.SliceToMap(user.Privileges, func(item model.Privilege) (int64, struct{}) { return item.Value(), struct{}{} }) for _, p := range ps { if _, exist := pm[p.Value()]; !exist { return fmt.Errorf("缺少权限: %d, %s, %s", p.Value(), p.Code(), p.Label()) } } return nil } OrFunc vf = func(user *model.User, ps ...model.Privilege) error { pm := lo.SliceToMap(user.Privileges, func(item model.Privilege) (int64, struct{}) { return item.Value(), struct{}{} }) for _, p := range ps { if _, exist := pm[p.Value()]; exist { return nil } } return fmt.Errorf("缺少权限: %s", strings.Join( lo.Map(ps, func(item model.Privilege, index int) string { return item.Code() }), ", ", )) } ) func Verify(relation Relation, privileges ...model.Privilege) nf.HandlerFunc { var _vf vf switch relation { case RelationAnd: _vf = AndFunc case RelationOr: _vf = OrFunc default: log.Panic("middleware.Verify: unknown relation") } return func(c *nf.Ctx) error { if len(privileges) == 0 { return c.Next() } op, ok := c.Locals("user").(*model.User) if !ok { return resp.Resp401(c, nil) } if err := _vf(op, privileges...); err != nil { return resp.Resp403(c, err.Error()) } return c.Next() } }