From 95813714a517c4b882292059f30fcf3395000251 Mon Sep 17 00:00:00 2001 From: xhh Date: Fri, 22 May 2015 21:34:11 +0800 Subject: [PATCH 1/6] Add support of HTTP basic and API key auth to Ruby codegen --- .../src/main/resources/ruby/swagger.mustache | 6 +-- .../ruby/swagger/configuration.mustache | 6 ++- .../resources/ruby/swagger/request.mustache | 44 ++++++++++------ .../client/petstore/ruby/spec/request_spec.rb | 51 +++---------------- 4 files changed, 41 insertions(+), 66 deletions(-) diff --git a/modules/swagger-codegen/src/main/resources/ruby/swagger.mustache b/modules/swagger-codegen/src/main/resources/ruby/swagger.mustache index 750e6ac5155d..dd2f630a8c95 100644 --- a/modules/swagger-codegen/src/main/resources/ruby/swagger.mustache +++ b/modules/swagger-codegen/src/main/resources/ruby/swagger.mustache @@ -16,9 +16,9 @@ module {{moduleName}} # # @example # Swagger.configure do |config| - # config.api_key = '1234567890abcdef' # required - # config.username = 'wordlover' # optional, but needed for user-related functions - # config.password = 'i<3words' # optional, but needed for user-related functions + # config.api_key['api_key'] = '1234567890abcdef' # api key authentication + # config.username = 'wordlover' # http basic authentication + # config.password = 'i<3words' # http basic authentication # config.format = 'json' # optional, defaults to 'json' # end # diff --git a/modules/swagger-codegen/src/main/resources/ruby/swagger/configuration.mustache b/modules/swagger-codegen/src/main/resources/ruby/swagger/configuration.mustache index e780a9c8e7df..e64797979209 100644 --- a/modules/swagger-codegen/src/main/resources/ruby/swagger/configuration.mustache +++ b/modules/swagger-codegen/src/main/resources/ruby/swagger/configuration.mustache @@ -1,8 +1,8 @@ module {{moduleName}} module Swagger class Configuration - attr_accessor :format, :api_key, :username, :password, :auth_token, :scheme, :host, :base_path, :user_agent, :logger, :inject_format, :force_ending_format, :camelize_params, :user_agent - + attr_accessor :format, :api_key, :api_key_prefix, :username, :password, :auth_token, :scheme, :host, :base_path, :user_agent, :logger, :inject_format, :force_ending_format, :camelize_params, :user_agent + # Defaults go in here.. def initialize @format = 'json' @@ -13,6 +13,8 @@ module {{moduleName}} @inject_format = false @force_ending_format = false @camelize_params = true + @api_key = {} + @api_key_prefix = {} end end end diff --git a/modules/swagger-codegen/src/main/resources/ruby/swagger/request.mustache b/modules/swagger-codegen/src/main/resources/ruby/swagger/request.mustache index 14718bb6b3c3..1e04b92e23e9 100644 --- a/modules/swagger-codegen/src/main/resources/ruby/swagger/request.mustache +++ b/modules/swagger-codegen/src/main/resources/ruby/swagger/request.mustache @@ -13,24 +13,14 @@ module {{moduleName}} attributes[:format] ||= Swagger.configuration.format attributes[:params] ||= {} + update_params_for_auth(attributes) + # Set default headers default_headers = { 'Content-Type' => "application/#{attributes[:format].downcase}", - :api_key => Swagger.configuration.api_key, 'User-Agent' => Swagger.configuration.user_agent } - # api_key from headers hash trumps the default, even if its value is blank - if attributes[:headers].present? && attributes[:headers].has_key?(:api_key) - default_headers.delete(:api_key) - end - - # api_key from params hash trumps all others (headers and default_headers) - if attributes[:params].present? && attributes[:params].has_key?(:api_key) - default_headers.delete(:api_key) - attributes[:headers].delete(:api_key) if attributes[:headers].present? - end - # Merge argument headers into defaults attributes[:headers] = default_headers.merge(attributes[:headers] || {}) @@ -46,6 +36,31 @@ module {{moduleName}} end end + def update_params_for_auth(attributes) + (attributes[:auth_names] || []).each do |auth_name| + case auth_name + {{#authMethods}} + when '{{name}}' + {{#isApiKey}}{{#isKeyInHeader}}attributes[:headers] ||= {} + attributes[:headers]['{{keyParamName}}'] = get_api_key_with_prefix('{{keyParamName}}'){{/isKeyInHeader}}{{#isKeyInQuery}}attributes[:params] ||= {} + attributes[:params]['{{keyParamName}}'] = get_api_key_with_prefix('{{keyParamName}}'){{/isKeyInQuery}}{{/isApiKey}} + {{#isBasic}}attributes[:headers] ||= {} + http_auth_header = 'Basic ' + ["#{Swagger.configuration.username}:#{Swagger.configuration.password}"].pack('m').delete("\r\n") + attributes[:headers]['Authorization'] = http_auth_header{{/isBasic}} + {{#isOAuth}}# TODO: support oauth{{/isOAuth}} + {{/authMethods}} + end + end + end + + def get_api_key_with_prefix(param_name) + if Swagger.configuration.api_key_prefix[param_name].present? + "#{Swagger.configuration.api_key_prefix[param_name]} #{Swagger.configuration.api_key[param_name]}" + else + Swagger.configuration.api_key[param_name] + end + end + # Construct a base URL def url(options = {}) u = Addressable::URI.new( @@ -58,9 +73,6 @@ module {{moduleName}} # Drop trailing question mark, if present u.sub! /\?$/, '' - # Obfuscate API key? - u.sub! /api\_key=\w+/, 'api_key=YOUR_API_KEY' if options[:obfuscated] - u end @@ -129,7 +141,7 @@ module {{moduleName}} next if self.path.include? "{#{key}}" # skip path params next if value.blank? && value.class != FalseClass # skip empties if Swagger.configuration.camelize_params - key = key.to_s.camelize(:lower).to_sym unless key.to_sym == :api_key # api_key is not a camelCased param + key = key.to_s.camelize(:lower).to_sym end query_values[key] = value.to_s end diff --git a/samples/client/petstore/ruby/spec/request_spec.rb b/samples/client/petstore/ruby/spec/request_spec.rb index 8856a0cf315d..583ae591539d 100644 --- a/samples/client/petstore/ruby/spec/request_spec.rb +++ b/samples/client/petstore/ruby/spec/request_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' describe SwaggerClient::Swagger::Request do - before(:each) do + before(:each) do SwaggerClient::Swagger.configure do |config| inject_format = true config.api_key = 'special-key' @@ -22,7 +22,7 @@ describe SwaggerClient::Swagger::Request do it "sets default response format to json" do @request.format.should == 'json' end - + it "allows params to be nil" do @request = SwaggerClient::Swagger::Request.new(@default_http_method, @default_path, :params => nil) @request.query_string.should == "" @@ -55,7 +55,7 @@ describe SwaggerClient::Swagger::Request do end end - + describe "body" do it "camelCases parameters" do @@ -67,7 +67,7 @@ describe SwaggerClient::Swagger::Request do })) @request.body.keys.should == [:badDog, :goodDog] end - + end describe "path" do @@ -140,7 +140,7 @@ describe SwaggerClient::Swagger::Request do @request.query_string.should =~ /\?limit=100/ @request.url.should =~ /\?limit=100/ end - + it "camelCases parameters" do @request = SwaggerClient::Swagger::Request.new(@default_http_method, @default_path, @default_params.merge({ :params => { @@ -150,51 +150,12 @@ describe SwaggerClient::Swagger::Request do })) @request.query_string.should == "?badDog=bud&goodDog=dud" end - + it "converts boolean values to their string representation" do params = {:stringy => "fish", :truthy => true, :falsey => false} @request = SwaggerClient::Swagger::Request.new(:get, 'fakeMethod', :params => params) @request.query_string.should == "?falsey=false&stringy=fish&truthy=true" end - - end - - describe "API key" do - - it "is inferred from the Swagger base configuration by default" do - SwaggerClient::Swagger.configure {|c| c.api_key = "xyz" } - SwaggerClient::Swagger::Request.new(:get, "word/json").headers[:api_key].should == "xyz" - end - - it "can be obfuscated for public display" do - @request = SwaggerClient::Swagger::Request.new(:get, "words/fancy", @default_params.merge({ - :params => { - :word => "dog", - :api_key => "123456" - } - })) - - @request.url.should =~ /api\_key=123456/ - @request.url(:obfuscated => true).should =~ /api\_key=YOUR\_API\_KEY/ - end - - it "allows a key in the params to override the configuration-level key, even if it's blank" do - SwaggerClient::Swagger.configure {|c| c.api_key = "abc" } - @request_with_key = SwaggerClient::Swagger::Request.new(:get, "word/json", :params => {:api_key => "jkl"}) - @request_with_key.headers[:api_key].should be_nil - @request_with_key.params[:api_key].should == "jkl" - - @request_without_key = SwaggerClient::Swagger::Request.new(:get, "word/json", :params => {:api_key => nil}) - @request_without_key.headers[:api_key].should be_nil - @request_without_key.params[:api_key].should be_nil - end - - it "allows a key in the headers to override the configuration-level key, even if it's blank" do - SwaggerClient::Swagger.configure {|c| c.api_key = "hij" } - SwaggerClient::Swagger::Request.new(:get, "word/json").headers[:api_key].should == "hij" - SwaggerClient::Swagger::Request.new(:get, "word/json", :headers => {:api_key => "jkl"}).headers[:api_key].should == "jkl" - SwaggerClient::Swagger::Request.new(:get, "word/json", :headers => {:api_key => nil}).headers[:api_key].should be_nil - end end From e52694cde0e7b938b6c94dba9ccfb9dd67995905 Mon Sep 17 00:00:00 2001 From: xhh Date: Sat, 23 May 2015 09:41:03 +0800 Subject: [PATCH 2/6] Regenerate Ruby Petstore sample --- .../ruby/lib/swagger_client/swagger.rb | 6 +-- .../swagger_client/swagger/configuration.rb | 6 ++- .../lib/swagger_client/swagger/request.rb | 46 ++++++++++++------- 3 files changed, 37 insertions(+), 21 deletions(-) diff --git a/samples/client/petstore/ruby/lib/swagger_client/swagger.rb b/samples/client/petstore/ruby/lib/swagger_client/swagger.rb index 278db36e4cad..2e2632c169df 100644 --- a/samples/client/petstore/ruby/lib/swagger_client/swagger.rb +++ b/samples/client/petstore/ruby/lib/swagger_client/swagger.rb @@ -16,9 +16,9 @@ module SwaggerClient # # @example # Swagger.configure do |config| - # config.api_key = '1234567890abcdef' # required - # config.username = 'wordlover' # optional, but needed for user-related functions - # config.password = 'i<3words' # optional, but needed for user-related functions + # config.api_key['api_key'] = '1234567890abcdef' # api key authentication + # config.username = 'wordlover' # http basic authentication + # config.password = 'i<3words' # http basic authentication # config.format = 'json' # optional, defaults to 'json' # end # diff --git a/samples/client/petstore/ruby/lib/swagger_client/swagger/configuration.rb b/samples/client/petstore/ruby/lib/swagger_client/swagger/configuration.rb index 51f9539a9abe..91cdb66e0995 100644 --- a/samples/client/petstore/ruby/lib/swagger_client/swagger/configuration.rb +++ b/samples/client/petstore/ruby/lib/swagger_client/swagger/configuration.rb @@ -1,8 +1,8 @@ module SwaggerClient module Swagger class Configuration - attr_accessor :format, :api_key, :username, :password, :auth_token, :scheme, :host, :base_path, :user_agent, :logger, :inject_format, :force_ending_format, :camelize_params, :user_agent - + attr_accessor :format, :api_key, :api_key_prefix, :username, :password, :auth_token, :scheme, :host, :base_path, :user_agent, :logger, :inject_format, :force_ending_format, :camelize_params, :user_agent + # Defaults go in here.. def initialize @format = 'json' @@ -13,6 +13,8 @@ module SwaggerClient @inject_format = false @force_ending_format = false @camelize_params = true + @api_key = {} + @api_key_prefix = {} end end end diff --git a/samples/client/petstore/ruby/lib/swagger_client/swagger/request.rb b/samples/client/petstore/ruby/lib/swagger_client/swagger/request.rb index d5f266267dac..0dd1757167ce 100644 --- a/samples/client/petstore/ruby/lib/swagger_client/swagger/request.rb +++ b/samples/client/petstore/ruby/lib/swagger_client/swagger/request.rb @@ -13,24 +13,14 @@ module SwaggerClient attributes[:format] ||= Swagger.configuration.format attributes[:params] ||= {} + update_params_for_auth(attributes) + # Set default headers default_headers = { 'Content-Type' => "application/#{attributes[:format].downcase}", - :api_key => Swagger.configuration.api_key, 'User-Agent' => Swagger.configuration.user_agent } - # api_key from headers hash trumps the default, even if its value is blank - if attributes[:headers].present? && attributes[:headers].has_key?(:api_key) - default_headers.delete(:api_key) - end - - # api_key from params hash trumps all others (headers and default_headers) - if attributes[:params].present? && attributes[:params].has_key?(:api_key) - default_headers.delete(:api_key) - attributes[:headers].delete(:api_key) if attributes[:headers].present? - end - # Merge argument headers into defaults attributes[:headers] = default_headers.merge(attributes[:headers] || {}) @@ -46,6 +36,33 @@ module SwaggerClient end end + def update_params_for_auth(attributes) + (attributes[:auth_names] || []).each do |auth_name| + case auth_name + + when 'api_key' + attributes[:headers] ||= {} + attributes[:headers]['api_key'] = get_api_key_with_prefix('api_key') + + + + when 'petstore_auth' + + + # TODO: support oauth + + end + end + end + + def get_api_key_with_prefix(param_name) + if Swagger.configuration.api_key_prefix[param_name].present? + "#{Swagger.configuration.api_key_prefix[param_name]} #{Swagger.configuration.api_key[param_name]}" + else + Swagger.configuration.api_key[param_name] + end + end + # Construct a base URL def url(options = {}) u = Addressable::URI.new( @@ -58,9 +75,6 @@ module SwaggerClient # Drop trailing question mark, if present u.sub! /\?$/, '' - # Obfuscate API key? - u.sub! /api\_key=\w+/, 'api_key=YOUR_API_KEY' if options[:obfuscated] - u end @@ -129,7 +143,7 @@ module SwaggerClient next if self.path.include? "{#{key}}" # skip path params next if value.blank? && value.class != FalseClass # skip empties if Swagger.configuration.camelize_params - key = key.to_s.camelize(:lower).to_sym unless key.to_sym == :api_key # api_key is not a camelCased param + key = key.to_s.camelize(:lower).to_sym end query_values[key] = value.to_s end From 623a1278cf6b1ff26814f14eed6519f6598041fa Mon Sep 17 00:00:00 2001 From: xhh Date: Sat, 23 May 2015 11:52:49 +0800 Subject: [PATCH 3/6] Add test case for API key auth --- .../src/main/resources/ruby/api.mustache | 5 ++-- .../resources/ruby/swagger/request.mustache | 23 ++++++++---------- .../ruby/lib/swagger_client/api/pet_api.rb | 24 ++++++++++++------- .../ruby/lib/swagger_client/api/store_api.rb | 12 ++++++---- .../ruby/lib/swagger_client/api/user_api.rb | 24 ++++++++++++------- .../lib/swagger_client/swagger/request.rb | 20 ++++++---------- .../client/petstore/ruby/spec/request_spec.rb | 24 ++++++++++++++++++- .../client/petstore/ruby/spec/spec_helper.rb | 2 +- 8 files changed, 84 insertions(+), 50 deletions(-) diff --git a/modules/swagger-codegen/src/main/resources/ruby/api.mustache b/modules/swagger-codegen/src/main/resources/ruby/api.mustache index e9f90087db1c..3e1ac14014ef 100644 --- a/modules/swagger-codegen/src/main/resources/ruby/api.mustache +++ b/modules/swagger-codegen/src/main/resources/ruby/api.mustache @@ -50,8 +50,9 @@ module {{moduleName}} {{/bodyParam}}{{#bodyParam}}post_body = Swagger::Request.object_to_http_body({{#required}}{{{paramName}}}{{/required}}{{^required}}opts[:'{{{paramName}}}']{{/required}}) {{/bodyParam}} - {{#returnType}}response = Swagger::Request.new(:{{httpMethod}}, path, {:params => query_params, :headers => header_params, :form_params => form_params, :body => post_body}).make.body - {{#returnContainer}}response.map {|response| {{/returnContainer}}obj = {{returnBaseType}}.new() and obj.build_from_hash(response){{#returnContainer}} }{{/returnContainer}}{{/returnType}}{{^returnType}}Swagger::Request.new(:{{httpMethod}}, path, {:params => query_params,:headers => header_params, :form_params => form_params, :body => post_body}).make + auth_names = [{{#authMethods}}'{{name}}'{{#hasMore}}, {{/hasMore}}{{/authMethods}}] + {{#returnType}}response = Swagger::Request.new(:{{httpMethod}}, path, {:params => query_params, :headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make.body + {{#returnContainer}}response.map {|response| {{/returnContainer}}obj = {{returnBaseType}}.new() and obj.build_from_hash(response){{#returnContainer}} }{{/returnContainer}}{{/returnType}}{{^returnType}}Swagger::Request.new(:{{httpMethod}}, path, {:params => query_params,:headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make nil{{/returnType}} end {{/operation}} diff --git a/modules/swagger-codegen/src/main/resources/ruby/swagger/request.mustache b/modules/swagger-codegen/src/main/resources/ruby/swagger/request.mustache index 1e04b92e23e9..07fa2035db20 100644 --- a/modules/swagger-codegen/src/main/resources/ruby/swagger/request.mustache +++ b/modules/swagger-codegen/src/main/resources/ruby/swagger/request.mustache @@ -5,7 +5,7 @@ module {{moduleName}} require 'addressable/uri' require 'typhoeus' - attr_accessor :host, :path, :format, :params, :body, :http_method, :headers, :form_params + attr_accessor :host, :path, :format, :params, :body, :http_method, :headers, :form_params, :auth_names # All requests must have an HTTP method and a path # Optionals parameters are :params, :headers, :body, :format, :host @@ -13,8 +13,6 @@ module {{moduleName}} attributes[:format] ||= Swagger.configuration.format attributes[:params] ||= {} - update_params_for_auth(attributes) - # Set default headers default_headers = { 'Content-Type' => "application/#{attributes[:format].downcase}", @@ -34,20 +32,19 @@ module {{moduleName}} attributes.each do |name, value| send("#{name.to_s.underscore.to_sym}=", value) end + + update_params_for_auth! end - def update_params_for_auth(attributes) - (attributes[:auth_names] || []).each do |auth_name| + def update_params_for_auth! + (@auth_names || []).each do |auth_name| case auth_name - {{#authMethods}} - when '{{name}}' - {{#isApiKey}}{{#isKeyInHeader}}attributes[:headers] ||= {} - attributes[:headers]['{{keyParamName}}'] = get_api_key_with_prefix('{{keyParamName}}'){{/isKeyInHeader}}{{#isKeyInQuery}}attributes[:params] ||= {} - attributes[:params]['{{keyParamName}}'] = get_api_key_with_prefix('{{keyParamName}}'){{/isKeyInQuery}}{{/isApiKey}} - {{#isBasic}}attributes[:headers] ||= {} + {{#authMethods}}when '{{name}}' + {{#isApiKey}}{{#isKeyInHeader}}@headers ||= {} + @headers['{{keyParamName}}'] = get_api_key_with_prefix('{{keyParamName}}'){{/isKeyInHeader}}{{#isKeyInQuery}}@params ||= {} + @params['{{keyParamName}}'] = get_api_key_with_prefix('{{keyParamName}}'){{/isKeyInQuery}}{{/isApiKey}}{{#isBasic}}@headers ||= {} http_auth_header = 'Basic ' + ["#{Swagger.configuration.username}:#{Swagger.configuration.password}"].pack('m').delete("\r\n") - attributes[:headers]['Authorization'] = http_auth_header{{/isBasic}} - {{#isOAuth}}# TODO: support oauth{{/isOAuth}} + @headers['Authorization'] = http_auth_header{{/isBasic}}{{#isOAuth}}# TODO: support oauth{{/isOAuth}} {{/authMethods}} end end diff --git a/samples/client/petstore/ruby/lib/swagger_client/api/pet_api.rb b/samples/client/petstore/ruby/lib/swagger_client/api/pet_api.rb index 40e5f1e3177a..7bed9b47780c 100644 --- a/samples/client/petstore/ruby/lib/swagger_client/api/pet_api.rb +++ b/samples/client/petstore/ruby/lib/swagger_client/api/pet_api.rb @@ -37,7 +37,8 @@ module SwaggerClient post_body = Swagger::Request.object_to_http_body(opts[:'body']) - Swagger::Request.new(:PUT, path, {:params => query_params,:headers => header_params, :form_params => form_params, :body => post_body}).make + auth_names = ['petstore_auth'] + Swagger::Request.new(:PUT, path, {:params => query_params,:headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make nil end @@ -73,7 +74,8 @@ module SwaggerClient post_body = Swagger::Request.object_to_http_body(opts[:'body']) - Swagger::Request.new(:POST, path, {:params => query_params,:headers => header_params, :form_params => form_params, :body => post_body}).make + auth_names = ['petstore_auth'] + Swagger::Request.new(:POST, path, {:params => query_params,:headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make nil end @@ -110,7 +112,8 @@ module SwaggerClient post_body = nil - response = Swagger::Request.new(:GET, path, {:params => query_params, :headers => header_params, :form_params => form_params, :body => post_body}).make.body + auth_names = ['petstore_auth'] + response = Swagger::Request.new(:GET, path, {:params => query_params, :headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make.body response.map {|response| obj = Pet.new() and obj.build_from_hash(response) } end @@ -147,7 +150,8 @@ module SwaggerClient post_body = nil - response = Swagger::Request.new(:GET, path, {:params => query_params, :headers => header_params, :form_params => form_params, :body => post_body}).make.body + auth_names = ['petstore_auth'] + response = Swagger::Request.new(:GET, path, {:params => query_params, :headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make.body response.map {|response| obj = Pet.new() and obj.build_from_hash(response) } end @@ -186,7 +190,8 @@ module SwaggerClient post_body = nil - response = Swagger::Request.new(:GET, path, {:params => query_params, :headers => header_params, :form_params => form_params, :body => post_body}).make.body + auth_names = ['api_key', 'petstore_auth'] + response = Swagger::Request.new(:GET, path, {:params => query_params, :headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make.body obj = Pet.new() and obj.build_from_hash(response) end @@ -229,7 +234,8 @@ module SwaggerClient post_body = nil - Swagger::Request.new(:POST, path, {:params => query_params,:headers => header_params, :form_params => form_params, :body => post_body}).make + auth_names = ['petstore_auth'] + Swagger::Request.new(:POST, path, {:params => query_params,:headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make nil end @@ -270,7 +276,8 @@ module SwaggerClient post_body = nil - Swagger::Request.new(:DELETE, path, {:params => query_params,:headers => header_params, :form_params => form_params, :body => post_body}).make + auth_names = ['petstore_auth'] + Swagger::Request.new(:DELETE, path, {:params => query_params,:headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make nil end @@ -313,7 +320,8 @@ module SwaggerClient post_body = nil - Swagger::Request.new(:POST, path, {:params => query_params,:headers => header_params, :form_params => form_params, :body => post_body}).make + auth_names = ['petstore_auth'] + Swagger::Request.new(:POST, path, {:params => query_params,:headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make nil end end diff --git a/samples/client/petstore/ruby/lib/swagger_client/api/store_api.rb b/samples/client/petstore/ruby/lib/swagger_client/api/store_api.rb index 594c30a07759..010d170945be 100644 --- a/samples/client/petstore/ruby/lib/swagger_client/api/store_api.rb +++ b/samples/client/petstore/ruby/lib/swagger_client/api/store_api.rb @@ -36,7 +36,8 @@ module SwaggerClient post_body = nil - response = Swagger::Request.new(:GET, path, {:params => query_params, :headers => header_params, :form_params => form_params, :body => post_body}).make.body + auth_names = ['api_key'] + response = Swagger::Request.new(:GET, path, {:params => query_params, :headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make.body response.map {|response| obj = map.new() and obj.build_from_hash(response) } end @@ -72,7 +73,8 @@ module SwaggerClient post_body = Swagger::Request.object_to_http_body(opts[:'body']) - response = Swagger::Request.new(:POST, path, {:params => query_params, :headers => header_params, :form_params => form_params, :body => post_body}).make.body + auth_names = [] + response = Swagger::Request.new(:POST, path, {:params => query_params, :headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make.body obj = Order.new() and obj.build_from_hash(response) end @@ -111,7 +113,8 @@ module SwaggerClient post_body = nil - response = Swagger::Request.new(:GET, path, {:params => query_params, :headers => header_params, :form_params => form_params, :body => post_body}).make.body + auth_names = [] + response = Swagger::Request.new(:GET, path, {:params => query_params, :headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make.body obj = Order.new() and obj.build_from_hash(response) end @@ -150,7 +153,8 @@ module SwaggerClient post_body = nil - Swagger::Request.new(:DELETE, path, {:params => query_params,:headers => header_params, :form_params => form_params, :body => post_body}).make + auth_names = [] + Swagger::Request.new(:DELETE, path, {:params => query_params,:headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make nil end end diff --git a/samples/client/petstore/ruby/lib/swagger_client/api/user_api.rb b/samples/client/petstore/ruby/lib/swagger_client/api/user_api.rb index 96fe0cabada3..a3a57503b017 100644 --- a/samples/client/petstore/ruby/lib/swagger_client/api/user_api.rb +++ b/samples/client/petstore/ruby/lib/swagger_client/api/user_api.rb @@ -37,7 +37,8 @@ module SwaggerClient post_body = Swagger::Request.object_to_http_body(opts[:'body']) - Swagger::Request.new(:POST, path, {:params => query_params,:headers => header_params, :form_params => form_params, :body => post_body}).make + auth_names = [] + Swagger::Request.new(:POST, path, {:params => query_params,:headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make nil end @@ -73,7 +74,8 @@ module SwaggerClient post_body = Swagger::Request.object_to_http_body(opts[:'body']) - Swagger::Request.new(:POST, path, {:params => query_params,:headers => header_params, :form_params => form_params, :body => post_body}).make + auth_names = [] + Swagger::Request.new(:POST, path, {:params => query_params,:headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make nil end @@ -109,7 +111,8 @@ module SwaggerClient post_body = Swagger::Request.object_to_http_body(opts[:'body']) - Swagger::Request.new(:POST, path, {:params => query_params,:headers => header_params, :form_params => form_params, :body => post_body}).make + auth_names = [] + Swagger::Request.new(:POST, path, {:params => query_params,:headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make nil end @@ -148,7 +151,8 @@ module SwaggerClient post_body = nil - response = Swagger::Request.new(:GET, path, {:params => query_params, :headers => header_params, :form_params => form_params, :body => post_body}).make.body + auth_names = [] + response = Swagger::Request.new(:GET, path, {:params => query_params, :headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make.body obj = string.new() and obj.build_from_hash(response) end @@ -183,7 +187,8 @@ module SwaggerClient post_body = nil - Swagger::Request.new(:GET, path, {:params => query_params,:headers => header_params, :form_params => form_params, :body => post_body}).make + auth_names = [] + Swagger::Request.new(:GET, path, {:params => query_params,:headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make nil end @@ -222,7 +227,8 @@ module SwaggerClient post_body = nil - response = Swagger::Request.new(:GET, path, {:params => query_params, :headers => header_params, :form_params => form_params, :body => post_body}).make.body + auth_names = [] + response = Swagger::Request.new(:GET, path, {:params => query_params, :headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make.body obj = User.new() and obj.build_from_hash(response) end @@ -262,7 +268,8 @@ module SwaggerClient post_body = Swagger::Request.object_to_http_body(opts[:'body']) - Swagger::Request.new(:PUT, path, {:params => query_params,:headers => header_params, :form_params => form_params, :body => post_body}).make + auth_names = [] + Swagger::Request.new(:PUT, path, {:params => query_params,:headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make nil end @@ -301,7 +308,8 @@ module SwaggerClient post_body = nil - Swagger::Request.new(:DELETE, path, {:params => query_params,:headers => header_params, :form_params => form_params, :body => post_body}).make + auth_names = [] + Swagger::Request.new(:DELETE, path, {:params => query_params,:headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make nil end end diff --git a/samples/client/petstore/ruby/lib/swagger_client/swagger/request.rb b/samples/client/petstore/ruby/lib/swagger_client/swagger/request.rb index 0dd1757167ce..d063313f2d6a 100644 --- a/samples/client/petstore/ruby/lib/swagger_client/swagger/request.rb +++ b/samples/client/petstore/ruby/lib/swagger_client/swagger/request.rb @@ -5,7 +5,7 @@ module SwaggerClient require 'addressable/uri' require 'typhoeus' - attr_accessor :host, :path, :format, :params, :body, :http_method, :headers, :form_params + attr_accessor :host, :path, :format, :params, :body, :http_method, :headers, :form_params, :auth_names # All requests must have an HTTP method and a path # Optionals parameters are :params, :headers, :body, :format, :host @@ -13,8 +13,6 @@ module SwaggerClient attributes[:format] ||= Swagger.configuration.format attributes[:params] ||= {} - update_params_for_auth(attributes) - # Set default headers default_headers = { 'Content-Type' => "application/#{attributes[:format].downcase}", @@ -34,21 +32,17 @@ module SwaggerClient attributes.each do |name, value| send("#{name.to_s.underscore.to_sym}=", value) end + + update_params_for_auth! end - def update_params_for_auth(attributes) - (attributes[:auth_names] || []).each do |auth_name| + def update_params_for_auth! + (@auth_names || []).each do |auth_name| case auth_name - when 'api_key' - attributes[:headers] ||= {} - attributes[:headers]['api_key'] = get_api_key_with_prefix('api_key') - - - + @headers ||= {} + @headers['api_key'] = get_api_key_with_prefix('api_key') when 'petstore_auth' - - # TODO: support oauth end diff --git a/samples/client/petstore/ruby/spec/request_spec.rb b/samples/client/petstore/ruby/spec/request_spec.rb index 583ae591539d..49bbc5cdd1e2 100644 --- a/samples/client/petstore/ruby/spec/request_spec.rb +++ b/samples/client/petstore/ruby/spec/request_spec.rb @@ -5,7 +5,7 @@ describe SwaggerClient::Swagger::Request do before(:each) do SwaggerClient::Swagger.configure do |config| inject_format = true - config.api_key = 'special-key' + config.api_key['api_key'] = 'special-key' config.host = 'petstore.swagger.io' config.base_path = '/v2' end @@ -159,4 +159,26 @@ describe SwaggerClient::Swagger::Request do end + describe "#update_params_for_auth!" do + it "sets header api-key parameter with prefix" do + SwaggerClient::Swagger.configure do |config| + inject_format = true + config.api_key_prefix['api_key'] = 'PREFIX' + end + @request.auth_names = ['api_key', 'unknown'] + @request.update_params_for_auth! + @request.headers['api_key'].should == 'PREFIX special-key' + end + + it "sets header api-key parameter without prefix" do + SwaggerClient::Swagger.configure do |config| + inject_format = true + config.api_key_prefix['api_key'] = nil + end + @request.auth_names = ['api_key', 'unknown'] + @request.update_params_for_auth! + @request.headers['api_key'].should == 'special-key' + end + end + end diff --git a/samples/client/petstore/ruby/spec/spec_helper.rb b/samples/client/petstore/ruby/spec/spec_helper.rb index 09012db29983..f9081d3fe086 100644 --- a/samples/client/petstore/ruby/spec/spec_helper.rb +++ b/samples/client/petstore/ruby/spec/spec_helper.rb @@ -38,7 +38,7 @@ end def configure_swagger SwaggerClient::Swagger.configure do |config| - config.api_key = 'special-key' + config.api_key['api_key'] = 'special-key' config.host = 'petstore.swagger.io' config.base_path = '/v2' end From a29c3abeb8a48a0d1b30f26f86bdccf7a07f3a68 Mon Sep 17 00:00:00 2001 From: xhh Date: Fri, 29 May 2015 12:05:47 +0800 Subject: [PATCH 4/6] Use File.separatorChar in Ruby generator, add comments --- .../codegen/languages/RubyClientCodegen.java | 16 ++++++++-------- .../main/resources/ruby/swagger/request.mustache | 3 +++ .../ruby/lib/swagger_client/swagger/request.rb | 3 +++ 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/languages/RubyClientCodegen.java b/modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/languages/RubyClientCodegen.java index 939c0eb0e0af..3ca7758b1a38 100644 --- a/modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/languages/RubyClientCodegen.java +++ b/modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/languages/RubyClientCodegen.java @@ -36,7 +36,7 @@ public class RubyClientCodegen extends DefaultCodegen implements CodegenConfig { moduleName = generateModuleName(); modelPackage = gemName + "/models"; apiPackage = gemName + "/api"; - outputFolder = "generated-code/ruby"; + outputFolder = "generated-code" + File.separatorChar + "ruby"; modelTemplateFiles.put("model.mustache", ".rb"); apiTemplateFiles.put("api.mustache", ".rb"); templateDir = "ruby"; @@ -69,17 +69,17 @@ public class RubyClientCodegen extends DefaultCodegen implements CodegenConfig { typeMapping.put("List", "array"); typeMapping.put("map", "map"); - String baseFolder = "lib/" + gemName; - String swaggerFolder = baseFolder + "/swagger"; - String modelFolder = baseFolder + "/models"; + String baseFolder = "lib" + File.separatorChar + gemName; + String swaggerFolder = baseFolder + File.separatorChar + "swagger"; + String modelFolder = baseFolder + File.separatorChar + "models"; supportingFiles.add(new SupportingFile("swagger_client.gemspec.mustache", "", gemName + ".gemspec")); supportingFiles.add(new SupportingFile("swagger_client.mustache", "lib", gemName + ".rb")); supportingFiles.add(new SupportingFile("monkey.mustache", baseFolder, "monkey.rb")); supportingFiles.add(new SupportingFile("swagger.mustache", baseFolder, "swagger.rb")); - supportingFiles.add(new SupportingFile("swagger/request.mustache", swaggerFolder, "request.rb")); - supportingFiles.add(new SupportingFile("swagger/response.mustache", swaggerFolder, "response.rb")); - supportingFiles.add(new SupportingFile("swagger/version.mustache", swaggerFolder, "version.rb")); - supportingFiles.add(new SupportingFile("swagger/configuration.mustache", swaggerFolder, "configuration.rb")); + supportingFiles.add(new SupportingFile("swagger" + File.separatorChar + "request.mustache", swaggerFolder, "request.rb")); + supportingFiles.add(new SupportingFile("swagger" + File.separatorChar + "response.mustache", swaggerFolder, "response.rb")); + supportingFiles.add(new SupportingFile("swagger" + File.separatorChar + "version.mustache", swaggerFolder, "version.rb")); + supportingFiles.add(new SupportingFile("swagger" + File.separatorChar + "configuration.mustache", swaggerFolder, "configuration.rb")); supportingFiles.add(new SupportingFile("base_object.mustache", modelFolder, "base_object.rb")); } diff --git a/modules/swagger-codegen/src/main/resources/ruby/swagger/request.mustache b/modules/swagger-codegen/src/main/resources/ruby/swagger/request.mustache index 07fa2035db20..85270369763b 100644 --- a/modules/swagger-codegen/src/main/resources/ruby/swagger/request.mustache +++ b/modules/swagger-codegen/src/main/resources/ruby/swagger/request.mustache @@ -36,6 +36,7 @@ module {{moduleName}} update_params_for_auth! end + # Update hearder and query params based on authentication settings. def update_params_for_auth! (@auth_names || []).each do |auth_name| case auth_name @@ -50,6 +51,8 @@ module {{moduleName}} end end + # Get API key (with prefix if set). + # @param [String] param_name the parameter name of API key auth def get_api_key_with_prefix(param_name) if Swagger.configuration.api_key_prefix[param_name].present? "#{Swagger.configuration.api_key_prefix[param_name]} #{Swagger.configuration.api_key[param_name]}" diff --git a/samples/client/petstore/ruby/lib/swagger_client/swagger/request.rb b/samples/client/petstore/ruby/lib/swagger_client/swagger/request.rb index d063313f2d6a..a595d6ab7a1c 100644 --- a/samples/client/petstore/ruby/lib/swagger_client/swagger/request.rb +++ b/samples/client/petstore/ruby/lib/swagger_client/swagger/request.rb @@ -36,6 +36,7 @@ module SwaggerClient update_params_for_auth! end + # Update hearder and query params based on authentication settings. def update_params_for_auth! (@auth_names || []).each do |auth_name| case auth_name @@ -49,6 +50,8 @@ module SwaggerClient end end + # Get API key (with prefix if set). + # @param [String] param_name the parameter name of API key auth def get_api_key_with_prefix(param_name) if Swagger.configuration.api_key_prefix[param_name].present? "#{Swagger.configuration.api_key_prefix[param_name]} #{Swagger.configuration.api_key[param_name]}" From 2e285ed5622d9476bd02109e545ca274fa0148e9 Mon Sep 17 00:00:00 2001 From: xhh Date: Wed, 3 Jun 2015 12:49:09 +0800 Subject: [PATCH 5/6] Support skipping SSL certification verification in Ruby clients by e.g.: SwaggerClient::Swagger.configure do |config| config.verify_ssl = false end --- .../ruby/swagger/configuration.mustache | 10 +++++++++- .../resources/ruby/swagger/request.mustache | 19 ++++++++++--------- .../swagger_client/swagger/configuration.rb | 10 +++++++++- .../lib/swagger_client/swagger/request.rb | 19 ++++++++++--------- 4 files changed, 38 insertions(+), 20 deletions(-) diff --git a/modules/swagger-codegen/src/main/resources/ruby/swagger/configuration.mustache b/modules/swagger-codegen/src/main/resources/ruby/swagger/configuration.mustache index e64797979209..e9a8af9c1628 100644 --- a/modules/swagger-codegen/src/main/resources/ruby/swagger/configuration.mustache +++ b/modules/swagger-codegen/src/main/resources/ruby/swagger/configuration.mustache @@ -1,7 +1,7 @@ module {{moduleName}} module Swagger class Configuration - attr_accessor :format, :api_key, :api_key_prefix, :username, :password, :auth_token, :scheme, :host, :base_path, :user_agent, :logger, :inject_format, :force_ending_format, :camelize_params, :user_agent + attr_accessor :format, :api_key, :api_key_prefix, :username, :password, :auth_token, :scheme, :host, :base_path, :user_agent, :logger, :inject_format, :force_ending_format, :camelize_params, :user_agent, :verify_ssl # Defaults go in here.. def initialize @@ -13,8 +13,16 @@ module {{moduleName}} @inject_format = false @force_ending_format = false @camelize_params = true + + # keys for API key authentication (param-name => api-key) @api_key = {} + # api-key prefix for API key authentication, e.g. "Bearer" (param-name => api-key-prefix) @api_key_prefix = {} + + # whether to verify SSL certificate, default to true + # Note: do NOT set it to false in production code, otherwise you would + # face multiple types of cryptographic attacks + @verify_ssl = true end end end diff --git a/modules/swagger-codegen/src/main/resources/ruby/swagger/request.mustache b/modules/swagger-codegen/src/main/resources/ruby/swagger/request.mustache index 85270369763b..3c6aa31df4e7 100644 --- a/modules/swagger-codegen/src/main/resources/ruby/swagger/request.mustache +++ b/modules/swagger-codegen/src/main/resources/ruby/swagger/request.mustache @@ -160,39 +160,40 @@ module {{moduleName}} #TODO use configuration setting to determine if debugging #logger = Logger.new STDOUT #logger.debug self.url + + request_options = { + :ssl_verifypeer => Swagger.configuration.verify_ssl, + :headers => self.headers.stringify_keys + } response = case self.http_method.to_sym when :get,:GET Typhoeus::Request.get( self.url, - :headers => self.headers.stringify_keys, + request_options ) when :post,:POST Typhoeus::Request.post( self.url, - :body => self.outgoing_body, - :headers => self.headers.stringify_keys, + request_options.merge(:body => self.outgoing_body) ) when :patch,:PATCH Typhoeus::Request.patch( self.url, - :body => self.outgoing_body, - :headers => self.headers.stringify_keys, + request_options.merge(:body => self.outgoing_body) ) when :put,:PUT Typhoeus::Request.put( self.url, - :body => self.outgoing_body, - :headers => self.headers.stringify_keys, + request_options.merge(:body => self.outgoing_body) ) when :delete,:DELETE Typhoeus::Request.delete( self.url, - :body => self.outgoing_body, - :headers => self.headers.stringify_keys, + request_options.merge(:body => self.outgoing_body) ) end Response.new(response) diff --git a/samples/client/petstore/ruby/lib/swagger_client/swagger/configuration.rb b/samples/client/petstore/ruby/lib/swagger_client/swagger/configuration.rb index 91cdb66e0995..a2d4fe0e2918 100644 --- a/samples/client/petstore/ruby/lib/swagger_client/swagger/configuration.rb +++ b/samples/client/petstore/ruby/lib/swagger_client/swagger/configuration.rb @@ -1,7 +1,7 @@ module SwaggerClient module Swagger class Configuration - attr_accessor :format, :api_key, :api_key_prefix, :username, :password, :auth_token, :scheme, :host, :base_path, :user_agent, :logger, :inject_format, :force_ending_format, :camelize_params, :user_agent + attr_accessor :format, :api_key, :api_key_prefix, :username, :password, :auth_token, :scheme, :host, :base_path, :user_agent, :logger, :inject_format, :force_ending_format, :camelize_params, :user_agent, :verify_ssl # Defaults go in here.. def initialize @@ -13,8 +13,16 @@ module SwaggerClient @inject_format = false @force_ending_format = false @camelize_params = true + + # keys for API key authentication (param-name => api-key) @api_key = {} + # api-key prefix for API key authentication, e.g. "Bearer" (param-name => api-key-prefix) @api_key_prefix = {} + + # whether to verify SSL certificate, default to true + # Note: do NOT set it to false in production code, otherwise you would + # face multiple types of cryptographic attacks + @verify_ssl = true end end end diff --git a/samples/client/petstore/ruby/lib/swagger_client/swagger/request.rb b/samples/client/petstore/ruby/lib/swagger_client/swagger/request.rb index a595d6ab7a1c..fea2ea2a5cdc 100644 --- a/samples/client/petstore/ruby/lib/swagger_client/swagger/request.rb +++ b/samples/client/petstore/ruby/lib/swagger_client/swagger/request.rb @@ -159,39 +159,40 @@ module SwaggerClient #TODO use configuration setting to determine if debugging #logger = Logger.new STDOUT #logger.debug self.url + + request_options = { + :ssl_verifypeer => Swagger.configuration.verify_ssl, + :headers => self.headers.stringify_keys + } response = case self.http_method.to_sym when :get,:GET Typhoeus::Request.get( self.url, - :headers => self.headers.stringify_keys, + request_options ) when :post,:POST Typhoeus::Request.post( self.url, - :body => self.outgoing_body, - :headers => self.headers.stringify_keys, + request_options.merge(:body => self.outgoing_body) ) when :patch,:PATCH Typhoeus::Request.patch( self.url, - :body => self.outgoing_body, - :headers => self.headers.stringify_keys, + request_options.merge(:body => self.outgoing_body) ) when :put,:PUT Typhoeus::Request.put( self.url, - :body => self.outgoing_body, - :headers => self.headers.stringify_keys, + request_options.merge(:body => self.outgoing_body) ) when :delete,:DELETE Typhoeus::Request.delete( self.url, - :body => self.outgoing_body, - :headers => self.headers.stringify_keys, + request_options.merge(:body => self.outgoing_body) ) end Response.new(response) From 0ffe53933df28281ea844fc86a3654bff7dd87db Mon Sep 17 00:00:00 2001 From: xhh Date: Wed, 3 Jun 2015 21:17:42 +0800 Subject: [PATCH 6/6] Bug fix: "null" was used as post body for empty form parameters The form parameters could be empty when all of them are optional and no values are assigned to them. --- .../src/main/resources/ruby/swagger/request.mustache | 6 ++++-- .../petstore/ruby/lib/swagger_client/swagger/request.rb | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/modules/swagger-codegen/src/main/resources/ruby/swagger/request.mustache b/modules/swagger-codegen/src/main/resources/ruby/swagger/request.mustache index 3c6aa31df4e7..99b58d58be85 100644 --- a/modules/swagger-codegen/src/main/resources/ruby/swagger/request.mustache +++ b/modules/swagger-codegen/src/main/resources/ruby/swagger/request.mustache @@ -120,14 +120,16 @@ module {{moduleName}} # For form parameters, remove empty value def outgoing_body # http form - if @body.nil? && @form_params && !@form_params.empty? + if headers['Content-Type'] == 'application/x-www-form-urlencoded' data = form_params.dup data.each do |key, value| data[key] = value.to_s if value && !value.is_a?(File) # remove emtpy form parameter end data - else # http body is JSON + elsif @body # http body is JSON @body.is_a?(String) ? @body : @body.to_json + else + nil end end diff --git a/samples/client/petstore/ruby/lib/swagger_client/swagger/request.rb b/samples/client/petstore/ruby/lib/swagger_client/swagger/request.rb index fea2ea2a5cdc..4cd5d84b0b9b 100644 --- a/samples/client/petstore/ruby/lib/swagger_client/swagger/request.rb +++ b/samples/client/petstore/ruby/lib/swagger_client/swagger/request.rb @@ -119,14 +119,16 @@ module SwaggerClient # For form parameters, remove empty value def outgoing_body # http form - if @body.nil? && @form_params && !@form_params.empty? + if headers['Content-Type'] == 'application/x-www-form-urlencoded' data = form_params.dup data.each do |key, value| data[key] = value.to_s if value && !value.is_a?(File) # remove emtpy form parameter end data - else # http body is JSON + elsif @body # http body is JSON @body.is_a?(String) ? @body : @body.to_json + else + nil end end