roles.go 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. package model
  2. import (
  3. "context"
  4. "errors"
  5. "icloudapp.cn/tools/service"
  6. utString "icloudapp.cn/tools/util/string"
  7. url2 "icloudapp.cn/tools/util/url"
  8. "net/url"
  9. "strings"
  10. )
  11. type MRoles struct {
  12. ctx context.Context
  13. }
  14. func NewMRoles(ctx context.Context) *MRoles {
  15. return &MRoles{
  16. ctx: ctx,
  17. }
  18. }
  19. func (r *MRoles) Verify(uid int64, URL *url.URL) (bool, error) {
  20. if uid == 0 {
  21. return false, errors.New("请先登录后再试")
  22. }
  23. userGroups := service.NewUserGroup(r.ctx).UserGroups(uid)
  24. if userGroups == nil {
  25. return false, errors.New("无访问组权限")
  26. }
  27. splitGroups := strings.Split(userGroups.Groups, ",")
  28. var groupsID []int64
  29. for _, v := range splitGroups {
  30. groupsID = append(groupsID, utString.ConvertInt64(v))
  31. }
  32. if len(groupsID) == 0 {
  33. return false, errors.New("无访问组权限")
  34. }
  35. //获取分组对应的权限
  36. groupsField, _ := service.NewGroup(r.ctx).Infos(groupsID...)
  37. if groupsField == nil {
  38. return false, errors.New("无权限访问")
  39. }
  40. var rolesID strings.Builder
  41. for _, v := range groupsField {
  42. if v == nil {
  43. continue
  44. }
  45. rolesID.WriteString(v.Roles + ",")
  46. }
  47. //获取权限对应的model
  48. roles := uniqueToInt64(rolesID.String(), ",")
  49. if len(roles) == 0 {
  50. return false, errors.New("无权限访问")
  51. }
  52. mRole := service.NewRoles(r.ctx)
  53. modelsField, _ := mRole.Infos(roles...)
  54. if modelsField == nil {
  55. return false, errors.New("无模块访问权限")
  56. }
  57. var modelIds strings.Builder
  58. for _, v := range modelsField {
  59. modelIds.WriteString(v.ModelIds + ",")
  60. }
  61. //获取对应的model
  62. modulesId := uniqueToInt64(modelIds.String(), ",")
  63. modules := service.NewModule(r.ctx)
  64. moduleField, _ := modules.Infos(modulesId...)
  65. if moduleField == nil {
  66. return false, errors.New("无模块访问权限")
  67. }
  68. //验证request是否有权限
  69. matchedURL := make([]string, 0)
  70. for _, module := range moduleField {
  71. moduleURL := module.ModelURL
  72. //设置的url和请求的path一样直接通过,如果是带参数或*需要额外处理
  73. if moduleURL == URL.Path {
  74. return true, nil
  75. } else if strings.Contains(moduleURL, URL.Path) {
  76. matchedURL = append(matchedURL, moduleURL)
  77. } else if strings.Contains(moduleURL, ".*") {
  78. //如果是以.*结尾的,将modelURL才分成两部分,前半部分能匹配上当前的url就可以
  79. urlSplit := strings.Split(moduleURL, ",")
  80. if strings.Contains(URL.String(), urlSplit[0]) {
  81. return true, nil
  82. }
  83. }
  84. }
  85. if len(matchedURL) == 0 {
  86. return false, errors.New("无模块访问权限")
  87. }
  88. for _, singleURL := range matchedURL {
  89. //这里需要区分url中有没有参数,没有参数就直接过,有参数就再验证参数
  90. parseString, _ := url2.ParseString(singleURL)
  91. queries := parseString.Query()
  92. for name, _ := range queries {
  93. if queries.Get(name) != URL.Query().Get(name) {
  94. return false, errors.New("权限无匹配")
  95. }
  96. }
  97. }
  98. return true, nil
  99. }
  100. func splitStrToInt64(str, sep string) []int64 {
  101. splitSlice := strings.Split(str, sep)
  102. var res []int64
  103. for _, v := range splitSlice {
  104. res = append(res, utString.ConvertInt64(v))
  105. }
  106. return res
  107. }
  108. func uniqueToInt64(str, sep string) []int64 {
  109. var res []int64
  110. splitSlice := splitStrToInt64(str, sep)
  111. splitMap := make(map[int64]bool, 0)
  112. for _, v := range splitSlice {
  113. if v == 0 {
  114. continue
  115. }
  116. if _, ok := splitMap[v]; ok {
  117. continue
  118. }
  119. splitMap[v] = true
  120. res = append(res, v)
  121. }
  122. return res
  123. }