api_defender.go 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. package httpd
  2. import (
  3. "encoding/hex"
  4. "errors"
  5. "fmt"
  6. "net"
  7. "net/http"
  8. "time"
  9. "github.com/go-chi/render"
  10. "github.com/drakkan/sftpgo/v2/common"
  11. "github.com/drakkan/sftpgo/v2/dataprovider"
  12. "github.com/drakkan/sftpgo/v2/util"
  13. )
  14. func getDefenderHosts(w http.ResponseWriter, r *http.Request) {
  15. r.Body = http.MaxBytesReader(w, r.Body, maxRequestSize)
  16. hosts, err := common.GetDefenderHosts()
  17. if err != nil {
  18. sendAPIResponse(w, r, err, "", getRespStatus(err))
  19. return
  20. }
  21. if hosts == nil {
  22. render.JSON(w, r, make([]dataprovider.DefenderEntry, 0))
  23. return
  24. }
  25. render.JSON(w, r, hosts)
  26. }
  27. func getDefenderHostByID(w http.ResponseWriter, r *http.Request) {
  28. r.Body = http.MaxBytesReader(w, r.Body, maxRequestSize)
  29. ip, err := getIPFromID(r)
  30. if err != nil {
  31. sendAPIResponse(w, r, err, "", http.StatusBadRequest)
  32. return
  33. }
  34. host, err := common.GetDefenderHost(ip)
  35. if err != nil {
  36. sendAPIResponse(w, r, err, "", getRespStatus(err))
  37. return
  38. }
  39. render.JSON(w, r, host)
  40. }
  41. func deleteDefenderHostByID(w http.ResponseWriter, r *http.Request) {
  42. r.Body = http.MaxBytesReader(w, r.Body, maxRequestSize)
  43. ip, err := getIPFromID(r)
  44. if err != nil {
  45. sendAPIResponse(w, r, err, "", http.StatusBadRequest)
  46. return
  47. }
  48. if !common.DeleteDefenderHost(ip) {
  49. sendAPIResponse(w, r, nil, "Not found", http.StatusNotFound)
  50. return
  51. }
  52. sendAPIResponse(w, r, nil, "OK", http.StatusOK)
  53. }
  54. func getBanTime(w http.ResponseWriter, r *http.Request) {
  55. r.Body = http.MaxBytesReader(w, r.Body, maxRequestSize)
  56. ip := r.URL.Query().Get("ip")
  57. err := validateIPAddress(ip)
  58. if err != nil {
  59. sendAPIResponse(w, r, err, "", http.StatusBadRequest)
  60. return
  61. }
  62. banStatus := make(map[string]*string)
  63. banTime, err := common.GetDefenderBanTime(ip)
  64. if err != nil {
  65. if _, ok := err.(*util.RecordNotFoundError); ok {
  66. banTime = nil
  67. } else {
  68. sendAPIResponse(w, r, err, "", getRespStatus(err))
  69. return
  70. }
  71. }
  72. var banTimeString *string
  73. if banTime != nil {
  74. rfc3339String := banTime.UTC().Format(time.RFC3339)
  75. banTimeString = &rfc3339String
  76. }
  77. banStatus["date_time"] = banTimeString
  78. render.JSON(w, r, banStatus)
  79. }
  80. func getScore(w http.ResponseWriter, r *http.Request) {
  81. r.Body = http.MaxBytesReader(w, r.Body, maxRequestSize)
  82. ip := r.URL.Query().Get("ip")
  83. err := validateIPAddress(ip)
  84. if err != nil {
  85. sendAPIResponse(w, r, err, "", http.StatusBadRequest)
  86. return
  87. }
  88. score, err := common.GetDefenderScore(ip)
  89. if err != nil {
  90. if _, ok := err.(*util.RecordNotFoundError); ok {
  91. score = 0
  92. } else {
  93. sendAPIResponse(w, r, err, "", getRespStatus(err))
  94. return
  95. }
  96. }
  97. scoreStatus := make(map[string]int)
  98. scoreStatus["score"] = score
  99. render.JSON(w, r, scoreStatus)
  100. }
  101. func unban(w http.ResponseWriter, r *http.Request) {
  102. r.Body = http.MaxBytesReader(w, r.Body, maxRequestSize)
  103. var postBody map[string]string
  104. err := render.DecodeJSON(r.Body, &postBody)
  105. if err != nil {
  106. sendAPIResponse(w, r, err, "", http.StatusBadRequest)
  107. return
  108. }
  109. ip := postBody["ip"]
  110. err = validateIPAddress(ip)
  111. if err != nil {
  112. sendAPIResponse(w, r, err, "", http.StatusBadRequest)
  113. return
  114. }
  115. if common.DeleteDefenderHost(ip) {
  116. sendAPIResponse(w, r, nil, "OK", http.StatusOK)
  117. } else {
  118. sendAPIResponse(w, r, nil, "Not found", http.StatusNotFound)
  119. }
  120. }
  121. func getIPFromID(r *http.Request) (string, error) {
  122. decoded, err := hex.DecodeString(getURLParam(r, "id"))
  123. if err != nil {
  124. return "", errors.New("invalid host id")
  125. }
  126. ip := string(decoded)
  127. err = validateIPAddress(ip)
  128. if err != nil {
  129. return "", err
  130. }
  131. return ip, nil
  132. }
  133. func validateIPAddress(ip string) error {
  134. if ip == "" {
  135. return errors.New("ip address is required")
  136. }
  137. if net.ParseIP(ip) == nil {
  138. return fmt.Errorf("ip address %#v is not valid", ip)
  139. }
  140. return nil
  141. }