url_instruction.go 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  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 -}}{{- if .Privilege -}}privilege;{{- end -}}"`
  38. )
  39. type PermUrlInstruction struct {
  40. Group string
  41. Name string
  42. Description string
  43. NeedCheckExpire bool
  44. SensitiveWordScene int
  45. Privilege bool
  46. }
  47. func (cmd *PermUrlInstruction) check() error {
  48. if strutils.IsStringEmpty(cmd.Group) {
  49. return errors.New("没有传递权限组")
  50. }
  51. if strutils.IsStringEmpty(cmd.Name) {
  52. return errors.New("没有传递权限名称")
  53. }
  54. return nil
  55. }
  56. func (cmd *PermUrlInstruction) FormUrlInstruction() (string, error) {
  57. err := cmd.check()
  58. if err != nil {
  59. return "", err
  60. }
  61. permUrlInstruction, err := template.ParseTemplateStringToString(permUrlInstructionTpl, cmd)
  62. if err != nil {
  63. return "", err
  64. }
  65. return permUrlInstruction, nil
  66. }
  67. // Perm指令定义
  68. const (
  69. tagPartSeparator = ";"
  70. tagPartKeyValueSeparator = ":"
  71. )
  72. const (
  73. permTagKey = "perm"
  74. permTagPartGroup = "group"
  75. permTagPartName = "name"
  76. permTagPartDescription = "description"
  77. permTagPartNeedCheckExpire = "needCheckExpire"
  78. permTagPartSensitiveWordScene = "sensitiveWordScene"
  79. permTagPartPrivilege = "privilege"
  80. )
  81. func parseRelativePathPerm(basePath string, relativePathPattern string, method string) (string, *PermissionItem, error) {
  82. re := regexp.MustCompile(`\$\{(.+)\}\$`)
  83. matches := re.FindStringSubmatch(relativePathPattern)
  84. if len(matches) == 0 {
  85. return relativePathPattern, nil, nil
  86. }
  87. relativePath := re.ReplaceAllString(relativePathPattern, "")
  88. permTag, ok := reflect.StructTag(matches[1]).Lookup(permTagKey)
  89. if !ok {
  90. return relativePath, nil, nil
  91. }
  92. tagParts := strings.Split(permTag, tagPartSeparator)
  93. if tagParts == nil || len(tagParts) == 0 {
  94. return relativePath, nil, nil
  95. }
  96. fullPath, err := url.JoinPath(basePath, relativePath)
  97. if err != nil {
  98. return "", nil, err
  99. }
  100. permissionItem := &PermissionItem{
  101. Group: "",
  102. Name: "",
  103. Description: "",
  104. Resource: fullPath,
  105. Action: method,
  106. NeedCheckExpire: false,
  107. SensitiveWordScene: 0,
  108. Privilege: false,
  109. }
  110. for _, tagPart := range tagParts {
  111. tagPartKeyValue := strings.SplitN(strings.TrimSpace(tagPart), tagPartKeyValueSeparator, 2)
  112. if strutils.IsStringEmpty(tagPartKeyValue[0]) {
  113. continue
  114. }
  115. switch tagPartKeyValue[0] {
  116. case permTagPartGroup:
  117. permissionItem.Group = tagPartKeyValue[1]
  118. case permTagPartName:
  119. permissionItem.Name = tagPartKeyValue[1]
  120. case permTagPartDescription:
  121. permissionItem.Description = tagPartKeyValue[1]
  122. case permTagPartNeedCheckExpire:
  123. permissionItem.NeedCheckExpire = true
  124. case permTagPartSensitiveWordScene:
  125. scene, err := strconv.Atoi(tagPartKeyValue[1])
  126. if err != nil {
  127. return relativePath, nil, err
  128. }
  129. if scene < 1 || scene > 4 {
  130. return relativePath, nil, errors.New("不支持的敏感词场景: " + tagPartKeyValue[1])
  131. }
  132. permissionItem.SensitiveWordScene = scene
  133. case permTagPartPrivilege:
  134. permissionItem.Privilege = true
  135. default:
  136. err := errors.New(permTagKey + "不支持的tag: " + tagPartKeyValue[0])
  137. logger.GetInstance().Error(err)
  138. continue
  139. }
  140. }
  141. err = permissionItem.check()
  142. if err != nil {
  143. return "", nil, err
  144. }
  145. return relativePath, permissionItem, nil
  146. }