wash_out 0.8.4 → 0.9.0.beta.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e9f5b28be0d686376641e72fe453eb0d726361ee
4
- data.tar.gz: 6f814eff3cdc68936e048041682bea97be9ff8f7
3
+ metadata.gz: 4791d7a762e3d5a75e9f8d3233ddd7d0b10a240f
4
+ data.tar.gz: d0d43203c81135e8040258cf971bd5b849c95b2e
5
5
  SHA512:
6
- metadata.gz: a6752952791b76997031adcdd04ebfa4ff6029a4d61b7e8926675567db8bebfa176b4b7263790c9058ca2d2a67cd03c574fa5996f9191f4c36bf14eb2cacfbd7
7
- data.tar.gz: eed694bc389c2800e85caeccdbb376017b1c116183d2636f5731b2611c521f71108852293d9f86fbff8609bd41bb311b11ac42021701122629a3973914e1a13f
6
+ metadata.gz: 925b2b09044af493d24e94e63a089cd81e56797c04c52ed8555605e0c306f9e99acec82427d4c010092af825508addb61e7b11b7bc3d28100db0d5353075bcc9
7
+ data.tar.gz: 300d800215c4b1442e9eb85b1c07d67126b04b3d8cca50120072b5543e32d51f14db91d33fb7258aa8580c29942cc8518924dec2c63b5ebfd00e89479b509e09
data/README.md CHANGED
@@ -22,6 +22,8 @@ In your Gemfile, add this line:
22
22
 
23
23
  gem 'wash_out'
24
24
 
25
+ If you are upgrading from version < 0.8.5, replace `include WashOut::Soap` with `soap_service` at the controller level.
26
+
25
27
  ## Usage
26
28
 
27
29
  A SOAP endpoint in WashOut is simply a Rails controller which includes the module WashOut::SOAP. Each SOAP
@@ -34,7 +36,7 @@ demonstrated.
34
36
  ```ruby
35
37
  # app/controllers/rumbas_controller.rb
36
38
  class RumbasController < ApplicationController
37
- include WashOut::SOAP
39
+ soap_service namespace: 'urn:WashOut'
38
40
 
39
41
  # Simple case
40
42
  soap_action "integer_to_string",
@@ -139,7 +141,8 @@ inside your interface declarations.
139
141
 
140
142
  ## Configuration
141
143
 
142
- Use `config.wash_out...` inside your environment configuration to setup WashOut.
144
+ Use `config.wash_out...` inside your environment configuration to setup WashOut globally.
145
+ To override the values on a specific controller just add an override as part of the arguments to the `soap_service` method.
143
146
 
144
147
  Available properties are:
145
148
 
@@ -149,7 +152,7 @@ Available properties are:
149
152
  * **namespace**: SOAP namespace to use. Default is `urn:WashOut`.
150
153
  * **snakecase**: *(DEPRECATED SINCE 0.4.0)* Determines if WashOut should modify parameters keys to snakecase. Default is `false`.
151
154
  * **snakecase_input**: Determines if WashOut should modify parameters keys to snakecase. Default is `false`.
152
- * **camelize_wsdl**: Determines if WashOut should camelize types within WSDL and responses. Default is `false`.
155
+ * **camelize_wsdl**: Determines if WashOut should camelize types within WSDL and responses. Supports `true` for CamelCase and `:lower` for camelCase. Default is `false`.
153
156
 
154
157
  ### Camelization
155
158
 
@@ -164,6 +167,17 @@ soap_action "foo" # this will be passed as is
164
167
 
165
168
  * Boris Staal, [@inossidabile](http://staal.io)
166
169
 
170
+ ## Contributors (in random order)
171
+
172
+ * Mikael Henriksson, [@mhenrixon](http://twitter.com/mhenrixon)
173
+ * Björn Nilsson [@Bjorn-Nilsson](https://github.com/Bjorn-Nilsson)
174
+ * Tobias Bielohlawek [@rngtng](https://github.com/rngtng)
175
+ * Francesco Negri [@dhinus](https://github.com/dhinus)
176
+ * Edgars Beigarts [@ebeigarts](https://github.com/ebeigarts)
177
+ * [Exad](https://github.com/exad) [@wknechtel](https://github.com/wknechtel) and [@☈king](https://github.com/rking)
178
+ * Mark Goris [@gorism](https://github.com/gorism)
179
+ * ... and [others](https://github.com/inossidabile/wash_out/graphs/contributors)
180
+
167
181
  ## License
168
182
 
169
- It is free software, and may be redistributed under the terms of MIT license.
183
+ It is free software, and may be redistributed under the terms of MIT license.
@@ -1,7 +1,7 @@
1
1
  module WashOutHelper
2
2
 
3
3
  def wsdl_data_options(param)
4
- case WashOut::Engine.style
4
+ case controller.soap_config.wsdl_style
5
5
  when 'rpc'
6
6
  { :"xsi:type" => param.namespaced_type }
7
7
  when 'document'
@@ -3,7 +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}#{WashOut::Engine.camelize_wsdl ? 'Response' : '_response'}"
6
+ key = "tns:#{@operation}#{controller.soap_config.camelize_wsdl ? 'Response' : '_response'}"
7
7
 
8
8
  xml.tag! @action_spec[:response_tag] do
9
9
  wsdl_data xml, result
@@ -23,7 +23,7 @@ xml.definitions 'xmlns' => 'http://schemas.xmlsoap.org/wsdl/',
23
23
  @map.keys.each do |operation|
24
24
  xml.operation :name => operation do
25
25
  xml.input :message => "tns:#{operation}"
26
- xml.output :message => "tns:#{operation}#{WashOut::Engine.camelize_wsdl ? 'Response' : '_response'}"
26
+ xml.output :message => "tns:#{operation}#{controller.soap_config.camelize_wsdl ? 'Response' : '_response'}"
27
27
  end
28
28
  end
29
29
  end
@@ -59,7 +59,7 @@ xml.definitions 'xmlns' => 'http://schemas.xmlsoap.org/wsdl/',
59
59
  xml.part wsdl_occurence(p, false, :name => p.name, :type => p.namespaced_type)
60
60
  end
61
61
  end
62
- xml.message :name => "#{operation}#{WashOut::Engine.camelize_wsdl ? 'Response' : '_response'}" do
62
+ xml.message :name => "#{operation}#{controller.soap_config.camelize_wsdl ? 'Response' : '_response'}" do
63
63
  formats[:out].each do |p|
64
64
  xml.part wsdl_occurence(p, false, :name => p.name, :type => p.namespaced_type)
65
65
  end
@@ -4,7 +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}#{WashOut::Engine.camelize_wsdl ? 'Response' : '_response'}"
7
+ key = "tns:#{@operation}#{controller.soap_config.camelize_wsdl ? 'Response' : '_response'}"
8
8
 
9
9
  xml.tag! @action_spec[:response_tag] do
10
10
  wsdl_data xml, result
@@ -23,7 +23,7 @@ xml.definitions 'xmlns' => 'http://schemas.xmlsoap.org/wsdl/',
23
23
  @map.keys.each do |operation|
24
24
  xml.operation :name => operation do
25
25
  xml.input :message => "tns:#{operation}"
26
- xml.output :message => "tns:#{operation}#{WashOut::Engine.camelize_wsdl ? 'Response' : '_response'}"
26
+ xml.output :message => "tns:#{operation}#{controller.soap_config.camelize_wsdl ? 'Response' : '_response'}"
27
27
  end
28
28
  end
29
29
  end
@@ -59,7 +59,7 @@ xml.definitions 'xmlns' => 'http://schemas.xmlsoap.org/wsdl/',
59
59
  xml.part wsdl_occurence(p, true, :name => p.name, :type => p.namespaced_type)
60
60
  end
61
61
  end
62
- xml.message :name => "#{operation}#{WashOut::Engine.camelize_wsdl ? 'Response' : '_response'}" do
62
+ xml.message :name => "#{operation}#{controller.soap_config.camelize_wsdl ? 'Response' : '_response'}" do
63
63
  formats[:out].each do |p|
64
64
  xml.part wsdl_occurence(p, true, :name => p.name, :type => p.namespaced_type)
65
65
  end
@@ -0,0 +1,41 @@
1
+ module WashOut
2
+ module Configurable
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ cattr_reader :soap_config
7
+ class_variable_set :@@soap_config, WashOut::SoapConfig.new({})
8
+ end
9
+
10
+ module ClassMethods
11
+
12
+ def soap_config=(obj)
13
+
14
+ unless obj.is_a?(Hash)
15
+ raise "Value needs to be a Hash."
16
+ end
17
+
18
+ if class_variable_defined?(:@@soap_config)
19
+ class_variable_get(:@@soap_config).configure obj
20
+ else
21
+ class_variable_set :@@soap_config, WashOut::SoapConfig.new(obj)
22
+ end
23
+ end
24
+ end
25
+
26
+ def soap_config=(obj)
27
+
28
+ unless obj.is_a?(Hash)
29
+ raise "Value needs to be a Hash."
30
+ end
31
+
32
+ class_eval do
33
+ if class_variable_defined?(:@@soap_config)
34
+ class_variable_get(:@@soap_config).configure obj
35
+ else
36
+ class_variable_set :@@soap_config, WashOut::SoapConfig.new(obj)
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -12,14 +12,14 @@ module WashOut
12
12
 
13
13
  # This filter parses the SOAP request and puts it into +params+ array.
14
14
  def _parse_soap_parameters
15
- parser = Nori.new(
16
- :parser => WashOut::Engine.parser,
15
+
16
+ nori_parser = Nori.new(
17
+ :parser => soap_config.parser,
17
18
  :strip_namespaces => true,
18
19
  :advanced_typecasting => true,
19
- :convert_tags_to => ( WashOut::Engine.snakecase_input ? lambda { |tag| tag.snakecase.to_sym } \
20
- : lambda { |tag| tag.to_sym } ))
20
+ :convert_tags_to => ( soap_config.snakecase_input ? lambda { |tag| tag.snakecase.to_sym } : lambda { |tag| tag.to_sym } ))
21
21
 
22
- @_params = parser.parse(request.body.read)
22
+ @_params = nori_parser.parse(request.body.read)
23
23
  references = WashOut::Dispatcher.deep_select(@_params){|k,v| v.is_a?(Hash) && v.has_key?(:@id)}
24
24
 
25
25
  unless references.blank?
@@ -29,6 +29,7 @@ module WashOut
29
29
  end
30
30
 
31
31
  def _authenticate_wsse
32
+
32
33
  begin
33
34
  xml_security = @_params.values_at(:envelope, :Envelope).compact.first
34
35
  xml_security = xml_security.values_at(:header, :Header).compact.first
@@ -38,12 +39,13 @@ module WashOut
38
39
  username_token = nil
39
40
  end
40
41
 
41
- WashOut::Wsse.authenticate username_token
42
+ WashOut::Wsse.authenticate soap_config, username_token
42
43
 
43
44
  request.env['WSSE_TOKEN'] = username_token.with_indifferent_access unless username_token.blank?
44
45
  end
45
46
 
46
47
  def _map_soap_parameters
48
+
47
49
  soap_action = request.env['wash_out.soap_action']
48
50
  action_spec = self.class.soap_actions[soap_action]
49
51
 
@@ -55,7 +57,7 @@ module WashOut
55
57
  strip_empty_nodes = lambda{|hash|
56
58
  hash.keys.each do |key|
57
59
  if hash[key].is_a? Hash
58
- value = hash[key].delete_if{|key, value| key.to_s[0] == '@'}
60
+ value = hash[key].delete_if{|k, v| key.to_s[0] == '@'}
59
61
 
60
62
  if value.length > 0
61
63
  hash[key] = strip_empty_nodes.call(value)
@@ -85,17 +87,18 @@ module WashOut
85
87
 
86
88
  # This action generates the WSDL for defined SOAP methods.
87
89
  def _generate_wsdl
90
+
88
91
  @map = self.class.soap_actions
89
- @namespace = WashOut::Engine.namespace
92
+ @namespace = soap_config.namespace
90
93
  @name = controller_path.gsub('/', '_')
91
94
 
92
- render :template => "wash_with_soap/#{WashOut::Engine.style}/wsdl", :layout => false,
95
+ render :template => "wash_with_soap/#{soap_config.wsdl_style}/wsdl", :layout => false,
93
96
  :content_type => 'text/xml'
94
97
  end
95
98
 
96
99
  # Render a SOAP response.
97
100
  def _render_soap(result, options)
98
- @namespace = WashOut::Engine.namespace
101
+ @namespace = soap_config.namespace
99
102
  @operation = soap_action = request.env['wash_out.soap_action']
100
103
  @action_spec = self.class.soap_actions[soap_action]
101
104
 
@@ -144,7 +147,7 @@ module WashOut
144
147
  return result_spec
145
148
  }
146
149
 
147
- render :template => "wash_with_soap/#{WashOut::Engine.style}/response",
150
+ render :template => "wash_with_soap/#{soap_config.wsdl_style}/response",
148
151
  :layout => false,
149
152
  :locals => { :result => inject.call(result, @action_spec[:out]) },
150
153
  :content_type => 'text/xml'
@@ -164,7 +167,7 @@ module WashOut
164
167
  # Rails do not support sequental rescue_from handling, that is, rescuing an
165
168
  # exception from a rescue_from handler. Hence this function is a public API.
166
169
  def render_soap_error(message)
167
- render :template => "wash_with_soap/#{WashOut::Engine.style}/error", :status => 500,
170
+ render :template => "wash_with_soap/#{soap_config.wsdl_style}/error", :status => 500,
168
171
  :layout => false,
169
172
  :locals => { :error_message => message },
170
173
  :content_type => 'text/xml'
@@ -173,9 +176,12 @@ module WashOut
173
176
  def self.included(controller)
174
177
  controller.send :rescue_from, SOAPError, :with => :_render_soap_exception
175
178
  controller.send :helper, :wash_out
176
- controller.send :before_filter, :_parse_soap_parameters, :except => [ :_generate_wsdl, :_invalid_action ]
177
- controller.send :before_filter, :_authenticate_wsse, :except => [ :_generate_wsdl, :_invalid_action ]
178
- controller.send :before_filter, :_map_soap_parameters, :except => [ :_generate_wsdl, :_invalid_action ]
179
+ controller.send :before_filter, :_parse_soap_parameters, :except => [
180
+ :_generate_wsdl, :_invalid_action ]
181
+ controller.send :before_filter, :_authenticate_wsse, :except => [
182
+ :_generate_wsdl, :_invalid_action ]
183
+ controller.send :before_filter, :_map_soap_parameters, :except => [
184
+ :_generate_wsdl, :_invalid_action ]
179
185
  controller.send :skip_before_filter, :verify_authenticity_token
180
186
  end
181
187
 
@@ -1,49 +1,9 @@
1
+
1
2
  module WashOut
2
3
  class Engine < ::Rails::Engine
3
- class << self
4
- attr_accessor :parser
5
- attr_accessor :namespace
6
- attr_accessor :style
7
- attr_accessor :snakecase, :camelize_output
8
- attr_accessor :snakecase_input, :camelize_wsdl
9
- attr_accessor :wsse_username, :wsse_password
10
- attr_accessor :catch_xml_errors
11
- end
12
-
13
- self.parser = :rexml
14
-
15
- self.namespace = 'urn:WashOut'
16
- self.style = 'rpc'
17
- self.snakecase = nil
18
-
19
- self.snakecase_input = false
20
- self.camelize_wsdl = false
21
-
22
- self.wsse_username = nil
23
- self.wsse_password = nil
24
-
25
4
  config.wash_out = ActiveSupport::OrderedOptions.new
26
-
27
5
  initializer "wash_out.configuration" do |app|
28
- app.config.wash_out.each do |key, value|
29
- self.class.send "#{key}=", value
30
- end
31
-
32
- app.config.wash_out.catch_xml_errors ||= false
33
-
34
- unless self.class.snakecase.nil?
35
- raise "Usage of wash_out.snakecase is deprecated. You should use wash_out.snakecase_input and wash_out.camelize_wsdl"
36
- end
37
-
38
- unless self.class.camelize_output.nil?
39
- raise "Usage of wash_out.camelize_output is deprecated. You should use wash_out.camelize_wsdl option instead"
40
- end
41
-
42
- unless ['rpc','document'].include? self.class.style
43
- raise "Invalid binding. Style must be one of #{['rpc','document'].join(',')}"
44
- end
45
-
46
- if self.class.catch_xml_errors
6
+ if app.config.wash_out[:catch_xml_errors]
47
7
  app.config.middleware.insert_after 'ActionDispatch::ShowExceptions', WashOut::Middleware
48
8
  end
49
9
  end
@@ -10,17 +10,17 @@ module WashOut
10
10
 
11
11
  # Defines a WSDL parameter with name +name+ and type specifier +type+.
12
12
  # The type specifier format is described in #parse_def.
13
- def initialize(name, type, multiplied = false)
13
+ def initialize(soap_config, name, type, multiplied = false)
14
14
  type ||= {}
15
-
15
+ @soap_config = soap_config
16
16
  @name = name.to_s
17
17
  @raw_name = name.to_s
18
18
  @map = {}
19
19
  @multiplied = multiplied
20
20
 
21
- if WashOut::Engine.camelize_wsdl.to_s == 'lower'
21
+ if soap_config.camelize_wsdl.to_s == 'lower'
22
22
  @name = @name.camelize(:lower)
23
- elsif WashOut::Engine.camelize_wsdl
23
+ elsif soap_config.camelize_wsdl
24
24
  @name = @name.camelize
25
25
  end
26
26
 
@@ -28,11 +28,11 @@ module WashOut
28
28
  @type = type.to_s
29
29
  elsif type.is_a?(Class)
30
30
  @type = 'struct'
31
- @map = self.class.parse_def(type.wash_out_param_map)
31
+ @map = self.class.parse_def(soap_config, type.wash_out_param_map)
32
32
  @source_class = type
33
33
  else
34
34
  @type = 'struct'
35
- @map = self.class.parse_def(type)
35
+ @map = self.class.parse_def(soap_config, type)
36
36
  end
37
37
  end
38
38
 
@@ -50,13 +50,13 @@ module WashOut
50
50
  data ||= {}
51
51
  if @multiplied
52
52
  data.map do |x|
53
- map_struct x do |param, data, elem|
54
- param.load(data, elem)
53
+ map_struct x do |param, dat, elem|
54
+ param.load(dat, elem)
55
55
  end
56
56
  end
57
57
  else
58
- map_struct data do |param, data, elem|
59
- param.load(data, elem)
58
+ map_struct data do |param, dat, elem|
59
+ param.load(dat, elem)
60
60
  end
61
61
  end
62
62
  else
@@ -64,7 +64,7 @@ module WashOut
64
64
  when 'string'; :to_s
65
65
  when 'integer'; :to_i
66
66
  when 'double'; :to_f
67
- when 'boolean'; lambda{|data| data === "0" ? false : !!data}
67
+ when 'boolean'; lambda{|dat| dat === "0" ? false : !!dat}
68
68
  when 'date'; :to_date
69
69
  when 'datetime'; :to_datetime
70
70
  when 'time'; :to_time
@@ -99,7 +99,7 @@ module WashOut
99
99
 
100
100
  def basic_type
101
101
  return name unless classified?
102
- return source_class.wash_out_param_name
102
+ return source_class.wash_out_param_name(@soap_config)
103
103
  end
104
104
 
105
105
  def xsd_type
@@ -129,7 +129,7 @@ module WashOut
129
129
  # +:parameter_name+ is ignored.
130
130
  #
131
131
  # This function returns an array of WashOut::Param objects.
132
- def self.parse_def(definition)
132
+ def self.parse_def(soap_config, definition)
133
133
  raise RuntimeError, "[] should not be used in your params. Use nil if you want to mark empty set." if definition == []
134
134
  return [] if definition == nil
135
135
 
@@ -146,9 +146,9 @@ module WashOut
146
146
  if opt.is_a? WashOut::Param
147
147
  opt
148
148
  elsif opt.is_a? Array
149
- WashOut::Param.new(name, opt[0], true)
149
+ WashOut::Param.new(soap_config, name, opt[0], true)
150
150
  else
151
- WashOut::Param.new(name, opt)
151
+ WashOut::Param.new(soap_config, name, opt)
152
152
  end
153
153
  end
154
154
  else
@@ -157,7 +157,7 @@ module WashOut
157
157
  end
158
158
 
159
159
  def flat_copy
160
- copy = self.class.new(@name, @type.to_sym, @multiplied)
160
+ copy = self.class.new(@soap_config, @name, @type.to_sym, @multiplied)
161
161
  copy.raw_name = raw_name
162
162
  copy
163
163
  end
@@ -13,8 +13,8 @@ module WashOut
13
13
  # RUBY18 1.8 does not have force_encoding.
14
14
  soap_action.force_encoding('UTF-8') if soap_action.respond_to? :force_encoding
15
15
 
16
- if WashOut::Engine.namespace
17
- namespace = Regexp.escape WashOut::Engine.namespace.to_s
16
+ if controller.soap_config.namespace
17
+ namespace = Regexp.escape controller.soap_config.namespace.to_s
18
18
  soap_action.gsub!(/^\"(#{namespace}(\/|#)?)?(.*)\"$/, '\3')
19
19
  else
20
20
  soap_action = soap_action[1...-1]
data/lib/wash_out/soap.rb CHANGED
@@ -15,21 +15,22 @@ module WashOut
15
15
  # which are not valid Ruby function names.
16
16
  def soap_action(action, options={})
17
17
  if action.is_a?(Symbol)
18
- if WashOut::Engine.camelize_wsdl.to_s == 'lower'
18
+ if soap_config.camelize_wsdl.to_s == 'lower'
19
19
  options[:to] ||= action.to_s
20
20
  action = action.to_s.camelize(:lower)
21
- elsif WashOut::Engine.camelize_wsdl
21
+ elsif soap_config.camelize_wsdl
22
22
  options[:to] ||= action.to_s
23
23
  action = action.to_s.camelize
24
24
  end
25
+
25
26
  end
26
27
 
27
- default_response_tag = WashOut::Engine.camelize_wsdl ? 'Response' : '_response'
28
+ default_response_tag = soap_config.camelize_wsdl ? 'Response' : '_response'
28
29
  default_response_tag = "tns:#{action}#{default_response_tag}"
29
30
 
30
31
  self.soap_actions[action] = {
31
- :in => WashOut::Param.parse_def(options[:args]),
32
- :out => WashOut::Param.parse_def(options[:return]),
32
+ :in => WashOut::Param.parse_def(soap_config, options[:args]),
33
+ :out => WashOut::Param.parse_def(soap_config, options[:return]),
33
34
  :to => options[:to] || action,
34
35
  :response_tag => options[:response_tag] || default_response_tag
35
36
  }
@@ -37,6 +38,7 @@ module WashOut
37
38
  end
38
39
 
39
40
  included do
41
+ include WashOut::Configurable
40
42
  include WashOut::Dispatcher
41
43
  self.soap_actions = {}
42
44
  end
@@ -0,0 +1,91 @@
1
+ module WashOut
2
+ require 'forwardable'
3
+ # Configuration options for {Client}, defaulting to values
4
+ # in {Default}
5
+ class SoapConfig
6
+ extend Forwardable
7
+ DEFAULT_CONFIG = {
8
+ parser: :rexml,
9
+ namespace: 'urn:WashOut',
10
+ wsdl_style: 'rpc',
11
+ snakecase_input: false,
12
+ camelize_wsdl: false,
13
+ catch_xml_errors: false,
14
+ wsse_username: nil,
15
+ wsse_password: nil,
16
+ }
17
+
18
+ attr_reader :config
19
+ def_delegators :@config, :[], :[]=, :sort
20
+
21
+
22
+ # The keys allowed
23
+ def self.keys
24
+ @keys ||= config.keys
25
+ end
26
+
27
+ def self.config
28
+ DEFAULT_CONFIG
29
+ end
30
+
31
+ def self.soap_accessor(*syms)
32
+ syms.each do |sym|
33
+
34
+ unless sym =~ /^[_A-Za-z]\w*$/
35
+ raise NameError.new("invalid class attribute name: #{sym}")
36
+ end
37
+ class_eval(<<-EOS, __FILE__, __LINE__ + 1)
38
+ unless defined? @#{sym}
39
+ @#{sym} = nil
40
+ end
41
+
42
+ def #{sym}
43
+ @#{sym}
44
+ end
45
+
46
+ def #{sym}=(obj)
47
+ @#{sym} = obj
48
+ end
49
+ EOS
50
+ end
51
+ end
52
+
53
+ soap_accessor(*WashOut::SoapConfig.keys)
54
+
55
+ def initialize(options = {})
56
+ @config = {}
57
+ options.reverse_merge!(engine_config) if engine_config
58
+ options.reverse_merge!(DEFAULT_CONFIG)
59
+ configure options
60
+ end
61
+
62
+ def default?
63
+ DEFAULT_CONFIG.sort == config.sort
64
+ end
65
+
66
+ def configure(options = {})
67
+ @config.merge! validate_config!(options)
68
+
69
+ config.each do |key,value|
70
+ send("#{key}=", value)
71
+ end
72
+ end
73
+
74
+ private
75
+
76
+ def engine_config
77
+ @engine_config ||= WashOut::Engine.config.wash_out
78
+ end
79
+
80
+ def validate_config!(options = {})
81
+ rejected_keys = options.keys.reject do |key|
82
+ WashOut::SoapConfig.keys.include?(key)
83
+ end
84
+
85
+ if rejected_keys.any?
86
+ raise "The following keys are not allows: #{rejected_keys}\n Did you intend for one of the following? #{WashOut::SoapConfig.keys}"
87
+ end
88
+ options
89
+ end
90
+ end
91
+ end
data/lib/wash_out/type.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  module WashOut
2
2
  class Type
3
+
3
4
  def self.type_name(value)
4
5
  @param_type_name = value
5
6
  end
@@ -13,15 +14,15 @@ module WashOut
13
14
  @param_map
14
15
  end
15
16
 
16
- def self.wash_out_param_name
17
+ def self.wash_out_param_name(soap_config = nil)
18
+ soap_config ||= WashOut::SoapConfig.new({})
17
19
  @param_type_name ||= name.underscore.gsub '/', '.'
18
20
 
19
- if WashOut::Engine.camelize_wsdl.to_s == 'lower'
21
+ if soap_config.camelize_wsdl.to_s == 'lower'
20
22
  @param_type_name = @param_type_name.camelize(:lower)
21
- elsif WashOut::Engine.camelize_wsdl
23
+ elsif soap_config.camelize_wsdl
22
24
  @param_type_name = @param_type_name.camelize
23
25
  end
24
-
25
26
  @param_type_name
26
27
  end
27
28
  end
@@ -1,3 +1,3 @@
1
1
  module WashOut
2
- VERSION = "0.8.4"
2
+ VERSION = "0.9.0.beta.1"
3
3
  end
data/lib/wash_out/wsse.rb CHANGED
@@ -1,15 +1,16 @@
1
1
  module WashOut
2
2
  class Wsse
3
-
4
- def self.authenticate(token)
5
- wsse = self.new(token)
3
+ attr_reader :soap_config
4
+ def self.authenticate(soap_config, token)
5
+ wsse = self.new(soap_config, token)
6
6
 
7
7
  unless wsse.eligible?
8
8
  raise WashOut::Dispatcher::SOAPError, "Unauthorized"
9
9
  end
10
10
  end
11
11
 
12
- def initialize(token)
12
+ def initialize(soap_config, token)
13
+ @soap_config = soap_config
13
14
  if token.blank? && required?
14
15
  raise WashOut::Dispatcher::SOAPError, "Missing required UsernameToken"
15
16
  end
@@ -17,15 +18,15 @@ module WashOut
17
18
  end
18
19
 
19
20
  def required?
20
- !WashOut::Engine.wsse_username.blank?
21
+ !soap_config.wsse_username.blank?
21
22
  end
22
23
 
23
24
  def expected_user
24
- WashOut::Engine.wsse_username
25
+ soap_config.wsse_username
25
26
  end
26
27
 
27
28
  def expected_password
28
- WashOut::Engine.wsse_password
29
+ soap_config.wsse_password
29
30
  end
30
31
 
31
32
  def matches_expected_digest?(password)
data/lib/wash_out.rb CHANGED
@@ -1,3 +1,6 @@
1
+ require 'wash_out/configurable'
2
+ require 'wash_out/soap_config'
3
+ require 'wash_out/soap'
1
4
  require 'wash_out/engine'
2
5
  require 'wash_out/param'
3
6
  require 'wash_out/dispatcher'
@@ -28,9 +31,17 @@ ActionController::Renderers.add :soap do |what, options|
28
31
  _render_soap(what, options)
29
32
  end
30
33
 
31
- module ActionView
32
- class Base
33
- cattr_accessor :washout_namespace
34
- @@washout_namespace = false
34
+ ActionController::Base.class_eval do
35
+
36
+ # Define a SOAP service. The function has no required +options+:
37
+ # but allow any of :parser, :namespace, :wsdl_style, :snakecase_input,
38
+ # :camelize_wsdl, :wsse_username, :wsse_password and :catch_xml_errors.
39
+ #
40
+ # Any of the the params provided allows for overriding the defaults
41
+ # (like supporting multiple namespaces instead of application wide such)
42
+ #
43
+ def self.soap_service(options={})
44
+ include WashOut::SOAP
45
+ self.soap_config = options
35
46
  end
36
- end
47
+ end
@@ -5,7 +5,7 @@ require 'spec_helper'
5
5
  describe WashOut::Dispatcher do
6
6
 
7
7
  class Dispatcher < ApplicationController
8
- include WashOut::SOAP
8
+ soap_service
9
9
 
10
10
  def self.mock(text="")
11
11
  dispatcher = self.new
@@ -60,27 +60,27 @@ describe WashOut::Dispatcher do
60
60
 
61
61
  describe "#_load_params" do
62
62
  let(:dispatcher) { Dispatcher.new }
63
-
63
+ let(:soap_config) { WashOut::SoapConfig.new({ camelize_wsdl: false }) }
64
64
  it "should load params for an array" do
65
- spec = WashOut::Param.parse_def( {:my_array => [:integer] } )
65
+ spec = WashOut::Param.parse_def(soap_config, {:my_array => [:integer] } )
66
66
  xml_data = {:my_array => [1, 2, 3]}
67
67
  dispatcher._load_params(spec, xml_data).should == {"my_array" => [1, 2, 3]}
68
68
  end
69
69
 
70
70
  it "should load params for an empty array" do
71
- spec = WashOut::Param.parse_def( {:my_array => [:integer] } )
71
+ spec = WashOut::Param.parse_def(soap_config, {:my_array => [:integer] } )
72
72
  xml_data = {}
73
73
  dispatcher._load_params(spec, xml_data).should == {}
74
74
  end
75
75
 
76
76
  it "should load params for a nested array" do
77
- spec = WashOut::Param.parse_def( {:nested => {:my_array => [:integer]}} )
77
+ spec = WashOut::Param.parse_def(soap_config, {:nested => {:my_array => [:integer]}} )
78
78
  xml_data = {:nested => {:my_array => [1, 2, 3]}}
79
79
  dispatcher._load_params(spec, xml_data).should == {"nested" => {"my_array" => [1, 2, 3]}}
80
80
  end
81
81
 
82
82
  it "should load params for an empty nested array" do
83
- spec = WashOut::Param.parse_def( {:nested => {:empty => [:integer] }} )
83
+ spec = WashOut::Param.parse_def(soap_config, {:nested => {:empty => [:integer] }} )
84
84
  xml_data = {:nested => nil}
85
85
  dispatcher._load_params(spec, xml_data).should == {"nested" => {}}
86
86
  end
@@ -5,18 +5,21 @@ require 'spec_helper'
5
5
  describe WashOut::Param do
6
6
 
7
7
  context "custom types" do
8
+
8
9
  class Abraka1 < WashOut::Type
9
10
  map(
10
11
  :test => :string
11
12
  )
12
13
  end
14
+
13
15
  class Abraka2 < WashOut::Type
14
16
  type_name 'test'
15
17
  map :foo => Abraka1
16
18
  end
17
19
 
18
20
  it "loads custom_types" do
19
- map = WashOut::Param.parse_def Abraka2
21
+ soap_config = WashOut::SoapConfig.new({ camelize_wsdl: false })
22
+ map = WashOut::Param.parse_def soap_config, Abraka2
20
23
 
21
24
  map.should be_a_kind_of(Array)
22
25
  map[0].name.should == 'foo'
@@ -24,9 +27,9 @@ describe WashOut::Param do
24
27
  end
25
28
 
26
29
  it "respects camelization setting" do
27
- WashOut::Engine.camelize_wsdl = true
30
+ soap_config = WashOut::SoapConfig.new({ camelize_wsdl: true })
28
31
 
29
- map = WashOut::Param.parse_def Abraka2
32
+ map = WashOut::Param.parse_def soap_config, Abraka2
30
33
 
31
34
  map.should be_a_kind_of(Array)
32
35
  map[0].name.should == 'Foo'
@@ -35,14 +38,16 @@ describe WashOut::Param do
35
38
  end
36
39
 
37
40
  it "should accept nested empty arrays" do
38
- map = WashOut::Param.parse_def( {:nested => {:some_attr => :string, :empty => [:integer] }} )
41
+ soap_config = WashOut::SoapConfig.new({ camelize_wsdl: false })
42
+ map = WashOut::Param.parse_def(soap_config, {:nested => {:some_attr => :string, :empty => [:integer] }} )
39
43
  map[0].load( {:nested => nil}, :nested).should == {}
40
44
  end
41
45
 
42
46
  describe "booleans" do
47
+ let(:soap_config) { WashOut::SoapConfig.new({ camelize_wsdl: false }) }
43
48
  # following http://www.w3.org/TR/xmlschema-2/#boolean, only true, false, 0 and 1 are allowed.
44
49
  # Nori maps the strings true and false to TrueClass and FalseClass, but not 0 and 1.
45
- let(:map) { WashOut::Param.parse_def(:value => :boolean) }
50
+ let(:map) { WashOut::Param.parse_def(soap_config, :value => :boolean) }
46
51
 
47
52
  it "should accept 'true' and '1'" do
48
53
  map[0].load({:value => true}, :value).should be_true
@@ -5,9 +5,11 @@ require 'spec_helper'
5
5
  describe WashOut::Type do
6
6
 
7
7
  it "defines custom type" do
8
+
8
9
  class Abraka1 < WashOut::Type
9
10
  map :test => :string
10
11
  end
12
+
11
13
  class Abraka2 < WashOut::Type
12
14
  type_name 'test'
13
15
  map :foo => Abraka1
@@ -3,11 +3,6 @@
3
3
  require 'spec_helper'
4
4
 
5
5
  describe WashOut do
6
- before :each do
7
- WashOut::Engine.snakecase_input = true
8
- WashOut::Engine.camelize_wsdl = true
9
- WashOut::Engine.namespace = false
10
- end
11
6
 
12
7
  let :nori do
13
8
  Nori.new(
@@ -54,11 +49,12 @@ describe WashOut do
54
49
  mock_controller do
55
50
  soap_action :result, :args => nil, :return => :int
56
51
 
57
- soap_action "getArea", :args => { :circle => [{ :center => { :x => [:integer],
58
- :y => :integer },
59
- :radius => :double }] },
60
- :return => { :area => :double }
61
-
52
+ soap_action "getArea", :args => {
53
+ :circle => [{
54
+ :center => { :x => [:integer], :y => :integer },
55
+ :radius => :double
56
+ }]},
57
+ :return => { :area => :double }
62
58
  soap_action "rocky", :args => { :circle1 => { :x => :integer } },
63
59
  :return => { :circle2 => { :y => :integer } }
64
60
  end
@@ -429,7 +425,7 @@ describe WashOut do
429
425
  context "errors" do
430
426
  it "raise for incorrect requests" do
431
427
  mock_controller do
432
- soap_action "duty",
428
+ soap_action "duty",
433
429
  :args => {:bad => {:a => :string, :b => :string}, :good => {:a => :string, :b => :string}},
434
430
  :return => nil
435
431
  def duty
@@ -564,10 +560,7 @@ describe WashOut do
564
560
  end
565
561
 
566
562
  it "handles snakecase option properly" do
567
- WashOut::Engine.snakecase_input = false
568
- WashOut::Engine.camelize_wsdl = false
569
-
570
- mock_controller do
563
+ mock_controller(snakecase_input: false, camelize_wsdl: false) do
571
564
  soap_action "rocknroll", :args => {:ZOMG => :string}, :return => nil
572
565
  def rocknroll
573
566
  params["ZOMG"].should == "yam!"
@@ -583,10 +576,7 @@ describe WashOut do
583
576
  describe "WS Security" do
584
577
 
585
578
  it "appends username_token to params" do
586
- WashOut::Engine.wsse_username = nil
587
- WashOut::Engine.wsse_password = nil
588
-
589
- mock_controller do
579
+ mock_controller(wsse_username: "gorilla", wsse_password: "secret") do
590
580
  soap_action "checkToken", :args => :integer, :return => nil, :to => 'check_token'
591
581
  def check_token
592
582
  request.env['WSSE_TOKEN']['username'].should == "gorilla"
@@ -601,10 +591,7 @@ describe WashOut do
601
591
  end
602
592
 
603
593
  it "handles PasswordText auth" do
604
- WashOut::Engine.wsse_username = "gorilla"
605
- WashOut::Engine.wsse_password = "secret"
606
-
607
- mock_controller do
594
+ mock_controller(wsse_username: "gorilla", wsse_password: "secret") do
608
595
  soap_action "checkAuth", :args => :integer, :return => :boolean, :to => 'check_auth'
609
596
  def check_auth
610
597
  render :soap => (params[:value] == 42)
@@ -629,10 +616,7 @@ describe WashOut do
629
616
  end
630
617
 
631
618
  it "handles PasswordDigest auth" do
632
- WashOut::Engine.wsse_username = "gorilla"
633
- WashOut::Engine.wsse_password = "secret"
634
-
635
- mock_controller do
619
+ mock_controller(wsse_username: "gorilla", wsse_password: "secret") do
636
620
  soap_action "checkAuth", :args => :integer, :return => :boolean, :to => 'check_auth'
637
621
  def check_auth
638
622
  render :soap => (params[:value] == 42)
data/spec/spec_helper.rb CHANGED
@@ -27,9 +27,11 @@ RSpec.configure do |config|
27
27
 
28
28
  config.mock_with :rspec
29
29
  config.before(:all) do
30
- WashOut::Engine.snakecase_input = false
31
- WashOut::Engine.camelize_wsdl = false
32
- WashOut::Engine.namespace = false
30
+ WashOut::Engine.config.wash_out = {
31
+ snakecase_input: false,
32
+ camelize_wsdl: false,
33
+ namespace: false
34
+ }
33
35
  end
34
36
 
35
37
  config.after(:suite) do
@@ -51,11 +53,14 @@ Dummy::Application.routes.draw do
51
53
  wash_out :api
52
54
  end
53
55
 
54
- def mock_controller(&block)
56
+ def mock_controller(options = {}, &block)
55
57
  Object.send :remove_const, :ApiController if defined?(ApiController)
56
58
  Object.send :const_set, :ApiController, Class.new(ApplicationController) {
57
- include WashOut::SOAP
58
-
59
+ soap_service options.reverse_merge({
60
+ snakecase_input: true,
61
+ camelize_wsdl: true,
62
+ namespace: false
63
+ })
59
64
  class_exec &block if block
60
65
  }
61
66
 
data/wash_out.gemspec CHANGED
@@ -12,6 +12,9 @@ Gem::Specification.new do |s|
12
12
 
13
13
  s.files = `git ls-files`.split("\n")
14
14
  s.require_paths = ["lib"]
15
-
15
+ s.post_install_message = <<-EOS
16
+ Please replace `include WashOut::SOAP` with `soap_service`
17
+ in your controllers if you are upgrading from a version before 0.8.5.
18
+ EOS
16
19
  s.add_dependency("nori", ">= 2.0.0")
17
20
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: wash_out
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.4
4
+ version: 0.9.0.beta.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Boris Staal
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-09-03 00:00:00.000000000 Z
12
+ date: 2013-09-08 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: nori
@@ -50,6 +50,7 @@ files:
50
50
  - app/views/wash_with_soap/rpc/wsdl.builder
51
51
  - init.rb
52
52
  - lib/wash_out.rb
53
+ - lib/wash_out/configurable.rb
53
54
  - lib/wash_out/dispatcher.rb
54
55
  - lib/wash_out/engine.rb
55
56
  - lib/wash_out/middleware.rb
@@ -57,6 +58,7 @@ files:
57
58
  - lib/wash_out/param.rb
58
59
  - lib/wash_out/router.rb
59
60
  - lib/wash_out/soap.rb
61
+ - lib/wash_out/soap_config.rb
60
62
  - lib/wash_out/type.rb
61
63
  - lib/wash_out/version.rb
62
64
  - lib/wash_out/wsse.rb
@@ -93,7 +95,9 @@ files:
93
95
  homepage: http://github.com/inossidabile/wash_out/
94
96
  licenses: []
95
97
  metadata: {}
96
- post_install_message:
98
+ post_install_message: |2
99
+ Please replace `include WashOut::SOAP` with `soap_service`
100
+ in your controllers if you are upgrading from a version before 0.8.5.
97
101
  rdoc_options: []
98
102
  require_paths:
99
103
  - lib
@@ -104,9 +108,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
104
108
  version: '0'
105
109
  required_rubygems_version: !ruby/object:Gem::Requirement
106
110
  requirements:
107
- - - '>='
111
+ - - '>'
108
112
  - !ruby/object:Gem::Version
109
- version: '0'
113
+ version: 1.3.1
110
114
  requirements: []
111
115
  rubyforge_project:
112
116
  rubygems_version: 2.0.6