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 +1 -1
- data/lib/onelogin/saml/response.rb +30 -28
- data/ruby-saml.gemspec +3 -2
- data/test/responses/response3.xml.base64 +66 -0
- data/test/ruby-saml_test.rb +13 -0
- data/test/test_helper.rb +5 -0
- metadata +5 -4
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.4.0
|
@@ -3,17 +3,15 @@ require "time"
|
|
3
3
|
|
4
4
|
module Onelogin::Saml
|
5
5
|
class Response
|
6
|
-
|
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
|
11
|
-
self.document
|
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 ||=
|
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
|
33
|
+
# A hash of alle the attributes with the response. Assuming there is only one value for each key
|
33
34
|
def attributes
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
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
|
-
|
42
|
-
|
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 ||=
|
48
|
-
|
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
|
data/ruby-saml.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{ruby-saml}
|
8
|
-
s.version = "0.
|
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-
|
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=
|
data/test/ruby-saml_test.rb
CHANGED
@@ -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
|
data/test/test_helper.rb
CHANGED
@@ -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:
|
4
|
+
hash: 15
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
- 3
|
9
8
|
- 4
|
10
|
-
|
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-
|
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
|