casbin.go 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. package service
  2. import (
  3. "dy-admin/internal/pcmserver/global"
  4. "dy-admin/internal/pcmserver/pkg/code"
  5. "dy-admin/internal/pcmserver/sys/model/request"
  6. "dy-admin/pkg/log"
  7. "dy-admin/pkg/rescode"
  8. "github.com/casbin/casbin/v2"
  9. "github.com/casbin/casbin/v2/model"
  10. gormadapter "github.com/casbin/gorm-adapter/v3"
  11. "go.uber.org/zap"
  12. "strconv"
  13. "sync"
  14. )
  15. type CasbinService struct{}
  16. var CasbinServiceInstance = new(CasbinService)
  17. // UpdateCasbin 更新角色对应的casbin权限规则
  18. func (cs *CasbinService) UpdateCasbin(roleId int, casbinInfos []request.CasbinInfo) error {
  19. roleIdStr := strconv.Itoa(roleId)
  20. cs.ClearCasbin(0, roleIdStr)
  21. rules := make([][]string, 0, len(casbinInfos))
  22. for _, v := range casbinInfos {
  23. rules = append(rules, []string{roleIdStr, v.Path, v.Action})
  24. }
  25. e := cs.Casbin()
  26. success, err := e.AddPolicies(rules)
  27. if !success {
  28. return rescode.RegisterErrorWithCause(err, code.ErrCodeMap[code.ErrCasbinInternalCode])
  29. }
  30. err = e.InvalidateCache()
  31. if err != nil {
  32. return rescode.RegisterErrorWithCause(err, code.ErrCodeMap[code.ErrCasbinInternalCode])
  33. }
  34. return nil
  35. }
  36. // UpdateCasbinApi 更新casbinApi
  37. func (cs *CasbinService) UpdateCasbinApi(oldPath string, newPath string, oldMethod string, newMethod string) error {
  38. global.DB.Model(&gormadapter.CasbinRule{}).Where("v1 = ? AND v2 = ?", oldPath, oldMethod).Updates(map[string]interface{}{
  39. "v1": newPath,
  40. "v2": newMethod,
  41. })
  42. e := cs.Casbin()
  43. err := e.InvalidateCache()
  44. if err != nil {
  45. return rescode.RegisterErrorWithCause(err, code.ErrCodeMap[code.ErrCasbinInternalCode])
  46. }
  47. return nil
  48. }
  49. // GetPolicyPathByAuthorityId 获取权限列表
  50. func (cs *CasbinService) GetPolicyPathByAuthorityId(roleID uint) (pathMaps []request.CasbinInfo) {
  51. e := cs.Casbin()
  52. roleIDStr := strconv.Itoa(int(roleID))
  53. list := e.GetFilteredPolicy(0, roleIDStr)
  54. for _, v := range list {
  55. pathMaps = append(pathMaps, request.CasbinInfo{
  56. Path: v[1],
  57. Action: v[2],
  58. })
  59. }
  60. return pathMaps
  61. }
  62. func (cs *CasbinService) ClearCasbin(v int, p ...string) (bool, error) {
  63. e := cs.Casbin()
  64. success, err := e.RemoveFilteredPolicy(v, p...)
  65. return success, err
  66. }
  67. var (
  68. cachedEnforcer *casbin.CachedEnforcer
  69. once sync.Once
  70. )
  71. func (cs *CasbinService) Casbin() *casbin.CachedEnforcer {
  72. once.Do(func() {
  73. a, _ := gormadapter.NewAdapterByDB(global.DB)
  74. text := `
  75. [request_definition]
  76. r = sub, obj, act
  77. [policy_definition]
  78. p = sub, obj, act
  79. [role_definition]
  80. g = _, _
  81. [policy_effect]
  82. e = some(where (p.eft == allow))
  83. [matchers]
  84. m = r.sub == p.sub && keyMatch(r.obj,p.obj) && r.act == p.act
  85. `
  86. m, err := model.NewModelFromString(text)
  87. if err != nil {
  88. log.Error("字符串加载模型失败!", zap.Error(err))
  89. return
  90. }
  91. cachedEnforcer, _ = casbin.NewCachedEnforcer(m, a)
  92. cachedEnforcer.SetExpireTime(60 * 60)
  93. _ = cachedEnforcer.LoadPolicy()
  94. })
  95. return cachedEnforcer
  96. }