ruby-saml-bekk 0.3.2 → 0.3.3
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.
- data/VERSION +1 -1
- data/lib/onelogin/saml/logoutrequest.rb +9 -9
- data/lib/onelogin/saml/logoutresponse.rb +5 -0
- data/lib/onelogin/saml/response.rb +4 -0
- data/lib/onelogin/saml/settings.rb +1 -2
- data/test/ruby-saml_test.rb +39 -5
- metadata +2 -2
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.3.
|
1
|
+
0.3.3
|
@@ -1,36 +1,36 @@
|
|
1
|
-
require 'base64'
|
2
1
|
require 'uuid'
|
3
|
-
require 'cgi'
|
4
2
|
|
5
3
|
module Onelogin::Saml
|
6
4
|
class Logoutrequest
|
5
|
+
include Codeing
|
7
6
|
attr_reader :transaction_id
|
8
7
|
|
9
8
|
def initialize
|
10
9
|
@transaction_id = UUID.new.generate
|
11
10
|
end
|
12
11
|
|
13
|
-
def create(settings,
|
12
|
+
def create(settings, params={})
|
14
13
|
issue_instant = Onelogin::Saml::Logoutrequest.timestamp
|
15
14
|
|
16
|
-
request = xml(settings,
|
15
|
+
request = xml(settings, issue_instant)
|
17
16
|
|
18
|
-
deflated_request =
|
19
|
-
base64_request =
|
17
|
+
deflated_request = deflate(request)
|
18
|
+
base64_request = encode(deflated_request)
|
20
19
|
params["SAMLRequest"] = base64_request
|
21
|
-
query_string = params.map {|key, value| "#{key}=#{
|
20
|
+
query_string = params.map {|key, value| "#{key}=#{escape(value)}"}.join("&")
|
22
21
|
|
23
22
|
settings.idp_slo_target_url + "?#{query_string}"
|
24
23
|
end
|
25
24
|
|
26
|
-
def xml(settings,
|
25
|
+
def xml(settings, issue_instant)
|
27
26
|
request = <<-EOF
|
28
27
|
<samlp:LogoutRequest xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
|
29
28
|
ID="#{transaction_id}" Version="2.0" IssueInstant="#{issue_instant}">
|
30
29
|
<saml:Issuer xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">#{settings.issuer}</saml:Issuer>
|
31
30
|
<saml:NameID xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
|
32
31
|
NameQualifier="#{settings.sp_name_qualifier}"
|
33
|
-
Format="#{settings.name_identifier_format}">#{
|
32
|
+
Format="#{settings.name_identifier_format}">#{settings.name_id}</saml:NameID>
|
33
|
+
<samlp:SessionIndex xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol">#{settings.sessionindex}</samlp:SessionIndex>
|
34
34
|
</samlp:LogoutRequest>
|
35
35
|
EOF
|
36
36
|
|
@@ -24,6 +24,11 @@ module Onelogin
|
|
24
24
|
document.elements["/samlp:LogoutResponse"].attributes["InResponseTo"]
|
25
25
|
end
|
26
26
|
|
27
|
+
def success?
|
28
|
+
document.elements["/samlp:LogoutResponse/samlp:Status/samlp:StatusCode"].attributes["Value"] == "urn:oasis:names:tc:SAML:2.0:status:Success"
|
29
|
+
|
30
|
+
end
|
31
|
+
|
27
32
|
protected
|
28
33
|
def document
|
29
34
|
REXML::Document.new(@response)
|
@@ -43,6 +43,10 @@ module Onelogin::Saml
|
|
43
43
|
@expires_at ||= Time.parse(document.elements["/samlp:Response/saml:Assertion/saml:AuthnStatement"].attributes["SessionNotOnOrAfter"])
|
44
44
|
end
|
45
45
|
|
46
|
+
def sessionindex
|
47
|
+
document.elements["/samlp:Response/saml:Assertion/saml:AuthnStatement"].attributes["SessionIndex"]
|
48
|
+
end
|
49
|
+
|
46
50
|
private
|
47
51
|
|
48
52
|
def make_hash_access_indiferent(hash)
|
@@ -3,7 +3,6 @@ module Onelogin::Saml
|
|
3
3
|
attr_accessor :assertion_consumer_service_url, :issuer, :sp_name_qualifier
|
4
4
|
attr_accessor :idp_sso_target_url, :idp_cert_fingerprint, :name_identifier_format
|
5
5
|
attr_accessor :idp_slo_target_url
|
6
|
-
|
7
|
-
SLO_ELEMENT_PATH = "/EntityDescriptor/IDPSSODescriptor/SingleLogoutService[@Binding='urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect']"
|
6
|
+
attr_accessor :sessionindex, :name_id
|
8
7
|
end
|
9
8
|
end
|
data/test/ruby-saml_test.rb
CHANGED
@@ -11,7 +11,7 @@ class RubySamlTest < Test::Unit::TestCase
|
|
11
11
|
end
|
12
12
|
should "should provide getters and settings" do
|
13
13
|
accessors = [
|
14
|
-
:assertion_consumer_service_url, :issuer, :sp_name_qualifier,
|
14
|
+
:assertion_consumer_service_url, :issuer, :sp_name_qualifier,
|
15
15
|
:idp_sso_target_url, :idp_cert_fingerprint, :name_identifier_format
|
16
16
|
]
|
17
17
|
|
@@ -82,6 +82,13 @@ class RubySamlTest < Test::Unit::TestCase
|
|
82
82
|
end
|
83
83
|
end
|
84
84
|
|
85
|
+
context "#sessionindex" do
|
86
|
+
should "get the sessionindex" do
|
87
|
+
response = Onelogin::Saml::Response.new(response_document)
|
88
|
+
assert_equal "_531c32d283bdff7e04e487bcdbc4dd8d", response.sessionindex
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
85
92
|
context "#session_expires_at" do
|
86
93
|
should "extract the value of the SessionNotOnOrAfter attribute" do
|
87
94
|
response = Onelogin::Saml::Response.new(response_document)
|
@@ -127,7 +134,9 @@ class RubySamlTest < Test::Unit::TestCase
|
|
127
134
|
should "generate a correct logout request" do
|
128
135
|
logoutrequest = Onelogin::Saml::Logoutrequest.new
|
129
136
|
|
130
|
-
|
137
|
+
@settings.name_id = "demo"
|
138
|
+
@settings.sessionindex = "s2c8e391dbfcb2f71796595c803cf8b4079119ff01"
|
139
|
+
logout_xml = logoutrequest.xml(@settings, "test")
|
131
140
|
|
132
141
|
expected_xml = <<-EOF
|
133
142
|
<samlp:LogoutRequest xmlns:samlp=\"urn:oasis:names:tc:SAML:2.0:protocol\"
|
@@ -136,6 +145,7 @@ class RubySamlTest < Test::Unit::TestCase
|
|
136
145
|
<saml:NameID xmlns:saml=\"urn:oasis:names:tc:SAML:2.0:assertion\"
|
137
146
|
NameQualifier=\"sp name\"
|
138
147
|
Format=\"urn:oasis:names:tc:SAML:2.0:nameid-format:transient\">demo</saml:NameID>
|
148
|
+
<samlp:SessionIndex xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol">s2c8e391dbfcb2f71796595c803cf8b4079119ff01</samlp:SessionIndex>
|
139
149
|
</samlp:LogoutRequest>
|
140
150
|
EOF
|
141
151
|
|
@@ -145,9 +155,11 @@ class RubySamlTest < Test::Unit::TestCase
|
|
145
155
|
|
146
156
|
should "generate a correct request" do
|
147
157
|
logoutrequest = Onelogin::Saml::Logoutrequest.new
|
148
|
-
|
158
|
+
@settings.name_id = "demo"
|
159
|
+
@settings.sessionindex = "sessionindex"
|
160
|
+
logout_url = logoutrequest.create(@settings, {})
|
149
161
|
|
150
|
-
expected_url = "http://slotarget.com/?SAMLRequest=
|
162
|
+
expected_url = "http://slotarget.com/?SAMLRequest=nZJNa8MwDEDv%2FRXG92xZCKMxTWBQBoFusBV2VxxlGGI7sxToz18%2Bui1hWw%2FV%0A0ZbekywLMceOwLadOvh33%2FMrfvRILE62daSmm1z2wSkPZEg5sEiKtTo%2BPB1U%0AchOrLnj22rdyIxZR7nNZw31aYRVHCeg0iu8SjCDTWZRuK623mDVpWkvxhoGM%0Ad7kcYFKURD2Wjhgc55LNYGOwlSxW9O%2Bu1ZQfFt1ebhaIMPCgk4WZKne3C8x%2F%0AkueBU%2B6vkPzijTHSXnpoTWMw5JI6MSL%2Bzn30wQJf1o0npo6aKVVxAEcGHcui%0ARuvP880TrOc7r%2F2INL5%2F6Wo8XbH1guZ6M9bPtjXzR%2Fp1u%2FpoxeYT%0A"
|
151
163
|
assert_equal expected_url, logout_url
|
152
164
|
end
|
153
165
|
|
@@ -166,7 +178,7 @@ class RubySamlTest < Test::Unit::TestCase
|
|
166
178
|
<saml:Issuer xmlns:saml=\"urn:oasis:names:tc:SAML:2.0:assertion\">#{issuer}</saml:Issuer>
|
167
179
|
<samlp:Status xmlns:samlp=\"urn:oasis:names:tc:SAML:2.0:protocol\">
|
168
180
|
<samlp:StatusCode xmlns:samlp=\"urn:oasis:names:tc:SAML:2.0:protocol\"
|
169
|
-
Value=\"urn:oasis:names:tc:SAML:2.0:status:
|
181
|
+
Value=\"urn:oasis:names:tc:SAML:2.0:status:Success\">
|
170
182
|
</samlp:StatusCode>
|
171
183
|
</samlp:Status>
|
172
184
|
</samlp:LogoutResponse>"
|
@@ -177,6 +189,28 @@ class RubySamlTest < Test::Unit::TestCase
|
|
177
189
|
|
178
190
|
assert_equal logoutresponse.issuer, issuer
|
179
191
|
assert_equal logoutresponse.in_response_to, transaction_id
|
192
|
+
assert_equal true, logoutresponse.success?
|
193
|
+
end
|
194
|
+
|
195
|
+
should "validate the a failing response" do
|
196
|
+
|
197
|
+
|
198
|
+
logout_xml = "<samlp:LogoutResponse xmlns:samlp=\"urn:oasis:names:tc:SAML:2.0:protocol\"
|
199
|
+
ID=\"sedf164edc2121a23d4ca4b31d35261e5563dc352\" Version=\"2.0\"
|
200
|
+
IssueInstant=\"2011-03-07T14:43:34Z\" Destination=\"http://localhost:3000/saml/consume_logout\"
|
201
|
+
InResponseTo=\"adflkjalkfjalsdfjlaskjdf\">
|
202
|
+
<saml:Issuer xmlns:saml=\"urn:oasis:names:tc:SAML:2.0:assertion\">https://test-idp.test.no:443/issuer</saml:Issuer>
|
203
|
+
<samlp:Status xmlns:samlp=\"urn:oasis:names:tc:SAML:2.0:protocol\">
|
204
|
+
<samlp:StatusCode xmlns:samlp=\"urn:oasis:names:tc:SAML:2.0:protocol\"
|
205
|
+
Value=\"urn:oasis:names:tc:SAML:2.0:status:Requester\">
|
206
|
+
</samlp:StatusCode>
|
207
|
+
</samlp:Status>
|
208
|
+
</samlp:LogoutResponse>"
|
209
|
+
|
210
|
+
|
211
|
+
logoutresponse = Onelogin::Saml::Logoutresponse.new(encode(deflate(logout_xml)))
|
212
|
+
|
213
|
+
assert_equal false, logoutresponse.success?
|
180
214
|
end
|
181
215
|
end
|
182
216
|
|