main
1# frozen_string_literal: true
2
3RSpec.describe Saml::Kit::DefaultRegistry do
4 subject { described_class.new }
5
6 let(:entity_id) { FFaker::Internet.http_url }
7 let(:service_provider_metadata) do
8 Saml::Kit::ServiceProviderMetadata.build do |builder|
9 builder.entity_id = entity_id
10 builder.add_assertion_consumer_service(FFaker::Internet.uri('https'), binding: :http_post)
11 end
12 end
13 let(:identity_provider_metadata) do
14 Saml::Kit::IdentityProviderMetadata.build do |builder|
15 builder.entity_id = entity_id
16 builder.add_single_sign_on_service(FFaker::Internet.uri('https'), binding: :http_post)
17 end
18 end
19
20 describe '#metadata_for' do
21 it 'returns the metadata for the entity_id' do
22 subject.register(service_provider_metadata)
23 expect(subject.metadata_for(entity_id)).to eql(service_provider_metadata)
24 end
25 end
26
27 describe '#register_url' do
28 let(:url) { FFaker::Internet.http_url }
29
30 it 'fetches the SP metadata from a remote url and registers it' do
31 stub_request(:get, url)
32 .to_return(status: 200, body: service_provider_metadata.to_xml)
33 subject.register_url(url)
34
35 result = subject.metadata_for(entity_id)
36 expect(result).to be_present
37 expect(result).to be_instance_of(Saml::Kit::ServiceProviderMetadata)
38 end
39
40 it 'fetches the IDP metadata from a remote url' do
41 stub_request(:get, url)
42 .to_return(status: 200, body: identity_provider_metadata.to_xml)
43 subject.register_url(url)
44
45 result = subject.metadata_for(entity_id)
46 expect(result).to be_present
47 expect(result).to be_instance_of(Saml::Kit::IdentityProviderMetadata)
48 end
49
50 it 'registers metadata that serves as both an IDP and SP' do
51 xml = <<-XML.strip_heredoc
52 <EntityDescriptor xmlns="#{Saml::Kit::Namespaces::METADATA}" ID="#{::Xml::Kit::Id.generate}" entityID="#{entity_id}">
53 <SPSSODescriptor AuthnRequestsSigned="false" WantAssertionsSigned="true" protocolSupportEnumeration="#{Saml::Kit::Namespaces::PROTOCOL}">
54 <SingleLogoutService Binding="#{Saml::Kit::Bindings::HTTP_POST}" Location="#{FFaker::Internet.uri('https')}"/>
55 <NameIDFormat>#{Saml::Kit::Namespaces::PERSISTENT}</NameIDFormat>
56 <AssertionConsumerService Binding="#{Saml::Kit::Bindings::HTTP_POST}" Location="#{FFaker::Internet.uri('https')}" index="0" isDefault="true"/>
57 </SPSSODescriptor>
58 <IDPSSODescriptor WantAuthnRequestsSigned="true" protocolSupportEnumeration="#{Saml::Kit::Namespaces::PROTOCOL}">
59 <SingleLogoutService Binding="#{Saml::Kit::Bindings::HTTP_POST}" Location="#{FFaker::Internet.uri('https')}"/>
60 <NameIDFormat>#{Saml::Kit::Namespaces::PERSISTENT}</NameIDFormat>
61 <SingleSignOnService Binding="#{Saml::Kit::Bindings::HTTP_POST}" Location="#{FFaker::Internet.uri('https')}"/>
62 <SingleSignOnService Binding="#{Saml::Kit::Bindings::HTTP_REDIRECT}" Location="#{FFaker::Internet.uri('https')}"/>
63 </IDPSSODescriptor>
64 <Organization>
65 <OrganizationName xml:lang="en">Acme, Inc</OrganizationName>
66 <OrganizationDisplayName xml:lang="en">Acme, Inc</OrganizationDisplayName>
67 <OrganizationURL xml:lang="en">http://localhost:5000/</OrganizationURL>
68 </Organization>
69 <ContactPerson contactType="technical">
70 <Company>mailto:hi@example.com</Company>
71 </ContactPerson>
72 </EntityDescriptor>
73 XML
74 stub_request(:get, url).to_return(status: 200, body: xml)
75 subject.register_url(url)
76
77 result = subject.metadata_for(entity_id)
78 expect(result).to be_present
79 expect(result).to be_instance_of(Saml::Kit::CompositeMetadata)
80 end
81 end
82
83 describe '#register' do
84 it 'registers the metadata' do
85 metadata = Saml::Kit::IdentityProviderMetadata.build do |xxx|
86 xxx.entity_id = FFaker::Internet.uri('https')
87 xxx.add_single_sign_on_service(FFaker::Internet.uri('https'), binding: :http_post)
88 end
89 subject.register(metadata)
90 expect(subject.metadata_for(metadata.entity_id)).to eql(metadata)
91 end
92
93 it 'raises an error when the metadata is invalid' do
94 expect do
95 subject.register(Saml::Kit::IdentityProviderMetadata.build)
96 end.to raise_error(/Cannot register invalid metadata/)
97 end
98
99 it 'raises an error when the document is not a metadata' do
100 authn_request = Saml::Kit::AuthenticationRequest.build
101 allow(authn_request).to receive(:valid?).and_return(true)
102
103 expect do
104 subject.register(authn_request)
105 end.to raise_error(/Cannot register invalid metadata/)
106 end
107
108 it 'raises an error when the document is nil' do
109 expect do
110 subject.register(nil)
111 end.to raise_error(/Cannot register invalid metadata/)
112 end
113 end
114
115 describe '#each' do
116 it 'yields each registered metadata' do
117 idp = Saml::Kit::IdentityProviderMetadata.build do |xxx|
118 xxx.entity_id = 'idp'
119 xxx.add_single_sign_on_service(FFaker::Internet.uri('https'), binding: :http_post)
120 end
121 sp = Saml::Kit::ServiceProviderMetadata.build do |xxx|
122 xxx.entity_id = 'sp'
123 xxx.add_assertion_consumer_service(FFaker::Internet.uri('https'), binding: :http_post)
124 end
125
126 subject.register(idp)
127 subject.register(sp)
128
129 expect(subject.map(&:to_xml)).to match_array([idp.to_xml, sp.to_xml])
130 end
131 end
132end