Commit a2c26c7

mo <mo@mokhan.ca>
2017-11-02 17:29:36
support multiple signin and logout bindings.
1 parent a2d04c8
lib/saml/kit/identity_provider_metadata.rb
@@ -25,12 +25,23 @@ module Saml
       private
 
       class Builder
-        attr_accessor :id, :organization_name, :organization_url, :contact_email, :entity_id, :single_sign_on_location, :single_logout_location, :attributes
+        attr_accessor :id, :organization_name, :organization_url, :contact_email, :entity_id, :attributes
+        attr_reader :logout_urls, :single_sign_on_urls
 
         def initialize(configuration = Saml::Kit.configuration)
           @id = SecureRandom.uuid
           @entity_id = configuration.issuer
           @attributes = []
+          @single_sign_on_urls = []
+          @logout_urls = []
+        end
+
+        def add_single_sign_on_service(url, binding: :post)
+          @single_sign_on_urls.push(location: url, binding: binding_namespace_for(binding))
+        end
+
+        def add_single_logout_service(url, binding: :post)
+          @logout_urls.push(location: url, binding: binding_namespace_for(binding))
         end
 
         def to_xml
@@ -41,8 +52,12 @@ module Saml
             signature.template(xml)
             xml.IDPSSODescriptor protocolSupportEnumeration: Namespaces::PROTOCOL do
               xml.NameIDFormat Namespaces::Formats::NameId::PERSISTENT
-              xml.SingleLogoutService Binding: Namespaces::Bindings::POST, Location: single_logout_location
-              xml.SingleSignOnService Binding: Namespaces::Bindings::HTTP_REDIRECT, Location: single_sign_on_location
+              logout_urls.each do |item|
+                xml.SingleLogoutService Binding: item[:binding], Location: item[:location]
+              end
+              single_sign_on_urls.each do |item|
+                xml.SingleSignOnService Binding: item[:binding], Location: item[:location]
+              end
               attributes.each do |attribute|
                 xml.tag! 'saml:Attribute', NameFormat: Namespaces::Formats::Attr::URI, Name: attribute, FriendlyName: attribute
               end
@@ -74,6 +89,14 @@ module Saml
             entityID: entity_id,
           }
         end
+
+        def binding_namespace_for(binding)
+          if :post == binding
+            Namespaces::Bindings::POST
+          else
+            Namespaces::Bindings::HTTP_REDIRECT
+          end
+        end
       end
     end
   end
spec/saml/identity_provider_metadata_spec.rb
@@ -13,8 +13,8 @@ RSpec.describe Saml::Kit::IdentityProviderMetadata do
       subject.entity_id = entity_id
       subject.organization_name = org_name
       subject.organization_url = url
-      subject.single_sign_on_location = "https://www.example.com/login"
-      subject.single_logout_location = "https://www.example.com/logout"
+      subject.add_single_sign_on_service("https://www.example.com/login", binding: :http_redirect)
+      subject.add_single_logout_service("https://www.example.com/logout", binding: :post)
       subject.attributes << "id"
 
       result = Hash.from_xml(subject.build.to_xml)
spec/saml/xml_spec.rb
@@ -40,17 +40,5 @@ RSpec.describe Saml::Kit::Xml do
       expect(subject).to_not be_valid
       expect(subject.errors[:signature]).to be_present
     end
-
-    [
-      'ad_2012.xml',
-      'ad_with_logout.xml',
-      'okta.xml',
-    ].each do |xml_file|
-      it "validates #{xml_file}" do
-        travel_to DateTime.new(2017, 10, 6)
-        xml = IO.read("spec/fixtures/metadata/#{xml_file}")
-        expect(described_class.new(xml)).to be_valid
-      end
-    end
   end
 end