diff --git a/CHANGES.md b/CHANGES.md index 36f73908..e2d69750 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,5 +1,6 @@ # Changes +* 0.4 (April 10, 2014) - WebHooksController has been renamed to WebRequestsController and all HTTP verbs are now accepted and passed through to Agents' #receive_web_request method. The new DataOutputAgent returns JSON or RSS feeds of incoming Events via external web request. * 0.31 (Jan 2, 2014) - Agents now have an optional keep\_events\_for option that is propagated to created events' expires\_at field, and they update their events' expires\_at fields on change. * 0.3 (Jan 1, 2014) - Remove symbolization of memory, options, and payloads; convert memory, options, and payloads to JSON from YAML. Migration will perform conversion and adjust tables to be UTF-8. Recommend making a DB backup before migrating. * 0.2 (Nov 6, 2013) - PeakDetectorAgent now uses `window_duration_in_days` and `min_peak_spacing_in_days`. Additionally, peaks trigger when the time series rises over the standard deviation multiple, not after it starts to fall. diff --git a/app/controllers/web_requests_controller.rb b/app/controllers/web_requests_controller.rb new file mode 100644 index 00000000..8bafc9ae --- /dev/null +++ b/app/controllers/web_requests_controller.rb @@ -0,0 +1,41 @@ +# This controller is designed to allow your Agents to receive cross-site Webhooks (POSTs), or to output data streams. +# When a POST or GET is received, your Agent will have #receive_web_request called on itself with the incoming params, +# method, and requested content-type. +# +# Requests are routed as follows: +# http://yourserver.com/users/:user_id/web_requests/:agent_id/:secret +# where :user_id is a User's id, :agent_id is an Agent's id, and :secret is a token that should be user-specifiable in +# an Agent that implements #receive_web_request. It is highly recommended that every Agent verify this token whenever +# #receive_web_request is called. For example, one of your Agent's options could be :secret and you could compare this +# value to params[:secret] whenever #receive_web_request is called on your Agent, rejecting invalid requests. +# +# Your Agent's #receive_web_request method should return an Array of json_or_string_response, status_code, and +# optional mime type. For example: +# [{status: "success"}, 200] +# or +# ["not found", 404, 'text/plain'] + +class WebRequestsController < ApplicationController + skip_before_filter :authenticate_user! + + def handle_request + user = User.find_by_id(params[:user_id]) + if user + agent = user.agents.find_by_id(params[:agent_id]) + if agent + content, status, content_type = agent.trigger_web_request(params.except(:action, :controller, :agent_id, :user_id, :format), request.method_symbol.to_s, request.format.to_s) + if content.is_a?(String) + render :text => content, :status => status || 200, :content_type => content_type || 'text/plain' + elsif content.is_a?(Hash) + render :json => content, :status => status || 200 + else + head(status || 200) + end + else + render :text => "agent not found", :status => 404 + end + else + render :text => "user not found", :status => 404 + end + end +end diff --git a/app/controllers/webhooks_controller.rb b/app/controllers/webhooks_controller.rb deleted file mode 100644 index c4a7cdc1..00000000 --- a/app/controllers/webhooks_controller.rb +++ /dev/null @@ -1,39 +0,0 @@ -# This controller is designed to allow your Agents to receive cross-site Webhooks (POSTs), or to output data streams. -# When a POST or GET is received, your Agent will have #receive_webhook called on itself with the incoming params. -# -# To implement webhooks, make POSTs to the following URL: -# http://yourserver.com/users/:user_id/webhooks/:agent_id/:secret -# where :user_id is your User's id, :agent_id is an Agent's id, and :secret is a token that should be -# user-specifiable in your Agent. It is highly recommended that you verify this token whenever #receive_webhook -# is called. For example, one of your Agent's options could be :secret and you could compare this value -# to params[:secret] whenever #receive_webhook is called on your Agent, rejecting invalid requests. -# -# Your Agent's #receive_webhook method should return an Array of [json_or_string_response, status_code, optional mime type]. For example: -# [{status: "success"}, 200] -# or -# ["not found", 404, 'text/plain'] - -class WebhooksController < ApplicationController - skip_before_filter :authenticate_user! - - def handle_request - user = User.find_by_id(params[:user_id]) - if user - agent = user.agents.find_by_id(params[:agent_id]) - if agent - content, status, content_type = agent.trigger_webhook(params.except(:action, :controller, :agent_id, :user_id, :format), request.method_symbol.to_s, request.format.to_s) - if content.is_a?(String) - render :text => content, :status => status || 200, :content_type => content_type || 'text/plain' - elsif content.is_a?(Hash) - render :json => content, :status => status || 200 - else - head(status || 200) - end - else - render :text => "agent not found", :status => 404 - end - else - render :text => "user not found", :status => 404 - end - end -end diff --git a/app/models/agent.rb b/app/models/agent.rb index d25549cc..976fdb1b 100644 --- a/app/models/agent.rb +++ b/app/models/agent.rb @@ -73,7 +73,7 @@ class Agent < ActiveRecord::Base # Implement me in your subclass of Agent. end - def receive_webhook(params, method, format) + def receive_web_request(params, method, format) # Implement me in your subclass of Agent. ["not implemented", 404] end @@ -136,10 +136,18 @@ class Agent < ActiveRecord::Base message.gsub(/<([^>]+)>/) { Utils.value_at(payload, $1) || "??" } end - def trigger_webhook(params, method, format) - receive_webhook(params, method, format).tap do - self.last_webhook_at = Time.now - save! + def trigger_web_request(params, method, format) + if respond_to?(:receive_webhook) + Rails.logger.warn "DEPRECATED: The .receive_webhook method is deprecated, please switch your Agent to use .receive_web_request." + receive_webhook(params).tap do + self.last_web_request_at = Time.now + save! + end + else + receive_web_request(params, method, format).tap do + self.last_web_request_at = Time.now + save! + end end end diff --git a/app/models/agents/data_output_agent.rb b/app/models/agents/data_output_agent.rb index f57f85e2..df58530c 100644 --- a/app/models/agents/data_output_agent.rb +++ b/app/models/agents/data_output_agent.rb @@ -8,7 +8,7 @@ module Agents This Agent will output data at: - `https://#{ENV['DOMAIN']}/users/#{user.id}/webhooks/#{id || ''}/:secret.xml` + `https://#{ENV['DOMAIN']}/users/#{user.id}/web_requests/#{id || ''}/:secret.xml` where `:secret` is one of the allowed secrets specified in your options and the extension can be `xml` or `json`. @@ -75,7 +75,7 @@ module Agents options['template']['description'].presence || "A feed of Events received by the '#{name}' Huginn Agent" end - def receive_webhook(params, method, format) + def receive_web_request(params, method, format) if options['secrets'].include?(params['secret']) items = received_events.order('id desc').limit(events_to_show).map do |event| interpolated = Utils.recursively_interpolate_jsonpaths(options['template']['item'], event.payload, :leading_dollarsign_is_jsonpath => true) diff --git a/app/models/agents/twilio_agent.rb b/app/models/agents/twilio_agent.rb index 74fe9d8d..a8648265 100644 --- a/app/models/agents/twilio_agent.rb +++ b/app/models/agents/twilio_agent.rb @@ -75,10 +75,10 @@ module Agents end def post_url(server_url,secret) - "#{server_url}/users/#{self.user.id}/webhooks/#{self.id}/#{secret}" + "#{server_url}/users/#{self.user.id}/web_requests/#{self.id}/#{secret}" end - def receive_webhook(params, method, format) + def receive_web_request(params, method, format) if memory['pending_calls'].has_key? params['secret'] response = Twilio::TwiML::Response.new {|r| r.Say memory['pending_calls'][params['secret']], :voice => 'woman'} memory['pending_calls'].delete params['secret'] diff --git a/app/models/agents/webhook_agent.rb b/app/models/agents/webhook_agent.rb index 2f13e146..9168affc 100644 --- a/app/models/agents/webhook_agent.rb +++ b/app/models/agents/webhook_agent.rb @@ -1,6 +1,7 @@ module Agents class WebhookAgent < Agent cannot_be_scheduled! + cannot_receive_events! description do <<-MD @@ -8,7 +9,7 @@ module Agents In order to create events with this agent, make a POST request to: ``` - https://#{ENV['DOMAIN']}/users/#{user.id}/webhooks/#{id || ''}/:secret + https://#{ENV['DOMAIN']}/users/#{user.id}/web_requests/#{id || ''}/:secret ``` where `:secret` is specified in your options. The @@ -36,9 +37,10 @@ module Agents "payload_path" => "payload"} end - def receive_webhook(params, method, format) + def receive_web_request(params, method, format) secret = params.delete('secret') - return ["Not Authorized", 401] unless secret == options['secret'] && method == "post" + return ["Please use POST requests only", 401] unless method == "post" + return ["Not Authorized", 401] unless secret == options['secret'] create_event(:payload => payload_for(params)) diff --git a/app/views/agents/agent_views/data_output_agent/_show.html.erb b/app/views/agents/agent_views/data_output_agent/_show.html.erb index 856bceea..c491bedd 100644 --- a/app/views/agents/agent_views/data_output_agent/_show.html.erb +++ b/app/views/agents/agent_views/data_output_agent/_show.html.erb @@ -5,7 +5,7 @@
    <% @agent.options['secrets'].each do |secret| %> - <% url = lambda { |format| webhooks_url(:agent_id => @agent.id, :user_id => current_user.id, :secret => secret, :format => format) } %> + <% url = lambda { |format| web_requests_url(:agent_id => @agent.id, :user_id => current_user.id, :secret => secret, :format => format) } %>
  • <%= link_to url.call(:json), url.call(:json), :target => :blank %>
  • <%= link_to url.call(:xml), url.call(:xml), :target => :blank %>
  • <% end %> diff --git a/app/views/agents/agent_views/webhook_agent/_show.html.erb b/app/views/agents/agent_views/webhook_agent/_show.html.erb new file mode 100644 index 00000000..dc23e672 --- /dev/null +++ b/app/views/agents/agent_views/webhook_agent/_show.html.erb @@ -0,0 +1,3 @@ +

    + Send WebHooks (POST requests) to this Agent at <%= link_to web_requests_url(:agent_id => @agent.id, :user_id => current_user.id, :secret => @agent.options['secret']), web_requests_url(:agent_id => @agent.id, :user_id => current_user.id, :secret => @agent.options['secret']), :target => :blank %> +

    \ No newline at end of file diff --git a/config/routes.rb b/config/routes.rb index db9358e8..c2d044be 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -31,7 +31,9 @@ Huginn::Application.routes.draw do match "/worker_status" => "worker_status#show" post "/users/:user_id/update_location/:secret" => "user_location_updates#create" - match "/users/:user_id/webhooks/:agent_id/:secret" => "webhooks#handle_request", :as => :webhooks + + match "/users/:user_id/web_requests/:agent_id/:secret" => "web_requests#handle_request", :as => :web_requests + post "/users/:user_id/webhooks/:agent_id/:secret" => "web_requests#handle_request" # legacy # match "/delayed_job" => DelayedJobWeb, :anchor => false devise_for :users, :sign_out_via => [ :post, :delete ] diff --git a/db/migrate/20140408150825_rename_webhook_to_web_request.rb b/db/migrate/20140408150825_rename_webhook_to_web_request.rb new file mode 100644 index 00000000..c107595f --- /dev/null +++ b/db/migrate/20140408150825_rename_webhook_to_web_request.rb @@ -0,0 +1,9 @@ +class RenameWebhookToWebRequest < ActiveRecord::Migration + def up + rename_column :agents, :last_webhook_at, :last_web_request_at + end + + def down + rename_column :agents, :last_web_request_at, :last_webhook_at + end +end diff --git a/db/schema.rb b/db/schema.rb index 87da5de2..49ac682b 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,21 +11,21 @@ # # It's strongly recommended to check this file into your version control system. -ActiveRecord::Schema.define(:version => 20140216201250) do +ActiveRecord::Schema.define(:version => 20140408150825) do create_table "agent_logs", :force => true do |t| - t.integer "agent_id", :null => false - t.text "message", :limit => 16777215, :null => false - t.integer "level", :default => 3, :null => false + t.integer "agent_id", :null => false + t.text "message", :null => false + t.integer "level", :default => 3, :null => false t.integer "inbound_event_id" t.integer "outbound_event_id" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false end create_table "agents", :force => true do |t| t.integer "user_id" - t.text "options", :limit => 16777215 + t.text "options" t.string "type" t.string "name" t.string "schedule" @@ -36,10 +36,10 @@ ActiveRecord::Schema.define(:version => 20140216201250) do t.datetime "created_at", :null => false t.datetime "updated_at", :null => false t.text "memory", :limit => 2147483647 - t.datetime "last_webhook_at" + t.datetime "last_web_request_at" + t.integer "keep_events_for", :default => 0, :null => false t.datetime "last_event_at" t.datetime "last_error_log_at" - t.integer "keep_events_for", :default => 0, :null => false t.boolean "propagate_immediately", :default => false, :null => false end @@ -47,19 +47,11 @@ ActiveRecord::Schema.define(:version => 20140216201250) do add_index "agents", ["type"], :name => "index_agents_on_type" add_index "agents", ["user_id", "created_at"], :name => "index_agents_on_user_id_and_created_at" - create_table "contacts", :force => true do |t| - t.text "message" - t.string "name" - t.string "email" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - end - create_table "delayed_jobs", :force => true do |t| t.integer "priority", :default => 0 t.integer "attempts", :default => 0 t.text "handler", :limit => 16777215 - t.text "last_error", :limit => 16777215 + t.text "last_error" t.datetime "run_at" t.datetime "locked_at" t.datetime "failed_at" @@ -74,11 +66,11 @@ ActiveRecord::Schema.define(:version => 20140216201250) do create_table "events", :force => true do |t| t.integer "user_id" t.integer "agent_id" - t.decimal "lat", :precision => 15, :scale => 10 - t.decimal "lng", :precision => 15, :scale => 10 - t.text "payload", :limit => 2147483647 - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false + t.decimal "lat", :precision => 15, :scale => 10 + t.decimal "lng", :precision => 15, :scale => 10 + t.text "payload", :limit => 16777215 + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false t.datetime "expires_at" end diff --git a/spec/controllers/webhooks_controller_spec.rb b/spec/controllers/web_requests_controller_spec.rb similarity index 59% rename from spec/controllers/webhooks_controller_spec.rb rename to spec/controllers/web_requests_controller_spec.rb index d978f8c9..fdc6348a 100644 --- a/spec/controllers/webhooks_controller_spec.rb +++ b/spec/controllers/web_requests_controller_spec.rb @@ -1,15 +1,15 @@ require 'spec_helper' -describe WebhooksController do - class Agents::WebhookReceiverAgent < Agent +describe WebRequestsController do + class Agents::WebRequestReceiverAgent < Agent cannot_receive_events! cannot_be_scheduled! - def receive_webhook(params, method, format) + def receive_web_request(params, method, format) if params.delete(:secret) == options[:secret] - memory[:webhook_values] = params - memory[:webhook_format] = format - memory[:webhook_method] = method + memory[:web_request_values] = params + memory[:web_request_format] = format + memory[:web_request_method] = method ["success", 200, memory['content_type']] else ["failure", 404] @@ -18,32 +18,32 @@ describe WebhooksController do end before do - stub(Agents::WebhookReceiverAgent).valid_type?("Agents::WebhookReceiverAgent") { true } - @agent = Agents::WebhookReceiverAgent.new(:name => "something", :options => { :secret => "my_secret" }) + stub(Agents::WebRequestReceiverAgent).valid_type?("Agents::WebRequestReceiverAgent") { true } + @agent = Agents::WebRequestReceiverAgent.new(:name => "something", :options => { :secret => "my_secret" }) @agent.user = users(:bob) @agent.save! end - it "should not require login to trigger a webhook" do - @agent.last_webhook_at.should be_nil + it "should not require login to receive a web request" do + @agent.last_web_request_at.should be_nil post :handle_request, :user_id => users(:bob).to_param, :agent_id => @agent.id, :secret => "my_secret", :key => "value", :another_key => "5" - @agent.reload.last_webhook_at.should be_within(2).of(Time.now) + @agent.reload.last_web_request_at.should be_within(2).of(Time.now) response.body.should == "success" response.should be_success end - it "should call receive_webhook" do + it "should call receive_web_request" do post :handle_request, :user_id => users(:bob).to_param, :agent_id => @agent.id, :secret => "my_secret", :key => "value", :another_key => "5" @agent.reload - @agent.memory[:webhook_values].should == { 'key' => "value", 'another_key' => "5" } - @agent.memory[:webhook_format].should == "text/html" - @agent.memory[:webhook_method].should == "post" + @agent.memory[:web_request_values].should == { 'key' => "value", 'another_key' => "5" } + @agent.memory[:web_request_format].should == "text/html" + @agent.memory[:web_request_method].should == "post" response.body.should == "success" response.headers['Content-Type'].should == 'text/plain; charset=utf-8' response.should be_success post :handle_request, :user_id => users(:bob).to_param, :agent_id => @agent.id, :secret => "not_my_secret", :no => "go" - @agent.reload.memory[:webhook_values].should_not == { 'no' => "go" } + @agent.reload.memory[:web_request_values].should_not == { 'no' => "go" } response.body.should == "failure" response.should be_missing end @@ -51,9 +51,9 @@ describe WebhooksController do it "should accept gets" do get :handle_request, :user_id => users(:bob).to_param, :agent_id => @agent.id, :secret => "my_secret", :key => "value", :another_key => "5" @agent.reload - @agent.memory[:webhook_values].should == { 'key' => "value", 'another_key' => "5" } - @agent.memory[:webhook_format].should == "text/html" - @agent.memory[:webhook_method].should == "get" + @agent.memory[:web_request_values].should == { 'key' => "value", 'another_key' => "5" } + @agent.memory[:web_request_format].should == "text/html" + @agent.memory[:web_request_method].should == "get" response.body.should == "success" response.should be_success end @@ -61,21 +61,21 @@ describe WebhooksController do it "should pass through the received format" do get :handle_request, :user_id => users(:bob).to_param, :agent_id => @agent.id, :secret => "my_secret", :key => "value", :another_key => "5", :format => :json @agent.reload - @agent.memory[:webhook_values].should == { 'key' => "value", 'another_key' => "5" } - @agent.memory[:webhook_format].should == "application/json" - @agent.memory[:webhook_method].should == "get" + @agent.memory[:web_request_values].should == { 'key' => "value", 'another_key' => "5" } + @agent.memory[:web_request_format].should == "application/json" + @agent.memory[:web_request_method].should == "get" post :handle_request, :user_id => users(:bob).to_param, :agent_id => @agent.id, :secret => "my_secret", :key => "value", :another_key => "5", :format => :xml @agent.reload - @agent.memory[:webhook_values].should == { 'key' => "value", 'another_key' => "5" } - @agent.memory[:webhook_format].should == "application/xml" - @agent.memory[:webhook_method].should == "post" + @agent.memory[:web_request_values].should == { 'key' => "value", 'another_key' => "5" } + @agent.memory[:web_request_format].should == "application/xml" + @agent.memory[:web_request_method].should == "post" put :handle_request, :user_id => users(:bob).to_param, :agent_id => @agent.id, :secret => "my_secret", :key => "value", :another_key => "5", :format => :atom @agent.reload - @agent.memory[:webhook_values].should == { 'key' => "value", 'another_key' => "5" } - @agent.memory[:webhook_format].should == "application/atom+xml" - @agent.memory[:webhook_method].should == "put" + @agent.memory[:web_request_values].should == { 'key' => "value", 'another_key' => "5" } + @agent.memory[:web_request_format].should == "application/atom+xml" + @agent.memory[:web_request_method].should == "put" end it "can accept a content-type to return" do diff --git a/spec/models/agent_spec.rb b/spec/models/agent_spec.rb index 258de331..28f5b1ef 100644 --- a/spec/models/agent_spec.rb +++ b/spec/models/agent_spec.rb @@ -514,7 +514,55 @@ describe Agent do end end end + end + describe ".trigger_web_request" do + class Agents::WebRequestReceiver < Agent + cannot_be_scheduled! + end + + before do + stub(Agents::WebRequestReceiver).valid_type?("Agents::WebRequestReceiver") { true } + end + + context "when .receive_web_request is defined" do + before do + @agent = Agents::WebRequestReceiver.new(:name => "something") + @agent.user = users(:bob) + @agent.save! + + def @agent.receive_web_request(params, method, format) + memory['last_request'] = [params, method, format] + ['Ok!', 200] + end + end + + it "calls the .receive_web_request hook, updates last_web_request_at, and saves" do + @agent.trigger_web_request({ :some_param => "some_value" }, "post", "text/html") + @agent.reload.memory['last_request'].should == [ { "some_param" => "some_value" }, "post", "text/html" ] + @agent.last_web_request_at.to_i.should be_within(1).of(Time.now.to_i) + end + end + + context "when .receive_webhook is defined" do + before do + @agent = Agents::WebRequestReceiver.new(:name => "something") + @agent.user = users(:bob) + @agent.save! + + def @agent.receive_webhook(params) + memory['last_webhook_request'] = params + ['Ok!', 200] + end + end + + it "outputs a deprecation warning and calls .receive_webhook with the params" do + mock(Rails.logger).warn("DEPRECATED: The .receive_webhook method is deprecated, please switch your Agent to use .receive_web_request.") + @agent.trigger_web_request({ :some_param => "some_value" }, "post", "text/html") + @agent.reload.memory['last_webhook_request'].should == { "some_param" => "some_value" } + @agent.last_web_request_at.to_i.should be_within(1).of(Time.now.to_i) + end + end end describe "recent_error_logs?" do diff --git a/spec/models/agents/data_output_agent_spec.rb b/spec/models/agents/data_output_agent_spec.rb index e30313bc..e8e2b685 100644 --- a/spec/models/agents/data_output_agent_spec.rb +++ b/spec/models/agents/data_output_agent_spec.rb @@ -62,7 +62,7 @@ describe Agents::DataOutputAgent do end end - describe "#receive_webhook" do + describe "#receive_web_request" do before do current_time = Time.now stub(Time).now { current_time } @@ -70,15 +70,15 @@ describe Agents::DataOutputAgent do end it "requires a valid secret" do - content, status, content_type = agent.receive_webhook({ 'secret' => 'fake' }, 'get', 'text/xml') + content, status, content_type = agent.receive_web_request({ 'secret' => 'fake' }, 'get', 'text/xml') status.should == 401 content.should == "Not Authorized" - content, status, content_type = agent.receive_webhook({ 'secret' => 'fake' }, 'get', 'application/json') + content, status, content_type = agent.receive_web_request({ 'secret' => 'fake' }, 'get', 'application/json') status.should == 401 content.should == { :error => "Not Authorized" } - content, status, content_type = agent.receive_webhook({ 'secret' => 'secret1' }, 'get', 'application/json') + content, status, content_type = agent.receive_web_request({ 'secret' => 'secret1' }, 'get', 'application/json') status.should == 200 end @@ -100,7 +100,7 @@ describe Agents::DataOutputAgent do end it "can output RSS" do - content, status, content_type = agent.receive_webhook({ 'secret' => 'secret1' }, 'get', 'text/xml') + content, status, content_type = agent.receive_web_request({ 'secret' => 'secret1' }, 'get', 'text/xml') status.should == 200 content_type.should == 'text/xml' content.gsub(/\s+/, '').should == Utils.unindent(<<-XML).gsub(/\s+/, '') @@ -137,7 +137,7 @@ describe Agents::DataOutputAgent do it "can output JSON" do agent.options['template']['item']['foo'] = "hi" - content, status, content_type = agent.receive_webhook({ 'secret' => 'secret2' }, 'get', 'application/json') + content, status, content_type = agent.receive_web_request({ 'secret' => 'secret2' }, 'get', 'application/json') status.should == 200 content.should == { diff --git a/spec/models/agents/webhook_agent_spec.rb b/spec/models/agents/webhook_agent_spec.rb index 36c90307..e514532f 100644 --- a/spec/models/agents/webhook_agent_spec.rb +++ b/spec/models/agents/webhook_agent_spec.rb @@ -10,11 +10,11 @@ describe Agents::WebhookAgent do end let(:payload) { {'some' => 'info'} } - describe 'receive_webhook' do + describe 'receive_web_request' do it 'should create event if secret matches' do out = nil lambda { - out = agent.receive_webhook({ 'secret' => 'foobar', 'payload' => payload }, "post", "text/html") + out = agent.receive_web_request({ 'secret' => 'foobar', 'payload' => payload }, "post", "text/html") }.should change { Event.count }.by(1) out.should eq(['Event Created', 201]) Event.last.payload.should eq(payload) @@ -23,7 +23,7 @@ describe Agents::WebhookAgent do it 'should not create event if secrets dont match' do out = nil lambda { - out = agent.receive_webhook({ 'secret' => 'bazbat', 'payload' => payload }, "post", "text/html") + out = agent.receive_web_request({ 'secret' => 'bazbat', 'payload' => payload }, "post", "text/html") }.should change { Event.count }.by(0) out.should eq(['Not Authorized', 401]) end @@ -31,9 +31,9 @@ describe Agents::WebhookAgent do it "should only accept POSTs" do out = nil lambda { - out = agent.receive_webhook({ 'secret' => 'foobar', 'payload' => payload }, "get", "text/html") + out = agent.receive_web_request({ 'secret' => 'foobar', 'payload' => payload }, "get", "text/html") }.should change { Event.count }.by(0) - out.should eq(['Not Authorized', 401]) + out.should eq(['Please use POST requests only', 401]) end end end diff --git a/spec/routing/webhooks_controller_spec.rb b/spec/routing/webhooks_controller_spec.rb index b9b51f8d..41392c6f 100644 --- a/spec/routing/webhooks_controller_spec.rb +++ b/spec/routing/webhooks_controller_spec.rb @@ -1,19 +1,23 @@ require 'spec_helper' -describe "routing for webhooks" do +describe "routing for web requests" do it "routes to handle_request" do resulting_params = { :user_id => "6", :agent_id => "2", :secret => "foobar" } - get("/users/6/webhooks/2/foobar").should route_to("webhooks#handle_request", resulting_params) - post("/users/6/webhooks/2/foobar").should route_to("webhooks#handle_request", resulting_params) - put("/users/6/webhooks/2/foobar").should route_to("webhooks#handle_request", resulting_params) - delete("/users/6/webhooks/2/foobar").should route_to("webhooks#handle_request", resulting_params) + get("/users/6/web_requests/2/foobar").should route_to("web_requests#handle_request", resulting_params) + post("/users/6/web_requests/2/foobar").should route_to("web_requests#handle_request", resulting_params) + put("/users/6/web_requests/2/foobar").should route_to("web_requests#handle_request", resulting_params) + delete("/users/6/web_requests/2/foobar").should route_to("web_requests#handle_request", resulting_params) + end + + it "supports the legacy /webhooks/ route" do + post("/users/6/webhooks/2/foobar").should route_to("web_requests#handle_request", :user_id => "6", :agent_id => "2", :secret => "foobar") end it "routes with format" do - get("/users/6/webhooks/2/foobar.json").should route_to("webhooks#handle_request", + get("/users/6/web_requests/2/foobar.json").should route_to("web_requests#handle_request", { :user_id => "6", :agent_id => "2", :secret => "foobar", :format => "json" }) - get("/users/6/webhooks/2/foobar.atom").should route_to("webhooks#handle_request", + get("/users/6/web_requests/2/foobar.atom").should route_to("web_requests#handle_request", { :user_id => "6", :agent_id => "2", :secret => "foobar", :format => "atom" }) end end