ruby-saml 0.3.4 → 0.4.0

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/VERSION CHANGED
@@ -1 +1 @@
1
- 0.3.4
1
+ 0.4.0
@@ -3,17 +3,15 @@ require "time"
3
3
 
4
4
  module Onelogin::Saml
5
5
  class Response
6
- attr_accessor :response, :document, :logger, :settings, :namespace
6
+ ASSERTION = "urn:oasis:names:tc:SAML:2.0:assertion"
7
+ PROTOCOL = "urn:oasis:names:tc:SAML:2.0:protocol"
8
+
9
+ attr_accessor :response, :document, :logger, :settings
7
10
 
8
11
  def initialize(response)
9
12
  raise ArgumentError.new("Response cannot be nil") if response.nil?
10
- self.response = response
11
- self.document = XMLSecurity::SignedDocument.new(Base64.decode64(response))
12
- self.namespace = "saml"
13
-
14
- if document.elements["/#{namespace}p:Response/"].nil?
15
- self.namespace = "saml2"
16
- end
13
+ self.response = response
14
+ self.document = XMLSecurity::SignedDocument.new(Base64.decode64(response))
17
15
  end
18
16
 
19
17
  def is_valid?
@@ -26,36 +24,40 @@ module Onelogin::Saml
26
24
 
27
25
  # The value of the user identifier as designated by the initialization request response
28
26
  def name_id
29
- @name_id ||= document.elements["/#{namespace}p:Response/#{namespace}:Assertion/#{namespace}:Subject/#{namespace}:NameID"].text
27
+ @name_id ||= begin
28
+ node = REXML::XPath.first(document, "/p:Response/a:Assertion/a:Subject/a:NameID", { "p" => PROTOCOL, "a" => ASSERTION })
29
+ node.text
30
+ end
30
31
  end
31
32
 
32
- # A hash of alle the attributes with the response. Assuming there is onlye one value for each key
33
+ # A hash of alle the attributes with the response. Assuming there is only one value for each key
33
34
  def attributes
34
- saml_attribute_statements = document.elements["/#{namespace}p:Response/#{namespace}:Assertion/#{namespace}:AttributeStatement"].elements
35
- statements = saml_attribute_statements.map do |child|
36
- child.attributes.map do |key, attribute|
37
- [attribute, child.elements.first.text]
35
+ @attr_statements ||= begin
36
+ result = {}
37
+
38
+ stmt_element = REXML::XPath.first(document, "/p:Response/a:Assertion/a:AttributeStatement", { "p" => PROTOCOL, "a" => ASSERTION })
39
+ stmt_element.elements.each do |attr_element|
40
+ name = attr_element.attributes["Name"]
41
+ value = attr_element.elements.first.text
42
+
43
+ result[name] = value
38
44
  end
39
- end
40
45
 
41
- hash = Hash[statements.flatten(1)]
42
- @attributes ||= make_hash_access_indiferent(hash)
46
+ result.keys.each do |key|
47
+ result[key.intern] = result[key]
48
+ end
49
+
50
+ result
51
+ end
43
52
  end
44
53
 
45
54
  # When this user session should expire at latest
46
55
  def session_expires_at
47
- @expires_at ||= Time.parse(document.elements["/#{namespace}p:Response/#{namespace}:Assertion/#{namespace}:AuthnStatement"].attributes["SessionNotOnOrAfter"])
48
- end
49
-
50
- private
51
-
52
- def make_hash_access_indiferent(hash)
53
- sym_hash = {}
54
- hash.each do |key, value|
55
- sym_hash[key.intern] = value
56
+ @expires_at ||= begin
57
+ node = REXML::XPath.first(document, "/p:Response/a:Assertion/a:AuthnStatement", { "p" => PROTOCOL, "a" => ASSERTION })
58
+ Time.parse(node.attributes["SessionNotOnOrAfter"]) if node && node.attributes["SessionNotOnOrAfter"]
56
59
  end
57
-
58
- sym_hash.merge(hash)
59
60
  end
61
+
60
62
  end
61
63
  end
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{ruby-saml}
8
- s.version = "0.3.4"
8
+ s.version = "0.4.0"
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-04-28}
12
+ s.date = %q{2011-05-03}
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 = [
@@ -32,6 +32,7 @@ Gem::Specification.new do |s|
32
32
  "ruby-saml.gemspec",
33
33
  "test/responses/response1.xml.base64",
34
34
  "test/responses/response2.xml.base64",
35
+ "test/responses/response3.xml.base64",
35
36
  "test/ruby-saml_test.rb",
36
37
  "test/test_helper.rb",
37
38
  "test/xml_security_test.rb"
@@ -0,0 +1,66 @@
1
+ PD94bWwgdmVyc2lvbj0iMS4wIj8+CjxzYW1scDpSZXNwb25zZSB4bWxuczpz
2
+ YW1scD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOnByb3RvY29sIiBJ
3
+ RD0iXzZiODVkMGRkLWJmYTgtNGRlZi04MmMyLTg2MjFlMDQ1MjQ3NyIgVmVy
4
+ c2lvbj0iMi4wIiBJc3N1ZUluc3RhbnQ9IjIwMTEtMDUtMDJUMTk6NDM6NTQu
5
+ NjkyWiIgRGVzdGluYXRpb249Imh0dHBzOi8vZXhhbXBsZS5jb20vYWNjZXNz
6
+ L3NhbWwiIENvbnNlbnQ9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDpj
7
+ b25zZW50OnVuc3BlY2lmaWVkIiBJblJlc3BvbnNlVG89Il9mYjg0MThkMC01
8
+ NzFlLTAxMmUtZWVlMC0wMDUwNTY5MjAwZDAiPgogIDxJc3N1ZXIgeG1sbnM9
9
+ InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDphc3NlcnRpb24iPmh0dHA6
10
+ Ly9leGFtcGxlLmNvbS9zZXJ2aWNlcy90cnVzdDwvSXNzdWVyPgogIDxzYW1s
11
+ cDpTdGF0dXM+CiAgICA8c2FtbHA6U3RhdHVzQ29kZSBWYWx1ZT0idXJuOm9h
12
+ c2lzOm5hbWVzOnRjOlNBTUw6Mi4wOnN0YXR1czpTdWNjZXNzIi8+CiAgPC9z
13
+ YW1scDpTdGF0dXM+CiAgPEFzc2VydGlvbiB4bWxucz0idXJuOm9hc2lzOm5h
14
+ bWVzOnRjOlNBTUw6Mi4wOmFzc2VydGlvbiIgSUQ9Il9kYmU2YTM2NS05NTgy
15
+ LTQ2MGYtYjRiMS0xZjc5YmY3MGY3NmIiIElzc3VlSW5zdGFudD0iMjAxMS0w
16
+ NS0wMlQxOTo0Mzo1NC42NDVaIiBWZXJzaW9uPSIyLjAiPgogICAgPElzc3Vl
17
+ cj5odHRwOi8vZXhhbXBsZS5jb20vc2VydmljZXMvdHJ1c3Q8L0lzc3Vlcj4K
18
+ ICAgIDxkczpTaWduYXR1cmUgeG1sbnM6ZHM9Imh0dHA6Ly93d3cudzMub3Jn
19
+ LzIwMDAvMDkveG1sZHNpZyMiPgogICAgICA8ZHM6U2lnbmVkSW5mbz4KICAg
20
+ ICAgICA8ZHM6Q2Fub25pY2FsaXphdGlvbk1ldGhvZCBBbGdvcml0aG09Imh0
21
+ dHA6Ly93d3cudzMub3JnLzIwMDEvMTAveG1sLWV4Yy1jMTRuIyIvPgogICAg
22
+ ICAgIDxkczpTaWduYXR1cmVNZXRob2QgQWxnb3JpdGhtPSJodHRwOi8vd3d3
23
+ LnczLm9yZy8yMDAwLzA5L3htbGRzaWcjcnNhLXNoYTEiLz4KICAgICAgICA8
24
+ ZHM6UmVmZXJlbmNlIFVSST0iI19kYmU2YTM2NS05NTgyLTQ2MGYtYjRiMS0x
25
+ Zjc5YmY3MGY3NmIiPgogICAgICAgICAgPGRzOlRyYW5zZm9ybXM+CiAgICAg
26
+ ICAgICAgIDxkczpUcmFuc2Zvcm0gQWxnb3JpdGhtPSJodHRwOi8vd3d3Lncz
27
+ Lm9yZy8yMDAwLzA5L3htbGRzaWcjZW52ZWxvcGVkLXNpZ25hdHVyZSIvPgog
28
+ ICAgICAgICAgICA8ZHM6VHJhbnNmb3JtIEFsZ29yaXRobT0iaHR0cDovL3d3
29
+ dy53My5vcmcvMjAwMS8xMC94bWwtZXhjLWMxNG4jIi8+CiAgICAgICAgICA8
30
+ L2RzOlRyYW5zZm9ybXM+CiAgICAgICAgICA8ZHM6RGlnZXN0TWV0aG9kIEFs
31
+ Z29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMC8wOS94bWxkc2lnI3No
32
+ YTEiLz4KICAgICAgICAgIDxkczpEaWdlc3RWYWx1ZT5EaWdlc3Q8L2RzOkRp
33
+ Z2VzdFZhbHVlPgogICAgICAgIDwvZHM6UmVmZXJlbmNlPgogICAgICA8L2Rz
34
+ OlNpZ25lZEluZm8+CiAgICAgIDxkczpTaWduYXR1cmVWYWx1ZT5TaWduYXR1
35
+ cmU8L2RzOlNpZ25hdHVyZVZhbHVlPgogICAgICA8S2V5SW5mbyB4bWxucz0i
36
+ aHR0cDovL3d3dy53My5vcmcvMjAwMC8wOS94bWxkc2lnIyI+CiAgICAgICAg
37
+ PGRzOlg1MDlEYXRhPgogICAgICAgICAgPGRzOlg1MDlDZXJ0aWZpY2F0ZT5T
38
+ dHVmZjwvZHM6WDUwOUNlcnRpZmljYXRlPgogICAgICAgIDwvZHM6WDUwOURh
39
+ dGE+CiAgICAgIDwvS2V5SW5mbz4KICAgIDwvZHM6U2lnbmF0dXJlPgogICAg
40
+ PFN1YmplY3Q+CiAgICAgIDxOYW1lSUQgRm9ybWF0PSJ1cm46b2FzaXM6bmFt
41
+ ZXM6dGM6U0FNTDoxLjE6bmFtZWlkLWZvcm1hdDplbWFpbEFkZHJlc3MiPnNv
42
+ bWVvbmVAZXhhbXBsZS5jb208L05hbWVJRD4KICAgICAgPFN1YmplY3RDb25m
43
+ aXJtYXRpb24gTWV0aG9kPSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6
44
+ Y206YmVhcmVyIj4KICAgICAgICA8U3ViamVjdENvbmZpcm1hdGlvbkRhdGEg
45
+ SW5SZXNwb25zZVRvPSJfZmI4NDE4ZDAtNTcxZS0wMTJlLWVlZTAtMDA1MDU2
46
+ OTIwMGQwIiBOb3RPbk9yQWZ0ZXI9IjIwMTEtMDUtMDJUMTk6NDg6NTQuNzA3
47
+ WiIgUmVjaXBpZW50PSJodHRwczovL2V4YW1wbGUuY29tL2FjY2Vzcy9zYW1s
48
+ Ii8+CiAgICAgIDwvU3ViamVjdENvbmZpcm1hdGlvbj4KICAgIDwvU3ViamVj
49
+ dD4KICAgIDxDb25kaXRpb25zIE5vdEJlZm9yZT0iMjAxMS0wNS0wMlQxOTo0
50
+ Mzo1NC42NDVaIiBOb3RPbk9yQWZ0ZXI9IjIwMTEtMDUtMDJUMjA6NDM6NTQu
51
+ NjQ1WiI+CiAgICAgIDxBdWRpZW5jZVJlc3RyaWN0aW9uPgogICAgICAgIDxB
52
+ dWRpZW5jZT5jb25zdW1lci5leGFtcGxlLmNvbTwvQXVkaWVuY2U+CiAgICAg
53
+ IDwvQXVkaWVuY2VSZXN0cmljdGlvbj4KICAgIDwvQ29uZGl0aW9ucz4KICAg
54
+ IDxBdHRyaWJ1dGVTdGF0ZW1lbnQ+CiAgICAgIDxBdHRyaWJ1dGUgTmFtZT0i
55
+ aHR0cDovL3NjaGVtYXMueG1sc29hcC5vcmcvd3MvMjAwNS8wNS9pZGVudGl0
56
+ eS9jbGFpbXMvZW1haWxhZGRyZXNzIj4KICAgICAgICA8QXR0cmlidXRlVmFs
57
+ dWU+c29tZW9uZUBleGFtcGxlLmNvbTwvQXR0cmlidXRlVmFsdWU+CiAgICAg
58
+ IDwvQXR0cmlidXRlPgogICAgPC9BdHRyaWJ1dGVTdGF0ZW1lbnQ+CiAgICA8
59
+ QXV0aG5TdGF0ZW1lbnQgQXV0aG5JbnN0YW50PSIyMDExLTA1LTAyVDE5OjQz
60
+ OjU0LjI4NVoiIFNlc3Npb25JbmRleD0iX2RiZTZhMzY1LTk1ODItNDYwZi1i
61
+ NGIxLTFmNzliZjcwZjc2YiI+CiAgICAgIDxBdXRobkNvbnRleHQ+CiAgICAg
62
+ ICAgPEF1dGhuQ29udGV4dENsYXNzUmVmPnVybjpvYXNpczpuYW1lczp0YzpT
63
+ QU1MOjIuMDphYzpjbGFzc2VzOlBhc3N3b3JkUHJvdGVjdGVkVHJhbnNwb3J0
64
+ PC9BdXRobkNvbnRleHRDbGFzc1JlZj4KICAgICAgPC9BdXRobkNvbnRleHQ+
65
+ CiAgICA8L0F1dGhuU3RhdGVtZW50PgogIDwvQXNzZXJ0aW9uPgo8L3NhbWxw
66
+ OlJlc3BvbnNlPgo=
@@ -35,6 +35,8 @@ class RubySamlTest < Test::Unit::TestCase
35
35
  assert !response.name_id.nil?
36
36
  response = Onelogin::Saml::Response.new(response_document_2)
37
37
  assert !response.name_id.nil?
38
+ response = Onelogin::Saml::Response.new(response_document_3)
39
+ assert !response.name_id.nil?
38
40
  end
39
41
 
40
42
  context "#is_valid?" do
@@ -65,6 +67,9 @@ class RubySamlTest < Test::Unit::TestCase
65
67
  should "extract the value of the name id element" do
66
68
  response = Onelogin::Saml::Response.new(response_document)
67
69
  assert_equal "support@onelogin.com", response.name_id
70
+
71
+ response = Onelogin::Saml::Response.new(response_document_3)
72
+ assert_equal "someone@example.com", response.name_id
68
73
  end
69
74
  end
70
75
 
@@ -84,12 +89,20 @@ class RubySamlTest < Test::Unit::TestCase
84
89
  assert_equal "demo", response.attributes[:uid]
85
90
  assert_equal "value", response.attributes[:another_value]
86
91
  end
92
+
93
+ should "work for implicit namespaces" do
94
+ response = Onelogin::Saml::Response.new(response_document_3)
95
+ assert_equal "someone@example.com", response.attributes["http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress"]
96
+ end
87
97
  end
88
98
 
89
99
  context "#session_expires_at" do
90
100
  should "extract the value of the SessionNotOnOrAfter attribute" do
91
101
  response = Onelogin::Saml::Response.new(response_document)
92
102
  assert response.session_expires_at.is_a?(Time)
103
+
104
+ response = Onelogin::Saml::Response.new(response_document_2)
105
+ assert response.session_expires_at.nil?
93
106
  end
94
107
  end
95
108
  end
@@ -15,4 +15,9 @@ class Test::Unit::TestCase
15
15
  def response_document_2
16
16
  @response_document2 ||= File.read(File.join(File.dirname(__FILE__), 'responses', 'response2.xml.base64'))
17
17
  end
18
+
19
+ def response_document_3
20
+ @response_document3 ||= File.read(File.join(File.dirname(__FILE__), 'responses', 'response3.xml.base64'))
21
+ end
22
+
18
23
  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: 27
4
+ hash: 15
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
- - 3
9
8
  - 4
10
- version: 0.3.4
9
+ - 0
10
+ version: 0.4.0
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-04-28 00:00:00 +02:00
18
+ date: 2011-05-03 00:00:00 +02:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -101,6 +101,7 @@ files:
101
101
  - ruby-saml.gemspec
102
102
  - test/responses/response1.xml.base64
103
103
  - test/responses/response2.xml.base64
104
+ - test/responses/response3.xml.base64
104
105
  - test/ruby-saml_test.rb
105
106
  - test/test_helper.rb
106
107
  - test/xml_security_test.rb