decisions_test.go 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436
  1. package apiserver
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "io/ioutil"
  6. "net/http"
  7. "net/http/httptest"
  8. "strings"
  9. "testing"
  10. "time"
  11. "github.com/crowdsecurity/crowdsec/pkg/models"
  12. log "github.com/sirupsen/logrus"
  13. "github.com/stretchr/testify/assert"
  14. )
  15. func TestDeleteDecisionRange(t *testing.T) {
  16. router, loginResp, err := InitMachineTest()
  17. if err != nil {
  18. log.Fatalln(err.Error())
  19. }
  20. // Create Valid Alert
  21. alertContentBytes, err := ioutil.ReadFile("./tests/alert_minibulk.json")
  22. if err != nil {
  23. log.Fatal(err)
  24. }
  25. alerts := make([]*models.Alert, 0)
  26. if err := json.Unmarshal(alertContentBytes, &alerts); err != nil {
  27. log.Fatal(err)
  28. }
  29. for _, alert := range alerts {
  30. *alert.StartAt = time.Now().UTC().Format(time.RFC3339)
  31. *alert.StopAt = time.Now().UTC().Format(time.RFC3339)
  32. }
  33. alertContent, err := json.Marshal(alerts)
  34. if err != nil {
  35. log.Fatal(err)
  36. }
  37. w := httptest.NewRecorder()
  38. req, _ := http.NewRequest("POST", "/v1/alerts", strings.NewReader(string(alertContent)))
  39. AddAuthHeaders(req, loginResp)
  40. router.ServeHTTP(w, req)
  41. // delete by ip wrong
  42. w = httptest.NewRecorder()
  43. req, _ = http.NewRequest("DELETE", "/v1/decisions?range=1.2.3.0/24", strings.NewReader(""))
  44. AddAuthHeaders(req, loginResp)
  45. router.ServeHTTP(w, req)
  46. assert.Equal(t, 200, w.Code)
  47. assert.Equal(t, `{"nbDeleted":"0"}`, w.Body.String())
  48. // delete by range
  49. w = httptest.NewRecorder()
  50. req, _ = http.NewRequest("DELETE", "/v1/decisions?range=91.121.79.0/24&contains=false", strings.NewReader(""))
  51. AddAuthHeaders(req, loginResp)
  52. router.ServeHTTP(w, req)
  53. assert.Equal(t, 200, w.Code)
  54. assert.Equal(t, `{"nbDeleted":"2"}`, w.Body.String())
  55. // delete by range : ensure it was already deleted
  56. w = httptest.NewRecorder()
  57. req, _ = http.NewRequest("DELETE", "/v1/decisions?range=91.121.79.0/24", strings.NewReader(""))
  58. AddAuthHeaders(req, loginResp)
  59. router.ServeHTTP(w, req)
  60. assert.Equal(t, 200, w.Code)
  61. assert.Equal(t, `{"nbDeleted":"0"}`, w.Body.String())
  62. }
  63. func TestDeleteDecisionFilter(t *testing.T) {
  64. router, loginResp, err := InitMachineTest()
  65. if err != nil {
  66. log.Fatalln(err.Error())
  67. }
  68. // Create Valid Alert
  69. alertContentBytes, err := ioutil.ReadFile("./tests/alert_minibulk.json")
  70. if err != nil {
  71. log.Fatal(err)
  72. }
  73. alerts := make([]*models.Alert, 0)
  74. if err := json.Unmarshal(alertContentBytes, &alerts); err != nil {
  75. log.Fatal(err)
  76. }
  77. for _, alert := range alerts {
  78. *alert.StartAt = time.Now().UTC().Format(time.RFC3339)
  79. *alert.StopAt = time.Now().UTC().Format(time.RFC3339)
  80. }
  81. alertContent, err := json.Marshal(alerts)
  82. if err != nil {
  83. log.Fatal(err)
  84. }
  85. w := httptest.NewRecorder()
  86. req, _ := http.NewRequest("POST", "/v1/alerts", strings.NewReader(string(alertContent)))
  87. AddAuthHeaders(req, loginResp)
  88. router.ServeHTTP(w, req)
  89. // delete by ip wrong
  90. w = httptest.NewRecorder()
  91. req, _ = http.NewRequest("DELETE", "/v1/decisions?ip=1.2.3.4", strings.NewReader(""))
  92. AddAuthHeaders(req, loginResp)
  93. router.ServeHTTP(w, req)
  94. assert.Equal(t, 200, w.Code)
  95. assert.Equal(t, `{"nbDeleted":"0"}`, w.Body.String())
  96. // delete by ip good
  97. w = httptest.NewRecorder()
  98. req, _ = http.NewRequest("DELETE", "/v1/decisions?ip=91.121.79.179", strings.NewReader(""))
  99. AddAuthHeaders(req, loginResp)
  100. router.ServeHTTP(w, req)
  101. assert.Equal(t, 200, w.Code)
  102. assert.Equal(t, `{"nbDeleted":"1"}`, w.Body.String())
  103. // delete by scope/value
  104. w = httptest.NewRecorder()
  105. req, _ = http.NewRequest("DELETE", "/v1/decisions?scope=Ip&value=91.121.79.178", strings.NewReader(""))
  106. AddAuthHeaders(req, loginResp)
  107. router.ServeHTTP(w, req)
  108. assert.Equal(t, 200, w.Code)
  109. assert.Equal(t, `{"nbDeleted":"1"}`, w.Body.String())
  110. }
  111. func TestGetDecisionFilters(t *testing.T) {
  112. router, loginResp, err := InitMachineTest()
  113. if err != nil {
  114. log.Fatalln(err.Error())
  115. }
  116. // Create Valid Alert
  117. alertContentBytes, err := ioutil.ReadFile("./tests/alert_minibulk.json")
  118. if err != nil {
  119. log.Fatal(err)
  120. }
  121. alerts := make([]*models.Alert, 0)
  122. if err := json.Unmarshal(alertContentBytes, &alerts); err != nil {
  123. log.Fatal(err)
  124. }
  125. for _, alert := range alerts {
  126. *alert.StartAt = time.Now().UTC().Format(time.RFC3339)
  127. *alert.StopAt = time.Now().UTC().Format(time.RFC3339)
  128. }
  129. alertContent, err := json.Marshal(alerts)
  130. if err != nil {
  131. log.Fatal(err)
  132. }
  133. w := httptest.NewRecorder()
  134. req, _ := http.NewRequest("POST", "/v1/alerts", strings.NewReader(string(alertContent)))
  135. AddAuthHeaders(req, loginResp)
  136. router.ServeHTTP(w, req)
  137. APIKey, err := CreateTestBouncer()
  138. if err != nil {
  139. log.Fatalf("%s", err.Error())
  140. }
  141. // Get Decision
  142. w = httptest.NewRecorder()
  143. req, _ = http.NewRequest("GET", "/v1/decisions", strings.NewReader(""))
  144. req.Header.Add("User-Agent", UserAgent)
  145. req.Header.Add("X-Api-Key", APIKey)
  146. router.ServeHTTP(w, req)
  147. assert.Equal(t, 200, w.Code)
  148. assert.Contains(t, w.Body.String(), `"id":1,"origin":"crowdsec","scenario":"crowdsecurity/ssh-bf","scope":"Ip","type":"ban","value":"91.121.79.179"`)
  149. assert.Contains(t, w.Body.String(), `"id":2,"origin":"crowdsec","scenario":"crowdsecurity/ssh-bf","scope":"Ip","type":"ban","value":"91.121.79.178"`)
  150. // Get Decision : type filter
  151. w = httptest.NewRecorder()
  152. req, _ = http.NewRequest("GET", "/v1/decisions?type=ban", strings.NewReader(""))
  153. req.Header.Add("User-Agent", UserAgent)
  154. req.Header.Add("X-Api-Key", APIKey)
  155. router.ServeHTTP(w, req)
  156. assert.Equal(t, 200, w.Code)
  157. assert.Contains(t, w.Body.String(), `"id":1,"origin":"crowdsec","scenario":"crowdsecurity/ssh-bf","scope":"Ip","type":"ban","value":"91.121.79.179"`)
  158. assert.Contains(t, w.Body.String(), `"id":2,"origin":"crowdsec","scenario":"crowdsecurity/ssh-bf","scope":"Ip","type":"ban","value":"91.121.79.178"`)
  159. // Get Decision : scope/value
  160. w = httptest.NewRecorder()
  161. req, _ = http.NewRequest("GET", "/v1/decisions?scope=Ip&value=91.121.79.179", strings.NewReader(""))
  162. req.Header.Add("User-Agent", UserAgent)
  163. req.Header.Add("X-Api-Key", APIKey)
  164. router.ServeHTTP(w, req)
  165. assert.Equal(t, 200, w.Code)
  166. assert.Contains(t, w.Body.String(), `"id":1,"origin":"crowdsec","scenario":"crowdsecurity/ssh-bf","scope":"Ip","type":"ban","value":"91.121.79.179"`)
  167. assert.NotContains(t, w.Body.String(), `"id":2,"origin":"crowdsec","scenario":"crowdsecurity/ssh-bf","scope":"Ip","type":"ban","value":"91.121.79.178"`)
  168. // Get Decision : ip filter
  169. w = httptest.NewRecorder()
  170. req, _ = http.NewRequest("GET", "/v1/decisions?ip=91.121.79.179", strings.NewReader(""))
  171. req.Header.Add("User-Agent", UserAgent)
  172. req.Header.Add("X-Api-Key", APIKey)
  173. router.ServeHTTP(w, req)
  174. assert.Equal(t, 200, w.Code)
  175. assert.Contains(t, w.Body.String(), `"id":1,"origin":"crowdsec","scenario":"crowdsecurity/ssh-bf","scope":"Ip","type":"ban","value":"91.121.79.179"`)
  176. assert.NotContains(t, w.Body.String(), `"id":2,"origin":"crowdsec","scenario":"crowdsecurity/ssh-bf","scope":"Ip","type":"ban","value":"91.121.79.178"`)
  177. // Get decision : by range
  178. w = httptest.NewRecorder()
  179. req, _ = http.NewRequest("GET", "/v1/decisions?range=91.121.79.0/24&contains=false", strings.NewReader(""))
  180. req.Header.Add("User-Agent", UserAgent)
  181. req.Header.Add("X-Api-Key", APIKey)
  182. router.ServeHTTP(w, req)
  183. assert.Equal(t, 200, w.Code)
  184. assert.Contains(t, w.Body.String(), `"id":1,"origin":"crowdsec","scenario":"crowdsecurity/ssh-bf","scope":"Ip","type":"ban","value":"91.121.79.179"`)
  185. assert.Contains(t, w.Body.String(), `"id":2,"origin":"crowdsec","scenario":"crowdsecurity/ssh-bf","scope":"Ip","type":"ban","value":"91.121.79.178"`)
  186. }
  187. func TestGetDecision(t *testing.T) {
  188. router, loginResp, err := InitMachineTest()
  189. if err != nil {
  190. log.Fatalln(err.Error())
  191. }
  192. // Create Valid Alert
  193. alertContentBytes, err := ioutil.ReadFile("./tests/alert_sample.json")
  194. if err != nil {
  195. log.Fatal(err)
  196. }
  197. alerts := make([]*models.Alert, 0)
  198. if err := json.Unmarshal(alertContentBytes, &alerts); err != nil {
  199. log.Fatal(err)
  200. }
  201. for _, alert := range alerts {
  202. *alert.StartAt = time.Now().UTC().Format(time.RFC3339)
  203. *alert.StopAt = time.Now().UTC().Format(time.RFC3339)
  204. }
  205. alertContent, err := json.Marshal(alerts)
  206. if err != nil {
  207. log.Fatal(err)
  208. }
  209. w := httptest.NewRecorder()
  210. req, _ := http.NewRequest("POST", "/v1/alerts", strings.NewReader(string(alertContent)))
  211. AddAuthHeaders(req, loginResp)
  212. router.ServeHTTP(w, req)
  213. APIKey, err := CreateTestBouncer()
  214. if err != nil {
  215. log.Fatalf("%s", err.Error())
  216. }
  217. // Get Decision with invalid filter
  218. w = httptest.NewRecorder()
  219. req, _ = http.NewRequest("GET", "/v1/decisions?test=test", strings.NewReader(""))
  220. req.Header.Add("User-Agent", UserAgent)
  221. req.Header.Add("X-Api-Key", APIKey)
  222. router.ServeHTTP(w, req)
  223. assert.Equal(t, 500, w.Code)
  224. assert.Equal(t, "{\"message\":\"'test' doesn't exist: invalid filter\"}", w.Body.String())
  225. // Get Decision
  226. w = httptest.NewRecorder()
  227. req, _ = http.NewRequest("GET", "/v1/decisions", strings.NewReader(""))
  228. req.Header.Add("User-Agent", UserAgent)
  229. req.Header.Add("X-Api-Key", APIKey)
  230. router.ServeHTTP(w, req)
  231. assert.Equal(t, 200, w.Code)
  232. assert.Contains(t, w.Body.String(), "\"id\":1,\"origin\":\"test\",\"scenario\":\"crowdsecurity/test\",\"scope\":\"Ip\",\"type\":\"ban\",\"value\":\"127.0.0.1\"}]")
  233. }
  234. func TestDeleteDecisionByID(t *testing.T) {
  235. router, loginResp, err := InitMachineTest()
  236. if err != nil {
  237. log.Fatalln(err.Error())
  238. }
  239. // Create Valid Alert
  240. alertContentBytes, err := ioutil.ReadFile("./tests/alert_sample.json")
  241. if err != nil {
  242. log.Fatal(err)
  243. }
  244. alerts := make([]*models.Alert, 0)
  245. if err := json.Unmarshal(alertContentBytes, &alerts); err != nil {
  246. log.Fatal(err)
  247. }
  248. for _, alert := range alerts {
  249. *alert.StartAt = time.Now().UTC().Format(time.RFC3339)
  250. *alert.StopAt = time.Now().UTC().Format(time.RFC3339)
  251. }
  252. alertContent, err := json.Marshal(alerts)
  253. if err != nil {
  254. log.Fatal(err)
  255. }
  256. w := httptest.NewRecorder()
  257. req, _ := http.NewRequest("POST", "/v1/alerts", strings.NewReader(string(alertContent)))
  258. AddAuthHeaders(req, loginResp)
  259. router.ServeHTTP(w, req)
  260. // Delete alert with Invalid ID
  261. w = httptest.NewRecorder()
  262. req, _ = http.NewRequest("DELETE", "/v1/decisions/test", strings.NewReader(""))
  263. AddAuthHeaders(req, loginResp)
  264. router.ServeHTTP(w, req)
  265. assert.Equal(t, 400, w.Code)
  266. assert.Equal(t, "{\"message\":\"decision_id must be valid integer\"}", w.Body.String())
  267. // Delete alert with ID that not exist
  268. w = httptest.NewRecorder()
  269. req, _ = http.NewRequest("DELETE", "/v1/decisions/100", strings.NewReader(""))
  270. AddAuthHeaders(req, loginResp)
  271. router.ServeHTTP(w, req)
  272. assert.Equal(t, 500, w.Code)
  273. assert.Equal(t, "{\"message\":\"decision with id '100' doesn't exist: unable to delete\"}", w.Body.String())
  274. // Delete alert with valid ID
  275. w = httptest.NewRecorder()
  276. req, _ = http.NewRequest("DELETE", "/v1/decisions/1", strings.NewReader(""))
  277. AddAuthHeaders(req, loginResp)
  278. router.ServeHTTP(w, req)
  279. assert.Equal(t, 200, w.Code)
  280. assert.Equal(t, "{\"nbDeleted\":\"1\"}", w.Body.String())
  281. }
  282. func TestDeleteDecision(t *testing.T) {
  283. router, loginResp, err := InitMachineTest()
  284. if err != nil {
  285. log.Fatalln(err.Error())
  286. }
  287. // Create Valid Alert
  288. alertContentBytes, err := ioutil.ReadFile("./tests/alert_sample.json")
  289. if err != nil {
  290. log.Fatal(err)
  291. }
  292. alerts := make([]*models.Alert, 0)
  293. if err := json.Unmarshal(alertContentBytes, &alerts); err != nil {
  294. log.Fatal(err)
  295. }
  296. for _, alert := range alerts {
  297. *alert.StartAt = time.Now().UTC().Format(time.RFC3339)
  298. *alert.StopAt = time.Now().UTC().Format(time.RFC3339)
  299. }
  300. alertContent, err := json.Marshal(alerts)
  301. if err != nil {
  302. log.Fatal(err)
  303. }
  304. w := httptest.NewRecorder()
  305. req, _ := http.NewRequest("POST", "/v1/alerts", strings.NewReader(string(alertContent)))
  306. AddAuthHeaders(req, loginResp)
  307. router.ServeHTTP(w, req)
  308. // Delete alert with Invalid filter
  309. w = httptest.NewRecorder()
  310. req, _ = http.NewRequest("DELETE", "/v1/decisions?test=test", strings.NewReader(""))
  311. AddAuthHeaders(req, loginResp)
  312. router.ServeHTTP(w, req)
  313. assert.Equal(t, 500, w.Code)
  314. assert.Equal(t, "{\"message\":\"'test' doesn't exist: invalid filter\"}", w.Body.String())
  315. // Delete alert
  316. w = httptest.NewRecorder()
  317. req, _ = http.NewRequest("DELETE", "/v1/decisions", strings.NewReader(""))
  318. AddAuthHeaders(req, loginResp)
  319. router.ServeHTTP(w, req)
  320. assert.Equal(t, 200, w.Code)
  321. assert.Equal(t, "{\"nbDeleted\":\"1\"}", w.Body.String())
  322. }
  323. func TestStreamDecision(t *testing.T) {
  324. router, loginResp, err := InitMachineTest()
  325. if err != nil {
  326. log.Fatalln(err.Error())
  327. }
  328. // Create Valid Alert
  329. alertContentBytes, err := ioutil.ReadFile("./tests/alert_sample.json")
  330. if err != nil {
  331. log.Fatal(err)
  332. }
  333. alerts := make([]*models.Alert, 0)
  334. if err := json.Unmarshal(alertContentBytes, &alerts); err != nil {
  335. log.Fatal(err)
  336. }
  337. for _, alert := range alerts {
  338. *alert.StartAt = time.Now().UTC().Format(time.RFC3339)
  339. *alert.StopAt = time.Now().UTC().Format(time.RFC3339)
  340. }
  341. alertContent, err := json.Marshal(alerts)
  342. if err != nil {
  343. log.Fatal(err)
  344. }
  345. w := httptest.NewRecorder()
  346. req, _ := http.NewRequest("POST", "/v1/alerts", strings.NewReader(string(alertContent)))
  347. req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", loginResp.Token))
  348. router.ServeHTTP(w, req)
  349. APIKey, err := CreateTestBouncer()
  350. if err != nil {
  351. log.Fatalf("%s", err.Error())
  352. }
  353. // Get Stream
  354. w = httptest.NewRecorder()
  355. req, _ = http.NewRequest("GET", "/v1/decisions/stream", strings.NewReader(""))
  356. req.Header.Add("X-Api-Key", APIKey)
  357. router.ServeHTTP(w, req)
  358. assert.Equal(t, 200, w.Code)
  359. assert.Equal(t, "{\"deleted\":null,\"new\":null}", w.Body.String())
  360. // Get Stream just startup
  361. w = httptest.NewRecorder()
  362. req, _ = http.NewRequest("GET", "/v1/decisions/stream?startup=true", strings.NewReader(""))
  363. req.Header.Add("X-Api-Key", APIKey)
  364. router.ServeHTTP(w, req)
  365. assert.Equal(t, 200, w.Code)
  366. assert.Contains(t, w.Body.String(), "\"id\":1,\"origin\":\"test\",\"scenario\":\"crowdsecurity/test\",\"scope\":\"Ip\",\"type\":\"ban\",\"value\":\"127.0.0.1\"}]}")
  367. }