Commit 0e1afd6
Changed files (8)
spec/saml/kit/assertion_spec.rb
@@ -11,28 +11,28 @@ RSpec.describe Saml::Kit::Assertion do
now = Time.current
travel_to now
not_on_or_after = configuration.session_timeout.since(now).iso8601
- xml = <<-XML
-<Response>
-<Assertion xmlns="#{Saml::Kit::Namespaces::ASSERTION}" ID="#{Xml::Kit::Id.generate}" IssueInstant="#{now.iso8601}" Version="2.0">
- <Issuer>#{FFaker::Internet.uri('https')}</Issuer>
- <Subject>
- <NameID Format="#{Saml::Kit::Namespaces::PERSISTENT}">#{SecureRandom.uuid}</NameID>
- <SubjectConfirmation Method="#{Saml::Kit::Namespaces::BEARER}">
- <SubjectConfirmationData InResponseTo="#{SecureRandom.uuid}" NotOnOrAfter="#{not_on_or_after}" Recipient="#{FFaker::Internet.uri('https')}"/>
- </SubjectConfirmation>
- </Subject>
- <Conditions NotBefore="#{now.utc.iso8601}" NotOnOrAfter="#{not_on_or_after}">
- <AudienceRestriction>
- <Audience>#{FFaker::Internet.uri('https')}</Audience>
- </AudienceRestriction>
- </Conditions>
- <AuthnStatement AuthnInstant="#{now.utc.iso8601}" SessionIndex="#{Xml::Kit::Id.generate}" SessionNotOnOrAfter="#{not_on_or_after}">
- <AuthnContext>
- <AuthnContextClassRef>#{Saml::Kit::Namespaces::PASSWORD}</AuthnContextClassRef>
- </AuthnContext>
- </AuthnStatement>
-</Assertion>
-</Response>
+ xml = <<-XML.strip_heredoc
+ <Response>
+ <Assertion xmlns="#{Saml::Kit::Namespaces::ASSERTION}" ID="#{Xml::Kit::Id.generate}" IssueInstant="#{now.iso8601}" Version="2.0">
+ <Issuer>#{FFaker::Internet.uri('https')}</Issuer>
+ <Subject>
+ <NameID Format="#{Saml::Kit::Namespaces::PERSISTENT}">#{SecureRandom.uuid}</NameID>
+ <SubjectConfirmation Method="#{Saml::Kit::Namespaces::BEARER}">
+ <SubjectConfirmationData InResponseTo="#{SecureRandom.uuid}" NotOnOrAfter="#{not_on_or_after}" Recipient="#{FFaker::Internet.uri('https')}"/>
+ </SubjectConfirmation>
+ </Subject>
+ <Conditions NotBefore="#{now.utc.iso8601}" NotOnOrAfter="#{not_on_or_after}">
+ <AudienceRestriction>
+ <Audience>#{FFaker::Internet.uri('https')}</Audience>
+ </AudienceRestriction>
+ </Conditions>
+ <AuthnStatement AuthnInstant="#{now.utc.iso8601}" SessionIndex="#{Xml::Kit::Id.generate}" SessionNotOnOrAfter="#{not_on_or_after}">
+ <AuthnContext>
+ <AuthnContextClassRef>#{Saml::Kit::Namespaces::PASSWORD}</AuthnContextClassRef>
+ </AuthnContext>
+ </AuthnStatement>
+ </Assertion>
+ </Response>
XML
subject = described_class.new(Nokogiri::XML(xml), configuration: configuration)
travel_to (configuration.clock_drift - 1.second).before(now)
@@ -46,28 +46,28 @@ XML
travel_to now
not_before = now.utc.iso8601
not_after = configuration.session_timeout.since(now).iso8601
- xml = <<-XML
-<Response>
-<Assertion xmlns="#{Saml::Kit::Namespaces::ASSERTION}" ID="#{Xml::Kit::Id.generate}" IssueInstant="#{now.iso8601}" Version="2.0">
- <Issuer>#{FFaker::Internet.uri('https')}</Issuer>
- <Subject>
- <NameID Format="#{Saml::Kit::Namespaces::PERSISTENT}">#{SecureRandom.uuid}</NameID>
- <SubjectConfirmation Method="#{Saml::Kit::Namespaces::BEARER}">
- <SubjectConfirmationData InResponseTo="#{SecureRandom.uuid}" NotOnOrAfter="#{not_after}" Recipient="#{FFaker::Internet.uri('https')}"/>
- </SubjectConfirmation>
- </Subject>
- <Conditions NotBefore="#{not_before}" NotOnOrAfter="#{not_after}">
- <AudienceRestriction>
- <Audience>#{FFaker::Internet.uri('https')}</Audience>
- </AudienceRestriction>
- </Conditions>
- <AuthnStatement AuthnInstant="#{now.utc.iso8601}" SessionIndex="#{Xml::Kit::Id.generate}" SessionNotOnOrAfter="#{not_after}">
- <AuthnContext>
- <AuthnContextClassRef>#{Saml::Kit::Namespaces::PASSWORD}</AuthnContextClassRef>
- </AuthnContext>
- </AuthnStatement>
-</Assertion>
-</Response>
+ xml = <<-XML.strip_heredoc
+ <Response>
+ <Assertion xmlns="#{Saml::Kit::Namespaces::ASSERTION}" ID="#{Xml::Kit::Id.generate}" IssueInstant="#{now.iso8601}" Version="2.0">
+ <Issuer>#{FFaker::Internet.uri('https')}</Issuer>
+ <Subject>
+ <NameID Format="#{Saml::Kit::Namespaces::PERSISTENT}">#{SecureRandom.uuid}</NameID>
+ <SubjectConfirmation Method="#{Saml::Kit::Namespaces::BEARER}">
+ <SubjectConfirmationData InResponseTo="#{SecureRandom.uuid}" NotOnOrAfter="#{not_after}" Recipient="#{FFaker::Internet.uri('https')}"/>
+ </SubjectConfirmation>
+ </Subject>
+ <Conditions NotBefore="#{not_before}" NotOnOrAfter="#{not_after}">
+ <AudienceRestriction>
+ <Audience>#{FFaker::Internet.uri('https')}</Audience>
+ </AudienceRestriction>
+ </Conditions>
+ <AuthnStatement AuthnInstant="#{now.utc.iso8601}" SessionIndex="#{Xml::Kit::Id.generate}" SessionNotOnOrAfter="#{not_after}">
+ <AuthnContext>
+ <AuthnContextClassRef>#{Saml::Kit::Namespaces::PASSWORD}</AuthnContextClassRef>
+ </AuthnContext>
+ </AuthnStatement>
+ </Assertion>
+ </Response>
XML
subject = described_class.new(Nokogiri::XML(xml), configuration: configuration)
expect(subject).to be_active
@@ -84,28 +84,28 @@ XML
it 'returns true when the assertion is present' do
not_before = Time.now.utc.iso8601
not_after = 10.minutes.from_now.iso8601
- xml = <<-XML
-<Response>
-<Assertion xmlns="#{Saml::Kit::Namespaces::ASSERTION}" ID="#{Xml::Kit::Id.generate}" IssueInstant="#{Time.now.iso8601}" Version="2.0">
- <Issuer>#{FFaker::Internet.uri('https')}</Issuer>
- <Subject>
- <NameID Format="#{Saml::Kit::Namespaces::PERSISTENT}">#{SecureRandom.uuid}</NameID>
- <SubjectConfirmation Method="#{Saml::Kit::Namespaces::BEARER}">
- <SubjectConfirmationData InResponseTo="#{SecureRandom.uuid}" NotOnOrAfter="#{not_after}" Recipient="#{FFaker::Internet.uri('https')}"/>
- </SubjectConfirmation>
- </Subject>
- <Conditions NotBefore="#{not_before}" NotOnOrAfter="#{not_after}">
- <AudienceRestriction>
- <Audience>#{FFaker::Internet.uri('https')}</Audience>
- </AudienceRestriction>
- </Conditions>
- <AuthnStatement AuthnInstant="#{Time.now.utc.iso8601}" SessionIndex="#{Xml::Kit::Id.generate}" SessionNotOnOrAfter="#{not_after}">
- <AuthnContext>
- <AuthnContextClassRef>#{Saml::Kit::Namespaces::PASSWORD}</AuthnContextClassRef>
- </AuthnContext>
- </AuthnStatement>
-</Assertion>
-</Response>
+ xml = <<-XML.strip_heredoc
+ <Response>
+ <Assertion xmlns="#{Saml::Kit::Namespaces::ASSERTION}" ID="#{Xml::Kit::Id.generate}" IssueInstant="#{Time.now.iso8601}" Version="2.0">
+ <Issuer>#{FFaker::Internet.uri('https')}</Issuer>
+ <Subject>
+ <NameID Format="#{Saml::Kit::Namespaces::PERSISTENT}">#{SecureRandom.uuid}</NameID>
+ <SubjectConfirmation Method="#{Saml::Kit::Namespaces::BEARER}">
+ <SubjectConfirmationData InResponseTo="#{SecureRandom.uuid}" NotOnOrAfter="#{not_after}" Recipient="#{FFaker::Internet.uri('https')}"/>
+ </SubjectConfirmation>
+ </Subject>
+ <Conditions NotBefore="#{not_before}" NotOnOrAfter="#{not_after}">
+ <AudienceRestriction>
+ <Audience>#{FFaker::Internet.uri('https')}</Audience>
+ </AudienceRestriction>
+ </Conditions>
+ <AuthnStatement AuthnInstant="#{Time.now.utc.iso8601}" SessionIndex="#{Xml::Kit::Id.generate}" SessionNotOnOrAfter="#{not_after}">
+ <AuthnContext>
+ <AuthnContextClassRef>#{Saml::Kit::Namespaces::PASSWORD}</AuthnContextClassRef>
+ </AuthnContext>
+ </AuthnStatement>
+ </Assertion>
+ </Response>
XML
subject = described_class.new(Nokogiri::XML(xml))
expect(subject).to be_present
spec/saml/kit/authentication_request_spec.rb
@@ -95,11 +95,11 @@ RSpec.describe Saml::Kit::AuthenticationRequest do
it 'validates a request without a signature' do
now = Time.now.utc
- raw_xml = <<-XML
-<samlp:AuthnRequest AssertionConsumerServiceURL='#{assertion_consumer_service_url}' ID='#{Xml::Kit::Id.generate}' IssueInstant='#{now.iso8601}' Version='2.0' xmlns:saml='#{Saml::Kit::Namespaces::ASSERTION}' xmlns:samlp='#{Saml::Kit::Namespaces::PROTOCOL}'>
- <saml:Issuer>#{issuer}</saml:Issuer>
- <samlp:NameIDPolicy AllowCreate='true' Format='#{Saml::Kit::Namespaces::EMAIL_ADDRESS}'/>
-</samlp:AuthnRequest>
+ raw_xml = <<-XML.strip_heredoc
+ <samlp:AuthnRequest AssertionConsumerServiceURL='#{assertion_consumer_service_url}' ID='#{Xml::Kit::Id.generate}' IssueInstant='#{now.iso8601}' Version='2.0' xmlns:saml='#{Saml::Kit::Namespaces::ASSERTION}' xmlns:samlp='#{Saml::Kit::Namespaces::PROTOCOL}'>
+ <saml:Issuer>#{issuer}</saml:Issuer>
+ <samlp:NameIDPolicy AllowCreate='true' Format='#{Saml::Kit::Namespaces::EMAIL_ADDRESS}'/>
+ </samlp:AuthnRequest>
XML
subject = described_class.new(raw_xml, configuration: configuration)
@@ -109,11 +109,11 @@ RSpec.describe Saml::Kit::AuthenticationRequest do
it 'is valid when there is no signature, and the issuer is registered' do
now = Time.now.utc
- raw_xml = <<-XML
-<samlp:AuthnRequest AssertionConsumerServiceURL='#{assertion_consumer_service_url}' ID='#{Xml::Kit::Id.generate}' IssueInstant='#{now.iso8601}' Version='2.0' xmlns:saml='#{Saml::Kit::Namespaces::ASSERTION}' xmlns:samlp='#{Saml::Kit::Namespaces::PROTOCOL}'>
- <saml:Issuer>#{issuer}</saml:Issuer>
- <samlp:NameIDPolicy AllowCreate='true' Format='#{Saml::Kit::Namespaces::PERSISTENT}'/>
-</samlp:AuthnRequest>
+ raw_xml = <<-XML.strip_heredoc
+ <samlp:AuthnRequest AssertionConsumerServiceURL='#{assertion_consumer_service_url}' ID='#{Xml::Kit::Id.generate}' IssueInstant='#{now.iso8601}' Version='2.0' xmlns:saml='#{Saml::Kit::Namespaces::ASSERTION}' xmlns:samlp='#{Saml::Kit::Namespaces::PROTOCOL}'>
+ <saml:Issuer>#{issuer}</saml:Issuer>
+ <samlp:NameIDPolicy AllowCreate='true' Format='#{Saml::Kit::Namespaces::PERSISTENT}'/>
+ </samlp:AuthnRequest>
XML
allow(registry).to receive(:metadata_for).with(issuer).and_return(metadata)
@@ -123,11 +123,11 @@ RSpec.describe Saml::Kit::AuthenticationRequest do
it 'is invalid when there is no signature, and the issuer is not registered' do
now = Time.now.utc
- raw_xml = <<-XML
-<samlp:AuthnRequest AssertionConsumerServiceURL='#{assertion_consumer_service_url}' ID='#{Xml::Kit::Id.generate}' IssueInstant='#{now.iso8601}' Version='2.0' xmlns:saml='#{Saml::Kit::Namespaces::ASSERTION}' xmlns:samlp='#{Saml::Kit::Namespaces::PROTOCOL}'>
- <saml:Issuer>#{issuer}</saml:Issuer>
- <samlp:NameIDPolicy AllowCreate='true' Format='#{Saml::Kit::Namespaces::PERSISTENT}'/>
-</samlp:AuthnRequest>
+ raw_xml = <<-XML.strip_heredoc
+ <samlp:AuthnRequest AssertionConsumerServiceURL='#{assertion_consumer_service_url}' ID='#{Xml::Kit::Id.generate}' IssueInstant='#{now.iso8601}' Version='2.0' xmlns:saml='#{Saml::Kit::Namespaces::ASSERTION}' xmlns:samlp='#{Saml::Kit::Namespaces::PROTOCOL}'>
+ <saml:Issuer>#{issuer}</saml:Issuer>
+ <samlp:NameIDPolicy AllowCreate='true' Format='#{Saml::Kit::Namespaces::PERSISTENT}'/>
+ </samlp:AuthnRequest>
XML
allow(registry).to receive(:metadata_for).with(issuer).and_return(nil)
spec/saml/kit/composite_metadata_spec.rb
@@ -13,57 +13,57 @@ RSpec.describe Saml::Kit::CompositeMetadata do
let(:idp_signing_certificate) { ::Xml::Kit::KeyPair.generate(use: :signing).certificate }
let(:idp_encryption_certificate) { ::Xml::Kit::KeyPair.generate(use: :encryption).certificate }
let(:xml) do
- <<-XML
-<EntityDescriptor xmlns="#{Saml::Kit::Namespaces::METADATA}" ID="#{::Xml::Kit::Id.generate}" entityID="#{entity_id}">
- <SPSSODescriptor AuthnRequestsSigned="false" WantAssertionsSigned="true" protocolSupportEnumeration="#{Saml::Kit::Namespaces::PROTOCOL}">
- <KeyDescriptor use="signing">
- <KeyInfo xmlns="#{::Xml::Kit::Namespaces::XMLDSIG}">
- <X509Data>
- <X509Certificate>#{sp_signing_certificate.stripped}</X509Certificate>
- </X509Data>
- </KeyInfo>
- </KeyDescriptor>
- <KeyDescriptor use="encryption">
- <KeyInfo xmlns="#{::Xml::Kit::Namespaces::XMLDSIG}">
- <X509Data>
- <X509Certificate>#{sp_encryption_certificate.stripped}</X509Certificate>
- </X509Data>
- </KeyInfo>
- </KeyDescriptor>
- <SingleLogoutService Binding="#{post_binding}" Location="#{sp_logout_service}"/>
- <NameIDFormat>#{Saml::Kit::Namespaces::PERSISTENT}</NameIDFormat>
- <AssertionConsumerService Binding="#{post_binding}" Location="#{assertion_consumer_service}" index="0" isDefault="true"/>
- </SPSSODescriptor>
- <IDPSSODescriptor WantAuthnRequestsSigned="true" protocolSupportEnumeration="#{Saml::Kit::Namespaces::PROTOCOL}">
- <KeyDescriptor use="signing">
- <KeyInfo xmlns="#{::Xml::Kit::Namespaces::XMLDSIG}">
- <X509Data>
- <X509Certificate>#{idp_signing_certificate.stripped}</X509Certificate>
- </X509Data>
- </KeyInfo>
- </KeyDescriptor>
- <KeyDescriptor use="encryption">
- <KeyInfo xmlns="#{::Xml::Kit::Namespaces::XMLDSIG}">
- <X509Data>
- <X509Certificate>#{idp_encryption_certificate.stripped}</X509Certificate>
- </X509Data>
- </KeyInfo>
- </KeyDescriptor>
- <SingleLogoutService Binding="#{post_binding}" Location="#{idp_logout_service}"/>
- <NameIDFormat>#{Saml::Kit::Namespaces::PERSISTENT}</NameIDFormat>
- <SingleSignOnService Binding="#{post_binding}" Location="#{sign_on_service}"/>
- <SingleSignOnService Binding="#{redirect_binding}" Location="#{sign_on_service}"/>
- <Attribute xmlns="#{Saml::Kit::Namespaces::ASSERTION}" Name="id" ></Attribute>
- </IDPSSODescriptor>
- <Organization>
- <OrganizationName xml:lang="en">Acme, Inc</OrganizationName>
- <OrganizationDisplayName xml:lang="en">Acme, Inc</OrganizationDisplayName>
- <OrganizationURL xml:lang="en">http://localhost:5000/</OrganizationURL>
- </Organization>
- <ContactPerson contactType="technical">
- <Company>mailto:hi@example.com</Company>
- </ContactPerson>
-</EntityDescriptor>
+ <<-XML.strip_heredoc
+ <EntityDescriptor xmlns="#{Saml::Kit::Namespaces::METADATA}" ID="#{::Xml::Kit::Id.generate}" entityID="#{entity_id}">
+ <SPSSODescriptor AuthnRequestsSigned="false" WantAssertionsSigned="true" protocolSupportEnumeration="#{Saml::Kit::Namespaces::PROTOCOL}">
+ <KeyDescriptor use="signing">
+ <KeyInfo xmlns="#{::Xml::Kit::Namespaces::XMLDSIG}">
+ <X509Data>
+ <X509Certificate>#{sp_signing_certificate.stripped}</X509Certificate>
+ </X509Data>
+ </KeyInfo>
+ </KeyDescriptor>
+ <KeyDescriptor use="encryption">
+ <KeyInfo xmlns="#{::Xml::Kit::Namespaces::XMLDSIG}">
+ <X509Data>
+ <X509Certificate>#{sp_encryption_certificate.stripped}</X509Certificate>
+ </X509Data>
+ </KeyInfo>
+ </KeyDescriptor>
+ <SingleLogoutService Binding="#{post_binding}" Location="#{sp_logout_service}"/>
+ <NameIDFormat>#{Saml::Kit::Namespaces::PERSISTENT}</NameIDFormat>
+ <AssertionConsumerService Binding="#{post_binding}" Location="#{assertion_consumer_service}" index="0" isDefault="true"/>
+ </SPSSODescriptor>
+ <IDPSSODescriptor WantAuthnRequestsSigned="true" protocolSupportEnumeration="#{Saml::Kit::Namespaces::PROTOCOL}">
+ <KeyDescriptor use="signing">
+ <KeyInfo xmlns="#{::Xml::Kit::Namespaces::XMLDSIG}">
+ <X509Data>
+ <X509Certificate>#{idp_signing_certificate.stripped}</X509Certificate>
+ </X509Data>
+ </KeyInfo>
+ </KeyDescriptor>
+ <KeyDescriptor use="encryption">
+ <KeyInfo xmlns="#{::Xml::Kit::Namespaces::XMLDSIG}">
+ <X509Data>
+ <X509Certificate>#{idp_encryption_certificate.stripped}</X509Certificate>
+ </X509Data>
+ </KeyInfo>
+ </KeyDescriptor>
+ <SingleLogoutService Binding="#{post_binding}" Location="#{idp_logout_service}"/>
+ <NameIDFormat>#{Saml::Kit::Namespaces::PERSISTENT}</NameIDFormat>
+ <SingleSignOnService Binding="#{post_binding}" Location="#{sign_on_service}"/>
+ <SingleSignOnService Binding="#{redirect_binding}" Location="#{sign_on_service}"/>
+ <Attribute xmlns="#{Saml::Kit::Namespaces::ASSERTION}" Name="id" ></Attribute>
+ </IDPSSODescriptor>
+ <Organization>
+ <OrganizationName xml:lang="en">Acme, Inc</OrganizationName>
+ <OrganizationDisplayName xml:lang="en">Acme, Inc</OrganizationDisplayName>
+ <OrganizationURL xml:lang="en">http://localhost:5000/</OrganizationURL>
+ </Organization>
+ <ContactPerson contactType="technical">
+ <Company>mailto:hi@example.com</Company>
+ </ContactPerson>
+ </EntityDescriptor>
XML
end
spec/saml/kit/default_registry_spec.rb
@@ -44,28 +44,28 @@ RSpec.describe Saml::Kit::DefaultRegistry do
end
it 'registers metadata that serves as both an IDP and SP' do
- xml = <<-XML
-<EntityDescriptor xmlns="#{Saml::Kit::Namespaces::METADATA}" ID="#{::Xml::Kit::Id.generate}" entityID="#{entity_id}">
- <SPSSODescriptor AuthnRequestsSigned="false" WantAssertionsSigned="true" protocolSupportEnumeration="#{Saml::Kit::Namespaces::PROTOCOL}">
- <SingleLogoutService Binding="#{Saml::Kit::Bindings::HTTP_POST}" Location="#{FFaker::Internet.uri('https')}"/>
- <NameIDFormat>#{Saml::Kit::Namespaces::PERSISTENT}</NameIDFormat>
- <AssertionConsumerService Binding="#{Saml::Kit::Bindings::HTTP_POST}" Location="#{FFaker::Internet.uri('https')}" index="0" isDefault="true"/>
- </SPSSODescriptor>
- <IDPSSODescriptor WantAuthnRequestsSigned="true" protocolSupportEnumeration="#{Saml::Kit::Namespaces::PROTOCOL}">
- <SingleLogoutService Binding="#{Saml::Kit::Bindings::HTTP_POST}" Location="#{FFaker::Internet.uri('https')}"/>
- <NameIDFormat>#{Saml::Kit::Namespaces::PERSISTENT}</NameIDFormat>
- <SingleSignOnService Binding="#{Saml::Kit::Bindings::HTTP_POST}" Location="#{FFaker::Internet.uri('https')}"/>
- <SingleSignOnService Binding="#{Saml::Kit::Bindings::HTTP_REDIRECT}" Location="#{FFaker::Internet.uri('https')}"/>
- </IDPSSODescriptor>
- <Organization>
- <OrganizationName xml:lang="en">Acme, Inc</OrganizationName>
- <OrganizationDisplayName xml:lang="en">Acme, Inc</OrganizationDisplayName>
- <OrganizationURL xml:lang="en">http://localhost:5000/</OrganizationURL>
- </Organization>
- <ContactPerson contactType="technical">
- <Company>mailto:hi@example.com</Company>
- </ContactPerson>
-</EntityDescriptor>
+ xml = <<-XML.strip_heredoc
+ <EntityDescriptor xmlns="#{Saml::Kit::Namespaces::METADATA}" ID="#{::Xml::Kit::Id.generate}" entityID="#{entity_id}">
+ <SPSSODescriptor AuthnRequestsSigned="false" WantAssertionsSigned="true" protocolSupportEnumeration="#{Saml::Kit::Namespaces::PROTOCOL}">
+ <SingleLogoutService Binding="#{Saml::Kit::Bindings::HTTP_POST}" Location="#{FFaker::Internet.uri('https')}"/>
+ <NameIDFormat>#{Saml::Kit::Namespaces::PERSISTENT}</NameIDFormat>
+ <AssertionConsumerService Binding="#{Saml::Kit::Bindings::HTTP_POST}" Location="#{FFaker::Internet.uri('https')}" index="0" isDefault="true"/>
+ </SPSSODescriptor>
+ <IDPSSODescriptor WantAuthnRequestsSigned="true" protocolSupportEnumeration="#{Saml::Kit::Namespaces::PROTOCOL}">
+ <SingleLogoutService Binding="#{Saml::Kit::Bindings::HTTP_POST}" Location="#{FFaker::Internet.uri('https')}"/>
+ <NameIDFormat>#{Saml::Kit::Namespaces::PERSISTENT}</NameIDFormat>
+ <SingleSignOnService Binding="#{Saml::Kit::Bindings::HTTP_POST}" Location="#{FFaker::Internet.uri('https')}"/>
+ <SingleSignOnService Binding="#{Saml::Kit::Bindings::HTTP_REDIRECT}" Location="#{FFaker::Internet.uri('https')}"/>
+ </IDPSSODescriptor>
+ <Organization>
+ <OrganizationName xml:lang="en">Acme, Inc</OrganizationName>
+ <OrganizationDisplayName xml:lang="en">Acme, Inc</OrganizationDisplayName>
+ <OrganizationURL xml:lang="en">http://localhost:5000/</OrganizationURL>
+ </Organization>
+ <ContactPerson contactType="technical">
+ <Company>mailto:hi@example.com</Company>
+ </ContactPerson>
+ </EntityDescriptor>
XML
stub_request(:get, url).to_return(status: 200, body: xml)
subject.register_url(url)
spec/saml/kit/metadata_spec.rb
@@ -13,28 +13,28 @@ RSpec.describe Saml::Kit::Metadata do
end
it 'returns a composite' do
- xml = <<-XML
-<EntityDescriptor xmlns="#{Saml::Kit::Namespaces::METADATA}" ID="#{Xml::Kit::Id.generate}" entityID="#{FFaker::Internet.uri('https')}">
- <SPSSODescriptor AuthnRequestsSigned="false" WantAssertionsSigned="true" protocolSupportEnumeration="#{Saml::Kit::Namespaces::PROTOCOL}">
- <SingleLogoutService Binding="#{Saml::Kit::Bindings::HTTP_POST}" Location="#{FFaker::Internet.uri('https')}"/>
- <NameIDFormat>#{Saml::Kit::Namespaces::PERSISTENT}</NameIDFormat>
- <AssertionConsumerService Binding="#{Saml::Kit::Bindings::HTTP_POST}" Location="#{FFaker::Internet.uri('https')}" index="0" isDefault="true"/>
- </SPSSODescriptor>
- <IDPSSODescriptor WantAuthnRequestsSigned="true" protocolSupportEnumeration="#{Saml::Kit::Namespaces::PROTOCOL}">
- <SingleLogoutService Binding="#{Saml::Kit::Bindings::HTTP_POST}" Location="#{FFaker::Internet.uri('https')}"/>
- <NameIDFormat>#{Saml::Kit::Namespaces::PERSISTENT}</NameIDFormat>
- <SingleSignOnService Binding="#{Saml::Kit::Bindings::HTTP_POST}" Location="#{FFaker::Internet.uri('https')}"/>
- <SingleSignOnService Binding="#{Saml::Kit::Bindings::HTTP_REDIRECT}" Location="#{FFaker::Internet.uri('https')}"/>
- </IDPSSODescriptor>
- <Organization>
- <OrganizationName xml:lang="en">Acme, Inc</OrganizationName>
- <OrganizationDisplayName xml:lang="en">Acme, Inc</OrganizationDisplayName>
- <OrganizationURL xml:lang="en">http://localhost:5000/</OrganizationURL>
- </Organization>
- <ContactPerson contactType="technical">
- <Company>mailto:hi@example.com</Company>
- </ContactPerson>
-</EntityDescriptor>
+ xml = <<-XML.strip_heredoc
+ <EntityDescriptor xmlns="#{Saml::Kit::Namespaces::METADATA}" ID="#{Xml::Kit::Id.generate}" entityID="#{FFaker::Internet.uri('https')}">
+ <SPSSODescriptor AuthnRequestsSigned="false" WantAssertionsSigned="true" protocolSupportEnumeration="#{Saml::Kit::Namespaces::PROTOCOL}">
+ <SingleLogoutService Binding="#{Saml::Kit::Bindings::HTTP_POST}" Location="#{FFaker::Internet.uri('https')}"/>
+ <NameIDFormat>#{Saml::Kit::Namespaces::PERSISTENT}</NameIDFormat>
+ <AssertionConsumerService Binding="#{Saml::Kit::Bindings::HTTP_POST}" Location="#{FFaker::Internet.uri('https')}" index="0" isDefault="true"/>
+ </SPSSODescriptor>
+ <IDPSSODescriptor WantAuthnRequestsSigned="true" protocolSupportEnumeration="#{Saml::Kit::Namespaces::PROTOCOL}">
+ <SingleLogoutService Binding="#{Saml::Kit::Bindings::HTTP_POST}" Location="#{FFaker::Internet.uri('https')}"/>
+ <NameIDFormat>#{Saml::Kit::Namespaces::PERSISTENT}</NameIDFormat>
+ <SingleSignOnService Binding="#{Saml::Kit::Bindings::HTTP_POST}" Location="#{FFaker::Internet.uri('https')}"/>
+ <SingleSignOnService Binding="#{Saml::Kit::Bindings::HTTP_REDIRECT}" Location="#{FFaker::Internet.uri('https')}"/>
+ </IDPSSODescriptor>
+ <Organization>
+ <OrganizationName xml:lang="en">Acme, Inc</OrganizationName>
+ <OrganizationDisplayName xml:lang="en">Acme, Inc</OrganizationDisplayName>
+ <OrganizationURL xml:lang="en">http://localhost:5000/</OrganizationURL>
+ </Organization>
+ <ContactPerson contactType="technical">
+ <Company>mailto:hi@example.com</Company>
+ </ContactPerson>
+ </EntityDescriptor>
XML
result = subject.from(xml)
expect(result).to be_present
spec/saml/kit/response_spec.rb
@@ -146,14 +146,14 @@ RSpec.describe Saml::Kit::Response do
it 'is invalid' do
now = Time.now.utc
destination = FFaker::Internet.uri('https')
- raw_xml = <<-XML
-<?xml version="1.0"?>
-<samlp:Response xmlns:samlp="#{Saml::Kit::Namespaces::PROTOCOL}" ID="#{Xml::Kit::Id.generate}" Version="2.0" IssueInstant="#{now.iso8601}" Destination="#{destination}" Consent="#{Saml::Kit::Namespaces::UNSPECIFIED}" InResponseTo="#{request.id}">
- <Issuer xmlns="#{Saml::Kit::Namespaces::ASSERTION}">#{request.issuer}</Issuer>
- <samlp:Status>
- <samlp:StatusCode Value="#{Saml::Kit::Namespaces::RESPONDER_ERROR}"/>
- </samlp:Status>
-</samlp:Response>
+ raw_xml = <<-XML.strip_heredoc
+ <?xml version="1.0"?>
+ <samlp:Response xmlns:samlp="#{Saml::Kit::Namespaces::PROTOCOL}" ID="#{Xml::Kit::Id.generate}" Version="2.0" IssueInstant="#{now.iso8601}" Destination="#{destination}" Consent="#{Saml::Kit::Namespaces::UNSPECIFIED}" InResponseTo="#{request.id}">
+ <Issuer xmlns="#{Saml::Kit::Namespaces::ASSERTION}">#{request.issuer}</Issuer>
+ <samlp:Status>
+ <samlp:StatusCode Value="#{Saml::Kit::Namespaces::RESPONDER_ERROR}"/>
+ </samlp:Status>
+ </samlp:Response>
XML
allow(registry).to receive(:metadata_for).with(request.issuer).and_return(metadata)
@@ -264,32 +264,32 @@ RSpec.describe Saml::Kit::Response do
let(:url) { FFaker::Internet.uri('https') }
it 'returns true when the Assertion is signed' do
- xml = <<-XML
-<?xml version="1.0"?>
-<samlp:Response xmlns:samlp="#{Saml::Kit::Namespaces::PROTOCOL}" ID="#{id}" Version="2.0" IssueInstant="#{now.iso8601}" Destination="#{url}" Consent="urn:oasis:names:tc:SAML:2.0:consent:unspecified" InResponseTo="_#{SecureRandom.uuid}">
- <Assertion xmlns="#{Saml::Kit::Namespaces::ASSERTION}" ID="#{id}" IssueInstant="#{now.iso8601}" Version="2.0">
- <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
- <ds:SignedInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
- <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
- <ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
- <ds:Reference URI="##{id}">
- <ds:Transforms>
- <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
- <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
- </ds:Transforms>
- <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
- <ds:DigestValue></ds:DigestValue>
- </ds:Reference>
- </ds:SignedInfo>
- <ds:SignatureValue></ds:SignatureValue>
- <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
- <ds:X509Data>
- <ds:X509Certificate></ds:X509Certificate>
- </ds:X509Data>
- </KeyInfo>
- </ds:Signature>
- </Assertion>
-</samlp:Response>
+ xml = <<-XML.strip_heredoc
+ <?xml version="1.0"?>
+ <samlp:Response xmlns:samlp="#{Saml::Kit::Namespaces::PROTOCOL}" ID="#{id}" Version="2.0" IssueInstant="#{now.iso8601}" Destination="#{url}" Consent="urn:oasis:names:tc:SAML:2.0:consent:unspecified" InResponseTo="_#{SecureRandom.uuid}">
+ <Assertion xmlns="#{Saml::Kit::Namespaces::ASSERTION}" ID="#{id}" IssueInstant="#{now.iso8601}" Version="2.0">
+ <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
+ <ds:SignedInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
+ <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
+ <ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
+ <ds:Reference URI="##{id}">
+ <ds:Transforms>
+ <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
+ <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
+ </ds:Transforms>
+ <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
+ <ds:DigestValue></ds:DigestValue>
+ </ds:Reference>
+ </ds:SignedInfo>
+ <ds:SignatureValue></ds:SignatureValue>
+ <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
+ <ds:X509Data>
+ <ds:X509Certificate></ds:X509Certificate>
+ </ds:X509Data>
+ </KeyInfo>
+ </ds:Signature>
+ </Assertion>
+ </samlp:Response>
XML
subject = described_class.new(xml)
expect(subject).not_to be_signed
@@ -297,42 +297,42 @@ RSpec.describe Saml::Kit::Response do
end
it 'returns true when the Response is signed' do
- xml = <<-XML
-<?xml version="1.0"?>
-<samlp:Response xmlns:samlp="#{Saml::Kit::Namespaces::PROTOCOL}" ID="#{id}" Version="2.0" IssueInstant="#{now.iso8601}" Destination="#{url}" Consent="urn:oasis:names:tc:SAML:2.0:consent:unspecified" InResponseTo="_#{SecureRandom.uuid}">
- <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
- <ds:SignedInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
- <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
- <ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
- <ds:Reference URI="##{id}">
- <ds:Transforms>
- <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
- <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
- </ds:Transforms>
- <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
- <ds:DigestValue></ds:DigestValue>
- </ds:Reference>
- </ds:SignedInfo>
- <ds:SignatureValue></ds:SignatureValue>
- <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
- <ds:X509Data>
- <ds:X509Certificate></ds:X509Certificate>
- </ds:X509Data>
- </KeyInfo>
- </ds:Signature>
- <Assertion xmlns="#{Saml::Kit::Namespaces::ASSERTION}" ID="#{id}" IssueInstant="#{now.iso8601}" Version="2.0"></Assertion>
-</samlp:Response>
+ xml = <<-XML.strip_heredoc
+ <?xml version="1.0"?>
+ <samlp:Response xmlns:samlp="#{Saml::Kit::Namespaces::PROTOCOL}" ID="#{id}" Version="2.0" IssueInstant="#{now.iso8601}" Destination="#{url}" Consent="urn:oasis:names:tc:SAML:2.0:consent:unspecified" InResponseTo="_#{SecureRandom.uuid}">
+ <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
+ <ds:SignedInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
+ <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
+ <ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
+ <ds:Reference URI="##{id}">
+ <ds:Transforms>
+ <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
+ <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
+ </ds:Transforms>
+ <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
+ <ds:DigestValue></ds:DigestValue>
+ </ds:Reference>
+ </ds:SignedInfo>
+ <ds:SignatureValue></ds:SignatureValue>
+ <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
+ <ds:X509Data>
+ <ds:X509Certificate></ds:X509Certificate>
+ </ds:X509Data>
+ </KeyInfo>
+ </ds:Signature>
+ <Assertion xmlns="#{Saml::Kit::Namespaces::ASSERTION}" ID="#{id}" IssueInstant="#{now.iso8601}" Version="2.0"></Assertion>
+ </samlp:Response>
XML
subject = described_class.new(xml)
expect(subject).to be_signed
end
it 'returns false when there is no signature' do
- xml = <<-XML
-<?xml version="1.0"?>
-<samlp:Response xmlns:samlp="#{Saml::Kit::Namespaces::PROTOCOL}" ID="#{id}" Version="2.0" IssueInstant="#{now.iso8601}" Destination="#{url}" Consent="urn:oasis:names:tc:SAML:2.0:consent:unspecified" InResponseTo="_#{SecureRandom.uuid}">
- <Assertion xmlns="#{Saml::Kit::Namespaces::ASSERTION}" ID="#{id}" IssueInstant="#{now.iso8601}" Version="2.0"></Assertion>
-</samlp:Response>
+ xml = <<-XML.strip_heredoc
+ <?xml version="1.0"?>
+ <samlp:Response xmlns:samlp="#{Saml::Kit::Namespaces::PROTOCOL}" ID="#{id}" Version="2.0" IssueInstant="#{now.iso8601}" Destination="#{url}" Consent="urn:oasis:names:tc:SAML:2.0:consent:unspecified" InResponseTo="_#{SecureRandom.uuid}">
+ <Assertion xmlns="#{Saml::Kit::Namespaces::ASSERTION}" ID="#{id}" IssueInstant="#{now.iso8601}" Version="2.0"></Assertion>
+ </samlp:Response>
XML
subject = described_class.new(xml)
expect(subject).not_to be_signed
@@ -351,32 +351,32 @@ RSpec.describe Saml::Kit::Response do
end
it 'returns the certificate when the Assertion is signed' do
- xml = <<-XML
-<?xml version="1.0"?>
-<samlp:Response xmlns:samlp="#{Saml::Kit::Namespaces::PROTOCOL}" ID="#{id}" Version="2.0" IssueInstant="#{now.iso8601}" Destination="#{url}" Consent="urn:oasis:names:tc:SAML:2.0:consent:unspecified" InResponseTo="_#{SecureRandom.uuid}">
- <Assertion xmlns="#{Saml::Kit::Namespaces::ASSERTION}" ID="#{id}" IssueInstant="#{now.iso8601}" Version="2.0">
- <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
- <ds:SignedInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
- <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
- <ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
- <ds:Reference URI="##{id}">
- <ds:Transforms>
- <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
- <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
- </ds:Transforms>
- <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
- <ds:DigestValue></ds:DigestValue>
- </ds:Reference>
- </ds:SignedInfo>
- <ds:SignatureValue></ds:SignatureValue>
- <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
- <ds:X509Data>
- <ds:X509Certificate>#{certificate.stripped}</ds:X509Certificate>
- </ds:X509Data>
- </KeyInfo>
- </ds:Signature>
- </Assertion>
-</samlp:Response>
+ xml = <<-XML.strip_heredoc
+ <?xml version="1.0"?>
+ <samlp:Response xmlns:samlp="#{Saml::Kit::Namespaces::PROTOCOL}" ID="#{id}" Version="2.0" IssueInstant="#{now.iso8601}" Destination="#{url}" Consent="urn:oasis:names:tc:SAML:2.0:consent:unspecified" InResponseTo="_#{SecureRandom.uuid}">
+ <Assertion xmlns="#{Saml::Kit::Namespaces::ASSERTION}" ID="#{id}" IssueInstant="#{now.iso8601}" Version="2.0">
+ <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
+ <ds:SignedInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
+ <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
+ <ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
+ <ds:Reference URI="##{id}">
+ <ds:Transforms>
+ <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
+ <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
+ </ds:Transforms>
+ <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
+ <ds:DigestValue></ds:DigestValue>
+ </ds:Reference>
+ </ds:SignedInfo>
+ <ds:SignatureValue></ds:SignatureValue>
+ <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
+ <ds:X509Data>
+ <ds:X509Certificate>#{certificate.stripped}</ds:X509Certificate>
+ </ds:X509Data>
+ </KeyInfo>
+ </ds:Signature>
+ </Assertion>
+ </samlp:Response>
XML
subject = described_class.new(xml)
expect(subject.signature).not_to be_present
@@ -385,42 +385,42 @@ RSpec.describe Saml::Kit::Response do
end
it 'returns the certificate when the Response is signed' do
- xml = <<-XML
-<?xml version="1.0"?>
-<samlp:Response xmlns:samlp="#{Saml::Kit::Namespaces::PROTOCOL}" ID="#{id}" Version="2.0" IssueInstant="#{now.iso8601}" Destination="#{url}" Consent="urn:oasis:names:tc:SAML:2.0:consent:unspecified" InResponseTo="_#{SecureRandom.uuid}">
- <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
- <ds:SignedInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
- <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
- <ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
- <ds:Reference URI="##{id}">
- <ds:Transforms>
- <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
- <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
- </ds:Transforms>
- <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
- <ds:DigestValue></ds:DigestValue>
- </ds:Reference>
- </ds:SignedInfo>
- <ds:SignatureValue></ds:SignatureValue>
- <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
- <ds:X509Data>
- <ds:X509Certificate>#{certificate}</ds:X509Certificate>
- </ds:X509Data>
- </KeyInfo>
- </ds:Signature>
- <Assertion xmlns="#{Saml::Kit::Namespaces::ASSERTION}" ID="#{id}" IssueInstant="#{now.iso8601}" Version="2.0"></Assertion>
-</samlp:Response>
+ xml = <<-XML.strip_heredoc
+ <?xml version="1.0"?>
+ <samlp:Response xmlns:samlp="#{Saml::Kit::Namespaces::PROTOCOL}" ID="#{id}" Version="2.0" IssueInstant="#{now.iso8601}" Destination="#{url}" Consent="urn:oasis:names:tc:SAML:2.0:consent:unspecified" InResponseTo="_#{SecureRandom.uuid}">
+ <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
+ <ds:SignedInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
+ <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
+ <ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
+ <ds:Reference URI="##{id}">
+ <ds:Transforms>
+ <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
+ <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
+ </ds:Transforms>
+ <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
+ <ds:DigestValue></ds:DigestValue>
+ </ds:Reference>
+ </ds:SignedInfo>
+ <ds:SignatureValue></ds:SignatureValue>
+ <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
+ <ds:X509Data>
+ <ds:X509Certificate>#{certificate}</ds:X509Certificate>
+ </ds:X509Data>
+ </KeyInfo>
+ </ds:Signature>
+ <Assertion xmlns="#{Saml::Kit::Namespaces::ASSERTION}" ID="#{id}" IssueInstant="#{now.iso8601}" Version="2.0"></Assertion>
+ </samlp:Response>
XML
subject = described_class.new(xml)
expect(subject.signature.certificate).to eql(certificate)
end
it 'returns nil when there is no signature' do
- xml = <<-XML
-<?xml version="1.0"?>
-<samlp:Response xmlns:samlp="#{Saml::Kit::Namespaces::PROTOCOL}" ID="#{id}" Version="2.0" IssueInstant="#{now.iso8601}" Destination="#{url}" Consent="urn:oasis:names:tc:SAML:2.0:consent:unspecified" InResponseTo="_#{SecureRandom.uuid}">
- <Assertion xmlns="#{Saml::Kit::Namespaces::ASSERTION}" ID="#{id}" IssueInstant="#{now.iso8601}" Version="2.0"></Assertion>
-</samlp:Response>
+ xml = <<-XML.strip_heredoc
+ <?xml version="1.0"?>
+ <samlp:Response xmlns:samlp="#{Saml::Kit::Namespaces::PROTOCOL}" ID="#{id}" Version="2.0" IssueInstant="#{now.iso8601}" Destination="#{url}" Consent="urn:oasis:names:tc:SAML:2.0:consent:unspecified" InResponseTo="_#{SecureRandom.uuid}">
+ <Assertion xmlns="#{Saml::Kit::Namespaces::ASSERTION}" ID="#{id}" IssueInstant="#{now.iso8601}" Version="2.0"></Assertion>
+ </samlp:Response>
XML
subject = described_class.new(xml)
expect(subject.signature).not_to be_present
@@ -435,34 +435,34 @@ RSpec.describe Saml::Kit::Response do
let(:email) { FFaker::Internet.email }
let(:created_at) { DateTime.now }
let(:assertion) do
- <<-XML
-<Assertion xmlns="#{Saml::Kit::Namespaces::ASSERTION}" ID="#{id}" IssueInstant="2017-11-23T04:33:58Z" Version="2.0">
- <Issuer>#{FFaker::Internet.uri('https')}</Issuer>
- <Subject>
- <NameID Format="#{Saml::Kit::Namespaces::PERSISTENT}">#{SecureRandom.uuid}</NameID>
- <SubjectConfirmation Method="#{Saml::Kit::Namespaces::BEARER}">
- <SubjectConfirmationData InResponseTo="#{SecureRandom.uuid}" NotOnOrAfter="2017-11-23T07:33:58Z" Recipient="https://westyundt.ca/acs"/>
- </SubjectConfirmation>
- </Subject>
- <Conditions NotBefore="2017-11-23T04:33:58Z" NotOnOrAfter="2017-11-23T07:33:58Z">
- <AudienceRestriction>
- <Audience>American Wolves</Audience>
- </AudienceRestriction>
- </Conditions>
- <AuthnStatement AuthnInstant="2017-11-23T04:33:58Z" SessionIndex="_11d39a7f-1b86-43ed-90d7-68090a857ca8" SessionNotOnOrAfter="2017-11-23T07:33:58Z">
- <AuthnContext>
- <AuthnContextClassRef>#{Saml::Kit::Namespaces::PASSWORD}</AuthnContextClassRef>
- </AuthnContext>
- </AuthnStatement>
- <AttributeStatement>
- <Attribute Name="email" NameFormat="#{Saml::Kit::Namespaces::URI}">
- <AttributeValue>#{email}</AttributeValue>
- </Attribute>
- <Attribute Name="created_at" NameFormat="#{Saml::Kit::Namespaces::URI}">
- <AttributeValue>#{created_at.iso8601}</AttributeValue>
- </Attribute>
- </AttributeStatement>
-</Assertion>
+ <<-XML.strip_heredoc
+ <Assertion xmlns="#{Saml::Kit::Namespaces::ASSERTION}" ID="#{id}" IssueInstant="2017-11-23T04:33:58Z" Version="2.0">
+ <Issuer>#{FFaker::Internet.uri('https')}</Issuer>
+ <Subject>
+ <NameID Format="#{Saml::Kit::Namespaces::PERSISTENT}">#{SecureRandom.uuid}</NameID>
+ <SubjectConfirmation Method="#{Saml::Kit::Namespaces::BEARER}">
+ <SubjectConfirmationData InResponseTo="#{SecureRandom.uuid}" NotOnOrAfter="2017-11-23T07:33:58Z" Recipient="https://westyundt.ca/acs"/>
+ </SubjectConfirmation>
+ </Subject>
+ <Conditions NotBefore="2017-11-23T04:33:58Z" NotOnOrAfter="2017-11-23T07:33:58Z">
+ <AudienceRestriction>
+ <Audience>American Wolves</Audience>
+ </AudienceRestriction>
+ </Conditions>
+ <AuthnStatement AuthnInstant="2017-11-23T04:33:58Z" SessionIndex="_11d39a7f-1b86-43ed-90d7-68090a857ca8" SessionNotOnOrAfter="2017-11-23T07:33:58Z">
+ <AuthnContext>
+ <AuthnContextClassRef>#{Saml::Kit::Namespaces::PASSWORD}</AuthnContextClassRef>
+ </AuthnContext>
+ </AuthnStatement>
+ <AttributeStatement>
+ <Attribute Name="email" NameFormat="#{Saml::Kit::Namespaces::URI}">
+ <AttributeValue>#{email}</AttributeValue>
+ </Attribute>
+ <Attribute Name="created_at" NameFormat="#{Saml::Kit::Namespaces::URI}">
+ <AttributeValue>#{created_at.iso8601}</AttributeValue>
+ </Attribute>
+ </AttributeStatement>
+ </Assertion>
XML
end
@@ -479,29 +479,29 @@ XML
iv = cipher.random_iv
encrypted = cipher.update(assertion) + cipher.final
- xml = <<-XML
-<samlp:Response xmlns:samlp="#{Saml::Kit::Namespaces::PROTOCOL}" xmlns:saml="#{Saml::Kit::Namespaces::ASSERTION}" ID="#{id}" Version="2.0" IssueInstant="#{now.iso8601}" Destination="#{assertion_consumer_service_url}" InResponseTo="#{Xml::Kit::Id.generate}">
- <saml:Issuer>#{FFaker::Internet.uri('https')}</saml:Issuer>
- <samlp:Status>
- <samlp:StatusCode Value="#{Saml::Kit::Namespaces::SUCCESS}"/>
- </samlp:Status>
- <saml:EncryptedAssertion>
- <xenc:EncryptedData xmlns:xenc="http://www.w3.org/2001/04/xmlenc#" xmlns:dsig="http://www.w3.org/2000/09/xmldsig#">
- <xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc"/>
- <dsig:KeyInfo xmlns:dsig="http://www.w3.org/2000/09/xmldsig#">
- <xenc:EncryptedKey>
- <xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5"/>
- <xenc:CipherData>
- <xenc:CipherValue>#{Base64.encode64(public_key.public_encrypt(key))}</xenc:CipherValue>
- </xenc:CipherData>
- </xenc:EncryptedKey>
- </dsig:KeyInfo>
- <xenc:CipherData>
- <xenc:CipherValue>#{Base64.encode64(iv + encrypted)}</xenc:CipherValue>
- </xenc:CipherData>
- </xenc:EncryptedData>
- </saml:EncryptedAssertion>
-</samlp:Response>
+ xml = <<-XML.strip_heredoc
+ <samlp:Response xmlns:samlp="#{Saml::Kit::Namespaces::PROTOCOL}" xmlns:saml="#{Saml::Kit::Namespaces::ASSERTION}" ID="#{id}" Version="2.0" IssueInstant="#{now.iso8601}" Destination="#{assertion_consumer_service_url}" InResponseTo="#{Xml::Kit::Id.generate}">
+ <saml:Issuer>#{FFaker::Internet.uri('https')}</saml:Issuer>
+ <samlp:Status>
+ <samlp:StatusCode Value="#{Saml::Kit::Namespaces::SUCCESS}"/>
+ </samlp:Status>
+ <saml:EncryptedAssertion>
+ <xenc:EncryptedData xmlns:xenc="http://www.w3.org/2001/04/xmlenc#" xmlns:dsig="http://www.w3.org/2000/09/xmldsig#">
+ <xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc"/>
+ <dsig:KeyInfo xmlns:dsig="http://www.w3.org/2000/09/xmldsig#">
+ <xenc:EncryptedKey>
+ <xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5"/>
+ <xenc:CipherData>
+ <xenc:CipherValue>#{Base64.encode64(public_key.public_encrypt(key))}</xenc:CipherValue>
+ </xenc:CipherData>
+ </xenc:EncryptedKey>
+ </dsig:KeyInfo>
+ <xenc:CipherData>
+ <xenc:CipherValue>#{Base64.encode64(iv + encrypted)}</xenc:CipherValue>
+ </xenc:CipherData>
+ </xenc:EncryptedData>
+ </saml:EncryptedAssertion>
+ </samlp:Response>
XML
subject = described_class.new(xml)
spec/saml/kit/service_provider_metadata_spec.rb
@@ -102,14 +102,14 @@ RSpec.describe Saml::Kit::ServiceProviderMetadata do
end
it 'is invalid when 0 ACS endpoints are specified' do
- xml = <<-XML
-<?xml version="1.0" encoding="UTF-8"?>
-<EntityDescriptor xmlns="#{Saml::Kit::Namespaces::METADATA}" ID="#{::Xml::Kit::Id.generate}" entityID="#{entity_id}">
- <SPSSODescriptor AuthnRequestsSigned="false" WantAssertionsSigned="true" protocolSupportEnumeration="#{Saml::Kit::Namespaces::PROTOCOL}">
- <SingleLogoutService Binding="#{Saml::Kit::Bindings::HTTP_POST}" Location="#{FFaker::Internet.uri('https')}"/>
- <NameIDFormat>#{Saml::Kit::Namespaces::PERSISTENT}</NameIDFormat>
- </SPSSODescriptor>
-</EntityDescriptor>
+ xml = <<-XML.strip_heredoc
+ <?xml version="1.0" encoding="UTF-8"?>
+ <EntityDescriptor xmlns="#{Saml::Kit::Namespaces::METADATA}" ID="#{::Xml::Kit::Id.generate}" entityID="#{entity_id}">
+ <SPSSODescriptor AuthnRequestsSigned="false" WantAssertionsSigned="true" protocolSupportEnumeration="#{Saml::Kit::Namespaces::PROTOCOL}">
+ <SingleLogoutService Binding="#{Saml::Kit::Bindings::HTTP_POST}" Location="#{FFaker::Internet.uri('https')}"/>
+ <NameIDFormat>#{Saml::Kit::Namespaces::PERSISTENT}</NameIDFormat>
+ </SPSSODescriptor>
+ </EntityDescriptor>
XML
expect(described_class.new(xml)).to be_invalid
end
.rubocop.yml
@@ -12,9 +12,6 @@ AllCops:
- 'vendor/**/*'
TargetRubyVersion: 2.2
-Layout/EndOfLine:
- EnforcedStyle: lf
-
Layout/ClassStructure:
Enabled: true
Categories:
@@ -31,6 +28,12 @@ Layout/ClassStructure:
- protected_methods
- private_methods
+Layout/EndOfLine:
+ EnforcedStyle: lf
+
+Layout/IndentHeredoc:
+ EnforcedStyle: active_support
+
Lint/AmbiguousBlockAssociation:
Exclude:
- 'spec/**/*.rb'
@@ -59,8 +62,14 @@ Style/StringLiterals:
Style/TrailingCommaInLiteral:
Enabled: false
-RSpec/NestedGroups:
- Max: 7
+RSpec/ExampleLength:
+ Max: 10
+
+RSpec/MultipleExpectations:
+ Max: 5
RSpec/NamedSubject:
Enabled: false
+
+RSpec/NestedGroups:
+ Max: 7