")
+ end
+ end
+
context "solicited Response" do
before(:each) do
params[:SAMLRequest] = make_saml_request
@@ -81,16 +91,6 @@ def params
expect(response.is_valid?).to be_truthy
end
- it "should create a SAML Logout Response" do
- params[:SAMLRequest] = make_saml_logout_request
- expect(validate_saml_request).to eq(true)
- expect(saml_request.logout_request?).to eq true
- saml_response = encode_response(principal)
- response = OneLogin::RubySaml::Logoutresponse.new(saml_response, saml_settings)
- expect(response.validate).to eq(true)
- expect(response.issuer).to eq("http://example.com")
- end
-
it "should by default create a SAML Response with a signed assertion" do
saml_response = encode_response(principal)
response = OneLogin::RubySaml::Response.new(saml_response)
@@ -124,4 +124,32 @@ def params
end
end
end
+
+ context "Single Logout Request" do
+ before do
+ idp_configure("https://foo.example.com/saml/consume", true)
+ slo_request = make_saml_sp_slo_request(security_options: { embed_sign: false })
+ params[:SAMLRequest] = slo_request['SAMLRequest']
+ params[:RelayState] = slo_request['RelayState']
+ params[:SigAlg] = slo_request['SigAlg']
+ params[:Signature] = slo_request['Signature']
+ end
+
+ it 'should successfully validate signature' do
+ expect(validate_saml_request).to eq(true)
+ end
+
+ context "solicited Response" do
+ let(:principal) { double email_address: "foo@example.com" }
+
+ it "should create a SAML Logout Response" do
+ expect(validate_saml_request).to eq(true)
+ expect(saml_request.logout_request?).to eq true
+ saml_response = encode_response(principal)
+ response = OneLogin::RubySaml::Logoutresponse.new(saml_response, saml_settings)
+ expect(response.validate).to eq(true)
+ expect(response.issuer).to eq("http://idp.com/saml/idp")
+ end
+ end
+ end
end
diff --git a/spec/lib/saml_idp/incoming_metadata_spec.rb b/spec/lib/saml_idp/incoming_metadata_spec.rb
index 7d483e0b..fb00ec53 100644
--- a/spec/lib/saml_idp/incoming_metadata_spec.rb
+++ b/spec/lib/saml_idp/incoming_metadata_spec.rb
@@ -1,4 +1,5 @@
require 'spec_helper'
+
module SamlIdp
metadata_1 = <<-eos
@@ -29,11 +30,52 @@ module SamlIdp
eos
+ metadata_5 = <<-eos
+
+
+
+
+
+ MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnht3GR...
+
+
+
+
+
+ eos
+
+ metadata_6 = <<-eos
+
+
+
+
+
+ MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmw6vGr...
+
+
+
+
+
+ eos
+
+ metadata_7 = <<-eos
+
+
+
+
+
+ MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1dX3Gr...
+
+
+
+
+
+ eos
+
describe IncomingMetadata do
it 'should properly set sign_assertions to false' do
metadata = SamlIdp::IncomingMetadata.new(metadata_1)
expect(metadata.sign_assertions).to eq(false)
- expect(metadata.sign_authn_request).to eq(false)
end
it 'should properly set entity_id as https://test-saml.com/saml' do
@@ -56,5 +98,37 @@ module SamlIdp
metadata = SamlIdp::IncomingMetadata.new(metadata_4)
expect(metadata.sign_authn_request).to eq(false)
end
+
+ it 'should properly set unspecified_certificate when present' do
+ metadata = SamlIdp::IncomingMetadata.new(metadata_5)
+ expect(metadata.unspecified_certificate).to eq('MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnht3GR...')
+ end
+
+ it 'should return empty unspecified_certificate when not present' do
+ metadata = SamlIdp::IncomingMetadata.new(metadata_1)
+ expect(metadata.unspecified_certificate).to eq('')
+ end
+
+ it 'should properly set signing_certificate when present but not unspecified_certificate' do
+ metadata = SamlIdp::IncomingMetadata.new(metadata_6)
+ expect(metadata.signing_certificate).to eq('MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmw6vGr...')
+ expect(metadata.unspecified_certificate).to eq('')
+ end
+
+ it 'should return empty signing_certificate when not present' do
+ metadata = SamlIdp::IncomingMetadata.new(metadata_1)
+ expect(metadata.signing_certificate).to eq('')
+ end
+
+ it 'should properly set encryption_certificate when present but not unspecified_certificate' do
+ metadata = SamlIdp::IncomingMetadata.new(metadata_7)
+ expect(metadata.encryption_certificate).to eq('MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1dX3Gr...')
+ expect(metadata.unspecified_certificate).to eq('')
+ end
+
+ it 'should return empty encryption_certificate when not present' do
+ metadata = SamlIdp::IncomingMetadata.new(metadata_1)
+ expect(metadata.encryption_certificate).to eq('')
+ end
end
end
diff --git a/spec/lib/saml_idp/logout_request_builder_spec.rb b/spec/lib/saml_idp/logout_request_builder_spec.rb
index 73f0a626..26890159 100644
--- a/spec/lib/saml_idp/logout_request_builder_spec.rb
+++ b/spec/lib/saml_idp/logout_request_builder_spec.rb
@@ -19,11 +19,13 @@ module SamlIdp
subject do
described_class.new(
- response_id,
- issuer_uri,
- saml_slo_url,
- name_id,
- algorithm
+ response_id: response_id,
+ issuer_uri: issuer_uri,
+ saml_slo_url: saml_slo_url,
+ name_id: name_id,
+ algorithm: algorithm,
+ public_cert: SamlIdp::Default::X509_CERTIFICATE,
+ private_key: SamlIdp::Default::SECRET_KEY
)
end
diff --git a/spec/lib/saml_idp/logout_response_builder_spec.rb b/spec/lib/saml_idp/logout_response_builder_spec.rb
index a4ca7bfd..44f730dd 100644
--- a/spec/lib/saml_idp/logout_response_builder_spec.rb
+++ b/spec/lib/saml_idp/logout_response_builder_spec.rb
@@ -19,11 +19,13 @@ module SamlIdp
subject do
described_class.new(
- response_id,
- issuer_uri,
- saml_slo_url,
- request_id,
- algorithm
+ response_id: response_id,
+ issuer_uri: issuer_uri,
+ saml_slo_url: saml_slo_url,
+ saml_request_id: request_id,
+ algorithm: algorithm,
+ public_cert: SamlIdp::Default::X509_CERTIFICATE,
+ private_key: SamlIdp::Default::SECRET_KEY
)
end
diff --git a/spec/lib/saml_idp/metadata_builder_spec.rb b/spec/lib/saml_idp/metadata_builder_spec.rb
index c8e14765..2b84c295 100644
--- a/spec/lib/saml_idp/metadata_builder_spec.rb
+++ b/spec/lib/saml_idp/metadata_builder_spec.rb
@@ -6,7 +6,7 @@ module SamlIdp
end
it "signs valid xml" do
- expect(Saml::XML::Document.parse(subject.signed).valid_signature?(Default::FINGERPRINT)).to be_truthy
+ expect(Saml::XML::Document.parse(subject.signed).valid_signature?("", Default::FINGERPRINT)).to be_truthy
end
it "includes logout element" do
@@ -71,5 +71,36 @@ module SamlIdp
subject.configurator.single_logout_service_redirect_location = 'https://example.com/saml/logout'
expect(subject.fresh).to match('')
end
+
+ context 'with custom configurator' do
+ let(:certificate) {'a certificate'}
+ let(:configurator) do SamlIdp::Configurator.new.tap do |c|
+ c.secret_key = 'a private key'
+ c.x509_certificate = certificate
+ end
+ end
+ subject { described_class.new(configurator) }
+
+ describe '.private_key' do
+ it 'returns the given private_key' do
+ expect(subject.private_key).to eq(configurator.secret_key)
+ end
+ end
+
+ describe '.x509_certificate' do
+ context 'with a given certificate string' do
+ it 'returns the given certificate' do
+ expect(subject.x509_certificate).to eq('a certificate')
+ end
+ end
+
+ context 'with a given certificate proc' do
+ let(:certificate) {Proc.new { "a certificate from proc"}}
+ it 'returns the given certificate' do
+ expect(subject.x509_certificate).to eq('a certificate from proc')
+ end
+ end
+ end
+ end
end
end
diff --git a/spec/lib/saml_idp/request_spec.rb b/spec/lib/saml_idp/request_spec.rb
index 47711539..151e391a 100644
--- a/spec/lib/saml_idp/request_spec.rb
+++ b/spec/lib/saml_idp/request_spec.rb
@@ -1,157 +1,195 @@
require 'spec_helper'
-module SamlIdp
- describe Request do
- let(:issuer) { 'localhost:3000' }
- let(:raw_authn_request) do
- "#{issuer}urn:oasis:names:tc:SAML:2.0:ac:classes:Password"
- end
- describe "deflated request" do
- let(:deflated_request) { Base64.encode64(Zlib::Deflate.deflate(raw_authn_request, 9)[2..-5]) }
+RSpec.describe SamlIdp::Request, type: :model do
+ let(:valid_saml_request) { make_saml_request("https://foo.example.com/saml/consume", true) }
+ let(:valid_logout_request) { make_saml_sp_slo_request(security_options: { embed_sign: true })['SAMLRequest'] }
+ let(:invalid_saml_request) { "invalid_saml_request" }
+ let(:external_attributes) { { saml_request: valid_saml_request, relay_state: "state" } }
- subject { described_class.from_deflated_request deflated_request }
+ describe ".from_deflated_request" do
+ context "when request is valid and deflated" do
+ it "inflates and decodes the request" do
+ request = SamlIdp::Request.from_deflated_request(valid_saml_request)
- it "inflates" do
- expect(subject.request_id).to eq("_af43d1a0-e111-0130-661a-3c0754403fdb")
+ expect { Saml::XML::Document.parse(request.raw_xml) }.not_to raise_error
end
+ end
- it "handles invalid SAML" do
- req = described_class.from_deflated_request "bang!"
- expect(req.valid?).to eq(false)
+ context "when request is invalid" do
+ it "returns an empty inflated string" do
+ request = SamlIdp::Request.from_deflated_request(nil)
+ expect(request.raw_xml).to eq("")
end
end
+ end
- describe "authn request" do
- subject { described_class.new raw_authn_request }
-
- it "has a valid request_id" do
- expect(subject.request_id).to eq("_af43d1a0-e111-0130-661a-3c0754403fdb")
- end
+ describe "#logout_request?" do
+ it "returns true for a valid logout request" do
+ request = SamlIdp::Request.from_deflated_request(valid_logout_request)
+ expect(request.logout_request?).to be true
+ end
- it "has a valid acs_url" do
- expect(subject.acs_url).to eq("http://localhost:3000/saml/consume")
- end
+ it "returns false for a non-logout request" do
+ request = SamlIdp::Request.from_deflated_request(valid_saml_request)
+ expect(request.logout_request?).to be false
+ end
+ end
- it "has a valid service_provider" do
- expect(subject.service_provider).to be_a ServiceProvider
- end
+ describe "#authn_request?" do
+ it "returns true for a valid authn request" do
+ request = SamlIdp::Request.from_deflated_request(valid_saml_request)
+ expect(request.authn_request?).to be true
+ end
- it "has a valid service_provider" do
- expect(subject.service_provider).to be_truthy
- end
+ it "returns false for a non-authn request" do
+ request = SamlIdp::Request.from_deflated_request(valid_logout_request)
+ expect(request.authn_request?).to be false
+ end
+ end
- it "has a valid issuer" do
- expect(subject.issuer).to eq("localhost:3000")
- end
+ describe "#valid?" do
+ let(:sp_issuer) { "test_issuer" }
+ let(:valid_service_provider) do
+ instance_double(
+ "SamlIdp::ServiceProvider",
+ valid?: true,
+ acs_url: 'https://foo.example.com/saml/consume',
+ current_metadata: instance_double("Metadata", sign_authn_request?: true),
+ assertion_consumer_logout_service_url: 'https://foo.example.com/saml/logout',
+ sign_authn_request: true,
+ acceptable_response_hosts: ["foo.example.com"],
+ cert: sp_x509_cert,
+ fingerprint: SamlIdp::Fingerprint.certificate_digest(sp_x509_cert, :sha256),
+ )
+ end
+
+ before do
+ allow_any_instance_of(SamlIdp::Request).to receive(:service_provider).and_return(valid_service_provider)
+ allow_any_instance_of(SamlIdp::Request).to receive(:issuer).and_return(sp_issuer)
+ end
- it "has a valid valid_signature" do
- expect(subject.valid_signature?).to be_truthy
+ context "when the request is valid" do
+ it "returns true for a valid authn request" do
+ request = SamlIdp::Request.from_deflated_request(valid_saml_request)
+ expect(request.errors).to be_empty
+ expect(request.valid?).to be true
end
- it "should return acs_url for response_url" do
- expect(subject.response_url).to eq(subject.acs_url)
+ it "returns true for a valid logout request" do
+ request = SamlIdp::Request.from_deflated_request(valid_logout_request)
+ expect(request.errors).to be_empty
+ expect(request.valid?).to be true
end
+ end
- it "is a authn request" do
- expect(subject.authn_request?).to eq(true)
- end
+ context 'when signature provided as external param' do
+ let!(:uri_query) { make_saml_sp_slo_request(security_options: { embed_sign: false }) }
+ let(:raw_saml_request) { uri_query['SAMLRequest'] }
+ let(:relay_state) { uri_query['RelayState'] }
+ let(:siging_algorithm) { uri_query['SigAlg'] }
+ let(:signature) { uri_query['Signature'] }
- it "fetches internal request" do
- expect(subject.request['ID']).to eq(subject.request_id)
+ subject do
+ described_class.from_deflated_request(
+ raw_saml_request,
+ saml_request: raw_saml_request,
+ relay_state: relay_state,
+ sig_algorithm: siging_algorithm,
+ signature: signature
+ )
end
- it 'has a valid authn context' do
- expect(subject.requested_authn_context).to eq('urn:oasis:names:tc:SAML:2.0:ac:classes:Password')
+ it "should validate the request" do
+ expect(subject.valid_external_signature?).to be true
+ expect(subject.errors).to be_empty
end
- context 'the issuer is empty' do
- let(:issuer) { nil }
- let(:logger) { ->(msg) { puts msg } }
-
- before do
- allow(SamlIdp.config).to receive(:logger).and_return(logger)
- end
-
- it 'is invalid' do
- expect(subject.issuer).to_not eq('')
- expect(subject.issuer).to be_nil
- expect(subject.valid?).to eq(false)
- end
-
- context 'a Ruby Logger is configured' do
- let(:logger) { Logger.new($stdout) }
-
- before do
- allow(logger).to receive(:info)
- end
-
- it 'logs an error message' do
- expect(subject.valid?).to be false
- expect(logger).to have_received(:info).with('Unable to find service provider for issuer ')
- end
- end
-
- context 'a Logger-like logger is configured' do
- let(:logger) do
- Class.new {
- def info(msg); end
- }.new
- end
-
- before do
- allow(logger).to receive(:info)
- end
-
- it 'logs an error message' do
- expect(subject.valid?).to be false
- expect(logger).to have_received(:info).with('Unable to find service provider for issuer ')
- end
- end
-
- context 'a logger lambda is configured' do
- let(:logger) { double }
-
- before { allow(logger).to receive(:call) }
-
- it 'logs an error message' do
- expect(subject.valid?).to be false
- expect(logger).to have_received(:call).with('Unable to find service provider for issuer ')
- end
- end
+ it "should collect errors when the signature is invalid" do
+ allow(subject).to receive(:valid_external_signature?).and_return(false)
+ expect(subject.valid?).to eq(false)
+ expect(subject.errors).to include(:invalid_external_signature)
end
end
- describe "logout request" do
- let(:raw_logout_request) { "http://example.comsome_name_idabc123index" }
-
- subject { described_class.new raw_logout_request }
+ context "when the service provider is invalid" do
+ it "returns false and logs an error" do
+ allow_any_instance_of(SamlIdp::Request).to receive(:service_provider?).and_return(false)
+ request = SamlIdp::Request.from_deflated_request(valid_saml_request)
- it "has a valid request_id" do
- expect(subject.request_id).to eq('_some_response_id')
+ expect(request.valid?).to be false
+ expect(request.errors).to include(:sp_not_found)
end
+ end
- it "should be flagged as a logout_request" do
- expect(subject.logout_request?).to eq(true)
+ context "when empty certificate for authn request validation" do
+ let(:valid_service_provider) do
+ instance_double(
+ "SamlIdp::ServiceProvider",
+ valid?: true,
+ acs_url: 'https://foo.example.com/saml/consume',
+ current_metadata: instance_double("Metadata", sign_authn_request?: true),
+ assertion_consumer_logout_service_url: 'https://foo.example.com/saml/logout',
+ sign_authn_request: true,
+ acceptable_response_hosts: ["foo.example.com"],
+ cert: nil,
+ fingerprint: nil,
+ )
+ end
+ it "returns false and logs an error" do
+ request = SamlIdp::Request.from_deflated_request(valid_saml_request)
+
+ expect(request.valid?).to be false
+ expect(request.errors).to include(:empty_certificate)
end
+ end
- it "should have a valid name_id" do
- expect(subject.name_id).to eq('some_name_id')
+ context "when empty certificate for logout validation" do
+ let(:valid_service_provider) do
+ instance_double(
+ "SamlIdp::ServiceProvider",
+ valid?: true,
+ acs_url: 'https://foo.example.com/saml/consume',
+ current_metadata: instance_double("Metadata", sign_authn_request?: true),
+ assertion_consumer_logout_service_url: 'https://foo.example.com/saml/logout',
+ sign_authn_request: true,
+ acceptable_response_hosts: ["foo.example.com"],
+ cert: nil,
+ fingerprint: nil,
+ )
end
- it "should have a session index" do
- expect(subject.session_index).to eq('abc123index')
+ before do
+ allow_any_instance_of(SamlIdp::Request).to receive(:authn_request?).and_return(false)
+ allow_any_instance_of(SamlIdp::Request).to receive(:logout_request?).and_return(true)
end
- it "should have a valid issuer" do
- expect(subject.issuer).to eq('http://example.com')
+ it "returns false and logs an error" do
+ request = SamlIdp::Request.from_deflated_request(valid_saml_request)
+
+ expect(request.valid?).to be false
+ expect(request.errors).to include(:empty_certificate)
end
+ end
- it "fetches internal request" do
- expect(subject.request['ID']).to eq(subject.request_id)
+ context "when both authn and logout requests are present" do
+ it "returns false and logs an error" do
+ allow_any_instance_of(SamlIdp::Request).to receive(:authn_request?).and_return(true)
+ allow_any_instance_of(SamlIdp::Request).to receive(:logout_request?).and_return(true)
+ request = SamlIdp::Request.from_deflated_request(valid_saml_request)
+
+ expect(request.valid?).to be false
+ expect(request.errors).to include(:unaccepted_request)
end
+ end
+
+ context "when the signature is invalid" do
+ it "returns false and logs an error" do
+ allow_any_instance_of(SamlIdp::Request).to receive(:valid_signature?).and_return(false)
+ allow_any_instance_of(SamlIdp::Request).to receive(:log)
+ request = SamlIdp::Request.from_deflated_request(valid_saml_request)
- it "should return logout_url for response_url" do
- expect(subject.response_url).to eq(subject.logout_url)
+ expect(request.valid?).to be false
+ expect(request.errors).to include(:invalid_embedded_signature)
end
end
end
diff --git a/spec/lib/saml_idp/response_builder_spec.rb b/spec/lib/saml_idp/response_builder_spec.rb
index 9105eede..ce5224e8 100644
--- a/spec/lib/saml_idp/response_builder_spec.rb
+++ b/spec/lib/saml_idp/response_builder_spec.rb
@@ -8,12 +8,15 @@ module SamlIdp
let(:assertion_and_signature) { "http://sportngin.comstuffjon.phenow@sportngin.comhttp://example.comjon.phenow@sportngin.comurn:federation:authentication:windows" }
let(:algorithm) { :sha256 }
subject { described_class.new(
- response_id,
- issuer_uri,
- saml_acs_url,
- saml_request_id,
- assertion_and_signature,
- algorithm
+ response_id: response_id,
+ issuer_uri: issuer_uri,
+ saml_acs_url: saml_acs_url,
+ saml_request_id: saml_request_id,
+ assertion_and_signature: assertion_and_signature,
+ raw_algorithm: algorithm,
+ public_cert: sp_encrypted_pv_key[:sp_public_cert],
+ private_key: sp_encrypted_pv_key[:sp_encrypted_pv_key],
+ pv_key_password: sp_encrypted_pv_key[:pv_key_password],
) }
before do
diff --git a/spec/lib/saml_idp/saml_response_spec.rb b/spec/lib/saml_idp/saml_response_spec.rb
index a9e82151..f702054c 100644
--- a/spec/lib/saml_idp/saml_response_spec.rb
+++ b/spec/lib/saml_idp/saml_response_spec.rb
@@ -28,43 +28,50 @@ module SamlIdp
let(:unsigned_response_opts) { false }
let(:signed_assertion_opts) { true }
let(:compress_opts) { false }
- let(:subject_encrypted) { described_class.new(reference_id,
- response_id,
- issuer_uri,
- name_id,
- audience_uri,
- saml_request_id,
- saml_acs_url,
- algorithm,
- authn_context_classref,
- expiry,
- encryption_opts,
- session_expiry,
- nil,
- nil,
- unsigned_response_opts,
- signed_assertion_opts,
- compress_opts
+ let(:subject_encrypted) { described_class.new(
+ reference_id: reference_id,
+ response_id: response_id,
+ issuer_uri: issuer_uri,
+ principal: name_id,
+ audience_uri: audience_uri,
+ saml_request_id: saml_request_id,
+ saml_acs_url: saml_acs_url,
+ algorithm: algorithm,
+ authn_context_classref: authn_context_classref,
+ public_cert: x509_certificate,
+ private_key: secret_key,
+ pv_key_password: nil,
+ expiry: expiry,
+ encryption_opts: encryption_opts,
+ session_expiry: session_expiry,
+ name_id_formats_opts: nil,
+ asserted_attributes_opts: nil,
+ signed_message_opts: unsigned_response_opts,
+ signed_assertion_opts: signed_assertion_opts,
+ compression_opts: compress_opts
)
}
- subject { described_class.new(reference_id,
- response_id,
- issuer_uri,
- name_id,
- audience_uri,
- saml_request_id,
- saml_acs_url,
- algorithm,
- authn_context_classref,
- expiry,
- nil,
- session_expiry,
- nil,
- nil,
- signed_response_opts,
- signed_assertion_opts,
- compress_opts
+ subject { described_class.new(reference_id: reference_id,
+ response_id: response_id,
+ issuer_uri: issuer_uri,
+ principal: name_id,
+ audience_uri: audience_uri,
+ saml_request_id: saml_request_id,
+ saml_acs_url: saml_acs_url,
+ algorithm: algorithm,
+ authn_context_classref: authn_context_classref,
+ public_cert: x509_certificate,
+ private_key: secret_key,
+ pv_key_password: nil,
+ expiry: expiry,
+ encryption_opts: nil,
+ session_expiry: session_expiry,
+ name_id_formats_opts: nil,
+ asserted_attributes_opts: nil,
+ signed_message_opts: signed_response_opts,
+ signed_assertion_opts: signed_assertion_opts,
+ compression_opts: compress_opts
)
}
@@ -192,6 +199,25 @@ module SamlIdp
expect(saml_resp.is_valid?).to eq(true)
end
+ it "will pass reference_id as SessionIndex" do
+ expect { subject.build }.not_to raise_error
+ signed_encoded_xml = subject.build
+ resp_settings = saml_settings(saml_acs_url)
+ resp_settings.private_key = Default::SECRET_KEY
+ resp_settings.issuer = audience_uri
+ saml_resp = OneLogin::RubySaml::Response.new(signed_encoded_xml, settings: resp_settings)
+
+ expect(
+ Nokogiri::XML(saml_resp.response).at_xpath(
+ "//saml:AuthnStatement/@SessionIndex",
+ {
+ "samlp" => "urn:oasis:names:tc:SAML:2.0:protocol",
+ "saml" => "urn:oasis:names:tc:SAML:2.0:assertion"
+ }
+ ).value
+ ).to eq("_#{reference_id}")
+ end
+
it "sets session expiration" do
saml_resp = OneLogin::RubySaml::Response.new(subject.build)
expect(saml_resp.session_expires_at).to eq Time.local(1990, "jan", 2).iso8601
diff --git a/spec/lib/saml_idp/signable_spec.rb b/spec/lib/saml_idp/signable_spec.rb
index cd9a90ae..0d033780 100644
--- a/spec/lib/saml_idp/signable_spec.rb
+++ b/spec/lib/saml_idp/signable_spec.rb
@@ -1,7 +1,9 @@
# encoding: utf-8
require 'spec_helper'
+
class MockSignable
include SamlIdp::Signable
+ include SecurityHelpers
def raw
builder = Builder::XmlMarkup.new
@@ -21,6 +23,18 @@ def digest
def algorithm
OpenSSL::Digest::SHA1
end
+
+ def private_key
+ sp_encrypted_pv_key[:sp_encrypted_pv_key]
+ end
+
+ def pv_key_password
+ sp_encrypted_pv_key[:pv_key_password]
+ end
+
+ def public_cert
+ sp_encrypted_pv_key[:sp_public_cert]
+ end
end
module SamlIdp
@@ -72,6 +86,5 @@ module SamlIdp
it "has a valid signed" do
expect(subject.signed).to match all_regex
end
-
end
end
diff --git a/spec/lib/saml_idp/signature_builder_spec.rb b/spec/lib/saml_idp/signature_builder_spec.rb
index ff28575a..8fe612b2 100644
--- a/spec/lib/saml_idp/signature_builder_spec.rb
+++ b/spec/lib/saml_idp/signature_builder_spec.rb
@@ -5,7 +5,8 @@ module SamlIdp
let(:raw_info) { "em8csGAWynywpe8S4nN64o56/4DosXi2XWMY6RJ6YfA=" }
let(:signed_info) { double raw: raw_info, signed: signed }
subject { described_class.new(
- signed_info
+ signed_info,
+ SamlIdp::Default::X509_CERTIFICATE
) }
before do
diff --git a/spec/lib/saml_idp/signed_info_builder_spec.rb b/spec/lib/saml_idp/signed_info_builder_spec.rb
index 4685d39a..0ac39966 100644
--- a/spec/lib/saml_idp/signed_info_builder_spec.rb
+++ b/spec/lib/saml_idp/signed_info_builder_spec.rb
@@ -1,4 +1,5 @@
require 'spec_helper'
+
module SamlIdp
describe SignedInfoBuilder do
let(:reference_id) { "abc" }
@@ -7,7 +8,9 @@ module SamlIdp
subject { described_class.new(
reference_id,
digest,
- algorithm
+ algorithm,
+ sp_encrypted_pv_key[:sp_encrypted_pv_key],
+ sp_encrypted_pv_key[:pv_key_password]
) }
before do
@@ -19,7 +22,7 @@ module SamlIdp
end
it "builds a legit digest of the XML file" do
- expect(subject.signed).to eq("hKLeWLRgatHcV6N5Fc8aKveqNp6Y/J4m2WSYp0awGFtsCTa/2nab32wI3du+3kuuIy59EDKeUhHVxEfyhoHUo6xTZuO2N7XcTpSonuZ/CB3WjozC2Q/9elss3z1rOC3154v5pW4puirLPRoG+Pwi8SmptxNRHczr6NvmfYmmGfo=")
+ expect(subject.signed).to eq("YP2e6cTEfRj1vI1/gaaSApLAMxPBQzyuBvbvulbS99x17LCLDSKvqA6MyU4WLavmVba5qiF88e97f0XKLsse7gEGOfnF/6jaRV3fePXk6+LFaeYUHZ11u7PkZ1/ucO459ASsuPN/9P9xCY2t+jtVKvIrcSZQbomymfsWGt9P/oY83elKU712aAwqcfvINsa1N+RefZRwdAW4ATBwwcDjE3VTR6mKOyGMsPJ4HQcPrNiEmuwd1QaPH0H1LLzxtewGQGmIL2UqNE/QMe/kKiSTFZ0loBKuSEc9WBw5XuH31QxbzpLJjqM/C1qy4aykPqDUuJtQ4csx78GgfFS4uiqowg==")
end
end
end
diff --git a/spec/rails_app/app/views/saml_idp/idp/new.html.erb b/spec/rails_app/app/views/saml_idp/idp/new.html.erb
index c71d85ab..01c86199 100644
--- a/spec/rails_app/app/views/saml_idp/idp/new.html.erb
+++ b/spec/rails_app/app/views/saml_idp/idp/new.html.erb
@@ -4,6 +4,9 @@
<%= form_tag do %>
<%= hidden_field_tag("SAMLRequest", params[:SAMLRequest]) %>
<%= hidden_field_tag("RelayState", params[:RelayState]) %>
+ <%= hidden_field_tag("SigAlg", params[:SigAlg]) %>
+ <%= hidden_field_tag("Signature", params[:Signature]) %>
+
<%= label_tag :email %>
<%= email_field_tag :email, params[:email], :autocapitalize => "off", :autocorrect => "off", :autofocus => "autofocus", :spellcheck => "false", :size => 30, :class => "email_pwd txt" %>
diff --git a/spec/rails_app/app/views/saml_idp/idp/saml_post.html.erb b/spec/rails_app/app/views/saml_idp/idp/saml_post.html.erb
index f79890c8..5c0c3d0d 100644
--- a/spec/rails_app/app/views/saml_idp/idp/saml_post.html.erb
+++ b/spec/rails_app/app/views/saml_idp/idp/saml_post.html.erb
@@ -5,10 +5,10 @@
- <%= form_tag(saml_acs_url) do %>
+