Comparing changes
v0.2.12
→
v0.2.13
5 commits
9 files changed
Commits
Changed files (9)
lib
saml
kit
spec
lib/saml/kit/locales/en.yml
@@ -5,6 +5,7 @@ en:
Assertion:
expired: "must not be expired."
must_match_issuer: "must match entityId."
+ must_contain_single_assertion: "must contain single Assertion."
AuthnRequest:
invalid: "must contain AuthnRequest."
invalid_fingerprint: "does not match."
lib/saml/kit/assertion.rb
@@ -70,12 +70,16 @@ module Saml
private
def assertion
- if encrypted?
+ @assertion ||= if encrypted?
decrypted = XmlDecryption.new(configuration: @configuration).decrypt(@xml_hash['Response']['EncryptedAssertion'])
Saml::Kit.logger.debug(decrypted)
Hash.from_xml(decrypted)['Assertion']
else
- @xml_hash.fetch('Response', {}).fetch('Assertion', {})
+ result = @xml_hash.fetch('Response', {}).fetch('Assertion', {})
+ return result if result.is_a?(Hash)
+
+ errors[:assertion] << error_message(:must_contain_single_assertion)
+ {}
end
end
lib/saml/kit/metadata.rb
@@ -29,6 +29,18 @@ module Saml
document.find_all("/md:EntityDescriptor/md:#{name}/md:NameIDFormat").map(&:text)
end
+ def organization_name
+ document.find_by("/md:EntityDescriptor/md:Organization/md:OrganizationName").try(:text)
+ end
+
+ def organization_url
+ document.find_by("/md:EntityDescriptor/md:Organization/md:OrganizationURL").try(:text)
+ end
+
+ def contact_person_company
+ document.find_by("/md:EntityDescriptor/md:ContactPerson/md:Company").try(:text)
+ end
+
def certificates
@certificates ||= document.find_all("/md:EntityDescriptor/md:#{name}/md:KeyDescriptor").map do |item|
cert = item.at_xpath("./ds:KeyInfo/ds:X509Data/ds:X509Certificate", Xml::NAMESPACES).text
lib/saml/kit/version.rb
@@ -1,5 +1,5 @@
module Saml
module Kit
- VERSION = "0.2.12"
+ VERSION = "0.2.13"
end
end
spec/saml/builders/metadata_spec.rb
@@ -54,18 +54,21 @@ RSpec.describe Saml::Kit::Builders::Metadata do
it 'generates signed idp and sp metadata' do
configuration = Saml::Kit::Configuration.new do |config|
- config.generate_key_pair_for(use: :signing)
+ 3.times { config.generate_key_pair_for(use: :signing) }
end
metadata = Saml::Kit::Metadata.build(configuration: configuration) do |builder|
builder.entity_id = FFaker::Internet.uri("https")
builder.build_identity_provider do |x|
x.embed_signature = true
+ x.add_single_sign_on_service(url, binding: :http_post)
end
builder.build_service_provider do |x|
x.embed_signature = true
+ x.add_assertion_consumer_service(url, binding: :http_post)
end
end
expect(metadata).to be_present
+ expect(metadata).to be_valid
end
end
end
spec/saml/certificate_spec.rb
@@ -1,7 +1,6 @@
require 'spec_helper'
RSpec.describe Saml::Kit::Certificate do
- #subject { Saml::Kit.configuration.certificates(use: :signing).last }
subject { described_class.new(certificate, use: :signing) }
let(:certificate) do
cert, _ = Saml::Kit::SelfSignedCertificate.new('password').create
spec/saml/metadata_spec.rb
@@ -44,6 +44,9 @@ RSpec.describe Saml::Kit::Metadata do
expect(result.single_sign_on_services.count).to eql(2)
expect(result.assertion_consumer_services.count).to eql(1)
expect(result.single_logout_services.count).to eql(2)
+ expect(result.organization_name).to eql("Acme, Inc")
+ expect(result.organization_url).to eql("http://localhost:5000/")
+ expect(result.contact_person_company).to eql("mailto:hi@example.com")
end
end
end
spec/saml/response_spec.rb
@@ -160,6 +160,80 @@ RSpec.describe Saml::Kit::Response do
subject = described_class.new(raw_xml)
expect(subject).to be_invalid
end
+
+ it 'is invalid when there are 2 assertions' do
+ id = Saml::Kit::Id.generate
+ issuer = FFaker::Internet.uri("https")
+ configuration = Saml::Kit::Configuration.new do |config|
+ config.generate_key_pair_for(use: :signing)
+ end
+ response_options = {
+ ID: id,
+ Version: "2.0",
+ IssueInstant: Time.now.iso8601,
+ Consent: Saml::Kit::Namespaces::UNSPECIFIED,
+ InResponseTo: request.id,
+ xmlns: Saml::Kit::Namespaces::PROTOCOL,
+ }
+ assertion_options = {
+ ID: Saml::Kit::Id.generate,
+ IssueInstant: Time.now.iso8601,
+ Version: "2.0",
+ xmlns: Saml::Kit::Namespaces::ASSERTION,
+ }
+ xml = Saml::Kit::Signatures.sign(configuration: configuration) do |xml, signature|
+ xml.instruct!
+ xml.Response response_options do
+ xml.Issuer(issuer, xmlns: Saml::Kit::Namespaces::ASSERTION)
+ xml.Status do
+ xml.StatusCode Value: Saml::Kit::Namespaces::SUCCESS
+ end
+ xml.Assertion(assertion_options) do
+ xml.Issuer issuer
+ signature.template(assertion_options[:ID])
+ xml.Subject do
+ xml.NameID FFaker::Internet.email, Format: Saml::Kit::Namespaces::EMAIL_ADDRESS
+ xml.SubjectConfirmation Method: Saml::Kit::Namespaces::BEARER do
+ xml.SubjectConfirmationData "", InResponseTo: request.id, NotOnOrAfter: 3.hours.from_now.utc.iso8601, Recipient: FFaker::Internet.uri("https")
+ end
+ end
+ xml.Conditions NotBefore: Time.now.utc.iso8601, NotOnOrAfter: 3.hours.from_now.utc.iso8601 do
+ xml.AudienceRestriction do
+ xml.Audience request.issuer
+ end
+ end
+ xml.AuthnStatement AuthnInstant: Time.now.iso8601, SessionIndex: assertion_options[:ID], SessionNotOnOrAfter: 3.hours.from_now.utc.iso8601 do
+ xml.AuthnContext do
+ xml.AuthnContextClassRef Saml::Kit::Namespaces::PASSWORD
+ end
+ end
+ end
+ new_options = assertion_options.merge(ID: Saml::Kit::Id.generate)
+ xml.Assertion(new_options) do
+ xml.Issuer issuer
+ xml.Subject do
+ xml.NameID FFaker::Internet.email, Format: Saml::Kit::Namespaces::EMAIL_ADDRESS
+ xml.SubjectConfirmation Method: Saml::Kit::Namespaces::BEARER do
+ xml.SubjectConfirmationData "", InResponseTo: request.id, NotOnOrAfter: 3.hours.from_now.utc.iso8601, Recipient: FFaker::Internet.uri("https")
+ end
+ end
+ xml.Conditions NotBefore: Time.now.utc.iso8601, NotOnOrAfter: 3.hours.from_now.utc.iso8601 do
+ xml.AudienceRestriction do
+ xml.Audience request.issuer
+ end
+ end
+ xml.AuthnStatement AuthnInstant: Time.now.iso8601, SessionIndex: new_options[:ID], SessionNotOnOrAfter: 3.hours.from_now.utc.iso8601 do
+ xml.AuthnContext do
+ xml.AuthnContextClassRef Saml::Kit::Namespaces::PASSWORD
+ end
+ end
+ end
+ end
+ end
+ subject = described_class.new(xml)
+ expect(subject).to_not be_valid
+ expect(subject.errors[:assertion]).to be_present
+ end
end
describe "#signed?" do
spec/saml/xml_spec.rb
@@ -45,5 +45,16 @@ RSpec.describe Saml::Kit::Xml do
expect(subject).to_not be_valid
expect(subject.errors[:signature]).to be_present
end
+
+ it 'is valid' do
+ configuration = Saml::Kit::Configuration.new do |config|
+ 5.times { config.generate_key_pair_for(use: :signing) }
+ end
+ signed_xml = Saml::Kit::Metadata.build_xml(configuration: configuration) do |builder|
+ builder.build_identity_provider
+ builder.build_service_provider
+ end
+ expect(described_class.new(signed_xml)).to be_valid
+ end
end
end