casbin.go 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. package service
  2. import (
  3. "dashoo.cn/micro/app/common/dao"
  4. dbModel "dashoo.cn/micro/app/common/model"
  5. "github.com/casbin/casbin/v2"
  6. "github.com/casbin/casbin/v2/model"
  7. "github.com/casbin/casbin/v2/persist"
  8. "github.com/gogf/gf/frame/g"
  9. "sync"
  10. )
  11. type cabin struct{}
  12. type adapterCasbin struct {
  13. Enforcer *casbin.SyncedEnforcer
  14. EnforcerErr error
  15. }
  16. var (
  17. Casbin = new(cabin)
  18. once sync.Once
  19. m sync.RWMutex
  20. ac *adapterCasbin
  21. )
  22. // GetEnforcer 获取adapter单例对象
  23. func (s *cabin) GetEnforcer() (enforcer *casbin.SyncedEnforcer, err error) {
  24. once.Do(func() {
  25. ac = s.newAdapter()
  26. })
  27. enforcer = ac.Enforcer
  28. err = ac.EnforcerErr
  29. return
  30. }
  31. // 初始化adapter操作
  32. func (s *cabin) newAdapter() (a *adapterCasbin) {
  33. a = new(adapterCasbin)
  34. a.initPolicy()
  35. return
  36. }
  37. func (a *adapterCasbin) initPolicy() {
  38. // Because the DB is empty at first,
  39. // so we need to load the policy from the file adapter (.CSV) first.
  40. e, err := casbin.NewSyncedEnforcer(g.Cfg().GetString("casbin.modelFile"),
  41. g.Cfg().GetString("casbin.policyFile"))
  42. if err != nil {
  43. a.EnforcerErr = err
  44. return
  45. }
  46. // This is a trick to save the current policy to the DB.
  47. // We can't call e.SavePolicy() because the adapter in the enforcer is still the file adapter.
  48. // The current policy means the policy in the Casbin enforcer (aka in memory).
  49. //err = a.SavePolicy(e.GetModel())
  50. //if err != nil {
  51. // return err
  52. //}
  53. //set adapter
  54. e.SetAdapter(a)
  55. // Clear the current policy.
  56. e.ClearPolicy()
  57. a.Enforcer = e
  58. // Load the policy from DB.
  59. err = a.LoadPolicy(e.GetModel())
  60. if err != nil {
  61. a.EnforcerErr = err
  62. return
  63. }
  64. }
  65. // SavePolicy saves policy to database.
  66. func (a *adapterCasbin) SavePolicy(model model.Model) (err error) {
  67. err = a.dropTable()
  68. if err != nil {
  69. return
  70. }
  71. err = a.createTable()
  72. if err != nil {
  73. return
  74. }
  75. for ptype, ast := range model["p"] {
  76. for _, rule := range ast.Policy {
  77. line := savePolicyLine(ptype, rule)
  78. _, err := dao.CasbinRule.Data(line).Insert()
  79. if err != nil {
  80. return err
  81. }
  82. }
  83. }
  84. for ptype, ast := range model["g"] {
  85. for _, rule := range ast.Policy {
  86. line := savePolicyLine(ptype, rule)
  87. _, err := dao.CasbinRule.Data(line).Insert()
  88. if err != nil {
  89. return err
  90. }
  91. }
  92. }
  93. return
  94. }
  95. func (a *adapterCasbin) dropTable() (err error) {
  96. return
  97. }
  98. func (a *adapterCasbin) createTable() (err error) {
  99. return
  100. }
  101. // LoadPolicy loads policy from database.
  102. func (a *adapterCasbin) LoadPolicy(model model.Model) error {
  103. var lines []*dbModel.CasbinRule
  104. if err := dao.CasbinRule.Scan(&lines); err != nil {
  105. return err
  106. }
  107. for _, line := range lines {
  108. loadPolicyLine(line, model)
  109. }
  110. return nil
  111. }
  112. // AddPolicy adds a policy rule to the storage.
  113. func (a *adapterCasbin) AddPolicy(sec string, ptype string, rule []string) error {
  114. line := savePolicyLine(ptype, rule)
  115. _, err := dao.CasbinRule.Data(line).Insert()
  116. return err
  117. }
  118. // RemovePolicy removes a policy rule from the storage.
  119. func (a *adapterCasbin) RemovePolicy(sec string, ptype string, rule []string) error {
  120. line := savePolicyLine(ptype, rule)
  121. err := rawDelete(a, line)
  122. return err
  123. }
  124. // RemoveFilteredPolicy removes policy rules that match the filter from the storage.
  125. func (a *adapterCasbin) RemoveFilteredPolicy(sec string, ptype string,
  126. fieldIndex int, fieldValues ...string) error {
  127. line := &dbModel.CasbinRule{}
  128. line.Ptype = ptype
  129. if fieldIndex <= 0 && 0 < fieldIndex+len(fieldValues) {
  130. line.V0 = fieldValues[0-fieldIndex]
  131. }
  132. if fieldIndex <= 1 && 1 < fieldIndex+len(fieldValues) {
  133. line.V1 = fieldValues[1-fieldIndex]
  134. }
  135. if fieldIndex <= 2 && 2 < fieldIndex+len(fieldValues) {
  136. line.V2 = fieldValues[2-fieldIndex]
  137. }
  138. if fieldIndex <= 3 && 3 < fieldIndex+len(fieldValues) {
  139. line.V3 = fieldValues[3-fieldIndex]
  140. }
  141. if fieldIndex <= 4 && 4 < fieldIndex+len(fieldValues) {
  142. line.V4 = fieldValues[4-fieldIndex]
  143. }
  144. if fieldIndex <= 5 && 5 < fieldIndex+len(fieldValues) {
  145. line.V5 = fieldValues[5-fieldIndex]
  146. }
  147. err := rawDelete(a, line)
  148. return err
  149. }
  150. func loadPolicyLine(line *dbModel.CasbinRule, model model.Model) {
  151. lineText := line.Ptype
  152. if line.V0 != "" {
  153. lineText += ", " + line.V0
  154. }
  155. if line.V1 != "" {
  156. lineText += ", " + line.V1
  157. }
  158. if line.V2 != "" {
  159. lineText += ", " + line.V2
  160. }
  161. if line.V3 != "" {
  162. lineText += ", " + line.V3
  163. }
  164. if line.V4 != "" {
  165. lineText += ", " + line.V4
  166. }
  167. if line.V5 != "" {
  168. lineText += ", " + line.V5
  169. }
  170. persist.LoadPolicyLine(lineText, model)
  171. }
  172. func savePolicyLine(ptype string, rule []string) *dbModel.CasbinRule {
  173. line := &dbModel.CasbinRule{}
  174. line.Ptype = ptype
  175. if len(rule) > 0 {
  176. line.V0 = rule[0]
  177. }
  178. if len(rule) > 1 {
  179. line.V1 = rule[1]
  180. }
  181. if len(rule) > 2 {
  182. line.V2 = rule[2]
  183. }
  184. if len(rule) > 3 {
  185. line.V3 = rule[3]
  186. }
  187. if len(rule) > 4 {
  188. line.V4 = rule[4]
  189. }
  190. if len(rule) > 5 {
  191. line.V5 = rule[5]
  192. }
  193. return line
  194. }
  195. func rawDelete(a *adapterCasbin, line *dbModel.CasbinRule) error {
  196. db := dao.CasbinRule.Where("ptype = ?", line.Ptype)
  197. if line.V0 != "" {
  198. db = db.Where("v0 = ?", line.V0)
  199. }
  200. if line.V1 != "" {
  201. db = db.Where("v1 = ?", line.V1)
  202. }
  203. if line.V2 != "" {
  204. db = db.Where("v2 = ?", line.V2)
  205. }
  206. if line.V3 != "" {
  207. db = db.Where("v3 = ?", line.V3)
  208. }
  209. if line.V4 != "" {
  210. db = db.Where("v4 = ?", line.V4)
  211. }
  212. if line.V5 != "" {
  213. db = db.Where("v5 = ?", line.V5)
  214. }
  215. _, err := db.Delete()
  216. return err
  217. }