oas_request 0.0.4 → 0.0.5

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
  SHA256:
3
- metadata.gz: ebadd3bb6a13145a40bfaca069cacbe7e626b042f683ff6eb6e166a6e9a975e6
4
- data.tar.gz: f9d3a245d1cd7d8407b94e9cccf39f89e9be52f245f0bf88ab3c7034df2ad1b1
3
+ metadata.gz: 18554b61f849e1beb2c9d0b19e4169f6cef4486cf77677246b9886a316290bd6
4
+ data.tar.gz: 2531349d54469d32b3fdf7357edea1243dbfef9038363d4f4c885a81395577e6
5
5
  SHA512:
6
- metadata.gz: 694d14c453f5872509e0961155d25d15199b0faf85d45e4b81b9975ca5e93281bdd91e25ad36ad4be62a99808227ff809b8f941912085e0b500869d24aad0db9
7
- data.tar.gz: 0db8ae9120ab145b5a9b44abd67797a2c97f99b15834fbac665c468d6d8fb98155e6be7514e5a02ffc3f5718ac090eba773c65e612d731b6748a6f5fe082b1c4
6
+ metadata.gz: 492836ae6c38677efc157712fa4328e4a02c58d47ef15d85d86637313e757644bc4940848315c9de40d644e2c59458d793aea1e40fcac7f49382f55d147fce0b
7
+ data.tar.gz: 8a27d7d5130e82d844dd7552f2e195be96c4bd57f75e088bbd76d2f87c9812ee2fc10d76e4c2822a5a4ace1b7bd48ef292db38a9861e9c9ca058af5d87a4d740
data/lib/oas_request.rb CHANGED
@@ -1,18 +1,24 @@
1
1
  require "rack"
2
2
  require "string"
3
3
 
4
- module OASRequest
4
+ class OASRequest
5
5
  def self.spec(oas)
6
+ @@oas_security_schemes = (oas["components"] && oas["components"]["securitySchemes"]) ? oas["components"]["securitySchemes"] : nil
7
+
6
8
  Class.new do
7
- def initialize(server:, headers: {}, params: {}, query: {})
8
- @server = server
9
+ def initialize(server:, headers: {}, params: {}, query: {}, secret: nil, jwt: {})
10
+ # TODO analyze oas.servers
11
+ @server = server.chomp("/")
9
12
 
13
+ # default properties
10
14
  @headers = headers
11
15
  @params = params
12
16
  @query = query
17
+ @secret = secret
18
+ @jwt = jwt
13
19
  end
14
20
 
15
- def __request(method:, url:, options: {})
21
+ def __request(method:, url:, security_requirements: {}, options: {})
16
22
  # merge params with global defaults
17
23
  params = @params.merge(options.fetch(:params, {}))
18
24
 
@@ -22,20 +28,36 @@ module OASRequest
22
28
  # construct final host & url parts
23
29
  uri = URI "#{@server}#{url_path}"
24
30
 
31
+ # Get security options from global config and per API method config
32
+ method_security = {}
33
+ if options.fetch(:secret, nil)
34
+ method_security[:secret] = options.fetch(:secret, nil)
35
+ end
36
+ if options.fetch(:jwt, nil)
37
+ method_security[:jwt] = options.fetch(:jwt, nil)
38
+ end
39
+
40
+ security_options = {}.merge({secret: @secret, jwt: @jwt}).merge(method_security)
41
+
42
+ # Get security values in headers and queries from the required security schemas, and the given security options
43
+ security_headers, security_queries = OASRequest::Security::parse_security(@@oas_security_schemes, security_requirements, security_options)
44
+
25
45
  # convert query back to regular hash
26
46
  search_obj = Rack::Utils.parse_query uri.query
27
47
 
28
- authorization_headers = {}
29
-
30
48
  # Overrides
31
- headers = @headers.merge(authorization_headers).merge(options.fetch(:headers, {}))
32
- query = search_obj.merge(@query).merge(options.fetch(:query, {}))
49
+ headers = {}.merge(@headers).merge(security_headers).merge(options.fetch(:headers, {}))
50
+ query = search_obj.merge(@query).merge(security_queries).merge(options.fetch(:query, {}))
33
51
 
34
52
  # final query string
35
53
  search = Rack::Utils.build_query query
36
54
 
37
55
  OASRequest::HTTP.http(
38
- headers: headers,
56
+ headers: headers.reduce({}) do |headers, raw_header|
57
+ header_name, header_value = raw_header
58
+ headers[header_name] = header_value.kind_of?(Array) ? header_value.join(',') : header_value
59
+ headers
60
+ end,
39
61
  host: uri.host,
40
62
  method: method,
41
63
  port: uri.port,
@@ -45,6 +67,7 @@ module OASRequest
45
67
  )
46
68
  end
47
69
 
70
+ global_security = oas["security"] ? oas["security"][0] || {} : {}
48
71
 
49
72
  oas["paths"].each do |url, methods|
50
73
  methods.each do |method, definition|
@@ -54,15 +77,23 @@ module OASRequest
54
77
  operation_id = definition["operationId"]
55
78
  underscored_operation_id = operation_id.underscore
56
79
 
57
- request_method = Proc.new do |headers: {}, params: {}, query: {}, body: nil|
80
+ method_security = definition["security"] ? definition["security"][0] || {} : {}
81
+
82
+ # Get the global security requirements, followed by the per method security requirements
83
+ security_requirements = {}.merge(global_security).merge(method_security)
84
+
85
+ request_method = Proc.new do |headers: {}, params: {}, query: {}, body: nil, secret: nil, jwt: {}|
58
86
  __request(
59
87
  method: method,
60
88
  url: url,
89
+ security_requirements: security_requirements,
61
90
  options: {
62
91
  headers: headers,
63
92
  params: params,
64
93
  query: query,
65
- body: body
94
+ body: body,
95
+ secret: secret,
96
+ jwt: jwt
66
97
  }
67
98
  )
68
99
  end
@@ -80,3 +111,4 @@ end
80
111
 
81
112
  require "oas_request/path_template"
82
113
  require "oas_request/http"
114
+ require "oas_request/security"
@@ -10,7 +10,7 @@ REQUEST_CLASSES = {
10
10
  delete: Net::HTTP::Delete
11
11
  }
12
12
 
13
- module OASRequest::HTTP
13
+ class OASRequest::HTTP
14
14
  def self.config(opts = {})
15
15
  # set default options
16
16
  opts[:host] ||= "localhost"
@@ -1,4 +1,4 @@
1
- module OASRequest::PathTemplate
1
+ class OASRequest::PathTemplate
2
2
  def self.template(url, params)
3
3
  params_symbol = params.transform_keys(&:to_s)
4
4
 
@@ -0,0 +1,83 @@
1
+ require 'jwt'
2
+
3
+ class OASRequest::Security
4
+ def self.is_number?(input)
5
+ true if Float(input) rescue false
6
+ end
7
+
8
+ def self.parse_security(oas_security_schemes, security_requirements, security_options)
9
+ headers = {}
10
+ queries = {}
11
+
12
+ if oas_security_schemes
13
+ security_requirements.each do |key, value|
14
+ security_scheme = oas_security_schemes.fetch(key, nil)
15
+
16
+ # Security scheme is not defined in the global scheme, throw error
17
+ unless security_scheme
18
+ raise "Security scheme #{key} not defined in spec."
19
+ end
20
+
21
+ secret = security_options[:secret]
22
+ jwt = security_options[:jwt]
23
+
24
+ case security_scheme["type"]
25
+ when "http"
26
+ unless headers.include?(:authorization)
27
+ headers[:authorization] = []
28
+ end
29
+
30
+ case security_scheme['scheme']
31
+ when 'bearer'
32
+
33
+ case security_scheme['bearerFormat']
34
+ when 'JWT'
35
+ payload = {}
36
+
37
+ if jwt
38
+ exp = jwt[:exp]
39
+
40
+ if exp
41
+ raise "exp must be a number." unless self.is_number?(exp)
42
+ payload[:exp] = Time.now.to_i + (exp.to_i * 60)
43
+ end
44
+ end
45
+
46
+ headers[:authorization].push("Bearer #{JWT.encode(payload, secret)}")
47
+
48
+ else
49
+ headers[:authorization].push("Bearer #{secret}")
50
+ end
51
+ else
52
+ raise "#{security_scheme["scheme"]} scheme type not implemented."
53
+ end
54
+
55
+ when "apiKey"
56
+ # apiKey type
57
+
58
+ case security_scheme["in"]
59
+ when "header"
60
+ unless headers.include?(security_scheme["name"])
61
+ headers[security_scheme["name"]] = []
62
+ end
63
+ headers[security_scheme["name"]].push(secret)
64
+
65
+ when "query"
66
+ unless queries.include?(security_scheme["name"])
67
+ queries[security_scheme["name"]] = []
68
+ end
69
+ queries[security_scheme["name"]].push(secret)
70
+
71
+ else
72
+ raise "#{security_scheme["in"]} type not implemented."
73
+ end
74
+
75
+ else
76
+ raise "#{security_scheme["type"]} type not implemented."
77
+ end
78
+ end
79
+ end
80
+
81
+ [headers, queries]
82
+ end
83
+ end
@@ -0,0 +1,3 @@
1
+ module OASRequest
2
+ VERSION = "0.0.5".freeze
3
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: oas_request
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - ''
@@ -10,34 +10,66 @@ bindir: bin
10
10
  cert_chain: []
11
11
  date: 2020-07-28 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: jwt
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '2.2'
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 2.2.2
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - "~>"
28
+ - !ruby/object:Gem::Version
29
+ version: '2.2'
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 2.2.2
13
33
  - !ruby/object:Gem::Dependency
14
34
  name: rack
15
35
  requirement: !ruby/object:Gem::Requirement
16
36
  requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '2.2'
17
40
  - - ">="
18
41
  - !ruby/object:Gem::Version
19
- version: '0'
42
+ version: 2.2.3
20
43
  type: :runtime
21
44
  prerelease: false
22
45
  version_requirements: !ruby/object:Gem::Requirement
23
46
  requirements:
47
+ - - "~>"
48
+ - !ruby/object:Gem::Version
49
+ version: '2.2'
24
50
  - - ">="
25
51
  - !ruby/object:Gem::Version
26
- version: '0'
52
+ version: 2.2.3
27
53
  - !ruby/object:Gem::Dependency
28
54
  name: webmock
29
55
  requirement: !ruby/object:Gem::Requirement
30
56
  requirements:
57
+ - - "~>"
58
+ - !ruby/object:Gem::Version
59
+ version: '3.8'
31
60
  - - ">="
32
61
  - !ruby/object:Gem::Version
33
- version: '0'
62
+ version: 3.8.3
34
63
  type: :development
35
64
  prerelease: false
36
65
  version_requirements: !ruby/object:Gem::Requirement
37
66
  requirements:
67
+ - - "~>"
68
+ - !ruby/object:Gem::Version
69
+ version: '3.8'
38
70
  - - ">="
39
71
  - !ruby/object:Gem::Version
40
- version: '0'
72
+ version: 3.8.3
41
73
  description: A simple OAS request generator
42
74
  email: ''
43
75
  executables: []
@@ -47,6 +79,8 @@ files:
47
79
  - lib/oas_request.rb
48
80
  - lib/oas_request/http.rb
49
81
  - lib/oas_request/path_template.rb
82
+ - lib/oas_request/security.rb
83
+ - lib/oas_request/version.rb
50
84
  - lib/string.rb
51
85
  homepage: https://rubygems.org/gems/oas_request
52
86
  licenses: