wash_out 0.10.0 → 0.12.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.
- checksums.yaml +4 -4
- data/.travis.yml +3 -18
- data/Appraisals +11 -10
- data/Gemfile +3 -1
- data/README.md +47 -7
- data/Rakefile +13 -2
- data/app/helpers/wash_out_helper.rb +13 -7
- data/app/views/wash_out/document/response.builder +7 -0
- data/app/views/wash_out/document/wsdl.builder +1 -1
- data/app/views/wash_out/rpc/response.builder +8 -1
- data/app/views/wash_out/rpc/wsdl.builder +1 -1
- data/gemfiles/{rails_3.2.12.gemfile → rails_3.2.13.gemfile} +2 -1
- data/gemfiles/rails_4.0.0.gemfile +3 -1
- data/gemfiles/rails_4.1.0.gemfile +3 -1
- data/gemfiles/rails_4.2.0.gemfile +3 -1
- data/gemfiles/{rails_3.1.3.gemfile → rails_5.0.0.beta2.gemfile} +1 -2
- data/gemfiles/rails_5.0.0.gemfile +20 -0
- data/gemfiles/rails_5.1.1.gemfile +20 -0
- data/lib/wash_out/dispatcher.rb +75 -23
- data/lib/wash_out/engine.rb +1 -2
- data/lib/wash_out/router.rb +50 -17
- data/lib/wash_out/soap.rb +10 -0
- data/lib/wash_out/version.rb +1 -1
- data/lib/wash_out/wsse.rb +32 -27
- data/lib/wash_out.rb +28 -5
- data/spec/dummy/app/controllers/application_controller.rb +1 -1
- data/spec/fixtures/nested_refs_to_arrays.xml +19 -0
- data/spec/fixtures/ref_to_one_array.xml +11 -0
- data/spec/fixtures/refs_to_arrays.xml +16 -0
- data/spec/lib/wash_out/dispatcher_spec.rb +113 -6
- data/spec/lib/wash_out/router_spec.rb +33 -5
- data/spec/lib/wash_out_spec.rb +306 -19
- data/spec/spec_helper.rb +25 -5
- metadata +10 -5
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 4fceeab03335d36c3f64b930cc9380f02f8ce364
|
|
4
|
+
data.tar.gz: c3001962354e7327d218defdc575d4a108c2a002
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: af7895f5b669386339ca1c26ff772764a3722e71ae9befeb759d4993be89a522c839c524682362d7c4d1250b46343cc3d5bf7847ed8c74c49d52278e909f4866
|
|
7
|
+
data.tar.gz: c8c62b42781fe3926f6680edddf50d87ab9f886a30f910815e32aff10527e134ea34d1e6b78535d961b49c5fa4adda4bc34cff4e4b94cf6ec9c0b15207d21d63
|
data/.travis.yml
CHANGED
|
@@ -1,26 +1,11 @@
|
|
|
1
1
|
script: bundle exec rspec
|
|
2
2
|
gemfile:
|
|
3
|
-
- gemfiles/rails_3.1.3.gemfile
|
|
4
|
-
- gemfiles/rails_3.2.12.gemfile
|
|
5
3
|
- gemfiles/rails_4.0.0.gemfile
|
|
6
4
|
- gemfiles/rails_4.1.0.gemfile
|
|
7
5
|
- gemfiles/rails_4.2.0.gemfile
|
|
6
|
+
- gemfiles/rails_5.0.0.gemfile
|
|
7
|
+
- gemfiles/rails_5.1.1.gemfile
|
|
8
8
|
rvm:
|
|
9
|
-
- 1.9.3
|
|
10
|
-
- 2.0.0
|
|
11
|
-
- 2.1.8
|
|
12
|
-
- 2.2.4
|
|
13
9
|
- 2.3.0
|
|
14
|
-
- jruby
|
|
15
|
-
matrix:
|
|
16
|
-
exclude:
|
|
17
|
-
- rvm: 2.2.4
|
|
18
|
-
gemfile: gemfiles/rails_3.1.3.gemfile
|
|
19
|
-
- rvm: 2.2.4
|
|
20
|
-
gemfile: gemfiles/rails_3.2.12.gemfile
|
|
21
|
-
- rvm: 2.3.0
|
|
22
|
-
gemfile: gemfiles/rails_3.1.3.gemfile
|
|
23
|
-
- rvm: 2.3.0
|
|
24
|
-
gemfile: gemfiles/rails_3.2.12.gemfile
|
|
25
10
|
before_install:
|
|
26
|
-
- gem update bundler
|
|
11
|
+
- gem update bundler
|
data/Appraisals
CHANGED
|
@@ -1,21 +1,22 @@
|
|
|
1
|
-
appraise "rails-3.1.3" do
|
|
2
|
-
gem "rails", "3.1.3"
|
|
3
|
-
gem "test-unit"
|
|
4
|
-
end
|
|
5
|
-
|
|
6
|
-
appraise "rails-3.2.12" do
|
|
7
|
-
gem "rails", "3.2.12"
|
|
8
|
-
gem "test-unit"
|
|
9
|
-
end
|
|
10
|
-
|
|
11
1
|
appraise "rails-4.0.0" do
|
|
12
2
|
gem "rails", "4.0.0"
|
|
3
|
+
gem "listen", "< 3.1.0"
|
|
13
4
|
end
|
|
14
5
|
|
|
15
6
|
appraise "rails-4.1.0" do
|
|
16
7
|
gem "rails", "4.1.0"
|
|
8
|
+
gem "listen", "< 3.1.0"
|
|
17
9
|
end
|
|
18
10
|
|
|
19
11
|
appraise "rails-4.2.0" do
|
|
20
12
|
gem "rails", "4.2.0"
|
|
13
|
+
gem "listen", "< 3.1.0"
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
appraise "rails-5.0.0" do
|
|
17
|
+
gem "rails", "5.0.0"
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
appraise "rails-5.1.1" do
|
|
21
|
+
gem "rails", "5.1.1"
|
|
21
22
|
end
|
data/Gemfile
CHANGED
data/README.md
CHANGED
|
@@ -10,11 +10,7 @@ But if you have a chance, please [http://stopsoap.com/](http://stopsoap.com/).
|
|
|
10
10
|
|
|
11
11
|
## Compatibility
|
|
12
12
|
|
|
13
|
-
Rails
|
|
14
|
-
|
|
15
|
-
Ruby 1.8 is not officially supported since 0.5.3. We will accept further compatibilty pull-requests but no upcoming versions will be tested against it.
|
|
16
|
-
|
|
17
|
-
Rubinius support temporarily dropped since 0.6.2 due to Rails 4 incompatibility.
|
|
13
|
+
Rails 4.0 and higher is tested. Code is known to work with earlier versions but we don't bother testing outdated versions anymore - give it a try if you are THAT unlucky.
|
|
18
14
|
|
|
19
15
|
## Installation
|
|
20
16
|
|
|
@@ -75,7 +71,7 @@ class RumbasController < ApplicationController
|
|
|
75
71
|
:args => { :data => [:integer] },
|
|
76
72
|
:return => [:boolean]
|
|
77
73
|
def integers_to_boolean
|
|
78
|
-
render :soap => params[:data].map{|
|
|
74
|
+
render :soap => params[:data].map{|i| i > 0}
|
|
79
75
|
end
|
|
80
76
|
|
|
81
77
|
# Params from XML attributes;
|
|
@@ -122,6 +118,50 @@ class RumbasController < ApplicationController
|
|
|
122
118
|
def dump_parameters
|
|
123
119
|
Rails.logger.debug params.inspect
|
|
124
120
|
end
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
# Rendering SOAP headers
|
|
124
|
+
soap_action "integer_to_header_string",
|
|
125
|
+
:args => :integer,
|
|
126
|
+
:return => :string,
|
|
127
|
+
:header_return => :string
|
|
128
|
+
def integer_to_header_string
|
|
129
|
+
render :soap => params[:value].to_s, :header => (params[:value]+1).to_s
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
# Reading SOAP Headers
|
|
133
|
+
# This is different than normal SOAP params, because we don't specify the incoming format of the header,
|
|
134
|
+
# but we can still access it through `soap_request.headers`. Note that the values are all strings or hashes.
|
|
135
|
+
soap_action "AddCircleWithHeaderRadius",
|
|
136
|
+
:args => { :circle => { :center => { :x => :integer,
|
|
137
|
+
:y => :integer } } },
|
|
138
|
+
:return => nil, # [] for wash_out below 0.3.0
|
|
139
|
+
:to => :add_circle
|
|
140
|
+
# e.g. for a request to the 'AddCircleWithHeaderRadius' action:
|
|
141
|
+
# <soapenv:Envelope>
|
|
142
|
+
# <soap:Header>
|
|
143
|
+
# <radius>12345</radius>
|
|
144
|
+
# </soap:Header>
|
|
145
|
+
# <soapenv:Body>
|
|
146
|
+
# <AddCircle>
|
|
147
|
+
# <Circle radius="5.0">
|
|
148
|
+
# <Center x="10" y="12" />
|
|
149
|
+
# </Circle>
|
|
150
|
+
# </AddCircle>
|
|
151
|
+
# </soapenv:Body>
|
|
152
|
+
# </soapenv:Envelope>
|
|
153
|
+
def add_circle_with_header_radius
|
|
154
|
+
circle = params[:circle]
|
|
155
|
+
radius = soap_request.headers[:radius]
|
|
156
|
+
raise SOAPError, "radius must be specified in the SOAP header" if radius.blank?
|
|
157
|
+
radius = radius.to_f
|
|
158
|
+
raise SOAPError, "radius is too small" if radius < 3.0
|
|
159
|
+
|
|
160
|
+
Circle.new(circle[:center][:x], circle[:center][:y], radius)
|
|
161
|
+
|
|
162
|
+
render :soap => nil
|
|
163
|
+
end
|
|
164
|
+
|
|
125
165
|
end
|
|
126
166
|
```
|
|
127
167
|
|
|
@@ -160,7 +200,7 @@ inside separate classes for the complex ones. Here's the way to do that:
|
|
|
160
200
|
class Fluffy < WashOut::Type
|
|
161
201
|
map :universe => {
|
|
162
202
|
:name => :string,
|
|
163
|
-
:age => :
|
|
203
|
+
:age => :integer
|
|
164
204
|
}
|
|
165
205
|
end
|
|
166
206
|
|
data/Rakefile
CHANGED
|
@@ -3,11 +3,22 @@ require 'bundler/gem_tasks'
|
|
|
3
3
|
require 'appraisal'
|
|
4
4
|
require 'rspec/core/rake_task'
|
|
5
5
|
|
|
6
|
-
RSpec::Core::RakeTask.new
|
|
6
|
+
RSpec::Core::RakeTask.new
|
|
7
7
|
|
|
8
8
|
task :console do
|
|
9
9
|
require "action_controller/railtie"
|
|
10
10
|
require "rails/test_unit/railtie"
|
|
11
11
|
Bundler.require
|
|
12
12
|
binding.pry
|
|
13
|
-
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
desc 'Default: run the unit tests.'
|
|
17
|
+
task default: [:all]
|
|
18
|
+
|
|
19
|
+
desc 'Test the plugin under all supported Rails versions.'
|
|
20
|
+
task :all do |_t|
|
|
21
|
+
# this is needed for minitest because it does not support "--pattern" option as Rspec Does
|
|
22
|
+
ENV['SPEC'] = '--name=spec/**{,/*/**}/*_spec.rb'
|
|
23
|
+
exec('bundle exec appraisal install && bundle exec rake appraisal spec')
|
|
24
|
+
end
|
|
@@ -3,9 +3,15 @@ module WashOutHelper
|
|
|
3
3
|
def wsdl_data_options(param)
|
|
4
4
|
case controller.soap_config.wsdl_style
|
|
5
5
|
when 'rpc'
|
|
6
|
-
|
|
6
|
+
if param.map.present? || !param.value.nil?
|
|
7
|
+
{ :"xsi:type" => param.namespaced_type }
|
|
8
|
+
else
|
|
9
|
+
{ :"xsi:nil" => true }
|
|
10
|
+
end
|
|
7
11
|
when 'document'
|
|
8
|
-
{
|
|
12
|
+
{}
|
|
13
|
+
else
|
|
14
|
+
{}
|
|
9
15
|
end
|
|
10
16
|
end
|
|
11
17
|
|
|
@@ -96,11 +102,11 @@ module WashOutHelper
|
|
|
96
102
|
end
|
|
97
103
|
|
|
98
104
|
def wsdl_occurence(param, inject, extend_with = {})
|
|
99
|
-
data =
|
|
100
|
-
|
|
101
|
-
"#{'xsi:' if inject}
|
|
102
|
-
|
|
103
|
-
|
|
105
|
+
data = {"#{'xsi:' if inject}nillable" => 'true'}
|
|
106
|
+
if param.multiplied
|
|
107
|
+
data["#{'xsi:' if inject}minOccurs"] = 0
|
|
108
|
+
data["#{'xsi:' if inject}maxOccurs"] = 'unbounded'
|
|
109
|
+
end
|
|
104
110
|
extend_with.merge(data)
|
|
105
111
|
end
|
|
106
112
|
end
|
|
@@ -2,6 +2,13 @@ xml.instruct!
|
|
|
2
2
|
xml.tag! "soap:Envelope", "xmlns:soap" => 'http://schemas.xmlsoap.org/soap/envelope/',
|
|
3
3
|
"xmlns:xsd" => 'http://www.w3.org/2001/XMLSchema',
|
|
4
4
|
"xmlns:tns" => @namespace do
|
|
5
|
+
if !header.nil?
|
|
6
|
+
xml.tag! "soap:Header" do
|
|
7
|
+
xml.tag! "tns:#{@action_spec[:response_tag]}" do
|
|
8
|
+
wsdl_data xml, header
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
end
|
|
5
12
|
xml.tag! "soap:Body" do
|
|
6
13
|
xml.tag! "tns:#{@action_spec[:response_tag]}" do
|
|
7
14
|
wsdl_data xml, result
|
|
@@ -62,7 +62,7 @@ xml.definitions 'xmlns' => 'http://schemas.xmlsoap.org/wsdl/',
|
|
|
62
62
|
|
|
63
63
|
xml.service :name => "service" do
|
|
64
64
|
xml.port :name => "#{@name}_port", :binding => "tns:#{@name}_binding" do
|
|
65
|
-
xml.tag! "soap:address", :location =>
|
|
65
|
+
xml.tag! "soap:address", :location => WashOut::Router.url(request, @name)
|
|
66
66
|
end
|
|
67
67
|
end
|
|
68
68
|
end
|
|
@@ -3,9 +3,16 @@ xml.tag! "soap:Envelope", "xmlns:soap" => 'http://schemas.xmlsoap.org/soap/envel
|
|
|
3
3
|
"xmlns:xsd" => 'http://www.w3.org/2001/XMLSchema',
|
|
4
4
|
"xmlns:xsi" => 'http://www.w3.org/2001/XMLSchema-instance',
|
|
5
5
|
"xmlns:tns" => @namespace do
|
|
6
|
+
if !header.nil?
|
|
7
|
+
xml.tag! "soap:Header" do
|
|
8
|
+
xml.tag! "tns:#{@action_spec[:response_tag]}" do
|
|
9
|
+
wsdl_data xml, header
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
6
13
|
xml.tag! "soap:Body" do
|
|
7
14
|
xml.tag! "tns:#{@action_spec[:response_tag]}" do
|
|
8
15
|
wsdl_data xml, result
|
|
9
16
|
end
|
|
10
17
|
end
|
|
11
|
-
end
|
|
18
|
+
end
|
|
@@ -62,7 +62,7 @@ xml.definitions 'xmlns' => 'http://schemas.xmlsoap.org/wsdl/',
|
|
|
62
62
|
|
|
63
63
|
xml.service :name => "service" do
|
|
64
64
|
xml.port :name => "#{@name}_port", :binding => "tns:#{@name}_binding" do
|
|
65
|
-
xml.tag! "soap:address", :location =>
|
|
65
|
+
xml.tag! "soap:address", :location => WashOut::Router.url(request, @name)
|
|
66
66
|
end
|
|
67
67
|
end
|
|
68
68
|
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# This file was generated by Appraisal
|
|
2
|
+
|
|
3
|
+
source "http://rubygems.org"
|
|
4
|
+
|
|
5
|
+
gem "wasabi"
|
|
6
|
+
gem "savon", ">= 2.0.0"
|
|
7
|
+
gem "httpi"
|
|
8
|
+
gem "rspec-rails"
|
|
9
|
+
gem "guard"
|
|
10
|
+
gem "guard-rspec"
|
|
11
|
+
gem "rb-fsevent"
|
|
12
|
+
gem "appraisal"
|
|
13
|
+
gem "tzinfo"
|
|
14
|
+
gem "pry"
|
|
15
|
+
gem "simplecov"
|
|
16
|
+
gem "simplecov-summary"
|
|
17
|
+
gem "minitest", "<5.10.0"
|
|
18
|
+
gem "rails", "5.0.0"
|
|
19
|
+
|
|
20
|
+
gemspec path: "../"
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# This file was generated by Appraisal
|
|
2
|
+
|
|
3
|
+
source "http://rubygems.org"
|
|
4
|
+
|
|
5
|
+
gem "wasabi"
|
|
6
|
+
gem "savon", ">= 2.0.0"
|
|
7
|
+
gem "httpi"
|
|
8
|
+
gem "rspec-rails"
|
|
9
|
+
gem "guard"
|
|
10
|
+
gem "guard-rspec"
|
|
11
|
+
gem "rb-fsevent"
|
|
12
|
+
gem "appraisal"
|
|
13
|
+
gem "tzinfo"
|
|
14
|
+
gem "pry"
|
|
15
|
+
gem "simplecov"
|
|
16
|
+
gem "simplecov-summary"
|
|
17
|
+
gem "rails", "5.1.1"
|
|
18
|
+
gem "railties", "5.1.1"
|
|
19
|
+
|
|
20
|
+
gemspec path: "../"
|
data/lib/wash_out/dispatcher.rb
CHANGED
|
@@ -16,9 +16,8 @@ module WashOut
|
|
|
16
16
|
class ProgrammerError < Exception; end
|
|
17
17
|
|
|
18
18
|
def _authenticate_wsse
|
|
19
|
-
|
|
20
19
|
begin
|
|
21
|
-
xml_security = env['wash_out.soap_data'].values_at(:envelope, :Envelope).compact.first
|
|
20
|
+
xml_security = request.env['wash_out.soap_data'].values_at(:envelope, :Envelope).compact.first
|
|
22
21
|
xml_security = xml_security.values_at(:header, :Header).compact.first
|
|
23
22
|
xml_security = xml_security.values_at(:security, :Security).compact.first
|
|
24
23
|
username_token = xml_security.values_at(:username_token, :UsernameToken).compact.first
|
|
@@ -32,10 +31,14 @@ module WashOut
|
|
|
32
31
|
end
|
|
33
32
|
|
|
34
33
|
def _map_soap_parameters
|
|
35
|
-
|
|
34
|
+
self.params = _load_params action_spec[:in],
|
|
36
35
|
_strip_empty_nodes(action_spec[:in], xml_data)
|
|
37
36
|
end
|
|
38
37
|
|
|
38
|
+
def _map_soap_headers
|
|
39
|
+
@_soap_headers = xml_header_data
|
|
40
|
+
end
|
|
41
|
+
|
|
39
42
|
def _strip_empty_nodes(params, hash)
|
|
40
43
|
hash.keys.each do |key|
|
|
41
44
|
param = params.detect { |a| a.raw_name.to_s == key.to_s }
|
|
@@ -69,10 +72,9 @@ module WashOut
|
|
|
69
72
|
|
|
70
73
|
# This action generates the WSDL for defined SOAP methods.
|
|
71
74
|
def _generate_wsdl
|
|
72
|
-
|
|
73
75
|
@map = self.class.soap_actions
|
|
74
76
|
@namespace = soap_config.namespace
|
|
75
|
-
@name = controller_path
|
|
77
|
+
@name = controller_path
|
|
76
78
|
|
|
77
79
|
render :template => "wash_out/#{soap_config.wsdl_style}/wsdl", :layout => false,
|
|
78
80
|
:content_type => 'text/xml'
|
|
@@ -129,9 +131,19 @@ module WashOut
|
|
|
129
131
|
return result_spec
|
|
130
132
|
}
|
|
131
133
|
|
|
134
|
+
header = options[:header]
|
|
135
|
+
if header.present?
|
|
136
|
+
header = { 'value' => header } unless header.is_a? Hash
|
|
137
|
+
header = HashWithIndifferentAccess.new(header)
|
|
138
|
+
end
|
|
139
|
+
|
|
132
140
|
render :template => "wash_out/#{soap_config.wsdl_style}/response",
|
|
133
141
|
:layout => false,
|
|
134
|
-
:locals => {
|
|
142
|
+
:locals => {
|
|
143
|
+
:header => header.present? ? inject.call(header, @action_spec[:header_out])
|
|
144
|
+
: nil,
|
|
145
|
+
:result => inject.call(result, @action_spec[:out])
|
|
146
|
+
},
|
|
135
147
|
:content_type => 'text/xml'
|
|
136
148
|
end
|
|
137
149
|
|
|
@@ -140,6 +152,10 @@ module WashOut
|
|
|
140
152
|
render_soap_error("Cannot find SOAP action mapping for #{request.env['wash_out.soap_action']}")
|
|
141
153
|
end
|
|
142
154
|
|
|
155
|
+
def _invalid_request
|
|
156
|
+
render_soap_error("Invalid SOAP request")
|
|
157
|
+
end
|
|
158
|
+
|
|
143
159
|
def _catch_soap_errors
|
|
144
160
|
yield
|
|
145
161
|
rescue SOAPError => error
|
|
@@ -157,37 +173,68 @@ module WashOut
|
|
|
157
173
|
:content_type => 'text/xml'
|
|
158
174
|
end
|
|
159
175
|
|
|
176
|
+
def soap_request
|
|
177
|
+
OpenStruct.new({
|
|
178
|
+
params: @_params,
|
|
179
|
+
headers: @_soap_headers
|
|
180
|
+
})
|
|
181
|
+
end
|
|
182
|
+
|
|
160
183
|
def self.included(controller)
|
|
161
|
-
|
|
184
|
+
entity = if defined?(Rails::VERSION::MAJOR) && (Rails::VERSION::MAJOR >= 4)
|
|
185
|
+
'action'
|
|
186
|
+
else
|
|
187
|
+
'filter'
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
controller.send :"around_#{entity}", :_catch_soap_errors
|
|
162
191
|
controller.send :helper, :wash_out
|
|
163
|
-
controller.send :
|
|
164
|
-
|
|
165
|
-
controller.send :
|
|
166
|
-
|
|
167
|
-
|
|
192
|
+
controller.send :"before_#{entity}", :_authenticate_wsse, :if => :soap_action?
|
|
193
|
+
controller.send :"before_#{entity}", :_map_soap_parameters, :if => :soap_action?
|
|
194
|
+
controller.send :"before_#{entity}", :_map_soap_headers, :if => :soap_action?
|
|
195
|
+
|
|
196
|
+
if defined?(Rails::VERSION::MAJOR) && (Rails::VERSION::MAJOR >= 5)
|
|
197
|
+
controller.send :"skip_before_#{entity}", :verify_authenticity_token, :raise => false
|
|
198
|
+
else
|
|
199
|
+
controller.send :"skip_before_#{entity}", :verify_authenticity_token
|
|
200
|
+
end
|
|
168
201
|
end
|
|
169
202
|
|
|
170
|
-
def self.deep_select(
|
|
171
|
-
|
|
203
|
+
def self.deep_select(collection, result=[], &blk)
|
|
204
|
+
values = collection.respond_to?(:values) ? collection.values : collection
|
|
205
|
+
result += values.select(&blk)
|
|
172
206
|
|
|
173
|
-
|
|
174
|
-
|
|
207
|
+
values.each do |value|
|
|
208
|
+
if value.is_a?(Hash) || value.is_a?(Array)
|
|
209
|
+
result = deep_select(value, result, &blk)
|
|
210
|
+
end
|
|
175
211
|
end
|
|
176
212
|
|
|
177
213
|
result
|
|
178
214
|
end
|
|
179
215
|
|
|
180
|
-
def self.deep_replace_href(
|
|
181
|
-
return
|
|
216
|
+
def self.deep_replace_href(element, replace)
|
|
217
|
+
return element unless element.is_a?(Array) || element.is_a?(Hash)
|
|
182
218
|
|
|
183
|
-
|
|
184
|
-
|
|
219
|
+
if element.is_a?(Array) # Traverse arrays
|
|
220
|
+
return element.map{|x| deep_replace_href(x, replace)}
|
|
185
221
|
end
|
|
186
222
|
|
|
187
|
-
|
|
223
|
+
if element.has_key?(:@href) # Replace needle and traverse replacement
|
|
224
|
+
return deep_replace_href(replace[element[:@href]], replace)
|
|
225
|
+
end
|
|
226
|
+
|
|
227
|
+
element.each do |key, value| # Traverse hashes
|
|
228
|
+
element[key] = deep_replace_href(value, replace)
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
element
|
|
188
232
|
end
|
|
189
233
|
|
|
190
234
|
private
|
|
235
|
+
def soap_action?
|
|
236
|
+
soap_action.present?
|
|
237
|
+
end
|
|
191
238
|
|
|
192
239
|
def action_spec
|
|
193
240
|
self.class.soap_actions[soap_action]
|
|
@@ -202,11 +249,16 @@ module WashOut
|
|
|
202
249
|
end
|
|
203
250
|
|
|
204
251
|
def xml_data
|
|
205
|
-
|
|
206
|
-
xml_data =
|
|
252
|
+
envelope = request.env['wash_out.soap_data'].values_at(:envelope, :Envelope).compact.first
|
|
253
|
+
xml_data = envelope.values_at(:body, :Body).compact.first || {}
|
|
207
254
|
return xml_data if soap_config.wsdl_style == "document"
|
|
208
255
|
xml_data = xml_data.values_at(soap_action.underscore.to_sym, soap_action.to_sym, request_input_tag.to_sym).compact.first || {}
|
|
209
256
|
end
|
|
210
257
|
|
|
258
|
+
def xml_header_data
|
|
259
|
+
envelope = request.env['wash_out.soap_data'].values_at(:envelope, :Envelope).compact.first
|
|
260
|
+
header_data = envelope.values_at(:header, :Header).compact.first || {}
|
|
261
|
+
end
|
|
262
|
+
|
|
211
263
|
end
|
|
212
264
|
end
|
data/lib/wash_out/engine.rb
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
|
|
2
1
|
module WashOut
|
|
3
2
|
class Engine < ::Rails::Engine
|
|
4
3
|
config.wash_out = ActiveSupport::OrderedOptions.new
|
|
5
4
|
initializer "wash_out.configuration" do |app|
|
|
6
5
|
if app.config.wash_out[:catch_xml_errors]
|
|
7
|
-
app.config.middleware.insert_after
|
|
6
|
+
app.config.middleware.insert_after(ActionDispatch::ShowExceptions, WashOut::Middleware)
|
|
8
7
|
end
|
|
9
8
|
end
|
|
10
9
|
|
data/lib/wash_out/router.rb
CHANGED
|
@@ -4,6 +4,40 @@ module WashOut
|
|
|
4
4
|
# This class is a Rack middleware used to route SOAP requests to a proper
|
|
5
5
|
# action of a given SOAP controller.
|
|
6
6
|
class Router
|
|
7
|
+
def self.lookup_soap_routes(controller_name, routes, path=[], &block)
|
|
8
|
+
routes.each do |x|
|
|
9
|
+
defaults = x.defaults
|
|
10
|
+
defaults = defaults[:defaults] if defaults.include?(:defaults) # Rails 5
|
|
11
|
+
if defaults[:controller] == controller_name && defaults[:action] == 'soap'
|
|
12
|
+
yield path+[x]
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
app = x.app
|
|
16
|
+
app = app.app if app.respond_to?(:app)
|
|
17
|
+
if app.respond_to?(:routes) && app.routes.respond_to?(:routes)
|
|
18
|
+
lookup_soap_routes(controller_name, app.routes.routes, path+[x], &block)
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def self.url(request, controller_name)
|
|
24
|
+
lookup_soap_routes(controller_name, Rails.application.routes.routes) do |routes|
|
|
25
|
+
|
|
26
|
+
path = if routes.first.respond_to?(:optimized_path) # Rails 4
|
|
27
|
+
routes.map(&:optimized_path)
|
|
28
|
+
elsif routes.first.path.respond_to?(:build_formatter) # Rails 5
|
|
29
|
+
routes.map{|x| x.path.build_formatter.evaluate(nil)}
|
|
30
|
+
else
|
|
31
|
+
routes.map{|x| x.format({})} # Rails 3.2
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
if Rails.application.config.relative_url_root.present?
|
|
35
|
+
path.prepend Rails.application.config.relative_url_root
|
|
36
|
+
end
|
|
37
|
+
return request.protocol + request.host_with_port + path.flatten.join('')
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
7
41
|
def initialize(controller_name)
|
|
8
42
|
@controller_name = "#{controller_name.to_s}_controller".camelize
|
|
9
43
|
end
|
|
@@ -17,15 +51,13 @@ module WashOut
|
|
|
17
51
|
|
|
18
52
|
soap_action = controller.soap_config.soap_action_routing ? env['HTTP_SOAPACTION'].to_s.gsub(/^"(.*)"$/, '\1')
|
|
19
53
|
: ''
|
|
20
|
-
|
|
21
54
|
if soap_action.blank?
|
|
22
55
|
parsed_soap_body = nori(controller.soap_config.snakecase_input).parse(soap_body env)
|
|
23
56
|
return nil if parsed_soap_body.blank?
|
|
24
57
|
|
|
25
|
-
soap_action = parsed_soap_body
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
.keys.first.to_s
|
|
58
|
+
soap_action = parsed_soap_body.values_at(:envelope, :Envelope).try(:compact).try(:first)
|
|
59
|
+
soap_action = soap_action.values_at(:body, :Body).try(:compact).try(:first) if soap_action
|
|
60
|
+
soap_action = soap_action.keys.first.to_s if soap_action
|
|
29
61
|
end
|
|
30
62
|
|
|
31
63
|
# RUBY18 1.8 does not have force_encoding.
|
|
@@ -61,9 +93,8 @@ module WashOut
|
|
|
61
93
|
|
|
62
94
|
def parse_soap_parameters(env)
|
|
63
95
|
return env['wash_out.soap_data'] if env['wash_out.soap_data']
|
|
64
|
-
|
|
65
96
|
env['wash_out.soap_data'] = nori(controller.soap_config.snakecase_input).parse(soap_body env)
|
|
66
|
-
references = WashOut::Dispatcher.deep_select(env['wash_out.soap_data']){|
|
|
97
|
+
references = WashOut::Dispatcher.deep_select(env['wash_out.soap_data']){|v| v.is_a?(Hash) && v.has_key?(:@id)}
|
|
67
98
|
|
|
68
99
|
unless references.blank?
|
|
69
100
|
replaces = {}; references.each{|r| replaces['#'+r[:@id]] = r}
|
|
@@ -76,19 +107,21 @@ module WashOut
|
|
|
76
107
|
def call(env)
|
|
77
108
|
@controller = @controller_name.constantize
|
|
78
109
|
|
|
79
|
-
soap_action
|
|
80
|
-
return [200, {}, ['OK']] if soap_action.blank?
|
|
81
|
-
|
|
82
|
-
soap_parameters = parse_soap_parameters(env)
|
|
110
|
+
soap_action = parse_soap_action(env)
|
|
83
111
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
if action_spec
|
|
87
|
-
action = action_spec[:to]
|
|
112
|
+
action = if soap_action.blank?
|
|
113
|
+
'_invalid_request'
|
|
88
114
|
else
|
|
89
|
-
|
|
115
|
+
soap_parameters = parse_soap_parameters(env)
|
|
116
|
+
action_spec = controller.soap_actions[soap_action]
|
|
117
|
+
|
|
118
|
+
if action_spec
|
|
119
|
+
action_spec[:to]
|
|
120
|
+
else
|
|
121
|
+
'_invalid_action'
|
|
122
|
+
end
|
|
90
123
|
end
|
|
91
|
-
|
|
124
|
+
env["action_dispatch.request.content_type"] = Mime[:soap]
|
|
92
125
|
controller.action(action).call(env)
|
|
93
126
|
end
|
|
94
127
|
end
|