Comparing changes

v0.2.7 v0.2.8
7 commits 7 files changed
lib/saml/kit/bindings/binding.rb
@@ -48,10 +48,14 @@ module Saml
         protected
 
         def saml_param_from(params)
-          if params['SAMLRequest'].present?
-            params['SAMLRequest']
-          elsif params['SAMLResponse'].present?
-            params['SAMLResponse']
+          parameters = {
+            SAMLRequest: params[:SAMLRequest] || params['SAMLRequest'],
+            SAMLResponse: params[:SAMLResponse] || params['SAMLResponse'],
+          }
+          if parameters[:SAMLRequest].present?
+            parameters[:SAMLRequest]
+          elsif parameters[:SAMLResponse].present?
+            parameters[:SAMLResponse]
           else
             raise ArgumentError.new("SAMLRequest or SAMLResponse parameter is required.")
           end
lib/saml/kit/bindings/url_builder.rb
@@ -10,10 +10,14 @@ module Saml
         end
 
         def build(saml_document, relay_state: nil)
-          payload = canonicalize(saml_document, relay_state)
           if configuration.sign?
+            payload = canonicalize(saml_document, relay_state)
             "#{saml_document.destination}?#{payload}&Signature=#{signature_for(payload)}"
           else
+            payload = to_query_string(
+              saml_document.query_string_parameter => serialize(saml_document.to_xml),
+              'RelayState' => relay_state,
+            )
             "#{saml_document.destination}?#{payload}"
           end
         end
@@ -26,11 +30,15 @@ module Saml
         end
 
         def canonicalize(saml_document, relay_state)
-          {
+          to_query_string(
             saml_document.query_string_parameter => serialize(saml_document.to_xml),
             'RelayState' => relay_state,
             'SigAlg' => Saml::Kit::Namespaces::SHA256,
-          }.map do |(key, value)|
+          )
+        end
+
+        def to_query_string(query_params)
+          query_params.map do |(key, value)|
             value.present? ? "#{key}=#{escape(value)}" : nil
           end.compact.join('&')
         end
lib/saml/kit/configuration.rb
@@ -17,7 +17,7 @@ module Saml
       end
 
       def add_key_pair(certificate, private_key, password:, use: :signing)
-        @key_pairs.push(KeyPair.new(certificate, private_key, password, use))
+        @key_pairs.push(KeyPair.new(certificate, private_key, password, use.to_sym))
       end
 
       def generate_key_pair_for(use:, password: SecureRandom.uuid)
lib/saml/kit/identity_provider_metadata.rb
@@ -29,8 +29,8 @@ module Saml
         end
       end
 
-      def login_request_for(binding:, relay_state: nil)
-        builder = Saml::Kit::AuthenticationRequest.builder do |x|
+      def login_request_for(binding:, relay_state: nil, configuration: Saml::Kit.configuration)
+        builder = Saml::Kit::AuthenticationRequest.builder(configuration: configuration) do |x|
           x.embed_signature = want_authn_requests_signed
           yield x if block_given?
         end
lib/saml/kit/key_pair.rb
@@ -1,7 +1,7 @@
 module Saml
   module Kit
     class KeyPair
-      attr_reader :certificate, :private_key
+      attr_reader :certificate, :private_key, :use
 
       def initialize(certificate, private_key, password, use)
         @use = use
lib/saml/kit/version.rb
@@ -1,5 +1,5 @@
 module Saml
   module Kit
-    VERSION = "0.2.7"
+    VERSION = "0.2.8"
   end
 end
spec/saml/bindings/http_redirect_spec.rb
@@ -37,6 +37,27 @@ RSpec.describe Saml::Kit::Bindings::HttpRedirect do
       expect(result).to be_instance_of(Saml::Kit::AuthenticationRequest)
     end
 
+    it 'deserializes the SAMLRequest to an AuthnRequest with symbols for keys' do
+      url, _ = subject.serialize(Saml::Kit::AuthenticationRequest.builder_class.new)
+      result = subject.deserialize(query_params_from(url).symbolize_keys)
+      expect(result).to be_instance_of(Saml::Kit::AuthenticationRequest)
+    end
+
+    it 'deserializes the SAMLRequest to an AuthnRequest when given a custom params object' do
+      class Parameters
+        def initialize(params)
+          @params = params
+        end
+
+        def [](key)
+          @params[key]
+        end
+      end
+      url, _ = subject.serialize(Saml::Kit::AuthenticationRequest.builder_class.new)
+      result = subject.deserialize(Parameters.new(query_params_from(url)))
+      expect(result).to be_instance_of(Saml::Kit::AuthenticationRequest)
+    end
+
     it 'deserializes the SAMLRequest to a LogoutRequest' do
       user = double(:user, name_id_for: SecureRandom.uuid)
       url, _ = subject.serialize(Saml::Kit::LogoutRequest.builder_class.new(user))
@@ -79,7 +100,15 @@ RSpec.describe Saml::Kit::Bindings::HttpRedirect do
     end
 
     it 'raises an error when the signature does not match' do
-      url, _ = subject.serialize(Saml::Kit::AuthenticationRequest.builder_class.new)
+      configuration = Saml::Kit::Configuration.new do |config|
+        config.issuer = issuer
+        config.generate_key_pair_for(use: :signing)
+      end
+      url, _ = subject.serialize(
+        Saml::Kit::AuthenticationRequest.builder(configuration: configuration) do |x|
+          x.embed_signature = true
+        end
+      )
       query_params = query_params_from(url)
       query_params['Signature'] = 'invalid'
       expect do