api_events.go 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. package httpd
  2. import (
  3. "fmt"
  4. "net/http"
  5. "strconv"
  6. "github.com/drakkan/sftpgo/v2/dataprovider"
  7. "github.com/drakkan/sftpgo/v2/sdk/plugin"
  8. "github.com/drakkan/sftpgo/v2/sdk/plugin/eventsearcher"
  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. if _, ok := r.URL.Query()["fs_provider"]; ok {
  62. provider := r.URL.Query().Get("fs_provider")
  63. val, err := strconv.Atoi(provider)
  64. if err != nil {
  65. return s, util.NewValidationError(fmt.Sprintf("invalid fs_provider: %v", provider))
  66. }
  67. s.FsProvider = val
  68. }
  69. s.IP = r.URL.Query().Get("ip")
  70. s.SSHCmd = r.URL.Query().Get("ssh_cmd")
  71. s.Bucket = r.URL.Query().Get("bucket")
  72. s.Endpoint = r.URL.Query().Get("endpoint")
  73. s.Protocols = getCommaSeparatedQueryParam(r, "protocols")
  74. statuses := getCommaSeparatedQueryParam(r, "statuses")
  75. for _, status := range statuses {
  76. val, err := strconv.Atoi(status)
  77. if err != nil {
  78. return s, util.NewValidationError(fmt.Sprintf("invalid status: %v", status))
  79. }
  80. s.Statuses = append(s.Statuses, int32(val))
  81. }
  82. return s, nil
  83. }
  84. func getProviderSearchParamsFromRequest(r *http.Request) (eventsearcher.ProviderEventSearch, error) {
  85. var err error
  86. s := eventsearcher.ProviderEventSearch{}
  87. s.CommonSearchParams, err = getCommonSearchParamsFromRequest(r)
  88. if err != nil {
  89. return s, err
  90. }
  91. s.ObjectName = r.URL.Query().Get("object_name")
  92. s.ObjectTypes = getCommaSeparatedQueryParam(r, "object_types")
  93. return s, nil
  94. }
  95. func searchFsEvents(w http.ResponseWriter, r *http.Request) {
  96. r.Body = http.MaxBytesReader(w, r.Body, maxRequestSize)
  97. filters, err := getFsSearchParamsFromRequest(r)
  98. if err != nil {
  99. sendAPIResponse(w, r, err, "", getRespStatus(err))
  100. return
  101. }
  102. data, _, _, err := plugin.Handler.SearchFsEvents(&filters)
  103. if err != nil {
  104. sendAPIResponse(w, r, err, "", getRespStatus(err))
  105. return
  106. }
  107. w.Header().Set("Content-Type", "application/json; charset=utf-8")
  108. w.Write(data) //nolint:errcheck
  109. }
  110. func searchProviderEvents(w http.ResponseWriter, r *http.Request) {
  111. r.Body = http.MaxBytesReader(w, r.Body, maxRequestSize)
  112. filters, err := getProviderSearchParamsFromRequest(r)
  113. if err != nil {
  114. sendAPIResponse(w, r, err, "", getRespStatus(err))
  115. return
  116. }
  117. data, _, _, err := plugin.Handler.SearchProviderEvents(&filters)
  118. if err != nil {
  119. sendAPIResponse(w, r, err, "", getRespStatus(err))
  120. return
  121. }
  122. w.Header().Set("Content-Type", "application/json; charset=utf-8")
  123. w.Write(data) //nolint:errcheck
  124. }