Remove old Slap and EncryptedSlap and cleanup legacy receive
Closes #30
This commit is contained in:
parent
56385a14c1
commit
0163963849
11 changed files with 13 additions and 462 deletions
|
|
@ -5,18 +5,14 @@ require_dependency "diaspora_federation/application_controller"
|
|||
module DiasporaFederation
|
||||
# This controller processes receiving messages.
|
||||
class ReceiveController < ApplicationController
|
||||
before_action :check_for_xml
|
||||
|
||||
# Receives public messages
|
||||
#
|
||||
# POST /receive/public
|
||||
def public
|
||||
legacy = request.content_type != "application/magic-envelope+xml"
|
||||
|
||||
data = data_for_public_message(legacy)
|
||||
data = request.body.read
|
||||
logger.debug data
|
||||
|
||||
DiasporaFederation.callbacks.trigger(:queue_public_receive, data, legacy)
|
||||
DiasporaFederation.callbacks.trigger(:queue_public_receive, data)
|
||||
|
||||
head :accepted
|
||||
end
|
||||
|
|
@ -25,43 +21,12 @@ module DiasporaFederation
|
|||
#
|
||||
# POST /receive/users/:guid
|
||||
def private
|
||||
legacy = request.content_type != "application/json"
|
||||
|
||||
data = data_for_private_message(legacy)
|
||||
data = request.body.read
|
||||
logger.debug data
|
||||
|
||||
success = DiasporaFederation.callbacks.trigger(:queue_private_receive, params[:guid], data, legacy)
|
||||
success = DiasporaFederation.callbacks.trigger(:queue_private_receive, params[:guid], data)
|
||||
|
||||
head success ? :accepted : :not_found
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Checks the xml parameter for legacy salmon slaps
|
||||
# @deprecated
|
||||
def check_for_xml
|
||||
legacy_request = request.content_type.nil? || request.content_type == "application/x-www-form-urlencoded"
|
||||
head :unprocessable_entity 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
|
||||
|
|
|
|||
|
|
@ -184,13 +184,11 @@ module DiasporaFederation
|
|||
# queue_public_receive
|
||||
# Queue a public salmon xml to process in background
|
||||
# @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] 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
|
||||
#
|
||||
# receive_entity
|
||||
|
|
|
|||
|
|
@ -8,14 +8,9 @@ module DiasporaFederation
|
|||
|
||||
# Receive a public message
|
||||
# @param [String] data message to receive
|
||||
# @param [Boolean] legacy use old slap parser
|
||||
def self.receive_public(data, legacy=false)
|
||||
magic_env = if legacy
|
||||
Salmon::Slap.from_xml(data)
|
||||
else
|
||||
magic_env_xml = Nokogiri::XML(data).root
|
||||
Salmon::MagicEnvelope.unenvelop(magic_env_xml)
|
||||
end
|
||||
def self.receive_public(data)
|
||||
magic_env_xml = Nokogiri::XML(data).root
|
||||
magic_env = Salmon::MagicEnvelope.unenvelop(magic_env_xml)
|
||||
Public.new(magic_env).receive
|
||||
rescue => e # rubocop:disable Style/RescueStandardError
|
||||
logger.error "failed to receive public message: #{e.class}: #{e.message}"
|
||||
|
|
@ -28,16 +23,11 @@ module DiasporaFederation
|
|||
# @param [OpenSSL::PKey::RSA] recipient_private_key recipient private key to decrypt the message
|
||||
# @param [Object] recipient_id the identifier to persist the entity for the correct user,
|
||||
# see +receive_entity+ callback
|
||||
# @param [Boolean] legacy use old slap parser
|
||||
def self.receive_private(data, recipient_private_key, recipient_id, legacy=false)
|
||||
def self.receive_private(data, recipient_private_key, recipient_id)
|
||||
raise ArgumentError, "no recipient key provided" unless recipient_private_key.instance_of?(OpenSSL::PKey::RSA)
|
||||
|
||||
magic_env = if legacy
|
||||
Salmon::EncryptedSlap.from_xml(data, recipient_private_key)
|
||||
else
|
||||
magic_env_xml = Salmon::EncryptedMagicEnvelope.decrypt(data, recipient_private_key)
|
||||
Salmon::MagicEnvelope.unenvelop(magic_env_xml)
|
||||
end
|
||||
magic_env_xml = Salmon::EncryptedMagicEnvelope.decrypt(data, recipient_private_key)
|
||||
magic_env = Salmon::MagicEnvelope.unenvelop(magic_env_xml)
|
||||
Private.new(magic_env, recipient_id).receive
|
||||
rescue => e # rubocop:disable Style/RescueStandardError
|
||||
logger.error "failed to receive private message for #{recipient_id}: #{e.class}: #{e.message}"
|
||||
|
|
|
|||
|
|
@ -16,5 +16,3 @@ require "diaspora_federation/salmon/exceptions"
|
|||
require "diaspora_federation/salmon/xml_payload"
|
||||
require "diaspora_federation/salmon/magic_envelope"
|
||||
require "diaspora_federation/salmon/encrypted_magic_envelope"
|
||||
require "diaspora_federation/salmon/slap"
|
||||
require "diaspora_federation/salmon/encrypted_slap"
|
||||
|
|
|
|||
|
|
@ -1,113 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require "json"
|
||||
|
||||
module DiasporaFederation
|
||||
module Salmon
|
||||
# +EncryptedSlap+ provides class methods for generating and parsing encrypted
|
||||
# Slaps. (In principle the same as {Slap}, but with encryption.)
|
||||
#
|
||||
# The basic encryption mechanism used here is based on the knowledge that
|
||||
# asymmetrical encryption is slow and symmetrical encryption is fast. Keeping in
|
||||
# mind that a message we want to de-/encrypt may greatly vary in length,
|
||||
# performance considerations must play a part of this scheme.
|
||||
#
|
||||
# A diaspora*-flavored encrypted magic-enveloped XML message looks like the following:
|
||||
#
|
||||
# <?xml version="1.0" encoding="UTF-8"?>
|
||||
# <diaspora xmlns="https://joindiaspora.com/protocol" xmlns:me="http://salmon-protocol.org/ns/magic-env">
|
||||
# <encrypted_header>{encrypted_header}</encrypted_header>
|
||||
# {magic_envelope with encrypted data}
|
||||
# </diaspora>
|
||||
#
|
||||
# The encrypted header is encoded in JSON like this (when in plain text):
|
||||
#
|
||||
# {
|
||||
# "aes_key" => "...",
|
||||
# "ciphertext" => "..."
|
||||
# }
|
||||
#
|
||||
# +aes_key+ is encrypted using the recipients public key, and contains the AES
|
||||
# +key+ and +iv+ used to encrypt the +ciphertext+ also encoded as JSON.
|
||||
#
|
||||
# {
|
||||
# "key" => "...",
|
||||
# "iv" => "..."
|
||||
# }
|
||||
#
|
||||
# +ciphertext+, once decrypted, contains the +author_id+, +aes_key+ and +iv+
|
||||
# relevant to the decryption of the data in the magic_envelope and the
|
||||
# verification of its signature.
|
||||
#
|
||||
# The decrypted cyphertext has this XML structure:
|
||||
#
|
||||
# <decrypted_header>
|
||||
# <iv>{iv}</iv>
|
||||
# <aes_key>{aes_key}</aes_key>
|
||||
# <author_id>{author_id}</author_id>
|
||||
# </decrypted_header>
|
||||
#
|
||||
# Finally, before decrypting the magic envelope payload, the signature should
|
||||
# first be verified.
|
||||
#
|
||||
# @example Parsing a Salmon Slap
|
||||
# recipient_privkey = however_you_retrieve_the_recipients_private_key()
|
||||
# entity = EncryptedSlap.from_xml(slap_xml, recipient_privkey).payload
|
||||
#
|
||||
# @deprecated
|
||||
class EncryptedSlap < Slap
|
||||
# Creates a {MagicEnvelope} instance from the data within the given XML string
|
||||
# containing an encrypted payload.
|
||||
#
|
||||
# @param [String] slap_xml encrypted Salmon xml
|
||||
# @param [OpenSSL::PKey::RSA] privkey recipient private_key for decryption
|
||||
#
|
||||
# @return [MagicEnvelope] magic envelope instance with payload and sender
|
||||
#
|
||||
# @raise [ArgumentError] if any of the arguments is of the wrong type
|
||||
# @raise [MissingHeader] if the +encrypted_header+ element is missing in the XML
|
||||
# @raise [MissingMagicEnvelope] if the +me:env+ element is missing in the XML
|
||||
def self.from_xml(slap_xml, privkey)
|
||||
raise ArgumentError unless slap_xml.instance_of?(String) && privkey.instance_of?(OpenSSL::PKey::RSA)
|
||||
|
||||
doc = Nokogiri::XML(slap_xml)
|
||||
|
||||
header_elem = doc.at_xpath("d:diaspora/d:encrypted_header", Slap::NS)
|
||||
raise MissingHeader if header_elem.nil?
|
||||
|
||||
header = header_data(header_elem.content, privkey)
|
||||
sender = header[:author_id]
|
||||
cipher_params = {key: Base64.decode64(header[:aes_key]), iv: Base64.decode64(header[:iv])}
|
||||
|
||||
MagicEnvelope.unenvelop(magic_env_from_doc(doc), sender, cipher_params)
|
||||
end
|
||||
|
||||
# Decrypts and reads the data from the encrypted XML header
|
||||
# @param [String] data base64 encoded, encrypted header data
|
||||
# @param [OpenSSL::PKey::RSA] privkey private key for decryption
|
||||
# @return [Hash] { iv: "...", aes_key: "...", author_id: "..." }
|
||||
private_class_method def self.header_data(data, privkey)
|
||||
header_elem = decrypt_header(data, privkey)
|
||||
raise InvalidHeader unless header_elem.name == "decrypted_header"
|
||||
|
||||
iv = header_elem.at_xpath("iv").content
|
||||
key = header_elem.at_xpath("aes_key").content
|
||||
author_id = header_elem.at_xpath("author_id").content
|
||||
|
||||
{iv: iv, aes_key: key, author_id: author_id}
|
||||
end
|
||||
|
||||
# Decrypts the xml header
|
||||
# @param [String] data base64 encoded, encrypted header data
|
||||
# @param [OpenSSL::PKey::RSA] privkey private key for decryption
|
||||
# @return [Nokogiri::XML::Element] header xml document
|
||||
private_class_method def self.decrypt_header(data, privkey)
|
||||
cipher_header = JSON.parse(Base64.decode64(data))
|
||||
key = JSON.parse(privkey.private_decrypt(Base64.decode64(cipher_header["aes_key"])))
|
||||
|
||||
xml = AES.decrypt(cipher_header["ciphertext"], Base64.decode64(key["key"]), Base64.decode64(key["iv"]))
|
||||
Nokogiri::XML(xml).root
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -2,26 +2,6 @@
|
|||
|
||||
module DiasporaFederation
|
||||
module Salmon
|
||||
# Raised, if the element containing the Magic Envelope is missing from the XML
|
||||
# @deprecated
|
||||
class MissingMagicEnvelope < RuntimeError
|
||||
end
|
||||
|
||||
# Raised, if the element containing the author is empty.
|
||||
# @deprecated
|
||||
class MissingAuthor < RuntimeError
|
||||
end
|
||||
|
||||
# Raised, if the element containing the header is missing from the XML
|
||||
# @deprecated
|
||||
class MissingHeader < RuntimeError
|
||||
end
|
||||
|
||||
# Raised, if the decrypted header has an unexpected XML structure
|
||||
# @deprecated
|
||||
class InvalidHeader < RuntimeError
|
||||
end
|
||||
|
||||
# Raised, if failed to fetch the public key of the sender of the received message
|
||||
class SenderKeyNotFound < RuntimeError
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,59 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module DiasporaFederation
|
||||
module Salmon
|
||||
# +Slap+ provides class methods to create unencrypted Slap XML from payload
|
||||
# data and parse incoming XML into a Slap instance.
|
||||
#
|
||||
# A diaspora* flavored magic-enveloped XML message looks like the following:
|
||||
#
|
||||
# <?xml version="1.0" encoding="UTF-8"?>
|
||||
# <diaspora xmlns="https://joindiaspora.com/protocol" xmlns:me="http://salmon-protocol.org/ns/magic-env">
|
||||
# <header>
|
||||
# <author_id>{author}</author_id>
|
||||
# </header>
|
||||
# {magic_envelope}
|
||||
# </diaspora>
|
||||
#
|
||||
# @example Parsing a Salmon Slap
|
||||
# entity = Slap.from_xml(slap_xml).payload
|
||||
#
|
||||
# @deprecated
|
||||
class Slap
|
||||
# Namespaces
|
||||
NS = {d: Salmon::XMLNS, me: MagicEnvelope::XMLNS}.freeze
|
||||
|
||||
# Parses an unencrypted Salmon XML string and returns a new instance of
|
||||
# {MagicEnvelope} with the XML data.
|
||||
#
|
||||
# @param [String] slap_xml Salmon XML
|
||||
#
|
||||
# @return [MagicEnvelope] magic envelope instance with payload and sender
|
||||
#
|
||||
# @raise [ArgumentError] if the argument is not a String
|
||||
# @raise [MissingAuthor] if the +author_id+ element is missing from the XML
|
||||
# @raise [MissingMagicEnvelope] if the +me:env+ element is missing from the XML
|
||||
def self.from_xml(slap_xml)
|
||||
raise ArgumentError unless slap_xml.instance_of?(String)
|
||||
|
||||
doc = Nokogiri::XML(slap_xml)
|
||||
|
||||
author_elem = doc.at_xpath("d:diaspora/d:header/d:author_id", Slap::NS)
|
||||
raise MissingAuthor if author_elem.nil? || author_elem.content.empty?
|
||||
|
||||
sender = author_elem.content
|
||||
|
||||
MagicEnvelope.unenvelop(magic_env_from_doc(doc), sender)
|
||||
end
|
||||
|
||||
# Parses the magic envelop from the document.
|
||||
#
|
||||
# @param [Nokogiri::XML::Document] doc Salmon XML Document
|
||||
private_class_method def self.magic_env_from_doc(doc)
|
||||
doc.at_xpath("d:diaspora/me:env", Slap::NS).tap do |env|
|
||||
raise MissingMagicEnvelope if env.nil?
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -5,32 +5,6 @@ module DiasporaFederation
|
|||
routes { DiasporaFederation::Engine.routes }
|
||||
|
||||
describe "POST #public" do
|
||||
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_callback(:queue_public_receive, "<diaspora/>", true)
|
||||
|
||||
post :public, params: {xml: "<diaspora/>"}
|
||||
expect(response.code).to eq("202")
|
||||
end
|
||||
|
||||
it "unescapes the xml before sending it to the callback" do
|
||||
expect_callback(:queue_public_receive, "<diaspora/>", true)
|
||||
|
||||
post :public, params: {xml: CGI.escape("<diaspora/>")}
|
||||
end
|
||||
end
|
||||
|
||||
context "magic envelope" do
|
||||
before do
|
||||
Mime::Type.register("application/magic-envelope+xml", :magic_envelope)
|
||||
|
|
@ -38,7 +12,7 @@ module DiasporaFederation
|
|||
end
|
||||
|
||||
it "returns a 202 if queued correctly" do
|
||||
expect_callback(:queue_public_receive, "<me:env/>", false)
|
||||
expect_callback(:queue_public_receive, "<me:env/>")
|
||||
|
||||
post :public, body: +"<me:env/>"
|
||||
expect(response.code).to eq("202")
|
||||
|
|
@ -47,39 +21,6 @@ module DiasporaFederation
|
|||
end
|
||||
|
||||
describe "POST #private" do
|
||||
context "legacy salmon slap" do
|
||||
it "return a 404 if not queued successfully (unknown user guid)" do
|
||||
expect_callback(:queue_private_receive, "any-guid", "<diaspora/>", true).and_return(false)
|
||||
|
||||
post :private, params: {guid: "any-guid", xml: "<diaspora/>"}
|
||||
expect(response.code).to eq("404")
|
||||
end
|
||||
|
||||
it "returns a 422 if no xml is passed" do
|
||||
post :private, params: {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, params: {guid: "any-guid"}
|
||||
expect(response.code).to eq("422")
|
||||
end
|
||||
|
||||
it "returns a 202 if the callback returned true" do
|
||||
expect_callback(:queue_private_receive, "any-guid", "<diaspora/>", true).and_return(true)
|
||||
|
||||
post :private, params: {guid: "any-guid", xml: "<diaspora/>"}
|
||||
expect(response.code).to eq("202")
|
||||
end
|
||||
|
||||
it "unescapes the xml before sending it to the callback" do
|
||||
expect_callback(:queue_private_receive, "any-guid", "<diaspora/>", true).and_return(true)
|
||||
|
||||
post :private, params: {guid: "any-guid", xml: CGI.escape("<diaspora/>")}
|
||||
end
|
||||
end
|
||||
|
||||
context "encrypted magic envelope" do
|
||||
before do
|
||||
@request.env["CONTENT_TYPE"] = "application/json"
|
||||
|
|
@ -87,7 +28,7 @@ module DiasporaFederation
|
|||
|
||||
it "return a 404 if not queued successfully (unknown user guid)" do
|
||||
expect_callback(
|
||||
:queue_private_receive, "any-guid", "{\"aes_key\": \"key\", \"encrypted_magic_envelope\": \"env\"}", false
|
||||
:queue_private_receive, "any-guid", "{\"aes_key\": \"key\", \"encrypted_magic_envelope\": \"env\"}"
|
||||
).and_return(false)
|
||||
|
||||
post :private,
|
||||
|
|
@ -98,7 +39,7 @@ module DiasporaFederation
|
|||
|
||||
it "returns a 202 if the callback returned true" do
|
||||
expect_callback(
|
||||
:queue_private_receive, "any-guid", "{\"aes_key\": \"key\", \"encrypted_magic_envelope\": \"env\"}", false
|
||||
:queue_private_receive, "any-guid", "{\"aes_key\": \"key\", \"encrypted_magic_envelope\": \"env\"}"
|
||||
).and_return(true)
|
||||
|
||||
post :private,
|
||||
|
|
|
|||
|
|
@ -23,21 +23,6 @@ module DiasporaFederation
|
|||
described_class.receive_public(data)
|
||||
end
|
||||
|
||||
it "parses the entity with legacy slap receiver" do
|
||||
expect_callback(:fetch_public_key, post.author).and_return(sender_key)
|
||||
|
||||
data = generate_legacy_salmon_slap(post, post.author, sender_key)
|
||||
|
||||
expect_callback(:receive_entity, kind_of(Entities::StatusMessage), post.author, nil) do |_, entity|
|
||||
expect(entity.guid).to eq(post.guid)
|
||||
expect(entity.author).to eq(post.author)
|
||||
expect(entity.text).to eq(post.text)
|
||||
expect(entity.public).to eq("true")
|
||||
end
|
||||
|
||||
described_class.receive_public(data, true)
|
||||
end
|
||||
|
||||
it "redirects exceptions from the receiver" do
|
||||
expect {
|
||||
described_class.receive_public("<xml/>")
|
||||
|
|
@ -64,21 +49,6 @@ module DiasporaFederation
|
|||
described_class.receive_private(data, recipient_key, 1234)
|
||||
end
|
||||
|
||||
it "parses the entity with legacy slap receiver" do
|
||||
expect_callback(:fetch_public_key, post.author).and_return(sender_key)
|
||||
|
||||
data = generate_legacy_encrypted_salmon_slap(post, post.author, sender_key, recipient_key)
|
||||
|
||||
expect_callback(:receive_entity, kind_of(Entities::StatusMessage), post.author, 1234) do |_, entity|
|
||||
expect(entity.guid).to eq(post.guid)
|
||||
expect(entity.author).to eq(post.author)
|
||||
expect(entity.text).to eq(post.text)
|
||||
expect(entity.public).to eq("false")
|
||||
end
|
||||
|
||||
described_class.receive_private(data, recipient_key, 1234, true)
|
||||
end
|
||||
|
||||
it "raises when recipient private key is not available" do
|
||||
magic_env = Salmon::MagicEnvelope.new(post, post.author).envelop(sender_key)
|
||||
data = Salmon::EncryptedMagicEnvelope.encrypt(magic_env, recipient_key.public_key)
|
||||
|
|
|
|||
|
|
@ -1,59 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module DiasporaFederation
|
||||
describe Salmon::EncryptedSlap do
|
||||
let(:sender) { "user_test@diaspora.example.tld" }
|
||||
let(:privkey) { OpenSSL::PKey::RSA.generate(512) } # use small key for speedy specs
|
||||
let(:recipient_key) { OpenSSL::PKey::RSA.generate(1024) } # use small key for speedy specs
|
||||
let(:payload) { Entities::TestEntity.new(test: "qwertzuiop") }
|
||||
let(:slap_xml) { generate_legacy_encrypted_salmon_slap(payload, sender, privkey, recipient_key.public_key) }
|
||||
|
||||
describe ".from_xml" do
|
||||
context "sanity" do
|
||||
it "accepts correct params" do
|
||||
expect_callback(:fetch_public_key, sender).and_return(privkey.public_key)
|
||||
|
||||
expect {
|
||||
Salmon::EncryptedSlap.from_xml(slap_xml, recipient_key)
|
||||
}.not_to raise_error
|
||||
end
|
||||
|
||||
it "raises an error when the params have a wrong type" do
|
||||
[1234, false, :symbol, payload, privkey].each do |val|
|
||||
expect {
|
||||
Salmon::EncryptedSlap.from_xml(val, val)
|
||||
}.to raise_error ArgumentError
|
||||
end
|
||||
end
|
||||
|
||||
it "verifies the existence of 'encrypted_header'" do
|
||||
faulty_xml = <<~XML
|
||||
<diaspora xmlns="https://joindiaspora.com/protocol" xmlns:me="http://salmon-protocol.org/ns/magic-env">
|
||||
</diaspora>
|
||||
XML
|
||||
expect {
|
||||
Salmon::EncryptedSlap.from_xml(faulty_xml, recipient_key)
|
||||
}.to raise_error Salmon::MissingHeader
|
||||
end
|
||||
|
||||
it "verifies the existence of a magic envelope" do
|
||||
faulty_xml = <<~XML
|
||||
<diaspora xmlns="https://joindiaspora.com/protocol" xmlns:me="http://salmon-protocol.org/ns/magic-env">
|
||||
<encrypted_header/>
|
||||
</diaspora>
|
||||
XML
|
||||
expect(Salmon::EncryptedSlap).to receive(:header_data).and_return(aes_key: "", iv: "", author_id: "")
|
||||
expect {
|
||||
Salmon::EncryptedSlap.from_xml(faulty_xml, recipient_key)
|
||||
}.to raise_error Salmon::MissingMagicEnvelope
|
||||
end
|
||||
end
|
||||
|
||||
context "generated instance" do
|
||||
it_behaves_like "a MagicEnvelope instance" do
|
||||
subject { Salmon::EncryptedSlap.from_xml(slap_xml, recipient_key) }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -1,60 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module DiasporaFederation
|
||||
describe Salmon::Slap do
|
||||
let(:sender) { "test_user@pod.somedomain.tld" }
|
||||
let(:privkey) { OpenSSL::PKey::RSA.generate(512) } # use small key for speedy specs
|
||||
let(:payload) { Entities::TestEntity.new(test: "qwertzuiop") }
|
||||
let(:slap_xml) { generate_legacy_salmon_slap(payload, sender, privkey) }
|
||||
|
||||
describe ".from_xml" do
|
||||
context "sanity" do
|
||||
it "accepts salmon xml as param" do
|
||||
expect_callback(:fetch_public_key, sender).and_return(privkey.public_key)
|
||||
|
||||
expect {
|
||||
Salmon::Slap.from_xml(slap_xml)
|
||||
}.not_to raise_error
|
||||
end
|
||||
|
||||
it "raises an error when the param has a wrong type" do
|
||||
[1234, false, :symbol, payload, privkey].each do |val|
|
||||
expect {
|
||||
Salmon::Slap.from_xml(val)
|
||||
}.to raise_error ArgumentError
|
||||
end
|
||||
end
|
||||
|
||||
it "verifies the existence of an author_id" do
|
||||
faulty_xml = <<~XML
|
||||
<diaspora xmlns="https://joindiaspora.com/protocol" xmlns:me="http://salmon-protocol.org/ns/magic-env">
|
||||
<header/>
|
||||
</diaspora>
|
||||
XML
|
||||
expect {
|
||||
Salmon::Slap.from_xml(faulty_xml)
|
||||
}.to raise_error Salmon::MissingAuthor
|
||||
end
|
||||
|
||||
it "verifies the existence of a magic envelope" do
|
||||
faulty_xml = <<~XML
|
||||
<diaspora xmlns="https://joindiaspora.com/protocol" xmlns:me="http://salmon-protocol.org/ns/magic-env">
|
||||
<header>
|
||||
<author_id>#{sender}</author_id>
|
||||
</header>
|
||||
</diaspora>
|
||||
XML
|
||||
expect {
|
||||
Salmon::Slap.from_xml(faulty_xml)
|
||||
}.to raise_error Salmon::MissingMagicEnvelope
|
||||
end
|
||||
end
|
||||
|
||||
context "generated instance" do
|
||||
it_behaves_like "a MagicEnvelope instance" do
|
||||
subject { Salmon::Slap.from_xml(slap_xml) }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
Loading…
Reference in a new issue