You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

136 lines
3.9 KiB

3 years ago
3 years ago
3 years ago
  1. package system
  2. import (
  3. "errors"
  4. "strings"
  5. "sync"
  6. "github.com/casbin/casbin/v2"
  7. "github.com/casbin/casbin/v2/util"
  8. gormadapter "github.com/casbin/gorm-adapter/v3"
  9. "github.com/flipped-aurora/gin-vue-admin/server/global"
  10. "github.com/flipped-aurora/gin-vue-admin/server/model/system"
  11. "github.com/flipped-aurora/gin-vue-admin/server/model/system/request"
  12. _ "github.com/go-sql-driver/mysql"
  13. )
  14. //@author: [piexlmax](https://github.com/piexlmax)
  15. //@function: UpdateCasbin
  16. //@description: 更新casbin权限
  17. //@param: authorityId string, casbinInfos []request.CasbinInfo
  18. //@return: error
  19. type CasbinService struct {
  20. }
  21. var CasbinServiceApp = new(CasbinService)
  22. func (casbinService *CasbinService) UpdateCasbin(authorityId string, casbinInfos []request.CasbinInfo) error {
  23. casbinService.ClearCasbin(0, authorityId)
  24. rules := [][]string{}
  25. for _, v := range casbinInfos {
  26. cm := system.CasbinModel{
  27. Ptype: "p",
  28. AuthorityId: authorityId,
  29. Path: v.Path,
  30. Method: v.Method,
  31. }
  32. rules = append(rules, []string{cm.AuthorityId, cm.Path, cm.Method})
  33. }
  34. e := casbinService.Casbin()
  35. success, _ := e.AddPolicies(rules)
  36. if success == false {
  37. return errors.New("存在相同api,添加失败,请联系管理员")
  38. }
  39. return nil
  40. }
  41. //@author: [piexlmax](https://github.com/piexlmax)
  42. //@function: UpdateCasbinApi
  43. //@description: API更新随动
  44. //@param: oldPath string, newPath string, oldMethod string, newMethod string
  45. //@return: error
  46. func (casbinService *CasbinService) UpdateCasbinApi(oldPath string, newPath string, oldMethod string, newMethod string) error {
  47. err := global.GVA_DB.Table("casbin_rule").Model(&system.CasbinModel{}).Where("v1 = ? AND v2 = ?", oldPath, oldMethod).Updates(map[string]interface{}{
  48. "v1": newPath,
  49. "v2": newMethod,
  50. }).Error
  51. return err
  52. }
  53. //@author: [piexlmax](https://github.com/piexlmax)
  54. //@function: GetPolicyPathByAuthorityId
  55. //@description: 获取权限列表
  56. //@param: authorityId string
  57. //@return: pathMaps []request.CasbinInfo
  58. func (casbinService *CasbinService) GetPolicyPathByAuthorityId(authorityId string) (pathMaps []request.CasbinInfo) {
  59. e := casbinService.Casbin()
  60. list := e.GetFilteredPolicy(0, authorityId)
  61. for _, v := range list {
  62. pathMaps = append(pathMaps, request.CasbinInfo{
  63. Path: v[1],
  64. Method: v[2],
  65. })
  66. }
  67. return pathMaps
  68. }
  69. //@author: [piexlmax](https://github.com/piexlmax)
  70. //@function: ClearCasbin
  71. //@description: 清除匹配的权限
  72. //@param: v int, p ...string
  73. //@return: bool
  74. func (casbinService *CasbinService) ClearCasbin(v int, p ...string) bool {
  75. e := casbinService.Casbin()
  76. success, _ := e.RemoveFilteredPolicy(v, p...)
  77. return success
  78. }
  79. //@author: [piexlmax](https://github.com/piexlmax)
  80. //@function: Casbin
  81. //@description: 持久化到数据库 引入自定义规则
  82. //@return: *casbin.Enforcer
  83. var (
  84. syncedEnforcer *casbin.SyncedEnforcer
  85. once sync.Once
  86. )
  87. func (casbinService *CasbinService) Casbin() *casbin.SyncedEnforcer {
  88. once.Do(func() {
  89. a, _ := gormadapter.NewAdapterByDB(global.GVA_DB)
  90. syncedEnforcer, _ = casbin.NewSyncedEnforcer(global.GVA_CONFIG.Casbin.ModelPath, a)
  91. syncedEnforcer.AddFunction("ParamsMatch", casbinService.ParamsMatchFunc)
  92. })
  93. _ = syncedEnforcer.LoadPolicy()
  94. return syncedEnforcer
  95. }
  96. //@author: [piexlmax](https://github.com/piexlmax)
  97. //@function: ParamsMatch
  98. //@description: 自定义规则函数
  99. //@param: fullNameKey1 string, key2 string
  100. //@return: bool
  101. func (casbinService *CasbinService) ParamsMatch(fullNameKey1 string, key2 string) bool {
  102. key1 := strings.Split(fullNameKey1, "?")[0]
  103. // 剥离路径后再使用casbin的keyMatch2
  104. return util.KeyMatch2(key1, key2)
  105. }
  106. //@author: [piexlmax](https://github.com/piexlmax)
  107. //@function: ParamsMatchFunc
  108. //@description: 自定义规则函数
  109. //@param: args ...interface{}
  110. //@return: interface{}, error
  111. func (casbinService *CasbinService) ParamsMatchFunc(args ...interface{}) (interface{}, error) {
  112. name1 := args[0].(string)
  113. name2 := args[1].(string)
  114. return casbinService.ParamsMatch(name1, name2), nil
  115. }