wash-out 0.10.1

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.
Files changed (70) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/.rspec +1 -0
  4. data/.travis.yml +35 -0
  5. data/Appraisals +25 -0
  6. data/CHANGELOG.md +102 -0
  7. data/Gemfile +16 -0
  8. data/Guardfile +12 -0
  9. data/LICENSE +22 -0
  10. data/README.md +246 -0
  11. data/Rakefile +13 -0
  12. data/app/helpers/wash_out_helper.rb +106 -0
  13. data/app/views/wash_out/document/error.builder +9 -0
  14. data/app/views/wash_out/document/response.builder +10 -0
  15. data/app/views/wash_out/document/wsdl.builder +68 -0
  16. data/app/views/wash_out/rpc/error.builder +10 -0
  17. data/app/views/wash_out/rpc/response.builder +11 -0
  18. data/app/views/wash_out/rpc/wsdl.builder +68 -0
  19. data/gemfiles/rails_3.1.3.gemfile +20 -0
  20. data/gemfiles/rails_3.2.12.gemfile +20 -0
  21. data/gemfiles/rails_4.0.0.gemfile +19 -0
  22. data/gemfiles/rails_4.1.0.gemfile +19 -0
  23. data/gemfiles/rails_4.2.0.gemfile +19 -0
  24. data/gemfiles/rails_5.0.0.beta2.gemfile +19 -0
  25. data/init.rb +1 -0
  26. data/lib/wash_out.rb +53 -0
  27. data/lib/wash_out/configurable.rb +41 -0
  28. data/lib/wash_out/dispatcher.rb +218 -0
  29. data/lib/wash_out/engine.rb +12 -0
  30. data/lib/wash_out/middleware.rb +41 -0
  31. data/lib/wash_out/model.rb +29 -0
  32. data/lib/wash_out/param.rb +200 -0
  33. data/lib/wash_out/router.rb +95 -0
  34. data/lib/wash_out/soap.rb +48 -0
  35. data/lib/wash_out/soap_config.rb +93 -0
  36. data/lib/wash_out/type.rb +29 -0
  37. data/lib/wash_out/version.rb +3 -0
  38. data/lib/wash_out/wsse.rb +101 -0
  39. data/spec/dummy/Rakefile +7 -0
  40. data/spec/dummy/app/controllers/application_controller.rb +3 -0
  41. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  42. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  43. data/spec/dummy/config.ru +4 -0
  44. data/spec/dummy/config/application.rb +51 -0
  45. data/spec/dummy/config/boot.rb +10 -0
  46. data/spec/dummy/config/environment.rb +5 -0
  47. data/spec/dummy/config/environments/development.rb +23 -0
  48. data/spec/dummy/config/environments/test.rb +30 -0
  49. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  50. data/spec/dummy/config/initializers/inflections.rb +10 -0
  51. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  52. data/spec/dummy/config/initializers/secret_token.rb +8 -0
  53. data/spec/dummy/config/initializers/session_store.rb +8 -0
  54. data/spec/dummy/config/locales/en.yml +5 -0
  55. data/spec/dummy/config/routes.rb +58 -0
  56. data/spec/dummy/public/404.html +26 -0
  57. data/spec/dummy/public/422.html +26 -0
  58. data/spec/dummy/public/500.html +26 -0
  59. data/spec/dummy/public/favicon.ico +0 -0
  60. data/spec/dummy/public/stylesheets/.gitkeep +0 -0
  61. data/spec/dummy/script/rails +6 -0
  62. data/spec/lib/wash_out/dispatcher_spec.rb +99 -0
  63. data/spec/lib/wash_out/middleware_spec.rb +33 -0
  64. data/spec/lib/wash_out/param_spec.rb +94 -0
  65. data/spec/lib/wash_out/router_spec.rb +22 -0
  66. data/spec/lib/wash_out/type_spec.rb +41 -0
  67. data/spec/lib/wash_out_spec.rb +754 -0
  68. data/spec/spec_helper.rb +82 -0
  69. data/wash_out.gemspec +21 -0
  70. metadata +128 -0
@@ -0,0 +1,13 @@
1
+ require 'bundler/setup'
2
+ require 'bundler/gem_tasks'
3
+ require 'appraisal'
4
+ require 'rspec/core/rake_task'
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ task :console do
9
+ require "action_controller/railtie"
10
+ require "rails/test_unit/railtie"
11
+ Bundler.require
12
+ binding.pry
13
+ end
@@ -0,0 +1,106 @@
1
+ module WashOutHelper
2
+
3
+ def wsdl_data_options(param)
4
+ case controller.soap_config.wsdl_style
5
+ when 'rpc'
6
+ { :"xsi:type" => param.namespaced_type }
7
+ when 'document'
8
+ { }
9
+ end
10
+ end
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
+
22
+ def wsdl_data(xml, params)
23
+ params.each do |param|
24
+ next if param.attribute?
25
+
26
+ tag_name = param.name
27
+ param_options = wsdl_data_options(param)
28
+ param_options.merge! wsdl_data_attrs(param)
29
+
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
40
+ else
41
+ xml.tag! tag_name, param_options do
42
+ wsdl_data(xml, param.map)
43
+ end
44
+ end
45
+ else
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
50
+ end
51
+ else
52
+ xml.tag! tag_name, param.value, param_options
53
+ end
54
+ end
55
+ end
56
+ end
57
+
58
+ def wsdl_type(xml, param, defined=[])
59
+ more = []
60
+
61
+ if param.struct?
62
+ if !defined.include?(param.basic_type)
63
+ xml.tag! "xsd:complexType", :name => param.basic_type do
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
79
+ end
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
85
+ end
86
+
87
+ defined << param.basic_type
88
+ elsif !param.classified?
89
+ raise RuntimeError, "Duplicate use of `#{param.basic_type}` type name. Consider using classified types."
90
+ end
91
+ end
92
+
93
+ more.each do |p|
94
+ wsdl_type xml, p, defined
95
+ end
96
+ end
97
+
98
+ def wsdl_occurence(param, inject, extend_with = {})
99
+ data = !param.multiplied ? {} : {
100
+ "#{'xsi:' if inject}minOccurs" => 0,
101
+ "#{'xsi:' if inject}maxOccurs" => 'unbounded'
102
+ }
103
+
104
+ extend_with.merge(data)
105
+ end
106
+ end
@@ -0,0 +1,9 @@
1
+ xml.instruct!
2
+ xml.tag! "soap:Envelope", "xmlns:soap" => 'http://schemas.xmlsoap.org/soap/envelope/' do
3
+ xml.tag! "soap:Body" do
4
+ xml.tag! "soap:Fault" do
5
+ xml.faultcode error_code
6
+ xml.faultstring error_message
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,10 @@
1
+ xml.instruct!
2
+ xml.tag! "soap:Envelope", "xmlns:soap" => 'http://schemas.xmlsoap.org/soap/envelope/',
3
+ "xmlns:xsd" => 'http://www.w3.org/2001/XMLSchema',
4
+ "xmlns:tns" => @namespace do
5
+ xml.tag! "soap:Body" do
6
+ xml.tag! "tns:#{@action_spec[:response_tag]}" do
7
+ wsdl_data xml, result
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,68 @@
1
+ xml.instruct!
2
+ xml.definitions 'xmlns' => 'http://schemas.xmlsoap.org/wsdl/',
3
+ 'xmlns:tns' => @namespace,
4
+ 'xmlns:soap' => 'http://schemas.xmlsoap.org/wsdl/soap/',
5
+ 'xmlns:xsd' => 'http://www.w3.org/2001/XMLSchema',
6
+ 'xmlns:soap-enc' => 'http://schemas.xmlsoap.org/soap/encoding/',
7
+ 'xmlns:wsdl' => 'http://schemas.xmlsoap.org/wsdl/',
8
+ 'name' => @name,
9
+ 'targetNamespace' => @namespace do
10
+
11
+ xml.types do
12
+ xml.tag! "schema", :targetNamespace => @namespace, :xmlns => 'http://www.w3.org/2001/XMLSchema' do
13
+ defined = []
14
+ @map.each do |operation, formats|
15
+ (formats[:in] + formats[:out]).each do |p|
16
+ wsdl_type xml, p, defined
17
+ end
18
+ end
19
+ end
20
+ end
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
+
35
+ xml.portType :name => "#{@name}_port" do
36
+ @map.each do |operation, formats|
37
+ xml.operation :name => operation do
38
+ xml.input :message => "tns:#{operation}"
39
+ xml.output :message => "tns:#{formats[:response_tag]}"
40
+ end
41
+ end
42
+ end
43
+
44
+ xml.binding :name => "#{@name}_binding", :type => "tns:#{@name}_port" do
45
+ xml.tag! "soap:binding", :style => 'document', :transport => 'http://schemas.xmlsoap.org/soap/http'
46
+ @map.keys.each do |operation|
47
+ xml.operation :name => operation do
48
+ xml.tag! "soap:operation", :soapAction => operation
49
+ xml.input do
50
+ xml.tag! "soap:body",
51
+ :use => "literal",
52
+ :namespace => @namespace
53
+ end
54
+ xml.output do
55
+ xml.tag! "soap:body",
56
+ :use => "literal",
57
+ :namespace => @namespace
58
+ end
59
+ end
60
+ end
61
+ end
62
+
63
+ xml.service :name => "service" do
64
+ xml.port :name => "#{@name}_port", :binding => "tns:#{@name}_binding" do
65
+ xml.tag! "soap:address", :location => send("#{@name}_action_url")
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,10 @@
1
+ xml.instruct!
2
+ xml.tag! "soap:Envelope", "xmlns:soap" => 'http://schemas.xmlsoap.org/soap/envelope/',
3
+ "xmlns:xsi" => 'http://www.w3.org/2001/XMLSchema-instance' do
4
+ xml.tag! "soap:Body" do
5
+ xml.tag! "soap:Fault", :encodingStyle => 'http://schemas.xmlsoap.org/soap/encoding/' do
6
+ xml.faultcode error_code, 'xsi:type' => 'xsd:QName'
7
+ xml.faultstring error_message, 'xsi:type' => 'xsd:string'
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,11 @@
1
+ xml.instruct!
2
+ xml.tag! "soap:Envelope", "xmlns:soap" => 'http://schemas.xmlsoap.org/soap/envelope/',
3
+ "xmlns:xsd" => 'http://www.w3.org/2001/XMLSchema',
4
+ "xmlns:xsi" => 'http://www.w3.org/2001/XMLSchema-instance',
5
+ "xmlns:tns" => @namespace do
6
+ xml.tag! "soap:Body" do
7
+ xml.tag! "tns:#{@action_spec[:response_tag]}" do
8
+ wsdl_data xml, result
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,68 @@
1
+ xml.instruct!
2
+ xml.definitions 'xmlns' => 'http://schemas.xmlsoap.org/wsdl/',
3
+ 'xmlns:tns' => @namespace,
4
+ 'xmlns:soap' => 'http://schemas.xmlsoap.org/wsdl/soap/',
5
+ 'xmlns:xsd' => 'http://www.w3.org/2001/XMLSchema',
6
+ 'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance',
7
+ 'xmlns:soap-enc' => 'http://schemas.xmlsoap.org/soap/encoding/',
8
+ 'xmlns:wsdl' => 'http://schemas.xmlsoap.org/wsdl/',
9
+ 'name' => @name,
10
+ 'targetNamespace' => @namespace do
11
+ xml.types do
12
+ xml.tag! "schema", :targetNamespace => @namespace, :xmlns => 'http://www.w3.org/2001/XMLSchema' do
13
+ defined = []
14
+ @map.each do |operation, formats|
15
+ (formats[:in] + formats[:out]).each do |p|
16
+ wsdl_type xml, p, defined
17
+ end
18
+ end
19
+ end
20
+ end
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
+
35
+ xml.portType :name => "#{@name}_port" do
36
+ @map.each do |operation, formats|
37
+ xml.operation :name => operation do
38
+ xml.input :message => "tns:#{operation}"
39
+ xml.output :message => "tns:#{formats[:response_tag]}"
40
+ end
41
+ end
42
+ end
43
+
44
+ xml.binding :name => "#{@name}_binding", :type => "tns:#{@name}_port" do
45
+ xml.tag! "soap:binding", :style => 'rpc', :transport => 'http://schemas.xmlsoap.org/soap/http'
46
+ @map.keys.each do |operation|
47
+ xml.operation :name => operation do
48
+ xml.tag! "soap:operation", :soapAction => operation
49
+ xml.input do
50
+ xml.tag! "soap:body",
51
+ :use => "encoded", :encodingStyle => 'http://schemas.xmlsoap.org/soap/encoding/',
52
+ :namespace => @namespace
53
+ end
54
+ xml.output do
55
+ xml.tag! "soap:body",
56
+ :use => "encoded", :encodingStyle => 'http://schemas.xmlsoap.org/soap/encoding/',
57
+ :namespace => @namespace
58
+ end
59
+ end
60
+ end
61
+ end
62
+
63
+ xml.service :name => "service" do
64
+ xml.port :name => "#{@name}_port", :binding => "tns:#{@name}_binding" do
65
+ xml.tag! "soap:address", :location => send("#{@name}_action_url")
66
+ end
67
+ 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 => "../"
@@ -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.2.12"
18
+ gem "test-unit"
19
+
20
+ gemspec :path => "../"
@@ -0,0 +1,19 @@
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", "4.0.0"
18
+
19
+ gemspec :path => "../"
@@ -0,0 +1,19 @@
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", "4.1.0"
18
+
19
+ gemspec :path => "../"
@@ -0,0 +1,19 @@
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", "4.2.0"
18
+
19
+ gemspec :path => "../"
@@ -0,0 +1,19 @@
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.0.0.beta2"
18
+
19
+ gemspec :path => "../"
data/init.rb ADDED
@@ -0,0 +1 @@
1
+ require 'wash_out'
@@ -0,0 +1,53 @@
1
+ require 'wash_out/configurable'
2
+ require 'wash_out/soap_config'
3
+ require 'wash_out/soap'
4
+ require 'wash_out/engine'
5
+ require 'wash_out/param'
6
+ require 'wash_out/dispatcher'
7
+ require 'wash_out/soap'
8
+ require 'wash_out/router'
9
+ require 'wash_out/type'
10
+ require 'wash_out/model'
11
+ require 'wash_out/wsse'
12
+ require 'wash_out/middleware'
13
+
14
+ module WashOut
15
+ def self.root
16
+ File.expand_path '../..', __FILE__
17
+ end
18
+ end
19
+
20
+ module ActionDispatch::Routing
21
+ class Mapper
22
+ # Adds the routes for a SOAP endpoint at +controller+.
23
+ def wash_out(controller_name, options={})
24
+ options.each_with_index { |key, value| @scope[key] = value } if @scope
25
+ controller_class_name = [options[:module], controller_name].compact.join("/")
26
+
27
+ match "#{controller_name}/wsdl" => "#{controller_name}#_generate_wsdl", :via => :get, :format => false
28
+ match "#{controller_name}/action" => WashOut::Router.new(controller_class_name), :via => [:get, :post], :defaults => { :controller => controller_class_name, :action => '_action' }, :format => false
29
+ end
30
+ end
31
+ end
32
+
33
+ Mime::Type.register "application/soap+xml", :soap
34
+ ActiveRecord::Base.send :extend, WashOut::Model if defined?(ActiveRecord)
35
+
36
+ ActionController::Renderers.add :soap do |what, options|
37
+ _render_soap(what, options)
38
+ end
39
+
40
+ ActionController::Base.class_eval do
41
+
42
+ # Define a SOAP service. The function has no required +options+:
43
+ # but allow any of :parser, :namespace, :wsdl_style, :snakecase_input,
44
+ # :camelize_wsdl, :wsse_username, :wsse_password and :catch_xml_errors.
45
+ #
46
+ # Any of the the params provided allows for overriding the defaults
47
+ # (like supporting multiple namespaces instead of application wide such)
48
+ #
49
+ def self.soap_service(options={})
50
+ include WashOut::SOAP
51
+ self.soap_config = options
52
+ end
53
+ end