1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139
|
require File.expand_path(File.join(File.dirname(__FILE__), "test_helper"))
require 'onelogin/ruby-saml/idp_metadata_parser'
class IdpMetadataParserTest < Minitest::Test
class MockSuccessResponse < Net::HTTPSuccess
# override parent's initialize
def initialize; end
attr_accessor :body
end
class MockFailureResponse < Net::HTTPNotFound
# override parent's initialize
def initialize; end
attr_accessor :body
end
describe "parsing an IdP descriptor file" do
it "extract settings details from xml" do
idp_metadata_parser = OneLogin::RubySaml::IdpMetadataParser.new
settings = idp_metadata_parser.parse(idp_metadata)
assert_equal "https://example.hello.com/access/saml/idp.xml", settings.idp_entity_id
assert_equal "https://example.hello.com/access/saml/login", settings.idp_sso_target_url
assert_equal "F1:3C:6B:80:90:5A:03:0E:6C:91:3E:5D:15:FA:DD:B0:16:45:48:72", settings.idp_cert_fingerprint
assert_equal "https://example.hello.com/access/saml/logout", settings.idp_slo_target_url
assert_equal "urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified", settings.name_identifier_format
assert_equal ["AuthToken", "SSOStartPage"], settings.idp_attribute_names
assert_equal "F1:3C:6B:80:90:5A:03:0E:6C:91:3E:5D:15:FA:DD:B0:16:45:48:72", settings.idp_cert_fingerprint
end
it "extract certificate from md:KeyDescriptor[@use='signing']" do
idp_metadata_parser = OneLogin::RubySaml::IdpMetadataParser.new
idp_metadata = read_response("idp_descriptor.xml")
settings = idp_metadata_parser.parse(idp_metadata)
assert_equal "F1:3C:6B:80:90:5A:03:0E:6C:91:3E:5D:15:FA:DD:B0:16:45:48:72", settings.idp_cert_fingerprint
end
it "extract certificate from md:KeyDescriptor[@use='encryption']" do
idp_metadata_parser = OneLogin::RubySaml::IdpMetadataParser.new
idp_metadata = read_response("idp_descriptor.xml")
idp_metadata = idp_metadata.sub(/<md:KeyDescriptor use="signing">(.*?)<\/md:KeyDescriptor>/m, "")
settings = idp_metadata_parser.parse(idp_metadata)
assert_equal "F1:3C:6B:80:90:5A:03:0E:6C:91:3E:5D:15:FA:DD:B0:16:45:48:72", settings.idp_cert_fingerprint
end
it "extract certificate from md:KeyDescriptor" do
idp_metadata_parser = OneLogin::RubySaml::IdpMetadataParser.new
idp_metadata = read_response("idp_descriptor.xml")
idp_metadata = idp_metadata.sub(/<md:KeyDescriptor use="signing">(.*?)<\/md:KeyDescriptor>/m, "")
idp_metadata = idp_metadata.sub('<md:KeyDescriptor use="encryption">', '<md:KeyDescriptor>')
settings = idp_metadata_parser.parse(idp_metadata)
assert_equal "F1:3C:6B:80:90:5A:03:0E:6C:91:3E:5D:15:FA:DD:B0:16:45:48:72", settings.idp_cert_fingerprint
end
it "uses settings options as hash for overrides" do
idp_metadata_parser = OneLogin::RubySaml::IdpMetadataParser.new
idp_metadata = read_response("idp_descriptor.xml")
settings = idp_metadata_parser.parse(idp_metadata, {
:settings => {
:security => {
:digest_method => XMLSecurity::Document::SHA256,
:signature_method => XMLSecurity::Document::RSA_SHA256
}
}
})
assert_equal "F1:3C:6B:80:90:5A:03:0E:6C:91:3E:5D:15:FA:DD:B0:16:45:48:72", settings.idp_cert_fingerprint
assert_equal XMLSecurity::Document::SHA256, settings.security[:digest_method]
assert_equal XMLSecurity::Document::RSA_SHA256, settings.security[:signature_method]
end
end
describe "download and parse IdP descriptor file" do
before do
mock_response = MockSuccessResponse.new
mock_response.body = idp_metadata
@url = "https://example.com"
uri = URI(@url)
@http = Net::HTTP.new(uri.host, uri.port)
Net::HTTP.expects(:new).returns(@http)
@http.expects(:request).returns(mock_response)
end
it "extract settings from remote xml" do
idp_metadata_parser = OneLogin::RubySaml::IdpMetadataParser.new
settings = idp_metadata_parser.parse_remote(@url)
assert_equal "https://example.hello.com/access/saml/idp.xml", settings.idp_entity_id
assert_equal "https://example.hello.com/access/saml/login", settings.idp_sso_target_url
assert_equal "F1:3C:6B:80:90:5A:03:0E:6C:91:3E:5D:15:FA:DD:B0:16:45:48:72", settings.idp_cert_fingerprint
assert_equal "https://example.hello.com/access/saml/logout", settings.idp_slo_target_url
assert_equal "urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified", settings.name_identifier_format
assert_equal ["AuthToken", "SSOStartPage"], settings.idp_attribute_names
assert_equal OpenSSL::SSL::VERIFY_PEER, @http.verify_mode
end
it "accept self signed certificate if insturcted" do
idp_metadata_parser = OneLogin::RubySaml::IdpMetadataParser.new
idp_metadata_parser.parse_remote(@url, false)
assert_equal OpenSSL::SSL::VERIFY_NONE, @http.verify_mode
end
end
describe "download failure cases" do
it "raises an exception when the url has no scheme" do
idp_metadata_parser = OneLogin::RubySaml::IdpMetadataParser.new
exception = assert_raises(ArgumentError) do
idp_metadata_parser.parse_remote("blahblah")
end
assert_equal("url must begin with http or https", exception.message)
end
it "raises an exception when unable to download metadata" do
mock_response = MockFailureResponse.new
@url = "https://example.com"
uri = URI(@url)
@http = Net::HTTP.new(uri.host, uri.port)
Net::HTTP.expects(:new).returns(@http)
@http.expects(:request).returns(mock_response)
idp_metadata_parser = OneLogin::RubySaml::IdpMetadataParser.new
exception = assert_raises(OneLogin::RubySaml::HttpError) do
idp_metadata_parser.parse_remote("https://example.hello.com/access/saml/idp.xml")
end
assert_equal("Failed to fetch idp metadata", exception.message)
end
end
end
|