Commit 6ab0459

mo <mo@mokhan.ca>
2017-11-29 02:38:30
move idp builder to separate file.
1 parent 52fa7fb
lib/saml/kit/builders/identity_provider_metadata.rb
@@ -0,0 +1,103 @@
+module Saml
+  module Kit
+    class IdentityProviderMetadata < Metadata
+      class Builder
+        attr_accessor :id, :organization_name, :organization_url, :contact_email, :entity_id, :attributes, :name_id_formats
+        attr_accessor :want_authn_requests_signed, :sign
+        attr_reader :logout_urls, :single_sign_on_urls
+
+        def initialize(configuration = Saml::Kit.configuration)
+          @id = SecureRandom.uuid
+          @entity_id = configuration.issuer
+          @attributes = []
+          @name_id_formats = [Namespaces::PERSISTENT]
+          @single_sign_on_urls = []
+          @logout_urls = []
+          @configuration = configuration
+          @sign = true
+          @want_authn_requests_signed = true
+        end
+
+        def add_single_sign_on_service(url, binding: :http_post)
+          @single_sign_on_urls.push(location: url, binding: Bindings.binding_for(binding))
+        end
+
+        def add_single_logout_service(url, binding: :http_post)
+          @logout_urls.push(location: url, binding: Bindings.binding_for(binding))
+        end
+
+        def to_xml
+          Signature.sign(sign: sign) do |xml, signature|
+            xml.instruct!
+            xml.EntityDescriptor entity_descriptor_options do
+              signature.template(id)
+              xml.IDPSSODescriptor idp_sso_descriptor_options do
+                if @configuration.signing_certificate_pem.present?
+                  xml.KeyDescriptor use: "signing" do
+                    xml.KeyInfo "xmlns": Namespaces::XMLDSIG do
+                      xml.X509Data do
+                        xml.X509Certificate @configuration.stripped_signing_certificate
+                      end
+                    end
+                  end
+                end
+                if @configuration.encryption_certificate_pem.present?
+                  xml.KeyDescriptor use: "encryption" do
+                    xml.KeyInfo "xmlns": Namespaces::XMLDSIG do
+                      xml.X509Data do
+                        xml.X509Certificate @configuration.stripped_encryption_certificate
+                      end
+                    end
+                  end
+                end
+                logout_urls.each do |item|
+                  xml.SingleLogoutService Binding: item[:binding], Location: item[:location]
+                end
+                name_id_formats.each do |format|
+                  xml.NameIDFormat format
+                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', Name: attribute
+                end
+              end
+              xml.Organization do
+                xml.OrganizationName organization_name, 'xml:lang': "en"
+                xml.OrganizationDisplayName organization_name, 'xml:lang': "en"
+                xml.OrganizationURL organization_url, 'xml:lang': "en"
+              end
+              xml.ContactPerson contactType: "technical" do
+                xml.Company "mailto:#{contact_email}"
+              end
+            end
+          end
+        end
+
+        def build
+          IdentityProviderMetadata.new(to_xml)
+        end
+
+        private
+
+        def entity_descriptor_options
+          {
+            'xmlns': Namespaces::METADATA,
+            'xmlns:ds': Namespaces::XMLDSIG,
+            'xmlns:saml': Namespaces::ASSERTION,
+            ID: "_#{id}",
+            entityID: entity_id,
+          }
+        end
+
+        def idp_sso_descriptor_options
+          {
+            WantAuthnRequestsSigned: want_authn_requests_signed,
+            protocolSupportEnumeration: Namespaces::PROTOCOL,
+          }
+        end
+      end
+    end
+  end
+end
lib/saml/kit/builders.rb
@@ -1,1 +1,2 @@
 require 'saml/kit/builders/authentication_request'
+require 'saml/kit/builders/identity_provider_metadata'
lib/saml/kit/identity_provider_metadata.rb
@@ -28,106 +28,6 @@ module Saml
           }
         end
       end
-
-      private
-
-      class Builder
-        attr_accessor :id, :organization_name, :organization_url, :contact_email, :entity_id, :attributes, :name_id_formats
-        attr_accessor :want_authn_requests_signed, :sign
-        attr_reader :logout_urls, :single_sign_on_urls
-
-        def initialize(configuration = Saml::Kit.configuration)
-          @id = SecureRandom.uuid
-          @entity_id = configuration.issuer
-          @attributes = []
-          @name_id_formats = [Namespaces::PERSISTENT]
-          @single_sign_on_urls = []
-          @logout_urls = []
-          @configuration = configuration
-          @sign = true
-          @want_authn_requests_signed = true
-        end
-
-        def add_single_sign_on_service(url, binding: :http_post)
-          @single_sign_on_urls.push(location: url, binding: Bindings.binding_for(binding))
-        end
-
-        def add_single_logout_service(url, binding: :http_post)
-          @logout_urls.push(location: url, binding: Bindings.binding_for(binding))
-        end
-
-        def to_xml
-          Signature.sign(sign: sign) do |xml, signature|
-            xml.instruct!
-            xml.EntityDescriptor entity_descriptor_options do
-              signature.template(id)
-              xml.IDPSSODescriptor idp_sso_descriptor_options do
-                if @configuration.signing_certificate_pem.present?
-                  xml.KeyDescriptor use: "signing" do
-                    xml.KeyInfo "xmlns": Namespaces::XMLDSIG do
-                      xml.X509Data do
-                        xml.X509Certificate @configuration.stripped_signing_certificate
-                      end
-                    end
-                  end
-                end
-                if @configuration.encryption_certificate_pem.present?
-                  xml.KeyDescriptor use: "encryption" do
-                    xml.KeyInfo "xmlns": Namespaces::XMLDSIG do
-                      xml.X509Data do
-                        xml.X509Certificate @configuration.stripped_encryption_certificate
-                      end
-                    end
-                  end
-                end
-                logout_urls.each do |item|
-                  xml.SingleLogoutService Binding: item[:binding], Location: item[:location]
-                end
-                name_id_formats.each do |format|
-                  xml.NameIDFormat format
-                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', Name: attribute
-                end
-              end
-              xml.Organization do
-                xml.OrganizationName organization_name, 'xml:lang': "en"
-                xml.OrganizationDisplayName organization_name, 'xml:lang': "en"
-                xml.OrganizationURL organization_url, 'xml:lang': "en"
-              end
-              xml.ContactPerson contactType: "technical" do
-                xml.Company "mailto:#{contact_email}"
-              end
-            end
-          end
-        end
-
-        def build
-          IdentityProviderMetadata.new(to_xml)
-        end
-
-        private
-
-        def entity_descriptor_options
-          {
-            'xmlns': Namespaces::METADATA,
-            'xmlns:ds': Namespaces::XMLDSIG,
-            'xmlns:saml': Namespaces::ASSERTION,
-            ID: "_#{id}",
-            entityID: entity_id,
-          }
-        end
-
-        def idp_sso_descriptor_options
-          {
-            WantAuthnRequestsSigned: want_authn_requests_signed,
-            protocolSupportEnumeration: Namespaces::PROTOCOL,
-          }
-        end
-      end
     end
   end
 end
spec/saml/builders/identity_provider_metadata_spec.rb
@@ -0,0 +1,51 @@
+require 'spec_helper'
+
+RSpec.describe Saml::Kit::IdentityProviderMetadata::Builder do
+  subject { described_class.new }
+  let(:email) { FFaker::Internet.email }
+  let(:org_name) { FFaker::Movie.title }
+  let(:url) { "https://#{FFaker::Internet.domain_name}" }
+  let(:entity_id) { FFaker::Movie.title }
+
+  it 'builds a proper metadata' do
+    subject.contact_email = email
+    subject.entity_id = entity_id
+    subject.organization_name = org_name
+    subject.organization_url = url
+    subject.name_id_formats = [
+      Saml::Kit::Namespaces::PERSISTENT,
+      Saml::Kit::Namespaces::TRANSIENT,
+      Saml::Kit::Namespaces::EMAIL_ADDRESS,
+    ]
+    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: :http_post)
+    subject.attributes << "id"
+
+    result = Hash.from_xml(subject.build.to_xml)
+
+    expect(result['EntityDescriptor']['ID']).to be_present
+    expect(result['EntityDescriptor']['entityID']).to eql(entity_id)
+    expect(result['EntityDescriptor']['IDPSSODescriptor']['protocolSupportEnumeration']).to eql(Saml::Kit::Namespaces::PROTOCOL)
+    expect(result['EntityDescriptor']['IDPSSODescriptor']['WantAuthnRequestsSigned']).to eql('true')
+    expect(result['EntityDescriptor']['IDPSSODescriptor']['NameIDFormat']).to match_array([
+      Saml::Kit::Namespaces::PERSISTENT,
+      Saml::Kit::Namespaces::TRANSIENT,
+      Saml::Kit::Namespaces::EMAIL_ADDRESS,
+    ])
+    expect(result['EntityDescriptor']['IDPSSODescriptor']['SingleSignOnService']['Binding']).to eql(Saml::Kit::Bindings::HTTP_REDIRECT)
+    expect(result['EntityDescriptor']['IDPSSODescriptor']['SingleSignOnService']['Location']).to eql("https://www.example.com/login")
+    expect(result['EntityDescriptor']['IDPSSODescriptor']['SingleLogoutService']['Binding']).to eql(Saml::Kit::Bindings::HTTP_POST)
+    expect(result['EntityDescriptor']['IDPSSODescriptor']['SingleLogoutService']['Location']).to eql("https://www.example.com/logout")
+    expect(result['EntityDescriptor']['IDPSSODescriptor']['Attribute']['Name']).to eql("id")
+    certificates = result['EntityDescriptor']['IDPSSODescriptor']['KeyDescriptor'].map { |x| x['KeyInfo']['X509Data']['X509Certificate'] }
+    expect(certificates).to match_array([
+      Saml::Kit.configuration.stripped_signing_certificate,
+      Saml::Kit.configuration.stripped_encryption_certificate,
+    ])
+    expect(result['EntityDescriptor']['Organization']['OrganizationName']).to eql(org_name)
+    expect(result['EntityDescriptor']['Organization']['OrganizationDisplayName']).to eql(org_name)
+    expect(result['EntityDescriptor']['Organization']['OrganizationURL']).to eql(url)
+    expect(result['EntityDescriptor']['ContactPerson']['contactType']).to eql("technical")
+    expect(result['EntityDescriptor']['ContactPerson']['Company']).to eql("mailto:#{email}")
+  end
+end
spec/saml/identity_provider_metadata_spec.rb
@@ -187,54 +187,4 @@ RSpec.describe Saml::Kit::IdentityProviderMetadata do
       expect(subject.single_logout_service_for(binding: :soap)).to be_nil
     end
   end
-
-  describe described_class::Builder do
-    subject { described_class.new }
-    let(:email) { FFaker::Internet.email }
-    let(:org_name) { FFaker::Movie.title }
-    let(:url) { "https://#{FFaker::Internet.domain_name}" }
-    let(:entity_id) { FFaker::Movie.title }
-
-    it 'builds a proper metadata' do
-      subject.contact_email = email
-      subject.entity_id = entity_id
-      subject.organization_name = org_name
-      subject.organization_url = url
-      subject.name_id_formats = [
-        Saml::Kit::Namespaces::PERSISTENT,
-        Saml::Kit::Namespaces::TRANSIENT,
-        Saml::Kit::Namespaces::EMAIL_ADDRESS,
-      ]
-      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: :http_post)
-      subject.attributes << "id"
-
-      result = Hash.from_xml(subject.build.to_xml)
-
-      expect(result['EntityDescriptor']['ID']).to be_present
-      expect(result['EntityDescriptor']['entityID']).to eql(entity_id)
-      expect(result['EntityDescriptor']['IDPSSODescriptor']['protocolSupportEnumeration']).to eql(Saml::Kit::Namespaces::PROTOCOL)
-      expect(result['EntityDescriptor']['IDPSSODescriptor']['WantAuthnRequestsSigned']).to eql('true')
-      expect(result['EntityDescriptor']['IDPSSODescriptor']['NameIDFormat']).to match_array([
-        Saml::Kit::Namespaces::PERSISTENT,
-        Saml::Kit::Namespaces::TRANSIENT,
-        Saml::Kit::Namespaces::EMAIL_ADDRESS,
-      ])
-      expect(result['EntityDescriptor']['IDPSSODescriptor']['SingleSignOnService']['Binding']).to eql(Saml::Kit::Bindings::HTTP_REDIRECT)
-      expect(result['EntityDescriptor']['IDPSSODescriptor']['SingleSignOnService']['Location']).to eql("https://www.example.com/login")
-      expect(result['EntityDescriptor']['IDPSSODescriptor']['SingleLogoutService']['Binding']).to eql(Saml::Kit::Bindings::HTTP_POST)
-      expect(result['EntityDescriptor']['IDPSSODescriptor']['SingleLogoutService']['Location']).to eql("https://www.example.com/logout")
-      expect(result['EntityDescriptor']['IDPSSODescriptor']['Attribute']['Name']).to eql("id")
-      certificates = result['EntityDescriptor']['IDPSSODescriptor']['KeyDescriptor'].map { |x| x['KeyInfo']['X509Data']['X509Certificate'] }
-      expect(certificates).to match_array([
-        Saml::Kit.configuration.stripped_signing_certificate,
-        Saml::Kit.configuration.stripped_encryption_certificate,
-      ])
-      expect(result['EntityDescriptor']['Organization']['OrganizationName']).to eql(org_name)
-      expect(result['EntityDescriptor']['Organization']['OrganizationDisplayName']).to eql(org_name)
-      expect(result['EntityDescriptor']['Organization']['OrganizationURL']).to eql(url)
-      expect(result['EntityDescriptor']['ContactPerson']['contactType']).to eql("technical")
-      expect(result['EntityDescriptor']['ContactPerson']['Company']).to eql("mailto:#{email}")
-    end
-  end
 end