quota.go 2.3 KB

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