api_eventrule.go 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  1. // Copyright (C) 2019-2023 Nicola Murino
  2. //
  3. // This program is free software: you can redistribute it and/or modify
  4. // it under the terms of the GNU Affero General Public License as published
  5. // by the Free Software Foundation, version 3.
  6. //
  7. // This program is distributed in the hope that it will be useful,
  8. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. // GNU Affero General Public License for more details.
  11. //
  12. // You should have received a copy of the GNU Affero General Public License
  13. // along with this program. If not, see <https://www.gnu.org/licenses/>.
  14. package httpd
  15. import (
  16. "context"
  17. "fmt"
  18. "net/http"
  19. "net/url"
  20. "github.com/go-chi/render"
  21. "github.com/drakkan/sftpgo/v2/internal/common"
  22. "github.com/drakkan/sftpgo/v2/internal/dataprovider"
  23. "github.com/drakkan/sftpgo/v2/internal/util"
  24. )
  25. func getEventActions(w http.ResponseWriter, r *http.Request) {
  26. r.Body = http.MaxBytesReader(w, r.Body, maxRequestSize)
  27. limit, offset, order, err := getSearchFilters(w, r)
  28. if err != nil {
  29. return
  30. }
  31. actions, err := dataprovider.GetEventActions(limit, offset, order, false)
  32. if err != nil {
  33. sendAPIResponse(w, r, err, "", http.StatusInternalServerError)
  34. return
  35. }
  36. render.JSON(w, r, actions)
  37. }
  38. func renderEventAction(w http.ResponseWriter, r *http.Request, name string, claims *jwtTokenClaims, status int) {
  39. action, err := dataprovider.EventActionExists(name)
  40. if err != nil {
  41. sendAPIResponse(w, r, err, "", getRespStatus(err))
  42. return
  43. }
  44. if hideConfidentialData(claims, r) {
  45. action.PrepareForRendering()
  46. }
  47. if status != http.StatusOK {
  48. ctx := context.WithValue(r.Context(), render.StatusCtxKey, status)
  49. render.JSON(w, r.WithContext(ctx), action)
  50. } else {
  51. render.JSON(w, r, action)
  52. }
  53. }
  54. func getEventActionByName(w http.ResponseWriter, r *http.Request) {
  55. r.Body = http.MaxBytesReader(w, r.Body, maxRequestSize)
  56. claims, err := getTokenClaims(r)
  57. if err != nil || claims.Username == "" {
  58. sendAPIResponse(w, r, err, "Invalid token claims", http.StatusBadRequest)
  59. return
  60. }
  61. name := getURLParam(r, "name")
  62. renderEventAction(w, r, name, &claims, http.StatusOK)
  63. }
  64. func addEventAction(w http.ResponseWriter, r *http.Request) {
  65. r.Body = http.MaxBytesReader(w, r.Body, maxRequestSize)
  66. claims, err := getTokenClaims(r)
  67. if err != nil || claims.Username == "" {
  68. sendAPIResponse(w, r, err, "Invalid token claims", http.StatusBadRequest)
  69. return
  70. }
  71. var action dataprovider.BaseEventAction
  72. err = render.DecodeJSON(r.Body, &action)
  73. if err != nil {
  74. sendAPIResponse(w, r, err, "", http.StatusBadRequest)
  75. return
  76. }
  77. ipAddr := util.GetIPFromRemoteAddress(r.RemoteAddr)
  78. err = dataprovider.AddEventAction(&action, claims.Username, ipAddr, claims.Role)
  79. if err != nil {
  80. sendAPIResponse(w, r, err, "", getRespStatus(err))
  81. return
  82. }
  83. w.Header().Add("Location", fmt.Sprintf("%s/%s", eventActionsPath, url.PathEscape(action.Name)))
  84. renderEventAction(w, r, action.Name, &claims, http.StatusCreated)
  85. }
  86. func updateEventAction(w http.ResponseWriter, r *http.Request) {
  87. r.Body = http.MaxBytesReader(w, r.Body, maxRequestSize)
  88. claims, err := getTokenClaims(r)
  89. if err != nil || claims.Username == "" {
  90. sendAPIResponse(w, r, err, "Invalid token claims", http.StatusBadRequest)
  91. return
  92. }
  93. name := getURLParam(r, "name")
  94. action, err := dataprovider.EventActionExists(name)
  95. if err != nil {
  96. sendAPIResponse(w, r, err, "", getRespStatus(err))
  97. return
  98. }
  99. var updatedAction dataprovider.BaseEventAction
  100. err = render.DecodeJSON(r.Body, &updatedAction)
  101. if err != nil {
  102. sendAPIResponse(w, r, err, "", http.StatusBadRequest)
  103. return
  104. }
  105. updatedAction.ID = action.ID
  106. updatedAction.Name = action.Name
  107. updatedAction.Options.SetEmptySecretsIfNil()
  108. switch updatedAction.Type {
  109. case dataprovider.ActionTypeHTTP:
  110. if updatedAction.Options.HTTPConfig.Password.IsNotPlainAndNotEmpty() {
  111. updatedAction.Options.HTTPConfig.Password = action.Options.HTTPConfig.Password
  112. }
  113. }
  114. err = dataprovider.UpdateEventAction(&updatedAction, claims.Username, util.GetIPFromRemoteAddress(r.RemoteAddr), claims.Role)
  115. if err != nil {
  116. sendAPIResponse(w, r, err, "", getRespStatus(err))
  117. return
  118. }
  119. sendAPIResponse(w, r, nil, "Event action updated", http.StatusOK)
  120. }
  121. func deleteEventAction(w http.ResponseWriter, r *http.Request) {
  122. r.Body = http.MaxBytesReader(w, r.Body, maxRequestSize)
  123. claims, err := getTokenClaims(r)
  124. if err != nil || claims.Username == "" {
  125. sendAPIResponse(w, r, err, "Invalid token claims", http.StatusBadRequest)
  126. return
  127. }
  128. name := getURLParam(r, "name")
  129. err = dataprovider.DeleteEventAction(name, claims.Username, util.GetIPFromRemoteAddress(r.RemoteAddr), claims.Role)
  130. if err != nil {
  131. sendAPIResponse(w, r, err, "", getRespStatus(err))
  132. return
  133. }
  134. sendAPIResponse(w, r, err, "Event action deleted", http.StatusOK)
  135. }
  136. func getEventRules(w http.ResponseWriter, r *http.Request) {
  137. r.Body = http.MaxBytesReader(w, r.Body, maxRequestSize)
  138. limit, offset, order, err := getSearchFilters(w, r)
  139. if err != nil {
  140. return
  141. }
  142. rules, err := dataprovider.GetEventRules(limit, offset, order)
  143. if err != nil {
  144. sendAPIResponse(w, r, err, "", http.StatusInternalServerError)
  145. return
  146. }
  147. render.JSON(w, r, rules)
  148. }
  149. func renderEventRule(w http.ResponseWriter, r *http.Request, name string, claims *jwtTokenClaims, status int) {
  150. rule, err := dataprovider.EventRuleExists(name)
  151. if err != nil {
  152. sendAPIResponse(w, r, err, "", getRespStatus(err))
  153. return
  154. }
  155. if hideConfidentialData(claims, r) {
  156. rule.PrepareForRendering()
  157. }
  158. if status != http.StatusOK {
  159. ctx := context.WithValue(r.Context(), render.StatusCtxKey, status)
  160. render.JSON(w, r.WithContext(ctx), rule)
  161. } else {
  162. render.JSON(w, r, rule)
  163. }
  164. }
  165. func getEventRuleByName(w http.ResponseWriter, r *http.Request) {
  166. r.Body = http.MaxBytesReader(w, r.Body, maxRequestSize)
  167. claims, err := getTokenClaims(r)
  168. if err != nil || claims.Username == "" {
  169. sendAPIResponse(w, r, err, "Invalid token claims", http.StatusBadRequest)
  170. return
  171. }
  172. name := getURLParam(r, "name")
  173. renderEventRule(w, r, name, &claims, http.StatusOK)
  174. }
  175. func addEventRule(w http.ResponseWriter, r *http.Request) {
  176. r.Body = http.MaxBytesReader(w, r.Body, maxRequestSize)
  177. claims, err := getTokenClaims(r)
  178. if err != nil || claims.Username == "" {
  179. sendAPIResponse(w, r, err, "Invalid token claims", http.StatusBadRequest)
  180. return
  181. }
  182. var rule dataprovider.EventRule
  183. err = render.DecodeJSON(r.Body, &rule)
  184. if err != nil {
  185. sendAPIResponse(w, r, err, "", http.StatusBadRequest)
  186. return
  187. }
  188. ipAddr := util.GetIPFromRemoteAddress(r.RemoteAddr)
  189. if err := dataprovider.AddEventRule(&rule, claims.Username, ipAddr, claims.Role); err != nil {
  190. sendAPIResponse(w, r, err, "", getRespStatus(err))
  191. return
  192. }
  193. w.Header().Add("Location", fmt.Sprintf("%s/%s", eventRulesPath, url.PathEscape(rule.Name)))
  194. renderEventRule(w, r, rule.Name, &claims, http.StatusCreated)
  195. }
  196. func updateEventRule(w http.ResponseWriter, r *http.Request) {
  197. r.Body = http.MaxBytesReader(w, r.Body, maxRequestSize)
  198. claims, err := getTokenClaims(r)
  199. if err != nil || claims.Username == "" {
  200. sendAPIResponse(w, r, err, "Invalid token claims", http.StatusBadRequest)
  201. return
  202. }
  203. rule, err := dataprovider.EventRuleExists(getURLParam(r, "name"))
  204. if err != nil {
  205. sendAPIResponse(w, r, err, "", getRespStatus(err))
  206. return
  207. }
  208. var updatedRule dataprovider.EventRule
  209. err = render.DecodeJSON(r.Body, &updatedRule)
  210. if err != nil {
  211. sendAPIResponse(w, r, err, "", http.StatusBadRequest)
  212. return
  213. }
  214. updatedRule.ID = rule.ID
  215. updatedRule.Name = rule.Name
  216. err = dataprovider.UpdateEventRule(&updatedRule, claims.Username, util.GetIPFromRemoteAddress(r.RemoteAddr), claims.Role)
  217. if err != nil {
  218. sendAPIResponse(w, r, err, "", getRespStatus(err))
  219. return
  220. }
  221. sendAPIResponse(w, r, nil, "Event rules updated", http.StatusOK)
  222. }
  223. func deleteEventRule(w http.ResponseWriter, r *http.Request) {
  224. r.Body = http.MaxBytesReader(w, r.Body, maxRequestSize)
  225. claims, err := getTokenClaims(r)
  226. if err != nil || claims.Username == "" {
  227. sendAPIResponse(w, r, err, "Invalid token claims", http.StatusBadRequest)
  228. return
  229. }
  230. name := getURLParam(r, "name")
  231. err = dataprovider.DeleteEventRule(name, claims.Username, util.GetIPFromRemoteAddress(r.RemoteAddr), claims.Role)
  232. if err != nil {
  233. sendAPIResponse(w, r, err, "", getRespStatus(err))
  234. return
  235. }
  236. sendAPIResponse(w, r, nil, "Event rule deleted", http.StatusOK)
  237. }
  238. func runOnDemandRule(w http.ResponseWriter, r *http.Request) {
  239. r.Body = http.MaxBytesReader(w, r.Body, maxRequestSize)
  240. name := getURLParam(r, "name")
  241. if err := common.RunOnDemandRule(name); err != nil {
  242. sendAPIResponse(w, r, err, "", getRespStatus(err))
  243. return
  244. }
  245. sendAPIResponse(w, r, nil, "Event rule started", http.StatusAccepted)
  246. }