oas_request 0.0.4 → 0.0.5

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.
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: