|
|
@@ -0,0 +1,162 @@
|
|
|
+package api
|
|
|
+
|
|
|
+import (
|
|
|
+ "net/url"
|
|
|
+ "reflect"
|
|
|
+ "regexp"
|
|
|
+ "strconv"
|
|
|
+ "strings"
|
|
|
+
|
|
|
+ "git.sxidc.com/go-framework/baize/framework/core/infrastructure/logger"
|
|
|
+ "git.sxidc.com/go-tools/utils/strutils"
|
|
|
+ "git.sxidc.com/go-tools/utils/template"
|
|
|
+ "github.com/pkg/errors"
|
|
|
+)
|
|
|
+
|
|
|
+type UrlInstruction interface {
|
|
|
+ FormUrlInstruction() (string, error)
|
|
|
+}
|
|
|
+
|
|
|
+func FormUrlInstruction(instructions ...UrlInstruction) string {
|
|
|
+ urlInstructions := make([]string, 0)
|
|
|
+ for _, instruction := range instructions {
|
|
|
+ urlInstruction, err := instruction.FormUrlInstruction()
|
|
|
+ if err != nil {
|
|
|
+ panic(err)
|
|
|
+ }
|
|
|
+
|
|
|
+ urlInstructions = append(urlInstructions, urlInstruction)
|
|
|
+ }
|
|
|
+
|
|
|
+ return "${" + strings.Join(urlInstructions, " ") + "}$"
|
|
|
+}
|
|
|
+
|
|
|
+const (
|
|
|
+ permUrlInstructionTpl = `perm:"group:{{ .Group }};name:{{ .Name }};{{- if .Description -}}description:{{ .Description }};{{- end -}}{{- if .NeedCheckExpire -}}needCheckExpire;{{- end -}}{{- if .SensitiveWordScene -}}sensitiveWordScene:{{ .SensitiveWordScene }};{{- end -}}"`
|
|
|
+)
|
|
|
+
|
|
|
+type PermUrlInstruction struct {
|
|
|
+ Group string
|
|
|
+ Name string
|
|
|
+ Description string
|
|
|
+ NeedCheckExpire bool
|
|
|
+ SensitiveWordScene int
|
|
|
+}
|
|
|
+
|
|
|
+func (cmd *PermUrlInstruction) check() error {
|
|
|
+ if strutils.IsStringEmpty(cmd.Group) {
|
|
|
+ return errors.New("没有传递权限组")
|
|
|
+ }
|
|
|
+
|
|
|
+ if strutils.IsStringEmpty(cmd.Name) {
|
|
|
+ return errors.New("没有传递权限名称")
|
|
|
+ }
|
|
|
+
|
|
|
+ return nil
|
|
|
+}
|
|
|
+
|
|
|
+func (cmd *PermUrlInstruction) FormUrlInstruction() (string, error) {
|
|
|
+ err := cmd.check()
|
|
|
+ if err != nil {
|
|
|
+ return "", err
|
|
|
+ }
|
|
|
+
|
|
|
+ permUrlInstruction, err := template.ParseTemplateStringToString(permUrlInstructionTpl, cmd)
|
|
|
+ if err != nil {
|
|
|
+ return "", err
|
|
|
+ }
|
|
|
+
|
|
|
+ return permUrlInstruction, nil
|
|
|
+}
|
|
|
+
|
|
|
+// Perm指令定义
|
|
|
+
|
|
|
+const (
|
|
|
+ tagPartSeparator = ";"
|
|
|
+ tagPartKeyValueSeparator = ":"
|
|
|
+)
|
|
|
+
|
|
|
+const (
|
|
|
+ permTagKey = "perm"
|
|
|
+ permTagPartGroup = "group"
|
|
|
+ permTagPartName = "name"
|
|
|
+ permTagPartDescription = "description"
|
|
|
+ permTagPartNeedCheckExpire = "needCheckExpire"
|
|
|
+ permTagPartSensitiveWordScene = "sensitiveWordScene"
|
|
|
+)
|
|
|
+
|
|
|
+func parseRelativePathPerm(basePath string, relativePathPattern string, method string) (string, *PermissionItem, error) {
|
|
|
+ re := regexp.MustCompile(`\$\{(.+)\}\$`)
|
|
|
+ matches := re.FindStringSubmatch(relativePathPattern)
|
|
|
+
|
|
|
+ if len(matches) == 0 {
|
|
|
+ return relativePathPattern, nil, nil
|
|
|
+ }
|
|
|
+
|
|
|
+ relativePath := re.ReplaceAllString(relativePathPattern, "")
|
|
|
+ permTag, ok := reflect.StructTag(matches[1]).Lookup(permTagKey)
|
|
|
+ if !ok {
|
|
|
+ return relativePath, nil, nil
|
|
|
+ }
|
|
|
+
|
|
|
+ tagParts := strings.Split(permTag, tagPartSeparator)
|
|
|
+ if tagParts == nil || len(tagParts) == 0 {
|
|
|
+ return relativePath, nil, nil
|
|
|
+ }
|
|
|
+
|
|
|
+ fullPath, err := url.JoinPath(basePath, relativePath)
|
|
|
+ if err != nil {
|
|
|
+ return "", nil, err
|
|
|
+ }
|
|
|
+
|
|
|
+ permissionItem := &PermissionItem{
|
|
|
+ Group: "",
|
|
|
+ Name: "",
|
|
|
+ Description: "",
|
|
|
+ Resource: fullPath,
|
|
|
+ Action: method,
|
|
|
+ NeedCheckExpire: false,
|
|
|
+ SensitiveWordScene: 0,
|
|
|
+ }
|
|
|
+
|
|
|
+ for _, tagPart := range tagParts {
|
|
|
+ tagPartKeyValue := strings.SplitN(strings.TrimSpace(tagPart), tagPartKeyValueSeparator, 2)
|
|
|
+
|
|
|
+ if strutils.IsStringEmpty(tagPartKeyValue[0]) {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+
|
|
|
+ switch tagPartKeyValue[0] {
|
|
|
+ case permTagPartGroup:
|
|
|
+ permissionItem.Group = tagPartKeyValue[1]
|
|
|
+ case permTagPartName:
|
|
|
+ permissionItem.Name = tagPartKeyValue[1]
|
|
|
+ case permTagPartDescription:
|
|
|
+ permissionItem.Description = tagPartKeyValue[1]
|
|
|
+ case permTagPartNeedCheckExpire:
|
|
|
+ permissionItem.NeedCheckExpire = true
|
|
|
+ case permTagPartSensitiveWordScene:
|
|
|
+ scene, err := strconv.Atoi(tagPartKeyValue[1])
|
|
|
+ if err != nil {
|
|
|
+ return relativePath, nil, err
|
|
|
+ }
|
|
|
+
|
|
|
+ if scene < 1 || scene > 4 {
|
|
|
+ return relativePath, nil, errors.New("不支持的敏感词场景: " + tagPartKeyValue[1])
|
|
|
+ }
|
|
|
+
|
|
|
+ permissionItem.SensitiveWordScene = scene
|
|
|
+ default:
|
|
|
+ err := errors.New(permTagKey + "不支持的tag: " + tagPartKeyValue[0])
|
|
|
+ logger.GetInstance().Error(err)
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ err = permissionItem.check()
|
|
|
+ if err != nil {
|
|
|
+ return "", nil, err
|
|
|
+ }
|
|
|
+
|
|
|
+ return relativePath, permissionItem, nil
|
|
|
+}
|