2022-05-14 03:53:04 +00:00
|
|
|
require File.expand_path(File.join(File.dirname(__FILE__), "test_helper"))
|
|
|
|
|
|
|
|
require 'onelogin/ruby-saml/settings'
|
|
|
|
require 'onelogin/ruby-saml/validation_error'
|
|
|
|
|
|
|
|
class SettingsTest < Minitest::Test
|
|
|
|
|
|
|
|
describe "Settings" do
|
|
|
|
before do
|
|
|
|
@settings = OneLogin::RubySaml::Settings.new
|
|
|
|
end
|
|
|
|
|
|
|
|
it "should provide getters and settings" do
|
|
|
|
accessors = [
|
|
|
|
:idp_entity_id, :idp_sso_target_url, :idp_sso_service_url, :idp_slo_target_url, :idp_slo_service_url, :valid_until,
|
|
|
|
:idp_cert, :idp_cert_fingerprint, :idp_cert_fingerprint_algorithm, :idp_cert_multi,
|
|
|
|
:idp_attribute_names, :issuer, :assertion_consumer_service_url, :single_logout_service_url,
|
|
|
|
:sp_name_qualifier, :name_identifier_format, :name_identifier_value, :name_identifier_value_requested,
|
|
|
|
:sessionindex, :attributes_index, :passive, :force_authn,
|
|
|
|
:compress_request, :double_quote_xml_attribute_values, :message_max_bytesize,
|
|
|
|
:security, :certificate, :private_key,
|
|
|
|
:authn_context, :authn_context_comparison, :authn_context_decl_ref,
|
|
|
|
:assertion_consumer_logout_service_url
|
|
|
|
]
|
|
|
|
|
|
|
|
accessors.each do |accessor|
|
|
|
|
value = Kernel.rand
|
|
|
|
@settings.send("#{accessor}=".to_sym, value)
|
|
|
|
assert_equal value, @settings.send(accessor)
|
|
|
|
|
|
|
|
@settings.send("#{accessor}=".to_sym, nil)
|
|
|
|
assert_nil @settings.send(accessor)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
it "should provide getters and settings for binding parameters" do
|
|
|
|
accessors = [
|
|
|
|
:protocol_binding, :assertion_consumer_service_binding,
|
|
|
|
:single_logout_service_binding, :assertion_consumer_logout_service_binding
|
|
|
|
]
|
|
|
|
|
|
|
|
accessors.each do |accessor|
|
|
|
|
value = Kernel.rand.to_s
|
|
|
|
@settings.send("#{accessor}=".to_sym, value)
|
|
|
|
assert_equal value, @settings.send(accessor)
|
|
|
|
|
|
|
|
@settings.send("#{accessor}=".to_sym, :redirect)
|
|
|
|
assert_equal "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect", @settings.send(accessor)
|
|
|
|
|
|
|
|
@settings.send("#{accessor}=".to_sym, :post)
|
|
|
|
assert_equal "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST", @settings.send(accessor)
|
|
|
|
|
|
|
|
@settings.send("#{accessor}=".to_sym, nil)
|
|
|
|
assert_nil @settings.send(accessor)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
it "idp_sso/slo_service_binding should fallback to :embed_sign inferred value" do
|
|
|
|
accessors = [:idp_sso_service_binding, :idp_slo_service_binding]
|
|
|
|
|
|
|
|
accessors.each do |accessor|
|
|
|
|
@settings.security[:embed_sign] = true
|
|
|
|
|
|
|
|
value = Kernel.rand.to_s
|
|
|
|
@settings.send("#{accessor}=".to_sym, value)
|
|
|
|
assert_equal value, @settings.send(accessor)
|
|
|
|
|
|
|
|
@settings.send("#{accessor}=".to_sym, :redirect)
|
|
|
|
assert_equal "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect", @settings.send(accessor)
|
|
|
|
|
|
|
|
@settings.send("#{accessor}=".to_sym, :post)
|
|
|
|
assert_equal "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST", @settings.send(accessor)
|
|
|
|
|
|
|
|
@settings.send("#{accessor}=".to_sym, nil)
|
|
|
|
assert_equal "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST", @settings.send(accessor)
|
|
|
|
|
|
|
|
@settings.security[:embed_sign] = false
|
|
|
|
assert_equal "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect", @settings.send(accessor)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
it "create settings from hash" do
|
|
|
|
config = {
|
|
|
|
:assertion_consumer_service_url => "http://app.muda.no/sso",
|
|
|
|
:issuer => "http://muda.no",
|
|
|
|
:sp_name_qualifier => "http://sso.muda.no",
|
|
|
|
:idp_sso_service_url => "http://sso.muda.no/sso",
|
|
|
|
:idp_sso_service_binding => "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST",
|
|
|
|
:idp_slo_service_url => "http://sso.muda.no/slo",
|
|
|
|
:idp_slo_service_binding => "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST",
|
|
|
|
:idp_cert_fingerprint => "00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00",
|
|
|
|
:message_max_bytesize => 750000,
|
|
|
|
:valid_until => '2029-04-16T03:35:08.277Z',
|
|
|
|
:name_identifier_format => "urn:oasis:names:tc:SAML:2.0:nameid-format:transient",
|
|
|
|
:attributes_index => 30,
|
|
|
|
:passive => true,
|
|
|
|
:protocol_binding => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST'
|
|
|
|
}
|
|
|
|
@settings = OneLogin::RubySaml::Settings.new(config)
|
|
|
|
|
|
|
|
config.each do |k,v|
|
|
|
|
assert_equal v, @settings.send(k)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
it "configure attribute service attributes correctly" do
|
|
|
|
@settings.attribute_consuming_service.configure do
|
|
|
|
service_name "Test Service"
|
|
|
|
add_attribute :name => "Name", :name_format => "Name Format", :friendly_name => "Friendly Name"
|
|
|
|
end
|
|
|
|
|
|
|
|
assert_equal @settings.attribute_consuming_service.configured?, true
|
|
|
|
assert_equal @settings.attribute_consuming_service.name, "Test Service"
|
|
|
|
assert_equal @settings.attribute_consuming_service.attributes, [{:name => "Name", :name_format => "Name Format", :friendly_name => "Friendly Name" }]
|
|
|
|
end
|
|
|
|
|
|
|
|
it "does not modify default security settings" do
|
|
|
|
settings = OneLogin::RubySaml::Settings.new
|
|
|
|
settings.security[:authn_requests_signed] = true
|
|
|
|
settings.security[:embed_sign] = true
|
|
|
|
settings.security[:digest_method] = XMLSecurity::Document::SHA256
|
|
|
|
settings.security[:signature_method] = XMLSecurity::Document::RSA_SHA256
|
|
|
|
|
|
|
|
new_settings = OneLogin::RubySaml::Settings.new
|
|
|
|
assert_equal new_settings.security[:authn_requests_signed], false
|
|
|
|
assert_equal new_settings.security[:embed_sign], false
|
|
|
|
assert_equal new_settings.security[:digest_method], XMLSecurity::Document::SHA1
|
|
|
|
assert_equal new_settings.security[:signature_method], XMLSecurity::Document::RSA_SHA1
|
|
|
|
end
|
|
|
|
|
|
|
|
it "overrides only provided security attributes passing a second parameter" do
|
|
|
|
config = {
|
|
|
|
:security => {
|
|
|
|
:metadata_signed => true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@default_attributes = OneLogin::RubySaml::Settings::DEFAULTS
|
|
|
|
|
|
|
|
@settings = OneLogin::RubySaml::Settings.new(config, true)
|
|
|
|
assert_equal @settings.security[:metadata_signed], true
|
|
|
|
assert_equal @settings.security[:digest_method], @default_attributes[:security][:digest_method]
|
|
|
|
end
|
|
|
|
|
|
|
|
it "doesn't override only provided security attributes without passing a second parameter" do
|
|
|
|
config = {
|
|
|
|
:security => {
|
|
|
|
:metadata_signed => true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@default_attributes = OneLogin::RubySaml::Settings::DEFAULTS
|
|
|
|
|
|
|
|
@settings = OneLogin::RubySaml::Settings.new(config)
|
|
|
|
assert_equal @settings.security[:metadata_signed], true
|
|
|
|
assert_nil @settings.security[:digest_method]
|
|
|
|
end
|
|
|
|
|
|
|
|
describe "#single_logout_service_url" do
|
|
|
|
it "when single_logout_service_url is nil but assertion_consumer_logout_service_url returns its value" do
|
|
|
|
@settings.single_logout_service_url = nil
|
|
|
|
@settings.assertion_consumer_logout_service_url = "http://app.muda.no/sls"
|
|
|
|
|
|
|
|
assert_equal "http://app.muda.no/sls", @settings.single_logout_service_url
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe "#single_logout_service_binding" do
|
|
|
|
it "when single_logout_service_binding is nil but assertion_consumer_logout_service_binding returns its value" do
|
|
|
|
@settings.single_logout_service_binding = nil
|
|
|
|
@settings.assertion_consumer_logout_service_binding = "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
|
|
|
|
|
|
|
|
assert_equal "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect", @settings.single_logout_service_binding
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe "#idp_sso_service_url" do
|
|
|
|
it "when idp_sso_service_url is nil but idp_sso_target_url returns its value" do
|
|
|
|
@settings.idp_sso_service_url = nil
|
|
|
|
@settings.idp_sso_target_url = "https://idp.example.com/sso"
|
|
|
|
|
|
|
|
assert_equal "https://idp.example.com/sso", @settings.idp_sso_service_url
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe "#idp_slo_service_url" do
|
|
|
|
it "when idp_slo_service_url is nil but idp_slo_target_url returns its value" do
|
|
|
|
@settings.idp_slo_service_url = nil
|
|
|
|
@settings.idp_slo_target_url = "https://idp.example.com/slo"
|
|
|
|
|
|
|
|
assert_equal "https://idp.example.com/slo", @settings.idp_slo_service_url
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe "#get_idp_cert" do
|
|
|
|
it "returns nil when the cert is an empty string" do
|
|
|
|
@settings.idp_cert = ""
|
|
|
|
assert_nil @settings.get_idp_cert
|
|
|
|
end
|
|
|
|
|
|
|
|
it "returns nil when the cert is nil" do
|
|
|
|
@settings.idp_cert = nil
|
|
|
|
assert_nil @settings.get_idp_cert
|
|
|
|
end
|
|
|
|
|
|
|
|
it "returns the certificate when it is valid" do
|
|
|
|
@settings.idp_cert = ruby_saml_cert_text
|
|
|
|
assert @settings.get_idp_cert.kind_of? OpenSSL::X509::Certificate
|
|
|
|
end
|
|
|
|
|
|
|
|
it "raises when the certificate is not valid" do
|
|
|
|
# formatted but invalid cert
|
|
|
|
@settings.idp_cert = read_certificate("formatted_certificate")
|
|
|
|
assert_raises(OpenSSL::X509::CertificateError) {
|
|
|
|
@settings.get_idp_cert
|
|
|
|
}
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe "#get_idp_cert_multi" do
|
|
|
|
it "returns nil when the value is empty" do
|
|
|
|
@settings.idp_cert = {}
|
|
|
|
assert_nil @settings.get_idp_cert_multi
|
|
|
|
end
|
|
|
|
|
|
|
|
it "returns nil when the idp_cert_multi is nil or empty" do
|
|
|
|
@settings.idp_cert_multi = nil
|
|
|
|
assert_nil @settings.get_idp_cert_multi
|
|
|
|
end
|
|
|
|
|
|
|
|
it "returns partial hash when contains some values" do
|
|
|
|
empty_multi = {
|
|
|
|
:signing => [],
|
|
|
|
:encryption => []
|
|
|
|
}
|
|
|
|
|
|
|
|
@settings.idp_cert_multi = {
|
|
|
|
:signing => []
|
|
|
|
}
|
|
|
|
assert_equal empty_multi, @settings.get_idp_cert_multi
|
|
|
|
|
|
|
|
@settings.idp_cert_multi = {
|
|
|
|
:encryption => []
|
|
|
|
}
|
|
|
|
assert_equal empty_multi, @settings.get_idp_cert_multi
|
|
|
|
|
|
|
|
@settings.idp_cert_multi = {
|
|
|
|
:signing => [],
|
|
|
|
:encryption => []
|
|
|
|
}
|
|
|
|
assert_equal empty_multi, @settings.get_idp_cert_multi
|
|
|
|
|
|
|
|
@settings.idp_cert_multi = {
|
|
|
|
:yyy => [],
|
|
|
|
:zzz => []
|
|
|
|
}
|
|
|
|
assert_equal empty_multi, @settings.get_idp_cert_multi
|
|
|
|
end
|
|
|
|
|
2023-02-13 15:21:45 +00:00
|
|
|
it "returns partial hash when contains some values with string keys" do
|
|
|
|
empty_multi = {
|
|
|
|
:signing => [],
|
|
|
|
:encryption => []
|
|
|
|
}
|
|
|
|
|
|
|
|
@settings.idp_cert_multi = {
|
|
|
|
"signing" => []
|
|
|
|
}
|
|
|
|
assert_equal empty_multi, @settings.get_idp_cert_multi
|
|
|
|
|
|
|
|
@settings.idp_cert_multi = {
|
|
|
|
"encryption" => []
|
|
|
|
}
|
|
|
|
assert_equal empty_multi, @settings.get_idp_cert_multi
|
|
|
|
|
|
|
|
@settings.idp_cert_multi = {
|
|
|
|
"signing" => [],
|
|
|
|
"encryption" => []
|
|
|
|
}
|
|
|
|
assert_equal empty_multi, @settings.get_idp_cert_multi
|
|
|
|
|
|
|
|
@settings.idp_cert_multi = {
|
|
|
|
"yyy" => [],
|
|
|
|
"zzz" => []
|
|
|
|
}
|
|
|
|
assert_equal empty_multi, @settings.get_idp_cert_multi
|
|
|
|
end
|
|
|
|
|
2022-05-14 03:53:04 +00:00
|
|
|
it "returns the hash with certificates when values were valid" do
|
2023-02-13 15:21:45 +00:00
|
|
|
certificates = [ruby_saml_cert_text]
|
|
|
|
@settings.idp_cert_multi = {
|
|
|
|
:signing => certificates,
|
|
|
|
:encryption => certificates,
|
|
|
|
}
|
|
|
|
|
|
|
|
assert @settings.get_idp_cert_multi.kind_of? Hash
|
|
|
|
assert @settings.get_idp_cert_multi[:signing].kind_of? Array
|
|
|
|
assert @settings.get_idp_cert_multi[:encryption].kind_of? Array
|
|
|
|
assert @settings.get_idp_cert_multi[:signing][0].kind_of? OpenSSL::X509::Certificate
|
|
|
|
assert @settings.get_idp_cert_multi[:encryption][0].kind_of? OpenSSL::X509::Certificate
|
|
|
|
end
|
|
|
|
|
|
|
|
it "returns the hash with certificates when values were valid and with string keys" do
|
|
|
|
certificates = [ruby_saml_cert_text]
|
2022-05-14 03:53:04 +00:00
|
|
|
@settings.idp_cert_multi = {
|
2023-02-13 15:21:45 +00:00
|
|
|
"signing" => certificates,
|
|
|
|
"encryption" => certificates,
|
2022-05-14 03:53:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
assert @settings.get_idp_cert_multi.kind_of? Hash
|
|
|
|
assert @settings.get_idp_cert_multi[:signing].kind_of? Array
|
|
|
|
assert @settings.get_idp_cert_multi[:encryption].kind_of? Array
|
|
|
|
assert @settings.get_idp_cert_multi[:signing][0].kind_of? OpenSSL::X509::Certificate
|
|
|
|
assert @settings.get_idp_cert_multi[:encryption][0].kind_of? OpenSSL::X509::Certificate
|
|
|
|
end
|
|
|
|
|
|
|
|
it "raises when there is a cert in idp_cert_multi not valid" do
|
|
|
|
certificate = read_certificate("formatted_certificate")
|
|
|
|
|
|
|
|
@settings.idp_cert_multi = {
|
|
|
|
:signing => [],
|
|
|
|
:encryption => []
|
|
|
|
}
|
|
|
|
@settings.idp_cert_multi[:signing].push(certificate)
|
|
|
|
@settings.idp_cert_multi[:encryption].push(certificate)
|
|
|
|
|
|
|
|
assert_raises(OpenSSL::X509::CertificateError) {
|
|
|
|
@settings.get_idp_cert_multi
|
|
|
|
}
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe "#get_sp_cert" do
|
|
|
|
it "returns nil when the cert is an empty string" do
|
|
|
|
@settings.certificate = ""
|
|
|
|
assert_nil @settings.get_sp_cert
|
|
|
|
end
|
|
|
|
|
|
|
|
it "returns nil when the cert is nil" do
|
|
|
|
@settings.certificate = nil
|
|
|
|
assert_nil @settings.get_sp_cert
|
|
|
|
end
|
|
|
|
|
|
|
|
it "returns the certificate when it is valid" do
|
|
|
|
@settings.certificate = ruby_saml_cert_text
|
|
|
|
assert @settings.get_sp_cert.kind_of? OpenSSL::X509::Certificate
|
|
|
|
end
|
|
|
|
|
|
|
|
it "raises when the certificate is not valid" do
|
|
|
|
# formatted but invalid cert
|
|
|
|
@settings.certificate = read_certificate("formatted_certificate")
|
|
|
|
assert_raises(OpenSSL::X509::CertificateError) { @settings.get_sp_cert }
|
|
|
|
end
|
|
|
|
|
|
|
|
it "raises an error if SP certificate expired and check_sp_cert_expiration enabled" do
|
|
|
|
@settings.certificate = ruby_saml_cert_text
|
|
|
|
@settings.security[:check_sp_cert_expiration] = true
|
|
|
|
assert_raises(OneLogin::RubySaml::ValidationError) { @settings.get_sp_cert }
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe "#get_sp_cert_new" do
|
|
|
|
it "returns nil when the cert is an empty string" do
|
|
|
|
@settings.certificate_new = ""
|
|
|
|
assert_nil @settings.get_sp_cert_new
|
|
|
|
end
|
|
|
|
|
|
|
|
it "returns nil when the cert is nil" do
|
|
|
|
@settings.certificate_new = nil
|
|
|
|
assert_nil @settings.get_sp_cert_new
|
|
|
|
end
|
|
|
|
|
|
|
|
it "returns the certificate when it is valid" do
|
|
|
|
@settings.certificate_new = ruby_saml_cert_text
|
|
|
|
assert @settings.get_sp_cert_new.kind_of? OpenSSL::X509::Certificate
|
|
|
|
end
|
|
|
|
|
|
|
|
it "raises when the certificate is not valid" do
|
|
|
|
# formatted but invalid cert
|
|
|
|
@settings.certificate_new = read_certificate("formatted_certificate")
|
|
|
|
assert_raises(OpenSSL::X509::CertificateError) {
|
|
|
|
@settings.get_sp_cert_new
|
|
|
|
}
|
|
|
|
end
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
describe "#get_sp_key" do
|
|
|
|
it "returns nil when the private key is an empty string" do
|
|
|
|
@settings.private_key = ""
|
|
|
|
assert_nil @settings.get_sp_key
|
|
|
|
end
|
|
|
|
|
|
|
|
it "returns nil when the private key is nil" do
|
|
|
|
@settings.private_key = nil
|
|
|
|
assert_nil @settings.get_sp_key
|
|
|
|
end
|
|
|
|
|
|
|
|
it "returns the private key when it is valid" do
|
|
|
|
@settings.private_key = ruby_saml_key_text
|
|
|
|
assert @settings.get_sp_key.kind_of? OpenSSL::PKey::RSA
|
|
|
|
end
|
|
|
|
|
|
|
|
it "raises when the private key is not valid" do
|
|
|
|
# formatted but invalid rsa private key
|
|
|
|
@settings.private_key = read_certificate("formatted_rsa_private_key")
|
|
|
|
assert_raises(OpenSSL::PKey::RSAError) {
|
|
|
|
@settings.get_sp_key
|
|
|
|
}
|
|
|
|
end
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
describe "#get_fingerprint" do
|
|
|
|
it "get the fingerprint value when cert and fingerprint in settings are nil" do
|
|
|
|
@settings.idp_cert_fingerprint = nil
|
|
|
|
@settings.idp_cert = nil
|
|
|
|
fingerprint = @settings.get_fingerprint
|
|
|
|
assert_nil fingerprint
|
|
|
|
end
|
|
|
|
|
|
|
|
it "get the fingerprint value when there is a cert at the settings" do
|
|
|
|
@settings.idp_cert_fingerprint = nil
|
|
|
|
@settings.idp_cert = ruby_saml_cert_text
|
|
|
|
fingerprint = @settings.get_fingerprint
|
|
|
|
assert fingerprint.downcase == ruby_saml_cert_fingerprint.downcase
|
|
|
|
end
|
|
|
|
|
|
|
|
it "get the fingerprint value when there is a fingerprint at the settings" do
|
|
|
|
@settings.idp_cert_fingerprint = ruby_saml_cert_fingerprint
|
|
|
|
@settings.idp_cert = nil
|
|
|
|
fingerprint = @settings.get_fingerprint
|
|
|
|
assert fingerprint.downcase == ruby_saml_cert_fingerprint.downcase
|
|
|
|
end
|
|
|
|
|
|
|
|
it "get the fingerprint value when there are cert and fingerprint at the settings" do
|
|
|
|
@settings.idp_cert_fingerprint = ruby_saml_cert_fingerprint
|
|
|
|
@settings.idp_cert = ruby_saml_cert_text
|
|
|
|
fingerprint = @settings.get_fingerprint
|
|
|
|
assert fingerprint.downcase == ruby_saml_cert_fingerprint.downcase
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|