Skip to content

Commit cbc4da5

Browse files
committed
Merge pull request #783 from xhh/ruby-auth
[Ruby] Add authentication support (API key, HTTP basic)
2 parents aecb4ad + 0ffe539 commit cbc4da5

File tree

13 files changed

+194
-141
lines changed

13 files changed

+194
-141
lines changed

modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/languages/RubyClientCodegen.java

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ public RubyClientCodegen() {
3636
moduleName = generateModuleName();
3737
modelPackage = gemName + "/models";
3838
apiPackage = gemName + "/api";
39-
outputFolder = "generated-code/ruby";
39+
outputFolder = "generated-code" + File.separatorChar + "ruby";
4040
modelTemplateFiles.put("model.mustache", ".rb");
4141
apiTemplateFiles.put("api.mustache", ".rb");
4242
templateDir = "ruby";
@@ -69,17 +69,17 @@ public RubyClientCodegen() {
6969
typeMapping.put("List", "array");
7070
typeMapping.put("map", "map");
7171

72-
String baseFolder = "lib/" + gemName;
73-
String swaggerFolder = baseFolder + "/swagger";
74-
String modelFolder = baseFolder + "/models";
72+
String baseFolder = "lib" + File.separatorChar + gemName;
73+
String swaggerFolder = baseFolder + File.separatorChar + "swagger";
74+
String modelFolder = baseFolder + File.separatorChar + "models";
7575
supportingFiles.add(new SupportingFile("swagger_client.gemspec.mustache", "", gemName + ".gemspec"));
7676
supportingFiles.add(new SupportingFile("swagger_client.mustache", "lib", gemName + ".rb"));
7777
supportingFiles.add(new SupportingFile("monkey.mustache", baseFolder, "monkey.rb"));
7878
supportingFiles.add(new SupportingFile("swagger.mustache", baseFolder, "swagger.rb"));
79-
supportingFiles.add(new SupportingFile("swagger/request.mustache", swaggerFolder, "request.rb"));
80-
supportingFiles.add(new SupportingFile("swagger/response.mustache", swaggerFolder, "response.rb"));
81-
supportingFiles.add(new SupportingFile("swagger/version.mustache", swaggerFolder, "version.rb"));
82-
supportingFiles.add(new SupportingFile("swagger/configuration.mustache", swaggerFolder, "configuration.rb"));
79+
supportingFiles.add(new SupportingFile("swagger" + File.separatorChar + "request.mustache", swaggerFolder, "request.rb"));
80+
supportingFiles.add(new SupportingFile("swagger" + File.separatorChar + "response.mustache", swaggerFolder, "response.rb"));
81+
supportingFiles.add(new SupportingFile("swagger" + File.separatorChar + "version.mustache", swaggerFolder, "version.rb"));
82+
supportingFiles.add(new SupportingFile("swagger" + File.separatorChar + "configuration.mustache", swaggerFolder, "configuration.rb"));
8383
supportingFiles.add(new SupportingFile("base_object.mustache", modelFolder, "base_object.rb"));
8484
}
8585

modules/swagger-codegen/src/main/resources/ruby/api.mustache

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,9 @@ module {{moduleName}}
5050
{{/bodyParam}}{{#bodyParam}}post_body = Swagger::Request.object_to_http_body({{#required}}{{{paramName}}}{{/required}}{{^required}}opts[:'{{{paramName}}}']{{/required}})
5151
{{/bodyParam}}
5252

53-
{{#returnType}}response = Swagger::Request.new(:{{httpMethod}}, path, {:params => query_params, :headers => header_params, :form_params => form_params, :body => post_body}).make.body
54-
{{#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
53+
auth_names = [{{#authMethods}}'{{name}}'{{#hasMore}}, {{/hasMore}}{{/authMethods}}]
54+
{{#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
55+
{{#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
5556
nil{{/returnType}}
5657
end
5758
{{/operation}}

modules/swagger-codegen/src/main/resources/ruby/swagger.mustache

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,9 @@ module {{moduleName}}
1616
#
1717
# @example
1818
# Swagger.configure do |config|
19-
# config.api_key = '1234567890abcdef' # required
20-
# config.username = 'wordlover' # optional, but needed for user-related functions
21-
# config.password = 'i<3words' # optional, but needed for user-related functions
19+
# config.api_key['api_key'] = '1234567890abcdef' # api key authentication
20+
# config.username = 'wordlover' # http basic authentication
21+
# config.password = 'i<3words' # http basic authentication
2222
# config.format = 'json' # optional, defaults to 'json'
2323
# end
2424
#

modules/swagger-codegen/src/main/resources/ruby/swagger/configuration.mustache

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
module {{moduleName}}
22
module Swagger
33
class Configuration
4-
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
5-
4+
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
5+
66
# Defaults go in here..
77
def initialize
88
@format = 'json'
@@ -13,6 +13,16 @@ module {{moduleName}}
1313
@inject_format = false
1414
@force_ending_format = false
1515
@camelize_params = true
16+
17+
# keys for API key authentication (param-name => api-key)
18+
@api_key = {}
19+
# api-key prefix for API key authentication, e.g. "Bearer" (param-name => api-key-prefix)
20+
@api_key_prefix = {}
21+
22+
# whether to verify SSL certificate, default to true
23+
# Note: do NOT set it to false in production code, otherwise you would
24+
# face multiple types of cryptographic attacks
25+
@verify_ssl = true
1626
end
1727
end
1828
end

modules/swagger-codegen/src/main/resources/ruby/swagger/request.mustache

Lines changed: 43 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ module {{moduleName}}
55
require 'addressable/uri'
66
require 'typhoeus'
77

8-
attr_accessor :host, :path, :format, :params, :body, :http_method, :headers, :form_params
8+
attr_accessor :host, :path, :format, :params, :body, :http_method, :headers, :form_params, :auth_names
99

1010
# All requests must have an HTTP method and a path
1111
# Optionals parameters are :params, :headers, :body, :format, :host
@@ -16,21 +16,9 @@ module {{moduleName}}
1616
# Set default headers
1717
default_headers = {
1818
'Content-Type' => "application/#{attributes[:format].downcase}",
19-
:api_key => Swagger.configuration.api_key,
2019
'User-Agent' => Swagger.configuration.user_agent
2120
}
2221

23-
# api_key from headers hash trumps the default, even if its value is blank
24-
if attributes[:headers].present? && attributes[:headers].has_key?(:api_key)
25-
default_headers.delete(:api_key)
26-
end
27-
28-
# api_key from params hash trumps all others (headers and default_headers)
29-
if attributes[:params].present? && attributes[:params].has_key?(:api_key)
30-
default_headers.delete(:api_key)
31-
attributes[:headers].delete(:api_key) if attributes[:headers].present?
32-
end
33-
3422
# Merge argument headers into defaults
3523
attributes[:headers] = default_headers.merge(attributes[:headers] || {})
3624

@@ -44,6 +32,33 @@ module {{moduleName}}
4432
attributes.each do |name, value|
4533
send("#{name.to_s.underscore.to_sym}=", value)
4634
end
35+
36+
update_params_for_auth!
37+
end
38+
39+
# Update hearder and query params based on authentication settings.
40+
def update_params_for_auth!
41+
(@auth_names || []).each do |auth_name|
42+
case auth_name
43+
{{#authMethods}}when '{{name}}'
44+
{{#isApiKey}}{{#isKeyInHeader}}@headers ||= {}
45+
@headers['{{keyParamName}}'] = get_api_key_with_prefix('{{keyParamName}}'){{/isKeyInHeader}}{{#isKeyInQuery}}@params ||= {}
46+
@params['{{keyParamName}}'] = get_api_key_with_prefix('{{keyParamName}}'){{/isKeyInQuery}}{{/isApiKey}}{{#isBasic}}@headers ||= {}
47+
http_auth_header = 'Basic ' + ["#{Swagger.configuration.username}:#{Swagger.configuration.password}"].pack('m').delete("\r\n")
48+
@headers['Authorization'] = http_auth_header{{/isBasic}}{{#isOAuth}}# TODO: support oauth{{/isOAuth}}
49+
{{/authMethods}}
50+
end
51+
end
52+
end
53+
54+
# Get API key (with prefix if set).
55+
# @param [String] param_name the parameter name of API key auth
56+
def get_api_key_with_prefix(param_name)
57+
if Swagger.configuration.api_key_prefix[param_name].present?
58+
"#{Swagger.configuration.api_key_prefix[param_name]} #{Swagger.configuration.api_key[param_name]}"
59+
else
60+
Swagger.configuration.api_key[param_name]
61+
end
4762
end
4863

4964
# Construct a base URL
@@ -58,9 +73,6 @@ module {{moduleName}}
5873
# Drop trailing question mark, if present
5974
u.sub! /\?$/, ''
6075

61-
# Obfuscate API key?
62-
u.sub! /api\_key=\w+/, 'api_key=YOUR_API_KEY' if options[:obfuscated]
63-
6476
u
6577
end
6678

@@ -108,14 +120,16 @@ module {{moduleName}}
108120
# For form parameters, remove empty value
109121
def outgoing_body
110122
# http form
111-
if @body.nil? && @form_params && !@form_params.empty?
123+
if headers['Content-Type'] == 'application/x-www-form-urlencoded'
112124
data = form_params.dup
113125
data.each do |key, value|
114126
data[key] = value.to_s if value && !value.is_a?(File) # remove emtpy form parameter
115127
end
116128
data
117-
else # http body is JSON
129+
elsif @body # http body is JSON
118130
@body.is_a?(String) ? @body : @body.to_json
131+
else
132+
nil
119133
end
120134
end
121135

@@ -129,7 +143,7 @@ module {{moduleName}}
129143
next if self.path.include? "{#{key}}" # skip path params
130144
next if value.blank? && value.class != FalseClass # skip empties
131145
if Swagger.configuration.camelize_params
132-
key = key.to_s.camelize(:lower).to_sym unless key.to_sym == :api_key # api_key is not a camelCased param
146+
key = key.to_s.camelize(:lower).to_sym
133147
end
134148
query_values[key] = value.to_s
135149
end
@@ -148,39 +162,40 @@ module {{moduleName}}
148162
#TODO use configuration setting to determine if debugging
149163
#logger = Logger.new STDOUT
150164
#logger.debug self.url
165+
166+
request_options = {
167+
:ssl_verifypeer => Swagger.configuration.verify_ssl,
168+
:headers => self.headers.stringify_keys
169+
}
151170
response = case self.http_method.to_sym
152171
when :get,:GET
153172
Typhoeus::Request.get(
154173
self.url,
155-
:headers => self.headers.stringify_keys,
174+
request_options
156175
)
157176

158177
when :post,:POST
159178
Typhoeus::Request.post(
160179
self.url,
161-
:body => self.outgoing_body,
162-
:headers => self.headers.stringify_keys,
180+
request_options.merge(:body => self.outgoing_body)
163181
)
164182

165183
when :patch,:PATCH
166184
Typhoeus::Request.patch(
167185
self.url,
168-
:body => self.outgoing_body,
169-
:headers => self.headers.stringify_keys,
186+
request_options.merge(:body => self.outgoing_body)
170187
)
171188

172189
when :put,:PUT
173190
Typhoeus::Request.put(
174191
self.url,
175-
:body => self.outgoing_body,
176-
:headers => self.headers.stringify_keys,
192+
request_options.merge(:body => self.outgoing_body)
177193
)
178194

179195
when :delete,:DELETE
180196
Typhoeus::Request.delete(
181197
self.url,
182-
:body => self.outgoing_body,
183-
:headers => self.headers.stringify_keys,
198+
request_options.merge(:body => self.outgoing_body)
184199
)
185200
end
186201
Response.new(response)

samples/client/petstore/ruby/lib/swagger_client/api/pet_api.rb

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@ def self.update_pet(opts = {})
3737
post_body = Swagger::Request.object_to_http_body(opts[:'body'])
3838

3939

40-
Swagger::Request.new(:PUT, path, {:params => query_params,:headers => header_params, :form_params => form_params, :body => post_body}).make
40+
auth_names = ['petstore_auth']
41+
Swagger::Request.new(:PUT, path, {:params => query_params,:headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make
4142
nil
4243
end
4344

@@ -73,7 +74,8 @@ def self.add_pet(opts = {})
7374
post_body = Swagger::Request.object_to_http_body(opts[:'body'])
7475

7576

76-
Swagger::Request.new(:POST, path, {:params => query_params,:headers => header_params, :form_params => form_params, :body => post_body}).make
77+
auth_names = ['petstore_auth']
78+
Swagger::Request.new(:POST, path, {:params => query_params,:headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make
7779
nil
7880
end
7981

@@ -110,7 +112,8 @@ def self.find_pets_by_status(opts = {})
110112
post_body = nil
111113

112114

113-
response = Swagger::Request.new(:GET, path, {:params => query_params, :headers => header_params, :form_params => form_params, :body => post_body}).make.body
115+
auth_names = ['petstore_auth']
116+
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
114117
response.map {|response| obj = Pet.new() and obj.build_from_hash(response) }
115118
end
116119

@@ -147,7 +150,8 @@ def self.find_pets_by_tags(opts = {})
147150
post_body = nil
148151

149152

150-
response = Swagger::Request.new(:GET, path, {:params => query_params, :headers => header_params, :form_params => form_params, :body => post_body}).make.body
153+
auth_names = ['petstore_auth']
154+
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
151155
response.map {|response| obj = Pet.new() and obj.build_from_hash(response) }
152156
end
153157

@@ -186,7 +190,8 @@ def self.get_pet_by_id(pet_id, opts = {})
186190
post_body = nil
187191

188192

189-
response = Swagger::Request.new(:GET, path, {:params => query_params, :headers => header_params, :form_params => form_params, :body => post_body}).make.body
193+
auth_names = ['api_key', 'petstore_auth']
194+
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
190195
obj = Pet.new() and obj.build_from_hash(response)
191196
end
192197

@@ -229,7 +234,8 @@ def self.update_pet_with_form(pet_id, opts = {})
229234
post_body = nil
230235

231236

232-
Swagger::Request.new(:POST, path, {:params => query_params,:headers => header_params, :form_params => form_params, :body => post_body}).make
237+
auth_names = ['petstore_auth']
238+
Swagger::Request.new(:POST, path, {:params => query_params,:headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make
233239
nil
234240
end
235241

@@ -270,7 +276,8 @@ def self.delete_pet(pet_id, opts = {})
270276
post_body = nil
271277

272278

273-
Swagger::Request.new(:DELETE, path, {:params => query_params,:headers => header_params, :form_params => form_params, :body => post_body}).make
279+
auth_names = ['petstore_auth']
280+
Swagger::Request.new(:DELETE, path, {:params => query_params,:headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make
274281
nil
275282
end
276283

@@ -313,7 +320,8 @@ def self.upload_file(pet_id, opts = {})
313320
post_body = nil
314321

315322

316-
Swagger::Request.new(:POST, path, {:params => query_params,:headers => header_params, :form_params => form_params, :body => post_body}).make
323+
auth_names = ['petstore_auth']
324+
Swagger::Request.new(:POST, path, {:params => query_params,:headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make
317325
nil
318326
end
319327
end

samples/client/petstore/ruby/lib/swagger_client/api/store_api.rb

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,8 @@ def self.get_inventory(opts = {})
3636
post_body = nil
3737

3838

39-
response = Swagger::Request.new(:GET, path, {:params => query_params, :headers => header_params, :form_params => form_params, :body => post_body}).make.body
39+
auth_names = ['api_key']
40+
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
4041
response.map {|response| obj = map.new() and obj.build_from_hash(response) }
4142
end
4243

@@ -72,7 +73,8 @@ def self.place_order(opts = {})
7273
post_body = Swagger::Request.object_to_http_body(opts[:'body'])
7374

7475

75-
response = Swagger::Request.new(:POST, path, {:params => query_params, :headers => header_params, :form_params => form_params, :body => post_body}).make.body
76+
auth_names = []
77+
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
7678
obj = Order.new() and obj.build_from_hash(response)
7779
end
7880

@@ -111,7 +113,8 @@ def self.get_order_by_id(order_id, opts = {})
111113
post_body = nil
112114

113115

114-
response = Swagger::Request.new(:GET, path, {:params => query_params, :headers => header_params, :form_params => form_params, :body => post_body}).make.body
116+
auth_names = []
117+
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
115118
obj = Order.new() and obj.build_from_hash(response)
116119
end
117120

@@ -150,7 +153,8 @@ def self.delete_order(order_id, opts = {})
150153
post_body = nil
151154

152155

153-
Swagger::Request.new(:DELETE, path, {:params => query_params,:headers => header_params, :form_params => form_params, :body => post_body}).make
156+
auth_names = []
157+
Swagger::Request.new(:DELETE, path, {:params => query_params,:headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make
154158
nil
155159
end
156160
end

0 commit comments

Comments
 (0)