Commit 9e2bf2b

mo <mo@mokhan.ca>
2017-11-22 20:54:00
extract bindings namespace.
1 parent a24e15d
exe/saml-kit-decode-http-post
@@ -3,6 +3,6 @@ require 'saml/kit'
 
 saml = STDIN.read
 
-binding = Saml::Kit::HttpPostBinding.new(location: '')
+binding = Saml::Kit::Bindings::HttpPost.new(location: '')
 xml = binding.deserialize('SAMLRequest' => saml).to_xml
 puts Nokogiri::XML(xml).to_xml(indent: 2)
lib/saml/kit/bindings/binding.rb
@@ -1,38 +1,40 @@
 module Saml
   module Kit
-    class Binding
-      attr_reader :binding, :location
+    module Bindings
+      class Binding
+        attr_reader :binding, :location
 
-      def initialize(binding:, location:)
-        @binding = binding
-        @location = location
-      end
+        def initialize(binding:, location:)
+          @binding = binding
+          @location = location
+        end
 
-      def binding?(other)
-        binding == other
-      end
+        def binding?(other)
+          binding == other
+        end
 
-      def serialize(builder, relay_state: nil)
-        []
-      end
+        def serialize(builder, relay_state: nil)
+          []
+        end
 
-      def deserialize(params)
-        raise ArgumentError.new("Unsupported binding")
-      end
+        def deserialize(params)
+          raise ArgumentError.new("Unsupported binding")
+        end
 
-      def to_h
-        { binding: binding, location: location }
-      end
+        def to_h
+          { binding: binding, location: location }
+        end
 
-      protected
+        protected
 
-      def saml_param_from(params)
-        if params['SAMLRequest'].present?
-          params['SAMLRequest']
-        elsif params['SAMLResponse'].present?
-          params['SAMLResponse']
-        else
-          raise ArgumentError.new("SAMLRequest or SAMLResponse parameter is required.")
+        def saml_param_from(params)
+          if params['SAMLRequest'].present?
+            params['SAMLRequest']
+          elsif params['SAMLResponse'].present?
+            params['SAMLResponse']
+          else
+            raise ArgumentError.new("SAMLRequest or SAMLResponse parameter is required.")
+          end
         end
       end
     end
lib/saml/kit/bindings/http_post.rb
@@ -1,26 +1,28 @@
 module Saml
   module Kit
-    class HttpPostBinding < Binding
-      include Serializable
+    module Bindings
+      class HttpPost < Binding
+        include Serializable
 
-      def initialize(location:)
-        super(binding: Saml::Kit::Namespaces::HTTP_POST, location: location)
-      end
+        def initialize(location:)
+          super(binding: Saml::Kit::Namespaces::HTTP_POST, location: location)
+        end
 
-      def serialize(builder, relay_state: nil)
-        builder.sign = true
-        builder.destination = location
-        document = builder.build
-        saml_params = {
-          document.query_string_parameter => Base64.strict_encode64(document.to_xml),
-        }
-        saml_params['RelayState'] = relay_state if relay_state.present?
-        [location, saml_params]
-      end
+        def serialize(builder, relay_state: nil)
+          builder.sign = true
+          builder.destination = location
+          document = builder.build
+          saml_params = {
+            document.query_string_parameter => Base64.strict_encode64(document.to_xml),
+          }
+          saml_params['RelayState'] = relay_state if relay_state.present?
+          [location, saml_params]
+        end
 
-      def deserialize(params)
-        xml = decode(saml_param_from(params))
-        Saml::Kit::Document.to_saml_document(xml)
+        def deserialize(params)
+          xml = decode(saml_param_from(params))
+          Saml::Kit::Document.to_saml_document(xml)
+        end
       end
     end
   end
lib/saml/kit/bindings/http_redirect.rb
@@ -1,57 +1,59 @@
 module Saml
   module Kit
-    class HttpRedirectBinding < Binding
-      include Serializable
+    module Bindings
+      class HttpRedirect < Binding
+        include Serializable
 
-      def initialize(location:)
-        super(binding: Saml::Kit::Namespaces::HTTP_REDIRECT, location: location)
-      end
+        def initialize(location:)
+          super(binding: Saml::Kit::Namespaces::HTTP_REDIRECT, location: location)
+        end
 
-      def serialize(builder, relay_state: nil)
-        builder.sign = false
-        builder.destination = location
-        document = builder.build
-        [UrlBuilder.new.build(document, relay_state: relay_state), {}]
-      end
+        def serialize(builder, relay_state: nil)
+          builder.sign = false
+          builder.destination = location
+          document = builder.build
+          [UrlBuilder.new.build(document, relay_state: relay_state), {}]
+        end
 
-      def deserialize(params)
-        document = deserialize_document_from!(params)
-        ensure_valid_signature!(params, document)
-        document.signature_verified!
-        document
-      end
+        def deserialize(params)
+          document = deserialize_document_from!(params)
+          ensure_valid_signature!(params, document)
+          document.signature_verified!
+          document
+        end
 
-      private
+        private
 
-      def deserialize_document_from!(params)
-        xml = inflate(decode(unescape(saml_param_from(params))))
-        Saml::Kit.logger.debug(xml)
-        Saml::Kit::Document.to_saml_document(xml)
-      end
+        def deserialize_document_from!(params)
+          xml = inflate(decode(unescape(saml_param_from(params))))
+          Saml::Kit.logger.debug(xml)
+          Saml::Kit::Document.to_saml_document(xml)
+        end
 
-      def ensure_valid_signature!(params, document)
-        return if params['Signature'].blank? || params['SigAlg'].blank?
+        def ensure_valid_signature!(params, document)
+          return if params['Signature'].blank? || params['SigAlg'].blank?
 
-        signature = decode(params['Signature'])
-        canonical_form = ['SAMLRequest', 'SAMLResponse', 'RelayState', 'SigAlg'].map do |key|
-          value = params[key]
-          value.present? ? "#{key}=#{value}" : nil
-        end.compact.join('&')
+          signature = decode(params['Signature'])
+          canonical_form = ['SAMLRequest', 'SAMLResponse', 'RelayState', 'SigAlg'].map do |key|
+            value = params[key]
+            value.present? ? "#{key}=#{value}" : nil
+          end.compact.join('&')
 
-        valid = document.provider.verify(algorithm_for(params['SigAlg']), signature, canonical_form)
-        raise ArgumentError.new("Invalid Signature") unless valid
-      end
+          valid = document.provider.verify(algorithm_for(params['SigAlg']), signature, canonical_form)
+          raise ArgumentError.new("Invalid Signature") unless valid
+        end
 
-      def algorithm_for(algorithm)
-        case algorithm =~ /(rsa-)?sha(.*?)$/i && $2.to_i
-        when 256
-          OpenSSL::Digest::SHA256.new
-        when 384
-          OpenSSL::Digest::SHA384.new
-        when 512
-          OpenSSL::Digest::SHA512.new
-        else
-          OpenSSL::Digest::SHA1.new
+        def algorithm_for(algorithm)
+          case algorithm =~ /(rsa-)?sha(.*?)$/i && $2.to_i
+          when 256
+            OpenSSL::Digest::SHA256.new
+          when 384
+            OpenSSL::Digest::SHA384.new
+          when 512
+            OpenSSL::Digest::SHA512.new
+          else
+            OpenSSL::Digest::SHA1.new
+          end
         end
       end
     end
lib/saml/kit/bindings/url_builder.rb
@@ -1,37 +1,39 @@
 module Saml
   module Kit
-    class UrlBuilder
-      include Serializable
+    module Bindings
+      class UrlBuilder
+        include Serializable
 
-      def initialize(private_key: Saml::Kit.configuration.signing_private_key)
-        @private_key = private_key
-      end
+        def initialize(private_key: Saml::Kit.configuration.signing_private_key)
+          @private_key = private_key
+        end
 
-      def build(saml_document, relay_state: nil)
-        payload = canonicalize(saml_document, relay_state)
-        "#{saml_document.destination}?#{payload}&Signature=#{signature_for(payload)}"
-      end
+        def build(saml_document, relay_state: nil)
+          payload = canonicalize(saml_document, relay_state)
+          "#{saml_document.destination}?#{payload}&Signature=#{signature_for(payload)}"
+        end
 
-      private
+        private
 
-      attr_reader :private_key
+        attr_reader :private_key
 
-      def signature_for(payload)
-        encode(private_key.sign(OpenSSL::Digest::SHA256.new, payload))
-      end
+        def signature_for(payload)
+          encode(private_key.sign(OpenSSL::Digest::SHA256.new, payload))
+        end
 
-      def canonicalize(saml_document, relay_state)
-        {
-          saml_document.query_string_parameter => serialize(saml_document.to_xml),
-          'RelayState' => relay_state,
-          'SigAlg' => Saml::Kit::Namespaces::SHA256,
-        }.map do |(key, value)|
-          value.present? ? "#{key}=#{escape(value)}" : nil
-        end.compact.join('&')
-      end
+        def canonicalize(saml_document, relay_state)
+          {
+            saml_document.query_string_parameter => serialize(saml_document.to_xml),
+            'RelayState' => relay_state,
+            'SigAlg' => Saml::Kit::Namespaces::SHA256,
+          }.map do |(key, value)|
+            value.present? ? "#{key}=#{escape(value)}" : nil
+          end.compact.join('&')
+        end
 
-      def serialize(value)
-        encode(deflate(value))
+        def serialize(value)
+          encode(deflate(value))
+        end
       end
     end
   end
lib/saml/kit/metadata.rb
@@ -160,11 +160,11 @@ module Saml
       def binding_for(binding, location)
         case binding
         when Namespaces::HTTP_REDIRECT
-          Saml::Kit::HttpRedirectBinding.new(location: location)
+          Saml::Kit::Bindings::HttpRedirect.new(location: location)
         when Namespaces::POST
-          Saml::Kit::HttpPostBinding.new(location: location)
+          Saml::Kit::Bindings::HttpPost.new(location: location)
         else
-          Saml::Kit::Binding.new(binding: binding, location: location)
+          Saml::Kit::Bindings::Binding.new(binding: binding, location: location)
         end
       end
     end
spec/saml/bindings/binding_spec.rb
@@ -1,8 +1,8 @@
 require 'spec_helper'
 
-RSpec.describe Saml::Kit::Binding do
+RSpec.describe Saml::Kit::Bindings::Binding do
   let(:location) { FFaker::Internet.http_url }
-  subject { Saml::Kit::Binding.new(binding: Saml::Kit::Namespaces::HTTP_ARTIFACT, location: location) }
+  subject { described_class.new(binding: Saml::Kit::Namespaces::HTTP_ARTIFACT, location: location) }
 
   describe "#serialize" do
     it 'ignores other bindings' do
spec/saml/bindings/http_post_spec.rb
@@ -1,8 +1,8 @@
 require 'spec_helper'
 
-RSpec.describe Saml::Kit::HttpPostBinding do
+RSpec.describe Saml::Kit::Bindings::HttpPost do
   let(:location) { FFaker::Internet.http_url }
-  subject { Saml::Kit::HttpPostBinding.new(location: location) }
+  subject { described_class.new(location: location) }
 
   describe "#serialize" do
     let(:relay_state) { "ECHO" }
spec/saml/bindings/http_redirect_spec.rb
@@ -1,8 +1,8 @@
 require 'spec_helper'
 
-RSpec.describe Saml::Kit::HttpRedirectBinding do
+RSpec.describe Saml::Kit::Bindings::HttpRedirect do
   let(:location) { FFaker::Internet.http_url }
-  subject { Saml::Kit::HttpRedirectBinding.new(location: location) }
+  subject { described_class.new(location: location) }
 
   describe "#serialize" do
     let(:relay_state) { "ECHO" }
spec/saml/bindings/url_builder_spec.rb
@@ -1,6 +1,6 @@
 require 'spec_helper'
 
-RSpec.describe Saml::Kit::UrlBuilder do
+RSpec.describe Saml::Kit::Bindings::UrlBuilder do
   describe "#build" do
     let(:xml) { "<xml></xml>" }
     let(:destination) { FFaker::Internet.http_url }
spec/saml/logout_request_spec.rb
@@ -38,7 +38,7 @@ RSpec.describe Saml::Kit::LogoutRequest do
       allow(registry).to receive(:metadata_for).and_return(metadata)
       allow(metadata).to receive(:matches?).and_return(true)
       allow(metadata).to receive(:single_logout_services).and_return([
-        Saml::Kit::HttpPostBinding.new(location: FFaker::Internet.http_url)
+        Saml::Kit::Bindings::HttpPost.new(location: FFaker::Internet.http_url)
       ])
     end
 
@@ -94,7 +94,7 @@ RSpec.describe Saml::Kit::LogoutRequest do
       allow(registry).to receive(:metadata_for).with(builder.issuer).and_return(metadata)
       allow(metadata).to receive(:matches?).and_return(true)
       allow(metadata).to receive(:single_logout_services).and_return([
-        Saml::Kit::HttpPostBinding.new(location: FFaker::Internet.http_url)
+        Saml::Kit::Bindings::HttpPost.new(location: FFaker::Internet.http_url)
       ])
 
       expect(builder.build).to be_valid