Commit 1e4867c

mo <mo.khan@gmail.com>
2018-02-15 23:30:33
extract null assertion.
1 parent 981a3b4
Changed files (4)
lib/saml/kit/locales/en.yml
@@ -20,6 +20,8 @@ en:
         unregistered: "is unregistered."
       LogoutResponse:
         unregistered: "is unregistered."
+      NullAssertion:
+        invalid: "is missing."
       Response:
         invalid: "must contain Response."
         invalid_fingerprint: "does not match."
lib/saml/kit/assertion.rb
@@ -1,6 +1,25 @@
 module Saml
   module Kit
+    class NullAssertion
+      include ActiveModel::Validations
+      include Translatable
+      validate :invalid
+
+      def invalid
+        errors[:assertion].push(error_message(:invalid))
+      end
+
+      def name
+        "NullAssertion"
+      end
+    end
+
     class Assertion
+      NULL=NullAssertion.new
+      XPATH=[
+        '/samlp:Response/saml:Assertion',
+        '/samlp:Response/saml:EncryptedAssertion'
+      ].join('|')
       include ActiveModel::Validations
       include Translatable
 
@@ -92,13 +111,9 @@ module Saml
 
       def assertion
         @assertion ||=
-          if encrypted?
-            (hash_from(@node)['Response'] || {})['Assertion']
-          else
-            result = @xml_hash.fetch('Assertion', {})
+          begin
+            result = (hash_from(@node)['Response'] || {})['Assertion']
             return result if result.is_a?(Hash)
-
-            errors[:assertion] << error_message(:must_contain_single_assertion)
             {}
           end
       end
lib/saml/kit/response.rb
@@ -18,11 +18,12 @@ module Saml
       def assertion(private_keys = configuration.private_keys(use: :encryption))
         @assertion ||=
           begin
-            node = at_xpath([
-              '/samlp:Response/saml:Assertion',
-              '/samlp:Response/saml:EncryptedAssertion'
-            ].join('|'))
-            Saml::Kit::Assertion.new(node, configuration: @configuration, private_keys: private_keys)
+            node = at_xpath(Saml::Kit::Assertion::XPATH)
+            if node.nil?
+              Saml::Kit::Assertion::NULL
+            else
+              Saml::Kit::Assertion.new(node, configuration: @configuration, private_keys: private_keys)
+            end
           end
       end
 
@@ -36,17 +37,13 @@ module Saml
       end
 
       def must_contain_single_assertion
-        nodes = search('/samlp:Response/saml:Assertion')
-        if nodes.count > 1
+        if assertion_nodes.count > 1
           errors[:base] << error_message(:must_contain_single_assertion)
         end
       end
 
       def assertion_nodes
-        search([
-          '/samlp:Response/saml:Assertion',
-          '/samlp:Response/saml:EncryptedAssertion'
-        ].join('|'))
+        search(Saml::Kit::Assertion::XPATH)
       end
     end
   end
spec/saml/response_spec.rb
@@ -24,6 +24,7 @@ RSpec.describe Saml::Kit::Response do
       subject = described_class.new("")
       expect(subject).to be_invalid
       expect(subject.errors[:content]).to be_present
+      expect(subject.errors[:assertion]).to match_array(["is missing."])
     end
 
     it 'is invalid if the document has been tampered with' do