webhook_agent_spec.rb 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710
  1. require 'rails_helper'
  2. describe Agents::WebhookAgent do
  3. let(:agent) do
  4. _agent = Agents::WebhookAgent.new(:name => 'webhook',
  5. :options => { 'secret' => 'foobar', 'payload_path' => 'some_key' })
  6. _agent.user = users(:bob)
  7. _agent.save!
  8. _agent
  9. end
  10. let(:payload) { {'people' => [{ 'name' => 'bob' }, { 'name' => 'jon' }] } }
  11. describe 'receive_web_request' do
  12. it 'should create event if secret matches' do
  13. webpayload = ActionDispatch::Request.new({
  14. 'action_dispatch.request.request_parameters' => { 'some_key' => payload },
  15. 'action_dispatch.request.path_parameters' => { secret: 'foobar' },
  16. 'REQUEST_METHOD' => "POST",
  17. 'HTTP_ACCEPT' => 'application/xml',
  18. 'HTTP_X_HELLO_WORLD' => "Hello Huginn"
  19. })
  20. out = nil
  21. agent.options['event_headers'] = 'Accept,X-Hello-World'
  22. agent.options['event_headers_key'] = 'X-HTTP-HEADERS'
  23. expect {
  24. out = agent.receive_web_request(webpayload)
  25. }.to change { Event.count }.by(1)
  26. expect(out).to eq(['Event Created', 201])
  27. expect(Event.last.payload).to eq( {"people"=>[{"name"=>"bob"}, {"name"=>"jon"}], "X-HTTP-HEADERS"=>{"Accept"=>"application/xml", "X-Hello-World"=>"Hello Huginn"}})
  28. end
  29. it 'should be able to create multiple events when given an array' do
  30. webpayload = ActionDispatch::Request.new({
  31. 'action_dispatch.request.request_parameters' => { 'some_key' => payload },
  32. 'action_dispatch.request.path_parameters' => { secret: 'foobar' },
  33. 'REQUEST_METHOD' => "POST",
  34. 'HTTP_ACCEPT' => 'application/xml',
  35. 'HTTP_X_HELLO_WORLD' => "Hello Huginn"
  36. })
  37. out = nil
  38. agent.options['payload_path'] = 'some_key.people'
  39. agent.options['event_headers'] = 'Accept,X-Hello-World'
  40. agent.options['event_headers_key'] = 'X-HTTP-HEADERS'
  41. expect {
  42. out = agent.receive_web_request(webpayload)
  43. }.to change { Event.count }.by(2)
  44. expect(out).to eq(['Event Created', 201])
  45. expect(Event.last.payload).to eq({"name"=>"jon", "X-HTTP-HEADERS"=>{"Accept"=>"application/xml", "X-Hello-World"=>"Hello Huginn"}})
  46. end
  47. it 'should not create event if secrets do not match' do
  48. webpayload = ActionDispatch::Request.new({
  49. 'action_dispatch.request.request_parameters' => { 'some_key' => payload },
  50. 'action_dispatch.request.path_parameters' => { secret: 'bazbat' },
  51. 'REQUEST_METHOD' => "POST",
  52. 'HTTP_ACCEPT' => 'application/xml',
  53. 'HTTP_X_HELLO_WORLD' => "Hello Huginn"
  54. })
  55. out = nil
  56. agent.options['event_headers'] = 'Accept,X-Hello-World'
  57. agent.options['event_headers_key'] = 'X-HTTP-HEADERS'
  58. expect {
  59. out = agent.receive_web_request(webpayload)
  60. }.to change { Event.count }.by(0)
  61. expect(out).to eq(['Not Authorized', 401])
  62. end
  63. it 'should respond with customized response message if configured with `response` option' do
  64. webpayload = ActionDispatch::Request.new({
  65. 'action_dispatch.request.request_parameters' => { 'some_key' => payload },
  66. 'action_dispatch.request.path_parameters' => { secret: 'foobar' },
  67. 'REQUEST_METHOD' => "POST",
  68. 'HTTP_ACCEPT' => 'application/xml',
  69. 'HTTP_X_HELLO_WORLD' => "Hello Huginn"
  70. })
  71. agent.options['response'] = 'That Worked'
  72. out = agent.receive_web_request(webpayload)
  73. expect(out).to eq(['That Worked', 201])
  74. # Empty string is a valid response
  75. agent.options['response'] = ''
  76. out = agent.receive_web_request(webpayload)
  77. expect(out).to eq(['', 201])
  78. end
  79. it 'should respond with interpolated response message if configured with `response` option' do
  80. webpayload = ActionDispatch::Request.new({
  81. 'action_dispatch.request.request_parameters' => { 'some_key' => payload },
  82. 'action_dispatch.request.path_parameters' => { secret: 'foobar' },
  83. 'REQUEST_METHOD' => "POST",
  84. 'HTTP_ACCEPT' => 'application/xml',
  85. 'HTTP_X_HELLO_WORLD' => "Hello Huginn"
  86. })
  87. agent.options['response'] = '{{some_key.people[1].name}}'
  88. out = agent.receive_web_request(webpayload)
  89. expect(out).to eq(['jon', 201])
  90. end
  91. it 'should respond with custom response header if configured with `response_headers` option' do
  92. webpayload = ActionDispatch::Request.new({
  93. 'action_dispatch.request.request_parameters' => { 'some_key' => payload },
  94. 'action_dispatch.request.path_parameters' => { secret: 'foobar' },
  95. 'REQUEST_METHOD' => "POST",
  96. 'HTTP_ACCEPT' => 'application/xml',
  97. 'HTTP_X_HELLO_WORLD' => "Hello Huginn"
  98. })
  99. agent.options['response_headers'] = {"X-My-Custom-Header" => 'hello'}
  100. out = agent.receive_web_request(webpayload)
  101. expect(out).to eq(['Event Created', 201, "text/plain", {"X-My-Custom-Header" => 'hello'}])
  102. end
  103. it 'should respond with `Event Created` if the response option is nil or missing' do
  104. webpayload = ActionDispatch::Request.new({
  105. 'action_dispatch.request.request_parameters' => { 'some_key' => payload },
  106. 'action_dispatch.request.path_parameters' => { secret: 'foobar' },
  107. 'REQUEST_METHOD' => "POST",
  108. 'HTTP_ACCEPT' => 'application/xml',
  109. 'HTTP_X_HELLO_WORLD' => "Hello Huginn"
  110. })
  111. agent.options['response'] = nil
  112. out = agent.receive_web_request(webpayload)
  113. expect(out).to eq(['Event Created', 201])
  114. agent.options.delete('response')
  115. out = agent.receive_web_request(webpayload)
  116. expect(out).to eq(['Event Created', 201])
  117. end
  118. it 'should respond with customized response code if configured with `code` option' do
  119. webpayload = ActionDispatch::Request.new({
  120. 'action_dispatch.request.request_parameters' => { 'some_key' => payload },
  121. 'action_dispatch.request.path_parameters' => { secret: 'foobar' },
  122. 'REQUEST_METHOD' => "POST",
  123. 'HTTP_ACCEPT' => 'application/xml',
  124. 'HTTP_X_HELLO_WORLD' => "Hello Huginn"
  125. })
  126. agent.options['code'] = '200'
  127. out = agent.receive_web_request(webpayload)
  128. expect(out).to eq(['Event Created', 200])
  129. end
  130. it 'should respond with `201` if the code option is empty, nil or missing' do
  131. webpayload = ActionDispatch::Request.new({
  132. 'action_dispatch.request.request_parameters' => { 'some_key' => payload },
  133. 'action_dispatch.request.path_parameters' => { secret: 'foobar' },
  134. 'REQUEST_METHOD' => "POST",
  135. 'HTTP_ACCEPT' => 'application/xml',
  136. 'HTTP_X_HELLO_WORLD' => "Hello Huginn"
  137. })
  138. agent.options['code'] = ''
  139. out = agent.receive_web_request(webpayload)
  140. expect(out).to eq(['Event Created', 201])
  141. agent.options['code'] = nil
  142. out = agent.receive_web_request(webpayload)
  143. expect(out).to eq(['Event Created', 201])
  144. agent.options.delete('code')
  145. out = agent.receive_web_request(webpayload)
  146. expect(out).to eq(['Event Created', 201])
  147. end
  148. describe "receiving events" do
  149. context "default settings" do
  150. it "should not accept GET" do
  151. webpayload = ActionDispatch::Request.new({
  152. 'action_dispatch.request.request_parameters' => { 'some_key' => payload },
  153. 'action_dispatch.request.path_parameters' => { secret: 'foobar' },
  154. 'REQUEST_METHOD' => "GET",
  155. 'HTTP_ACCEPT' => 'application/xml',
  156. 'HTTP_X_HELLO_WORLD' => "Hello Huginn"
  157. })
  158. out = nil
  159. expect {
  160. out = agent.receive_web_request(webpayload)
  161. }.to change { Event.count }.by(0)
  162. expect(out).to eq(['Please use POST requests only', 401])
  163. end
  164. it "should accept POST" do
  165. webpayload = ActionDispatch::Request.new({
  166. 'action_dispatch.request.request_parameters' => { 'some_key' => payload },
  167. 'action_dispatch.request.path_parameters' => { secret: 'foobar' },
  168. 'REQUEST_METHOD' => "POST",
  169. 'HTTP_ACCEPT' => 'application/xml',
  170. 'HTTP_X_HELLO_WORLD' => "Hello Huginn"
  171. })
  172. out = nil
  173. expect {
  174. out = agent.receive_web_request(webpayload)
  175. }.to change { Event.count }.by(1)
  176. expect(out).to eq(['Event Created', 201])
  177. end
  178. end
  179. context "accepting get and post" do
  180. before { agent.options['verbs'] = 'get,post' }
  181. it "should accept GET" do
  182. webpayload = ActionDispatch::Request.new({
  183. 'action_dispatch.request.request_parameters' => { 'some_key' => payload },
  184. 'action_dispatch.request.path_parameters' => { secret: 'foobar' },
  185. 'REQUEST_METHOD' => "GET",
  186. 'HTTP_ACCEPT' => 'application/xml',
  187. 'HTTP_X_HELLO_WORLD' => "Hello Huginn"
  188. })
  189. out = nil
  190. expect {
  191. out = agent.receive_web_request(webpayload)
  192. }.to change { Event.count }.by(1)
  193. expect(out).to eq(['Event Created', 201])
  194. end
  195. it "should accept POST" do
  196. webpayload = ActionDispatch::Request.new({
  197. 'action_dispatch.request.request_parameters' => { 'some_key' => payload },
  198. 'action_dispatch.request.path_parameters' => { secret: 'foobar' },
  199. 'REQUEST_METHOD' => "POST",
  200. 'HTTP_ACCEPT' => 'application/xml',
  201. 'HTTP_X_HELLO_WORLD' => "Hello Huginn"
  202. })
  203. out = nil
  204. expect {
  205. out = agent.receive_web_request(webpayload)
  206. }.to change { Event.count }.by(1)
  207. expect(out).to eq(['Event Created', 201])
  208. end
  209. it "should not accept PUT" do
  210. webpayload = ActionDispatch::Request.new({
  211. 'action_dispatch.request.request_parameters' => { 'some_key' => payload },
  212. 'action_dispatch.request.path_parameters' => { secret: 'foobar' },
  213. 'REQUEST_METHOD' => "PUT",
  214. 'HTTP_ACCEPT' => 'application/xml',
  215. 'HTTP_X_HELLO_WORLD' => "Hello Huginn"
  216. })
  217. out = nil
  218. expect {
  219. out = agent.receive_web_request(webpayload)
  220. }.to change { Event.count }.by(0)
  221. expect(out).to eq(['Please use GET/POST requests only', 401])
  222. end
  223. end
  224. context "accepting only get" do
  225. before { agent.options['verbs'] = 'get' }
  226. it "should accept GET" do
  227. webpayload = ActionDispatch::Request.new({
  228. 'action_dispatch.request.request_parameters' => { 'some_key' => payload },
  229. 'action_dispatch.request.path_parameters' => { secret: 'foobar' },
  230. 'REQUEST_METHOD' => "GET",
  231. 'HTTP_ACCEPT' => 'application/xml',
  232. 'HTTP_X_HELLO_WORLD' => "Hello Huginn"
  233. })
  234. out = nil
  235. expect {
  236. out = agent.receive_web_request(webpayload)
  237. }.to change { Event.count }.by(1)
  238. expect(out).to eq(['Event Created', 201])
  239. end
  240. it "should not accept POST" do
  241. webpayload = ActionDispatch::Request.new({
  242. 'action_dispatch.request.request_parameters' => { 'some_key' => payload },
  243. 'action_dispatch.request.path_parameters' => { secret: 'foobar' },
  244. 'REQUEST_METHOD' => "POST",
  245. 'HTTP_ACCEPT' => 'application/xml',
  246. 'HTTP_X_HELLO_WORLD' => "Hello Huginn"
  247. })
  248. out = nil
  249. expect {
  250. out = agent.receive_web_request(webpayload)
  251. }.to change { Event.count }.by(0)
  252. expect(out).to eq(['Please use GET requests only', 401])
  253. end
  254. end
  255. context "accepting only post" do
  256. before { agent.options['verbs'] = 'post' }
  257. it "should not accept GET" do
  258. webpayload = ActionDispatch::Request.new({
  259. 'action_dispatch.request.request_parameters' => { 'some_key' => payload },
  260. 'action_dispatch.request.path_parameters' => { secret: 'foobar' },
  261. 'REQUEST_METHOD' => "GET",
  262. 'HTTP_ACCEPT' => 'application/xml',
  263. 'HTTP_X_HELLO_WORLD' => "Hello Huginn"
  264. })
  265. out = nil
  266. expect {
  267. out = agent.receive_web_request(webpayload)
  268. }.to change { Event.count }.by(0)
  269. expect(out).to eq(['Please use POST requests only', 401])
  270. end
  271. it "should accept POST" do
  272. webpayload = ActionDispatch::Request.new({
  273. 'action_dispatch.request.request_parameters' => { 'some_key' => payload },
  274. 'action_dispatch.request.path_parameters' => { secret: 'foobar' },
  275. 'REQUEST_METHOD' => "POST",
  276. 'HTTP_ACCEPT' => 'application/xml',
  277. 'HTTP_X_HELLO_WORLD' => "Hello Huginn"
  278. })
  279. out = nil
  280. expect {
  281. out = agent.receive_web_request(webpayload)
  282. }.to change { Event.count }.by(1)
  283. expect(out).to eq(['Event Created', 201])
  284. end
  285. end
  286. context "accepting only put" do
  287. before { agent.options['verbs'] = 'put' }
  288. it "should accept PUT" do
  289. webpayload = ActionDispatch::Request.new({
  290. 'action_dispatch.request.request_parameters' => { 'some_key' => payload },
  291. 'action_dispatch.request.path_parameters' => { secret: 'foobar' },
  292. 'REQUEST_METHOD' => "PUT",
  293. 'HTTP_ACCEPT' => 'application/xml',
  294. 'HTTP_X_HELLO_WORLD' => "Hello Huginn"
  295. })
  296. out = nil
  297. expect {
  298. out = agent.receive_web_request(webpayload)
  299. }.to change { Event.count }.by(1)
  300. expect(out).to eq(['Event Created', 201])
  301. end
  302. it "should not accept GET" do
  303. webpayload = ActionDispatch::Request.new({
  304. 'action_dispatch.request.request_parameters' => { 'some_key' => payload },
  305. 'action_dispatch.request.path_parameters' => { secret: 'foobar' },
  306. 'REQUEST_METHOD' => "GET",
  307. 'HTTP_ACCEPT' => 'application/xml',
  308. 'HTTP_X_HELLO_WORLD' => "Hello Huginn"
  309. })
  310. out = nil
  311. expect {
  312. out = agent.receive_web_request(webpayload)
  313. }.to change { Event.count }.by(0)
  314. expect(out).to eq(['Please use PUT requests only', 401])
  315. end
  316. it "should not accept POST" do
  317. webpayload = ActionDispatch::Request.new({
  318. 'action_dispatch.request.request_parameters' => { 'some_key' => payload },
  319. 'action_dispatch.request.path_parameters' => { secret: 'foobar' },
  320. 'REQUEST_METHOD' => "POST",
  321. 'HTTP_ACCEPT' => 'application/xml',
  322. 'HTTP_X_HELLO_WORLD' => "Hello Huginn"
  323. })
  324. out = nil
  325. expect {
  326. out = agent.receive_web_request(webpayload)
  327. }.to change { Event.count }.by(0)
  328. expect(out).to eq(['Please use PUT requests only', 401])
  329. end
  330. end
  331. context "flaky content with commas" do
  332. before { agent.options['verbs'] = ',, PUT,POST, gEt , ,' }
  333. it "should accept PUT" do
  334. webpayload = ActionDispatch::Request.new({
  335. 'action_dispatch.request.request_parameters' => { 'some_key' => payload },
  336. 'action_dispatch.request.path_parameters' => { secret: 'foobar' },
  337. 'REQUEST_METHOD' => "PUT",
  338. 'HTTP_ACCEPT' => 'application/xml',
  339. 'HTTP_X_HELLO_WORLD' => "Hello Huginn"
  340. })
  341. out = nil
  342. expect {
  343. out = agent.receive_web_request(webpayload)
  344. }.to change { Event.count }.by(1)
  345. expect(out).to eq(['Event Created', 201])
  346. end
  347. it "should accept GET" do
  348. webpayload = ActionDispatch::Request.new({
  349. 'action_dispatch.request.request_parameters' => { 'some_key' => payload },
  350. 'action_dispatch.request.path_parameters' => { secret: 'foobar' },
  351. 'REQUEST_METHOD' => "GET",
  352. 'HTTP_ACCEPT' => 'application/xml',
  353. 'HTTP_X_HELLO_WORLD' => "Hello Huginn"
  354. })
  355. out = nil
  356. expect {
  357. out = agent.receive_web_request(webpayload)
  358. }.to change { Event.count }.by(1)
  359. expect(out).to eq(['Event Created', 201])
  360. end
  361. it "should accept POST" do
  362. webpayload = ActionDispatch::Request.new({
  363. 'action_dispatch.request.request_parameters' => { 'some_key' => payload },
  364. 'action_dispatch.request.path_parameters' => { secret: 'foobar' },
  365. 'REQUEST_METHOD' => "POST",
  366. 'HTTP_ACCEPT' => 'application/xml',
  367. 'HTTP_X_HELLO_WORLD' => "Hello Huginn"
  368. })
  369. out = nil
  370. expect {
  371. out = agent.receive_web_request(webpayload)
  372. }.to change { Event.count }.by(1)
  373. expect(out).to eq(['Event Created', 201])
  374. end
  375. it "should not accept DELETE" do
  376. webpayload = ActionDispatch::Request.new({
  377. 'action_dispatch.request.request_parameters' => { 'some_key' => payload },
  378. 'action_dispatch.request.path_parameters' => { secret: 'foobar' },
  379. 'REQUEST_METHOD' => "DELETE",
  380. 'HTTP_ACCEPT' => 'application/xml',
  381. 'HTTP_X_HELLO_WORLD' => "Hello Huginn"
  382. })
  383. out = nil
  384. expect {
  385. out = agent.receive_web_request(webpayload)
  386. }.to change { Event.count }.by(0)
  387. expect(out).to eq(['Please use PUT/POST/GET requests only', 401])
  388. end
  389. end
  390. context "with reCAPTCHA" do
  391. it "should not check a reCAPTCHA response unless recaptcha_secret is set" do
  392. webpayload = ActionDispatch::Request.new({
  393. 'action_dispatch.request.request_parameters' => { 'some_key' => payload },
  394. 'action_dispatch.request.path_parameters' => { secret: 'foobar' },
  395. 'REQUEST_METHOD' => "POST",
  396. 'HTTP_ACCEPT' => 'application/xml',
  397. 'HTTP_X_HELLO_WORLD' => "Hello Huginn"
  398. })
  399. checked = false
  400. out = nil
  401. stub_request(:any, /verify/).to_return { |request|
  402. checked = true
  403. { status: 200, body: '{"success":false}' }
  404. }
  405. expect {
  406. out= agent.receive_web_request(webpayload)
  407. }.not_to change { checked }
  408. expect(out).to eq(["Event Created", 201])
  409. end
  410. it "should reject a request if recaptcha_secret is set but g-recaptcha-response is not given" do
  411. agent.options['recaptcha_secret'] = 'supersupersecret'
  412. webpayload = ActionDispatch::Request.new({
  413. 'action_dispatch.request.request_parameters' => { 'some_key' => payload },
  414. 'action_dispatch.request.path_parameters' => { secret: 'foobar' },
  415. 'REQUEST_METHOD' => "POST",
  416. 'HTTP_ACCEPT' => 'application/xml',
  417. 'HTTP_X_HELLO_WORLD' => "Hello Huginn"
  418. })
  419. checked = false
  420. out = nil
  421. stub_request(:any, /verify/).to_return { |request|
  422. checked = true
  423. { status: 200, body: '{"success":false}' }
  424. }
  425. expect {
  426. out = agent.receive_web_request(webpayload)
  427. }.not_to change { checked }
  428. expect(out).to eq(["Not Authorized", 401])
  429. end
  430. it "should reject a request if recaptcha_secret is set and g-recaptcha-response given is not verified" do
  431. agent.options['recaptcha_secret'] = 'supersupersecret'
  432. webpayload = ActionDispatch::Request.new({
  433. 'action_dispatch.request.request_parameters' => { 'some_key' => payload, 'g-recaptcha-response' => 'somevalue' },
  434. 'action_dispatch.request.path_parameters' => { secret: 'foobar' },
  435. 'REQUEST_METHOD' => "POST",
  436. 'HTTP_ACCEPT' => 'application/xml',
  437. 'HTTP_X_HELLO_WORLD' => "Hello Huginn"
  438. })
  439. checked = false
  440. out = nil
  441. stub_request(:any, /verify/).to_return { |request|
  442. checked = true
  443. { status: 200, body: '{"success":false}' }
  444. }
  445. expect {
  446. out = agent.receive_web_request(webpayload)
  447. }.to change { checked }
  448. expect(out).to eq(["Not Authorized", 401])
  449. end
  450. it "should accept a request if recaptcha_secret is set and g-recaptcha-response given is verified" do
  451. agent.options['payload_path'] = '.'
  452. agent.options['recaptcha_secret'] = 'supersupersecret'
  453. webpayload = ActionDispatch::Request.new({
  454. 'action_dispatch.request.request_parameters' => payload.merge({ 'g-recaptcha-response' => 'somevalue' }),
  455. 'action_dispatch.request.path_parameters' => { secret: 'foobar' },
  456. 'REQUEST_METHOD' => "POST",
  457. 'HTTP_ACCEPT' => 'application/xml',
  458. 'HTTP_X_HELLO_WORLD' => "Hello Huginn"
  459. })
  460. checked = false
  461. out = nil
  462. stub_request(:any, /verify/).to_return { |request|
  463. checked = true
  464. { status: 200, body: '{"success":true}' }
  465. }
  466. expect {
  467. out = agent.receive_web_request(webpayload)
  468. }.to change { checked }
  469. expect(out).to eq(["Event Created", 201])
  470. expect(Event.last.payload).to eq(payload)
  471. end
  472. it "should accept a request if recaptcha_secret is set and g-recaptcha-response given is verified and
  473. reCAPTCHA v3 score is above score_treshold" do
  474. agent.options['payload_path'] = '.'
  475. agent.options['recaptcha_secret'] = 'supersupersecret'
  476. agent.options['score_threshold'] = 0.5
  477. webpayload = ActionDispatch::Request.new({
  478. 'action_dispatch.request.request_parameters' => payload.merge({ 'g-recaptcha-response' => 'somevalue' }),
  479. 'action_dispatch.request.path_parameters' => { secret: 'foobar' },
  480. 'REQUEST_METHOD' => "POST",
  481. 'HTTP_ACCEPT' => 'application/xml',
  482. 'HTTP_X_HELLO_WORLD' => "Hello Huginn"
  483. })
  484. checked = false
  485. out = nil
  486. stub_request(:any, /verify/).to_return { |request|
  487. checked = true
  488. { status: 200, body: '{"success":true, "score":0.9}' }
  489. }
  490. expect {
  491. out = agent.receive_web_request(webpayload)
  492. }.to change { checked }
  493. expect(out).to eq(["Event Created", 201])
  494. expect(Event.last.payload).to eq(payload)
  495. end
  496. it "should reject a request if recaptcha_secret is set and g-recaptcha-response given is verified and
  497. reCAPTCHA v3 score is below score_treshold" do
  498. agent.options['payload_path'] = '.'
  499. agent.options['recaptcha_secret'] = 'supersupersecret'
  500. agent.options['score_threshold'] = 0.5
  501. webpayload = ActionDispatch::Request.new({
  502. 'action_dispatch.request.request_parameters' => payload.merge({ 'g-recaptcha-response' => 'somevalue' }),
  503. 'action_dispatch.request.path_parameters' => { secret: 'foobar' },
  504. 'REQUEST_METHOD' => "POST",
  505. 'HTTP_ACCEPT' => 'application/xml',
  506. 'HTTP_X_HELLO_WORLD' => "Hello Huginn"
  507. })
  508. checked = false
  509. out = nil
  510. stub_request(:any, /verify/).to_return { |request|
  511. checked = true
  512. { status: 200, body: '{"success":true, "score":0.1}' }
  513. }
  514. expect {
  515. out = agent.receive_web_request(webpayload)
  516. }.to change { checked }
  517. expect(out).to eq(["Not Authorized", 401])
  518. end
  519. end
  520. end
  521. context "with headers" do
  522. it "should not pass any headers if event_headers_key is not set" do
  523. webpayload = ActionDispatch::Request.new({
  524. 'action_dispatch.request.request_parameters' => { 'some_key' => payload },
  525. 'action_dispatch.request.path_parameters' => { secret: 'foobar' },
  526. 'REQUEST_METHOD' => "POST",
  527. 'HTTP_ACCEPT' => 'application/xml',
  528. 'HTTP_X_HELLO_WORLD' => "Hello Huginn"
  529. })
  530. agent.options['event_headers'] = 'Accept,X-Hello-World'
  531. agent.options['event_headers_key'] = ''
  532. out = nil
  533. expect {
  534. out = agent.receive_web_request(webpayload)
  535. }.to change { Event.count }.by(1)
  536. expect(out).to eq(['Event Created', 201])
  537. expect(Event.last.payload).to eq(payload)
  538. end
  539. it "should pass selected headers specified in event_headers_key" do
  540. webpayload = ActionDispatch::Request.new({
  541. 'action_dispatch.request.request_parameters' => { 'some_key' => payload },
  542. 'action_dispatch.request.path_parameters' => { secret: 'foobar' },
  543. 'REQUEST_METHOD' => "POST",
  544. 'HTTP_ACCEPT' => 'application/xml',
  545. 'HTTP_X_HELLO_WORLD' => "Hello Huginn"
  546. })
  547. agent.options['event_headers'] = 'X-Hello-World'
  548. agent.options['event_headers_key'] = 'X-HTTP-HEADERS'
  549. out = nil
  550. expect {
  551. out= agent.receive_web_request(webpayload)
  552. }.to change { Event.count }.by(1)
  553. expect(out).to eq(['Event Created', 201])
  554. expect(Event.last.payload).to eq({"people"=>[{"name"=>"bob"}, {"name"=>"jon"}], "X-HTTP-HEADERS"=>{"X-Hello-World"=>"Hello Huginn"}})
  555. end
  556. it "should pass empty event_headers_key if none of the headers exist" do
  557. webpayload = ActionDispatch::Request.new({
  558. 'action_dispatch.request.request_parameters' => { 'some_key' => payload },
  559. 'action_dispatch.request.path_parameters' => { secret: 'foobar' },
  560. 'REQUEST_METHOD' => "POST",
  561. 'HTTP_ACCEPT' => 'application/xml',
  562. 'HTTP_X_HELLO_WORLD' => "Hello Huginn"
  563. })
  564. agent.options['event_headers'] = 'x-hello-world1'
  565. agent.options['event_headers_key'] = 'X-HTTP-HEADERS'
  566. out = nil
  567. expect {
  568. out= agent.receive_web_request(webpayload)
  569. }.to change { Event.count }.by(1)
  570. expect(out).to eq(['Event Created', 201])
  571. expect(Event.last.payload).to eq({"people"=>[{"name"=>"bob"}, {"name"=>"jon"}], "X-HTTP-HEADERS"=>{}})
  572. end
  573. it "should pass empty event_headers_key if event_headers is empty" do
  574. webpayload = ActionDispatch::Request.new({
  575. 'action_dispatch.request.request_parameters' => { 'some_key' => payload },
  576. 'action_dispatch.request.path_parameters' => { secret: 'foobar' },
  577. 'REQUEST_METHOD' => "POST",
  578. 'HTTP_ACCEPT' => 'application/xml',
  579. 'HTTP_X_HELLO_WORLD' => "Hello Huginn"
  580. })
  581. agent.options['event_headers'] = ''
  582. agent.options['event_headers_key'] = 'X-HTTP-HEADERS'
  583. out = nil
  584. expect {
  585. out= agent.receive_web_request(webpayload)
  586. }.to change { Event.count }.by(1)
  587. expect(out).to eq(['Event Created', 201])
  588. expect(Event.last.payload).to eq({"people"=>[{"name"=>"bob"}, {"name"=>"jon"}], "X-HTTP-HEADERS"=>{}})
  589. end
  590. end
  591. end
  592. end