ruby-saml 0.8.18 → 0.9

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 (90) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.travis.yml +1 -6
  4. data/Gemfile +2 -12
  5. data/README.md +363 -35
  6. data/Rakefile +14 -0
  7. data/changelog.md +22 -9
  8. data/lib/onelogin/ruby-saml/attribute_service.rb +34 -0
  9. data/lib/onelogin/ruby-saml/attributes.rb +26 -64
  10. data/lib/onelogin/ruby-saml/authrequest.rb +47 -93
  11. data/lib/onelogin/ruby-saml/idp_metadata_parser.rb +87 -0
  12. data/lib/onelogin/ruby-saml/logoutrequest.rb +36 -100
  13. data/lib/onelogin/ruby-saml/logoutresponse.rb +25 -35
  14. data/lib/onelogin/ruby-saml/metadata.rb +46 -16
  15. data/lib/onelogin/ruby-saml/response.rb +63 -373
  16. data/lib/onelogin/ruby-saml/saml_message.rb +78 -0
  17. data/lib/onelogin/ruby-saml/settings.rb +54 -122
  18. data/lib/onelogin/ruby-saml/slo_logoutrequest.rb +25 -71
  19. data/lib/onelogin/ruby-saml/slo_logoutresponse.rb +37 -102
  20. data/lib/onelogin/ruby-saml/utils.rb +32 -199
  21. data/lib/onelogin/ruby-saml/version.rb +1 -1
  22. data/lib/ruby-saml.rb +5 -2
  23. data/lib/schemas/{saml20assertion_schema.xsd → saml-schema-assertion-2.0.xsd} +283 -283
  24. data/lib/schemas/saml-schema-authn-context-2.0.xsd +23 -0
  25. data/lib/schemas/saml-schema-authn-context-types-2.0.xsd +821 -0
  26. data/lib/schemas/saml-schema-metadata-2.0.xsd +339 -0
  27. data/lib/schemas/{saml20protocol_schema.xsd → saml-schema-protocol-2.0.xsd} +302 -302
  28. data/lib/schemas/sstc-metadata-attr.xsd +35 -0
  29. data/lib/schemas/sstc-saml-attribute-ext.xsd +25 -0
  30. data/lib/schemas/sstc-saml-metadata-algsupport-v1.0.xsd +41 -0
  31. data/lib/schemas/sstc-saml-metadata-ui-v1.0.xsd +89 -0
  32. data/lib/schemas/{xenc_schema.xsd → xenc-schema.xsd} +1 -11
  33. data/lib/schemas/xml.xsd +287 -0
  34. data/lib/schemas/{xmldsig_schema.xsd → xmldsig-core-schema.xsd} +0 -9
  35. data/lib/xml_security.rb +83 -235
  36. data/ruby-saml.gemspec +1 -0
  37. data/test/idp_metadata_parser_test.rb +54 -0
  38. data/test/logoutrequest_test.rb +68 -155
  39. data/test/logoutresponse_test.rb +43 -32
  40. data/test/metadata_test.rb +87 -0
  41. data/test/request_test.rb +102 -99
  42. data/test/response_test.rb +181 -495
  43. data/test/responses/idp_descriptor.xml +3 -0
  44. data/test/responses/logoutresponse_fixtures.rb +7 -8
  45. data/test/responses/response_no_cert_and_encrypted_attrs.xml +29 -0
  46. data/test/responses/response_with_multiple_attribute_values.xml +1 -1
  47. data/test/responses/slo_request.xml +4 -0
  48. data/test/settings_test.rb +25 -112
  49. data/test/slo_logoutrequest_test.rb +40 -50
  50. data/test/slo_logoutresponse_test.rb +86 -185
  51. data/test/test_helper.rb +27 -102
  52. data/test/xml_security_test.rb +114 -337
  53. metadata +30 -81
  54. data/lib/onelogin/ruby-saml/setting_error.rb +0 -6
  55. data/test/certificates/certificate.der +0 -0
  56. data/test/certificates/formatted_certificate +0 -14
  57. data/test/certificates/formatted_chained_certificate +0 -42
  58. data/test/certificates/formatted_private_key +0 -12
  59. data/test/certificates/formatted_rsa_private_key +0 -12
  60. data/test/certificates/invalid_certificate1 +0 -1
  61. data/test/certificates/invalid_certificate2 +0 -1
  62. data/test/certificates/invalid_certificate3 +0 -12
  63. data/test/certificates/invalid_chained_certificate1 +0 -1
  64. data/test/certificates/invalid_private_key1 +0 -1
  65. data/test/certificates/invalid_private_key2 +0 -1
  66. data/test/certificates/invalid_private_key3 +0 -10
  67. data/test/certificates/invalid_rsa_private_key1 +0 -1
  68. data/test/certificates/invalid_rsa_private_key2 +0 -1
  69. data/test/certificates/invalid_rsa_private_key3 +0 -10
  70. data/test/certificates/ruby-saml-2.crt +0 -15
  71. data/test/requests/logoutrequest_fixtures.rb +0 -47
  72. data/test/responses/encrypted_new_attack.xml.base64 +0 -1
  73. data/test/responses/invalids/invalid_issuer_assertion.xml.base64 +0 -1
  74. data/test/responses/invalids/invalid_issuer_message.xml.base64 +0 -1
  75. data/test/responses/invalids/multiple_signed.xml.base64 +0 -1
  76. data/test/responses/invalids/no_signature.xml.base64 +0 -1
  77. data/test/responses/invalids/response_with_concealed_signed_assertion.xml +0 -51
  78. data/test/responses/invalids/response_with_doubled_signed_assertion.xml +0 -49
  79. data/test/responses/invalids/signature_wrapping_attack.xml.base64 +0 -1
  80. data/test/responses/response_node_text_attack.xml.base64 +0 -1
  81. data/test/responses/response_with_concealed_signed_assertion.xml +0 -51
  82. data/test/responses/response_with_doubled_signed_assertion.xml +0 -49
  83. data/test/responses/response_with_multiple_attribute_statements.xml +0 -72
  84. data/test/responses/response_with_signed_assertion_3.xml +0 -30
  85. data/test/responses/response_with_signed_message_and_assertion.xml +0 -34
  86. data/test/responses/response_with_undefined_recipient.xml.base64 +0 -1
  87. data/test/responses/response_wrapped.xml.base64 +0 -150
  88. data/test/responses/valid_response.xml.base64 +0 -1
  89. data/test/responses/valid_response_without_x509certificate.xml.base64 +0 -1
  90. data/test/utils_test.rb +0 -231
@@ -0,0 +1,3 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <md:EntityDescriptor entityID="https://example.hello.com/access/saml/idp.xml" validUntil="2014-04-17T18:02:33.910Z" xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata"><md:IDPSSODescriptor WantAuthnRequestsSigned="true" protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol"><md:KeyDescriptor use="signing"><ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#"><ds:X509Data><ds:X509Certificate>LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURxekNDQXhTZ0F3SUJBZ0lCQVRBTkJna3Foa2lHOXcwQkFRc0ZBRENCaGpFTE1Ba0dBMVVFQmhNQ1FWVXgKRERBS0JnTlZCQWdUQTA1VFZ6RVBNQTBHQTFVRUJ4TUdVM2xrYm1WNU1Rd3dDZ1lEVlFRS0RBTlFTVlF4Q1RBSApCZ05WQkFzTUFERVlNQllHQTFVRUF3d1BiR0YzY21WdVkyVndhWFF1WTI5dE1TVXdJd1lKS29aSWh2Y05BUWtCCkRCWnNZWGR5Wlc1alpTNXdhWFJBWjIxaGFXd3VZMjl0TUI0WERURXlNRFF4T1RJeU5UUXhPRm9YRFRNeU1EUXgKTkRJeU5UUXhPRm93Z1lZeEN6QUpCZ05WQkFZVEFrRlZNUXd3Q2dZRFZRUUlFd05PVTFjeER6QU5CZ05WQkFjVApCbE41Wkc1bGVURU1NQW9HQTFVRUNnd0RVRWxVTVFrd0J3WURWUVFMREFBeEdEQVdCZ05WQkFNTUQyeGhkM0psCmJtTmxjR2wwTG1OdmJURWxNQ01HQ1NxR1NJYjNEUUVKQVF3V2JHRjNjbVZ1WTJVdWNHbDBRR2R0WVdsc0xtTnYKYlRDQm56QU5CZ2txaGtpRzl3MEJBUUVGQUFPQmpRQXdnWWtDZ1lFQXFqaWUzUjJvaStwRGFldndJeXMvbWJVVApubkdsa3h0ZGlrcnExMXZleHd4SmlQTmhtaHFSVzNtVXVKRXpsbElkVkw2RW14R1lUcXBxZjkzSGxoa3NhZUowCjhVZ2pQOVVtTVlyaFZKdTFqY0ZXVjdmei9yKzIxL2F3VG5EVjlzTVlRcXVJUllZeTdiRzByMU9iaXdkb3ZudGsKN2dGSTA2WjB2WmFjREU1Ym9xVUNBd0VBQWFPQ0FTVXdnZ0VoTUFrR0ExVWRFd1FDTUFBd0N3WURWUjBQQkFRRApBZ1VnTUIwR0ExVWREZ1FXQkJTUk9OOEdKOG8rOGpnRnRqa3R3WmRxeDZCUnlUQVRCZ05WSFNVRUREQUtCZ2dyCkJnRUZCUWNEQVRBZEJnbGdoa2dCaHZoQ0FRMEVFQllPVkdWemRDQllOVEE1SUdObGNuUXdnYk1HQTFVZEl3U0IKcXpDQnFJQVVrVGpmQmlmS1B2STRCYlk1TGNHWGFzZWdVY21oZ1l5a2dZa3dnWVl4Q3pBSkJnTlZCQVlUQWtGVgpNUXd3Q2dZRFZRUUlFd05PVTFjeER6QU5CZ05WQkFjVEJsTjVaRzVsZVRFTU1Bb0dBMVVFQ2d3RFVFbFVNUWt3CkJ3WURWUVFMREFBeEdEQVdCZ05WQkFNTUQyeGhkM0psYm1ObGNHbDBMbU52YlRFbE1DTUdDU3FHU0liM0RRRUoKQVF3V2JHRjNjbVZ1WTJVdWNHbDBRR2R0WVdsc0xtTnZiWUlCQVRBTkJna3Foa2lHOXcwQkFRc0ZBQU9CZ1FDRQpUQWVKVERTQVc2ejFVRlRWN1FyZWg0VUxGT1JhajkrZUN1RjNLV0RIYyswSVFDajlyZG5ERzRRL3dmNy9yYVEwCkpuUFFDU0NkclBMSmV5b1BIN1FhVHdvYUY3ZHpWdzRMQ3N5TkpURld4NGNNNTBWdzZSNWZET2dpQzhic2ZmUzgKQkptb3VscnJaRE5OVmpHOG1XNmNMeHJZdlZRT3JSVmVjQ0ZJZ3NzQ2JBPT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=
3
+ </ds:X509Certificate></ds:X509Data></ds:KeyInfo></md:KeyDescriptor><md:KeyDescriptor use="encryption"><ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#"><ds:X509Data><ds:X509Certificate>LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURxekNDQXhTZ0F3SUJBZ0lCQVRBTkJna3Foa2lHOXcwQkFRc0ZBRENCaGpFTE1Ba0dBMVVFQmhNQ1FWVXgKRERBS0JnTlZCQWdUQTA1VFZ6RVBNQTBHQTFVRUJ4TUdVM2xrYm1WNU1Rd3dDZ1lEVlFRS0RBTlFTVlF4Q1RBSApCZ05WQkFzTUFERVlNQllHQTFVRUF3d1BiR0YzY21WdVkyVndhWFF1WTI5dE1TVXdJd1lKS29aSWh2Y05BUWtCCkRCWnNZWGR5Wlc1alpTNXdhWFJBWjIxaGFXd3VZMjl0TUI0WERURXlNRFF4T1RJeU5UUXhPRm9YRFRNeU1EUXgKTkRJeU5UUXhPRm93Z1lZeEN6QUpCZ05WQkFZVEFrRlZNUXd3Q2dZRFZRUUlFd05PVTFjeER6QU5CZ05WQkFjVApCbE41Wkc1bGVURU1NQW9HQTFVRUNnd0RVRWxVTVFrd0J3WURWUVFMREFBeEdEQVdCZ05WQkFNTUQyeGhkM0psCmJtTmxjR2wwTG1OdmJURWxNQ01HQ1NxR1NJYjNEUUVKQVF3V2JHRjNjbVZ1WTJVdWNHbDBRR2R0WVdsc0xtTnYKYlRDQm56QU5CZ2txaGtpRzl3MEJBUUVGQUFPQmpRQXdnWWtDZ1lFQXFqaWUzUjJvaStwRGFldndJeXMvbWJVVApubkdsa3h0ZGlrcnExMXZleHd4SmlQTmhtaHFSVzNtVXVKRXpsbElkVkw2RW14R1lUcXBxZjkzSGxoa3NhZUowCjhVZ2pQOVVtTVlyaFZKdTFqY0ZXVjdmei9yKzIxL2F3VG5EVjlzTVlRcXVJUllZeTdiRzByMU9iaXdkb3ZudGsKN2dGSTA2WjB2WmFjREU1Ym9xVUNBd0VBQWFPQ0FTVXdnZ0VoTUFrR0ExVWRFd1FDTUFBd0N3WURWUjBQQkFRRApBZ1VnTUIwR0ExVWREZ1FXQkJTUk9OOEdKOG8rOGpnRnRqa3R3WmRxeDZCUnlUQVRCZ05WSFNVRUREQUtCZ2dyCkJnRUZCUWNEQVRBZEJnbGdoa2dCaHZoQ0FRMEVFQllPVkdWemRDQllOVEE1SUdObGNuUXdnYk1HQTFVZEl3U0IKcXpDQnFJQVVrVGpmQmlmS1B2STRCYlk1TGNHWGFzZWdVY21oZ1l5a2dZa3dnWVl4Q3pBSkJnTlZCQVlUQWtGVgpNUXd3Q2dZRFZRUUlFd05PVTFjeER6QU5CZ05WQkFjVEJsTjVaRzVsZVRFTU1Bb0dBMVVFQ2d3RFVFbFVNUWt3CkJ3WURWUVFMREFBeEdEQVdCZ05WQkFNTUQyeGhkM0psYm1ObGNHbDBMbU52YlRFbE1DTUdDU3FHU0liM0RRRUoKQVF3V2JHRjNjbVZ1WTJVdWNHbDBRR2R0WVdsc0xtTnZiWUlCQVRBTkJna3Foa2lHOXcwQkFRc0ZBQU9CZ1FDRQpUQWVKVERTQVc2ejFVRlRWN1FyZWg0VUxGT1JhajkrZUN1RjNLV0RIYyswSVFDajlyZG5ERzRRL3dmNy9yYVEwCkpuUFFDU0NkclBMSmV5b1BIN1FhVHdvYUY3ZHpWdzRMQ3N5TkpURld4NGNNNTBWdzZSNWZET2dpQzhic2ZmUzgKQkptb3VscnJaRE5OVmpHOG1XNmNMeHJZdlZRT3JSVmVjQ0ZJZ3NzQ2JBPT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=</ds:X509Certificate></ds:X509Data></ds:KeyInfo></md:KeyDescriptor><md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://example.hello.com/access/saml/logout" ResponseLocation="https://example.hello.com/access/saml/logout"/><md:NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified</md:NameIDFormat><md:NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress</md:NameIDFormat><md:NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:persistent</md:NameIDFormat><md:SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://example.hello.com/access/saml/login"/></md:IDPSSODescriptor></md:EntityDescriptor>
@@ -3,7 +3,6 @@
3
3
  def default_response_opts
4
4
  {
5
5
  :uuid => "_28024690-000e-0130-b6d2-38f6b112be8b",
6
- :uuid2 => "_48024690-100e-1130-e6d2-28f6b112be71",
7
6
  :issue_instant => Time.now.strftime('%Y-%m-%dT%H:%M:%SZ'),
8
7
  :settings => settings
9
8
  }
@@ -14,11 +13,11 @@ def valid_response(opts = {})
14
13
 
15
14
  "<samlp:LogoutResponse
16
15
  xmlns:samlp=\"urn:oasis:names:tc:SAML:2.0:protocol\"
17
- ID=\"#{opts[:uuid]}\" Version=\"2.0\"
16
+ ID=\"#{random_id}\" Version=\"2.0\"
18
17
  IssueInstant=\"#{opts[:issue_instant]}\"
19
- Destination=\"#{opts[:settings].idp_slo_target_url}\"
20
- InResponseTo=\"#{opts[:uuid2]}\">
21
- <saml:Issuer xmlns:saml=\"urn:oasis:names:tc:SAML:2.0:assertion\">#{opts[:settings].idp_entity_id}</saml:Issuer>
18
+ Destination=\"#{opts[:settings].single_logout_service_url}\"
19
+ InResponseTo=\"#{opts[:uuid]}\">
20
+ <saml:Issuer xmlns:saml=\"urn:oasis:names:tc:SAML:2.0:assertion\">#{opts[:settings].issuer}</saml:Issuer>
22
21
  <samlp:Status xmlns:samlp=\"urn:oasis:names:tc:SAML:2.0:protocol\">
23
22
  <samlp:StatusCode xmlns:samlp=\"urn:oasis:names:tc:SAML:2.0:protocol\"
24
23
  Value=\"urn:oasis:names:tc:SAML:2.0:status:Success\">
@@ -34,9 +33,9 @@ def unsuccessful_response(opts = {})
34
33
  xmlns:samlp=\"urn:oasis:names:tc:SAML:2.0:protocol\"
35
34
  ID=\"#{random_id}\" Version=\"2.0\"
36
35
  IssueInstant=\"#{opts[:issue_instant]}\"
37
- Destination=\"#{opts[:settings].idp_slo_target_url}\"
36
+ Destination=\"#{opts[:settings].single_logout_service_url}\"
38
37
  InResponseTo=\"#{opts[:uuid]}\">
39
- <saml:Issuer xmlns:saml=\"urn:oasis:names:tc:SAML:2.0:assertion\">#{opts[:settings].idp_entity_id}</saml:Issuer>
38
+ <saml:Issuer xmlns:saml=\"urn:oasis:names:tc:SAML:2.0:assertion\">#{opts[:settings].issuer}</saml:Issuer>
40
39
  <samlp:Status xmlns:samlp=\"urn:oasis:names:tc:SAML:2.0:protocol\">
41
40
  <samlp:StatusCode xmlns:samlp=\"urn:oasis:names:tc:SAML:2.0:protocol\"
42
41
  Value=\"urn:oasis:names:tc:SAML:2.0:status:Requester\">
@@ -57,7 +56,7 @@ def settings
57
56
  {
58
57
  :assertion_consumer_service_url => "http://app.muda.no/sso/consume",
59
58
  :single_logout_service_url => "http://app.muda.no/sso/consume_logout",
60
- :sp_entity_id => "http://app.muda.no",
59
+ :issuer => "http://app.muda.no",
61
60
  :sp_name_qualifier => "http://sso.muda.no",
62
61
  :idp_sso_target_url => "http://sso.muda.no/sso",
63
62
  :idp_slo_target_url => "http://sso.muda.no/slo",
@@ -0,0 +1,29 @@
1
+ <?xml version="1.0" encoding="UTF-8"?><samlp:Response xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" Destination="https://vmwdemo.socialcast.com/saml/authenticate" ID="_f9fbcbf79715244c7ff909d8663d782e" InResponseTo="_4b4c72d0-eb5a-0131-0fec-0050568312b8" IssueInstant="2014-07-11T18:53:30.916Z" Version="2.0"><samlp:Status><samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/></samlp:Status><saml:Assertion xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" ID="_fddb13c899036a90f920ddaac50fc0d6" IssueInstant="2014-07-11T18:53:30.916Z" Version="2.0"><saml:Issuer>https://hw6dldc.vmwdemo.com/SAAS/API/1.0/GET/metadata/idp.xml</saml:Issuer><ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
2
+ <ds:SignedInfo>
3
+ <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
4
+ <ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
5
+ <ds:Reference URI="#_fddb13c899036a90f920ddaac50fc0d6">
6
+ <ds:Transforms>
7
+ <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
8
+ <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"><ec:InclusiveNamespaces xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#" PrefixList="ds saml xenc xs xsi"/></ds:Transform>
9
+ </ds:Transforms>
10
+ <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
11
+ <ds:DigestValue>HS49Xqi+JftXvslmp/boT9ixzp8=</ds:DigestValue>
12
+ </ds:Reference>
13
+ </ds:SignedInfo>
14
+ <ds:SignatureValue>
15
+ gdY9y3GNOgOqBOlEx981yILKAssUG79fXw639MJB3uJjLYokqY+Y5KFFtAU4FGvh/L6Romghx0is
16
+ rxukFkfw9coxKOhCoDZiaYPvvuC2qqhTwTAZ0Spvwuffrj3UwztSWbS6JGXtebo4ghKnae4hH5lF
17
+ tRawV9HnbLJmhL3cVPSu+7SF3iWov0PZyZczH1P6sZrYeX5X32h3RhXXxMi3kgHGWxaVTQmgTEgu
18
+ xN3GD7lnsf+WOAvdPAPgFrJjEGJZDd/MClS/x5ZwLnMZ82r7XHoFhiC47eq3Te+JE9qZvSbIs/om
19
+ dpuFSaFKxxdM8C+vHTRUDDaGckqckPc5Y7wlgA==
20
+ </ds:SignatureValue>
21
+ </ds:Signature><saml:Subject><saml:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress" NameQualifier="https://hw6dldc.vmwdemo.com/SAAS/API/1.0/GET/metadata/idp.xml">akjoshi87+du@gmail.com</saml:NameID><saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer"><saml:SubjectConfirmationData InResponseTo="_4b4c72d0-eb5a-0131-0fec-0050568312b8" NotOnOrAfter="2014-07-11T18:56:50.916Z" Recipient="https://vmwdemo.socialcast.com/saml/authenticate"/></saml:SubjectConfirmation></saml:Subject><saml:Conditions NotBefore="2014-07-11T18:53:15.916Z" NotOnOrAfter="2014-07-11T18:56:50.916Z"><saml:AudienceRestriction><saml:Audience>vmwdemo.socialcast.com</saml:Audience></saml:AudienceRestriction></saml:Conditions><saml:AuthnStatement AuthnInstant="2014-07-11T18:53:30.916Z" SessionIndex="_876ca8142c7ba8126af3c90d952af251"><saml:AuthnContext><saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport</saml:AuthnContextClassRef></saml:AuthnContext></saml:AuthnStatement><saml:AttributeStatement><saml:Attribute Name="first_name" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic"><saml:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">Demo</saml:AttributeValue></saml:Attribute><saml:Attribute Name="email" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic"><saml:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">akjoshi87+du@gmail.com</saml:AttributeValue></saml:Attribute><saml:Attribute Name="last_name" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic"><saml:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">User</saml:AttributeValue></saml:Attribute><saml:EncryptedAttribute><xenc:EncryptedData xmlns:xenc="http://www.w3.org/2001/04/xmlenc#" Id="_2a1c0500932ae79e9f5ede82dccb57c6" Type="http://www.w3.org/2001/04/xmlenc#Element"><xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc"/><ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#"><xenc:EncryptedKey Id="_ff2d29836cd453cdfca94b69b630cf40"><xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5"/><xenc:CipherData><xenc:CipherValue>IdFfvxdt+YBaLSkWfcxuGqiPDyiQtpklGkJZFW+UoZXMhopZXmW/ekfEAf1VpzIlDlo3xwY2y8Rw
22
+ zZwASwjiuHoQSMZQzZ6Ws184f1pWh9un23wgHzYc/jwXF0pXfcVL944SSxxNO4zO+DMJz6Px9rvk
23
+ Rpac86uujfBuqXlo684=</xenc:CipherValue></xenc:CipherData></xenc:EncryptedKey></ds:KeyInfo><xenc:CipherData><xenc:CipherValue>/+Noi1tNN1HcY+bW/iyBkwOYR4X32pTPzq7EjQO/HB3L0B2RtpsYkvC9750eb6KydbsBSGCyNt3k
24
+ grjcI1nUgvvY488NhIo9+PWv3MhAqnljKhDzl6AcfE00Lq3HA1FcTCwrE0VLjUV4NtztK2JVCZwu
25
+ ToViUJMlu1SGL8U7uRfsRpbrXoIEv1AwFHjz+XZgwD3nxl79iAcnm3FFX7nIkjUQIPPBWC/U4XJN
26
+ u+u5svSoUpIOFqdeNcDQUq5+P5lXT46O5LcULQrEY8xHNGToxOwINMOrU+rCgwyAVbP/SaY9ywYe
27
+ bxpESNkHmkjLAI7GBvLRRkTEE88Q6/uV9D1A5X3rT4BMQJ0N7BfgnOJ7IMga2Q9wU9oPuoCsqL9I
28
+ bP9IY1vCLcAAEsMR0EgZaInLCiLoXdmDHllSo2fyKQqBGxE+KpZhvVdCOVzLN3+TrW3k/xl/kx6w
29
+ AIPFlXd6TRVzmg==</xenc:CipherValue></xenc:CipherData></xenc:EncryptedData></saml:EncryptedAttribute></saml:AttributeStatement></saml:Assertion></samlp:Response>
@@ -64,4 +64,4 @@
64
64
  </saml:Attribute>
65
65
  </saml:AttributeStatement>
66
66
  </saml:Assertion>
67
- </samlp:Response>
67
+ </samlp:Response>
@@ -0,0 +1,4 @@
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:LogoutRequest>
@@ -1,18 +1,23 @@
1
1
  require File.expand_path(File.join(File.dirname(__FILE__), "test_helper"))
2
2
 
3
- class SettingsTest < Minitest::Test
3
+ class SettingsTest < Test::Unit::TestCase
4
4
 
5
- describe "Settings" do
6
- before do
5
+ context "Settings" do
6
+ setup do
7
7
  @settings = OneLogin::RubySaml::Settings.new
8
8
  end
9
- it "should provide getters and settings" do
9
+ should "should provide getters and settings" do
10
10
  accessors = [
11
- :assertion_consumer_service_url, :issuer, :sp_entity_id, :sp_name_qualifier,
12
- :idp_sso_target_url, :idp_cert_fingerprint, :name_identifier_format,
13
- :idp_slo_target_url, :name_identifier_value, :name_identifier_value_requested,
14
- :sessionindex, :assertion_consumer_logout_service_url,
15
- :passive, :force_authn, :protocol_binding, :single_logout_service_url, :single_logout_service_binding
11
+ :idp_entity_id, :idp_sso_target_url, :idp_slo_target_url, :idp_cert, :idp_cert_fingerprint,
12
+ :issuer, :assertion_consumer_service_url, :assertion_consumer_service_binding,
13
+ :single_logout_service_url, :single_logout_service_binding,
14
+ :sp_name_qualifier, :name_identifier_format, :name_identifier_value,
15
+ :sessionindex, :attributes_index, :passive, :force_authn,
16
+ :compress_request, :double_quote_xml_attribute_values, :protocol_binding,
17
+ :security, :certificate, :private_key,
18
+ :authn_context, :authn_context_comparison, :authn_context_decl_ref,
19
+ :assertion_consumer_logout_service_url,
20
+ :assertion_consumer_logout_service_binding
16
21
  ]
17
22
 
18
23
  accessors.each do |accessor|
@@ -20,9 +25,10 @@ class SettingsTest < Minitest::Test
20
25
  @settings.send("#{accessor}=".to_sym, value)
21
26
  assert_equal value, @settings.send(accessor)
22
27
  end
28
+
23
29
  end
24
30
 
25
- it "create settings from hash" do
31
+ should "create settings from hash" do
26
32
 
27
33
  config = {
28
34
  :assertion_consumer_service_url => "http://app.muda.no/sso",
@@ -32,6 +38,7 @@ class SettingsTest < Minitest::Test
32
38
  :idp_slo_target_url => "http://sso.muda.no/slo",
33
39
  :idp_cert_fingerprint => "00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00",
34
40
  :name_identifier_format => "urn:oasis:names:tc:SAML:2.0:nameid-format:transient",
41
+ :attributes_index => 30,
35
42
  :passive => true,
36
43
  :protocol_binding => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST'
37
44
  }
@@ -42,110 +49,16 @@ class SettingsTest < Minitest::Test
42
49
  end
43
50
  end
44
51
 
45
- describe "#get_idp_cert" do
46
- it "returns nil when the cert is an empty string" do
47
- @settings.idp_cert = ""
48
- assert_nil @settings.get_idp_cert
49
- end
50
-
51
- it "returns nil when the cert is nil" do
52
- @settings.idp_cert = nil
53
- assert_nil @settings.get_idp_cert
54
- end
55
-
56
- it "returns the certificate when it is valid" do
57
- @settings.idp_cert = ruby_saml_cert_text
58
- assert @settings.get_idp_cert.kind_of? OpenSSL::X509::Certificate
59
- end
60
-
61
- it "raises when the certificate is not valid" do
62
- # formatted but invalid cert
63
- @settings.idp_cert = read_certificate("formatted_certificate")
64
- assert_raises(OpenSSL::X509::CertificateError) {
65
- @settings.get_idp_cert
66
- }
67
- end
68
- end
69
-
70
- describe "#get_sp_cert" do
71
- it "returns nil when the cert is an empty string" do
72
- @settings.certificate = ""
73
- assert_nil @settings.get_sp_cert
74
- end
75
-
76
- it "returns nil when the cert is nil" do
77
- @settings.certificate = nil
78
- assert_nil @settings.get_sp_cert
79
- end
80
-
81
- it "returns the certificate when it is valid" do
82
- @settings.certificate = ruby_saml_cert_text
83
- assert @settings.get_sp_cert.kind_of? OpenSSL::X509::Certificate
84
- end
85
-
86
- it "raises when the certificate is not valid" do
87
- # formatted but invalid cert
88
- @settings.certificate = read_certificate("formatted_certificate")
89
- assert_raises(OpenSSL::X509::CertificateError) {
90
- @settings.get_sp_cert
91
- }
92
- end
93
- end
94
-
95
- describe "#get_sp_key" do
96
- it "returns nil when the private key is an empty string" do
97
- @settings.private_key = ""
98
- assert_nil @settings.get_sp_key
99
- end
100
-
101
- it "returns nil when the private key is nil" do
102
- @settings.private_key = nil
103
- assert_nil @settings.get_sp_key
104
- end
105
-
106
- it "returns the private key when it is valid" do
107
- @settings.private_key = ruby_saml_key_text
108
- assert @settings.get_sp_key.kind_of? OpenSSL::PKey::RSA
109
- end
110
-
111
- it "raises when the private key is not valid" do
112
- # formatted but invalid rsa private key
113
- @settings.private_key = read_certificate("formatted_rsa_private_key")
114
- assert_raises(OpenSSL::PKey::RSAError) {
115
- @settings.get_sp_key
116
- }
117
- end
118
-
119
- end
120
-
121
- describe "#get_fingerprint" do
122
- it "get the fingerprint value when cert and fingerprint in settings are nil" do
123
- @settings.idp_cert_fingerprint = nil
124
- @settings.idp_cert = nil
125
- fingerprint = @settings.get_fingerprint
126
- assert_nil fingerprint
127
- end
128
-
129
- it "get the fingerprint value when there is a cert at the settings" do
130
- @settings.idp_cert_fingerprint = nil
131
- @settings.idp_cert = ruby_saml_cert_text
132
- fingerprint = @settings.get_fingerprint
133
- assert fingerprint.downcase == ruby_saml_cert_fingerprint.downcase
134
- end
135
-
136
- it "get the fingerprint value when there is a fingerprint at the settings" do
137
- @settings.idp_cert_fingerprint = ruby_saml_cert_fingerprint
138
- @settings.idp_cert = nil
139
- fingerprint = @settings.get_fingerprint
140
- assert fingerprint.downcase == ruby_saml_cert_fingerprint.downcase
52
+ should "configure attribute service attributes correctly" do
53
+ @settings = OneLogin::RubySaml::Settings.new
54
+ @settings.attribute_consuming_service.configure do
55
+ service_name "Test Service"
56
+ add_attribute :name => "Name", :name_format => "Name Format", :friendly_name => "Friendly Name"
141
57
  end
142
58
 
143
- it "get the fingerprint value when there are cert and fingerprint at the settings" do
144
- @settings.idp_cert_fingerprint = ruby_saml_cert_fingerprint
145
- @settings.idp_cert = ruby_saml_cert_text
146
- fingerprint = @settings.get_fingerprint
147
- assert fingerprint.downcase == ruby_saml_cert_fingerprint.downcase
148
- end
59
+ assert_equal @settings.attribute_consuming_service.configured?, true
60
+ assert_equal @settings.attribute_consuming_service.name, "Test Service"
61
+ assert_equal @settings.attribute_consuming_service.attributes, [{:name => "Name", :name_format => "Name Format", :friendly_name => "Friendly Name" }]
149
62
  end
150
63
 
151
64
  end
@@ -1,71 +1,61 @@
1
1
  require File.expand_path(File.join(File.dirname(__FILE__), "test_helper"))
2
- require File.expand_path(File.join(File.dirname(__FILE__), "requests/logoutrequest_fixtures"))
2
+ require 'responses/logoutresponse_fixtures'
3
3
 
4
- class SloLogoutrequestTest < Minitest::Test
4
+ class RubySamlTest < Test::Unit::TestCase
5
5
 
6
- describe "SloLogoutrequest" do
6
+ context "SloLogoutrequest" do
7
+ should "raise an exception when response is initialized with nil" do
8
+ assert_raises(ArgumentError) { OneLogin::RubySaml::SloLogoutrequest.new(nil) }
9
+ end
7
10
 
8
- describe "#new" do
9
- it "raise an exception when request is initialized with nil" do
10
- assert_raises(ArgumentError) { OneLogin::RubySaml::SloLogoutrequest.new(nil) }
11
- end
12
- it "default to empty settings" do
13
- logoutrequest = OneLogin::RubySaml::SloLogoutrequest.new(valid_request)
14
- assert logoutrequest.settings.nil?
15
- end
16
- it "accept constructor-injected settings" do
17
- logoutrequest = OneLogin::RubySaml::SloLogoutrequest.new(valid_request, settings)
18
- assert !logoutrequest.settings.nil?
19
- end
20
- it "accept constructor-injected options" do
21
- logoutrequest = OneLogin::RubySaml::SloLogoutrequest.new(valid_request, nil, { :foo => :bar} )
22
- assert !logoutrequest.options.empty?
11
+ context "#is_valid?" do
12
+ should "return false when response is initialized with blank data" do
13
+ request = OneLogin::RubySaml::SloLogoutrequest.new('')
14
+ assert !request.is_valid?
23
15
  end
24
- it "support base64 encoded requests" do
25
- expected_request = valid_request
26
- logoutrequest = OneLogin::RubySaml::SloLogoutrequest.new(Base64.encode64(expected_request), settings)
27
16
 
28
- assert_equal expected_request, logoutrequest.request
17
+ should "return true when the request is initialized with valid data" do
18
+ request = OneLogin::RubySaml::SloLogoutrequest.new(logout_request_document)
19
+ assert request.is_valid?
20
+ assert_equal 'someone@example.org', request.name_id
29
21
  end
30
- end
31
-
32
- describe "#validate" do
33
- it "validate the request" do
34
- in_relation_to_request_id = random_id
35
- settings.idp_entity_id = "https://example.com/idp"
36
- logoutrequest = OneLogin::RubySaml::SloLogoutrequest.new(valid_request({:uuid => in_relation_to_request_id}), settings)
37
-
38
- assert logoutrequest.validate
39
22
 
40
- assert_equal settings.idp_entity_id, logoutrequest.issuer
41
-
42
- assert_equal "testuser@example.com", logoutrequest.nameid
23
+ should "should be idempotent when the response is initialized with invalid data" do
24
+ request = OneLogin::RubySaml::SloLogoutrequest.new(invalid_xml_response)
25
+ assert !request.is_valid?
26
+ assert !request.is_valid?
27
+ end
43
28
 
44
- assert_equal "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress", logoutrequest.nameid_format
29
+ should "should be idempotent when the response is initialized with valid data" do
30
+ request = OneLogin::RubySaml::SloLogoutrequest.new(logout_request_document)
31
+ assert request.is_valid?
32
+ assert request.is_valid?
45
33
  end
46
34
 
35
+ should "raise error for invalid xml" do
36
+ logout_request = OneLogin::RubySaml::SloLogoutrequest.new(invalid_xml_response)
37
+ assert_raises(OneLogin::RubySaml::ValidationError) { logout_request.validate! }
38
+ end
47
39
  end
48
40
 
49
- describe "#validate!" do
50
- it "validates good requests" do
51
- in_relation_to_request_id = random_id
52
-
53
- logoutrequest = OneLogin::RubySaml::SloLogoutrequest.new(valid_request({:uuid => in_relation_to_request_id}), settings)
54
-
55
- logoutrequest.validate!
41
+ context "#name_id" do
42
+ should "extract the value of the name id element" do
43
+ request = OneLogin::RubySaml::SloLogoutrequest.new(logout_request_document)
44
+ assert_equal "someone@example.org", request.name_id
56
45
  end
46
+ end
57
47
 
58
- it "raise error for invalid xml" do
59
- logoutrequest = OneLogin::RubySaml::SloLogoutrequest.new(invalid_xml_request, settings)
60
-
61
- assert_raises(OneLogin::RubySaml::ValidationError) { logoutrequest.validate! }
48
+ context "#issuer" do
49
+ should "return the issuer inside the request" do
50
+ request = OneLogin::RubySaml::SloLogoutrequest.new(logout_request_document)
51
+ assert_equal "https://app.onelogin.com/saml/metadata/SOMEACCOUNT", request.issuer
62
52
  end
63
53
  end
64
54
 
65
- describe "#request_id" do
66
- it "extract the value of the Response ID" do
67
- logoutrequest = OneLogin::RubySaml::SloLogoutrequest.new(valid_request, settings)
68
- assert_equal "_28024690-000e-0130-b6d2-38f6b112be8b", logoutrequest.request_id
55
+ context "#id" do
56
+ should "extract the value of the ID attribute" do
57
+ request = OneLogin::RubySaml::SloLogoutrequest.new(logout_request_document)
58
+ assert_equal "_c0348950-935b-0131-1060-782bcb56fcaa", request.id
69
59
  end
70
60
  end
71
61