api_events.go 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. package httpd
  2. import (
  3. "fmt"
  4. "net/http"
  5. "strconv"
  6. "github.com/sftpgo/sdk/plugin/eventsearcher"
  7. "github.com/drakkan/sftpgo/v2/dataprovider"
  8. "github.com/drakkan/sftpgo/v2/plugin"
  9. "github.com/drakkan/sftpgo/v2/util"
  10. )
  11. func getCommonSearchParamsFromRequest(r *http.Request) (eventsearcher.CommonSearchParams, error) {
  12. c := eventsearcher.CommonSearchParams{}
  13. c.Limit = 100
  14. if _, ok := r.URL.Query()["limit"]; ok {
  15. limit, err := strconv.Atoi(r.URL.Query().Get("limit"))
  16. if err != nil {
  17. return c, util.NewValidationError(fmt.Sprintf("invalid limit: %v", err))
  18. }
  19. if limit < 1 || limit > 1000 {
  20. return c, util.NewValidationError(fmt.Sprintf("limit is out of the 1-1000 range: %v", limit))
  21. }
  22. c.Limit = limit
  23. }
  24. if _, ok := r.URL.Query()["order"]; ok {
  25. order := r.URL.Query().Get("order")
  26. if order != dataprovider.OrderASC && order != dataprovider.OrderDESC {
  27. return c, util.NewValidationError(fmt.Sprintf("invalid order %#v", order))
  28. }
  29. if order == dataprovider.OrderASC {
  30. c.Order = 1
  31. }
  32. }
  33. if _, ok := r.URL.Query()["start_timestamp"]; ok {
  34. ts, err := strconv.ParseInt(r.URL.Query().Get("start_timestamp"), 10, 64)
  35. if err != nil {
  36. return c, util.NewValidationError(fmt.Sprintf("invalid start_timestamp: %v", err))
  37. }
  38. c.StartTimestamp = ts
  39. }
  40. if _, ok := r.URL.Query()["end_timestamp"]; ok {
  41. ts, err := strconv.ParseInt(r.URL.Query().Get("end_timestamp"), 10, 64)
  42. if err != nil {
  43. return c, util.NewValidationError(fmt.Sprintf("invalid end_timestamp: %v", err))
  44. }
  45. c.EndTimestamp = ts
  46. }
  47. c.Actions = getCommaSeparatedQueryParam(r, "actions")
  48. c.Username = r.URL.Query().Get("username")
  49. c.IP = r.URL.Query().Get("ip")
  50. c.InstanceIDs = getCommaSeparatedQueryParam(r, "instance_ids")
  51. c.ExcludeIDs = getCommaSeparatedQueryParam(r, "exclude_ids")
  52. return c, nil
  53. }
  54. func getFsSearchParamsFromRequest(r *http.Request) (eventsearcher.FsEventSearch, error) {
  55. var err error
  56. s := eventsearcher.FsEventSearch{}
  57. s.CommonSearchParams, err = getCommonSearchParamsFromRequest(r)
  58. if err != nil {
  59. return s, err
  60. }
  61. s.FsProvider = -1
  62. if _, ok := r.URL.Query()["fs_provider"]; ok {
  63. provider := r.URL.Query().Get("fs_provider")
  64. val, err := strconv.Atoi(provider)
  65. if err != nil {
  66. return s, util.NewValidationError(fmt.Sprintf("invalid fs_provider: %v", provider))
  67. }
  68. s.FsProvider = val
  69. }
  70. s.IP = r.URL.Query().Get("ip")
  71. s.SSHCmd = r.URL.Query().Get("ssh_cmd")
  72. s.Bucket = r.URL.Query().Get("bucket")
  73. s.Endpoint = r.URL.Query().Get("endpoint")
  74. s.Protocols = getCommaSeparatedQueryParam(r, "protocols")
  75. statuses := getCommaSeparatedQueryParam(r, "statuses")
  76. for _, status := range statuses {
  77. val, err := strconv.Atoi(status)
  78. if err != nil {
  79. return s, util.NewValidationError(fmt.Sprintf("invalid status: %v", status))
  80. }
  81. s.Statuses = append(s.Statuses, int32(val))
  82. }
  83. return s, nil
  84. }
  85. func getProviderSearchParamsFromRequest(r *http.Request) (eventsearcher.ProviderEventSearch, error) {
  86. var err error
  87. s := eventsearcher.ProviderEventSearch{}
  88. s.CommonSearchParams, err = getCommonSearchParamsFromRequest(r)
  89. if err != nil {
  90. return s, err
  91. }
  92. s.ObjectName = r.URL.Query().Get("object_name")
  93. s.ObjectTypes = getCommaSeparatedQueryParam(r, "object_types")
  94. return s, nil
  95. }
  96. func searchFsEvents(w http.ResponseWriter, r *http.Request) {
  97. r.Body = http.MaxBytesReader(w, r.Body, maxRequestSize)
  98. filters, err := getFsSearchParamsFromRequest(r)
  99. if err != nil {
  100. sendAPIResponse(w, r, err, "", getRespStatus(err))
  101. return
  102. }
  103. data, _, _, err := plugin.Handler.SearchFsEvents(&filters)
  104. if err != nil {
  105. sendAPIResponse(w, r, err, "", getRespStatus(err))
  106. return
  107. }
  108. w.Header().Set("Content-Type", "application/json; charset=utf-8")
  109. w.Write(data) //nolint:errcheck
  110. }
  111. func searchProviderEvents(w http.ResponseWriter, r *http.Request) {
  112. r.Body = http.MaxBytesReader(w, r.Body, maxRequestSize)
  113. filters, err := getProviderSearchParamsFromRequest(r)
  114. if err != nil {
  115. sendAPIResponse(w, r, err, "", getRespStatus(err))
  116. return
  117. }
  118. data, _, _, err := plugin.Handler.SearchProviderEvents(&filters)
  119. if err != nil {
  120. sendAPIResponse(w, r, err, "", getRespStatus(err))
  121. return
  122. }
  123. w.Header().Set("Content-Type", "application/json; charset=utf-8")
  124. w.Write(data) //nolint:errcheck
  125. }