wash_out 0.10.0.beta.1 → 0.10.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +3 -1
  3. data/.travis.yml +23 -3
  4. data/Appraisals +11 -5
  5. data/Gemfile +2 -2
  6. data/README.md +66 -2
  7. data/Rakefile +6 -7
  8. data/app/helpers/wash_out_helper.rb +49 -18
  9. data/app/views/{wash_with_soap → wash_out}/document/error.builder +0 -0
  10. data/app/views/{wash_with_soap → wash_out}/document/response.builder +1 -3
  11. data/app/views/{wash_with_soap → wash_out}/document/wsdl.builder +15 -15
  12. data/app/views/{wash_with_soap → wash_out}/rpc/error.builder +0 -0
  13. data/app/views/{wash_with_soap → wash_out}/rpc/response.builder +1 -3
  14. data/app/views/{wash_with_soap → wash_out}/rpc/wsdl.builder +16 -16
  15. data/gemfiles/rails_3.1.3.gemfile +20 -0
  16. data/gemfiles/rails_3.2.12.gemfile +20 -0
  17. data/gemfiles/rails_4.0.0.gemfile +19 -0
  18. data/gemfiles/rails_4.1.0.gemfile +19 -0
  19. data/gemfiles/rails_4.2.0.gemfile +19 -0
  20. data/lib/wash_out.rb +48 -16
  21. data/lib/wash_out/configurable.rb +41 -0
  22. data/lib/wash_out/dispatcher.rb +212 -0
  23. data/lib/wash_out/engine.rb +12 -0
  24. data/lib/wash_out/middleware.rb +41 -0
  25. data/lib/wash_out/model.rb +29 -0
  26. data/lib/wash_out/param.rb +43 -16
  27. data/lib/wash_out/router.rb +95 -0
  28. data/lib/wash_out/soap.rb +48 -0
  29. data/lib/wash_out/soap_config.rb +93 -0
  30. data/lib/wash_out/type.rb +20 -13
  31. data/lib/wash_out/version.rb +1 -1
  32. data/lib/wash_out/wsse.rb +29 -10
  33. data/spec/dummy/config/environments/test.rb +1 -0
  34. data/spec/lib/wash_out/dispatcher_spec.rb +28 -13
  35. data/spec/lib/wash_out/middleware_spec.rb +33 -0
  36. data/spec/lib/wash_out/param_spec.rb +47 -17
  37. data/spec/lib/wash_out/router_spec.rb +22 -0
  38. data/spec/lib/wash_out/type_spec.rb +9 -9
  39. data/spec/lib/wash_out_spec.rb +139 -87
  40. data/spec/spec_helper.rb +7 -1
  41. metadata +32 -25
  42. data/lib/wash_out/exceptions/programmer_error.rb +0 -10
  43. data/lib/wash_out/exceptions/soap_error.rb +0 -19
  44. data/lib/wash_out/middlewares/catcher.rb +0 -42
  45. data/lib/wash_out/middlewares/router.rb +0 -132
  46. data/lib/wash_out/rails/active_record.rb +0 -27
  47. data/lib/wash_out/rails/controller.rb +0 -201
  48. data/lib/wash_out/rails/engine.rb +0 -74
  49. data/spec/lib/wash_out/rack_spec.rb +0 -55
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 443e624e950f3d062ccc19a9d2221dbc1ac91b25
4
- data.tar.gz: facd37fd93991475d04e93a3544e156db1736a2c
3
+ metadata.gz: a23248a1bd38c14fe7eae75c2589b4eb945687f6
4
+ data.tar.gz: 5f806cadfebf37d0b46ee2d7f69d00266f0bae53
5
5
  SHA512:
6
- metadata.gz: c7e405ff31de4bdae9c2927e28791167a36a942a999a1eb732fcaa459855b5b1f227e30ab71d784a4efd6ec0b4a10d5d23b170dba8c27287c71b7d1d4aeab9f9
7
- data.tar.gz: 6874a42fc4db8368b1cbb7fff4989ce5741449f743d2924b234be4da80762ac4688a4354aa5a5e245eb0d067b249c9dd01ceabe82239f0c05e384ba978cf2dc5
6
+ metadata.gz: 5879036aca9ca31804573e45c5cc3aa4f7ffdb5303c27ea195c322c9246afd1ecde6d518783cd6e13dcd49ccb7a29c99f7017bc28a8feb43fbb45afeb2988063
7
+ data.tar.gz: d791bece6a7eb059ff83dbac5bce07ccd6e7dfc95c761579ff53ff97776dae4c7a5156b76997131f8de931b5263ba846545ec5018daa75eeb66faf985bbb2a6e
data/.gitignore CHANGED
@@ -2,6 +2,8 @@
2
2
  .bundle/
3
3
  *.gem
4
4
  .idea/
5
+ .ruby-gemset
6
+ .ruby-version
5
7
  .rvmrc
6
8
  *.swp
7
9
  log/*.log
@@ -9,7 +11,7 @@ pkg/
9
11
  spec/dummy/db/*.sqlite3
10
12
  spec/dummy/log/*.log
11
13
  spec/dummy/tmp/
12
- gemfiles
14
+ gemfiles/*.lock
13
15
  coverage
14
16
  tags
15
17
  Gemfile.lock
@@ -1,6 +1,26 @@
1
- before_install:
2
- - gem install bundler
1
+ script: bundle exec rspec
2
+ gemfile:
3
+ - gemfiles/rails_3.1.3.gemfile
4
+ - gemfiles/rails_3.2.12.gemfile
5
+ - gemfiles/rails_4.0.0.gemfile
6
+ - gemfiles/rails_4.1.0.gemfile
7
+ - gemfiles/rails_4.2.0.gemfile
3
8
  rvm:
4
9
  - 1.9.3
5
- - jruby-19mode
6
10
  - 2.0.0
11
+ - 2.1.8
12
+ - 2.2.4
13
+ - 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
+ before_install:
26
+ - gem update bundler
data/Appraisals CHANGED
@@ -1,15 +1,21 @@
1
- appraise "rails-3.2.8" do
2
- gem "rails", "3.2.8"
3
- end
4
-
5
1
  appraise "rails-3.1.3" do
6
2
  gem "rails", "3.1.3"
3
+ gem "test-unit"
7
4
  end
8
5
 
9
6
  appraise "rails-3.2.12" do
10
7
  gem "rails", "3.2.12"
8
+ gem "test-unit"
11
9
  end
12
10
 
13
11
  appraise "rails-4.0.0" do
14
12
  gem "rails", "4.0.0"
15
- end
13
+ end
14
+
15
+ appraise "rails-4.1.0" do
16
+ gem "rails", "4.1.0"
17
+ end
18
+
19
+ appraise "rails-4.2.0" do
20
+ gem "rails", "4.2.0"
21
+ end
data/Gemfile CHANGED
@@ -4,7 +4,7 @@ gemspec
4
4
 
5
5
  gem 'wasabi'
6
6
  gem 'savon', '>= 2.0.0'
7
- gem 'httpi', :git => 'git://github.com/savonrb/httpi.git'
7
+ gem 'httpi'
8
8
 
9
9
  gem 'rspec-rails'
10
10
  gem 'guard'
@@ -14,4 +14,4 @@ gem 'appraisal'
14
14
  gem 'tzinfo'
15
15
  gem 'pry'
16
16
  gem 'simplecov'
17
- gem 'simplecov-summary'
17
+ gem 'simplecov-summary'
data/README.md CHANGED
@@ -63,7 +63,7 @@ class RumbasController < ApplicationController
63
63
  def add_circle
64
64
  circle = params[:circle]
65
65
 
66
- raise WashOut::SOAPError, "radius is too small" if circle[:radius] < 3.0
66
+ raise SOAPError, "radius is too small" if circle[:radius] < 3.0
67
67
 
68
68
  Circle.new(circle[:center][:x], circle[:center][:y], circle[:radius])
69
69
 
@@ -78,6 +78,44 @@ class RumbasController < ApplicationController
78
78
  render :soap => params[:data].map{|x| x ? 1 : 0}
79
79
  end
80
80
 
81
+ # Params from XML attributes;
82
+ # e.g. for a request to the 'AddCircle' action:
83
+ # <soapenv:Envelope>
84
+ # <soapenv:Body>
85
+ # <AddCircle>
86
+ # <Circle radius="5.0">
87
+ # <Center x="10" y="12" />
88
+ # </Circle>
89
+ # </AddCircle>
90
+ # </soapenv:Body>
91
+ # </soapenv:Envelope>
92
+ soap_action "AddCircle",
93
+ :args => { :circle => { :center => { :@x => :integer,
94
+ :@y => :integer },
95
+ :@radius => :double } },
96
+ :return => nil, # [] for wash_out below 0.3.0
97
+ :to => :add_circle
98
+ def add_circle
99
+ circle = params[:circle]
100
+ Circle.new(circle[:center][:x], circle[:center][:y], circle[:radius])
101
+
102
+ render :soap => nil
103
+ end
104
+
105
+ # With a customised input tag name, in case params are wrapped;
106
+ # e.g. for a request to the 'IntegersToBoolean' action:
107
+ # <soapenv:Envelope>
108
+ # <soapenv:Body>
109
+ # <MyRequest> <!-- not <IntegersToBoolean> -->
110
+ # <Data>...</Data>
111
+ # </MyRequest>
112
+ # </soapenv:Body>
113
+ # </soapenv:Envelope>
114
+ soap_action "integers_to_boolean",
115
+ :args => { :my_request => { :data => [:integer] } },
116
+ :as => 'MyRequest',
117
+ :return => [:boolean]
118
+
81
119
  # You can use all Rails features like filtering, too. A SOAP controller
82
120
  # is just like a normal controller with a special routing.
83
121
  before_filter :dump_parameters
@@ -94,7 +132,7 @@ WashOutSample::Application.routes.draw do
94
132
  end
95
133
  ```
96
134
 
97
- In such a setup, the generated WSDL may be queried at path `/api/wsdl`. So, with a
135
+ In such a setup, the generated WSDL may be queried at path `/rumbas/wsdl`. So, with a
98
136
  gem like Savon, a request can be done using this path:
99
137
 
100
138
  ```ruby
@@ -137,6 +175,32 @@ To use defined type inside your inline declaration, pass the class instead of ty
137
175
  Note that WashOut extends the `ActiveRecord` so every model you use is already a WashOut::Type and can be used
138
176
  inside your interface declarations.
139
177
 
178
+ ## WSSE Authentication
179
+
180
+ WashOut provides two mechanism for WSSE Authentication.
181
+
182
+ ### Static Authentication
183
+
184
+ You can configure the service to validate against a username and password with the following configuration:
185
+
186
+ ```ruby
187
+ soap_service namespace: "wash_out", wsse_username: "username", wsse_password: "password"
188
+ ```
189
+
190
+ With this mechanism, all the actions in the controller will be authenticated against the specified username and password. If you need to authenticate different users, you can use the dynamic mechanism described below.
191
+
192
+ ### Dynamic Authentication
193
+
194
+ Dynamic authentication allows you to process the username and password any way you want, with the most common case being authenticating against a database. The configuration option for this mechanism is called `wsse_auth_callback`:
195
+
196
+ ```ruby
197
+ soap_service namespace: "wash_out", wsse_auth_callback: ->(username, password) {
198
+ return !User.find_by(username: username).authenticate(password).blank?
199
+ }
200
+ ```
201
+
202
+ Keep in mind that the password may already be hashed by the SOAP client, so you would have to check against that condition too as per [spec](http://www.oasis-open.org/committees/download.php/16782/wss-v1.1-spec-os-UsernameTokenProfile.pdf)
203
+
140
204
  ## Configuration
141
205
 
142
206
  Use `config.wash_out...` inside your environment configuration to setup WashOut globally.
data/Rakefile CHANGED
@@ -5,10 +5,9 @@ require 'rspec/core/rake_task'
5
5
 
6
6
  RSpec::Core::RakeTask.new(:spec)
7
7
 
8
- desc "Default: run the unit tests."
9
- task :default => [:all]
10
-
11
- desc 'Test the plugin under all supported Rails versions.'
12
- task :all => ["appraisal:install"] do |t|
13
- exec('rake appraisal spec')
14
- end
8
+ task :console do
9
+ require "action_controller/railtie"
10
+ require "rails/test_unit/railtie"
11
+ Bundler.require
12
+ binding.pry
13
+ end
@@ -9,31 +9,47 @@ module WashOutHelper
9
9
  end
10
10
  end
11
11
 
12
+ def wsdl_data_attrs(param)
13
+ param.map.reduce({}) do |memo, p|
14
+ if p.respond_to?(:attribute?) && p.attribute?
15
+ memo.merge p.attr_name => p.value
16
+ else
17
+ memo
18
+ end
19
+ end
20
+ end
21
+
12
22
  def wsdl_data(xml, params)
13
23
  params.each do |param|
24
+ next if param.attribute?
25
+
14
26
  tag_name = param.name
15
27
  param_options = wsdl_data_options(param)
28
+ param_options.merge! wsdl_data_attrs(param)
16
29
 
17
- if !param.struct?
18
- if !param.multiplied
19
- xml.tag! tag_name, param.value, param_options
30
+ if param.struct?
31
+ if param.multiplied
32
+ param.map.each do |p|
33
+ attrs = wsdl_data_attrs p
34
+ if p.is_a?(Array) || p.map.size > attrs.size
35
+ blk = proc { wsdl_data(xml, p.map) }
36
+ end
37
+ attrs.reject! { |_, v| v.nil? }
38
+ xml.tag! tag_name, param_options.merge(attrs), &blk
39
+ end
20
40
  else
21
- param.value = [] unless param.value.is_a?(Array)
22
- param.value.each do |v|
23
- xml.tag! tag_name, v, param_options
41
+ xml.tag! tag_name, param_options do
42
+ wsdl_data(xml, param.map)
24
43
  end
25
44
  end
26
45
  else
27
- if !param.multiplied
28
- xml.tag! tag_name, param_options do
29
- wsdl_data(xml, param.map)
46
+ if param.multiplied
47
+ param.value = [] unless param.value.is_a?(Array)
48
+ param.value.each do |v|
49
+ xml.tag! tag_name, v, param_options
30
50
  end
31
51
  else
32
- param.map.each do |p|
33
- xml.tag! tag_name, param_options do
34
- wsdl_data(xml, p.map)
35
- end
36
- end
52
+ xml.tag! tag_name, param.value, param_options
37
53
  end
38
54
  end
39
55
  end
@@ -45,12 +61,27 @@ module WashOutHelper
45
61
  if param.struct?
46
62
  if !defined.include?(param.basic_type)
47
63
  xml.tag! "xsd:complexType", :name => param.basic_type do
48
- xml.tag! "xsd:sequence" do
49
- param.map.each do |value|
50
- more << value if value.struct?
51
- xml.tag! "xsd:element", wsdl_occurence(value, false, :name => value.name, :type => value.namespaced_type)
64
+ attrs, elems = [], []
65
+ param.map.each do |value|
66
+ more << value if value.struct?
67
+ if value.attribute?
68
+ attrs << value
69
+ else
70
+ elems << value
71
+ end
72
+ end
73
+
74
+ if elems.any?
75
+ xml.tag! "xsd:sequence" do
76
+ elems.each do |value|
77
+ xml.tag! "xsd:element", wsdl_occurence(value, false, :name => value.name, :type => value.namespaced_type)
78
+ end
52
79
  end
53
80
  end
81
+
82
+ attrs.each do |value|
83
+ xml.tag! "xsd:attribute", wsdl_occurence(value, false, :name => value.attr_name, :type => value.namespaced_type)
84
+ end
54
85
  end
55
86
 
56
87
  defined << param.basic_type
@@ -3,9 +3,7 @@ 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:tns" => @namespace do
5
5
  xml.tag! "soap:Body" do
6
- key = "tns:#{@operation}#{controller.soap_config.camelize_wsdl ? 'Response' : '_response'}"
7
-
8
- xml.tag! @action_spec[:response_tag] || key do
6
+ xml.tag! "tns:#{@action_spec[:response_tag]}" do
9
7
  wsdl_data xml, result
10
8
  end
11
9
  end
@@ -19,11 +19,24 @@ xml.definitions 'xmlns' => 'http://schemas.xmlsoap.org/wsdl/',
19
19
  end
20
20
  end
21
21
 
22
+ @map.each do |operation, formats|
23
+ xml.message :name => "#{operation}" do
24
+ formats[:in].each do |p|
25
+ xml.part wsdl_occurence(p, false, :name => p.name, :type => p.namespaced_type)
26
+ end
27
+ end
28
+ xml.message :name => formats[:response_tag] do
29
+ formats[:out].each do |p|
30
+ xml.part wsdl_occurence(p, false, :name => p.name, :type => p.namespaced_type)
31
+ end
32
+ end
33
+ end
34
+
22
35
  xml.portType :name => "#{@name}_port" do
23
- @map.keys.each do |operation|
36
+ @map.each do |operation, formats|
24
37
  xml.operation :name => operation do
25
38
  xml.input :message => "tns:#{operation}"
26
- xml.output :message => "tns:#{operation}#{controller.soap_config.camelize_wsdl ? 'Response' : '_response'}"
39
+ xml.output :message => "tns:#{formats[:response_tag]}"
27
40
  end
28
41
  end
29
42
  end
@@ -52,17 +65,4 @@ xml.definitions 'xmlns' => 'http://schemas.xmlsoap.org/wsdl/',
52
65
  xml.tag! "soap:address", :location => send("#{@name}_action_url")
53
66
  end
54
67
  end
55
-
56
- @map.each do |operation, formats|
57
- xml.message :name => "#{operation}" do
58
- formats[:in].each do |p|
59
- xml.part wsdl_occurence(p, false, :name => p.name, :type => p.namespaced_type)
60
- end
61
- end
62
- xml.message :name => "#{operation}#{controller.soap_config.camelize_wsdl ? 'Response' : '_response'}" do
63
- formats[:out].each do |p|
64
- xml.part wsdl_occurence(p, false, :name => p.name, :type => p.namespaced_type)
65
- end
66
- end
67
- end
68
68
  end
@@ -4,9 +4,7 @@ xml.tag! "soap:Envelope", "xmlns:soap" => 'http://schemas.xmlsoap.org/soap/envel
4
4
  "xmlns:xsi" => 'http://www.w3.org/2001/XMLSchema-instance',
5
5
  "xmlns:tns" => @namespace do
6
6
  xml.tag! "soap:Body" do
7
- key = "tns:#{@operation}#{controller.soap_config.camelize_wsdl ? 'Response' : '_response'}"
8
-
9
- xml.tag! @action_spec[:response_tag] || key do
7
+ xml.tag! "tns:#{@action_spec[:response_tag]}" do
10
8
  wsdl_data xml, result
11
9
  end
12
10
  end
@@ -19,11 +19,24 @@ xml.definitions 'xmlns' => 'http://schemas.xmlsoap.org/wsdl/',
19
19
  end
20
20
  end
21
21
 
22
+ @map.each do |operation, formats|
23
+ xml.message :name => "#{operation}" do
24
+ formats[:in].each do |p|
25
+ xml.part wsdl_occurence(p, true, :name => p.name, :type => p.namespaced_type)
26
+ end
27
+ end
28
+ xml.message :name => formats[:response_tag] do
29
+ formats[:out].each do |p|
30
+ xml.part wsdl_occurence(p, true, :name => p.name, :type => p.namespaced_type)
31
+ end
32
+ end
33
+ end
34
+
22
35
  xml.portType :name => "#{@name}_port" do
23
- @map.keys.each do |operation|
36
+ @map.each do |operation, formats|
24
37
  xml.operation :name => operation do
25
38
  xml.input :message => "tns:#{operation}"
26
- xml.output :message => "tns:#{operation}#{controller.soap_config.camelize_wsdl ? 'Response' : '_response'}"
39
+ xml.output :message => "tns:#{formats[:response_tag]}"
27
40
  end
28
41
  end
29
42
  end
@@ -52,17 +65,4 @@ xml.definitions 'xmlns' => 'http://schemas.xmlsoap.org/wsdl/',
52
65
  xml.tag! "soap:address", :location => send("#{@name}_action_url")
53
66
  end
54
67
  end
55
-
56
- @map.each do |operation, formats|
57
- xml.message :name => "#{operation}" do
58
- formats[:in].each do |p|
59
- xml.part wsdl_occurence(p, true, :name => p.name, :type => p.namespaced_type)
60
- end
61
- end
62
- xml.message :name => "#{operation}#{controller.soap_config.camelize_wsdl ? 'Response' : '_response'}" do
63
- formats[:out].each do |p|
64
- xml.part wsdl_occurence(p, true, :name => p.name, :type => p.namespaced_type)
65
- end
66
- end
67
- end
68
- end
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 "rails", "3.1.3"
18
+ gem "test-unit"
19
+
20
+ gemspec :path => "../"