diff --git a/app/controllers/diaspora_federation/receive_controller.rb b/app/controllers/diaspora_federation/receive_controller.rb index 9b3c908..2e86b07 100644 --- a/app/controllers/diaspora_federation/receive_controller.rb +++ b/app/controllers/diaspora_federation/receive_controller.rb @@ -9,11 +9,12 @@ module DiasporaFederation # # POST /receive/public def public - logger.info "received a public message" - xml = CGI.unescape(params[:xml]) - logger.debug xml + legacy = request.content_type != "application/magic-envelope+xml" - DiasporaFederation.callbacks.trigger(:queue_public_receive, xml) + data = data_for_public_message(legacy) + logger.debug data + + DiasporaFederation.callbacks.trigger(:queue_public_receive, data, legacy) render nothing: true, status: 202 end @@ -22,19 +23,43 @@ module DiasporaFederation # # POST /receive/users/:guid def private - logger.info "received a private message for #{params[:guid]}" - xml = CGI.unescape(params[:xml]) - logger.debug xml + legacy = request.content_type != "application/json" - success = DiasporaFederation.callbacks.trigger(:queue_private_receive, params[:guid], xml) + data = data_for_private_message(legacy) + logger.debug data + + success = DiasporaFederation.callbacks.trigger(:queue_private_receive, params[:guid], data, legacy) render nothing: true, status: success ? 202 : 404 end private + # checks the xml parameter for legacy salmon slaps + # @deprecated def check_for_xml - render nothing: true, status: 422 if params[:xml].nil? + legacy_request = request.content_type.nil? || request.content_type == "application/x-www-form-urlencoded" + render nothing: true, status: 422 if params[:xml].nil? && legacy_request + end + + def data_for_public_message(legacy) + if legacy + logger.info "received a public salmon slap" + CGI.unescape(params[:xml]) + else + logger.info "received a public magic envelope" + request.body.read + end + end + + def data_for_private_message(legacy) + if legacy + logger.info "received a private salmon slap for #{params[:guid]}" + CGI.unescape(params[:xml]) + else + logger.info "received a private encrypted magic envelope for #{params[:guid]}" + request.body.read + end end end end diff --git a/lib/diaspora_federation.rb b/lib/diaspora_federation.rb index 5756e2c..a4bea52 100644 --- a/lib/diaspora_federation.rb +++ b/lib/diaspora_federation.rb @@ -155,12 +155,14 @@ module DiasporaFederation # # queue_public_receive # Queue a public salmon xml to process in background - # @param [String] xml salmon xml + # @param [String] data salmon slap xml or magic envelope xml + # @param [Boolean] legacy true if it is a legacy salmon slap, false if it is a magic envelope xml # # queue_private_receive # Queue a private salmon xml to process in background # @param [String] guid guid of the receiver person - # @param [String] xml salmon xml + # @param [String] data salmon slap xml or encrypted magic envelope json + # @param [Boolean] legacy true if it is a legacy salmon slap, false if it is a encrypted magic envelope json # @return [Boolean] true if successful, false if the user was not found # # save_entity_after_receive diff --git a/spec/controllers/diaspora_federation/receive_controller_spec.rb b/spec/controllers/diaspora_federation/receive_controller_spec.rb index 3131280..5acbe14 100644 --- a/spec/controllers/diaspora_federation/receive_controller_spec.rb +++ b/spec/controllers/diaspora_federation/receive_controller_spec.rb @@ -3,55 +3,108 @@ module DiasporaFederation routes { DiasporaFederation::Engine.routes } describe "POST #public" do - it "returns a 422 if no xml is passed" do - post :public - expect(response.code).to eq("422") + context "legacy salmon slap" do + it "returns a 422 if no xml is passed" do + post :public + expect(response.code).to eq("422") + end + + it "returns a 422 if no xml is passed with content-type application/x-www-form-urlencoded" do + @request.env["CONTENT_TYPE"] = "application/x-www-form-urlencoded" + post :public + expect(response.code).to eq("422") + end + + it "returns a 202 if queued correctly" do + expect(DiasporaFederation.callbacks).to receive(:trigger).with(:queue_public_receive, "", true) + + post :public, xml: "" + expect(response.code).to eq("202") + end + + it "unescapes the xml before sending it to the callback" do + expect(DiasporaFederation.callbacks).to receive(:trigger).with(:queue_public_receive, "", true) + + post :public, xml: CGI.escape("") + end end - it "returns a 202 if queued correctly" do - expect(DiasporaFederation.callbacks).to receive(:trigger).with(:queue_public_receive, "") + context "magic envelope" do + before do + @request.env["CONTENT_TYPE"] = "application/magic-envelope+xml" + end - post :public, xml: "" - expect(response.code).to eq("202") - end + it "returns a 202 if queued correctly" do + expect(DiasporaFederation.callbacks).to receive(:trigger).with(:queue_public_receive, "", false) - it "unescapes the xml before sending it to the callback" do - expect(DiasporaFederation.callbacks).to receive(:trigger).with(:queue_public_receive, "") - - post :public, xml: CGI.escape("") + post :public, "" + expect(response.code).to eq("202") + end end end describe "POST #private" do - it "return a 404 if not queued successfully (unknown user guid)" do - expect(DiasporaFederation.callbacks).to receive(:trigger).with( - :queue_private_receive, "any-guid", "" - ).and_return(false) + context "legacy salmon slap" do + it "return a 404 if not queued successfully (unknown user guid)" do + expect(DiasporaFederation.callbacks).to receive(:trigger).with( + :queue_private_receive, "any-guid", "", true + ).and_return(false) - post :private, guid: "any-guid", xml: "" - expect(response.code).to eq("404") + post :private, guid: "any-guid", xml: "" + expect(response.code).to eq("404") + end + + it "returns a 422 if no xml is passed" do + post :private, guid: "any-guid" + expect(response.code).to eq("422") + end + + it "returns a 422 if no xml is passed with content-type application/x-www-form-urlencoded" do + @request.env["CONTENT_TYPE"] = "application/x-www-form-urlencoded" + post :private, guid: "any-guid" + expect(response.code).to eq("422") + end + + it "returns a 202 if the callback returned true" do + expect(DiasporaFederation.callbacks).to receive(:trigger).with( + :queue_private_receive, "any-guid", "", true + ).and_return(true) + + post :private, guid: "any-guid", xml: "" + expect(response.code).to eq("202") + end + + it "unescapes the xml before sending it to the callback" do + expect(DiasporaFederation.callbacks).to receive(:trigger).with( + :queue_private_receive, "any-guid", "", true + ).and_return(true) + + post :private, guid: "any-guid", xml: CGI.escape("") + end end - it "returns a 422 if no xml is passed" do - post :private, guid: "any-guid" - expect(response.code).to eq("422") - end + context "encrypted magic envelope" do + before do + @request.env["CONTENT_TYPE"] = "application/json" + end - it "returns a 202 if the callback returned true" do - expect(DiasporaFederation.callbacks).to receive(:trigger).with( - :queue_private_receive, "any-guid", "" - ).and_return(true) + it "return a 404 if not queued successfully (unknown user guid)" do + expect(DiasporaFederation.callbacks).to receive(:trigger).with( + :queue_private_receive, "any-guid", "{\"aes_key\": \"key\", \"encrypted_magic_envelope\": \"env\"}", false + ).and_return(false) - post :private, guid: "any-guid", xml: "" - expect(response.code).to eq("202") - end + post :private, "{\"aes_key\": \"key\", \"encrypted_magic_envelope\": \"env\"}", guid: "any-guid" + expect(response.code).to eq("404") + end - it "unescapes the xml before sending it to the callback" do - expect(DiasporaFederation.callbacks).to receive(:trigger).with( - :queue_private_receive, "any-guid", "" - ).and_return(true) + it "returns a 202 if the callback returned true" do + expect(DiasporaFederation.callbacks).to receive(:trigger).with( + :queue_private_receive, "any-guid", "{\"aes_key\": \"key\", \"encrypted_magic_envelope\": \"env\"}", false + ).and_return(true) - post :private, guid: "any-guid", xml: CGI.escape("") + post :private, "{\"aes_key\": \"key\", \"encrypted_magic_envelope\": \"env\"}", guid: "any-guid" + expect(response.code).to eq("202") + end end end end