quota.go 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. package middleware
  2. import (
  3. "fmt"
  4. "github.com/grafana/grafana/pkg/bus"
  5. m "github.com/grafana/grafana/pkg/models"
  6. "github.com/grafana/grafana/pkg/services/session"
  7. "github.com/grafana/grafana/pkg/setting"
  8. "gopkg.in/macaron.v1"
  9. )
  10. func Quota(target string) macaron.Handler {
  11. return func(c *m.ReqContext) {
  12. limitReached, err := QuotaReached(c, target)
  13. if err != nil {
  14. c.JsonApiErr(500, "failed to get quota", err)
  15. return
  16. }
  17. if limitReached {
  18. c.JsonApiErr(403, fmt.Sprintf("%s Quota reached", target), nil)
  19. return
  20. }
  21. }
  22. }
  23. func QuotaReached(c *m.ReqContext, target string) (bool, error) {
  24. if !setting.Quota.Enabled {
  25. return false, nil
  26. }
  27. // get the list of scopes that this target is valid for. Org, User, Global
  28. scopes, err := m.GetQuotaScopes(target)
  29. if err != nil {
  30. return false, err
  31. }
  32. for _, scope := range scopes {
  33. c.Logger.Debug("Checking quota", "target", target, "scope", scope)
  34. switch scope.Name {
  35. case "global":
  36. if scope.DefaultLimit < 0 {
  37. continue
  38. }
  39. if scope.DefaultLimit == 0 {
  40. return true, nil
  41. }
  42. if target == "session" {
  43. usedSessions := session.GetSessionCount()
  44. if int64(usedSessions) > scope.DefaultLimit {
  45. c.Logger.Debug("Sessions limit reached", "active", usedSessions, "limit", scope.DefaultLimit)
  46. return true, nil
  47. }
  48. continue
  49. }
  50. query := m.GetGlobalQuotaByTargetQuery{Target: scope.Target}
  51. if err := bus.Dispatch(&query); err != nil {
  52. return true, err
  53. }
  54. if query.Result.Used >= scope.DefaultLimit {
  55. return true, nil
  56. }
  57. case "org":
  58. if !c.IsSignedIn {
  59. continue
  60. }
  61. query := m.GetOrgQuotaByTargetQuery{OrgId: c.OrgId, Target: scope.Target, Default: scope.DefaultLimit}
  62. if err := bus.Dispatch(&query); err != nil {
  63. return true, err
  64. }
  65. if query.Result.Limit < 0 {
  66. continue
  67. }
  68. if query.Result.Limit == 0 {
  69. return true, nil
  70. }
  71. if query.Result.Used >= query.Result.Limit {
  72. return true, nil
  73. }
  74. case "user":
  75. if !c.IsSignedIn || c.UserId == 0 {
  76. continue
  77. }
  78. query := m.GetUserQuotaByTargetQuery{UserId: c.UserId, Target: scope.Target, Default: scope.DefaultLimit}
  79. if err := bus.Dispatch(&query); err != nil {
  80. return true, err
  81. }
  82. if query.Result.Limit < 0 {
  83. continue
  84. }
  85. if query.Result.Limit == 0 {
  86. return true, nil
  87. }
  88. if query.Result.Used >= query.Result.Limit {
  89. return true, nil
  90. }
  91. }
  92. }
  93. return false, nil
  94. }