Commit ec28fa9
Changed files (33)
lib
saml
kit
bindings
builders
spec
saml
builders
lib/saml/kit/bindings/http_redirect.rb
@@ -12,7 +12,7 @@ module Saml
builder.sign = false
builder.destination = location
document = builder.build
- [UrlBuilder.new.build(document, relay_state: relay_state), {}]
+ [UrlBuilder.new(configuration: builder.configuration).build(document, relay_state: relay_state), {}]
end
def deserialize(params)
lib/saml/kit/bindings/url_builder.rb
@@ -3,21 +3,25 @@ module Saml
module Bindings
class UrlBuilder
include Serializable
+ attr_reader :configuration
- def initialize(private_key: Saml::Kit.configuration.signing_private_key)
- @private_key = private_key
+ def initialize(configuration: Saml::Kit.configuration)
+ @configuration = configuration
end
def build(saml_document, relay_state: nil)
payload = canonicalize(saml_document, relay_state)
- "#{saml_document.destination}?#{payload}&Signature=#{signature_for(payload)}"
+ if configuration.sign?
+ "#{saml_document.destination}?#{payload}&Signature=#{signature_for(payload)}"
+ else
+ "#{saml_document.destination}?#{payload}"
+ end
end
private
- attr_reader :private_key
-
def signature_for(payload)
+ private_key = configuration.signing_private_key
encode(private_key.sign(OpenSSL::Digest::SHA256.new, payload))
end
lib/saml/kit/builders/authentication_request.rb
@@ -3,17 +3,16 @@ module Saml
module Builders
class AuthenticationRequest
include Saml::Kit::Templatable
- attr_accessor :id, :now, :issuer, :assertion_consumer_service_url, :name_id_format, :sign, :destination
+ attr_accessor :id, :now, :issuer, :assertion_consumer_service_url, :name_id_format, :destination
attr_accessor :version
attr_reader :configuration
- def initialize(configuration: Saml::Kit.configuration, sign: true)
+ def initialize(configuration: Saml::Kit.configuration)
@configuration = configuration
@id = Id.generate
@issuer = configuration.issuer
@name_id_format = Namespaces::PERSISTENT
@now = Time.now.utc
- @sign = sign
@version = "2.0"
end
lib/saml/kit/builders/identity_provider_metadata.rb
@@ -4,18 +4,17 @@ module Saml
class IdentityProviderMetadata
include Saml::Kit::Templatable
attr_accessor :id, :organization_name, :organization_url, :contact_email, :entity_id, :attributes, :name_id_formats
- attr_accessor :want_authn_requests_signed, :sign
+ attr_accessor :want_authn_requests_signed
attr_reader :logout_urls, :single_sign_on_urls
attr_reader :configuration
- def initialize(configuration = Saml::Kit.configuration)
+ def initialize(configuration: Saml::Kit.configuration)
@attributes = []
@configuration = configuration
@entity_id = configuration.issuer
@id = Id.generate
@logout_urls = []
@name_id_formats = [Namespaces::PERSISTENT]
- @sign = true
@single_sign_on_urls = []
@want_authn_requests_signed = true
end
lib/saml/kit/builders/logout_request.rb
@@ -4,10 +4,10 @@ module Saml
class LogoutRequest
include Saml::Kit::Templatable
attr_accessor :id, :destination, :issuer, :name_id_format, :now
- attr_accessor :sign, :version
+ attr_accessor :version
attr_reader :user, :configuration
- def initialize(user, configuration: Saml::Kit.configuration, sign: true)
+ def initialize(user, configuration: Saml::Kit.configuration)
@configuration = configuration
@user = user
@id = "_#{SecureRandom.uuid}"
@@ -15,7 +15,6 @@ module Saml
@name_id_format = Saml::Kit::Namespaces::PERSISTENT
@now = Time.now.utc
@version = "2.0"
- @sign = sign
end
def build
lib/saml/kit/builders/logout_response.rb
@@ -3,17 +3,16 @@ module Saml
module Builders
class LogoutResponse
include Saml::Kit::Templatable
- attr_accessor :id, :issuer, :version, :status_code, :sign, :now, :destination
+ attr_accessor :id, :issuer, :version, :status_code, :now, :destination
attr_reader :request
attr_reader :configuration
- def initialize(user, request, configuration: Saml::Kit.configuration, sign: true)
+ def initialize(user, request, configuration: Saml::Kit.configuration)
@configuration = configuration
@id = Id.generate
@issuer = configuration.issuer
@now = Time.now.utc
@request = request
- @sign = sign
@status_code = Namespaces::SUCCESS
@user = user
@version = "2.0"
lib/saml/kit/builders/response.rb
@@ -6,7 +6,7 @@ module Saml
attr_reader :user, :request
attr_accessor :id, :reference_id, :now
attr_accessor :version, :status_code
- attr_accessor :issuer, :sign, :destination, :encrypt
+ attr_accessor :issuer, :destination, :encrypt
attr_reader :configuration
def initialize(user, request, configuration: Saml::Kit.configuration)
@@ -27,11 +27,11 @@ module Saml
request.provider.want_assertions_signed
rescue => error
Saml::Kit.logger.error(error)
- true
+ nil
end
def build
- Saml::Kit::Response.new(to_xml, request_id: request.id)
+ Saml::Kit::Response.new(to_xml, request_id: request.id, configuration: configuration)
end
private
lib/saml/kit/builders/service_provider_metadata.rb
@@ -3,19 +3,18 @@ module Saml
module Builders
class ServiceProviderMetadata
include Saml::Kit::Templatable
- attr_accessor :id, :entity_id, :acs_urls, :logout_urls, :name_id_formats, :sign
+ attr_accessor :id, :entity_id, :acs_urls, :logout_urls, :name_id_formats
attr_accessor :organization_name, :organization_url, :contact_email
attr_accessor :want_assertions_signed
attr_reader :configuration
- def initialize(configuration = Saml::Kit.configuration)
+ def initialize(configuration: Saml::Kit.configuration)
@acs_urls = []
@configuration = configuration
@entity_id = configuration.issuer
@id = Id.generate
@logout_urls = []
@name_id_formats = [Namespaces::PERSISTENT]
- @sign = true
@want_assertions_signed = true
end
@@ -43,7 +42,7 @@ module Saml
def descriptor_options
{
- AuthnRequestsSigned: sign,
+ AuthnRequestsSigned: sign?,
WantAssertionsSigned: want_assertions_signed,
protocolSupportEnumeration: Namespaces::PROTOCOL,
}
lib/saml/kit/builders/xml_signature.rb
@@ -21,11 +21,10 @@ module Saml
attr_reader :reference_id
attr_reader :x509_certificate
- def initialize(reference_id, configuration:, sign: true)
+ def initialize(reference_id, configuration:)
@configuration = configuration
@reference_id = reference_id
- @sign = sign
- @x509_certificate = configuration.certificates(use: :signing).last.stripped
+ @x509_certificate = configuration.certificates(use: :signing).sample.stripped
end
def signature_method
lib/saml/kit/assertion.rb
@@ -1,8 +1,9 @@
module Saml
module Kit
class Assertion
- def initialize(xml_hash)
+ def initialize(xml_hash, configuration: configuration)
@xml_hash = xml_hash
+ @configuration = configuration
end
def name_id
@@ -53,7 +54,7 @@ module Saml
def assertion
if encrypted?
- decrypted = XmlDecryption.new.decrypt(@xml_hash['Response']['EncryptedAssertion'])
+ decrypted = XmlDecryption.new(configuration: @configuration).decrypt(@xml_hash['Response']['EncryptedAssertion'])
Saml::Kit.logger.debug(decrypted)
Hash.from_xml(decrypted)['Assertion']
else
lib/saml/kit/configuration.rb
@@ -12,9 +12,9 @@ module Saml
@registry = DefaultRegistry.new
@session_timeout = 3.hours
@logger = Logger.new(STDOUT)
-
- create_default_key_pair_for(use: :signing)
- create_default_key_pair_for(use: :encryption)
+ #generate_key_pair_for(use: :signing)
+ #generate_key_pair_for(use: :encryption)
+ yield self if block_given?
end
def add_key_pair(certificate, private_key, password:, use: :signing)
@@ -24,6 +24,12 @@ module Saml
})
end
+ def generate_key_pair_for(use:)
+ private_key_password = SecureRandom.uuid
+ certificate_pem, private_key_pem = SelfSignedCertificate.new(private_key_password).create
+ add_key_pair(certificate_pem, private_key_pem, password: private_key_password, use: use)
+ end
+
def certificates(use: nil)
certificates = key_pairs.map { |x| x[:certificate] }
use.present? ? certificates.find_all { |x| x.for?(use) } : certificates
@@ -45,17 +51,15 @@ module Saml
private_keys(use: :encryption).last
end
+ def sign?
+ certificates(use: :signing).any?
+ end
+
private
def key_pairs
@key_pairs ||= []
end
-
- def create_default_key_pair_for(use:)
- private_key_password = SecureRandom.uuid
- certificate_pem, private_key_pem = SelfSignedCertificate.new(private_key_password).create
- add_key_pair(certificate_pem, private_key_pem, password: private_key_password, use: use)
- end
end
end
end
lib/saml/kit/response.rb
@@ -9,8 +9,9 @@ module Saml
validate :must_be_active_session
validate :must_match_issuer
- def initialize(xml, request_id: nil)
+ def initialize(xml, request_id: nil, configuration: Saml::Kit.configuration)
@request_id = request_id
+ @configuration = configuration
super(xml, name: "Response")
end
@@ -23,7 +24,7 @@ module Saml
end
def assertion
- @assertion = Saml::Kit::Assertion.new(to_h)
+ @assertion = Saml::Kit::Assertion.new(to_h, configuration: @configuration)
end
def signed?
lib/saml/kit/self_signed_certificate.rb
@@ -17,15 +17,6 @@ module Saml
certificate.public_key = public_key
certificate.serial = 0x0
certificate.version = 2
- factory = OpenSSL::X509::ExtensionFactory.new
- factory.subject_certificate = factory.issuer_certificate = certificate
- certificate.extensions = [
- factory.create_extension("basicConstraints","CA:TRUE", true),
- factory.create_extension("subjectKeyIdentifier", "hash"),
- ]
- certificate.add_extension(
- factory.create_extension("authorityKeyIdentifier", "keyid:always,issuer:always")
- )
certificate.sign(rsa_key, OpenSSL::Digest::SHA256.new)
[
certificate.to_pem,
lib/saml/kit/signature.rb
@@ -13,8 +13,8 @@ module Saml
Template.new(signatures.build(reference_id)).to_xml(xml: xml)
end
- def self.sign(sign: true, xml: ::Builder::XmlMarkup.new, configuration: Saml::Kit.configuration)
- signatures = Saml::Kit::Signatures.new(configuration: configuration, sign: sign)
+ def self.sign(xml: ::Builder::XmlMarkup.new, configuration: Saml::Kit.configuration)
+ signatures = Saml::Kit::Signatures.new(configuration: configuration)
yield xml, new(xml, signatures)
signatures.complete(xml.target!)
end
lib/saml/kit/signatures.rb
@@ -1,20 +1,19 @@
module Saml
module Kit
class Signatures
- attr_reader :sign, :configuration
+ attr_reader :configuration
- def initialize(configuration:, sign: true)
+ def initialize(configuration:)
@configuration = configuration
- @sign = sign
end
def build(reference_id)
- return nil unless sign
- Saml::Kit::Builders::XmlSignature.new(reference_id, configuration: configuration, sign: sign)
+ return nil unless configuration.sign?
+ Saml::Kit::Builders::XmlSignature.new(reference_id, configuration: configuration)
end
def complete(raw_xml)
- return raw_xml unless sign
+ return raw_xml unless configuration.sign?
private_key = configuration.signing_private_key
Xmldsig::SignedDocument.new(raw_xml).sign(private_key)
end
lib/saml/kit/templatable.rb
@@ -1,17 +1,23 @@
module Saml
module Kit
module Templatable
+ attr_accessor :sign
+
def to_xml(xml: ::Builder::XmlMarkup.new)
signatures.complete(render(self, xml: xml))
end
def signature_for(reference_id:, xml:)
- return unless sign
+ return unless sign?
render(signatures.build(reference_id), xml: xml)
end
+ def sign?
+ sign.nil? ? configuration.sign? : sign && configuration.sign?
+ end
+
def signatures
- @signatures ||= Saml::Kit::Signatures.new(configuration: configuration, sign: sign)
+ @signatures ||= Saml::Kit::Signatures.new(configuration: configuration)
end
def encryption_for(xml:)
lib/saml/kit/xml_decryption.rb
@@ -3,8 +3,8 @@ module Saml
class XmlDecryption
attr_reader :private_key
- def initialize(private_key = Saml::Kit.configuration.encryption_private_key)
- @private_key = private_key
+ def initialize(configuration: Saml::Kit.configuration)
+ @private_key = configuration.encryption_private_key
end
def decrypt(data)
spec/saml/bindings/http_post_spec.rb
@@ -1,14 +1,37 @@
require 'spec_helper'
RSpec.describe Saml::Kit::Bindings::HttpPost do
- let(:location) { FFaker::Internet.http_url }
+ let(:location) { FFaker::Internet.uri("https") }
subject { described_class.new(location: location) }
+ describe "equality" do
+ it 'is referentially equal' do
+ expect(subject).to eql(subject)
+ end
+
+ it 'is equal by value' do
+ expect(subject).to eql(
+ Saml::Kit::Bindings::HttpPost.new(location: location)
+ )
+ end
+
+ it 'is not equal' do
+ expect(subject).to_not eql(
+ described_class.new(location: FFaker::Internet.uri("https"))
+ )
+ end
+ end
+
describe "#serialize" do
let(:relay_state) { "ECHO" }
+ let(:configuration) do
+ Saml::Kit::Configuration.new do |config|
+ config.generate_key_pair_for(use: :signing)
+ end
+ end
it 'encodes the request using the HTTP-POST encoding for a AuthenticationRequest' do
- builder = Saml::Kit::AuthenticationRequest.builder_class.new
+ builder = Saml::Kit::AuthenticationRequest.builder_class.new(configuration: configuration)
url, saml_params = subject.serialize(builder, relay_state: relay_state)
expect(url).to eql(location)
@@ -22,7 +45,7 @@ RSpec.describe Saml::Kit::Bindings::HttpPost do
it 'returns a SAMLRequest for a LogoutRequest' do
user = double(:user, name_id_for: SecureRandom.uuid)
- builder = Saml::Kit::LogoutRequest.builder_class.new(user)
+ builder = Saml::Kit::LogoutRequest.builder_class.new(user, configuration: configuration)
url, saml_params = subject.serialize(builder, relay_state: relay_state)
expect(url).to eql(location)
@@ -37,7 +60,7 @@ RSpec.describe Saml::Kit::Bindings::HttpPost do
it 'returns a SAMLResponse for a LogoutResponse' do
user = double(:user, name_id_for: SecureRandom.uuid)
request = instance_double(Saml::Kit::AuthenticationRequest, id: SecureRandom.uuid)
- builder = Saml::Kit::LogoutResponse.builder_class.new(user, request)
+ builder = Saml::Kit::LogoutResponse.builder_class.new(user, request, configuration: configuration)
url, saml_params = subject.serialize(builder, relay_state: relay_state)
expect(url).to eql(location)
spec/saml/bindings/http_redirect_spec.rb
@@ -6,9 +6,14 @@ RSpec.describe Saml::Kit::Bindings::HttpRedirect do
describe "#serialize" do
let(:relay_state) { "ECHO" }
+ let(:configuration) do
+ Saml::Kit::Configuration.new do |config|
+ config.generate_key_pair_for(use: :signing)
+ end
+ end
it 'encodes the request using the HTTP-Redirect encoding' do
- builder = Saml::Kit::AuthenticationRequest.builder_class.new
+ builder = Saml::Kit::AuthenticationRequest.builder_class.new(configuration: configuration)
url, _ = subject.serialize(builder, relay_state: relay_state)
expect(url).to start_with(location)
expect(url).to have_query_param('SAMLRequest')
spec/saml/bindings/url_builder_spec.rb
@@ -13,6 +13,13 @@ RSpec.describe Saml::Kit::Bindings::UrlBuilder do
[Saml::Kit::LogoutResponse, 'SAMLResponse'],
].each do |(response_type, query_string_parameter)|
describe response_type.to_s do
+ subject { described_class.new(configuration: configuration) }
+ let(:configuration) do
+ Saml::Kit::Configuration.new do |config|
+ config.generate_key_pair_for(use: :signing)
+ end
+ end
+
let(:response) { instance_double(response_type, destination: destination, to_xml: xml, query_string_parameter: query_string_parameter) }
def to_query_params(url)
@@ -54,7 +61,7 @@ RSpec.describe Saml::Kit::Bindings::UrlBuilder do
payload = "#{query_string_parameter}=#{query_params[query_string_parameter]}"
payload << "&RelayState=#{query_params['RelayState']}"
payload << "&SigAlg=#{query_params['SigAlg']}"
- expected_signature = Base64.strict_encode64(Saml::Kit.configuration.signing_private_key.sign(OpenSSL::Digest::SHA256.new, payload))
+ expected_signature = Base64.strict_encode64(configuration.signing_private_key.sign(OpenSSL::Digest::SHA256.new, payload))
expect(query_params['Signature']).to eql(expected_signature)
end
@@ -65,7 +72,7 @@ RSpec.describe Saml::Kit::Bindings::UrlBuilder do
payload = "#{query_string_parameter}=#{query_params[query_string_parameter]}"
payload << "&SigAlg=#{query_params['SigAlg']}"
- expected_signature = Base64.strict_encode64(Saml::Kit.configuration.signing_private_key.sign(OpenSSL::Digest::SHA256.new, payload))
+ expected_signature = Base64.strict_encode64(configuration.signing_private_key.sign(OpenSSL::Digest::SHA256.new, payload))
expect(query_params['Signature']).to eql(expected_signature)
end
end
spec/saml/builders/identity_provider_metadata_spec.rb
@@ -1,7 +1,13 @@
require 'spec_helper'
RSpec.describe Saml::Kit::Builders::IdentityProviderMetadata do
- subject { described_class.new }
+ subject { described_class.new(configuration: configuration) }
+ let(:configuration) do
+ Saml::Kit::Configuration.new do |config|
+ config.generate_key_pair_for(use: :signing)
+ config.generate_key_pair_for(use: :encryption)
+ end
+ end
let(:email) { FFaker::Internet.email }
let(:org_name) { FFaker::Movie.title }
let(:url) { FFaker::Internet.uri("https") }
@@ -38,7 +44,7 @@ RSpec.describe Saml::Kit::Builders::IdentityProviderMetadata do
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'] }
- expected_certificates = Saml::Kit.configuration.certificates.map(&:stripped)
+ expected_certificates = configuration.certificates.map(&:stripped)
expect(certificates).to match_array(expected_certificates)
expect(result['EntityDescriptor']['Organization']['OrganizationName']).to eql(org_name)
expect(result['EntityDescriptor']['Organization']['OrganizationDisplayName']).to eql(org_name)
spec/saml/builders/logout_request_spec.rb
@@ -1,9 +1,14 @@
require 'spec_helper'
RSpec.describe Saml::Kit::Builders::LogoutRequest do
- subject { described_class.new(user) }
+ subject { described_class.new(user, configuration: configuration) }
let(:user) { double(:user, name_id_for: name_id) }
let(:name_id) { SecureRandom.uuid }
+ let(:configuration) do
+ Saml::Kit::Configuration.new do |config|
+ config.generate_key_pair_for(use: :signing)
+ end
+ end
it 'produces the expected xml' do
travel_to 1.second.from_now
spec/saml/builders/response_spec.rb
@@ -1,26 +1,28 @@
require 'spec_helper'
RSpec.describe Saml::Kit::Builders::Response do
- subject { described_class.new(user, request) }
+ subject { described_class.new(user, request, configuration: configuration) }
+ let(:configuration) do
+ Saml::Kit::Configuration.new do |config|
+ config.issuer = issuer
+ config.generate_key_pair_for(use: :signing)
+ config.generate_key_pair_for(use: :encryption)
+ end
+ end
let(:email) { FFaker::Internet.email }
let(:assertion_consumer_service_url) { FFaker::Internet.uri("https") }
let(:user) { double(:user, name_id_for: SecureRandom.uuid, assertion_attributes_for: { email: email, created_at: Time.now.utc.iso8601 }) }
let(:request) { double(:request, id: Saml::Kit::Id.generate, assertion_consumer_service_url: assertion_consumer_service_url, issuer: issuer, name_id_format: Saml::Kit::Namespaces::EMAIL_ADDRESS, provider: provider, trusted?: true, signed?: true) }
- let(:provider) { double(want_assertions_signed: false, encryption_certificates: [Saml::Kit::Certificate.new(encryption_pem, use: :encryption)]) }
- let(:encryption_pem) { Saml::Kit.configuration.encryption_certificate.stripped }
+ let(:provider) { double(:provider, want_assertions_signed: false, encryption_certificates: [configuration.encryption_certificate] ) }
let(:issuer) { FFaker::Internet.uri("https") }
- before :each do
- allow(Saml::Kit.configuration).to receive(:issuer).and_return(issuer)
- end
-
describe "#build" do
it 'builds a response with the request_id' do
expect(subject.build.request_id).to eql(request.id)
end
it 'builds a valid encrypted assertion' do
- allow(Saml::Kit.configuration.registry).to receive(:metadata_for).with(issuer).and_return(provider)
+ allow(configuration.registry).to receive(:metadata_for).with(issuer).and_return(provider)
allow(provider).to receive(:matches?).and_return(true)
subject.sign = true
@@ -83,6 +85,7 @@ RSpec.describe Saml::Kit::Builders::Response do
metadata = builder.build
allow(request).to receive(:provider).and_return(metadata)
+ subject = described_class.new(user, request)
hash = Hash.from_xml(subject.to_xml)
expect(hash['Response']['Signature']).to be_nil
end
@@ -92,7 +95,7 @@ RSpec.describe Saml::Kit::Builders::Response do
result = Hash.from_xml(subject.to_xml)
expect(result['Response']['EncryptedAssertion']).to be_present
encrypted_assertion = result['Response']['EncryptedAssertion']
- decrypted_assertion = Saml::Kit::XmlDecryption.new.decrypt(encrypted_assertion)
+ decrypted_assertion = Saml::Kit::XmlDecryption.new(configuration: configuration).decrypt(encrypted_assertion)
decrypted_hash = Hash.from_xml(decrypted_assertion)
expect(decrypted_hash['Assertion']).to be_present
expect(decrypted_hash['Assertion']['Issuer']).to be_present
spec/saml/builders/service_provider_metadata_spec.rb
@@ -1,6 +1,13 @@
require 'spec_helper'
RSpec.describe Saml::Kit::Builders::ServiceProviderMetadata do
+ subject { described_class.new(configuration: configuration) }
+ let(:configuration) do
+ Saml::Kit::Configuration.new do |config|
+ config.generate_key_pair_for(use: :signing)
+ config.generate_key_pair_for(use: :encryption)
+ end
+ end
let(:assertion_consumer_service_url) { FFaker::Internet.http_url }
let(:email) { FFaker::Internet.email }
let(:org_name) { FFaker::Movie.title }
@@ -37,7 +44,7 @@ RSpec.describe Saml::Kit::Builders::ServiceProviderMetadata do
expect(result['EntityDescriptor']['SPSSODescriptor']['AssertionConsumerService']['index']).to eql('0')
expect(result['EntityDescriptor']['Signature']).to be_present
expect(result['EntityDescriptor']['SPSSODescriptor']['KeyDescriptor'].map { |x| x['use'] }).to match_array(['signing', 'encryption'])
- expected_certificates = Saml::Kit.configuration.certificates.map(&:stripped)
+ expected_certificates = configuration.certificates.map(&:stripped)
expect(result['EntityDescriptor']['SPSSODescriptor']['KeyDescriptor'].map { |x| x['KeyInfo']['X509Data']['X509Certificate'] }).to match_array(expected_certificates)
expect(result['EntityDescriptor']['Organization']['OrganizationName']).to eql(org_name)
expect(result['EntityDescriptor']['Organization']['OrganizationDisplayName']).to eql(org_name)
spec/saml/authentication_request_spec.rb
@@ -78,7 +78,9 @@ RSpec.describe Saml::Kit::AuthenticationRequest do
it 'validates the schema of the request' do
id = Saml::Kit::Id.generate
- signed_xml = Saml::Kit::Signature.sign(sign: true) do |xml, signature|
+ configuration = Saml::Kit::Configuration.new
+ configuration.generate_key_pair_for(use: :signing)
+ signed_xml = Saml::Kit::Signature.sign(configuration: configuration) do |xml, signature|
xml.tag!('samlp:AuthnRequest', "xmlns:samlp" => Saml::Kit::Namespaces::PROTOCOL, AssertionConsumerServiceURL: assertion_consumer_service_url, ID: id) do
signature.template(id)
xml.Fake do
spec/saml/certificate_spec.rb
@@ -1,7 +1,12 @@
require 'spec_helper'
RSpec.describe Saml::Kit::Certificate do
- subject { Saml::Kit.configuration.certificates(use: :signing).last }
+ #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
+ cert
+ end
describe "#fingerprint" do
it 'returns a fingerprint' do
spec/saml/http_post_spec.rb
@@ -1,26 +0,0 @@
-require 'spec_helper'
-
-RSpec.describe Saml::Kit::Bindings::HttpPost do
- describe "equality" do
- let(:location) { FFaker::Internet.uri("https") }
- subject { Saml::Kit::Bindings::HttpPost.new(location: location) }
-
- it 'is referentially equal' do
- expect(subject).to eql(subject)
- end
-
- it 'is equal by value' do
- expect(subject).to eql(
- Saml::Kit::Bindings::HttpPost.new(location: location)
- )
- end
-
- it 'is not equal' do
- expect(subject).to_not eql(
- Saml::Kit::Bindings::HttpPost.new(
- location: FFaker::Internet.uri("https")
- )
- )
- end
- end
-end
spec/saml/logout_request_spec.rb
@@ -108,7 +108,9 @@ RSpec.describe Saml::Kit::LogoutRequest do
it 'validates the schema of the request' do
id = Saml::Kit::Id.generate
- signed_xml = Saml::Kit::Signature.sign(sign: true) do |xml, signature|
+ configuration = Saml::Kit::Configuration.new
+ configuration.generate_key_pair_for(use: :signing)
+ signed_xml = Saml::Kit::Signature.sign(configuration: configuration) do |xml, signature|
xml.LogoutRequest ID: id do
signature.template(id)
xml.Fake do
spec/saml/response_spec.rb
@@ -55,7 +55,9 @@ RSpec.describe Saml::Kit::Response do
allow(registry).to receive(:metadata_for).and_return(metadata)
allow(metadata).to receive(:matches?).and_return(true)
id = Saml::Kit::Id.generate
- signed_xml = Saml::Kit::Signature.sign(sign: true) do |xml, signature|
+ configuration = Saml::Kit::Configuration.new
+ configuration.generate_key_pair_for(use: :signing)
+ signed_xml = Saml::Kit::Signature.sign(configuration: configuration) do |xml, signature|
xml.tag! "samlp:Response", "xmlns:samlp" => Saml::Kit::Namespaces::PROTOCOL, ID: id do
signature.template(id)
xml.Fake do
spec/saml/service_provider_metadata_spec.rb
@@ -113,7 +113,12 @@ RSpec.describe Saml::Kit::ServiceProviderMetadata do
end
describe "#matches?" do
- subject { Saml::Kit::ServiceProviderMetadata.build }
+ let(:configuration) do
+ config = Saml::Kit::Configuration.new
+ config.generate_key_pair_for(use: :signing)
+ config
+ end
+ subject { Saml::Kit::ServiceProviderMetadata.build(configuration: configuration) }
it 'returns true when the fingerprint matches one of the signing certificates' do
certificate = Hash.from_xml(subject.to_xml)['EntityDescriptor']['Signature']['KeyInfo']['X509Data']['X509Certificate']
spec/saml/signature_spec.rb
@@ -30,7 +30,7 @@ RSpec.describe Saml::Kit::Signature do
"xmlns:saml" => "urn:oasis:names:tc:SAML:2.0:assertion",
ID: reference_id,
}
- signed_xml = described_class.sign(sign: true, configuration: configuration) do |xml, signature|
+ signed_xml = described_class.sign(configuration: configuration) do |xml, signature|
xml.tag!('samlp:AuthnRequest', options) do
signature.template(reference_id)
xml.tag!('saml:Issuer', "MyEntityID")
@@ -57,7 +57,7 @@ RSpec.describe Saml::Kit::Signature do
end
it 'does not add a signature' do
- signed_xml = described_class.sign(sign: false, configuration: configuration) do |xml, signature|
+ signed_xml = described_class.sign(configuration: Saml::Kit::Configuration.new) do |xml, signature|
xml.AuthnRequest do
signature.template(reference_id)
xml.Issuer "MyEntityID"
spec/saml/xml_decryption_spec.rb
@@ -40,7 +40,7 @@ RSpec.describe Saml::Kit::XmlDecryption do
}
}
}
- subject = described_class.new(private_key)
+ subject = described_class.new(configuration: double(encryption_private_key: private_key))
decrypted = subject.decrypt(data)
expect(decrypted.strip).to eql(secret)
end
spec/saml/xml_spec.rb
@@ -4,9 +4,14 @@ RSpec.describe Saml::Kit::Xml do
describe "#valid_signature?" do
let(:login_url) { "https://#{FFaker::Internet.domain_name}/login" }
let(:logout_url) { "https://#{FFaker::Internet.domain_name}/logout" }
+ let(:configuration) do
+ configuration = Saml::Kit::Configuration.new
+ configuration.generate_key_pair_for(use: :signing)
+ configuration
+ end
let(:signed_xml) do
- Saml::Kit::ServiceProviderMetadata.build do |builder|
+ Saml::Kit::ServiceProviderMetadata.build(configuration: configuration) do |builder|
builder.entity_id = FFaker::Movie.title
builder.add_assertion_consumer_service(login_url, binding: :http_post)
builder.add_assertion_consumer_service(login_url, binding: :http_redirect)