main
  1# frozen_string_literal: true
  2
  3RSpec.describe Saml::Kit::CompositeMetadata do
  4  subject { described_class.new(xml) }
  5
  6  let(:post_binding) { Saml::Kit::Bindings::HTTP_POST }
  7  let(:redirect_binding) { Saml::Kit::Bindings::HTTP_REDIRECT }
  8  let(:sign_on_service) { FFaker::Internet.uri('https') }
  9  let(:assertion_consumer_service) { FFaker::Internet.uri('https') }
 10  let(:sp_logout_service) { FFaker::Internet.uri('https') }
 11  let(:idp_logout_service) { FFaker::Internet.uri('https') }
 12  let(:entity_id) { FFaker::Internet.uri('https') }
 13  let(:sp_signing_certificate) { ::Xml::Kit::KeyPair.generate(use: :signing).certificate }
 14  let(:sp_encryption_certificate) { ::Xml::Kit::KeyPair.generate(use: :encryption).certificate }
 15  let(:idp_signing_certificate) { ::Xml::Kit::KeyPair.generate(use: :signing).certificate }
 16  let(:idp_encryption_certificate) { ::Xml::Kit::KeyPair.generate(use: :encryption).certificate }
 17  let(:xml) do
 18    <<-XML.strip_heredoc
 19      <EntityDescriptor xmlns="#{Saml::Kit::Namespaces::METADATA}" ID="#{::Xml::Kit::Id.generate}" entityID="#{entity_id}">
 20        <SPSSODescriptor AuthnRequestsSigned="false" WantAssertionsSigned="true" protocolSupportEnumeration="#{Saml::Kit::Namespaces::PROTOCOL}">
 21          <KeyDescriptor use="signing">
 22            <KeyInfo xmlns="#{::Xml::Kit::Namespaces::XMLDSIG}">
 23              <X509Data>
 24                <X509Certificate>#{sp_signing_certificate.stripped}</X509Certificate>
 25              </X509Data>
 26            </KeyInfo>
 27          </KeyDescriptor>
 28          <KeyDescriptor use="encryption">
 29            <KeyInfo xmlns="#{::Xml::Kit::Namespaces::XMLDSIG}">
 30              <X509Data>
 31                <X509Certificate>#{sp_encryption_certificate.stripped}</X509Certificate>
 32              </X509Data>
 33            </KeyInfo>
 34          </KeyDescriptor>
 35          <SingleLogoutService Binding="#{post_binding}" Location="#{sp_logout_service}"/>
 36          <NameIDFormat>#{Saml::Kit::Namespaces::PERSISTENT}</NameIDFormat>
 37          <AssertionConsumerService Binding="#{post_binding}" Location="#{assertion_consumer_service}" index="0" isDefault="true"/>
 38        </SPSSODescriptor>
 39        <IDPSSODescriptor WantAuthnRequestsSigned="true" protocolSupportEnumeration="#{Saml::Kit::Namespaces::PROTOCOL}">
 40          <KeyDescriptor use="signing">
 41            <KeyInfo xmlns="#{::Xml::Kit::Namespaces::XMLDSIG}">
 42              <X509Data>
 43                <X509Certificate>#{idp_signing_certificate.stripped}</X509Certificate>
 44              </X509Data>
 45            </KeyInfo>
 46          </KeyDescriptor>
 47          <KeyDescriptor use="encryption">
 48            <KeyInfo xmlns="#{::Xml::Kit::Namespaces::XMLDSIG}">
 49              <X509Data>
 50                <X509Certificate>#{idp_encryption_certificate.stripped}</X509Certificate>
 51              </X509Data>
 52            </KeyInfo>
 53          </KeyDescriptor>
 54          <SingleLogoutService Binding="#{post_binding}" Location="#{idp_logout_service}"/>
 55          <NameIDFormat>#{Saml::Kit::Namespaces::PERSISTENT}</NameIDFormat>
 56          <SingleSignOnService Binding="#{post_binding}" Location="#{sign_on_service}"/>
 57          <SingleSignOnService Binding="#{redirect_binding}" Location="#{sign_on_service}"/>
 58          <Attribute xmlns="#{Saml::Kit::Namespaces::ASSERTION}" Name="id" ></Attribute>
 59        </IDPSSODescriptor>
 60        <Organization>
 61          <OrganizationName xml:lang="en">Acme, Inc</OrganizationName>
 62          <OrganizationDisplayName xml:lang="en">Acme, Inc</OrganizationDisplayName>
 63          <OrganizationURL xml:lang="en">http://localhost:5000/</OrganizationURL>
 64        </Organization>
 65        <ContactPerson contactType="technical">
 66          <Company>mailto:hi@example.com</Company>
 67        </ContactPerson>
 68      </EntityDescriptor>
 69    XML
 70  end
 71
 72  describe '#single_sign_on_services' do
 73    it 'returns the single sign on services from the idp' do
 74      expect(subject.single_sign_on_services).to match_array([
 75        Saml::Kit::Bindings::HttpPost.new(location: sign_on_service),
 76        Saml::Kit::Bindings::HttpRedirect.new(location: sign_on_service),
 77      ])
 78    end
 79  end
 80
 81  describe '#single_sign_on_service_for' do
 82    it 'returns the post binding' do
 83      expect(subject.single_sign_on_service_for(binding: :http_post)).to eql(
 84        Saml::Kit::Bindings::HttpPost.new(location: sign_on_service)
 85      )
 86    end
 87  end
 88
 89  it { expect(subject.want_authn_requests_signed).to be_truthy }
 90  it { expect(subject.attributes).to match_array([name: 'id', format: nil]) }
 91  it { expect(subject.login_request_for(binding: :http_post)).to be_present }
 92
 93  it do
 94    expect(subject.assertion_consumer_services).to match_array([
 95      Saml::Kit::Bindings::HttpPost.new(location: assertion_consumer_service)
 96    ])
 97  end
 98
 99  it do
100    expect(subject.assertion_consumer_service_for(binding: :http_post)).to eql(
101      Saml::Kit::Bindings::HttpPost.new(location: assertion_consumer_service)
102    )
103  end
104
105  it { expect(subject.want_assertions_signed).to be_truthy }
106  it { expect(subject.entity_id).to eql(entity_id) }
107  it { expect(subject.name_id_formats).to match_array([Saml::Kit::Namespaces::PERSISTENT]) }
108
109  it do
110    expect(subject.certificates).to match_array([
111      sp_signing_certificate,
112      sp_encryption_certificate,
113      idp_signing_certificate,
114      idp_encryption_certificate,
115    ])
116  end
117
118  it do
119    expect(subject.encryption_certificates).to match_array([
120      sp_encryption_certificate,
121      idp_encryption_certificate,
122    ])
123  end
124
125  it do
126    expect(subject.signing_certificates).to match_array([
127      sp_signing_certificate,
128      idp_signing_certificate,
129    ])
130  end
131
132  it do
133    expect(subject.services('SingleLogoutService')).to match_array([
134      Saml::Kit::Bindings::HttpPost.new(location: sp_logout_service),
135      Saml::Kit::Bindings::HttpPost.new(location: idp_logout_service),
136    ])
137  end
138
139  it do
140    expect(subject.service_for(type: 'SingleLogoutService', binding: :http_post)).to eql(
141      Saml::Kit::Bindings::HttpPost.new(location: sp_logout_service)
142    )
143  end
144
145  it do
146    expect(subject.services('AssertionConsumerService')).to match_array([
147      Saml::Kit::Bindings::HttpPost.new(location: assertion_consumer_service),
148    ])
149  end
150
151  it do
152    expect(subject.service_for(type: 'AssertionConsumerService', binding: :http_post)).to eql(
153      Saml::Kit::Bindings::HttpPost.new(location: assertion_consumer_service)
154    )
155  end
156
157  it do
158    expect(subject.services('SingleSignOnService')).to match_array([
159      Saml::Kit::Bindings::HttpPost.new(location: sign_on_service),
160      Saml::Kit::Bindings::HttpRedirect.new(location: sign_on_service),
161    ])
162  end
163
164  it do
165    expect(subject.service_for(type: 'SingleSignOnService', binding: :http_post)).to eql(
166      Saml::Kit::Bindings::HttpPost.new(location: sign_on_service)
167    )
168  end
169
170  it do
171    expect(subject.single_logout_services).to match_array([
172      Saml::Kit::Bindings::HttpPost.new(location: sp_logout_service),
173      Saml::Kit::Bindings::HttpPost.new(location: idp_logout_service),
174    ])
175  end
176
177  it do
178    expect(subject.single_logout_service_for(binding: :http_post)).to eql(
179      Saml::Kit::Bindings::HttpPost.new(location: sp_logout_service)
180    )
181  end
182
183  specify { expect(subject.logout_request_for(User.new)).to be_present }
184end