Commit 397009c

mo <mo.khan@gmail.com>
2017-11-17 22:27:12
inline serialize/deserialize methods.
1 parent 4784343
lib/saml/kit/authentication_request.rb
@@ -74,10 +74,6 @@ module Saml
         to_xml
       end
 
-      def serialize(compress: false)
-        Saml::Kit::Content.serialize(to_xml, compress: compress)
-      end
-
       def response_for(user)
         Response::Builder.new(user, self).build
       end
lib/saml/kit/binding.rb
@@ -39,11 +39,11 @@ module Saml
           document
         elsif post?
           if params['SAMLRequest'].present?
-            Saml::Kit::Request.deserialize(params['SAMLRequest'])
+            deserialize_request(params['SAMLRequest'])
           elsif params['SAMLResponse'].present?
-            Saml::Kit::Response.deserialize(params['SAMLResponse'])
+            deserialize_response(params['SAMLResponse'])
           else
-          raise ArgumentError.new("Missing SAMLRequest or SAMLResponse")
+            raise ArgumentError.new("Missing SAMLRequest or SAMLResponse")
           end
         else
           raise ArgumentError.new("Unsupported binding")
@@ -79,9 +79,9 @@ module Saml
 
       def deserialize_document_from!(params)
         if params['SAMLRequest'].present?
-          Saml::Kit::Request.deserialize(CGI.unescape(params['SAMLRequest']))
+          deserialize_request(CGI.unescape(params['SAMLRequest']))
         elsif params['SAMLResponse'].present?
-          Saml::Kit::Response.deserialize(CGI.unescape(params['SAMLResponse']))
+          deserialize_response(CGI.unescape(params['SAMLResponse']))
         else
           raise ArgumentError.new("SAMLRequest or SAMLResponse parameter is required.")
         end
@@ -99,6 +99,34 @@ module Saml
           OpenSSL::Digest::SHA1.new
         end
       end
+
+      def deserialize_request(raw_request)
+        xml = Saml::Kit::Content.deserialize(raw_request)
+        hash = Hash.from_xml(xml)
+        if hash['AuthnRequest'].present?
+          AuthenticationRequest.new(xml)
+        else
+          LogoutRequest.new(xml)
+        end
+      rescue => error
+        Saml::Kit.logger.error(error)
+        Saml::Kit.logger.error(error.backtrace.join("\n"))
+        InvalidRequest.new(raw_request)
+      end
+
+      def deserialize_response(saml_response)
+        xml = Saml::Kit::Content.deserialize(saml_response)
+        hash = Hash.from_xml(xml)
+        if hash['Response'].present?
+          Response.new(xml)
+        else
+          LogoutResponse.new(xml)
+        end
+      rescue => error
+        Saml::Kit.logger.error(error)
+        Saml::Kit.logger.error(error.backtrace.join("\n"))
+        InvalidResponse.new(saml_response)
+      end
     end
   end
 end
lib/saml/kit/logout_request.rb
@@ -89,10 +89,6 @@ module Saml
         to_xml
       end
 
-      def serialize
-        Saml::Kit::Content.serialize(to_xml)
-      end
-
       def response_for(user)
         LogoutResponse::Builder.new(user, self).build
       end
lib/saml/kit/logout_response.rb
@@ -45,10 +45,6 @@ module Saml
         @xml_hash
       end
 
-      def serialize(compress: false)
-        Saml::Kit::Content.serialize(to_xml, compress: compress)
-      end
-
       def provider
         registry.metadata_for(issuer)
       end
lib/saml/kit/request.rb
@@ -1,19 +1,6 @@
 module Saml
   module Kit
     class Request
-      def self.deserialize(raw_request)
-        xml = Saml::Kit::Content.deserialize(raw_request)
-        hash = Hash.from_xml(xml)
-        if hash['AuthnRequest'].present?
-          AuthenticationRequest.new(xml)
-        else
-          LogoutRequest.new(xml)
-        end
-      rescue => error
-        Saml::Kit.logger.error(error)
-        Saml::Kit.logger.error(error.backtrace.join("\n"))
-        InvalidRequest.new(raw_request)
-      end
     end
   end
 end
lib/saml/kit/response.rb
@@ -76,10 +76,6 @@ module Saml
         @xml_hash
       end
 
-      def serialize(compress: false)
-        Saml::Kit::Content.serialize(to_xml, compress: compress)
-      end
-
       def certificate
         return unless signed?
         to_h.fetch(name, {}).fetch('Signature', {}).fetch('KeyInfo', {}).fetch('X509Data', {}).fetch('X509Certificate', nil)
@@ -120,22 +116,6 @@ module Saml
         registry.metadata_for(issuer)
       end
 
-      class << self
-        def deserialize(saml_response)
-          xml = Saml::Kit::Content.deserialize(saml_response)
-          hash = Hash.from_xml(xml)
-          if hash['Response'].present?
-            new(xml)
-          else
-            LogoutResponse.new(xml)
-          end
-        rescue => error
-          Saml::Kit.logger.error(error)
-          Saml::Kit.logger.error(error.backtrace.join("\n"))
-          InvalidResponse.new(saml_response)
-        end
-      end
-
       private
 
       def registry
spec/saml/authentication_request_spec.rb
@@ -176,18 +176,4 @@ RSpec.describe Saml::Kit::AuthenticationRequest do
       expect(subject.acs_url).to eql(acs_url)
     end
   end
-
-  describe "#serialize" do
-    subject { described_class::Builder.new.build }
-
-    it 'returns a compressed and base64 encoded document' do
-      expected_value = Base64.strict_encode64(Zlib::Deflate.deflate(subject.to_xml, 9)[2..-5])
-      expect(subject.serialize(compress: true)).to eql(expected_value)
-    end
-
-    it 'returns a base64 encoded document' do
-      expected_value = Base64.strict_encode64(subject.to_xml)
-      expect(subject.serialize).to eql(expected_value)
-    end
-  end
 end
spec/saml/binding_spec.rb
@@ -177,6 +177,16 @@ RSpec.describe Saml::Kit::Binding do
           subject.deserialize({})
         end.to raise_error(/Missing SAMLRequest or SAMLResponse/)
       end
+
+      [
+        'fZFPa4QwEMW/iuTumqymroMKC1IQ2lLa0kMvJXUjCjGxmbF/vn2je9le9jpvfm/mzZSoJjPDcaHBPunPRSNFP5OxCJtQscVbcApHBKsmjUAdPB/v72C/4zB7R65zhl0g1wmFqD2NzrKobSr2ngmlpS7yuJc8jbPikMfFjRDxh5SqF7w/5DJl0av2GJiKBYsAIi66tUjKUihxkceBEPJlnwLPgBdvLGpCjtEq2qiBaIYkMa5TZnBIIDnnCWpcTROrv1ldrqvD5uxrNfrZedqd9FeZXArl+VgPIVbbPDozdr/RrfOTouup18p4ivutFeY1DZK2xJL6POD/A+o/&RelayState=%7B"redirect_to":"/"%7D&SigAlg=http://www.w3.org/2001/04/xmlenc%23sha256&Signature=dcM/kfdrERjZ+Q+WpzBTvk3RLVeEM5qGEM5ONJ/r4fxvEtMQyk6nT7PNZGsox0XYv+myi2yPBsqYUNC2kVii/uc34dn9l7Voyu6dGsNQPNTOpEwRHHILdjJUqhxEDBpd49vVbgdlF++pQZ7l74bUw8FdIbJ7W4EcOBQ1ffNtWTQNLv9n/D/jYKeGtJtaf61x8zDOlCyBwNi861bKXNFScyOwEFNcpVsgBIYhqZqKUWQVAcgYiGH5r16mtWFcT8NdnIvtICrN5VBpepK/ARnawhM6KhacQYllMpnXgbtsJcyQrRf1s9hqrkos1mRwgKLawZ5NjmF66dw3mKKs22b9NQ==',
+        'fZFNb4MwDIb/CsqdJtBSWguQKqFJSNs0bdMOvUxZCCISJCw2+/j3C/TSXXrxwfbz2q9doByHCU4z9fZZf84aKfoZB4uwFko2ewtOokGwctQIpODl9HAP6UbA5B055QZ2hdwmJKL2ZJxlUVOX7H1/VEe12+s4y8RHvNuGcNRdHh8OoutUkudt17LoTXsMTMmCRAARZ91YJGkppESSx0kSJ9lruoUkBZGdWVQHH8ZKWqmeaALOB6fk0DskyIQQHDUuotzqb1YVy+qwKvtKGj85T5tWfxX8ulBcjvUYbDX1kxuM+o3unB8l3Xa9ZEwbd2srTIsbJG2J8eoy4P8Dqj8=&RelayState=%7B"redirect_to":"/"%7D&SigAlg=http://www.w3.org/2001/04/xmlenc%23sha256&Signature=sI50KhkFGLxFBnuWCZ4gJ+FrG5mY4f5f4afjdRc0lFHdgzMlJt9xzqh39ufHAkhpi2+OdWjg87pwpPgfz3das4QJMMenb/o5vNnFGqt2OMiyjoQbVc7b5xSA78FU+OlwqK3XgGdqo3KrRL+AJuagm4D3VeSbZhZ/0zPm1RG0/spCuxx+BbFwTW0BI+VU9+1zkmdV1CJt8kYtmNdvYavgD7rcUX2MWgaRVR+t/nNND5Wmdoxxfp/pzhkjrjt20+TpkDI9sKWlUSOZnATDFO/KlnKSvn/LrQ8wofqHViRksMhDIvVD9mNu7tJaQ6NB1yPUrmsOblPtAmRuBDBgChdHRA==',
+        'fZFPa4QwEMW/iuSejdFVy6DCghSEtpS29NDLko1ZFDSxmbF/vn2je9le9jpvfm/mzZSopnGGw0K9fTGfi0GKfqbRImxCxRZvwSkcEKyaDAJpeD08PkCyi2H2jpx2I7tCbhMK0XganGVR21TsGJ/yNM2V5jI/dXwvz4rfpUXCU53LRGdpoZOMRe/GY2AqFiwCiLiY1iIpS6EUy4JLyWX2lqQg9yDlB4uakGOwijaqJ5pBiNFpNfYOCbI4jgUaXE2FNd+sLtfVYXP2tRr87DztOvNVimuhvBzrKcRqm2c3Dvo3und+UnQ79VoZOn7eWmFe0yAZS0zUlwH/H1D/AQ==&RelayState=%7B"redirect_to":"/"%7D&SigAlg=http://www.w3.org/2001/04/xmlenc%23sha256&Signature=vNIzNWsCqdi2rs5HMRWSm+udc42K9sCm/epeV212sP4vYwot9K9xvoz8Z7jvY8zsY2BPdjZsEJPpHjPKb4+xB+riyc5fUP5wUEUSsQF5Q5FtoQx0jJbcNDadHoTdH1IEiQazTt7ED6sYmnY93lxqFtRkoUtov6XGXRT6ypNRGRFqn5T4JYZEROhdLRAOSCyoOjZ8kPcWKGP1Fo0+A25bwl1Yo3tqBTZsc522AaLhK/6f7uLftSUaTMA0lnmQqRXzZrfjVtDAHa5JSHLH2eh7vZavyvmqApshL1qHEihRN9VFx7DPjRspvp8pIn/8CH18ynVzzKPxIUOl3Kt4QNsVJA==',
+      ].each do |saml|
+        it do
+          expect(subject.deserialize('SAMLRequest' => saml)).to be_instance_of(Saml::Kit::AuthenticationRequest)
+        end
+      end
     end
 
     describe "Artifact binding" do
spec/saml/logout_response_spec.rb
@@ -23,23 +23,4 @@ RSpec.describe Saml::Kit::LogoutResponse do
       end
     end
   end
-
-  describe "#serialize" do
-    let(:user) { double(:user, name_id_for: SecureRandom.uuid, assertion_attributes_for: { }) }
-    let(:request) { double(id: SecureRandom.uuid, acs_url: acs_url, issuer: issuer, name_id_format: Saml::Kit::Namespaces::PERSISTENT, provider: nil) }
-    let(:acs_url) { FFaker::Internet.http_url }
-    let(:issuer) { FFaker::Internet.http_url }
-    let(:builder) { described_class::Builder.new(user, request) }
-    subject { builder.build }
-
-    it 'returns a compressed and base64 encoded document' do
-      expected_value = Base64.strict_encode64(Zlib::Deflate.deflate(subject.to_xml, 9)[2..-5])
-      expect(subject.serialize(compress: true)).to eql(expected_value)
-    end
-
-    it 'returns a base64 encoded document' do
-      expected_value = Base64.strict_encode64(subject.to_xml)
-      expect(subject.serialize).to eql(expected_value)
-    end
-  end
 end
spec/saml/request_spec.rb
@@ -1,52 +1,4 @@
 require 'spec_helper'
 
 RSpec.describe Saml::Kit::Request do
-  describe ".deserialize" do
-    subject { described_class }
-    let(:issuer) { FFaker::Internet.http_url }
-    let(:registry) { instance_double(Saml::Kit::DefaultRegistry) }
-    let(:service_provider_metadata) { instance_double(Saml::Kit::ServiceProviderMetadata) }
-
-    before :each do
-      allow(Saml::Kit.configuration).to receive(:registry).and_return(registry)
-      allow(registry).to receive(:metadata_for).and_return(service_provider_metadata)
-      allow(service_provider_metadata).to receive(:matches?).and_return(true)
-      allow(service_provider_metadata).to receive(:assertion_consumer_services).and_return([
-        { location: FFaker::Internet.http_url, binding: Saml::Kit::Namespaces::POST }
-      ])
-    end
-
-    it 'decodes the raw_request' do
-      builder = Saml::Kit::AuthenticationRequest::Builder.new
-      builder.issuer = issuer
-      raw_saml = builder.build.serialize
-
-      result = subject.deserialize(raw_saml)
-      expect(result.issuer).to eql(issuer)
-      expect(result).to be_valid
-    end
-
-    it 'returns an invalid request when the raw request is corrupted' do
-      expect(subject.deserialize("nonsense")).to be_invalid
-    end
-
-    it 'returns a logout request' do
-      user = double(:user, name_id_for: SecureRandom.uuid)
-      builder = Saml::Kit::LogoutRequest::Builder.new(user)
-
-      result = subject.deserialize(builder.build.serialize)
-      expect(result).to be_instance_of(Saml::Kit::LogoutRequest)
-      expect(result.name_id).to eql(user.name_id_for)
-    end
-
-    [
-      'fZFPa4QwEMW/iuTumqymroMKC1IQ2lLa0kMvJXUjCjGxmbF/vn2je9le9jpvfm/mzZSoJjPDcaHBPunPRSNFP5OxCJtQscVbcApHBKsmjUAdPB/v72C/4zB7R65zhl0g1wmFqD2NzrKobSr2ngmlpS7yuJc8jbPikMfFjRDxh5SqF7w/5DJl0av2GJiKBYsAIi66tUjKUihxkceBEPJlnwLPgBdvLGpCjtEq2qiBaIYkMa5TZnBIIDnnCWpcTROrv1ldrqvD5uxrNfrZedqd9FeZXArl+VgPIVbbPDozdr/RrfOTouup18p4ivutFeY1DZK2xJL6POD/A+o/&RelayState=%7B"redirect_to":"/"%7D&SigAlg=http://www.w3.org/2001/04/xmlenc%23sha256&Signature=dcM/kfdrERjZ+Q+WpzBTvk3RLVeEM5qGEM5ONJ/r4fxvEtMQyk6nT7PNZGsox0XYv+myi2yPBsqYUNC2kVii/uc34dn9l7Voyu6dGsNQPNTOpEwRHHILdjJUqhxEDBpd49vVbgdlF++pQZ7l74bUw8FdIbJ7W4EcOBQ1ffNtWTQNLv9n/D/jYKeGtJtaf61x8zDOlCyBwNi861bKXNFScyOwEFNcpVsgBIYhqZqKUWQVAcgYiGH5r16mtWFcT8NdnIvtICrN5VBpepK/ARnawhM6KhacQYllMpnXgbtsJcyQrRf1s9hqrkos1mRwgKLawZ5NjmF66dw3mKKs22b9NQ==',
-      'fZFNb4MwDIb/CsqdJtBSWguQKqFJSNs0bdMOvUxZCCISJCw2+/j3C/TSXXrxwfbz2q9doByHCU4z9fZZf84aKfoZB4uwFko2ewtOokGwctQIpODl9HAP6UbA5B055QZ2hdwmJKL2ZJxlUVOX7H1/VEe12+s4y8RHvNuGcNRdHh8OoutUkudt17LoTXsMTMmCRAARZ91YJGkppESSx0kSJ9lruoUkBZGdWVQHH8ZKWqmeaALOB6fk0DskyIQQHDUuotzqb1YVy+qwKvtKGj85T5tWfxX8ulBcjvUYbDX1kxuM+o3unB8l3Xa9ZEwbd2srTIsbJG2J8eoy4P8Dqj8=&RelayState=%7B"redirect_to":"/"%7D&SigAlg=http://www.w3.org/2001/04/xmlenc%23sha256&Signature=sI50KhkFGLxFBnuWCZ4gJ+FrG5mY4f5f4afjdRc0lFHdgzMlJt9xzqh39ufHAkhpi2+OdWjg87pwpPgfz3das4QJMMenb/o5vNnFGqt2OMiyjoQbVc7b5xSA78FU+OlwqK3XgGdqo3KrRL+AJuagm4D3VeSbZhZ/0zPm1RG0/spCuxx+BbFwTW0BI+VU9+1zkmdV1CJt8kYtmNdvYavgD7rcUX2MWgaRVR+t/nNND5Wmdoxxfp/pzhkjrjt20+TpkDI9sKWlUSOZnATDFO/KlnKSvn/LrQ8wofqHViRksMhDIvVD9mNu7tJaQ6NB1yPUrmsOblPtAmRuBDBgChdHRA==',
-      'fZFPa4QwEMW/iuSejdFVy6DCghSEtpS29NDLko1ZFDSxmbF/vn2je9le9jpvfm/mzZSopnGGw0K9fTGfi0GKfqbRImxCxRZvwSkcEKyaDAJpeD08PkCyi2H2jpx2I7tCbhMK0XganGVR21TsGJ/yNM2V5jI/dXwvz4rfpUXCU53LRGdpoZOMRe/GY2AqFiwCiLiY1iIpS6EUy4JLyWX2lqQg9yDlB4uakGOwijaqJ5pBiNFpNfYOCbI4jgUaXE2FNd+sLtfVYXP2tRr87DztOvNVimuhvBzrKcRqm2c3Dvo3und+UnQ79VoZOn7eWmFe0yAZS0zUlwH/H1D/AQ==&RelayState=%7B"redirect_to":"/"%7D&SigAlg=http://www.w3.org/2001/04/xmlenc%23sha256&Signature=vNIzNWsCqdi2rs5HMRWSm+udc42K9sCm/epeV212sP4vYwot9K9xvoz8Z7jvY8zsY2BPdjZsEJPpHjPKb4+xB+riyc5fUP5wUEUSsQF5Q5FtoQx0jJbcNDadHoTdH1IEiQazTt7ED6sYmnY93lxqFtRkoUtov6XGXRT6ypNRGRFqn5T4JYZEROhdLRAOSCyoOjZ8kPcWKGP1Fo0+A25bwl1Yo3tqBTZsc522AaLhK/6f7uLftSUaTMA0lnmQqRXzZrfjVtDAHa5JSHLH2eh7vZavyvmqApshL1qHEihRN9VFx7DPjRspvp8pIn/8CH18ynVzzKPxIUOl3Kt4QNsVJA==',
-    ].each do |saml|
-      it do
-        expect(subject.deserialize(saml)).to be_instance_of(Saml::Kit::AuthenticationRequest)
-      end
-    end
-  end
 end
spec/saml/response_spec.rb
@@ -75,30 +75,6 @@ RSpec.describe Saml::Kit::Response do
     end
   end
 
-  describe ".deserialize" do
-    subject { described_class }
-    let(:raw_response) { IO.read('spec/fixtures/encoded_response.txt') }
-
-    it 'decodes the response to the raw xml' do
-      result = Hash.from_xml(subject.deserialize(raw_response).to_xml)
-      expect(result['Response']['ID']).to eql('_75358cd9-f357-4b2d-999f-f53382ba8263')
-      expect(result['Response']['Version']).to eql('2.0')
-      expect(result['Response']['IssueInstant']).to eql("2017-10-22T23:36:44Z")
-      expect(result['Response']['Destination']).to eql('http://localhost:4000/session')
-      expect(result['Response']['Issuer']).to eql('proof.dev')
-      expect(result['Response']['Status']['StatusCode']['Value']).to eql('urn:oasis:names:tc:SAML:2.0:status:Success')
-      expect(result['Response']['Assertion']['ID']).to eql("_78cacf76-243e-4509-9ace-d1985353b3fe")
-      expect(result['Response']['Assertion']['IssueInstant']).to eql("2017-10-22T23:36:44Z")
-      expect(result['Response']['Assertion']['Issuer']).to eql("proof.dev")
-      expect(result['Response']['Assertion']['Subject']['NameID']).to eql("ea64c235-e18d-4b9a-8672-06ef84dabdec")
-      expect(result['Response']['Assertion']['Conditions']['NotBefore']).to eql("2017-10-22T23:36:39Z")
-      expect(result['Response']['Assertion']['Conditions']['NotOnOrAfter']).to eql("2017-10-23T02:36:44Z")
-      expect(result['Response']['Assertion']['Conditions']['AudienceRestriction']['Audience']).to eql('airport.dev')
-      expect(result['Response']['Assertion']['AttributeStatement']['Attribute'][0]['Name']).to eql('id')
-      expect(result['Response']['Assertion']['AttributeStatement']['Attribute'][0]['AttributeValue']).to eql("ea64c235-e18d-4b9a-8672-06ef84dabdec")
-    end
-  end
-
   describe "#valid?" do
     let(:request) { instance_double(Saml::Kit::AuthenticationRequest, id: "_#{SecureRandom.uuid}", issuer: FFaker::Internet.http_url, acs_url: FFaker::Internet.http_url, name_id_format: Saml::Kit::Namespaces::PERSISTENT, provider: nil) }
     let(:user) { double(:user, name_id_for: SecureRandom.uuid, assertion_attributes_for: { id: SecureRandom.uuid }) }
@@ -232,29 +208,4 @@ RSpec.describe Saml::Kit::Response do
       expect(subject.errors[:audience]).to be_present
     end
   end
-
-  describe "#serialize" do
-    let(:user) { double(:user, name_id_for: SecureRandom.uuid, assertion_attributes_for: { }) }
-    let(:request) { double(id: SecureRandom.uuid, acs_url: acs_url, issuer: issuer, name_id_format: Saml::Kit::Namespaces::PERSISTENT, provider: nil) }
-    let(:acs_url) { FFaker::Internet.http_url }
-    let(:issuer) { FFaker::Internet.http_url }
-
-    it 'returns a compressed and base64 encoded document' do
-      builder = described_class::Builder.new(user, request)
-      xml = builder.to_xml
-      subject = described_class.new(xml)
-
-      expected_value = Base64.strict_encode64(Zlib::Deflate.deflate(xml, 9)[2..-5])
-      expect(subject.serialize(compress: true)).to eql(expected_value)
-    end
-
-    it 'returns a base64 encoded document' do
-      builder = described_class::Builder.new(user, request)
-      xml = builder.to_xml
-      subject = described_class.new(xml)
-
-      expected_value = Base64.strict_encode64(xml)
-      expect(subject.serialize).to eql(expected_value)
-    end
-  end
 end