web_requests_controller.rb 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. # This controller is designed to allow your Agents to receive cross-site Webhooks (POSTs), or to output data streams.
  2. # When a POST or GET is received, your Agent will have #receive_web_request called on itself with the incoming params,
  3. # method, and requested content-type.
  4. #
  5. # Requests are routed as follows:
  6. # http://yourserver.com/users/:user_id/web_requests/:agent_id/:secret
  7. # 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
  8. # an Agent that implements #receive_web_request. It is highly recommended that every Agent verify this token whenever
  9. # #receive_web_request is called. For example, one of your Agent's options could be :secret and you could compare this
  10. # value to params[:secret] whenever #receive_web_request is called on your Agent, rejecting invalid requests.
  11. #
  12. # Your Agent's #receive_web_request method should return an Array of json_or_string_response, status_code,
  13. # optional mime type, and optional hash of custom response headers. For example:
  14. # [{status: "success"}, 200]
  15. # or
  16. # ["not found", 404, 'text/plain']
  17. # or
  18. # ["<status>success</status>", 200, 'text/xml', {"Access-Control-Allow-Origin" => "*"}]
  19. class WebRequestsController < ApplicationController
  20. skip_before_action :verify_authenticity_token
  21. skip_before_action :authenticate_user!
  22. def handle_request
  23. user = User.find_by_id(params[:user_id])
  24. if user
  25. agent = user.agents.find_by_id(params[:agent_id])
  26. if agent
  27. content, status, content_type, headers = agent.trigger_web_request(request)
  28. if headers.present?
  29. headers.each do |k,v|
  30. response.headers[k] = v
  31. end
  32. end
  33. status = status || 200
  34. if status.to_s.in?(["301", "302"])
  35. redirect_to content, status: status
  36. elsif content.is_a?(String)
  37. render plain: content, :status => status, :content_type => content_type || 'text/plain'
  38. elsif content.is_a?(Hash)
  39. render :json => content, :status => status
  40. else
  41. head(status)
  42. end
  43. else
  44. render plain: "agent not found", :status => 404
  45. end
  46. else
  47. render plain: "user not found", :status => 404
  48. end
  49. end
  50. # legacy
  51. def update_location
  52. if user = User.find_by_id(params[:user_id])
  53. secret = params[:secret]
  54. user.agents.of_type(Agents::UserLocationAgent).each { |agent|
  55. if agent.options[:secret] == secret
  56. agent.trigger_web_request(request)
  57. end
  58. }
  59. render plain: "ok"
  60. else
  61. render plain: "user not found", :status => :not_found
  62. end
  63. end
  64. end