Commit 2dbf9bf

mo <mo.khan@gmail.com>
2017-11-04 20:57:58
validate presence of ID
1 parent 074d2ea
Changed files (3)
lib/saml/kit/response.rb
@@ -7,6 +7,7 @@ module Saml
 
       attr_reader :content, :name
       validates_presence_of :content
+      validates_presence_of :id
       validate :must_have_valid_signature
       validate :must_be_response
       validate :must_be_registered
@@ -15,16 +16,20 @@ module Saml
 
       def initialize(xml)
         @content = xml
-        @xml_hash = Hash.from_xml(xml)
+        @xml_hash = Hash.from_xml(xml) || {}
         @name = 'Response'
       end
 
+      def id
+        @xml_hash.dig(name, 'ID')
+      end
+
       def name_id
-        @xml_hash[name]['Assertion']['Subject']['NameID']
+        @xml_hash.dig(name, 'Assertion', 'Subject', 'NameID')
       end
 
       def issuer
-        @xml_hash[name]['Issuer']
+        @xml_hash.dig(name, 'Issuer')
       end
 
       def [](key)
@@ -32,17 +37,17 @@ module Saml
       end
 
       def attributes
-        @attributes ||= Hash[@xml_hash[name]['Assertion']['AttributeStatement']['Attribute'].map do |item|
+        @attributes ||= Hash[@xml_hash.dig(name, 'Assertion', 'AttributeStatement', 'Attribute').map do |item|
           [item['Name'].to_sym, item['AttributeValue']]
         end].with_indifferent_access
       end
 
       def acs_url
-        @xml_hash[name]['Destination']
+        @xml_hash.dig(name, 'Destination')
       end
 
       def version
-        @xml_hash[name]['Version']
+        @xml_hash.dig(name, 'Version')
       end
 
       def to_xml
@@ -54,10 +59,11 @@ module Saml
       end
 
       def certificate
-        @xml_hash[name]['Signature']['KeyInfo']['X509Data']['X509Certificate']
+        @xml_hash.dig(name, 'Signature', 'KeyInfo', 'X509Data', 'X509Certificate')
       end
 
       def fingerprint
+        return if certificate.blank?
         Fingerprint.new(certificate)
       end
 
@@ -179,7 +185,7 @@ module Saml
 
         def response_options
           {
-            ID: "_#{id}",
+            ID: id.present? ? "_#{id}" : nil,
             Version: version,
             IssueInstant: now.iso8601,
             Destination: request.acs_url,
lib/saml/kit/signature.rb
@@ -24,6 +24,8 @@ module Saml
       end
 
       def template(xml = ::Builder::XmlMarkup.new)
+        return if reference_id.blank?
+
         xml.Signature "xmlns" => Namespaces::XMLDSIG do
           xml.SignedInfo do
             xml.CanonicalizationMethod Algorithm: "http://www.w3.org/2001/10/xml-exc-c14n#"
@@ -47,8 +49,12 @@ module Saml
       end
 
       def finalize(xml)
-        document = Xmldsig::SignedDocument.new(xml.target!)
-        document.sign(configuration.signing_private_key)
+        if reference_id.present?
+          document = Xmldsig::SignedDocument.new(xml.target!)
+          document.sign(configuration.signing_private_key)
+        else
+          xml.target!
+        end
       end
     end
   end
spec/saml/response_spec.rb
@@ -201,5 +201,12 @@ RSpec.describe Saml::Kit::Response do
       builder.version = "1.1"
       expect(described_class.new(builder.to_xml)).to be_invalid
     end
+
+    it 'validates the id' do
+      allow(registry).to receive(:metadata_for).and_return(metadata)
+      allow(metadata).to receive(:matches?).and_return(true)
+      builder.id = nil
+      expect(described_class.new(builder.to_xml)).to_not be_valid
+    end
   end
 end