From ae5745ac4769f166cd9bbc16acd288d35945b495 Mon Sep 17 00:00:00 2001 From: johnnyshields <27655+johnnyshields@users.noreply.github.com> Date: Wed, 10 Jul 2024 16:57:07 +0900 Subject: [PATCH] Alias/deprecate more params: - certificate --> sp_cert - private_key --> sp_private_key - assertion_consumer_service_url --> sp_assertion_consumer_service_url - assertion_consumer_service_binding --> sp_assertion_consumer_service_binding - single_logout_service_url --> sp_slo_service_url - single_logout_service_binding --> sp_slo_service_binding --- README.md | 38 ++++----- UPGRADING.md | 56 ++++++++++--- lib/ruby_saml/authrequest.rb | 4 +- lib/ruby_saml/logging.rb | 2 +- lib/ruby_saml/metadata.rb | 14 ++-- lib/ruby_saml/response.rb | 8 +- lib/ruby_saml/settings.rb | 62 ++++++++------ test/logging_test.rb | 8 ++ .../logoutresponse_fixtures.rb | 10 +-- test/logoutrequest_test.rb | 20 ++--- test/logoutresponse_test.rb | 8 +- test/metadata_test.rb | 18 ++-- test/onelogin_alias_test.rb | 2 +- test/request_test.rb | 22 ++--- test/response_test.rb | 68 +++++++-------- test/settings_deprecations_test.rb | 84 +++++++++++++++++++ test/settings_test.rb | 64 +++++++------- test/slo_logoutrequest_test.rb | 16 ++-- test/slo_logoutresponse_test.rb | 16 ++-- test/xml_test.rb | 4 +- 20 files changed, 327 insertions(+), 197 deletions(-) create mode 100644 test/settings_deprecations_test.rb diff --git a/README.md b/README.md index 4d5eb8ba..bcf46910 100644 --- a/README.md +++ b/README.md @@ -191,7 +191,7 @@ If you don't know what expect, always use the former (set the settings on initia def saml_settings settings = RubySaml::Settings.new - settings.assertion_consumer_service_url = "http://#{request.host}/saml/consume" + settings.sp_assertion_consumer_service_url = "http://#{request.host}/saml/consume" settings.sp_entity_id = "http://#{request.host}/saml/metadata" settings.idp_entity_id = "https://app.onelogin.com/saml/metadata/#{OneLoginAppId}" settings.idp_sso_service_url = "https://app.onelogin.com/trust/saml2/http-post/sso/#{OneLoginAppId}" @@ -211,8 +211,8 @@ def saml_settings ] # Optional bindings (defaults to Redirect for logout POST for ACS) - settings.single_logout_service_binding = "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" # or :post, :redirect - settings.assertion_consumer_service_binding = "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" # or :post, :redirect + settings.sp_slo_service_binding = "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" # or :post, :redirect + settings.sp_assertion_consumer_service_binding = "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" # or :post, :redirect settings end @@ -263,11 +263,11 @@ class SamlController < ApplicationController def saml_settings settings = RubySaml::Settings.new - settings.assertion_consumer_service_url = "http://#{request.host}/saml/consume" - settings.sp_entity_id = "http://#{request.host}/saml/metadata" - settings.idp_sso_service_url = "https://app.onelogin.com/saml/signon/#{OneLoginAppId}" - settings.idp_cert_fingerprint = OneLoginAppCertFingerPrint - settings.name_identifier_format = "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress" + settings.sp_assertion_consumer_service_url = "http://#{request.host}/saml/consume" + settings.sp_entity_id = "http://#{request.host}/saml/metadata" + settings.idp_sso_service_url = "https://app.onelogin.com/saml/signon/#{OneLoginAppId}" + settings.idp_cert_fingerprint = OneLoginAppCertFingerPrint + settings.name_identifier_format = "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress" # Optional for most SAML IdPs settings.authn_context = "urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport" @@ -338,9 +338,9 @@ def saml_settings # Returns RubySaml::Settings pre-populated with IdP metadata settings = idp_metadata_parser.parse_remote("https://example.com/auth/saml2/idp/metadata") - settings.assertion_consumer_service_url = "http://#{request.host}/saml/consume" - settings.sp_entity_id = "http://#{request.host}/saml/metadata" - settings.name_identifier_format = "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress" + settings.sp_assertion_consumer_service_url = "http://#{request.host}/saml/consume" + settings.sp_entity_id = "http://#{request.host}/saml/metadata" + settings.name_identifier_format = "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress" # Optional for most SAML IdPs settings.authn_context = "urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport" @@ -622,8 +622,8 @@ Ruby SAML supports the following functionality: In order to use functions 1-3 above, you must first define your SP public certificate and private key: ```ruby - settings.certificate = "CERTIFICATE TEXT WITH BEGIN/END HEADER AND FOOTER" - settings.private_key = "PRIVATE KEY TEXT WITH BEGIN/END HEADER AND FOOTER" + settings.sp_cert = "CERTIFICATE TEXT WITH BEGIN/END HEADER AND FOOTER" + settings.sp_private_key = "PRIVATE KEY TEXT WITH BEGIN/END HEADER AND FOOTER" ``` Note that the same certificate (and its associated private key) are used to perform @@ -642,8 +642,8 @@ You may also globally set the SP signature and digest method, to be used in SP s You may add a `` digital signature element to your SP Metadata XML using the following setting: ```ruby - settings.certificate = "CERTIFICATE TEXT WITH BEGIN/END HEADER AND FOOTER" - settings.private_key = "PRIVATE KEY TEXT WITH BEGIN/END HEADER AND FOOTER" + settings.sp_cert = "CERTIFICATE TEXT WITH BEGIN/END HEADER AND FOOTER" + settings.sp_private_key = "PRIVATE KEY TEXT WITH BEGIN/END HEADER AND FOOTER" settings.security[:metadata_signed] = true # Enable signature on Metadata ``` @@ -658,8 +658,8 @@ To enable, please first set your certificate and private key. This will add ` settings.single_logout_service_binding, - "Location" => settings.single_logout_service_url, - "ResponseLocation" => settings.single_logout_service_url + "Binding" => settings.sp_slo_service_binding, + "Location" => settings.sp_slo_service_url, + "ResponseLocation" => settings.sp_slo_service_url } end @@ -90,10 +90,10 @@ def add_sp_service_elements(sp_sso, settings) nameid.text = settings.name_identifier_format end - if settings.assertion_consumer_service_url + if settings.sp_assertion_consumer_service_url sp_sso.add_element "md:AssertionConsumerService", { - "Binding" => settings.assertion_consumer_service_binding, - "Location" => settings.assertion_consumer_service_url, + "Binding" => settings.sp_assertion_consumer_service_binding, + "Location" => settings.sp_assertion_consumer_service_url, "isDefault" => true, "index" => 0 } diff --git a/lib/ruby_saml/response.rb b/lib/ruby_saml/response.rb index a12007ea..8ce4b5d0 100644 --- a/lib/ruby_saml/response.rb +++ b/lib/ruby_saml/response.rb @@ -636,10 +636,10 @@ def validate_destination return append_error(error_msg) end - return true if settings.assertion_consumer_service_url.nil? || settings.assertion_consumer_service_url.empty? + return true if settings.sp_assertion_consumer_service_url.nil? || settings.sp_assertion_consumer_service_url.empty? - unless RubySaml::Utils.uri_match?(destination, settings.assertion_consumer_service_url) - error_msg = "The response was received at #{destination} instead of #{settings.assertion_consumer_service_url}" + unless RubySaml::Utils.uri_match?(destination, settings.sp_assertion_consumer_service_url) + error_msg = "The response was received at #{destination} instead of #{settings.sp_assertion_consumer_service_url}" return append_error(error_msg) end @@ -778,7 +778,7 @@ def validate_subject_confirmation next if (attrs.include? "InResponseTo" and attrs['InResponseTo'] != in_response_to) || (attrs.include? "NotBefore" and now < (parse_time(confirmation_data_node, "NotBefore") - allowed_clock_drift)) || (attrs.include? "NotOnOrAfter" and now >= (parse_time(confirmation_data_node, "NotOnOrAfter") + allowed_clock_drift)) || - (attrs.include? "Recipient" and !options[:skip_recipient_check] and settings and attrs['Recipient'] != settings.assertion_consumer_service_url) + (attrs.include? "Recipient" and !options[:skip_recipient_check] and settings and attrs['Recipient'] != settings.sp_assertion_consumer_service_url) valid_subject_confirmation = true break diff --git a/lib/ruby_saml/settings.rb b/lib/ruby_saml/settings.rb index 36badd69..d32015c0 100644 --- a/lib/ruby_saml/settings.rb +++ b/lib/ruby_saml/settings.rb @@ -42,12 +42,16 @@ def initialize(overrides = {}, keep_security_attributes = false) attr_accessor :idp_attribute_names attr_accessor :idp_name_qualifier attr_accessor :valid_until + # SP Data attr_accessor :sp_entity_id - attr_accessor :assertion_consumer_service_url - attr_reader :assertion_consumer_service_binding - attr_accessor :single_logout_service_url - attr_reader :single_logout_service_binding + attr_accessor :sp_assertion_consumer_service_url + attr_reader :sp_assertion_consumer_service_binding + attr_accessor :sp_slo_service_url + attr_reader :sp_slo_service_binding + attr_accessor :sp_cert + attr_accessor :sp_cert_multi + attr_accessor :sp_private_key attr_accessor :sp_name_qualifier attr_accessor :name_identifier_format attr_accessor :name_identifier_value @@ -59,14 +63,12 @@ def initialize(overrides = {}, keep_security_attributes = false) attr_reader :protocol_binding attr_accessor :attributes_index attr_accessor :force_authn - attr_accessor :certificate - attr_accessor :private_key - attr_accessor :sp_cert_multi attr_accessor :authn_context attr_accessor :authn_context_comparison attr_accessor :authn_context_decl_ref attr_reader :attribute_consuming_service - # Work-flow + + # Workflow attr_accessor :security attr_accessor :soft @@ -106,8 +108,8 @@ def protocol_binding=(value) # Setter for SP Assertion Consumer Service Binding # @param value [String, Symbol]. # - def assertion_consumer_service_binding=(value) - @assertion_consumer_service_binding = get_binding(value) + def sp_assertion_consumer_service_binding=(value) + @sp_assertion_consumer_service_binding = get_binding(value) end # Setter for Single Logout Service Binding. @@ -115,8 +117,8 @@ def assertion_consumer_service_binding=(value) # (Currently we only support "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect") # @param value [String, Symbol] # - def single_logout_service_binding=(value) - @single_logout_service_binding = get_binding(value) + def sp_slo_service_binding=(value) + @sp_slo_service_binding = get_binding(value) end # Calculates the fingerprint of the IdP x509 certificate. @@ -212,7 +214,7 @@ def get_sp_decryption_keys # @return [OpenSSL::X509::Certificate|nil] Build the New SP certificate from the settings. # # @deprecated Use get_sp_certs instead - def get_sp_cert_new + def get_certificate_new node = get_sp_certs[:signing].last node[0] if node end @@ -224,8 +226,8 @@ def get_binding(value) end DEFAULTS = { - assertion_consumer_service_binding: Utils::BINDINGS[:post], - single_logout_service_binding: Utils::BINDINGS[:redirect], + sp_assertion_consumer_service_binding: Utils::BINDINGS[:post], + sp_slo_service_binding: Utils::BINDINGS[:redirect], idp_cert_fingerprint_algorithm: RubySaml::XML::Document::SHA256, message_max_bytesize: 250_000, soft: true, @@ -249,55 +251,61 @@ def get_binding(value) { issuer: :sp_entity_id, + certificate: :sp_cert, + private_key: :sp_private_key, idp_sso_target_url: :idp_sso_service_url, idp_slo_target_url: :idp_slo_service_url, - assertion_consumer_logout_service_url: :single_logout_service_url, - assertion_consumer_logout_service_binding: :single_logout_service_binding + assertion_consumer_service_url: :sp_assertion_consumer_service_url, + assertion_consumer_service_binding: :sp_assertion_consumer_service_binding, + assertion_consumer_logout_service_url: :sp_slo_service_url, + assertion_consumer_logout_service_binding: :sp_slo_service_binding, + single_logout_service_url: :sp_slo_service_url, + single_logout_service_binding: :sp_slo_service_binding }.each do |old_param, new_param| - # @deprecated Will be removed in v2.1.0 + # @deprecated Will raise NotImplementedError in v3.0.0 define_method(old_param) do replaced_deprecation(old_param, new_param) send(new_param) end - # @deprecated Will be removed in v2.1.0 + # @deprecated Will raise NotImplementedError in v3.0.0 define_method(:"#{old_param}=") do |value| replaced_deprecation(old_param, new_param) send(:"#{new_param}=", value) end end - # @deprecated Will be removed in v2.1.0 + # @deprecated Will raise NotImplementedError in v2.1.0 def certificate_new certificate_new_deprecation @certificate_new end - # @deprecated Will be removed in v2.1.0 + # @deprecated Will raise NotImplementedError in v2.1.0 def certificate_new=(value) certificate_new_deprecation @certificate_new = value end - # @deprecated Will be removed in v2.1.0 + # @deprecated Will raise NotImplementedError in v2.1.0 def compress_request compress_deprecation('compress_request', 'idp_sso_service_binding') defined?(@compress_request) ? @compress_request : true end - # @deprecated Will be removed in v2.1.0 + # @deprecated Will raise NotImplementedError in v2.1.0 def compress_request=(value) compress_deprecation('compress_request', 'idp_sso_service_binding') @compress_request = value end - # @deprecated Will be removed in v2.1.0 + # @deprecated Will raise NotImplementedError in v2.1.0 def compress_response compress_deprecation('compress_response', 'idp_slo_service_binding') defined?(@compress_response) ? @compress_response : true end - # @deprecated Will be removed in v2.1.0 + # @deprecated Will raise NotImplementedError in v2.1.0 def compress_response=(value) compress_deprecation('compress_response', 'idp_slo_service_binding') @compress_response = value @@ -307,8 +315,8 @@ def compress_response=(value) # @deprecated Will be removed in v2.1.0 def replaced_deprecation(old_param, new_param) - Logging.deprecate "`RubySaml::Settings##{old_param}` is deprecated and will be removed in RubySaml 2.1.0. " \ - "Please set the same value to `RubySaml::Settings##{new_param}` instead." + Logging.deprecate "`RubySaml::Settings##{old_param}` is deprecated and has been renamed to `#{new_param}`. " \ + "Please replace it 1-for-1 in your code. `#{old_param}` will be removed in RubySaml 3.0.0." end # @deprecated Will be removed in v2.1.0 diff --git a/test/logging_test.rb b/test/logging_test.rb index 95751108..6c140418 100644 --- a/test/logging_test.rb +++ b/test/logging_test.rb @@ -58,5 +58,13 @@ class LoggingTest < Minitest::Test RubySaml::Logging.info('sup?') end end + + describe "#deprecate" do + it "logs a warning message" do + RubySaml::Logging.logger.expects(:warn).with('[RubySaml] DEPRECATION: hi mom') + + RubySaml::Logging.deprecate('hi mom') + end + end end end diff --git a/test/logout_responses/logoutresponse_fixtures.rb b/test/logout_responses/logoutresponse_fixtures.rb index 4db880bc..c647c854 100644 --- a/test/logout_responses/logoutresponse_fixtures.rb +++ b/test/logout_responses/logoutresponse_fixtures.rb @@ -15,7 +15,7 @@ def valid_logout_response_document(opts = {}) xmlns:samlp=\"urn:oasis:names:tc:SAML:2.0:protocol\" ID=\"#{random_id}\" Version=\"2.0\" IssueInstant=\"#{opts[:issue_instant]}\" - Destination=\"#{opts[:settings].single_logout_service_url}\" + Destination=\"#{opts[:settings].sp_slo_service_url}\" InResponseTo=\"#{opts[:uuid]}\"> #{opts[:settings].issuer} @@ -33,7 +33,7 @@ def unsuccessful_logout_response_document(opts = {}) xmlns:samlp=\"urn:oasis:names:tc:SAML:2.0:protocol\" ID=\"#{random_id}\" Version=\"2.0\" IssueInstant=\"#{opts[:issue_instant]}\" - Destination=\"#{opts[:settings].single_logout_service_url}\" + Destination=\"#{opts[:settings].sp_slo_service_url}\" InResponseTo=\"#{opts[:uuid]}\"> #{opts[:settings].issuer} @@ -51,7 +51,7 @@ def unsuccessful_logout_response_with_message_document(opts = {}) xmlns:samlp=\"urn:oasis:names:tc:SAML:2.0:protocol\" ID=\"#{random_id}\" Version=\"2.0\" IssueInstant=\"#{opts[:issue_instant]}\" - Destination=\"#{opts[:settings].single_logout_service_url}\" + Destination=\"#{opts[:settings].sp_slo_service_url}\" InResponseTo=\"#{opts[:uuid]}\"> #{opts[:settings].issuer} @@ -73,8 +73,8 @@ def invalid_xml_logout_response_document def settings @settings ||= RubySaml::Settings.new( { - :assertion_consumer_service_url => "http://app.muda.no/sso/consume", - :single_logout_service_url => "http://app.muda.no/sso/consume_logout", + :sp_assertion_consumer_service_url => "http://app.muda.no/sso/consume", + :sp_slo_service_url => "http://app.muda.no/sso/consume_logout", :issuer => "http://app.muda.no", :sp_name_qualifier => "http://sso.muda.no", :idp_sso_service_url => "http://sso.muda.no/sso", diff --git a/test/logoutrequest_test.rb b/test/logoutrequest_test.rb index a1368249..4e4ac959 100644 --- a/test/logoutrequest_test.rb +++ b/test/logoutrequest_test.rb @@ -114,8 +114,8 @@ class RequestTest < Minitest::Test settings.security[:logout_requests_signed] = true settings.idp_slo_service_binding = :post settings.idp_sso_service_binding = :redirect - settings.certificate = ruby_saml_cert_text - settings.private_key = ruby_saml_key_text + settings.sp_cert = ruby_saml_cert_text + settings.sp_private_key = ruby_saml_key_text end it "doesn't sign through create_xml_document" do @@ -185,8 +185,8 @@ class RequestTest < Minitest::Test end it "create a signed logout request using the first certificate and key" do - settings.certificate = nil - settings.private_key = nil + settings.sp_cert = nil + settings.sp_private_key = nil settings.sp_cert_multi = { signing: [ { certificate: ruby_saml_cert_text, private_key: ruby_saml_key_text }, @@ -203,8 +203,8 @@ class RequestTest < Minitest::Test end it "create a signed logout request using the first valid certificate and key when :check_sp_cert_expiration is true" do - settings.certificate = nil - settings.private_key = nil + settings.sp_cert = nil + settings.sp_private_key = nil settings.security[:check_sp_cert_expiration] = true settings.sp_cert_multi = { signing: [ @@ -238,8 +238,8 @@ class RequestTest < Minitest::Test settings.security[:logout_requests_signed] = true settings.idp_slo_service_binding = :redirect settings.idp_sso_service_binding = :post - settings.certificate = ruby_saml_cert_text - settings.private_key = ruby_saml_key_text + settings.sp_cert = ruby_saml_cert_text + settings.sp_private_key = ruby_saml_key_text end it "create a signature parameter with RSA_SHA1 / SHA1 and validate it" do @@ -310,8 +310,8 @@ class RequestTest < Minitest::Test it "create a signature parameter using the first certificate and key" do settings.security[:signature_method] = RubySaml::XML::Document::RSA_SHA1 - settings.certificate = nil - settings.private_key = nil + settings.sp_cert = nil + settings.sp_private_key = nil settings.sp_cert_multi = { signing: [ { certificate: ruby_saml_cert_text, private_key: ruby_saml_key_text }, diff --git a/test/logoutresponse_test.rb b/test/logoutresponse_test.rb index 55f41901..135e0f48 100644 --- a/test/logoutresponse_test.rb +++ b/test/logoutresponse_test.rb @@ -227,8 +227,8 @@ class RubySamlTest < Minitest::Test settings.soft = true settings.idp_slo_service_url = "http://example.com?field=value" settings.security[:logout_responses_signed] = true - settings.certificate = ruby_saml_cert_text - settings.private_key = ruby_saml_key_text + settings.sp_cert = ruby_saml_cert_text + settings.sp_private_key = ruby_saml_key_text settings.idp_cert = ruby_saml_cert_text end @@ -375,8 +375,8 @@ class RubySamlTest < Minitest::Test settings.idp_slo_service_url = "http://example.com?field=value" settings.security[:signature_method] = RubySaml::XML::Document::RSA_SHA1 settings.security[:logout_responses_signed] = true - settings.certificate = ruby_saml_cert_text - settings.private_key = ruby_saml_key_text + settings.sp_cert = ruby_saml_cert_text + settings.sp_private_key = ruby_saml_key_text settings.idp_cert = nil end diff --git a/test/metadata_test.rb b/test/metadata_test.rb index b97b8b38..97577c25 100644 --- a/test/metadata_test.rb +++ b/test/metadata_test.rb @@ -14,7 +14,7 @@ class MetadataTest < Minitest::Test before do settings.sp_entity_id = "https://example.com" settings.name_identifier_format = "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress" - settings.assertion_consumer_service_url = "https://foo.example/saml/consume" + settings.sp_assertion_consumer_service_url = "https://foo.example/saml/consume" end it "generates Pretty Print Service Provider Metadata" do @@ -38,8 +38,8 @@ class MetadataTest < Minitest::Test end it "generates Service Provider Metadata" do - settings.single_logout_service_binding = "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" - settings.single_logout_service_url = "https://foo.example/saml/sls" + settings.sp_slo_service_binding = "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" + settings.sp_slo_service_url = "https://foo.example/saml/sls" xml_metadata = RubySaml::Metadata.new.generate(settings, false) start = " settings) end - settings.certificate = ruby_saml_cert_text - settings.private_key = ruby_saml_key_text + settings.sp_cert = ruby_saml_cert_text + settings.sp_private_key = ruby_saml_key_text assert_raises(RubySaml::ValidationError, error_msg) do response3 = RubySaml::Response.new(signed_message_encrypted_unsigned_assertion) response3.settings @@ -1462,9 +1462,9 @@ def generate_audience_error(expected, actual) end it 'raise if an encrypted assertion is found and the sp private key is wrong' do - settings.certificate = ruby_saml_cert_text + settings.sp_cert = ruby_saml_cert_text wrong_private_key = ruby_saml_key_text.sub!('A', 'B') - settings.private_key = wrong_private_key + settings.sp_private_key = wrong_private_key error_msg = "Neither PUB key nor PRIV key: nested asn1 error" assert_raises(OpenSSL::PKey::RSAError, error_msg) do @@ -1473,8 +1473,8 @@ def generate_audience_error(expected, actual) end it 'return true if an encrypted assertion is found and settings initialized with private_key' do - settings.certificate = ruby_saml_cert_text - settings.private_key = ruby_saml_key_text + settings.sp_cert = ruby_saml_cert_text + settings.sp_private_key = ruby_saml_key_text response = RubySaml::Response.new(signed_message_encrypted_unsigned_assertion, :settings => settings) assert response.decrypted_document @@ -1499,9 +1499,9 @@ def generate_audience_error(expected, actual) before do settings.idp_cert_fingerprint = '55:FD:5F:3F:43:5A:AC:E6:79:89:BF:25:48:81:A1:C4:F3:37:3B:CB:1B:4D:68:A0:3E:A5:C9:FF:61:48:01:3F' settings.sp_entity_id = 'http://rubysaml.com:3000/saml/metadata' - settings.assertion_consumer_service_url = 'http://rubysaml.com:3000/saml/acs' - settings.certificate = ruby_saml_cert_text - settings.private_key = ruby_saml_key_text + settings.sp_assertion_consumer_service_url = 'http://rubysaml.com:3000/saml/acs' + settings.sp_cert = ruby_saml_cert_text + settings.sp_private_key = ruby_saml_key_text end it 'is possible when signed_message_encrypted_unsigned_assertion' do @@ -1545,7 +1545,7 @@ def generate_audience_error(expected, actual) describe "#decrypt_assertion" do before do - settings.private_key = ruby_saml_key_text + settings.sp_private_key = ruby_saml_key_text end describe "check right settings" do @@ -1558,7 +1558,7 @@ def generate_audience_error(expected, actual) "(/p:Response/EncryptedAssertion/)|(/p:Response/a:EncryptedAssertion/)", { "p" => "urn:oasis:names:tc:SAML:2.0:protocol", "a" => "urn:oasis:names:tc:SAML:2.0:assertion" } ) - response.settings.private_key = nil + response.settings.sp_private_key = nil error_msg = "An EncryptedAssertion found and no SP private key found on the settings to decrypt it" assert_raises(RubySaml::ValidationError, error_msg) do @@ -1567,7 +1567,7 @@ def generate_audience_error(expected, actual) end it "is not possible to decrypt the assertion if private key has expired and :check_sp_expiration is true" do - settings.certificate = ruby_saml_cert_text + settings.sp_cert = ruby_saml_cert_text settings.security[:check_sp_cert_expiration] = true assert_raises(RubySaml::ValidationError, "The SP certificate expired.") do RubySaml::Response.new(signed_message_encrypted_unsigned_assertion, :settings => settings) @@ -1594,7 +1594,7 @@ def generate_audience_error(expected, actual) end it "is possible to decrypt the assertion with one invalid and one valid private key" do - settings.private_key = nil + settings.sp_private_key = nil settings.sp_cert_multi = { encryption: [ CertificateHelper.generate_pair_hash, @@ -1614,7 +1614,7 @@ def generate_audience_error(expected, actual) end it "is possible to decrypt the assertion if private key provided and EncryptedKey RetrievalMethod presents in response" do - settings.private_key = ruby_saml_key_text + settings.sp_private_key = ruby_saml_key_text resp = read_response('response_with_retrieval_method.xml') response = RubySaml::Response.new(resp, :settings => settings) @@ -1744,7 +1744,7 @@ def generate_audience_error(expected, actual) describe "signature wrapping attack with encrypted assertion" do it "should not be valid" do - settings.private_key = ruby_saml_key_text + settings.sp_private_key = ruby_saml_key_text signature_wrapping_attack = read_invalid_response("encrypted_new_attack.xml.base64") response_wrapped = RubySaml::Response.new(signature_wrapping_attack, :settings => settings) response_wrapped.stubs(:conditions).returns(nil) diff --git a/test/settings_deprecations_test.rb b/test/settings_deprecations_test.rb new file mode 100644 index 00000000..9a4ca9e6 --- /dev/null +++ b/test/settings_deprecations_test.rb @@ -0,0 +1,84 @@ +require_relative 'test_helper' + +require 'ruby_saml/settings' + +class SettingsDeprecationsTest < Minitest::Test + + describe "Settings Deprecations" do + before do + @settings = RubySaml::Settings.new + end + + describe 'replaced deprecations' do + { + issuer: :sp_entity_id, + certificate: :sp_cert, + private_key: :sp_private_key, + idp_sso_target_url: :idp_sso_service_url, + idp_slo_target_url: :idp_slo_service_url, + assertion_consumer_service_url: :sp_assertion_consumer_service_url, + assertion_consumer_service_binding: :sp_assertion_consumer_service_binding, + assertion_consumer_logout_service_url: :sp_slo_service_url, + assertion_consumer_logout_service_binding: :sp_slo_service_binding, + single_logout_service_url: :sp_slo_service_url, + single_logout_service_binding: :sp_slo_service_binding + }.each do |old_method, new_method| + it ":#{old_method} is aliased to :#{new_method}" do + @settings.send(:"#{new_method}=", 'Dummy') + + assert_equal 'Dummy', @settings.send(:"#{old_method}") + assert_equal 'Dummy', @settings.send(:"#{new_method}") + end + + it ":#{old_method}= is aliased to :#{new_method}=" do + @settings.send(:"#{old_method}=", 'Dummy') + + assert_equal 'Dummy', @settings.send(:"#{old_method}") + assert_equal 'Dummy', @settings.send(:"#{new_method}") + end + + it ":#{old_method} logs a deprecation warning" do + RubySaml::Logging.expects(:deprecate).with(regexp_matches(/#{old_method}.+#{new_method}/)) + @settings.send(:"#{old_method}") + end + + it ":#{old_method}= logs a deprecation warning" do + RubySaml::Logging.expects(:deprecate).with(regexp_matches(/#{old_method}.+#{new_method}/)) + @settings.send(:"#{old_method}=", 'Dummy') + end + + it ":#{new_method} logs a deprecation warning" do + RubySaml::Logging.expects(:deprecate).never + @settings.send(:"#{new_method}") + end + + it ":#{new_method}= logs a deprecation warning" do + RubySaml::Logging.expects(:deprecate).never + @settings.send(:"#{new_method}=", 'Dummy') + end + end + end + + describe 'nullified deprecations' do + %i[ certificate_new + compress_request + compress_response ].each do |old_method| + it ":#{old_method} is an accessor" do + @settings.send(:"#{old_method}=", 'Dummy') + + assert_equal 'Dummy', @settings.send(:"#{old_method}") + end + + it ":#{old_method} logs a deprecation warning" do + RubySaml::Logging.expects(:deprecate).with(regexp_matches(/#{old_method}/)) + @settings.send(:"#{old_method}") + end + + it ":#{old_method}= logs a deprecation warning" do + RubySaml::Logging.expects(:deprecate).with(regexp_matches(/#{old_method}/)) + @settings.send(:"#{old_method}=", 'Dummy') + end + end + end + end +end diff --git a/test/settings_test.rb b/test/settings_test.rb index 21f4b6f8..8dd34201 100644 --- a/test/settings_test.rb +++ b/test/settings_test.rb @@ -14,7 +14,7 @@ class SettingsTest < Minitest::Test 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, + :idp_attribute_names, :issuer, :sp_assertion_consumer_service_url, :sp_slo_service_url, :sp_name_qualifier, :name_identifier_format, :name_identifier_value, :name_identifier_value_requested, :sessionindex, :attributes_index, :passive, :force_authn, :double_quote_xml_attribute_values, :message_max_bytesize, @@ -36,8 +36,8 @@ class SettingsTest < Minitest::Test it "should provide getters and settings for binding parameters" do accessors = [ :protocol_binding, - :assertion_consumer_service_binding, - :single_logout_service_binding, + :sp_assertion_consumer_service_binding, + :sp_slo_service_binding, :assertion_consumer_logout_service_binding ] @@ -59,7 +59,7 @@ class SettingsTest < Minitest::Test it "create settings from hash" do config = { - :assertion_consumer_service_url => "http://app.muda.no/sso", + :sp_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", @@ -132,21 +132,21 @@ class SettingsTest < Minitest::Test 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 + describe "#sp_slo_service_url" do + it "when sp_slo_service_url is nil but assertion_consumer_logout_service_url returns its value" do + @settings.sp_slo_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 + assert_equal "http://app.muda.no/sls", @settings.sp_slo_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 + describe "#sp_slo_service_binding" do + it "when sp_slo_service_binding is nil but assertion_consumer_logout_service_binding returns its value" do + @settings.sp_slo_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 + assert_equal "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect", @settings.sp_slo_service_binding end end @@ -308,77 +308,77 @@ class SettingsTest < Minitest::Test describe "#get_sp_cert" do it "returns nil when the cert is an empty string" do - @settings.certificate = "" + @settings.sp_cert = "" assert_nil @settings.get_sp_cert end it "returns nil when the cert is nil" do - @settings.certificate = nil + @settings.sp_cert = nil assert_nil @settings.get_sp_cert end it "returns the certificate when it is valid" do - @settings.certificate = ruby_saml_cert_text + @settings.sp_cert = 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") + @settings.sp_cert = 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.sp_cert = ruby_saml_cert_text @settings.security[:check_sp_cert_expiration] = true assert_raises(RubySaml::ValidationError) { @settings.get_sp_cert } end end - describe "#get_sp_cert_new" do + describe "#get_certificate_new" do it "returns nil when the cert is an empty string" do @settings.certificate_new = "" - assert_nil @settings.get_sp_cert_new + assert_nil @settings.get_certificate_new end it "returns nil when the cert is nil" do @settings.certificate_new = nil - assert_nil @settings.get_sp_cert_new + assert_nil @settings.get_certificate_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 + assert @settings.get_certificate_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 + @settings.get_certificate_new } end end describe "#get_sp_key" do it "returns nil when the private key is an empty string" do - @settings.private_key = "" + @settings.sp_private_key = "" assert_nil @settings.get_sp_key end it "returns nil when the private key is nil" do - @settings.private_key = nil + @settings.sp_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 + @settings.sp_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") + @settings.sp_private_key = read_certificate("formatted_rsa_private_key") assert_raises(OpenSSL::PKey::RSAError) { @settings.get_sp_key } @@ -423,8 +423,8 @@ class SettingsTest < Minitest::Test let(:key_text2) { CertificateHelper.generate_key.to_pem } it "returns certs for single case" do - @settings.certificate = cert_text1 - @settings.private_key = key_text1 + @settings.sp_cert = cert_text1 + @settings.sp_private_key = key_text1 actual = @settings.get_sp_certs expected = [[cert_text1, key_text1]] @@ -434,9 +434,9 @@ class SettingsTest < Minitest::Test end it "returns certs for single case with new cert" do - @settings.certificate = cert_text1 + @settings.sp_cert = cert_text1 @settings.certificate_new = cert_text2 - @settings.private_key = key_text1 + @settings.sp_private_key = key_text1 actual = @settings.get_sp_certs expected = [[cert_text1, key_text1], [cert_text2, key_text1]] @@ -540,7 +540,7 @@ class SettingsTest < Minitest::Test it "raises error when both sp_cert_multi and certificate are specified" do @settings.sp_cert_multi = { signing: [{ certificate: cert_text1, private_key: key_text1 }] } - @settings.certificate = cert_text1 + @settings.sp_cert = cert_text1 error_message = 'Cannot specify both sp_cert_multi and certificate, certificate_new, private_key parameters' assert_raises ArgumentError, error_message do @@ -560,7 +560,7 @@ class SettingsTest < Minitest::Test it "raises error when both sp_cert_multi and private_key are specified" do @settings.sp_cert_multi = { signing: [{ certificate: cert_text1, private_key: key_text1 }] } - @settings.private_key = key_text1 + @settings.sp_private_key = key_text1 error_message = 'Cannot specify both sp_cert_multi and certificate, certificate_new, private_key parameters' assert_raises ArgumentError, error_message do diff --git a/test/slo_logoutrequest_test.rb b/test/slo_logoutrequest_test.rb index d1657c83..c32caa54 100644 --- a/test/slo_logoutrequest_test.rb +++ b/test/slo_logoutrequest_test.rb @@ -56,8 +56,8 @@ class RubySamlTest < Minitest::Test it "collect errors when collect_errors=true" do settings.idp_entity_id = 'http://idp.example.com/invalid' settings.security[:logout_requests_signed] = true - settings.certificate = ruby_saml_cert_text - settings.private_key = ruby_saml_key_text + settings.sp_cert = ruby_saml_cert_text + settings.sp_private_key = ruby_saml_key_text settings.idp_cert = ruby_saml_cert_text settings.security[:signature_method] = RubySaml::XML::Document::RSA_SHA1 params = {} @@ -96,7 +96,7 @@ class RubySamlTest < Minitest::Test end it "extract the value of the name id element inside an EncryptedId" do - settings.private_key = ruby_saml_key_text + settings.sp_private_key = ruby_saml_key_text logout_request_encrypted_nameid.settings = settings assert_equal "someone@example.org", logout_request_encrypted_nameid.nameid end @@ -116,7 +116,7 @@ class RubySamlTest < Minitest::Test end it "extract the format attribute of the name id element" do - settings.private_key = ruby_saml_key_text + settings.sp_private_key = ruby_saml_key_text logout_request_encrypted_nameid.settings = settings assert_equal "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress", logout_request_encrypted_nameid.nameid_format end @@ -300,8 +300,8 @@ class RubySamlTest < Minitest::Test describe "#validate_signature" do before do settings.security[:logout_requests_signed] = true - settings.certificate = ruby_saml_cert_text - settings.private_key = ruby_saml_key_text + settings.sp_cert = ruby_saml_cert_text + settings.sp_private_key = ruby_saml_key_text settings.idp_cert = ruby_saml_cert_text end @@ -502,8 +502,8 @@ class RubySamlTest < Minitest::Test describe "#validate_signature with multiple idp certs" do before do - settings.certificate = ruby_saml_cert_text - settings.private_key = ruby_saml_key_text + settings.sp_cert = ruby_saml_cert_text + settings.sp_private_key = ruby_saml_key_text settings.idp_cert = nil settings.security[:logout_requests_signed] = true settings.security[:signature_method] = RubySaml::XML::Document::RSA_SHA1 diff --git a/test/slo_logoutresponse_test.rb b/test/slo_logoutresponse_test.rb index 421017f3..64af37c9 100644 --- a/test/slo_logoutresponse_test.rb +++ b/test/slo_logoutresponse_test.rb @@ -12,8 +12,8 @@ class SloLogoutresponseTest < Minitest::Test settings.idp_entity_id = 'https://app.onelogin.com/saml/metadata/SOMEACCOUNT' settings.idp_slo_service_url = "http://unauth.com/logout" settings.name_identifier_value = "f00f00" - settings.certificate = ruby_saml_cert_text - settings.private_key = ruby_saml_key_text + settings.sp_cert = ruby_saml_cert_text + settings.sp_private_key = ruby_saml_key_text logout_request.settings = settings end @@ -176,8 +176,8 @@ class SloLogoutresponseTest < Minitest::Test end it "create a signed logout response using the first certificate and key" do - settings.certificate = nil - settings.private_key = nil + settings.sp_cert = nil + settings.sp_private_key = nil settings.sp_cert_multi = { signing: [ { certificate: ruby_saml_cert_text, private_key: ruby_saml_key_text }, @@ -195,8 +195,8 @@ class SloLogoutresponseTest < Minitest::Test end it "create a signed logout response using the first valid certificate and key when :check_sp_cert_expiration is true" do - settings.certificate = nil - settings.private_key = nil + settings.sp_cert = nil + settings.sp_private_key = nil settings.security[:check_sp_cert_expiration] = true settings.sp_cert_multi = { signing: [ @@ -310,8 +310,8 @@ class SloLogoutresponseTest < Minitest::Test it "create a signature parameter using the first certificate and key" do settings.security[:signature_method] = RubySaml::XML::Document::RSA_SHA1 - settings.certificate = nil - settings.private_key = nil + settings.sp_cert = nil + settings.sp_private_key = nil settings.sp_cert_multi = { signing: [ { certificate: ruby_saml_cert_text, private_key: ruby_saml_key_text }, diff --git a/test/xml_test.rb b/test/xml_test.rb index b8a67176..7e6b1759 100644 --- a/test/xml_test.rb +++ b/test/xml_test.rb @@ -239,8 +239,8 @@ class XmlTest < Minitest::Test settings.protocol_binding = "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" settings.idp_slo_service_url = "https://idp.example.com/slo", settings.sp_entity_id = "https://sp.example.com/saml2" - settings.assertion_consumer_service_url = "https://sp.example.com/acs" - settings.single_logout_service_url = "https://sp.example.com/sls" + settings.sp_assertion_consumer_service_url = "https://sp.example.com/acs" + settings.sp_slo_service_url = "https://sp.example.com/sls" end it "sign an AuthNRequest" do