Commit 3b8bbde

mo <mo@mokhan.ca>
2017-12-13 16:51:21
extract Assertion class.
1 parent 27f4fb7
lib/saml/kit/assertion.rb
@@ -0,0 +1,73 @@
+module Saml
+  module Kit
+    class Assertion
+      def initialize(xml)
+        @xml = xml
+        @xml_hash = Hash.from_xml(xml) || {}
+      end
+
+      def name_id
+        assertion.fetch('Subject', {}).fetch('NameID', nil)
+      end
+
+      def signed?
+        assertion.fetch('Signature', nil).present?
+      end
+
+      def attributes
+        @attributes ||=
+          begin
+            attrs = assertion.fetch('AttributeStatement', {}).fetch('Attribute', [])
+            items = if attrs.is_a? Hash
+                      [[attrs["Name"], attrs["AttributeValue"]]]
+                    else
+                      attrs.map { |item| [item['Name'], item['AttributeValue']] }
+                    end
+            Hash[items].with_indifferent_access
+          end
+      end
+
+      def started_at
+        parse_date(assertion.fetch('Conditions', {}).fetch('NotBefore', nil))
+      end
+
+      def expired_at
+        parse_date(assertion.fetch('Conditions', {}).fetch('NotOnOrAfter', nil))
+      end
+
+      def certificate
+        assertion.fetch('Signature', {}).fetch('KeyInfo', {}).fetch('X509Data', {}).fetch('X509Certificate', nil)
+      end
+
+      def audiences
+        Array(assertion['Conditions']['AudienceRestriction']['Audience'])
+      rescue => error
+        Saml::Kit.logger.error(error)
+        []
+      end
+
+      private
+
+      def encrypted?
+        @xml_hash['Response']['EncryptedAssertion'].present?
+      end
+
+      def assertion
+        if encrypted?
+          decrypted = XmlDecryption.new.decrypt(@xml_hash['Response']['EncryptedAssertion'])
+          Saml::Kit.logger.debug(decrypted)
+          Hash.from_xml(decrypted)['Assertion']
+        else
+          @xml_hash['Response'].fetch('Assertion', {})
+        end
+      end
+
+      def parse_date(value)
+        DateTime.parse(value)
+      rescue => error
+        Saml::Kit.logger.error(error)
+        Time.at(0).to_datetime
+      end
+    end
+  end
+end
lib/saml/kit/response.rb
@@ -12,7 +12,7 @@ module Saml
       end
 
       def name_id
-        assertion.fetch('Subject', {}).fetch('NameID', nil)
+        assertion.name_id
       end
 
       def [](key)
@@ -20,24 +20,15 @@ module Saml
       end
 
       def attributes
-        @attributes ||=
-          begin
-            attrs = assertion.fetch('AttributeStatement', {}).fetch('Attribute', [])
-            items = if attrs.is_a? Hash
-              [[attrs["Name"], attrs["AttributeValue"]]]
-            else
-              attrs.map { |item| [item['Name'], item['AttributeValue']] }
-            end
-            Hash[items].with_indifferent_access
-          end
+        assertion.attributes
       end
 
       def started_at
-        parse_date(assertion.fetch('Conditions', {}).fetch('NotBefore', nil))
+        assertion.started_at
       end
 
       def expired_at
-        parse_date(assertion.fetch('Conditions', {}).fetch('NotOnOrAfter', nil))
+        assertion.expired_at
       end
 
       def expired?
@@ -48,29 +39,16 @@ module Saml
         Time.current > started_at && !expired?
       end
 
-      def encrypted?
-        to_h[name]['EncryptedAssertion'].present?
-      end
-
       def assertion
-        @assertion =
-          begin
-            if encrypted?
-              decrypted = XmlDecryption.new.decrypt(to_h.fetch(name, {}).fetch('EncryptedAssertion', {}))
-              Saml::Kit.logger.debug(decrypted)
-              Hash.from_xml(decrypted)['Assertion']
-            else
-              to_h.fetch(name, {}).fetch('Assertion', {})
-            end
-          end
+        @assertion = Saml::Kit::Assertion.new(content)
       end
 
       def signed?
-        super || assertion.fetch('Signature', nil).present?
+        super || assertion.signed?
       end
 
       def certificate
-        super || assertion.fetch('Signature', {}).fetch('KeyInfo', {}).fetch('X509Data', {}).fetch('X509Certificate', nil)
+        super || assertion.certificate
       end
 
       private
@@ -91,17 +69,7 @@ module Saml
       end
 
       def audiences
-        Array(assertion['Conditions']['AudienceRestriction']['Audience'])
-      rescue => error
-        Saml::Kit.logger.error(error)
-        []
-      end
-
-      def parse_date(value)
-        DateTime.parse(value)
-      rescue => error
-        Saml::Kit.logger.error(error)
-        Time.at(0).to_datetime
+        assertion.audiences
       end
 
       Builder = ActiveSupport::Deprecation::DeprecatedConstantProxy.new('Saml::Kit::Response::Builder', 'Saml::Kit::Builders::Response')
lib/saml/kit/xml.rb
@@ -7,6 +7,7 @@ module Saml
         "ds": Namespaces::XMLDSIG,
         "md": Namespaces::METADATA,
         "saml": Namespaces::ASSERTION,
+        "pro": Namespaces::PROTOCOL,
       }.freeze
 
       attr_reader :raw_xml, :document
lib/saml/kit.rb
@@ -26,6 +26,7 @@ require "saml/kit/requestable"
 require "saml/kit/trustable"
 require "saml/kit/document"
 
+require "saml/kit/assertion"
 require "saml/kit/authentication_request"
 require "saml/kit/bindings"
 require "saml/kit/certificate"
spec/saml/response_spec.rb
@@ -396,8 +396,10 @@ XML
 XML
 
       subject = described_class.new(xml)
-      expect(subject).to be_encrypted
-      expect(subject.attributes).to be_present
+      expect(subject.attributes).to match_array([
+        ["created_at", "2017-11-23T04:33:58Z"],
+        ["email", "sidney_bayer@nienowemmerich.com"]
+      ])
     end
   end