diff --git a/lib/akami/wsse.rb b/lib/akami/wsse.rb index 7212861..1a3f30c 100644 --- a/lib/akami/wsse.rb +++ b/lib/akami/wsse.rb @@ -91,23 +91,29 @@ def body_attributes # Returns the XML for a WSSE header. def to_xml + xml = hash + if signature? and signature.have_document? - Gyoku.xml wsse_signature.merge!(hash) - elsif username_token? && timestamp? - Gyoku.xml wsse_username_token.merge!(wsu_timestamp) { - |key, v1, v2| v1.merge!(v2) { - |key, v1, v2| v1.merge!(v2) - } - } + xml.merge!(wsse_signature) elsif username_token? - Gyoku.xml wsse_username_token.merge!(hash) - elsif timestamp? - Gyoku.xml wsu_timestamp.merge!(hash) - else - "" + xml.merge!(wsse_username_token) end - end + if timestamp? + xml.merge!(wsu_timestamp) do |key, v1, v2| + v1.merge!(v2) do |key, v1, v2| + if v1.is_a?(Hash) && v2.is_a?(Hash) + v1.merge!(v2) + end + end + end + unless xml['wsse:Security'][:order!].nil? + xml['wsse:Security'][:order!] << 'wsu:Timestamp' + end + end + + Gyoku.xml xml + end private # Returns a Hash containing wsse:UsernameToken details. diff --git a/spec/akami/wsse_spec.rb b/spec/akami/wsse_spec.rb index 2a6c1ec..6752988 100644 --- a/spec/akami/wsse_spec.rb +++ b/spec/akami/wsse_spec.rb @@ -29,8 +29,8 @@ ) end - it "contains the namespace for Base64 Encoding type" do - expect(Akami::WSSE::BASE64_URI).to eq( + it "contains the namespace for Base64 Encoding type" do + expect(Akami::WSSE::BASE64_URI).to eq( "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary" ) end @@ -243,7 +243,7 @@ end end - context "whith credentials and timestamp" do + context "with credentials and timestamp" do before do wsse.credentials "username", "password" wsse.timestamp = true @@ -261,6 +261,60 @@ expect(wsse.to_xml).to include("username", "password") end end + + context 'with signature' do + let(:fixtures_path) { + File.join(Bundler.root, 'spec', 'fixtures', 'akami', 'wsse', 'signature') + } + let(:xml) { fixture('akami/wsse/sample.xml') } + let(:cert_path) { File.join(fixtures_path, 'cert.pem') } + let(:signature) { + Akami::WSSE::Signature.new( + Akami::WSSE::Certs.new( + cert_file: cert_path, + private_key_file: cert_path, + private_key_password: 'password' + ) + ) + } + + before do + signature.document = xml + wsse.signature = signature + end + + it 'contains SignedInfo node' do + expect(wsse.to_xml).to include('SignedInfo') + end + it 'contains SignatureValue node' do + expect(wsse.to_xml).to include('SignatureValue') + end + it 'contains KeyInfo node' do + expect(wsse.to_xml).to include('KeyInfo') + end + + context 'with timestamp' do + before do + wsse.timestamp = true + end + it 'contains SignedInfo node' do + expect(wsse.to_xml).to include('SignedInfo') + end + it 'contains SignatureValue node' do + expect(wsse.to_xml).to include('SignatureValue') + end + it 'contains KeyInfo node' do + expect(wsse.to_xml).to include('KeyInfo') + end + it "contains a wsu:Created node" do + expect(wsse.to_xml).to include("") + end + it "contains a wsu:Expires node" do + expect(wsse.to_xml).to include("") + end + end + end + end end diff --git a/spec/fixtures/akami/wsse/sample.xml b/spec/fixtures/akami/wsse/sample.xml new file mode 100644 index 0000000..b574102 --- /dev/null +++ b/spec/fixtures/akami/wsse/sample.xml @@ -0,0 +1 @@ +Example