savon 0.9.4 → 0.9.5
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/CHANGELOG.md +4 -0
- data/lib/savon/client.rb +4 -3
- data/lib/savon/core_ext/string.rb +0 -15
- data/lib/savon/version.rb +1 -1
- data/lib/savon/wasabi/document.rb +6 -6
- data/savon.gemspec +1 -0
- data/spec/savon/client_spec.rb +6 -28
- data/spec/savon/core_ext/string_spec.rb +0 -13
- data/spec/savon/soap/xml_spec.rb +4 -4
- metadata +32 -26
- data/lib/savon/core_ext/time.rb +0 -22
- data/lib/savon/wsse.rb +0 -156
- data/spec/fixtures/wsdl/geotrust.xml +0 -156
- data/spec/fixtures/wsdl/namespaced_actions.xml +0 -307
- data/spec/fixtures/wsdl/no_namespace.xml +0 -115
- data/spec/fixtures/wsdl/soap12.xml +0 -11
- data/spec/fixtures/wsdl/two_bindings.xml +0 -25
- data/spec/savon/core_ext/time_spec.rb +0 -13
- data/spec/savon/wsse_spec.rb +0 -233
data/CHANGELOG.md
CHANGED
data/lib/savon/client.rb
CHANGED
@@ -1,9 +1,10 @@
|
|
1
1
|
require "httpi/request"
|
2
|
+
require "akami"
|
3
|
+
|
2
4
|
require "savon/wasabi/document"
|
3
5
|
require "savon/soap/xml"
|
4
6
|
require "savon/soap/request"
|
5
7
|
require "savon/soap/response"
|
6
|
-
require "savon/wsse"
|
7
8
|
|
8
9
|
module Savon
|
9
10
|
|
@@ -44,9 +45,9 @@ module Savon
|
|
44
45
|
@http ||= HTTPI::Request.new
|
45
46
|
end
|
46
47
|
|
47
|
-
# Returns the <tt>
|
48
|
+
# Returns the <tt>Akami::WSSE</tt> object.
|
48
49
|
def wsse
|
49
|
-
@wsse ||=
|
50
|
+
@wsse ||= Akami.wsse
|
50
51
|
end
|
51
52
|
|
52
53
|
# Returns the <tt>Savon::SOAP::XML</tt> object. Please notice, that this object is only available
|
@@ -16,21 +16,6 @@ module Savon
|
|
16
16
|
str
|
17
17
|
end unless method_defined?(:snakecase)
|
18
18
|
|
19
|
-
# Returns the String in lowerCamelCase.
|
20
|
-
def lower_camelcase
|
21
|
-
str = dup
|
22
|
-
str.gsub!(/\/(.?)/) { "::#{$1.upcase}" }
|
23
|
-
str.gsub!(/(?:_+|-+)([a-z])/) { $1.upcase }
|
24
|
-
str.gsub!(/(\A|\s)([A-Z])/) { $1 + $2.downcase }
|
25
|
-
str
|
26
|
-
end
|
27
|
-
|
28
|
-
# Returns whether the String starts with a given +prefix+.
|
29
|
-
def starts_with?(prefix)
|
30
|
-
prefix = prefix.to_s
|
31
|
-
self[0, prefix.length] == prefix
|
32
|
-
end unless method_defined?(:starts_with?)
|
33
|
-
|
34
19
|
end
|
35
20
|
end
|
36
21
|
end
|
data/lib/savon/version.rb
CHANGED
@@ -6,7 +6,7 @@ module Savon
|
|
6
6
|
|
7
7
|
# = Savon::Wasabi::Document
|
8
8
|
#
|
9
|
-
# Extends the <tt>Wasabi::Document</tt>
|
9
|
+
# Extends the document handling of the <tt>Wasabi::Document</tt> by
|
10
10
|
# adding support for remote and local WSDL documents.
|
11
11
|
class Document < ::Wasabi::Document
|
12
12
|
|
@@ -15,6 +15,11 @@ module Savon
|
|
15
15
|
@xml ||= document.kind_of?(String) ? resolve_document : document
|
16
16
|
end
|
17
17
|
|
18
|
+
# Sets the <tt>HTTPI::Request</tt> for remote WSDL documents.
|
19
|
+
attr_writer :request
|
20
|
+
|
21
|
+
private
|
22
|
+
|
18
23
|
# Sets up and returns the <tt>HTTPI::Request</tt>.
|
19
24
|
def request
|
20
25
|
@request ||= HTTPI::Request.new
|
@@ -22,11 +27,6 @@ module Savon
|
|
22
27
|
@request
|
23
28
|
end
|
24
29
|
|
25
|
-
# Sets the <tt>HTTPI::Request</tt> for remote WSDL documents.
|
26
|
-
attr_writer :request
|
27
|
-
|
28
|
-
private
|
29
|
-
|
30
30
|
# Resolves and returns the raw WSDL document.
|
31
31
|
def resolve_document
|
32
32
|
case document
|
data/savon.gemspec
CHANGED
@@ -18,6 +18,7 @@ Gem::Specification.new do |s|
|
|
18
18
|
s.add_dependency "nori", "~> 1.0"
|
19
19
|
s.add_dependency "httpi", "~> 0.9"
|
20
20
|
s.add_dependency "wasabi", "~> 1.0"
|
21
|
+
s.add_dependency "akami", "~> 1.0"
|
21
22
|
s.add_dependency "gyoku", ">= 0.4.0"
|
22
23
|
s.add_dependency "nokogiri", ">= 1.4.0"
|
23
24
|
|
data/spec/savon/client_spec.rb
CHANGED
@@ -32,7 +32,7 @@ describe Savon::Client do
|
|
32
32
|
Savon::Client.new do |wsdl, http, wsse|
|
33
33
|
wsdl.should be_an(Savon::Wasabi::Document)
|
34
34
|
http.should be_an(HTTPI::Request)
|
35
|
-
wsse.should be_an(
|
35
|
+
wsse.should be_an(Akami::WSSE)
|
36
36
|
end
|
37
37
|
end
|
38
38
|
end
|
@@ -47,7 +47,7 @@ describe Savon::Client do
|
|
47
47
|
end
|
48
48
|
|
49
49
|
it "should let you access the WSSE object" do
|
50
|
-
Savon::Client.new { wsse.should be_a(
|
50
|
+
Savon::Client.new { wsse.should be_a(Akami::WSSE) }
|
51
51
|
end
|
52
52
|
end
|
53
53
|
end
|
@@ -65,8 +65,8 @@ describe Savon::Client do
|
|
65
65
|
end
|
66
66
|
|
67
67
|
describe "#wsse" do
|
68
|
-
it "should return the
|
69
|
-
client.wsse.should be_a(
|
68
|
+
it "should return the Akami::WSSE object" do
|
69
|
+
client.wsse.should be_a(Akami::WSSE)
|
70
70
|
end
|
71
71
|
end
|
72
72
|
|
@@ -171,7 +171,7 @@ describe Savon::Client do
|
|
171
171
|
soap.should be_a(Savon::SOAP::XML)
|
172
172
|
wsdl.should be_a(Savon::Wasabi::Document)
|
173
173
|
http.should be_an(HTTPI::Request)
|
174
|
-
wsse.should be_a(
|
174
|
+
wsse.should be_a(Akami::WSSE)
|
175
175
|
end
|
176
176
|
end
|
177
177
|
end
|
@@ -186,7 +186,7 @@ describe Savon::Client do
|
|
186
186
|
end
|
187
187
|
|
188
188
|
it "should let you access the WSSE object" do
|
189
|
-
client.request(:authenticate) { wsse.should be_a(
|
189
|
+
client.request(:authenticate) { wsse.should be_a(Akami::WSSE) }
|
190
190
|
end
|
191
191
|
|
192
192
|
it "should let you access the WSDL object" do
|
@@ -222,10 +222,6 @@ describe Savon::Client do
|
|
222
222
|
let(:client) { Savon::Client.new { wsdl.document = Endpoint.wsdl } }
|
223
223
|
before { HTTPI.expects(:get).returns(new_response(:body => Fixture.wsdl(:authentication))) }
|
224
224
|
|
225
|
-
it "should return a list of available SOAP actions" do
|
226
|
-
client.wsdl.soap_actions.should == [:authenticate]
|
227
|
-
end
|
228
|
-
|
229
225
|
it "adds a SOAPAction header containing the SOAP action name" do
|
230
226
|
HTTPI.stubs(:post).returns(new_response)
|
231
227
|
|
@@ -248,10 +244,6 @@ describe Savon::Client do
|
|
248
244
|
|
249
245
|
before { HTTPI.expects(:get).never }
|
250
246
|
|
251
|
-
it "should return a list of available SOAP actions" do
|
252
|
-
client.wsdl.soap_actions.should == [:authenticate]
|
253
|
-
end
|
254
|
-
|
255
247
|
it "adds a SOAPAction header containing the SOAP action name" do
|
256
248
|
HTTPI.stubs(:post).returns(new_response)
|
257
249
|
|
@@ -260,13 +252,6 @@ describe Savon::Client do
|
|
260
252
|
end
|
261
253
|
end
|
262
254
|
|
263
|
-
it "should get #element_form_default from the WSDL" do
|
264
|
-
HTTPI.stubs(:post).returns(new_response)
|
265
|
-
Savon::Wasabi::Document.any_instance.expects(:element_form_default).returns(:qualified)
|
266
|
-
|
267
|
-
client.request :authenticate
|
268
|
-
end
|
269
|
-
|
270
255
|
it "should execute SOAP requests and return the response" do
|
271
256
|
HTTPI.expects(:post).returns(new_response)
|
272
257
|
response = client.request(:authenticate)
|
@@ -298,13 +283,6 @@ describe Savon::Client do
|
|
298
283
|
end
|
299
284
|
end
|
300
285
|
|
301
|
-
it "should not get #element_form_default from the WSDL" do
|
302
|
-
HTTPI.stubs(:post).returns(new_response)
|
303
|
-
Savon::Wasabi::Document.any_instance.expects(:element_form_default).never
|
304
|
-
|
305
|
-
client.request :authenticate
|
306
|
-
end
|
307
|
-
|
308
286
|
it "should execute SOAP requests and return the response" do
|
309
287
|
HTTPI.expects(:post).returns(new_response)
|
310
288
|
response = client.request(:authenticate)
|
@@ -34,17 +34,4 @@ describe String do
|
|
34
34
|
end
|
35
35
|
end
|
36
36
|
|
37
|
-
describe "lower_camelcase" do
|
38
|
-
it "converts a snakecase String to lowerCamelCase" do
|
39
|
-
"lower_camel_case".lower_camelcase.should == "lowerCamelCase"
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
describe "starts_with?" do
|
44
|
-
it "should return whether it starts with a given suffix" do
|
45
|
-
"authenticate".starts_with?("auth").should be_true
|
46
|
-
"authenticate".starts_with?("cate").should be_false
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
37
|
end
|
data/spec/savon/soap/xml_spec.rb
CHANGED
@@ -98,9 +98,9 @@ describe Savon::SOAP::XML do
|
|
98
98
|
end
|
99
99
|
|
100
100
|
describe "#wsse" do
|
101
|
-
it "should set the
|
102
|
-
xml.wsse =
|
103
|
-
xml.wsse.should be_a(
|
101
|
+
it "should set the Akami::WSSE object" do
|
102
|
+
xml.wsse = Akami.wsse
|
103
|
+
xml.wsse.should be_a(Akami::WSSE)
|
104
104
|
end
|
105
105
|
end
|
106
106
|
|
@@ -235,7 +235,7 @@ describe Savon::SOAP::XML do
|
|
235
235
|
|
236
236
|
context "with WSSE authentication" do
|
237
237
|
it "should containg a SOAP header with WSSE authentication details" do
|
238
|
-
xml.wsse =
|
238
|
+
xml.wsse = Akami.wsse
|
239
239
|
xml.wsse.credentials "username", "password"
|
240
240
|
|
241
241
|
xml.to_xml.should include("<env:Header><wsse:Security")
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: savon
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 49
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 9
|
9
|
-
-
|
10
|
-
version: 0.9.
|
9
|
+
- 5
|
10
|
+
version: 0.9.5
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Daniel Harrington
|
@@ -79,9 +79,24 @@ dependencies:
|
|
79
79
|
type: :runtime
|
80
80
|
version_requirements: *id004
|
81
81
|
- !ruby/object:Gem::Dependency
|
82
|
-
name:
|
82
|
+
name: akami
|
83
83
|
prerelease: false
|
84
84
|
requirement: &id005 !ruby/object:Gem::Requirement
|
85
|
+
none: false
|
86
|
+
requirements:
|
87
|
+
- - ~>
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
hash: 15
|
90
|
+
segments:
|
91
|
+
- 1
|
92
|
+
- 0
|
93
|
+
version: "1.0"
|
94
|
+
type: :runtime
|
95
|
+
version_requirements: *id005
|
96
|
+
- !ruby/object:Gem::Dependency
|
97
|
+
name: gyoku
|
98
|
+
prerelease: false
|
99
|
+
requirement: &id006 !ruby/object:Gem::Requirement
|
85
100
|
none: false
|
86
101
|
requirements:
|
87
102
|
- - ">="
|
@@ -93,11 +108,11 @@ dependencies:
|
|
93
108
|
- 0
|
94
109
|
version: 0.4.0
|
95
110
|
type: :runtime
|
96
|
-
version_requirements: *
|
111
|
+
version_requirements: *id006
|
97
112
|
- !ruby/object:Gem::Dependency
|
98
113
|
name: nokogiri
|
99
114
|
prerelease: false
|
100
|
-
requirement: &
|
115
|
+
requirement: &id007 !ruby/object:Gem::Requirement
|
101
116
|
none: false
|
102
117
|
requirements:
|
103
118
|
- - ">="
|
@@ -109,11 +124,11 @@ dependencies:
|
|
109
124
|
- 0
|
110
125
|
version: 1.4.0
|
111
126
|
type: :runtime
|
112
|
-
version_requirements: *
|
127
|
+
version_requirements: *id007
|
113
128
|
- !ruby/object:Gem::Dependency
|
114
129
|
name: rake
|
115
130
|
prerelease: false
|
116
|
-
requirement: &
|
131
|
+
requirement: &id008 !ruby/object:Gem::Requirement
|
117
132
|
none: false
|
118
133
|
requirements:
|
119
134
|
- - ~>
|
@@ -125,11 +140,11 @@ dependencies:
|
|
125
140
|
- 7
|
126
141
|
version: 0.8.7
|
127
142
|
type: :development
|
128
|
-
version_requirements: *
|
143
|
+
version_requirements: *id008
|
129
144
|
- !ruby/object:Gem::Dependency
|
130
145
|
name: rspec
|
131
146
|
prerelease: false
|
132
|
-
requirement: &
|
147
|
+
requirement: &id009 !ruby/object:Gem::Requirement
|
133
148
|
none: false
|
134
149
|
requirements:
|
135
150
|
- - ~>
|
@@ -141,11 +156,11 @@ dependencies:
|
|
141
156
|
- 0
|
142
157
|
version: 2.5.0
|
143
158
|
type: :development
|
144
|
-
version_requirements: *
|
159
|
+
version_requirements: *id009
|
145
160
|
- !ruby/object:Gem::Dependency
|
146
161
|
name: mocha
|
147
162
|
prerelease: false
|
148
|
-
requirement: &
|
163
|
+
requirement: &id010 !ruby/object:Gem::Requirement
|
149
164
|
none: false
|
150
165
|
requirements:
|
151
166
|
- - ~>
|
@@ -157,11 +172,11 @@ dependencies:
|
|
157
172
|
- 8
|
158
173
|
version: 0.9.8
|
159
174
|
type: :development
|
160
|
-
version_requirements: *
|
175
|
+
version_requirements: *id010
|
161
176
|
- !ruby/object:Gem::Dependency
|
162
177
|
name: timecop
|
163
178
|
prerelease: false
|
164
|
-
requirement: &
|
179
|
+
requirement: &id011 !ruby/object:Gem::Requirement
|
165
180
|
none: false
|
166
181
|
requirements:
|
167
182
|
- - ~>
|
@@ -173,11 +188,11 @@ dependencies:
|
|
173
188
|
- 5
|
174
189
|
version: 0.3.5
|
175
190
|
type: :development
|
176
|
-
version_requirements: *
|
191
|
+
version_requirements: *id011
|
177
192
|
- !ruby/object:Gem::Dependency
|
178
193
|
name: autotest
|
179
194
|
prerelease: false
|
180
|
-
requirement: &
|
195
|
+
requirement: &id012 !ruby/object:Gem::Requirement
|
181
196
|
none: false
|
182
197
|
requirements:
|
183
198
|
- - ">="
|
@@ -187,7 +202,7 @@ dependencies:
|
|
187
202
|
- 0
|
188
203
|
version: "0"
|
189
204
|
type: :development
|
190
|
-
version_requirements: *
|
205
|
+
version_requirements: *id012
|
191
206
|
description: Ruby's heavy metal SOAP client
|
192
207
|
email: me@rubiii.com
|
193
208
|
executables: []
|
@@ -210,7 +225,6 @@ files:
|
|
210
225
|
- lib/savon/client.rb
|
211
226
|
- lib/savon/core_ext/object.rb
|
212
227
|
- lib/savon/core_ext/string.rb
|
213
|
-
- lib/savon/core_ext/time.rb
|
214
228
|
- lib/savon/error.rb
|
215
229
|
- lib/savon/global.rb
|
216
230
|
- lib/savon/http/error.rb
|
@@ -221,7 +235,6 @@ files:
|
|
221
235
|
- lib/savon/soap/xml.rb
|
222
236
|
- lib/savon/version.rb
|
223
237
|
- lib/savon/wasabi/document.rb
|
224
|
-
- lib/savon/wsse.rb
|
225
238
|
- savon.gemspec
|
226
239
|
- spec/fixtures/gzip/message.gz
|
227
240
|
- spec/fixtures/response/another_soap_fault.xml
|
@@ -232,15 +245,9 @@ files:
|
|
232
245
|
- spec/fixtures/response/soap_fault.xml
|
233
246
|
- spec/fixtures/response/soap_fault12.xml
|
234
247
|
- spec/fixtures/wsdl/authentication.xml
|
235
|
-
- spec/fixtures/wsdl/geotrust.xml
|
236
|
-
- spec/fixtures/wsdl/namespaced_actions.xml
|
237
|
-
- spec/fixtures/wsdl/no_namespace.xml
|
238
|
-
- spec/fixtures/wsdl/soap12.xml
|
239
|
-
- spec/fixtures/wsdl/two_bindings.xml
|
240
248
|
- spec/savon/client_spec.rb
|
241
249
|
- spec/savon/core_ext/object_spec.rb
|
242
250
|
- spec/savon/core_ext/string_spec.rb
|
243
|
-
- spec/savon/core_ext/time_spec.rb
|
244
251
|
- spec/savon/http/error_spec.rb
|
245
252
|
- spec/savon/savon_spec.rb
|
246
253
|
- spec/savon/soap/fault_spec.rb
|
@@ -249,7 +256,6 @@ files:
|
|
249
256
|
- spec/savon/soap/xml_spec.rb
|
250
257
|
- spec/savon/soap_spec.rb
|
251
258
|
- spec/savon/wasabi/document_spec.rb
|
252
|
-
- spec/savon/wsse_spec.rb
|
253
259
|
- spec/spec_helper.rb
|
254
260
|
- spec/support/endpoint.rb
|
255
261
|
- spec/support/fixture.rb
|
data/lib/savon/core_ext/time.rb
DELETED
@@ -1,22 +0,0 @@
|
|
1
|
-
module Savon
|
2
|
-
module CoreExt
|
3
|
-
module Time
|
4
|
-
|
5
|
-
# Returns an xs:dateTime formatted String.
|
6
|
-
def xs_datetime
|
7
|
-
zone = if utc_offset < 0
|
8
|
-
"-#{"%02d" % (- utc_offset / 3600)}:#{"%02d" % ((- utc_offset % 3600) / 60)}"
|
9
|
-
elsif utc_offset > 0
|
10
|
-
"+#{"%02d" % (utc_offset / 3600)}:#{"%02d" % ((utc_offset % 3600) / 60)}"
|
11
|
-
else
|
12
|
-
"Z"
|
13
|
-
end
|
14
|
-
|
15
|
-
strftime "%Y-%m-%dT%H:%M:%S#{zone}"
|
16
|
-
end
|
17
|
-
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
Time.send :include, Savon::CoreExt::Time
|
data/lib/savon/wsse.rb
DELETED
@@ -1,156 +0,0 @@
|
|
1
|
-
require "base64"
|
2
|
-
require "digest/sha1"
|
3
|
-
|
4
|
-
require "savon/core_ext/string"
|
5
|
-
require "savon/core_ext/time"
|
6
|
-
|
7
|
-
module Savon
|
8
|
-
|
9
|
-
# = Savon::WSSE
|
10
|
-
#
|
11
|
-
# Provides WSSE authentication.
|
12
|
-
class WSSE
|
13
|
-
|
14
|
-
# Namespace for WS Security Secext.
|
15
|
-
WSENamespace = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
|
16
|
-
|
17
|
-
# Namespace for WS Security Utility.
|
18
|
-
WSUNamespace = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
|
19
|
-
|
20
|
-
# URI for "wsse:Password/@Type" #PasswordText.
|
21
|
-
PasswordTextURI = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText"
|
22
|
-
|
23
|
-
# URI for "wsse:Password/@Type" #PasswordDigest.
|
24
|
-
PasswordDigestURI = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest"
|
25
|
-
|
26
|
-
# Returns a value from the WSSE Hash.
|
27
|
-
def [](key)
|
28
|
-
hash[key]
|
29
|
-
end
|
30
|
-
|
31
|
-
# Sets a value on the WSSE Hash.
|
32
|
-
def []=(key, value)
|
33
|
-
hash[key] = value
|
34
|
-
end
|
35
|
-
|
36
|
-
# Sets authentication credentials for a wsse:UsernameToken header.
|
37
|
-
# Also accepts whether to use WSSE digest authentication.
|
38
|
-
def credentials(username, password, digest = false)
|
39
|
-
self.username = username
|
40
|
-
self.password = password
|
41
|
-
self.digest = digest
|
42
|
-
end
|
43
|
-
|
44
|
-
attr_accessor :username, :password, :created_at, :expires_at
|
45
|
-
|
46
|
-
# Returns whether to use WSSE digest. Defaults to +false+.
|
47
|
-
def digest?
|
48
|
-
!!@digest
|
49
|
-
end
|
50
|
-
|
51
|
-
attr_writer :digest
|
52
|
-
|
53
|
-
# Returns whether to generate a wsse:UsernameToken header.
|
54
|
-
def username_token?
|
55
|
-
username && password
|
56
|
-
end
|
57
|
-
|
58
|
-
# Returns whether to generate a wsu:Timestamp header.
|
59
|
-
def timestamp?
|
60
|
-
created_at || expires_at || @wsu_timestamp
|
61
|
-
end
|
62
|
-
|
63
|
-
# Sets whether to generate a wsu:Timestamp header.
|
64
|
-
def timestamp=(timestamp)
|
65
|
-
@wsu_timestamp = timestamp
|
66
|
-
end
|
67
|
-
|
68
|
-
# Returns the XML for a WSSE header.
|
69
|
-
def to_xml
|
70
|
-
if username_token? && timestamp?
|
71
|
-
Gyoku.xml wsse_username_token.merge!(wsu_timestamp) {
|
72
|
-
|key, v1, v2| v1.merge!(v2) {
|
73
|
-
|key, v1, v2| v1.merge!(v2)
|
74
|
-
}
|
75
|
-
}
|
76
|
-
elsif username_token?
|
77
|
-
Gyoku.xml wsse_username_token.merge!(hash)
|
78
|
-
elsif timestamp?
|
79
|
-
Gyoku.xml wsu_timestamp.merge!(hash)
|
80
|
-
else
|
81
|
-
""
|
82
|
-
end
|
83
|
-
end
|
84
|
-
|
85
|
-
private
|
86
|
-
|
87
|
-
# Returns a Hash containing wsse:UsernameToken details.
|
88
|
-
def wsse_username_token
|
89
|
-
if digest?
|
90
|
-
security_hash :wsse, "UsernameToken",
|
91
|
-
"wsse:Username" => username,
|
92
|
-
"wsse:Nonce" => nonce,
|
93
|
-
"wsu:Created" => timestamp,
|
94
|
-
"wsse:Password" => digest_password,
|
95
|
-
:attributes! => { "wsse:Password" => { "Type" => PasswordDigestURI } }
|
96
|
-
else
|
97
|
-
security_hash :wsse, "UsernameToken",
|
98
|
-
"wsse:Username" => username,
|
99
|
-
"wsse:Password" => password,
|
100
|
-
:attributes! => { "wsse:Password" => { "Type" => PasswordTextURI } }
|
101
|
-
end
|
102
|
-
end
|
103
|
-
|
104
|
-
# Returns a Hash containing wsu:Timestamp details.
|
105
|
-
def wsu_timestamp
|
106
|
-
security_hash :wsu, "Timestamp",
|
107
|
-
"wsu:Created" => (created_at || Time.now).xs_datetime,
|
108
|
-
"wsu:Expires" => (expires_at || (created_at || Time.now) + 60).xs_datetime
|
109
|
-
end
|
110
|
-
|
111
|
-
# Returns a Hash containing wsse/wsu Security details for a given
|
112
|
-
# +namespace+, +tag+ and +hash+.
|
113
|
-
def security_hash(namespace, tag, hash)
|
114
|
-
{
|
115
|
-
"wsse:Security" => {
|
116
|
-
"#{namespace}:#{tag}" => hash,
|
117
|
-
:attributes! => { "#{namespace}:#{tag}" => { "wsu:Id" => "#{tag}-#{count}", "xmlns:wsu" => WSUNamespace } }
|
118
|
-
},
|
119
|
-
:attributes! => { "wsse:Security" => { "xmlns:wsse" => WSENamespace } }
|
120
|
-
}
|
121
|
-
end
|
122
|
-
|
123
|
-
# Returns the WSSE password, encrypted for digest authentication.
|
124
|
-
def digest_password
|
125
|
-
token = nonce + timestamp + password
|
126
|
-
Base64.encode64(Digest::SHA1.hexdigest(token)).chomp!
|
127
|
-
end
|
128
|
-
|
129
|
-
# Returns a WSSE nonce.
|
130
|
-
def nonce
|
131
|
-
@nonce ||= Digest::SHA1.hexdigest random_string + timestamp
|
132
|
-
end
|
133
|
-
|
134
|
-
# Returns a random String of 100 characters.
|
135
|
-
def random_string
|
136
|
-
(0...100).map { ("a".."z").to_a[rand(26)] }.join
|
137
|
-
end
|
138
|
-
|
139
|
-
# Returns a WSSE timestamp.
|
140
|
-
def timestamp
|
141
|
-
@timestamp ||= Time.now.xs_datetime
|
142
|
-
end
|
143
|
-
|
144
|
-
# Returns a new number with every call.
|
145
|
-
def count
|
146
|
-
@count ||= 0
|
147
|
-
@count += 1
|
148
|
-
end
|
149
|
-
|
150
|
-
# Returns a memoized and autovivificating Hash.
|
151
|
-
def hash
|
152
|
-
@hash ||= Hash.new { |h, k| h[k] = Hash.new(&h.default_proc) }
|
153
|
-
end
|
154
|
-
|
155
|
-
end
|
156
|
-
end
|