decisions_test.go 15 KB

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