url_instruction.go 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. package api
  2. import (
  3. "net/url"
  4. "reflect"
  5. "regexp"
  6. "strconv"
  7. "strings"
  8. "git.sxidc.com/go-framework/baize/framework/core/infrastructure/logger"
  9. "git.sxidc.com/go-tools/utils/strutils"
  10. "git.sxidc.com/go-tools/utils/template"
  11. "github.com/pkg/errors"
  12. )
  13. type UrlInstruction interface {
  14. FormUrlInstruction() (string, error)
  15. }
  16. func FormUrlInstruction(instructions ...UrlInstruction) string {
  17. if instructions == nil || len(instructions) == 0 {
  18. return ""
  19. }
  20. urlInstructions := make([]string, 0)
  21. for _, instruction := range instructions {
  22. if instruction == nil {
  23. continue
  24. }
  25. urlInstruction, err := instruction.FormUrlInstruction()
  26. if err != nil {
  27. panic(err)
  28. }
  29. urlInstructions = append(urlInstructions, urlInstruction)
  30. }
  31. if urlInstructions == nil || len(urlInstructions) == 0 {
  32. return ""
  33. }
  34. return "${" + strings.Join(urlInstructions, " ") + "}$"
  35. }
  36. const (
  37. permUrlInstructionTpl = `perm:"group:{{ .Group }};name:{{ .Name }};{{- if .Description -}}description:{{ .Description }};{{- end -}}{{- if .NeedCheckExpire -}}needCheckExpire;{{- end -}}{{- if .SensitiveWordScene -}}sensitiveWordScene:{{ .SensitiveWordScene }};{{- end -}}"`
  38. )
  39. type PermUrlInstruction struct {
  40. Group string
  41. Name string
  42. Description string
  43. NeedCheckExpire bool
  44. SensitiveWordScene int
  45. }
  46. func (cmd *PermUrlInstruction) check() error {
  47. if strutils.IsStringEmpty(cmd.Group) {
  48. return errors.New("没有传递权限组")
  49. }
  50. if strutils.IsStringEmpty(cmd.Name) {
  51. return errors.New("没有传递权限名称")
  52. }
  53. return nil
  54. }
  55. func (cmd *PermUrlInstruction) FormUrlInstruction() (string, error) {
  56. err := cmd.check()
  57. if err != nil {
  58. return "", err
  59. }
  60. permUrlInstruction, err := template.ParseTemplateStringToString(permUrlInstructionTpl, cmd)
  61. if err != nil {
  62. return "", err
  63. }
  64. return permUrlInstruction, nil
  65. }
  66. // Perm指令定义
  67. const (
  68. tagPartSeparator = ";"
  69. tagPartKeyValueSeparator = ":"
  70. )
  71. const (
  72. permTagKey = "perm"
  73. permTagPartGroup = "group"
  74. permTagPartName = "name"
  75. permTagPartDescription = "description"
  76. permTagPartNeedCheckExpire = "needCheckExpire"
  77. permTagPartSensitiveWordScene = "sensitiveWordScene"
  78. )
  79. func parseRelativePathPerm(basePath string, relativePathPattern string, method string) (string, *PermissionItem, error) {
  80. re := regexp.MustCompile(`\$\{(.+)\}\$`)
  81. matches := re.FindStringSubmatch(relativePathPattern)
  82. if len(matches) == 0 {
  83. return relativePathPattern, nil, nil
  84. }
  85. relativePath := re.ReplaceAllString(relativePathPattern, "")
  86. permTag, ok := reflect.StructTag(matches[1]).Lookup(permTagKey)
  87. if !ok {
  88. return relativePath, nil, nil
  89. }
  90. tagParts := strings.Split(permTag, tagPartSeparator)
  91. if tagParts == nil || len(tagParts) == 0 {
  92. return relativePath, nil, nil
  93. }
  94. fullPath, err := url.JoinPath(basePath, relativePath)
  95. if err != nil {
  96. return "", nil, err
  97. }
  98. permissionItem := &PermissionItem{
  99. Group: "",
  100. Name: "",
  101. Description: "",
  102. Resource: fullPath,
  103. Action: method,
  104. NeedCheckExpire: false,
  105. SensitiveWordScene: 0,
  106. }
  107. for _, tagPart := range tagParts {
  108. tagPartKeyValue := strings.SplitN(strings.TrimSpace(tagPart), tagPartKeyValueSeparator, 2)
  109. if strutils.IsStringEmpty(tagPartKeyValue[0]) {
  110. continue
  111. }
  112. switch tagPartKeyValue[0] {
  113. case permTagPartGroup:
  114. permissionItem.Group = tagPartKeyValue[1]
  115. case permTagPartName:
  116. permissionItem.Name = tagPartKeyValue[1]
  117. case permTagPartDescription:
  118. permissionItem.Description = tagPartKeyValue[1]
  119. case permTagPartNeedCheckExpire:
  120. permissionItem.NeedCheckExpire = true
  121. case permTagPartSensitiveWordScene:
  122. scene, err := strconv.Atoi(tagPartKeyValue[1])
  123. if err != nil {
  124. return relativePath, nil, err
  125. }
  126. if scene < 1 || scene > 4 {
  127. return relativePath, nil, errors.New("不支持的敏感词场景: " + tagPartKeyValue[1])
  128. }
  129. permissionItem.SensitiveWordScene = scene
  130. default:
  131. err := errors.New(permTagKey + "不支持的tag: " + tagPartKeyValue[0])
  132. logger.GetInstance().Error(err)
  133. continue
  134. }
  135. }
  136. err = permissionItem.check()
  137. if err != nil {
  138. return "", nil, err
  139. }
  140. return relativePath, permissionItem, nil
  141. }