ruby-saml 0.4.5 → 0.4.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


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

data/Rakefile CHANGED
@@ -13,6 +13,7 @@ begin
13
13
  gem.add_dependency("canonix","~> 0.1")
14
14
  gem.add_dependency("uuid","~> 2.3")
15
15
  gem.add_development_dependency "shoulda"
16
+ gem.add_development_dependency "ruby-debug"
16
17
  gem.add_development_dependency "mocha"
17
18
  #gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
18
19
  end
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.4.5
1
+ 0.4.6
@@ -1,4 +1,5 @@
1
1
  require 'onelogin/saml/authrequest'
2
2
  require 'onelogin/saml/response'
3
3
  require 'onelogin/saml/settings'
4
+ require 'onelogin/saml/validation_error'
4
5
 
@@ -2,48 +2,38 @@ require "xml_security"
2
2
  require "time"
3
3
 
4
4
  module Onelogin::Saml
5
+
5
6
  class Response
6
7
  ASSERTION = "urn:oasis:names:tc:SAML:2.0:assertion"
7
8
  PROTOCOL = "urn:oasis:names:tc:SAML:2.0:protocol"
8
9
  DSIG = "http://www.w3.org/2000/09/xmldsig#"
9
10
 
10
- attr_accessor :response, :document, :logger, :settings, :original
11
+ attr_accessor :options, :response, :document, :settings
11
12
 
12
- def initialize(response)
13
+ def initialize(response, options = {})
13
14
  raise ArgumentError.new("Response cannot be nil") if response.nil?
15
+ self.options = options
14
16
  self.response = response
15
17
  self.document = XMLSecurity::SignedDocument.new(Base64.decode64(response))
16
18
  end
17
19
 
18
20
  def is_valid?
19
- return false if response.empty?
20
- return false if settings.nil?
21
- return false if settings.idp_cert_fingerprint.nil?
22
- return false if !check_conditions
21
+ validate(soft = true)
22
+ end
23
23
 
24
- document.validate(settings.idp_cert_fingerprint, logger)
24
+ def validate!
25
+ validate(soft = false)
25
26
  end
26
27
 
27
28
  # The value of the user identifier as designated by the initialization request response
28
29
  def name_id
29
30
  @name_id ||= begin
30
31
  node = REXML::XPath.first(document, "/p:Response/a:Assertion[@ID='#{document.signed_element_id[1,document.signed_element_id.size]}']/a:Subject/a:NameID", { "p" => PROTOCOL, "a" => ASSERTION })
32
+ node ||= REXML::XPath.first(document, "/p:Response[@ID='#{document.signed_element_id[1,document.signed_element_id.size]}']/a:Assertion/a:Subject/a:NameID", { "p" => PROTOCOL, "a" => ASSERTION })
31
33
  node.nil? ? nil : node.text
32
34
  end
33
35
  end
34
36
 
35
- def check_conditions
36
- return true if conditions.nil?
37
-
38
- not_before = parse_time(conditions, "NotBefore")
39
- return false if not_before && Time.now.utc < not_before
40
-
41
- not_on_or_after = parse_time(conditions, "NotOnOrAfter")
42
- return false if not_on_or_after && Time.now.utc >= not_on_or_after
43
-
44
- true
45
- end
46
-
47
37
  # A hash of alle the attributes with the response. Assuming there is only one value for each key
48
38
  def attributes
49
39
  @attr_statements ||= begin
@@ -84,6 +74,51 @@ module Onelogin::Saml
84
74
 
85
75
  private
86
76
 
77
+ def validation_error(message)
78
+ raise ValidationError.new(message)
79
+ end
80
+
81
+ def validate(soft = true)
82
+ validate_response_state(soft) &&
83
+ validate_conditions(soft) &&
84
+ document.validate(settings.idp_cert_fingerprint, soft)
85
+ end
86
+
87
+ def validate_response_state(soft = true)
88
+ if response.empty?
89
+ return soft ? false : validation_error("Blank response")
90
+ end
91
+
92
+ if settings.nil?
93
+ return soft ? false : validation_error("No settings on response")
94
+ end
95
+
96
+ if settings.idp_cert_fingerprint.nil?
97
+ return soft ? false : validation_error("No fingerprint on settings")
98
+ end
99
+
100
+ true
101
+ end
102
+
103
+ def validate_conditions(soft = true)
104
+ return true if conditions.nil?
105
+ return true if options[:skip_conditions]
106
+
107
+ if not_before = parse_time(conditions, "NotBefore")
108
+ if Time.now.utc < not_before
109
+ return soft ? false : validation_error("Current time is earlier than NotBefore condition")
110
+ end
111
+ end
112
+
113
+ if not_on_or_after = parse_time(conditions, "NotOnOrAfter")
114
+ if Time.now.utc >= not_on_or_after
115
+ return soft ? false : validation_error("Current time is on or after NotOnOrAfter condition")
116
+ end
117
+ end
118
+
119
+ true
120
+ end
121
+
87
122
  def parse_time(node, attribute)
88
123
  if node && node.attributes[attribute]
89
124
  Time.parse(node.attributes[attribute])
@@ -0,0 +1,7 @@
1
+ module Onelogin
2
+ module Saml
3
+ class ValidationError < Exception
4
+ end
5
+ end
6
+ end
7
+
@@ -28,11 +28,12 @@ require "rexml/xpath"
28
28
  require "openssl"
29
29
  require "xmlcanonicalizer"
30
30
  require "digest/sha1"
31
+ require "onelogin/saml/validation_error"
31
32
 
32
33
  module XMLSecurity
33
34
 
34
35
  class SignedDocument < REXML::Document
35
- DSIG = "http://www.w3.org/2000/09/xmldsig#"
36
+ DSIG = "http://www.w3.org/2000/09/xmldsig#"
36
37
 
37
38
  attr_accessor :signed_element_id
38
39
 
@@ -41,7 +42,7 @@ module XMLSecurity
41
42
  extract_signed_element_id
42
43
  end
43
44
 
44
- def validate (idp_cert_fingerprint, logger = nil)
45
+ def validate(idp_cert_fingerprint, soft = true)
45
46
  # get cert from response
46
47
  base64_cert = self.elements["//ds:X509Certificate"].text
47
48
  cert_text = Base64.decode64(base64_cert)
@@ -49,33 +50,44 @@ module XMLSecurity
49
50
 
50
51
  # check cert matches registered idp cert
51
52
  fingerprint = Digest::SHA1.hexdigest(cert.to_der)
52
- valid_flag = fingerprint == idp_cert_fingerprint.gsub(/[^a-zA-Z0-9]/,"").downcase
53
53
 
54
- return valid_flag if !valid_flag
54
+ if fingerprint != idp_cert_fingerprint.gsub(/[^a-zA-Z0-9]/,"").downcase
55
+ return soft ? false : (raise Onelogin::Saml::ValidationError.new("Fingerprint mismatch"))
56
+ end
55
57
 
56
- validate_doc(base64_cert, logger)
58
+ validate_doc(base64_cert, soft)
57
59
  end
58
60
 
59
- def validate_doc(base64_cert, logger)
61
+ def validate_doc(base64_cert, soft = true)
60
62
  # validate references
63
+
64
+ # check for inclusive namespaces
65
+
66
+ inclusive_namespaces = []
67
+ inclusive_namespace_element = REXML::XPath.first(self, "//ec:InclusiveNamespaces")
68
+
69
+ if inclusive_namespace_element
70
+ prefix_list = inclusive_namespace_element.attributes.get_attribute('PrefixList').value
71
+ inclusive_namespaces = prefix_list.split(" ")
72
+ end
61
73
 
62
74
  # remove signature node
63
75
  sig_element = REXML::XPath.first(self, "//ds:Signature", {"ds"=>"http://www.w3.org/2000/09/xmldsig#"})
64
76
  sig_element.remove
65
77
 
66
- #check digests
67
- REXML::XPath.each(sig_element, "//ds:Reference", {"ds"=>"http://www.w3.org/2000/09/xmldsig#"}) do | ref |
68
-
69
- uri = ref.attributes.get_attribute("URI").value
70
- hashed_element = REXML::XPath.first(self, "//[@ID='#{uri[1,uri.size]}']")
71
- canoner = XML::Util::XmlCanonicalizer.new(false, true)
72
- canon_hashed_element = canoner.canonicalize(hashed_element)
73
- hash = Base64.encode64(Digest::SHA1.digest(canon_hashed_element)).chomp
74
- digest_value = REXML::XPath.first(ref, "//ds:DigestValue", {"ds"=>"http://www.w3.org/2000/09/xmldsig#"}).text
75
-
76
- valid_flag = hash == digest_value
77
-
78
- return valid_flag if !valid_flag
78
+ # check digests
79
+ REXML::XPath.each(sig_element, "//ds:Reference", {"ds"=>"http://www.w3.org/2000/09/xmldsig#"}) do |ref|
80
+ uri = ref.attributes.get_attribute("URI").value
81
+ hashed_element = REXML::XPath.first(self, "//[@ID='#{uri[1,uri.size]}']")
82
+ canoner = XML::Util::XmlCanonicalizer.new(false, true)
83
+ canoner.inclusive_namespaces = inclusive_namespaces if canoner.respond_to?(:inclusive_namespaces) && !inclusive_namespaces.empty?
84
+ canon_hashed_element = canoner.canonicalize(hashed_element)
85
+ hash = Base64.encode64(Digest::SHA1.digest(canon_hashed_element)).chomp
86
+ digest_value = REXML::XPath.first(ref, "//ds:DigestValue", {"ds"=>"http://www.w3.org/2000/09/xmldsig#"}).text
87
+
88
+ if hash != digest_value
89
+ return soft ? false : (raise Onelogin::Saml::ValidationError.new("Digest mismatch"))
90
+ end
79
91
  end
80
92
 
81
93
  # verify signature
@@ -90,9 +102,11 @@ module XMLSecurity
90
102
  cert_text = Base64.decode64(base64_cert)
91
103
  cert = OpenSSL::X509::Certificate.new(cert_text)
92
104
 
93
- valid_flag = cert.public_key.verify(OpenSSL::Digest::SHA1.new, signature, canon_string)
105
+ if !cert.public_key.verify(OpenSSL::Digest::SHA1.new, signature, canon_string)
106
+ return soft ? false : (raise ValidationError.new("Key validation error"))
107
+ end
94
108
 
95
- return valid_flag
109
+ return true
96
110
  end
97
111
 
98
112
  private
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{ruby-saml}
8
- s.version = "0.4.5"
8
+ s.version = "0.4.6"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["OneLogin LLC"]
12
- s.date = %q{2011-06-17}
12
+ s.date = %q{2011-06-28}
13
13
  s.description = %q{SAML toolkit for Ruby on Rails}
14
14
  s.email = %q{support@onelogin.com}
15
15
  s.extra_rdoc_files = [
@@ -27,16 +27,22 @@ Gem::Specification.new do |s|
27
27
  "lib/onelogin/saml/authrequest.rb",
28
28
  "lib/onelogin/saml/response.rb",
29
29
  "lib/onelogin/saml/settings.rb",
30
+ "lib/onelogin/saml/validation_error.rb",
30
31
  "lib/ruby-saml.rb",
31
32
  "lib/xml_security.rb",
32
33
  "ruby-saml.gemspec",
34
+ "test/request_test.rb",
35
+ "test/response_test.rb",
36
+ "test/responses/adfs_response.xml.base64",
33
37
  "test/responses/certificate1",
38
+ "test/responses/open_saml_response.xml",
34
39
  "test/responses/response1.xml.base64",
35
40
  "test/responses/response2.xml.base64",
36
41
  "test/responses/response3.xml.base64",
37
42
  "test/responses/response4.xml.base64",
38
43
  "test/responses/response5.xml.base64",
39
- "test/ruby-saml_test.rb",
44
+ "test/responses/simple_saml_php.xml",
45
+ "test/settings_test.rb",
40
46
  "test/test_helper.rb",
41
47
  "test/xml_security_test.rb"
42
48
  ]
@@ -46,7 +52,9 @@ Gem::Specification.new do |s|
46
52
  s.rubygems_version = %q{1.3.7}
47
53
  s.summary = %q{SAML Ruby Tookit}
48
54
  s.test_files = [
49
- "test/ruby-saml_test.rb",
55
+ "test/request_test.rb",
56
+ "test/response_test.rb",
57
+ "test/settings_test.rb",
50
58
  "test/test_helper.rb",
51
59
  "test/xml_security_test.rb"
52
60
  ]
@@ -59,17 +67,20 @@ Gem::Specification.new do |s|
59
67
  s.add_runtime_dependency(%q<canonix>, ["~> 0.1"])
60
68
  s.add_runtime_dependency(%q<uuid>, ["~> 2.3"])
61
69
  s.add_development_dependency(%q<shoulda>, [">= 0"])
70
+ s.add_development_dependency(%q<ruby-debug>, [">= 0"])
62
71
  s.add_development_dependency(%q<mocha>, [">= 0"])
63
72
  else
64
73
  s.add_dependency(%q<canonix>, ["~> 0.1"])
65
74
  s.add_dependency(%q<uuid>, ["~> 2.3"])
66
75
  s.add_dependency(%q<shoulda>, [">= 0"])
76
+ s.add_dependency(%q<ruby-debug>, [">= 0"])
67
77
  s.add_dependency(%q<mocha>, [">= 0"])
68
78
  end
69
79
  else
70
80
  s.add_dependency(%q<canonix>, ["~> 0.1"])
71
81
  s.add_dependency(%q<uuid>, ["~> 2.3"])
72
82
  s.add_dependency(%q<shoulda>, [">= 0"])
83
+ s.add_dependency(%q<ruby-debug>, [">= 0"])
73
84
  s.add_dependency(%q<mocha>, [">= 0"])
74
85
  end
75
86
  end
@@ -0,0 +1,33 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), "test_helper"))
2
+
3
+ class RequestTest < Test::Unit::TestCase
4
+
5
+ context "Authrequest" do
6
+ should "create the deflated SAMLRequest URL parameter" do
7
+ settings = Onelogin::Saml::Settings.new
8
+ settings.idp_sso_target_url = "http://stuff.com"
9
+ auth_url = Onelogin::Saml::Authrequest.new.create(settings)
10
+ assert auth_url =~ /^http:\/\/stuff\.com\?SAMLRequest=/
11
+ payload = CGI.unescape(auth_url.split("=").last)
12
+ decoded = Base64.decode64(payload)
13
+
14
+ zstream = Zlib::Inflate.new(-Zlib::MAX_WBITS)
15
+ inflated = zstream.inflate(decoded)
16
+ zstream.finish
17
+ zstream.close
18
+
19
+ assert_match /^<samlp:AuthnRequest/, inflated
20
+ end
21
+
22
+ should "accept extra parameters" do
23
+ settings = Onelogin::Saml::Settings.new
24
+ settings.idp_sso_target_url = "http://stuff.com"
25
+
26
+ auth_url = Onelogin::Saml::Authrequest.new.create(settings, { :hello => "there" })
27
+ assert auth_url =~ /&hello=there$/
28
+
29
+ auth_url = Onelogin::Saml::Authrequest.new.create(settings, { :hello => nil })
30
+ assert auth_url =~ /&hello=$/
31
+ end
32
+ end
33
+ end
@@ -2,30 +2,7 @@ require File.expand_path(File.join(File.dirname(__FILE__), "test_helper"))
2
2
 
3
3
  class RubySamlTest < Test::Unit::TestCase
4
4
 
5
- context "Settings" do
6
- setup do
7
- @settings = Onelogin::Saml::Settings.new
8
- end
9
- should "should provide getters and settings" do
10
- accessors = [
11
- :assertion_consumer_service_url, :issuer, :sp_name_qualifier, :sp_name_qualifier,
12
- :idp_sso_target_url, :idp_cert_fingerprint, :name_identifier_format
13
- ]
14
-
15
- accessors.each do |accessor|
16
- value = Kernel.rand
17
- @settings.send("#{accessor}=".to_sym, value)
18
- assert_equal value, @settings.send(accessor)
19
- end
20
- end
21
- end
22
-
23
5
  context "Response" do
24
- should "provide setter for a logger" do
25
- response = Onelogin::Saml::Response.new('')
26
- assert response.logger = 'hello'
27
- end
28
-
29
6
  should "raise an exception when response is initialized with nil" do
30
7
  assert_raises(ArgumentError) { Onelogin::Saml::Response.new(nil) }
31
8
  end
@@ -39,6 +16,15 @@ class RubySamlTest < Test::Unit::TestCase
39
16
  assert !response.name_id.nil?
40
17
  end
41
18
 
19
+ context "#validate!" do
20
+ should "raise when encountering a condition that prevents the document from being valid" do
21
+ response = Onelogin::Saml::Response.new(response_document)
22
+ assert_raise(Onelogin::Saml::ValidationError) do
23
+ response.validate!
24
+ end
25
+ end
26
+ end
27
+
42
28
  context "#is_valid?" do
43
29
  should "return false when response is initialized with blank data" do
44
30
  response = Onelogin::Saml::Response.new('')
@@ -52,7 +38,7 @@ class RubySamlTest < Test::Unit::TestCase
52
38
 
53
39
  should "return true when the response is initialized with valid data" do
54
40
  response = Onelogin::Saml::Response.new(response_document_4)
55
- response.expects(:check_conditions).returns(true)
41
+ response.stubs(:conditions).returns(nil)
56
42
  assert !response.is_valid?
57
43
  settings = Onelogin::Saml::Settings.new
58
44
  assert !response.is_valid?
@@ -64,13 +50,22 @@ class RubySamlTest < Test::Unit::TestCase
64
50
 
65
51
  should "not allow signature wrapping attack" do
66
52
  response = Onelogin::Saml::Response.new(response_document_4)
67
- response.expects(:check_conditions).returns(true)
53
+ response.stubs(:conditions).returns(nil)
68
54
  settings = Onelogin::Saml::Settings.new
69
55
  settings.idp_cert_fingerprint = signature_fingerprint_1
70
56
  response.settings = settings
71
57
  assert response.is_valid?
72
58
  assert response.name_id == "test@onelogin.com"
73
59
  end
60
+
61
+ should_eventually "validate ADFS assertions" do
62
+ response = Onelogin::Saml::Response.new(fixture(:adfs_response))
63
+ response.stubs(:conditions).returns(nil)
64
+ settings = Onelogin::Saml::Settings.new
65
+ settings.idp_cert_fingerprint = "17:54:07:27:53:55:D1:93:67:A4:95:0A:6A:E4:D6:1E:FA:4A:94:1D"
66
+ response.settings = settings
67
+ assert response.validate!
68
+ end
74
69
  end
75
70
 
76
71
  context "#name_id" do
@@ -81,18 +76,28 @@ class RubySamlTest < Test::Unit::TestCase
81
76
  response = Onelogin::Saml::Response.new(response_document_3)
82
77
  assert_equal "someone@example.com", response.name_id
83
78
  end
79
+
80
+ should_eventually "be extractable from an OpenSAML response" do
81
+ response = Onelogin::Saml::Response.new(fixture(:open_saml))
82
+ assert_equal "someone@example.org", response.name_id
83
+ end
84
+
85
+ should_eventually "be extractable from a Simple SAML PHP response" do
86
+ response = Onelogin::Saml::Response.new(fixture(:simple_saml_php))
87
+ assert_equal "someone@example.com", response.name_id
88
+ end
84
89
  end
85
90
 
86
91
  context "#check_conditions" do
87
92
  should "check time conditions" do
88
93
  response = Onelogin::Saml::Response.new(response_document)
89
- assert !response.check_conditions
94
+ assert !response.send(:validate_conditions, true)
90
95
  response = Onelogin::Saml::Response.new(response_document_6)
91
- assert response.check_conditions
96
+ assert response.send(:validate_conditions, true)
92
97
  time = Time.parse("2011-06-14T18:25:01.516Z")
93
98
  Time.stubs(:now).returns(time)
94
99
  response = Onelogin::Saml::Response.new(response_document_5)
95
- assert response.check_conditions
100
+ assert response.send(:validate_conditions, true)
96
101
  end
97
102
  end
98
103
 
@@ -133,34 +138,7 @@ class RubySamlTest < Test::Unit::TestCase
133
138
  assert response.session_expires_at.nil?
134
139
  end
135
140
  end
136
- end
137
-
138
- context "Authrequest" do
139
- should "create the deflated SAMLRequest URL parameter" do
140
- settings = Onelogin::Saml::Settings.new
141
- settings.idp_sso_target_url = "http://stuff.com"
142
- auth_url = Onelogin::Saml::Authrequest.new.create(settings)
143
- assert auth_url =~ /^http:\/\/stuff\.com\?SAMLRequest=/
144
- payload = CGI.unescape(auth_url.split("=").last)
145
- decoded = Base64.decode64(payload)
146
-
147
- zstream = Zlib::Inflate.new(-Zlib::MAX_WBITS)
148
- inflated = zstream.inflate(decoded)
149
- zstream.finish
150
- zstream.close
151
-
152
- assert_match /^<samlp:AuthnRequest/, inflated
153
- end
154
-
155
- should "accept extra parameters" do
156
- settings = Onelogin::Saml::Settings.new
157
- settings.idp_sso_target_url = "http://stuff.com"
158
141
 
159
- auth_url = Onelogin::Saml::Authrequest.new.create(settings, { :hello => "there" })
160
- assert auth_url =~ /&hello=there$/
161
-
162
- auth_url = Onelogin::Saml::Authrequest.new.create(settings, { :hello => nil })
163
- assert auth_url =~ /&hello=$/
164
- end
165
142
  end
143
+
166
144
  end
@@ -0,0 +1,91 @@
1
+ PD94bWwgdmVyc2lvbj0iMS4wIj8+CjxzYW1scDpSZXNwb25zZSB4bWxuczpz
2
+ YW1scD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOnByb3RvY29sIiBJ
3
+ RD0iXzAyNjNhMDdiLTIwNWYtNDc5Yy05MGZjLTc0OTU3MTVlY2JiZiIgVmVy
4
+ c2lvbj0iMi4wIiBJc3N1ZUluc3RhbnQ9IjIwMTEtMDYtMjJUMTI6NDk6MzAu
5
+ MzQ4WiIgRGVzdGluYXRpb249Imh0dHBzOi8vc29tZW9uZS5leGFtcGxlLmNv
6
+ bS9lbmRwb2ludCIgQ29uc2VudD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6
7
+ Mi4wOmNvbnNlbnQ6dW5zcGVjaWZpZWQiIEluUmVzcG9uc2VUbz0iX2ZjNGEz
8
+ NGIwLTdlZmItMDEyZS1jYWFlLTc4MmJjYjEzYmIzOCI+CiAgPElzc3VlciB4
9
+ bWxucz0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOmFzc2VydGlvbiI+
10
+ aHR0cDovL2xvZ2luLmV4YW1wbGUuY29tL2lzc3VlcjwvSXNzdWVyPgogIDxz
11
+ YW1scDpTdGF0dXM+CiAgICA8c2FtbHA6U3RhdHVzQ29kZSBWYWx1ZT0idXJu
12
+ Om9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOnN0YXR1czpTdWNjZXNzIi8+CiAg
13
+ PC9zYW1scDpTdGF0dXM+CiAgPEFzc2VydGlvbiB4bWxucz0idXJuOm9hc2lz
14
+ Om5hbWVzOnRjOlNBTUw6Mi4wOmFzc2VydGlvbiIgSUQ9Il83MjFiNGE1YS1k
15
+ N2UxLTQ4NjEtOTc1NC1hOWIxOTdiNmY5YWIiIElzc3VlSW5zdGFudD0iMjAx
16
+ MS0wNi0yMlQxMjo0OTozMC4zNDhaIiBWZXJzaW9uPSIyLjAiPgogICAgPElz
17
+ c3Vlcj5odHRwOi8vbG9naW4uZXhhbXBsZS5jb20vaXNzdWVyPC9Jc3N1ZXI+
18
+ CiAgICA8ZHM6U2lnbmF0dXJlIHhtbG5zOmRzPSJodHRwOi8vd3d3LnczLm9y
19
+ Zy8yMDAwLzA5L3htbGRzaWcjIj4KICAgICAgPGRzOlNpZ25lZEluZm8+CiAg
20
+ ICAgICAgPGRzOkNhbm9uaWNhbGl6YXRpb25NZXRob2QgQWxnb3JpdGhtPSJo
21
+ dHRwOi8vd3d3LnczLm9yZy8yMDAxLzEwL3htbC1leGMtYzE0biMiLz4KICAg
22
+ ICAgICA8ZHM6U2lnbmF0dXJlTWV0aG9kIEFsZ29yaXRobT0iaHR0cDovL3d3
23
+ dy53My5vcmcvMjAwMS8wNC94bWxkc2lnLW1vcmUjcnNhLXNoYTI1NiIvPgog
24
+ ICAgICAgIDxkczpSZWZlcmVuY2UgVVJJPSIjXzcyMWI0YTVhLWQ3ZTEtNDg2
25
+ MS05NzU0LWE5YjE5N2I2ZjlhYiI+CiAgICAgICAgICA8ZHM6VHJhbnNmb3Jt
26
+ cz4KICAgICAgICAgICAgPGRzOlRyYW5zZm9ybSBBbGdvcml0aG09Imh0dHA6
27
+ Ly93d3cudzMub3JnLzIwMDAvMDkveG1sZHNpZyNlbnZlbG9wZWQtc2lnbmF0
28
+ dXJlIi8+CiAgICAgICAgICAgIDxkczpUcmFuc2Zvcm0gQWxnb3JpdGhtPSJo
29
+ dHRwOi8vd3d3LnczLm9yZy8yMDAxLzEwL3htbC1leGMtYzE0biMiLz4KICAg
30
+ ICAgICAgIDwvZHM6VHJhbnNmb3Jtcz4KICAgICAgICAgIDxkczpEaWdlc3RN
31
+ ZXRob2QgQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxLzA0L3ht
32
+ bGVuYyNzaGEyNTYiLz4KICAgICAgICAgIDxkczpEaWdlc3RWYWx1ZT52NTN3
33
+ cW80ZllESzhVY3JPVWNPV2cyemxKL2NIVnVtWVMwS2pycm5WdUprPTwvZHM6
34
+ RGlnZXN0VmFsdWU+CiAgICAgICAgPC9kczpSZWZlcmVuY2U+CiAgICAgIDwv
35
+ ZHM6U2lnbmVkSW5mbz4KICAgICAgPGRzOlNpZ25hdHVyZVZhbHVlPlowOXBl
36
+ d1k3ekZ2OTFobjkwbHgwRUVubE1HTkw5elVKWk14SVI2cW9mTFpPWk1sVG5Y
37
+ TjV6RnNmKzFYUFBJWVpMdzVsQ0dqanRtZE5seGR2NzJ6TkZsTVROUnFaN0lp
38
+ SXd2azVHUk0zenZBV3NOT1k2ZEI0YzVxamU0UkhxL2ZySkdCZ04vZ2VWeFZt
39
+ bjNMWmQ1WmNrdWh1UzFzN0ZKQW9MVWNaRUxKL25jZ1JEZGdqQUUrcjhHdGFO
40
+ a3U0VVRCUkdBZnRsMFBXbUFTMDdsbGU2bGFTVVBSQmRCRE5sVlN6R0FQT3lY
41
+ UDE2ZUkxOWJvbllMaGpiOHVoY0N0bWdicnJhbkpVVGxZc1htcnhvaGNGdW4r
42
+ eWZxVFdXd2l4OW1SUXRBdEFFOW5nSUUwVkRkTC9reFR0NktOb1B6d2tlajVW
43
+ eFNMRkFncTJ1M3JaTWN1WUdadTFIUT09PC9kczpTaWduYXR1cmVWYWx1ZT4K
44
+ ICAgICAgPEtleUluZm8geG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAv
45
+ MDkveG1sZHNpZyMiPgogICAgICAgIDxkczpYNTA5RGF0YT4KICAgICAgICAg
46
+ IDxkczpYNTA5Q2VydGlmaWNhdGU+TUlJQzVEQ0NBY3lnQXdJQkFnSVFOQlRr
47
+ dDdxaWNhcEtOc0lYTWNrOHhUQU5CZ2txaGtpRzl3MEJBUXNGQURBdU1Td3dL
48
+ Z1lEVlFRREV5TkJSRVpUSUZOcFoyNXBibWNnTFNCc2IyZHBiaTVrY21WemIz
49
+ VnlZMlZ6TG1OdmJUQWVGdzB4TVRBMk1UQXhPRFUyTURGYUZ3MHhNakEyTURr
50
+ eE9EVTJNREZhTUM0eExEQXFCZ05WQkFNVEkwRkVSbE1nVTJsbmJtbHVaeUF0
51
+ SUd4dloybHVMbVJ5WlhOdmRYSmpaWE11WTI5dE1JSUJJakFOQmdrcWhraUc5
52
+ dzBCQVFFRkFBT0NBUThBTUlJQkNnS0NBUUVBcTdBTURHbkJISUd3dDlLUHRM
53
+ RDBNMEVYR3VabldHQW1iNXAyRkRjRnp0SkhPSThXWVBxZVJwaHpWU0VrZ1h0
54
+ UEloNUp4M2VsUzZoVm43SFZqMld2eklENmpwQjQ1bzhpRGs4UFdnaTE0ZnhH
55
+ V0U1bzFQaUI4WHJlMWM1dnMySUc1YVBXSUQ1dUM2YkQwWGduTDk1TWdPOUhH
56
+ UFBTUVJGbnVqS05xekZRZHRvQkpJSmF3QWVEL2kveHM3RmpGazl4MWZBMEV5
57
+ TENuaCtlYWZmSXBvcmIrMXh4VzJENkQzbVJUZ2ZIeFhyV1I4VzRqSG5pZ2da
58
+ aHFkRGhVeHZFYWlRRlRiSU4yRCt6eUI3YVF3UUNIU0ZwZXJCYytSNUZsbGdu
59
+ R0FhK3NqYjZnMUZYYmVobUVHd1NheHdSWklEQWhqSVFtYTV3WDV5V0pEeEZ6
60
+ UjRwc1RlRlJRSURBUUFCTUEwR0NTcUdTSWIzRFFFQkN3VUFBNElCQVFCekFQ
61
+ QzJRUStVdHZrcVFZMm8vam9IR3RudUx5Zmt3ZDc2NERjR0RsY1lLVktFYURD
62
+ dm5KeDNneXdSVU9ERVJoRGh1Zkpid3I3T29YVmRodzcwTnRURU11Z0pGcjI5
63
+ U2d4bjNDaVRpeVBGU0RHang5MTFhYkt4dEpTQkludkkwMEFqWCtWbElaaG95
64
+ ODNZWU9SWEZjeWIrVXZoMnIyU1pVM0FDTnA4TTNjWlI2SjFFREJoUEtZd0VF
65
+ VWs4TlRNbVpMM3ZXanFMWldUeVRUaFRyUUYvbEg5UENsdzlPMjl1d2lmaXEy
66
+ WHpTeVNyMy9QSHh6cE1Sa0w5YzRFaTQ1UURtYWdlckFVUndlcTVwVVc4QzNV
67
+ QVVqTExWY1hrLzJwZXZaRU43MFlndDVwMmZBZ3M4NE9KaERSS2lIR3BhcmlF
68
+ bWo0THNKR1pzcDdxRkpwbjErTWlqUmU8L2RzOlg1MDlDZXJ0aWZpY2F0ZT4K
69
+ ICAgICAgICA8L2RzOlg1MDlEYXRhPgogICAgICA8L0tleUluZm8+CiAgICA8
70
+ L2RzOlNpZ25hdHVyZT4KICAgIDxTdWJqZWN0PgogICAgICA8TmFtZUlEIEZv
71
+ cm1hdD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6MS4xOm5hbWVpZC1mb3Jt
72
+ YXQ6ZW1haWxBZGRyZXNzIj5oZWxsb0BleGFtcGxlLmNvbTwvTmFtZUlEPgog
73
+ ICAgICA8U3ViamVjdENvbmZpcm1hdGlvbiBNZXRob2Q9InVybjpvYXNpczpu
74
+ YW1lczp0YzpTQU1MOjIuMDpjbTpiZWFyZXIiPgogICAgICAgIDxTdWJqZWN0
75
+ Q29uZmlybWF0aW9uRGF0YSBJblJlc3BvbnNlVG89Il9mYzRhMzRiMC03ZWZi
76
+ LTAxMmUtY2FhZS03ODJiY2IxM2JiMzgiIE5vdE9uT3JBZnRlcj0iMjAxMS0w
77
+ Ni0yMlQxMjo1NDozMC4zNDhaIiBSZWNpcGllbnQ9Imh0dHBzOi8vc29tZW9u
78
+ ZS5leGFtcGxlLmNvbS9lbmRwb2ludCIvPgogICAgICA8L1N1YmplY3RDb25m
79
+ aXJtYXRpb24+CiAgICA8L1N1YmplY3Q+CiAgICA8Q29uZGl0aW9ucyBOb3RC
80
+ ZWZvcmU9IjIwMTEtMDYtMjJUMTI6NDk6MzAuMzMyWiIgTm90T25PckFmdGVy
81
+ PSIyMDExLTA2LTIyVDEzOjQ5OjMwLjMzMloiPgogICAgICA8QXVkaWVuY2VS
82
+ ZXN0cmljdGlvbj4KICAgICAgICA8QXVkaWVuY2U+ZXhhbXBsZS5jb208L0F1
83
+ ZGllbmNlPgogICAgICA8L0F1ZGllbmNlUmVzdHJpY3Rpb24+CiAgICA8L0Nv
84
+ bmRpdGlvbnM+CiAgICA8QXV0aG5TdGF0ZW1lbnQgQXV0aG5JbnN0YW50PSIy
85
+ MDExLTA2LTIyVDEyOjQ5OjMwLjExMloiIFNlc3Npb25JbmRleD0iXzcyMWI0
86
+ YTVhLWQ3ZTEtNDg2MS05NzU0LWE5YjE5N2I2ZjlhYiI+CiAgICAgIDxBdXRo
87
+ bkNvbnRleHQ+CiAgICAgICAgPEF1dGhuQ29udGV4dENsYXNzUmVmPnVybjpv
88
+ YXNpczpuYW1lczp0YzpTQU1MOjIuMDphYzpjbGFzc2VzOlBhc3N3b3JkUHJv
89
+ dGVjdGVkVHJhbnNwb3J0PC9BdXRobkNvbnRleHRDbGFzc1JlZj4KICAgICAg
90
+ PC9BdXRobkNvbnRleHQ+CiAgICA8L0F1dGhuU3RhdGVtZW50PgogIDwvQXNz
91
+ ZXJ0aW9uPgo8L3NhbWxwOlJlc3BvbnNlPgo=
@@ -0,0 +1,56 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <saml2p:Response xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:xs="http://www.w3.org/2001/XMLSchema" Destination="https://example.hello.com/access/saml" ID="jVFQbyEpSfUwqhZtJtarIaGoshwuAQMDwLoiMhzJXsv" InResponseTo="cfeooghajnhofcmogakmlhpkohnmikicnfhdnjlc" IssueInstant="2011-06-21T13:54:38.661Z" Version="2.0">
3
+ <saml2:Issuer xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion">https://idm.orademo.com</saml2:Issuer>
4
+ <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
5
+ <ds:SignedInfo>
6
+ <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
7
+ <ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
8
+ <ds:Reference URI="#jVFQbyEpSfUwqhZtJtarIaGoshwuAQMDwLoiMhzJXsv">
9
+ <ds:Transforms>
10
+ <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
11
+ <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
12
+ <ec:InclusiveNamespaces xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#" PrefixList="xs"/>
13
+ </ds:Transform>
14
+ </ds:Transforms>
15
+ <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
16
+ <ds:DigestValue>uHuSry39P16Yh7srS32xESmj4Lw=</ds:DigestValue>
17
+ </ds:Reference>
18
+ </ds:SignedInfo>
19
+ <ds:SignatureValue>fdghdfggfd=</ds:SignatureValue>
20
+ <ds:KeyInfo>
21
+ <ds:X509Data>
22
+ <ds:X509Certificate>dfghjkl</ds:X509Certificate>
23
+ </ds:X509Data>
24
+ </ds:KeyInfo>
25
+ </ds:Signature>
26
+ <saml2p:Status>
27
+ <saml2p:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/>
28
+ </saml2p:Status>
29
+ <saml2:Assertion xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" ID="emmCjammnYdAbMWDuMAJeZvQIMBayeeYqqwvQoDclKE" IssueInstant="2011-06-21T13:54:38.676Z" Version="2.0">
30
+ <saml2:Issuer>https://idm.orademo.com</saml2:Issuer>
31
+ <saml2:Subject>
32
+ <saml2:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress" NameQualifier="idp.example.org">someone@example.org</saml2:NameID>
33
+ <saml2:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
34
+ <saml2:SubjectConfirmationData InResponseTo="cfeooghajnhofcmogakmlhpkohnmikicnfhdnjlc" NotOnOrAfter="2011-06-21T14:09:38.676Z" Recipient="https://example.hello.com/access/saml"/>
35
+ </saml2:SubjectConfirmation>
36
+ </saml2:Subject>
37
+ <saml2:Conditions NotBefore="2011-06-21T13:54:38.683Z" NotOnOrAfter="2011-06-21T14:09:38.683Z">
38
+ <saml2:AudienceRestriction>
39
+ <saml2:Audience>hello.com</saml2:Audience>
40
+ </saml2:AudienceRestriction>
41
+ </saml2:Conditions>
42
+ <saml2:AuthnStatement AuthnInstant="2011-06-21T13:54:38.685Z" SessionIndex="perdkjfskdjfksdiertusfsdfsddeurtherukjdfgkdffg">
43
+ <saml2:AuthnContext>
44
+ <saml2:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport</saml2:AuthnContextClassRef>
45
+ </saml2:AuthnContext>
46
+ </saml2:AuthnStatement>
47
+ <saml2:AttributeStatement>
48
+ <saml2:Attribute Name="FirstName">
49
+ <saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">Someone</saml2:AttributeValue>
50
+ </saml2:Attribute>
51
+ <saml2:Attribute Name="LastName">
52
+ <saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">Special</saml2:AttributeValue>
53
+ </saml2:Attribute>
54
+ </saml2:AttributeStatement>
55
+ </saml2:Assertion>
56
+ </saml2p:Response>
@@ -0,0 +1,71 @@
1
+ <?xml version="1.0"?>
2
+ <samlp:Response xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" ID="pfxc32aed67-820f-4296-0c20-205a10dd5787" Version="2.0" IssueInstant="2011-06-17T14:54:14Z" Destination="https://example.hello.com/access/saml" InResponseTo="_57bcbf70-7b1f-012e-c821-782bcb13bb38">
3
+ <saml:Issuer>https://federate.example.net/saml/saml2/idp/metadata.php</saml:Issuer>
4
+ <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
5
+ <ds:SignedInfo>
6
+ <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
7
+ <ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
8
+ <ds:Reference URI="#pfxc32aed67-820f-4296-0c20-205a10dd5787">
9
+ <ds:Transforms>
10
+ <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
11
+ <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
12
+ </ds:Transforms>
13
+ <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
14
+ <ds:DigestValue>dVJ592k5xPjCHBCMiJ8eZkPUiT8=</ds:DigestValue>
15
+ </ds:Reference>
16
+ </ds:SignedInfo>
17
+ <ds:SignatureValue>LHNK1FJfcOIUuWVKJmGABQ+W98+pQ==</ds:SignatureValue>
18
+ <ds:KeyInfo>
19
+ <ds:X509Data>
20
+ <ds:X509Certificate>MIIQmS6WmmIht3k=</ds:X509Certificate>
21
+ </ds:X509Data>
22
+ </ds:KeyInfo>
23
+ </ds:Signature>
24
+ <samlp:Status>
25
+ <samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/>
26
+ </samlp:Status>
27
+ <saml:Assertion xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" ID="pfx7841991c-c73f-4035-e2ee-c170c0e1d3e4" Version="2.0" IssueInstant="2011-06-17T14:54:14Z">
28
+ <saml:Issuer>https://federate.example.net/saml/saml2/idp/metadata.php</saml:Issuer>
29
+ <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
30
+ <ds:SignedInfo>
31
+ <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
32
+ <ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
33
+ <ds:Reference URI="#pfx7841991c-c73f-4035-e2ee-c170c0e1d3e4">
34
+ <ds:Transforms>
35
+ <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
36
+ <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
37
+ </ds:Transforms>
38
+ <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
39
+ <ds:DigestValue>mi0IAultZkpsZa1XxGx9X4iAPQg=</ds:DigestValue>
40
+ </ds:Reference>
41
+ </ds:SignedInfo>
42
+ <ds:SignatureValue>LqkW39SOYbttYxlGhIBw==</ds:SignatureValue>
43
+ <ds:KeyInfo>
44
+ <ds:X509Data>
45
+ <ds:X509Certificate>MIIGmmIht3k=</ds:X509Certificate>
46
+ </ds:X509Data>
47
+ </ds:KeyInfo>
48
+ </ds:Signature>
49
+ <saml:Subject>
50
+ <saml:NameID SPNameQualifier="hello.com" Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress">someone@example.com</saml:NameID>
51
+ <saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
52
+ <saml:SubjectConfirmationData NotOnOrAfter="2011-06-17T14:59:14Z" Recipient="https://example.hello.com/access/saml" InResponseTo="_57bcbf70-7b1f-012e-c821-782bcb13bb38"/>
53
+ </saml:SubjectConfirmation>
54
+ </saml:Subject>
55
+ <saml:Conditions NotBefore="2011-06-17T14:53:44Z" NotOnOrAfter="2011-06-17T14:59:14Z">
56
+ <saml:AudienceRestriction>
57
+ <saml:Audience>hello.com</saml:Audience>
58
+ </saml:AudienceRestriction>
59
+ </saml:Conditions>
60
+ <saml:AuthnStatement AuthnInstant="2011-06-17T14:54:07Z" SessionNotOnOrAfter="2011-06-17T22:54:14Z" SessionIndex="_51be37965feb5579d803141076936dc2e9d1d98ebf">
61
+ <saml:AuthnContext>
62
+ <saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:Password</saml:AuthnContextClassRef>
63
+ </saml:AuthnContext>
64
+ </saml:AuthnStatement>
65
+ <saml:AttributeStatement>
66
+ <saml:Attribute Name="mail" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
67
+ <saml:AttributeValue xsi:type="xs:string">someone@example.com</saml:AttributeValue>
68
+ </saml:Attribute>
69
+ </saml:AttributeStatement>
70
+ </saml:Assertion>
71
+ </samlp:Response>
@@ -0,0 +1,23 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), "test_helper"))
2
+
3
+ class SettingsTest < Test::Unit::TestCase
4
+
5
+ context "Settings" do
6
+ setup do
7
+ @settings = Onelogin::Saml::Settings.new
8
+ end
9
+ should "should provide getters and settings" do
10
+ accessors = [
11
+ :assertion_consumer_service_url, :issuer, :sp_name_qualifier, :sp_name_qualifier,
12
+ :idp_sso_target_url, :idp_cert_fingerprint, :name_identifier_format
13
+ ]
14
+
15
+ accessors.each do |accessor|
16
+ value = Kernel.rand
17
+ @settings.send("#{accessor}=".to_sym, value)
18
+ assert_equal value, @settings.send(accessor)
19
+ end
20
+ end
21
+ end
22
+
23
+ end
@@ -2,12 +2,22 @@ require 'rubygems'
2
2
  require 'test/unit'
3
3
  require 'shoulda'
4
4
  require 'mocha'
5
+ require 'ruby-debug'
5
6
 
6
7
  $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
7
8
  $LOAD_PATH.unshift(File.dirname(__FILE__))
8
9
  require 'ruby-saml'
9
10
 
10
11
  class Test::Unit::TestCase
12
+ def fixture(document, base64 = true)
13
+ response = Dir.glob(File.join(File.dirname(__FILE__), "responses", "#{document}*")).first
14
+ if base64 && response =~ /\.xml$/
15
+ Base64.encode64(File.read(response))
16
+ else
17
+ File.read(response)
18
+ end
19
+ end
20
+
11
21
  def response_document
12
22
  @response_document ||= File.read(File.join(File.dirname(__FILE__), 'responses', 'response1.xml.base64'))
13
23
  end
@@ -10,7 +10,7 @@ class XmlSecurityTest < Test::Unit::TestCase
10
10
 
11
11
  should "should run validate without throwing NS related exceptions" do
12
12
  base64cert = @document.elements["//ds:X509Certificate"].text
13
- @document.validate_doc(base64cert, nil)
13
+ @document.validate_doc(base64cert, true)
14
14
  end
15
15
  end
16
16
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby-saml
3
3
  version: !ruby/object:Gem::Version
4
- hash: 5
4
+ hash: 3
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 4
9
- - 5
10
- version: 0.4.5
9
+ - 6
10
+ version: 0.4.6
11
11
  platform: ruby
12
12
  authors:
13
13
  - OneLogin LLC
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-06-17 00:00:00 +02:00
18
+ date: 2011-06-28 00:00:00 +02:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -63,7 +63,7 @@ dependencies:
63
63
  type: :development
64
64
  version_requirements: *id003
65
65
  - !ruby/object:Gem::Dependency
66
- name: mocha
66
+ name: ruby-debug
67
67
  prerelease: false
68
68
  requirement: &id004 !ruby/object:Gem::Requirement
69
69
  none: false
@@ -76,6 +76,20 @@ dependencies:
76
76
  version: "0"
77
77
  type: :development
78
78
  version_requirements: *id004
79
+ - !ruby/object:Gem::Dependency
80
+ name: mocha
81
+ prerelease: false
82
+ requirement: &id005 !ruby/object:Gem::Requirement
83
+ none: false
84
+ requirements:
85
+ - - ">="
86
+ - !ruby/object:Gem::Version
87
+ hash: 3
88
+ segments:
89
+ - 0
90
+ version: "0"
91
+ type: :development
92
+ version_requirements: *id005
79
93
  description: SAML toolkit for Ruby on Rails
80
94
  email: support@onelogin.com
81
95
  executables: []
@@ -96,16 +110,22 @@ files:
96
110
  - lib/onelogin/saml/authrequest.rb
97
111
  - lib/onelogin/saml/response.rb
98
112
  - lib/onelogin/saml/settings.rb
113
+ - lib/onelogin/saml/validation_error.rb
99
114
  - lib/ruby-saml.rb
100
115
  - lib/xml_security.rb
101
116
  - ruby-saml.gemspec
117
+ - test/request_test.rb
118
+ - test/response_test.rb
119
+ - test/responses/adfs_response.xml.base64
102
120
  - test/responses/certificate1
121
+ - test/responses/open_saml_response.xml
103
122
  - test/responses/response1.xml.base64
104
123
  - test/responses/response2.xml.base64
105
124
  - test/responses/response3.xml.base64
106
125
  - test/responses/response4.xml.base64
107
126
  - test/responses/response5.xml.base64
108
- - test/ruby-saml_test.rb
127
+ - test/responses/simple_saml_php.xml
128
+ - test/settings_test.rb
109
129
  - test/test_helper.rb
110
130
  - test/xml_security_test.rb
111
131
  has_rdoc: true
@@ -143,6 +163,8 @@ signing_key:
143
163
  specification_version: 3
144
164
  summary: SAML Ruby Tookit
145
165
  test_files:
146
- - test/ruby-saml_test.rb
166
+ - test/request_test.rb
167
+ - test/response_test.rb
168
+ - test/settings_test.rb
147
169
  - test/test_helper.rb
148
170
  - test/xml_security_test.rb