Remove additional MagicEnvelope wrapper with diaspora header
Related to #30
This commit is contained in:
parent
221d87d7fe
commit
1f99518706
7 changed files with 53 additions and 110 deletions
|
|
@ -115,7 +115,7 @@ module DiasporaFederation
|
|||
|
||||
magic_envelope = MagicEnvelope.new(entity)
|
||||
slap.cipher_params = magic_envelope.encrypt!
|
||||
slap.magic_envelope_xml = magic_envelope.envelop(privkey)
|
||||
slap.magic_envelope_xml = magic_envelope.envelop(privkey).root
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -153,7 +153,7 @@ module DiasporaFederation
|
|||
def build_xml
|
||||
Nokogiri::XML::Builder.new(encoding: "UTF-8") {|xml|
|
||||
yield xml
|
||||
}.doc.root
|
||||
}.doc
|
||||
end
|
||||
|
||||
# Creates the signature for all fields according to specification
|
||||
|
|
|
|||
|
|
@ -49,27 +49,6 @@ module DiasporaFederation
|
|||
MagicEnvelope.unenvelop(magic_env_from_doc(doc), sender)
|
||||
end
|
||||
|
||||
# Creates an unencrypted Salmon Slap and returns the XML string.
|
||||
#
|
||||
# @param [String] author_id diaspora* ID of the author
|
||||
# @param [OpenSSL::PKey::RSA] privkey sender private_key for signing the magic envelope
|
||||
# @param [Entity] entity payload
|
||||
# @return [String] Salmon XML string
|
||||
# @raise [ArgumentError] if any of the arguments is not the correct type
|
||||
def self.generate_xml(author_id, privkey, entity)
|
||||
raise ArgumentError unless author_id.instance_of?(String) &&
|
||||
privkey.instance_of?(OpenSSL::PKey::RSA) &&
|
||||
entity.is_a?(Entity)
|
||||
|
||||
build_xml do |xml|
|
||||
xml.header {
|
||||
xml.author_id(author_id)
|
||||
}
|
||||
|
||||
xml.parent << MagicEnvelope.new(entity, author_id).envelop(privkey)
|
||||
end
|
||||
end
|
||||
|
||||
# Builds the xml for the Salmon Slap.
|
||||
#
|
||||
# @yield [xml] Invokes the block with the
|
||||
|
|
|
|||
|
|
@ -24,7 +24,13 @@ module DiasporaFederation
|
|||
it "parses the entity with legacy slap receiver" do
|
||||
expect_callback(:fetch_public_key, post.author).and_return(sender_key)
|
||||
|
||||
data = DiasporaFederation::Salmon::Slap.generate_xml(post.author, sender_key, post)
|
||||
data = DiasporaFederation::Salmon::Slap.build_xml do |xml|
|
||||
xml.header {
|
||||
xml.author_id(post.author)
|
||||
}
|
||||
|
||||
xml.parent << Salmon::MagicEnvelope.new(post, post.author).envelop(sender_key).root
|
||||
end
|
||||
|
||||
expect_callback(:receive_entity, kind_of(Entities::StatusMessage), post.author, nil) do |_, entity|
|
||||
expect(entity.guid).to eq(post.guid)
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ module DiasporaFederation
|
|||
|
||||
xml = Salmon::AES.decrypt(json["encrypted_magic_envelope"], key["key"], key["iv"])
|
||||
|
||||
expect(Nokogiri::XML::Document.parse(xml).root.to_xml).to eq(magic_env.to_xml)
|
||||
expect(Nokogiri::XML::Document.parse(xml).to_xml).to eq(magic_env.to_xml)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -6,10 +6,10 @@ module DiasporaFederation
|
|||
let(:envelope) { Salmon::MagicEnvelope.new(payload, sender) }
|
||||
|
||||
def sig_subj(env)
|
||||
data = Base64.urlsafe_decode64(env.at_xpath("me:data").content)
|
||||
type = env.at_xpath("me:data")["type"]
|
||||
enc = env.at_xpath("me:encoding").content
|
||||
alg = env.at_xpath("me:alg").content
|
||||
data = Base64.urlsafe_decode64(env.at_xpath("me:env/me:data").content)
|
||||
type = env.at_xpath("me:env/me:data")["type"]
|
||||
enc = env.at_xpath("me:env/me:encoding").content
|
||||
alg = env.at_xpath("me:env/me:alg").content
|
||||
|
||||
[data, type, enc, alg].map {|i| Base64.urlsafe_encode64(i) }.join(".")
|
||||
end
|
||||
|
|
@ -41,12 +41,12 @@ module DiasporaFederation
|
|||
end
|
||||
end
|
||||
|
||||
it "should be an instance of Nokogiri::XML::Element" do
|
||||
expect(envelope.envelop(privkey)).to be_an_instance_of Nokogiri::XML::Element
|
||||
it "should be an instance of Nokogiri::XML::Document" do
|
||||
expect(envelope.envelop(privkey)).to be_an_instance_of Nokogiri::XML::Document
|
||||
end
|
||||
|
||||
it "returns a magic envelope of correct structure" do
|
||||
env_xml = envelope.envelop(privkey)
|
||||
env_xml = envelope.envelop(privkey).root
|
||||
expect(env_xml.name).to eq("env")
|
||||
|
||||
control = %w(data encoding alg sig)
|
||||
|
|
@ -59,13 +59,13 @@ module DiasporaFederation
|
|||
end
|
||||
|
||||
it "adds the sender to the signature" do
|
||||
key_id = envelope.envelop(privkey).at_xpath("me:sig")["key_id"]
|
||||
key_id = envelope.envelop(privkey).at_xpath("me:env/me:sig")["key_id"]
|
||||
|
||||
expect(Base64.urlsafe_decode64(key_id)).to eq(sender)
|
||||
end
|
||||
|
||||
it "adds the data_type" do
|
||||
data_type = envelope.envelop(privkey).at_xpath("me:data")["type"]
|
||||
data_type = envelope.envelop(privkey).at_xpath("me:env/me:data")["type"]
|
||||
|
||||
expect(data_type).to eq("application/xml")
|
||||
end
|
||||
|
|
@ -74,7 +74,7 @@ module DiasporaFederation
|
|||
env_xml = envelope.envelop(privkey)
|
||||
|
||||
subj = sig_subj(env_xml)
|
||||
sig = Base64.urlsafe_decode64(env_xml.at_xpath("me:sig").content)
|
||||
sig = Base64.urlsafe_decode64(env_xml.at_xpath("me:env/me:sig").content)
|
||||
|
||||
expect(privkey.public_key.verify(OpenSSL::Digest::SHA256.new, sig, subj)).to be_truthy
|
||||
end
|
||||
|
|
@ -103,6 +103,8 @@ module DiasporaFederation
|
|||
end
|
||||
|
||||
describe ".unenvelop" do
|
||||
let(:envelope_root) { envelope.envelop(privkey).root }
|
||||
|
||||
context "sanity" do
|
||||
before do
|
||||
allow(DiasporaFederation.callbacks).to receive(:trigger).with(
|
||||
|
|
@ -112,7 +114,7 @@ module DiasporaFederation
|
|||
|
||||
it "works with sane input" do
|
||||
expect {
|
||||
Salmon::MagicEnvelope.unenvelop(envelope.envelop(privkey), sender)
|
||||
Salmon::MagicEnvelope.unenvelop(envelope_root, sender)
|
||||
}.not_to raise_error
|
||||
end
|
||||
|
||||
|
|
@ -131,10 +133,9 @@ module DiasporaFederation
|
|||
end
|
||||
|
||||
it "raises if missing signature" do
|
||||
bad_env = envelope.envelop(privkey)
|
||||
bad_env.at_xpath("me:sig").remove
|
||||
envelope_root.at_xpath("me:sig").remove
|
||||
expect {
|
||||
Salmon::MagicEnvelope.unenvelop(bad_env, sender)
|
||||
Salmon::MagicEnvelope.unenvelop(envelope_root, sender)
|
||||
}.to raise_error Salmon::InvalidEnvelope, "missing me:sig"
|
||||
end
|
||||
|
||||
|
|
@ -145,70 +146,63 @@ module DiasporaFederation
|
|||
expect_callback(:fetch_public_key, other_sender).and_return(other_key)
|
||||
|
||||
expect {
|
||||
Salmon::MagicEnvelope.unenvelop(envelope.envelop(privkey), other_sender)
|
||||
Salmon::MagicEnvelope.unenvelop(envelope_root, other_sender)
|
||||
}.to raise_error Salmon::InvalidSignature
|
||||
end
|
||||
|
||||
it "raises if missing data" do
|
||||
bad_env = envelope.envelop(privkey)
|
||||
bad_env.at_xpath("me:data").remove
|
||||
envelope_root.at_xpath("me:data").remove
|
||||
expect {
|
||||
Salmon::MagicEnvelope.unenvelop(bad_env, sender)
|
||||
Salmon::MagicEnvelope.unenvelop(envelope_root, sender)
|
||||
}.to raise_error Salmon::InvalidEnvelope, "missing me:data"
|
||||
end
|
||||
|
||||
it "raises if missing encoding" do
|
||||
bad_env = envelope.envelop(privkey)
|
||||
bad_env.at_xpath("me:encoding").remove
|
||||
envelope_root.at_xpath("me:encoding").remove
|
||||
expect {
|
||||
Salmon::MagicEnvelope.unenvelop(bad_env, sender)
|
||||
Salmon::MagicEnvelope.unenvelop(envelope_root, sender)
|
||||
}.to raise_error Salmon::InvalidEncoding, "missing encoding"
|
||||
end
|
||||
|
||||
it "verifies the encoding" do
|
||||
bad_env = envelope.envelop(privkey)
|
||||
bad_env.at_xpath("me:encoding").content = "invalid_enc"
|
||||
envelope_root.at_xpath("me:encoding").content = "invalid_enc"
|
||||
expect {
|
||||
Salmon::MagicEnvelope.unenvelop(bad_env, sender)
|
||||
Salmon::MagicEnvelope.unenvelop(envelope_root, sender)
|
||||
}.to raise_error Salmon::InvalidEncoding, "invalid encoding: invalid_enc"
|
||||
end
|
||||
|
||||
it "raises if missing algorithm" do
|
||||
bad_env = envelope.envelop(privkey)
|
||||
bad_env.at_xpath("me:alg").remove
|
||||
envelope_root.at_xpath("me:alg").remove
|
||||
expect {
|
||||
Salmon::MagicEnvelope.unenvelop(bad_env, sender)
|
||||
Salmon::MagicEnvelope.unenvelop(envelope_root, sender)
|
||||
}.to raise_error Salmon::InvalidAlgorithm, "missing algorithm"
|
||||
end
|
||||
|
||||
it "verifies the algorithm" do
|
||||
bad_env = envelope.envelop(privkey)
|
||||
bad_env.at_xpath("me:alg").content = "invalid_alg"
|
||||
envelope_root.at_xpath("me:alg").content = "invalid_alg"
|
||||
expect {
|
||||
Salmon::MagicEnvelope.unenvelop(bad_env, sender)
|
||||
Salmon::MagicEnvelope.unenvelop(envelope_root, sender)
|
||||
}.to raise_error Salmon::InvalidAlgorithm, "invalid algorithm: invalid_alg"
|
||||
end
|
||||
|
||||
it "raises if missing data type" do
|
||||
bad_env = envelope.envelop(privkey)
|
||||
bad_env.at_xpath("me:data").attributes["type"].remove
|
||||
envelope_root.at_xpath("me:data").attributes["type"].remove
|
||||
expect {
|
||||
Salmon::MagicEnvelope.unenvelop(bad_env, sender)
|
||||
Salmon::MagicEnvelope.unenvelop(envelope_root, sender)
|
||||
}.to raise_error Salmon::InvalidDataType, "missing data type"
|
||||
end
|
||||
|
||||
it "verifies the data type" do
|
||||
bad_env = envelope.envelop(privkey)
|
||||
bad_env.at_xpath("me:data")["type"] = "invalid_type"
|
||||
envelope_root.at_xpath("me:data")["type"] = "invalid_type"
|
||||
expect {
|
||||
Salmon::MagicEnvelope.unenvelop(bad_env, sender)
|
||||
Salmon::MagicEnvelope.unenvelop(envelope_root, sender)
|
||||
}.to raise_error Salmon::InvalidDataType, "invalid data type: invalid_type"
|
||||
end
|
||||
end
|
||||
|
||||
context "generated instance" do
|
||||
it_behaves_like "a MagicEnvelope instance" do
|
||||
subject { Salmon::MagicEnvelope.unenvelop(envelope.envelop(privkey), sender) }
|
||||
subject { Salmon::MagicEnvelope.unenvelop(envelope_root, sender) }
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -217,7 +211,7 @@ module DiasporaFederation
|
|||
|
||||
env = Salmon::MagicEnvelope.new(payload)
|
||||
params = env.encrypt!
|
||||
env_xml = env.envelop(privkey)
|
||||
env_xml = env.envelop(privkey).root
|
||||
|
||||
magic_env = Salmon::MagicEnvelope.unenvelop(env_xml, sender, params)
|
||||
expect(magic_env.payload).to be_an_instance_of Entities::TestEntity
|
||||
|
|
@ -227,17 +221,15 @@ module DiasporaFederation
|
|||
context "use key_id from magic envelope" do
|
||||
context "generated instance" do
|
||||
it_behaves_like "a MagicEnvelope instance" do
|
||||
subject { Salmon::MagicEnvelope.unenvelop(envelope.envelop(privkey)) }
|
||||
subject { Salmon::MagicEnvelope.unenvelop(envelope_root) }
|
||||
end
|
||||
end
|
||||
|
||||
it "raises if the magic envelope has no key_id" do
|
||||
bad_env = envelope.envelop(privkey)
|
||||
|
||||
bad_env.at_xpath("me:sig").attributes["key_id"].remove
|
||||
envelope_root.at_xpath("me:sig").attributes["key_id"].remove
|
||||
|
||||
expect {
|
||||
Salmon::MagicEnvelope.unenvelop(bad_env)
|
||||
Salmon::MagicEnvelope.unenvelop(envelope_root)
|
||||
}.to raise_error Salmon::InvalidEnvelope
|
||||
end
|
||||
|
||||
|
|
@ -245,7 +237,7 @@ module DiasporaFederation
|
|||
expect_callback(:fetch_public_key, sender).and_return(nil)
|
||||
|
||||
expect {
|
||||
Salmon::MagicEnvelope.unenvelop(envelope.envelop(privkey))
|
||||
Salmon::MagicEnvelope.unenvelop(envelope_root)
|
||||
}.to raise_error Salmon::SenderKeyNotFound
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -3,49 +3,15 @@ module DiasporaFederation
|
|||
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) { Salmon::Slap.generate_xml(sender, privkey, payload) }
|
||||
let(:slap_xml) {
|
||||
Salmon::Slap.build_xml do |xml|
|
||||
xml.header {
|
||||
xml.author_id(sender)
|
||||
}
|
||||
|
||||
describe ".generate_xml" do
|
||||
context "sanity" do
|
||||
it "accepts correct params" do
|
||||
expect {
|
||||
Salmon::Slap.generate_xml(sender, privkey, payload)
|
||||
}.not_to raise_error
|
||||
end
|
||||
|
||||
it "raises an error when the sender is the wrong type" do
|
||||
[1234, true, :symbol, payload, privkey].each do |val|
|
||||
expect {
|
||||
Salmon::Slap.generate_xml(val, privkey, payload)
|
||||
}.to raise_error ArgumentError
|
||||
end
|
||||
end
|
||||
|
||||
it "raises an error when the privkey is the wrong type" do
|
||||
["asdf", 1234, true, :symbol, payload].each do |val|
|
||||
expect {
|
||||
Salmon::Slap.generate_xml(sender, val, payload)
|
||||
}.to raise_error ArgumentError
|
||||
end
|
||||
end
|
||||
|
||||
it "raises an error when the payload is the wrong type" do
|
||||
["asdf", 1234, true, :symbol, privkey].each do |val|
|
||||
expect {
|
||||
Salmon::Slap.generate_xml(sender, privkey, val)
|
||||
}.to raise_error ArgumentError
|
||||
end
|
||||
end
|
||||
xml.parent << Salmon::MagicEnvelope.new(payload, sender).envelop(privkey).root
|
||||
end
|
||||
|
||||
it "generates valid xml" do
|
||||
ns = {d: Salmon::XMLNS, me: Salmon::MagicEnvelope::XMLNS}
|
||||
doc = Nokogiri::XML::Document.parse(slap_xml)
|
||||
expect(doc.root.name).to eq("diaspora")
|
||||
expect(doc.at_xpath("d:diaspora/d:header/d:author_id", ns).content).to eq(sender)
|
||||
expect(doc.xpath("d:diaspora/me:env", ns)).to have(1).item
|
||||
end
|
||||
end
|
||||
}
|
||||
|
||||
describe ".from_xml" do
|
||||
context "sanity" do
|
||||
|
|
|
|||
Loading…
Reference in a new issue