ruby-saml 0.9.4 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of ruby-saml might be problematic. Click here for more details.

Files changed (101) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/LICENSE +1 -1
  4. data/README.md +71 -15
  5. data/changelog.md +15 -6
  6. data/lib/onelogin/ruby-saml.rb +1 -0
  7. data/lib/onelogin/ruby-saml/attribute_service.rb +25 -2
  8. data/lib/onelogin/ruby-saml/attributes.rb +42 -23
  9. data/lib/onelogin/ruby-saml/authrequest.rb +33 -8
  10. data/lib/onelogin/ruby-saml/http_error.rb +7 -0
  11. data/lib/onelogin/ruby-saml/idp_metadata_parser.rb +65 -10
  12. data/lib/onelogin/ruby-saml/logging.rb +14 -10
  13. data/lib/onelogin/ruby-saml/logoutrequest.rb +39 -14
  14. data/lib/onelogin/ruby-saml/logoutresponse.rb +166 -39
  15. data/lib/onelogin/ruby-saml/metadata.rb +40 -23
  16. data/lib/onelogin/ruby-saml/response.rb +562 -88
  17. data/lib/onelogin/ruby-saml/saml_message.rb +80 -14
  18. data/lib/onelogin/ruby-saml/settings.rb +62 -23
  19. data/lib/onelogin/ruby-saml/slo_logoutrequest.rb +210 -20
  20. data/lib/onelogin/ruby-saml/slo_logoutresponse.rb +44 -13
  21. data/lib/onelogin/ruby-saml/utils.rb +163 -40
  22. data/lib/onelogin/ruby-saml/version.rb +1 -1
  23. data/lib/schemas/saml-schema-metadata-2.0.xsd +0 -2
  24. data/lib/xml_security.rb +87 -29
  25. data/ruby-saml.gemspec +1 -0
  26. data/test/certificates/{r1_certificate2_base64 → certificate_without_head_foot} +0 -0
  27. data/test/certificates/formatted_certificate +14 -0
  28. data/test/certificates/formatted_private_key +12 -0
  29. data/test/certificates/formatted_rsa_private_key +12 -0
  30. data/test/certificates/invalid_certificate1 +1 -0
  31. data/test/certificates/invalid_certificate2 +1 -0
  32. data/test/certificates/invalid_certificate3 +12 -0
  33. data/test/certificates/invalid_private_key1 +1 -0
  34. data/test/certificates/invalid_private_key2 +1 -0
  35. data/test/certificates/invalid_private_key3 +10 -0
  36. data/test/certificates/invalid_rsa_private_key1 +1 -0
  37. data/test/certificates/invalid_rsa_private_key2 +1 -0
  38. data/test/certificates/invalid_rsa_private_key3 +10 -0
  39. data/test/idp_metadata_parser_test.rb +41 -4
  40. data/test/logging_test.rb +62 -0
  41. data/test/logout_requests/invalid_slo_request.xml +6 -0
  42. data/test/{responses → logout_requests}/slo_request.xml +0 -0
  43. data/test/logout_requests/slo_request.xml.base64 +1 -0
  44. data/test/logout_requests/slo_request_deflated.xml.base64 +1 -0
  45. data/test/logout_requests/slo_request_with_session_index.xml +5 -0
  46. data/test/{responses → logout_responses}/logoutresponse_fixtures.rb +6 -6
  47. data/test/logoutrequest_test.rb +79 -52
  48. data/test/logoutresponse_test.rb +206 -59
  49. data/test/metadata_test.rb +77 -7
  50. data/test/request_test.rb +80 -65
  51. data/test/response_test.rb +862 -189
  52. data/test/responses/attackxee.xml +13 -0
  53. data/test/responses/invalids/invalid_audience.xml.base64 +1 -0
  54. data/test/responses/invalids/invalid_issuer_assertion.xml.base64 +1 -0
  55. data/test/responses/invalids/invalid_issuer_message.xml.base64 +1 -0
  56. data/test/responses/invalids/invalid_signature_position.xml.base64 +1 -0
  57. data/test/responses/invalids/invalid_subjectconfirmation_inresponse.xml.base64 +1 -0
  58. data/test/responses/invalids/invalid_subjectconfirmation_nb.xml.base64 +1 -0
  59. data/test/responses/invalids/invalid_subjectconfirmation_noa.xml.base64 +1 -0
  60. data/test/responses/invalids/invalid_subjectconfirmation_recipient.xml.base64 +1 -0
  61. data/test/responses/invalids/multiple_assertions.xml.base64 +2 -0
  62. data/test/responses/invalids/multiple_signed.xml.base64 +1 -0
  63. data/test/responses/invalids/no_id.xml.base64 +1 -0
  64. data/test/responses/invalids/no_saml2.xml.base64 +1 -0
  65. data/test/responses/invalids/no_signature.xml.base64 +1 -0
  66. data/test/responses/invalids/no_status.xml.base64 +1 -0
  67. data/test/responses/invalids/no_status_code.xml.base64 +1 -0
  68. data/test/responses/invalids/no_subjectconfirmation_data.xml.base64 +1 -0
  69. data/test/responses/invalids/no_subjectconfirmation_method.xml.base64 +1 -0
  70. data/test/responses/invalids/response_encrypted_attrs.xml.base64 +1 -0
  71. data/test/responses/invalids/response_invalid_signed_element.xml.base64 +1 -0
  72. data/test/responses/invalids/status_code_responder.xml.base64 +1 -0
  73. data/test/responses/invalids/status_code_responer_and_msg.xml.base64 +1 -0
  74. data/test/responses/{response4.xml.base64 → response_assertion_wrapped.xml.base64} +0 -0
  75. data/test/responses/response_encrypted_nameid.xml.base64 +1 -0
  76. data/test/responses/response_unsigned_xml_base64 +1 -0
  77. data/test/responses/{response5.xml.base64 → response_with_saml2_namespace.xml.base64} +0 -0
  78. data/test/responses/{response3.xml.base64 → response_with_signed_assertion.xml.base64} +0 -0
  79. data/test/responses/{r1_response6.xml.base64 → response_with_signed_assertion_2.xml.base64} +0 -0
  80. data/test/responses/{response1.xml.base64 → response_with_undefined_recipient.xml.base64} +0 -0
  81. data/test/responses/{response2.xml.base64 → response_without_attributes.xml.base64} +0 -0
  82. data/test/responses/{wrapped_response_2.xml.base64 → response_wrapped.xml.base64} +0 -0
  83. data/test/responses/signed_message_encrypted_signed_assertion.xml.base64 +1 -0
  84. data/test/responses/signed_message_encrypted_unsigned_assertion.xml.base64 +1 -0
  85. data/test/responses/unsigned_message_aes128_encrypted_signed_assertion.xml.base64 +1 -0
  86. data/test/responses/unsigned_message_aes192_encrypted_signed_assertion.xml.base64 +1 -0
  87. data/test/responses/unsigned_message_aes256_encrypted_signed_assertion.xml.base64 +1 -0
  88. data/test/responses/unsigned_message_des192_encrypted_signed_assertion.xml.base64 +1 -0
  89. data/test/responses/unsigned_message_encrypted_assertion_without_saml_namespace.xml.base64 +1 -0
  90. data/test/responses/unsigned_message_encrypted_signed_assertion.xml.base64 +1 -0
  91. data/test/responses/unsigned_message_encrypted_unsigned_assertion.xml.base64 +1 -0
  92. data/test/responses/valid_response.xml.base64 +1 -0
  93. data/test/saml_message_test.rb +56 -0
  94. data/test/settings_test.rb +138 -1
  95. data/test/slo_logoutrequest_test.rb +239 -28
  96. data/test/slo_logoutresponse_test.rb +93 -71
  97. data/test/test_helper.rb +138 -31
  98. data/test/utils_test.rb +129 -25
  99. data/test/xml_security_test.rb +140 -71
  100. metadata +142 -25
  101. data/test/responses/response_node_text_attack.xml.base64 +0 -1
@@ -36,6 +36,7 @@ Gem::Specification.new do |s|
36
36
  s.add_development_dependency('mocha', '~> 0.14')
37
37
  s.add_development_dependency('rake', '~> 10')
38
38
  s.add_development_dependency('shoulda', '~> 2.11')
39
+ s.add_development_dependency('simplecov','~> 0.9.0')
39
40
  s.add_development_dependency('systemu', '~> 2')
40
41
  s.add_development_dependency('timecop', '<= 0.6.0')
41
42
 
@@ -0,0 +1,14 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIICPDCCAaWgAwIBAgIIEiC/9HMAWWAwDQYJKoZIhvcNAQEFBQAwTzELMAkGA1UE
3
+ BhMCVVMxDDAKBgNVBAoTA2libTEMMAoGA1UECxMDc3NvMSQwIgYDVQQDExtjMjVh
4
+ MDI3Ny50b3JvbnRvLmNhLmlibS5jb20wHhcNMTEwNTI0MTYzNTQ4WhcNMjEwNTIx
5
+ wsQMPBj4WQTNzTYMCQYDVQQGEwJVUzEMMAoGA1UEChMDaWJtMQwwCgYDVQQLEwNz
6
+ c28xJDAiBgNVBAMTG2MyNWEwMjc3LnRvcm9udG8uY2EuaWJtLmNvbTCBnzANBgkq
7
+ hkiG9w0BAQEFAAOBjQAwgYkCgYEAgzfYQZuf5FVdJTcrsIQZ+YHTPjOsw2MGo0jC
8
+ mdGMcp4brWeFgk1OVaOmytPx6P76wHWR436AleX3crHBPd8gPxuZdnvBQ7PkrKpw
9
+ Vvaq52juenFrho8JY0TeVgVkY5jAh45YzytjP2y2k/cGQurI/56NT0PpQJ0S1G3N
10
+ 4eTg718CAwEAAaMhMB8wHQYDVR0OBBYEFCYVLJqcJ7WgdzGIsuJ/TzDGDqinMA0G
11
+ CSqGSIb3DQEBBQUAA4GBAB80bIePf+qWDvWe+9bEEnbFTw7pCknLexxZ0AMqrsmZ
12
+ +4jmI+evP1JZYCjfIg9X+MBH01hfp5dFcetz3o6w6SkV+BxLYLgfcy5KUcYsIM/1
13
+ 2Zkedj87bS1glzOy5B89pKD2DMbu6828Abzgc+4lyQ2ASifsqM4cZdVayzo8n+dQ
14
+ -----END CERTIFICATE-----
@@ -0,0 +1,12 @@
1
+ -----BEGIN PRIVATE KEY-----
2
+ MIIBuwIBAAKBgQDImEj39zKfeh4LbgzPuos/DCnyKZUJzAHX3OSXA1Akl+CA1Ak3
3
+ NgRCJ3NOflCGzW+PcLvxrSwH3mHaqQAvDA2fJOySiVtJ9+tm1jrQnL+AAw7JzUht
4
+ YzmnRC8wwuN1+TDuKiK1Hzr/4fz2eFZ6+M53YC4eHOkBYA0FdFGRYrH70wIVAJfR
5
+ hg3tWWhJvyJBvaZoh3/BP613AoGBAL0KkMDFRc3FXcvdRKNpWbrsU41G32bBlfQR
6
+ O1EBe1+ghIasBr7lxEEhdkfthlaF4JiFHyaXuSx5hPKUbo8AO/MfaPJ7SKK2QRS3
7
+ B/qlstzIbjmvgYJJuOs4O4x6lYgeU5rb9G5SoOEBvyo46ZxfzdWhAwfZofsrzAhe
8
+ 3WlOTZkdAoGAGmt0xlYn/0oYZjCxGKStjBA80E5NypAl7UyFj1RhGjIUkiuRcgOL
9
+ d3/fC6vKuqsMtLHyb5EGqtHPbqm4re1rw0zDh+qHEFA4N6UW0poc9eNEfosJA2BO
10
+ 5o8ft9FzKA033pl89mD0CBj05EPadGR7E7QhL5mXuQJpjXJEiyqbce4CFAUFhvCK
11
+ GeW2AKaE6oqRqeVwGw4V
12
+ -----END PRIVATE KEY-----
@@ -0,0 +1,12 @@
1
+ -----BEGIN RSA PRIVATE KEY-----
2
+ MIIBuwIBAAKBgQDImEj39zKfeh4LbgzPuos/DCnyKZUJzAHX3OSXA1Akl+CA1Ak3
3
+ NgRCJ3NOflCGzW+PcLvxrSwH3mHaqQAvDA2fJOySiVtJ9+tm1jrQnL+AAw7JzUht
4
+ YzmnRC8wwuN1+TDuKiK1Hzr/4fz2eFZ6+M53YC4eHOkBYA0FdFGRYrH70wIVAJfR
5
+ hg3tWWhJvyJBvaZoh3/BP613AoGBAL0KkMDFRc3FXcvdRKNpWbrsU41G32bBlfQR
6
+ O1EBe1+ghIasBr7lxEEhdkfthlaF4JiFHyaXuSx5hPKUbo8AO/MfaPJ7SKK2QRS3
7
+ B/qlstzIbjmvgYJJuOs4O4x6lYgeU5rb9G5SoOEBvyo46ZxfzdWhAwfZofsrzAhe
8
+ 3WlOTZkdAoGAGmt0xlYn/0oYZjCxGKStjBA80E5NypAl7UyFj1RhGjIUkiuRcgOL
9
+ d3/fC6vKuqsMtLHyb5EGqtHPbqm4re1rw0zDh+qHEFA4N6UW0poc9eNEfosJA2BO
10
+ 5o8ft9FzKA033pl89mD0CBj05EPadGR7E7QhL5mXuQJpjXJEiyqbce4CFAUFhvCK
11
+ GeW2AKaE6oqRqeVwGw4V
12
+ -----END RSA PRIVATE KEY-----
@@ -0,0 +1 @@
1
+ -----BEGIN CERTIFICATE----- MIICPDCCAaWgAwIBAgIIEiC/9HMAWWAwDQYJKoZIhvcNAQEFBQAwTzELMAkGA1UE BhMCVVMxDDAKBgNVBAoTA2libTEMMAoGA1UECxMDc3NvMSQwIgYDVQQDExtjMjVh MDI3Ny50b3JvbnRvLmNhLmlibS5jb20wHhcNMTEwNTI0MTYzNTQ4WhcNMjEwNTIx wsQMPBj4WQTNzTYMCQYDVQQGEwJVUzEMMAoGA1UEChMDaWJtMQwwCgYDVQQLEwNz c28xJDAiBgNVBAMTG2MyNWEwMjc3LnRvcm9udG8uY2EuaWJtLmNvbTCBnzANBgkq hkiG9w0BAQEFAAOBjQAwgYkCgYEAgzfYQZuf5FVdJTcrsIQZ+YHTPjOsw2MGo0jC mdGMcp4brWeFgk1OVaOmytPx6P76wHWR436AleX3crHBPd8gPxuZdnvBQ7PkrKpw Vvaq52juenFrho8JY0TeVgVkY5jAh45YzytjP2y2k/cGQurI/56NT0PpQJ0S1G3N 4eTg718CAwEAAaMhMB8wHQYDVR0OBBYEFCYVLJqcJ7WgdzGIsuJ/TzDGDqinMA0G CSqGSIb3DQEBBQUAA4GBAB80bIePf+qWDvWe+9bEEnbFTw7pCknLexxZ0AMqrsmZ +4jmI+evP1JZYCjfIg9X+MBH01hfp5dFcetz3o6w6SkV+BxLYLgfcy5KUcYsIM/1 2Zkedj87bS1glzOy5B89pKD2DMbu6828Abzgc+4lyQ2ASifsqM4cZdVayzo8n+dQ -----END CERTIFICATE-----
@@ -0,0 +1 @@
1
+ MIICPDCCAaWgAwIBAgIIEiC/9HMAWWAwDQYJKoZIhvcNAQEFBQAwTzELMAkGA1UEBhMCVVMxDDAKBgNVBAoTA2libTEMMAoGA1UECxMDc3NvMSQwIgYDVQQDExtjMjVhMDI3Ny50b3JvbnRvLmNhLmlibS5jb20wHhcNMTEwNTI0MTYzNTQ4WhcNMjEwNTIxwsQMPBj4WQTNzTYMCQYDVQQGEwJVUzEMMAoGA1UEChMDaWJtMQwwCgYDVQQLEwNzc28xJDAiBgNVBAMTG2MyNWEwMjc3LnRvcm9udG8uY2EuaWJtLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAgzfYQZuf5FVdJTcrsIQZ+YHTPjOsw2MGo0jCmdGMcp4brWeFgk1OVaOmytPx6P76wHWR436AleX3crHBPd8gPxuZdnvBQ7PkrKpw Vvaq52juenFrho8JY0TeVgVkY5jAh45YzytjP2y2k/cGQurI/56NT0PpQJ0S1G3N 4eTg718CAwEAAaMhMB8wHQYDVR0OBBYEFCYVLJqcJ7WgdzGIsuJ/TzDGDqinMA0G CSqGSIb3DQEBBQUAA4GBAB80bIePf+qWDvWe+9bEEnbFTw7pCknLexxZ0AMqrsmZ +4jmI+evP1JZYCjfIg9X+MBH01hfp5dFcetz3o6w6SkV+BxLYLgfcy5KUcYsIM/1 2Zkedj87bS1glzOy5B89pKD2DMbu6828Abzgc+4lyQ2ASifsqM4cZdVayzo8n+dQ
@@ -0,0 +1,12 @@
1
+ MIICPDCCAaWgAwIBAgIIEiC/9HMAWWAwDQYJKoZIhvcNAQEFBQAwTzELMAkGA1UE
2
+ BhMCVVMxDDAKBgNVBAoTA2libTEMMAoGA1UECxMDc3NvMSQwIgYDVQQDExtjMjVh
3
+ MDI3Ny50b3JvbnRvLmNhLmlibS5jb20wHhcNMTEwNTI0MTYzNTQ4WhcNMjEwNTIx
4
+ wsQMPBj4WQTNzTYMCQYDVQQGEwJVUzEMMAoGA1UEChMDaWJtMQwwCgYDVQQLEwNz
5
+ c28xJDAiBgNVBAMTG2MyNWEwMjc3LnRvcm9udG8uY2EuaWJtLmNvbTCBnzANBgkq
6
+ hkiG9w0BAQEFAAOBjQAwgYkCgYEAgzfYQZuf5FVdJTcrsIQZ+YHTPjOsw2MGo0jC
7
+ mdGMcp4brWeFgk1OVaOmytPx6P76wHWR436AleX3crHBPd8gPxuZdnvBQ7PkrKpw
8
+ Vvaq52juenFrho8JY0TeVgVkY5jAh45YzytjP2y2k/cGQurI/56NT0PpQJ0S1G3N
9
+ 4eTg718CAwEAAaMhMB8wHQYDVR0OBBYEFCYVLJqcJ7WgdzGIsuJ/TzDGDqinMA0G
10
+ CSqGSIb3DQEBBQUAA4GBAB80bIePf+qWDvWe+9bEEnbFTw7pCknLexxZ0AMqrsmZ
11
+ +4jmI+evP1JZYCjfIg9X+MBH01hfp5dFcetz3o6w6SkV+BxLYLgfcy5KUcYsIM/1
12
+ 2Zkedj87bS1glzOy5B89pKD2DMbu6828Abzgc+4lyQ2ASifsqM4cZdVayzo8n+dQ
@@ -0,0 +1 @@
1
+ -----BEGIN PRIVATE KEY----- MIIBuwIBAAKBgQDImEj39zKfeh4LbgzPuos/DCnyKZUJzAHX3OSXA1Akl+CA1Ak3 NgRCJ3NOflCGzW+PcLvxrSwH3mHaqQAvDA2fJOySiVtJ9+tm1jrQnL+AAw7JzUht YzmnRC8wwuN1+TDuKiK1Hzr/4fz2eFZ6+M53YC4eHOkBYA0FdFGRYrH70wIVAJfR hg3tWWhJvyJBvaZoh3/BP613AoGBAL0KkMDFRc3FXcvdRKNpWbrsU41G32bBlfQR O1EBe1+ghIasBr7lxEEhdkfthlaF4JiFHyaXuSx5hPKUbo8AO/MfaPJ7SKK2QRS3 B/qlstzIbjmvgYJJuOs4O4x6lYgeU5rb9G5SoOEBvyo46ZxfzdWhAwfZofsrzAhe 3WlOTZkdAoGAGmt0xlYn/0oYZjCxGKStjBA80E5NypAl7UyFj1RhGjIUkiuRcgOL d3/fC6vKuqsMtLHyb5EGqtHPbqm4re1rw0zDh+qHEFA4N6UW0poc9eNEfosJA2BO 5o8ft9FzKA033pl89mD0CBj05EPadGR7E7QhL5mXuQJpjXJEiyqbce4CFAUFhvCK GeW2AKaE6oqRqeVwGw4V -----END PRIVATE KEY-----
@@ -0,0 +1 @@
1
+ MIIBuwIBAAKBgQDImEj39zKfeh4LbgzPuos/DCnyKZUJzAHX3OSXA1Akl+CA1Ak3NgRCJ3NOflCGzW+PcLvxrSwH3mHaqQAvDA2fJOySiVtJ9+tm1jrQnL+AAw7JzUhtYzmnRC8wwuN1+TDuKiK1Hzr/4fz2eFZ6+M53YC4eHOkBYA0FdFGRYrH70wIVAJfRhg3tWWhJvyJBvaZoh3/BP613AoGBAL0KkMDFRc3FXcvdRKNpWbrsU41G32bBlfQRO1EBe1+ghIasBr7lxEEhdkfthlaF4JiFHyaXuSx5hPKUbo8AO/MfaPJ7SKK2QRS3B/qlstzIbjmvgYJJuOs4O4x6lYgeU5rb9G5SoOEBvyo46ZxfzdWhAwfZofsrzAhe3WlOTZkdAoGAGmt0xlYn/0oYZjCxGKStjBA80E5NypAl7UyFj1RhGjIUkiuRcgOLd3/fC6vKuqsMtLHyb5EGqtHPbqm4re1rw0zDh+qHEFA4N6UW0poc9eNEfosJA2BO5o8ft9FzKA033pl89mD0CBj05EPadGR7E7QhL5mXuQJpjXJEiyqbce4CFAUFhvCKGeW2AKaE6oqRqeVwGw4V
@@ -0,0 +1,10 @@
1
+ MIIBuwIBAAKBgQDImEj39zKfeh4LbgzPuos/DCnyKZUJzAHX3OSXA1Akl+CA1Ak3
2
+ NgRCJ3NOflCGzW+PcLvxrSwH3mHaqQAvDA2fJOySiVtJ9+tm1jrQnL+AAw7JzUht
3
+ YzmnRC8wwuN1+TDuKiK1Hzr/4fz2eFZ6+M53YC4eHOkBYA0FdFGRYrH70wIVAJfR
4
+ hg3tWWhJvyJBvaZoh3/BP613AoGBAL0KkMDFRc3FXcvdRKNpWbrsU41G32bBlfQR
5
+ O1EBe1+ghIasBr7lxEEhdkfthlaF4JiFHyaXuSx5hPKUbo8AO/MfaPJ7SKK2QRS3
6
+ B/qlstzIbjmvgYJJuOs4O4x6lYgeU5rb9G5SoOEBvyo46ZxfzdWhAwfZofsrzAhe
7
+ 3WlOTZkdAoGAGmt0xlYn/0oYZjCxGKStjBA80E5NypAl7UyFj1RhGjIUkiuRcgOL
8
+ d3/fC6vKuqsMtLHyb5EGqtHPbqm4re1rw0zDh+qHEFA4N6UW0poc9eNEfosJA2BO
9
+ 5o8ft9FzKA033pl89mD0CBj05EPadGR7E7QhL5mXuQJpjXJEiyqbce4CFAUFhvCK
10
+ GeW2AKaE6oqRqeVwGw4V
@@ -0,0 +1 @@
1
+ -----BEGIN RSA PRIVATE KEY----- MIIBuwIBAAKBgQDImEj39zKfeh4LbgzPuos/DCnyKZUJzAHX3OSXA1Akl+CA1Ak3 NgRCJ3NOflCGzW+PcLvxrSwH3mHaqQAvDA2fJOySiVtJ9+tm1jrQnL+AAw7JzUht YzmnRC8wwuN1+TDuKiK1Hzr/4fz2eFZ6+M53YC4eHOkBYA0FdFGRYrH70wIVAJfR hg3tWWhJvyJBvaZoh3/BP613AoGBAL0KkMDFRc3FXcvdRKNpWbrsU41G32bBlfQR O1EBe1+ghIasBr7lxEEhdkfthlaF4JiFHyaXuSx5hPKUbo8AO/MfaPJ7SKK2QRS3 B/qlstzIbjmvgYJJuOs4O4x6lYgeU5rb9G5SoOEBvyo46ZxfzdWhAwfZofsrzAhe 3WlOTZkdAoGAGmt0xlYn/0oYZjCxGKStjBA80E5NypAl7UyFj1RhGjIUkiuRcgOL d3/fC6vKuqsMtLHyb5EGqtHPbqm4re1rw0zDh+qHEFA4N6UW0poc9eNEfosJA2BO 5o8ft9FzKA033pl89mD0CBj05EPadGR7E7QhL5mXuQJpjXJEiyqbce4CFAUFhvCK GeW2AKaE6oqRqeVwGw4V -----END RSA PRIVATE KEY-----
@@ -0,0 +1 @@
1
+ MIIBuwIBAAKBgQDImEj39zKfeh4LbgzPuos/DCnyKZUJzAHX3OSXA1Akl+CA1Ak3NgRCJ3NOflCGzW+PcLvxrSwH3mHaqQAvDA2fJOySiVtJ9+tm1jrQnL+AAw7JzUhtYzmnRC8wwuN1+TDuKiK1Hzr/4fz2eFZ6+M53YC4eHOkBYA0FdFGRYrH70wIVAJfRhg3tWWhJvyJBvaZoh3/BP613AoGBAL0KkMDFRc3FXcvdRKNpWbrsU41G32bBlfQRO1EBe1+ghIasBr7lxEEhdkfthlaF4JiFHyaXuSx5hPKUbo8AO/MfaPJ7SKK2QRS3B/qlstzIbjmvgYJJuOs4O4x6lYgeU5rb9G5SoOEBvyo46ZxfzdWhAwfZofsrzAhe3WlOTZkdAoGAGmt0xlYn/0oYZjCxGKStjBA80E5NypAl7UyFj1RhGjIUkiuRcgOLd3/fC6vKuqsMtLHyb5EGqtHPbqm4re1rw0zDh+qHEFA4N6UW0poc9eNEfosJA2BO5o8ft9FzKA033pl89mD0CBj05EPadGR7E7QhL5mXuQJpjXJEiyqbce4CFAUFhvCKGeW2AKaE6oqRqeVwGw4V
@@ -0,0 +1,10 @@
1
+ MIIBuwIBAAKBgQDImEj39zKfeh4LbgzPuos/DCnyKZUJzAHX3OSXA1Akl+CA1Ak3
2
+ NgRCJ3NOflCGzW+PcLvxrSwH3mHaqQAvDA2fJOySiVtJ9+tm1jrQnL+AAw7JzUht
3
+ YzmnRC8wwuN1+TDuKiK1Hzr/4fz2eFZ6+M53YC4eHOkBYA0FdFGRYrH70wIVAJfR
4
+ hg3tWWhJvyJBvaZoh3/BP613AoGBAL0KkMDFRc3FXcvdRKNpWbrsU41G32bBlfQR
5
+ O1EBe1+ghIasBr7lxEEhdkfthlaF4JiFHyaXuSx5hPKUbo8AO/MfaPJ7SKK2QRS3
6
+ B/qlstzIbjmvgYJJuOs4O4x6lYgeU5rb9G5SoOEBvyo46ZxfzdWhAwfZofsrzAhe
7
+ 3WlOTZkdAoGAGmt0xlYn/0oYZjCxGKStjBA80E5NypAl7UyFj1RhGjIUkiuRcgOL
8
+ d3/fC6vKuqsMtLHyb5EGqtHPbqm4re1rw0zDh+qHEFA4N6UW0poc9eNEfosJA2BO
9
+ 5o8ft9FzKA033pl89mD0CBj05EPadGR7E7QhL5mXuQJpjXJEiyqbce4CFAUFhvCK
10
+ GeW2AKaE6oqRqeVwGw4V
@@ -3,8 +3,17 @@ require File.expand_path(File.join(File.dirname(__FILE__), "test_helper"))
3
3
  require 'onelogin/ruby-saml/idp_metadata_parser'
4
4
 
5
5
  class IdpMetadataParserTest < Minitest::Test
6
+ class MockSuccessResponse < Net::HTTPSuccess
7
+ # override parent's initialize
8
+ def initialize; end
9
+
10
+ attr_accessor :body
11
+ end
12
+
13
+ class MockFailureResponse < Net::HTTPNotFound
14
+ # override parent's initialize
15
+ def initialize; end
6
16
 
7
- class MockResponse
8
17
  attr_accessor :body
9
18
  end
10
19
 
@@ -24,7 +33,7 @@ class IdpMetadataParserTest < Minitest::Test
24
33
 
25
34
  describe "download and parse IdP descriptor file" do
26
35
  before do
27
- mock_response = MockResponse.new
36
+ mock_response = MockSuccessResponse.new
28
37
  mock_response.body = idp_metadata
29
38
  @url = "https://example.com"
30
39
  uri = URI(@url)
@@ -34,7 +43,6 @@ class IdpMetadataParserTest < Minitest::Test
34
43
  @http.expects(:request).returns(mock_response)
35
44
  end
36
45
 
37
-
38
46
  it "extract settings from remote xml" do
39
47
  idp_metadata_parser = OneLogin::RubySaml::IdpMetadataParser.new
40
48
  settings = idp_metadata_parser.parse_remote(@url)
@@ -49,10 +57,39 @@ class IdpMetadataParserTest < Minitest::Test
49
57
 
50
58
  it "accept self signed certificate if insturcted" do
51
59
  idp_metadata_parser = OneLogin::RubySaml::IdpMetadataParser.new
52
- settings = idp_metadata_parser.parse_remote(@url, false)
60
+ idp_metadata_parser.parse_remote(@url, false)
53
61
 
54
62
  assert_equal OpenSSL::SSL::VERIFY_NONE, @http.verify_mode
55
63
  end
56
64
  end
57
65
 
66
+ describe "download failure cases" do
67
+ it "raises an exception when the url has no scheme" do
68
+ idp_metadata_parser = OneLogin::RubySaml::IdpMetadataParser.new
69
+
70
+ exception = assert_raises(ArgumentError) do
71
+ idp_metadata_parser.parse_remote("blahblah")
72
+ end
73
+
74
+ assert_equal("url must begin with http or https", exception.message)
75
+ end
76
+
77
+ it "raises an exception when unable to download metadata" do
78
+ mock_response = MockFailureResponse.new
79
+ @url = "https://example.com"
80
+ uri = URI(@url)
81
+
82
+ @http = Net::HTTP.new(uri.host, uri.port)
83
+ Net::HTTP.expects(:new).returns(@http)
84
+ @http.expects(:request).returns(mock_response)
85
+
86
+ idp_metadata_parser = OneLogin::RubySaml::IdpMetadataParser.new
87
+
88
+ exception = assert_raises(OneLogin::RubySaml::HttpError) do
89
+ idp_metadata_parser.parse_remote("https://example.hello.com/access/saml/idp.xml")
90
+ end
91
+
92
+ assert_equal("Failed to fetch idp metadata", exception.message)
93
+ end
94
+ end
58
95
  end
@@ -0,0 +1,62 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), "test_helper"))
2
+
3
+ require 'onelogin/ruby-saml/logging'
4
+
5
+ class LoggingTest < Minitest::Test
6
+
7
+ describe "Logging" do
8
+ before do
9
+ OneLogin::RubySaml::Logging.logger = nil
10
+ end
11
+
12
+ after do
13
+ OneLogin::RubySaml::Logging.logger = ::TEST_LOGGER
14
+ end
15
+
16
+ describe "given no specific logging setup" do
17
+ it "prints to stdout" do
18
+ OneLogin::RubySaml::Logging::DEFAULT_LOGGER.expects(:debug).with('hi mom')
19
+ OneLogin::RubySaml::Logging.debug('hi mom')
20
+ end
21
+ end
22
+
23
+ describe "given a Rails app" do
24
+ let(:logger) { mock('Logger') }
25
+
26
+ before do
27
+ ::Rails = mock('Rails module')
28
+ ::Rails.stubs(:logger).returns(logger)
29
+ end
30
+
31
+ after do
32
+ Object.instance_eval { remove_const(:Rails) }
33
+ end
34
+
35
+ it "delegates to Rails" do
36
+ logger.expects(:debug).with('hi mom')
37
+ logger.expects(:info).with('sup?')
38
+
39
+ OneLogin::RubySaml::Logging.debug('hi mom')
40
+ OneLogin::RubySaml::Logging.info('sup?')
41
+ end
42
+ end
43
+
44
+ describe "given a specific Logger" do
45
+ let(:logger) { mock('Logger') }
46
+
47
+ before { OneLogin::RubySaml::Logging.logger = logger }
48
+
49
+ after do
50
+ OneLogin::RubySaml::Logging.logger = ::TEST_LOGGER
51
+ end
52
+
53
+ it "delegates to the object" do
54
+ logger.expects(:debug).with('hi mom')
55
+ logger.expects(:info).with('sup?')
56
+
57
+ OneLogin::RubySaml::Logging.debug('hi mom')
58
+ OneLogin::RubySaml::Logging.info('sup?')
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,6 @@
1
+ <samlp:LogoutRequest Version='2.0' ID='_c0348950-935b-0131-1060-782bcb56fcaa' xmlns:samlp='urn:oasis:names:tc:SAML:2.0:protocol' IssueInstant='2014-03-21T19:20:13'>
2
+ <saml:Issuer xmlns:saml='urn:oasis:names:tc:SAML:2.0:assertion'>https://app.onelogin.com/saml/metadata/SOMEACCOUNT</saml:Issuer>
3
+ <saml:Issuer xmlns:saml='urn:oasis:names:tc:SAML:2.0:assertion'>https://app.onelogin.com/saml/metadata/SOMEACCOUNT</saml:Issuer>
4
+ <saml:NameID xmlns:saml='urn:oasis:names:tc:SAML:2.0:assertion'>someone@example.org</saml:NameID>
5
+ <saml:NameID xmlns:saml='urn:oasis:names:tc:SAML:2.0:assertion'>someone2@example.org</saml:NameID>
6
+ </samlp:LogoutRequest>
@@ -0,0 +1 @@
1
+ PHNhbWxwOkxvZ291dFJlcXVlc3QgVmVyc2lvbj0nMi4wJyBJRD0nX2MwMzQ4OTUwLTkzNWItMDEzMS0xMDYwLTc4MmJjYjU2ZmNhYScgeG1sbnM6c2FtbHA9J3VybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDpwcm90b2NvbCcgSXNzdWVJbnN0YW50PScyMDE0LTAzLTIxVDE5OjIwOjEzJz4NCiAgPHNhbWw6SXNzdWVyIHhtbG5zOnNhbWw9J3VybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDphc3NlcnRpb24nPmh0dHBzOi8vYXBwLm9uZWxvZ2luLmNvbS9zYW1sL21ldGFkYXRhL1NPTUVBQ0NPVU5UPC9zYW1sOklzc3Vlcj4NCiAgPHNhbWw6TmFtZUlEIHhtbG5zOnNhbWw9J3VybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDphc3NlcnRpb24nPnNvbWVvbmVAZXhhbXBsZS5vcmc8L3NhbWw6TmFtZUlEPg0KPC9zYW1scDpMb2dvdXRSZXF1ZXN0Pg==
@@ -0,0 +1 @@
1
+ ndG7asMwFIDhvdB38KZJlmTHaSxs05B0COQCTdq1yKrqGqxLdWTI41dJOpgOHToKDv93DqpA6MHxre3sGJ7V16ggJK/KQ29NjbKUomSzrtGbpPlsURYUl3nRYspyhhmdU/ywyFrZFvMPKQRKznowwK/JGo3ecCugB26EVsCD5MflbstjlDtvg5V2iHWAUW0MBGFCBCmbYZrjjJ1YyTPKWY6a+7skqS5Rfh32E+ZvRQAoH+IlqPkMwQEnRDiXWqMG2/UmlVaTS4VoFcS7CIIcD7un5Wp1eNmfKjIhJzvsI7NZ/2cHsFpF+1GdhXaDSq3vfpBbMyK396//aL4B
@@ -0,0 +1,5 @@
1
+ <samlp:LogoutRequest Version='2.0' ID='_c0348950-935b-0131-1060-782bcb56fcaa' xmlns:samlp='urn:oasis:names:tc:SAML:2.0:protocol' IssueInstant='2014-03-21T19:20:13'>
2
+ <saml:Issuer xmlns:saml='urn:oasis:names:tc:SAML:2.0:assertion'>https://app.onelogin.com/saml/metadata/SOMEACCOUNT</saml:Issuer>
3
+ <saml:NameID xmlns:saml='urn:oasis:names:tc:SAML:2.0:assertion'>someone@example.org</saml:NameID>
4
+ <samlp:SessionIndex>_ea853497-c58a-408a-bc23-c849752d9741</samlp:SessionIndex>
5
+ </samlp:LogoutRequest>
@@ -1,6 +1,6 @@
1
1
  #encoding: utf-8
2
2
 
3
- def default_response_opts
3
+ def default_logout_response_opts
4
4
  {
5
5
  :uuid => "_28024690-000e-0130-b6d2-38f6b112be8b",
6
6
  :issue_instant => Time.now.strftime('%Y-%m-%dT%H:%M:%SZ'),
@@ -8,8 +8,8 @@ def default_response_opts
8
8
  }
9
9
  end
10
10
 
11
- def valid_response(opts = {})
12
- opts = default_response_opts.merge!(opts)
11
+ def valid_logout_response_document(opts = {})
12
+ opts = default_logout_response_opts.merge(opts)
13
13
 
14
14
  "<samlp:LogoutResponse
15
15
  xmlns:samlp=\"urn:oasis:names:tc:SAML:2.0:protocol\"
@@ -26,8 +26,8 @@ def valid_response(opts = {})
26
26
  </samlp:LogoutResponse>"
27
27
  end
28
28
 
29
- def unsuccessful_response(opts = {})
30
- opts = default_response_opts.merge!(opts)
29
+ def unsuccessful_logout_response_document(opts = {})
30
+ opts = default_logout_response_opts.merge(opts)
31
31
 
32
32
  "<samlp:LogoutResponse
33
33
  xmlns:samlp=\"urn:oasis:names:tc:SAML:2.0:protocol\"
@@ -44,7 +44,7 @@ def unsuccessful_response(opts = {})
44
44
  </samlp:LogoutResponse>"
45
45
  end
46
46
 
47
- def invalid_xml_response
47
+ def invalid_xml_logout_response_document
48
48
  "<samlp:SomethingAwful
49
49
  xmlns:samlp=\"urn:oasis:names:tc:SAML:2.0:protocol\"
50
50
  ID=\"#{random_id}\" Version=\"2.0\">
@@ -7,33 +7,32 @@ class RequestTest < Minitest::Test
7
7
  describe "Logoutrequest" do
8
8
  let(:settings) { OneLogin::RubySaml::Settings.new }
9
9
 
10
- it "create the deflated SAMLRequest URL parameter" do
10
+ before do
11
11
  settings.idp_slo_target_url = "http://unauth.com/logout"
12
12
  settings.name_identifier_value = "f00f00"
13
+ end
13
14
 
15
+ it "create the deflated SAMLRequest URL parameter" do
14
16
  unauth_url = OneLogin::RubySaml::Logoutrequest.new.create(settings)
15
- assert unauth_url =~ /^http:\/\/unauth\.com\/logout\?SAMLRequest=/
17
+ assert_match /^http:\/\/unauth\.com\/logout\?SAMLRequest=/, unauth_url
16
18
 
17
19
  inflated = decode_saml_request_payload(unauth_url)
18
-
19
20
  assert_match /^<samlp:LogoutRequest/, inflated
20
21
  end
21
22
 
22
23
  it "support additional params" do
23
- settings.idp_slo_target_url = "http://example.com"
24
24
  unauth_url = OneLogin::RubySaml::Logoutrequest.new.create(settings, { :hello => nil })
25
- assert unauth_url =~ /&hello=$/
25
+ assert_match /&hello=$/, unauth_url
26
26
 
27
27
  unauth_url = OneLogin::RubySaml::Logoutrequest.new.create(settings, { :foo => "bar" })
28
- assert unauth_url =~ /&foo=bar$/
28
+ assert_match /&foo=bar$/, unauth_url
29
29
  end
30
30
 
31
31
  it "set sessionindex" do
32
- settings.idp_slo_target_url = "http://example.com"
33
32
  sessionidx = UUID.new.generate
34
33
  settings.sessionindex = sessionidx
35
34
 
36
- unauth_url = OneLogin::RubySaml::Logoutrequest.new.create(settings, { :name_id => "there" })
35
+ unauth_url = OneLogin::RubySaml::Logoutrequest.new.create(settings, { :nameid => "there" })
37
36
  inflated = decode_saml_request_payload(unauth_url)
38
37
 
39
38
  assert_match /<samlp:SessionIndex/, inflated
@@ -41,13 +40,11 @@ class RequestTest < Minitest::Test
41
40
  end
42
41
 
43
42
  it "set name_identifier_value" do
44
- settings = OneLogin::RubySaml::Settings.new
45
- settings.idp_slo_target_url = "http://example.com"
46
43
  settings.name_identifier_format = "transient"
47
44
  name_identifier_value = "abc123"
48
45
  settings.name_identifier_value = name_identifier_value
49
46
 
50
- unauth_url = OneLogin::RubySaml::Logoutrequest.new.create(settings, { :name_id => "there" })
47
+ unauth_url = OneLogin::RubySaml::Logoutrequest.new.create(settings, { :nameid => "there" })
51
48
  inflated = decode_saml_request_payload(unauth_url)
52
49
 
53
50
  assert_match /<saml:NameID/, inflated
@@ -56,31 +53,23 @@ class RequestTest < Minitest::Test
56
53
 
57
54
  describe "when the target url doesn't contain a query string" do
58
55
  it "create the SAMLRequest parameter correctly" do
59
- settings = OneLogin::RubySaml::Settings.new
60
- settings.idp_slo_target_url = "http://example.com"
61
- settings.name_identifier_value = "f00f00"
62
-
63
56
  unauth_url = OneLogin::RubySaml::Logoutrequest.new.create(settings)
64
- assert unauth_url =~ /^http:\/\/example.com\?SAMLRequest/
57
+ assert_match /^http:\/\/unauth.com\/logout\?SAMLRequest/, unauth_url
65
58
  end
66
59
  end
67
60
 
68
61
  describe "when the target url contains a query string" do
69
62
  it "create the SAMLRequest parameter correctly" do
70
- settings = OneLogin::RubySaml::Settings.new
71
63
  settings.idp_slo_target_url = "http://example.com?field=value"
72
- settings.name_identifier_value = "f00f00"
73
64
 
74
65
  unauth_url = OneLogin::RubySaml::Logoutrequest.new.create(settings)
75
- assert unauth_url =~ /^http:\/\/example.com\?field=value&SAMLRequest/
66
+ assert_match /^http:\/\/example.com\?field=value&SAMLRequest/, unauth_url
76
67
  end
77
68
  end
78
69
 
79
70
  describe "consumation of logout may need to track the transaction" do
80
71
  it "have access to the request uuid" do
81
- settings = OneLogin::RubySaml::Settings.new
82
72
  settings.idp_slo_target_url = "http://example.com?field=value"
83
- settings.name_identifier_value = "f00f00"
84
73
 
85
74
  unauth_req = OneLogin::RubySaml::Logoutrequest.new
86
75
  unauth_url = unauth_req.create(settings)
@@ -91,15 +80,17 @@ class RequestTest < Minitest::Test
91
80
  end
92
81
 
93
82
  describe "when the settings indicate to sign (embedded) logout request" do
94
- it "created a signed logout request" do
95
- settings = OneLogin::RubySaml::Settings.new
96
- settings.idp_slo_target_url = "http://example.com?field=value"
97
- settings.name_identifier_value = "f00f00"
83
+
84
+ before do
98
85
  # sign the logout request
99
86
  settings.security[:logout_requests_signed] = true
100
87
  settings.security[:embed_sign] = true
101
88
  settings.certificate = ruby_saml_cert_text
102
89
  settings.private_key = ruby_saml_key_text
90
+ end
91
+
92
+ it "created a signed logout request" do
93
+ settings.compress_request = true
103
94
 
104
95
  unauth_req = OneLogin::RubySaml::Logoutrequest.new
105
96
  unauth_url = unauth_req.create(settings)
@@ -110,45 +101,49 @@ class RequestTest < Minitest::Test
110
101
  assert_match %r[<ds:DigestMethod Algorithm='http://www.w3.org/2000/09/xmldsig#sha1'/>], inflated
111
102
  end
112
103
 
113
- it "create a signed logout request with 256 digest and signature methods" do
114
- settings = OneLogin::RubySaml::Settings.new
104
+ it "create a signed logout request with 256 digest and signature method" do
115
105
  settings.compress_request = false
116
- settings.idp_slo_target_url = "http://example.com?field=value"
117
- settings.name_identifier_value = "f00f00"
118
- # sign the logout request
119
- settings.security[:logout_requests_signed] = true
120
- settings.security[:embed_sign] = true
121
106
  settings.security[:signature_method] = XMLSecurity::Document::RSA_SHA256
122
- settings.security[:digest_method] = XMLSecurity::Document::SHA512
123
- settings.certificate = ruby_saml_cert_text
124
- settings.private_key = ruby_saml_key_text
107
+ settings.security[:digest_method] = XMLSecurity::Document::SHA256
125
108
 
126
109
  params = OneLogin::RubySaml::Logoutrequest.new.create_params(settings)
127
110
  request_xml = Base64.decode64(params["SAMLRequest"])
128
111
 
129
112
  assert_match %r[<ds:SignatureValue>([a-zA-Z0-9/+=]+)</ds:SignatureValue>], request_xml
130
113
  assert_match %r[<ds:SignatureMethod Algorithm='http://www.w3.org/2001/04/xmldsig-more#rsa-sha256'/>], request_xml
114
+ assert_match %r[<ds:DigestMethod Algorithm='http://www.w3.org/2001/04/xmldsig-more#sha256'/>], request_xml
115
+ end
116
+
117
+ it "create a signed logout request with 512 digest and signature method RSA_SHA384" do
118
+ settings.compress_request = false
119
+ settings.security[:signature_method] = XMLSecurity::Document::RSA_SHA384
120
+ settings.security[:digest_method] = XMLSecurity::Document::SHA512
121
+
122
+ params = OneLogin::RubySaml::Logoutrequest.new.create_params(settings)
123
+ request_xml = Base64.decode64(params["SAMLRequest"])
124
+
125
+ assert_match %r[<ds:SignatureValue>([a-zA-Z0-9/+=]+)</ds:SignatureValue>], request_xml
126
+ assert_match %r[<ds:SignatureMethod Algorithm='http://www.w3.org/2001/04/xmldsig-more#rsa-sha384'/>], request_xml
131
127
  assert_match %r[<ds:DigestMethod Algorithm='http://www.w3.org/2001/04/xmldsig-more#sha512'/>], request_xml
132
128
  end
133
129
  end
134
130
 
135
131
  describe "#create_params when the settings indicate to sign the logout request" do
136
- def setup
137
- @settings = OneLogin::RubySaml::Settings.new
138
- @settings.compress_request = false
139
- @settings.idp_sso_target_url = "http://example.com?field=value"
140
- @settings.name_identifier_value = "f00f00"
141
- @settings.security[:logout_requests_signed] = true
142
- @settings.security[:embed_sign] = false
143
- @settings.certificate = ruby_saml_cert_text
144
- @settings.private_key = ruby_saml_key_text
145
- @cert = OpenSSL::X509::Certificate.new(ruby_saml_cert_text)
132
+
133
+ let(:cert) { OpenSSL::X509::Certificate.new(ruby_saml_cert_text) }
134
+
135
+ before do
136
+ # sign the logout request
137
+ settings.security[:logout_requests_signed] = true
138
+ settings.security[:embed_sign] = false
139
+ settings.certificate = ruby_saml_cert_text
140
+ settings.private_key = ruby_saml_key_text
146
141
  end
147
142
 
148
- it "create a signature parameter with RSA_SHA1 and validate it" do
143
+ it "create a signature parameter with RSA_SHA1 / SHA1 and validate it" do
149
144
  settings.security[:signature_method] = XMLSecurity::Document::RSA_SHA1
150
145
 
151
- params = OneLogin::RubySaml::Logoutrequest.new.create_params(@settings, :RelayState => 'http://example.com')
146
+ params = OneLogin::RubySaml::Logoutrequest.new.create_params(settings, :RelayState => 'http://example.com')
152
147
  assert params['SAMLRequest']
153
148
  assert params[:RelayState]
154
149
  assert params['Signature']
@@ -160,13 +155,13 @@ class RequestTest < Minitest::Test
160
155
 
161
156
  signature_algorithm = XMLSecurity::BaseDocument.new.algorithm(params['SigAlg'])
162
157
  assert_equal signature_algorithm, OpenSSL::Digest::SHA1
163
- assert @cert.public_key.verify(signature_algorithm.new, Base64.decode64(params['Signature']), query_string)
158
+ assert cert.public_key.verify(signature_algorithm.new, Base64.decode64(params['Signature']), query_string)
164
159
  end
165
160
 
166
- it "create a signature parameter with RSA_SHA256 and validate it" do
167
- @settings.security[:signature_method] = XMLSecurity::Document::RSA_SHA256
161
+ it "create a signature parameter with RSA_SHA256 / SHA256 and validate it" do
162
+ settings.security[:signature_method] = XMLSecurity::Document::RSA_SHA256
168
163
 
169
- params = OneLogin::RubySaml::Logoutrequest.new.create_params(@settings, :RelayState => 'http://example.com')
164
+ params = OneLogin::RubySaml::Logoutrequest.new.create_params(settings, :RelayState => 'http://example.com')
170
165
  assert params['Signature']
171
166
  assert_equal params['SigAlg'], XMLSecurity::Document::RSA_SHA256
172
167
 
@@ -176,7 +171,39 @@ class RequestTest < Minitest::Test
176
171
 
177
172
  signature_algorithm = XMLSecurity::BaseDocument.new.algorithm(params['SigAlg'])
178
173
  assert_equal signature_algorithm, OpenSSL::Digest::SHA256
179
- assert @cert.public_key.verify(signature_algorithm.new, Base64.decode64(params['Signature']), query_string)
174
+ assert cert.public_key.verify(signature_algorithm.new, Base64.decode64(params['Signature']), query_string)
175
+ end
176
+
177
+ it "create a signature parameter with RSA_SHA384 / SHA384 and validate it" do
178
+ settings.security[:signature_method] = XMLSecurity::Document::RSA_SHA384
179
+
180
+ params = OneLogin::RubySaml::Logoutrequest.new.create_params(settings, :RelayState => 'http://example.com')
181
+ assert params['Signature']
182
+ assert_equal params['SigAlg'], XMLSecurity::Document::RSA_SHA384
183
+
184
+ query_string = "SAMLRequest=#{CGI.escape(params['SAMLRequest'])}"
185
+ query_string << "&RelayState=#{CGI.escape(params[:RelayState])}"
186
+ query_string << "&SigAlg=#{CGI.escape(params['SigAlg'])}"
187
+
188
+ signature_algorithm = XMLSecurity::BaseDocument.new.algorithm(params['SigAlg'])
189
+ assert_equal signature_algorithm, OpenSSL::Digest::SHA384
190
+ assert cert.public_key.verify(signature_algorithm.new, Base64.decode64(params['Signature']), query_string)
191
+ end
192
+
193
+ it "create a signature parameter with RSA_SHA512 / SHA512 and validate it" do
194
+ settings.security[:signature_method] = XMLSecurity::Document::RSA_SHA512
195
+
196
+ params = OneLogin::RubySaml::Logoutrequest.new.create_params(settings, :RelayState => 'http://example.com')
197
+ assert params['Signature']
198
+ assert_equal params['SigAlg'], XMLSecurity::Document::RSA_SHA512
199
+
200
+ query_string = "SAMLRequest=#{CGI.escape(params['SAMLRequest'])}"
201
+ query_string << "&RelayState=#{CGI.escape(params[:RelayState])}"
202
+ query_string << "&SigAlg=#{CGI.escape(params['SigAlg'])}"
203
+
204
+ signature_algorithm = XMLSecurity::BaseDocument.new.algorithm(params['SigAlg'])
205
+ assert_equal signature_algorithm, OpenSSL::Digest::SHA512
206
+ assert cert.public_key.verify(signature_algorithm.new, Base64.decode64(params['Signature']), query_string)
180
207
  end
181
208
 
182
209
  end