3scale_toolbox 0.12.4 → 0.17.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (121) hide show
  1. checksums.yaml +4 -4
  2. data/3scale_toolbox.gemspec +4 -3
  3. data/README.md +31 -10
  4. data/lib/3scale_toolbox.rb +5 -2
  5. data/lib/3scale_toolbox/attribute_filters.rb +2 -0
  6. data/lib/3scale_toolbox/attribute_filters/attribute_filter.rb +9 -0
  7. data/lib/3scale_toolbox/attribute_filters/service_id_from_ref_filter.rb +30 -0
  8. data/lib/3scale_toolbox/cli.rb +4 -0
  9. data/lib/3scale_toolbox/cli/custom_table_printer.rb +32 -0
  10. data/lib/3scale_toolbox/cli/error_handler.rb +17 -14
  11. data/lib/3scale_toolbox/cli/json_printer.rb +13 -0
  12. data/lib/3scale_toolbox/cli/output_flag.rb +20 -0
  13. data/lib/3scale_toolbox/cli/yaml_printer.rb +13 -0
  14. data/lib/3scale_toolbox/commands.rb +5 -1
  15. data/lib/3scale_toolbox/commands/activedocs_command/apply_command.rb +34 -11
  16. data/lib/3scale_toolbox/commands/activedocs_command/create_command.rb +22 -7
  17. data/lib/3scale_toolbox/commands/activedocs_command/list_command.rb +21 -11
  18. data/lib/3scale_toolbox/commands/application_command/apply_command.rb +27 -4
  19. data/lib/3scale_toolbox/commands/application_command/create_command.rb +16 -1
  20. data/lib/3scale_toolbox/commands/application_command/list_command.rb +10 -13
  21. data/lib/3scale_toolbox/commands/application_command/show_command.rb +8 -14
  22. data/lib/3scale_toolbox/commands/backend_command.rb +22 -0
  23. data/lib/3scale_toolbox/commands/backend_command/copy_command.rb +65 -0
  24. data/lib/3scale_toolbox/commands/backend_command/copy_command/copy_mapping_rules_task.rb +52 -0
  25. data/lib/3scale_toolbox/commands/backend_command/copy_command/copy_methods_task.rb +40 -0
  26. data/lib/3scale_toolbox/commands/backend_command/copy_command/copy_metrics_task.rb +30 -0
  27. data/lib/3scale_toolbox/commands/backend_command/copy_command/create_or_update_target_backend_task.rb +45 -0
  28. data/lib/3scale_toolbox/commands/backend_command/copy_command/task.rb +89 -0
  29. data/lib/3scale_toolbox/commands/copy_command.rb +2 -2
  30. data/lib/3scale_toolbox/commands/copy_command/service_command.rb +40 -0
  31. data/lib/3scale_toolbox/commands/import_command/openapi.rb +29 -7
  32. data/lib/3scale_toolbox/commands/import_command/openapi/create_activedocs_step.rb +4 -17
  33. data/lib/3scale_toolbox/commands/import_command/openapi/create_service_step.rb +1 -5
  34. data/lib/3scale_toolbox/commands/import_command/openapi/mapping_rule.rb +3 -2
  35. data/lib/3scale_toolbox/commands/import_command/openapi/step.rb +43 -5
  36. data/lib/3scale_toolbox/commands/import_command/openapi/update_policies_step.rb +9 -10
  37. data/lib/3scale_toolbox/commands/import_command/openapi/update_service_oidc_conf_step.rb +2 -17
  38. data/lib/3scale_toolbox/commands/import_command/openapi/update_service_proxy_step.rb +10 -10
  39. data/lib/3scale_toolbox/commands/methods_command/apply_command.rb +26 -4
  40. data/lib/3scale_toolbox/commands/methods_command/create_command.rb +23 -1
  41. data/lib/3scale_toolbox/commands/methods_command/list_command.rb +11 -9
  42. data/lib/3scale_toolbox/commands/metrics_command/apply_command.rb +26 -4
  43. data/lib/3scale_toolbox/commands/metrics_command/create_command.rb +23 -1
  44. data/lib/3scale_toolbox/commands/metrics_command/list_command.rb +7 -12
  45. data/lib/3scale_toolbox/commands/plans_command/apply_command.rb +36 -7
  46. data/lib/3scale_toolbox/commands/plans_command/create_command.rb +23 -1
  47. data/lib/3scale_toolbox/commands/plans_command/import/import_plan_limits_step.rb +11 -12
  48. data/lib/3scale_toolbox/commands/plans_command/import/import_plan_pricing_rules_step.rb +11 -12
  49. data/lib/3scale_toolbox/commands/plans_command/list_command.rb +8 -13
  50. data/lib/3scale_toolbox/commands/plans_command/show_command.rb +6 -14
  51. data/lib/3scale_toolbox/commands/product_command.rb +22 -0
  52. data/lib/3scale_toolbox/commands/product_command/copy_command.rb +78 -0
  53. data/lib/3scale_toolbox/commands/product_command/copy_command/copy_backends_task.rb +71 -0
  54. data/lib/3scale_toolbox/commands/product_command/copy_command/delete_target_backend_usages_task.rb +48 -0
  55. data/lib/3scale_toolbox/commands/proxy_config_command.rb +3 -0
  56. data/lib/3scale_toolbox/commands/proxy_config_command/export_command.rb +74 -0
  57. data/lib/3scale_toolbox/commands/proxy_config_command/helper.rb +15 -0
  58. data/lib/3scale_toolbox/commands/proxy_config_command/list_command.rb +13 -29
  59. data/lib/3scale_toolbox/commands/proxy_config_command/show_command.rb +20 -23
  60. data/lib/3scale_toolbox/commands/service_command.rb +7 -5
  61. data/lib/3scale_toolbox/commands/service_command/apply_command.rb +69 -58
  62. data/lib/3scale_toolbox/commands/service_command/copy_command.rb +95 -0
  63. data/lib/3scale_toolbox/commands/service_command/copy_command/bump_proxy_version_task.rb +36 -0
  64. data/lib/3scale_toolbox/commands/service_command/copy_command/copy_activedocs_task.rb +46 -0
  65. data/lib/3scale_toolbox/commands/service_command/copy_command/copy_app_plans_task.rb +35 -0
  66. data/lib/3scale_toolbox/commands/service_command/copy_command/copy_limits_task.rb +39 -0
  67. data/lib/3scale_toolbox/commands/service_command/copy_command/copy_mapping_rules_task.rb +35 -0
  68. data/lib/3scale_toolbox/commands/service_command/copy_command/copy_methods_task.rb +40 -0
  69. data/lib/3scale_toolbox/commands/service_command/copy_command/copy_metrics_task.rb +37 -0
  70. data/lib/3scale_toolbox/commands/service_command/copy_command/copy_policies_task.rb +17 -0
  71. data/lib/3scale_toolbox/commands/service_command/copy_command/copy_pricingrules_task.rb +44 -0
  72. data/lib/3scale_toolbox/commands/service_command/copy_command/copy_service_proxy_task.rb +32 -0
  73. data/lib/3scale_toolbox/commands/service_command/copy_command/create_or_update_service_task.rb +48 -0
  74. data/lib/3scale_toolbox/commands/service_command/copy_command/destroy_mapping_rules_task.rb +34 -0
  75. data/lib/3scale_toolbox/commands/service_command/copy_command/task.rb +99 -0
  76. data/lib/3scale_toolbox/commands/service_command/create_command.rb +58 -44
  77. data/lib/3scale_toolbox/commands/service_command/delete_command.rb +31 -33
  78. data/lib/3scale_toolbox/commands/service_command/list_command.rb +24 -34
  79. data/lib/3scale_toolbox/commands/service_command/show_command.rb +39 -44
  80. data/lib/3scale_toolbox/commands/update_command.rb +3 -3
  81. data/lib/3scale_toolbox/commands/update_command/{update_service.rb → service_command.rb} +22 -18
  82. data/lib/3scale_toolbox/commands/update_command/service_command/copy_service_settings_task.rb +35 -0
  83. data/lib/3scale_toolbox/commands/update_command/service_command/delete_activedocs_task.rb +26 -0
  84. data/lib/3scale_toolbox/entities.rb +5 -0
  85. data/lib/3scale_toolbox/entities/application_plan.rb +31 -4
  86. data/lib/3scale_toolbox/entities/backend.rb +152 -0
  87. data/lib/3scale_toolbox/entities/backend_mapping_rule.rb +76 -0
  88. data/lib/3scale_toolbox/entities/backend_method.rb +90 -0
  89. data/lib/3scale_toolbox/entities/backend_metric.rb +88 -0
  90. data/lib/3scale_toolbox/entities/backend_usage.rb +99 -0
  91. data/lib/3scale_toolbox/entities/service.rb +18 -3
  92. data/lib/3scale_toolbox/error.rb +53 -0
  93. data/lib/3scale_toolbox/helper.rb +20 -0
  94. data/lib/3scale_toolbox/openapi.rb +2 -0
  95. data/lib/3scale_toolbox/openapi/oas3.rb +232 -0
  96. data/lib/3scale_toolbox/openapi/swagger.rb +192 -0
  97. data/lib/3scale_toolbox/proxy_logger.rb +1 -1
  98. data/lib/3scale_toolbox/version.rb +1 -1
  99. data/licenses.xml +190 -20
  100. data/resources/oas3_meta_schema.json +1654 -0
  101. metadata +69 -30
  102. data/lib/3scale_toolbox/commands/copy_command/copy_service.rb +0 -142
  103. data/lib/3scale_toolbox/commands/import_command/openapi/threescale_api_spec.rb +0 -80
  104. data/lib/3scale_toolbox/swagger.rb +0 -1
  105. data/lib/3scale_toolbox/swagger/swagger.rb +0 -123
  106. data/lib/3scale_toolbox/tasks.rb +0 -15
  107. data/lib/3scale_toolbox/tasks/bump_proxy_version_task.rb +0 -32
  108. data/lib/3scale_toolbox/tasks/copy_activedocs_task.rb +0 -42
  109. data/lib/3scale_toolbox/tasks/copy_app_plans_task.rb +0 -31
  110. data/lib/3scale_toolbox/tasks/copy_limits_task.rb +0 -36
  111. data/lib/3scale_toolbox/tasks/copy_mapping_rules_task.rb +0 -32
  112. data/lib/3scale_toolbox/tasks/copy_methods_task.rb +0 -36
  113. data/lib/3scale_toolbox/tasks/copy_metrics_task.rb +0 -33
  114. data/lib/3scale_toolbox/tasks/copy_policies_task.rb +0 -13
  115. data/lib/3scale_toolbox/tasks/copy_pricingrules_task.rb +0 -41
  116. data/lib/3scale_toolbox/tasks/copy_service_proxy_task.rb +0 -12
  117. data/lib/3scale_toolbox/tasks/copy_service_settings_task.rb +0 -38
  118. data/lib/3scale_toolbox/tasks/copy_task.rb +0 -66
  119. data/lib/3scale_toolbox/tasks/delete_activedocs_task.rb +0 -22
  120. data/lib/3scale_toolbox/tasks/destroy_mapping_rules_task.rb +0 -22
  121. data/lib/3scale_toolbox/tasks/helper_task.rb +0 -25
@@ -50,6 +50,26 @@ module ThreeScaleToolbox
50
50
  def period_already_taken_error?(error)
51
51
  Array(Hash(error)['period']).any? { |msg| msg.match(/has already been taken/) }
52
52
  end
53
+
54
+ def metrics_mapping(source_metrics, target_metrics)
55
+ target_metrics.map do |target|
56
+ source = source_metrics.find do |m|
57
+ compare_hashes(m, target, ['system_name'])
58
+ end || {}
59
+
60
+ [source['id'], target['id']]
61
+ end.to_h
62
+ end
63
+
64
+ def application_plan_mapping(source_app_plans, target_app_plans)
65
+ mapping = target_app_plans.map do |target|
66
+ source = source_app_plans.find do |app_plan|
67
+ compare_hashes(app_plan, target, ['system_name'])
68
+ end || {}
69
+ [source['id'], target]
70
+ end
71
+ mapping.reject { |key, _| key.nil? }
72
+ end
53
73
  end
54
74
 
55
75
  class BooleanTransformer
@@ -0,0 +1,2 @@
1
+ require '3scale_toolbox/openapi/swagger'
2
+ require '3scale_toolbox/openapi/oas3'
@@ -0,0 +1,232 @@
1
+ module ThreeScaleToolbox
2
+ module OpenAPI
3
+ ##
4
+ #
5
+ # OAS3 object
6
+ # * OAS3.title -> string
7
+ # * OAS3.description -> string
8
+ # * OAS3.version -> string
9
+ # * OAS3.base_path -> string
10
+ # * OAS3.host -> string
11
+ # * OAS3.scheme -> string
12
+ # * OAS3.operation -> array of operation hash
13
+ # * operation hash properties
14
+ # * :verb
15
+ # * :path
16
+ # * :description
17
+ # * :operation_id
18
+ # * OAS3.security -> security hash
19
+ # * security hash properties
20
+ # * :id -> string
21
+ # * :type -> string
22
+ # * :name -> string
23
+ # * :in_f -> string
24
+ # * :flow -> symbol (:implicit_flow_enabled, :direct_access_grants_enabled, :service_accounts_enabled, :standard_flow_enabled)
25
+ # * :scopes -> array of string
26
+ # * OAS3.service_backend_version -> string ('1','2','oidc')
27
+ # * OAS3.set_server_url -> def(spec, url)
28
+ # * OAS3.set_oauth2_urls-> def(spec, scheme_id, authorization_url, token_url)
29
+ class OAS3
30
+ META_SCHEMA_PATH = File.expand_path('../../../resources/oas3_meta_schema.json', __dir__)
31
+
32
+ def self.validate(raw)
33
+ meta_schema = JSON.parse(File.read(META_SCHEMA_PATH))
34
+ JSON::Validator.validate!(meta_schema, raw)
35
+ end
36
+
37
+ def self.build(path, raw, validate: true)
38
+ self.validate(raw) if validate
39
+
40
+ new(path, raw)
41
+ end
42
+
43
+ attr_reader :definition
44
+
45
+ def title
46
+ definition.info['title']
47
+ end
48
+
49
+ def description
50
+ definition.info['description']
51
+ end
52
+
53
+ def version
54
+ definition.info['version']
55
+ end
56
+
57
+ def base_path
58
+ # If there are many? take first
59
+ # From https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#openapi-object
60
+ # If the servers property is not provided, or is an empty array,
61
+ # the default value would be a Server Object with a url value of /
62
+ server_objects(&:path).first || '/'
63
+ end
64
+
65
+ def host
66
+ # If there are many? take first
67
+ server_objects(&:host).first
68
+ end
69
+
70
+ def scheme
71
+ # If there are many? take first
72
+ server_objects(&:scheme).first
73
+ end
74
+
75
+ def operations
76
+ @operations ||= parse_operations
77
+ end
78
+
79
+ def security
80
+ @security ||= parse_security
81
+ end
82
+
83
+ def service_backend_version
84
+ # default authentication mode if no security requirement
85
+ return '1' if security.nil?
86
+
87
+ case security[:type]
88
+ when 'oauth2'
89
+ 'oidc'
90
+ when 'apiKey'
91
+ '1'
92
+ else
93
+ raise ThreeScaleToolbox::Error, "Unexpected security scheme type #{security[:type]}"
94
+ end
95
+ end
96
+
97
+ ##
98
+ # Update given spec with urls
99
+ # It is expected identified security scheme to be oauth2 type
100
+ def set_oauth2_urls(spec, sec_scheme_id, authorization_url, token_url)
101
+ sec_scheme_obj = spec.dig('components', 'securitySchemes', sec_scheme_id)
102
+ if sec_scheme_obj.nil? || sec_scheme_obj['type'] != 'oauth2'
103
+ raise ThreeScaleToolbox::Error, "Expected security scheme {#{sec_scheme_id}} not found or not oauth2"
104
+ end
105
+
106
+ flow_key, flow_obj = sec_scheme_obj['flows'].first
107
+ flow_obj['authorizationUrl'] = authorization_url if %w[implicit authorizationCode].include?(flow_key)
108
+ flow_obj['tokenUrl'] = token_url if %w[password clientCredentials authorizationCode].include?(flow_key)
109
+ end
110
+
111
+ def set_server_url(spec, url)
112
+ spec['servers'] = [{ 'url' => url }]
113
+ end
114
+
115
+ private
116
+
117
+ def initialize(path, raw)
118
+ parser = OasParser::Parser.new(path, raw).resolve
119
+ @definition = OasParser::Definition.new(parser, path)
120
+ end
121
+
122
+ def server_objects
123
+ servers.map do |s|
124
+ yield Helper.parse_uri rendered_url(s)
125
+ end
126
+ end
127
+
128
+ # OAS3 server object variable substitution
129
+ def rendered_url(server_object)
130
+ template = erbfying_template(server_object.fetch('url'))
131
+ vars = server_object_variables(server_object['variables'])
132
+ ERB.new(template).result(OpenStruct.new(vars).instance_eval { binding })
133
+ end
134
+
135
+ def server_object_variables(variables)
136
+ vars = (variables || {}).each_with_object({}) do |(key, value), a|
137
+ a[key] = value['default']
138
+ end
139
+ JSON.parse(vars.to_json, symbolize_names: true)
140
+ end
141
+
142
+ def erbfying_template(template)
143
+ # A URL is composed from a limited set of characters belonging to the US-ASCII character set.
144
+ # These characters include digits (0-9), letters(A-Z, a-z), and a few special characters ("-", ".", "_", "~").
145
+ # https://www.urlencoder.io/learn/
146
+ tmp = template.gsub '{', '<%='
147
+ tmp.gsub '}', '%>'
148
+ end
149
+
150
+ def servers
151
+ definition.servers || []
152
+ end
153
+
154
+ def parse_operations
155
+ definition.paths.flat_map do |path_obj|
156
+ path_obj.endpoints.flat_map do |endpoint|
157
+ {
158
+ verb: endpoint.method,
159
+ path: endpoint.path.path,
160
+ description: endpoint.description,
161
+ operation_id: endpoint.operationId
162
+ }
163
+ end
164
+ end
165
+ end
166
+
167
+ def parse_security
168
+ raise ThreeScaleToolbox::Error, 'Invalid OAS: multiple security requirements' \
169
+ if global_security_requirements.size > 1
170
+
171
+ global_security_requirements.first
172
+ end
173
+
174
+ def global_security_requirements
175
+ @global_security_requirements ||= parse_global_security_reqs
176
+ end
177
+
178
+ def parse_global_security_reqs
179
+ security_requirements.flat_map do |sec_req|
180
+ sec_req.map do |sec_item_name, sec_item|
181
+ sec_def = fetch_security_scheme(sec_item_name)
182
+ {
183
+ id: sec_item_name,
184
+ type: sec_def['type'],
185
+ name: sec_def['name'],
186
+ in_f: sec_def['in'],
187
+ flow: parse_flows(sec_def['flows']),
188
+ scopes: sec_item
189
+ }
190
+ end
191
+ end
192
+ end
193
+
194
+ def fetch_security_scheme(name)
195
+ security_schemes.fetch(name) do |el|
196
+ raise ThreeScaleToolbox::Error, "OAS3 parsing error: #{el} not found in security schemes"
197
+ end
198
+ end
199
+
200
+ def security_requirements
201
+ definition.security || []
202
+ end
203
+
204
+ def security_schemes
205
+ (definition.components || {})['securitySchemes'] || {}
206
+ end
207
+
208
+ def parse_flows(flows_object)
209
+ return nil if flows_object.nil?
210
+
211
+ raise ThreeScaleToolbox::Error, 'Invalid OAS: multiple flows' if flows_object.size > 1
212
+
213
+ convert_flow(flows_object.keys.first)
214
+ end
215
+
216
+ def convert_flow(flow_name)
217
+ case flow_name
218
+ when 'implicit'
219
+ :implicit_flow_enabled
220
+ when 'password'
221
+ :direct_access_grants_enabled
222
+ when 'clientCredentials'
223
+ :service_accounts_enabled
224
+ when 'authorizationCode'
225
+ :standard_flow_enabled
226
+ else
227
+ raise ThreeScaleToolbox::Error, "Unexpected security flow field #{flow_name}"
228
+ end
229
+ end
230
+ end
231
+ end
232
+ end
@@ -0,0 +1,192 @@
1
+ module ThreeScaleToolbox
2
+ module OpenAPI
3
+ ##
4
+ #
5
+ # Swagger object
6
+ # * Swagger.title -> string
7
+ # * Swagger.description -> string
8
+ # * Swagger.version -> string
9
+ # * Swagger.basePath -> string
10
+ # * Swagger.host -> string
11
+ # * Swagger.scheme -> string
12
+ # * Swagger.operation -> array of operation hash
13
+ # * operation hash properties
14
+ # * :verb
15
+ # * :path
16
+ # * :description
17
+ # * :operation_id
18
+ # * Swagger.security -> security hash
19
+ # * security hash properties
20
+ # * :id -> string
21
+ # * :type -> string
22
+ # * :name -> string
23
+ # * :in_f -> string
24
+ # * :flow -> symbol (:implicit_flow_enabled, :direct_access_grants_enabled, :service_accounts_enabled, :standard_flow_enabled)
25
+ # * :scopes -> array of string
26
+ # * Swagger.service_backend_version -> string ('1','2','oidc')
27
+ # * Swagger.set_server_url -> def(spec, url)
28
+ # * Swagger.set_oauth2_urls-> def(spec, scheme_id, authorization_url, token_url)
29
+ class Swagger
30
+ META_SCHEMA_PATH = File.expand_path('../../../resources/swagger_meta_schema.json', __dir__)
31
+
32
+ def self.validate(raw)
33
+ meta_schema = JSON.parse(File.read(META_SCHEMA_PATH))
34
+ JSON::Validator.validate!(meta_schema, raw)
35
+ end
36
+
37
+ def self.build(raw, validate: true)
38
+ self.validate(raw) if validate
39
+
40
+ new(raw)
41
+ end
42
+
43
+ attr_reader :raw
44
+
45
+ def title
46
+ raw.dig('info', 'title')
47
+ end
48
+
49
+ def description
50
+ raw.dig('info', 'description')
51
+ end
52
+
53
+ def version
54
+ raw.dig('info', 'version')
55
+ end
56
+
57
+ def base_path
58
+ raw['basePath']
59
+ end
60
+
61
+ def host
62
+ raw['host']
63
+ end
64
+
65
+ def scheme
66
+ Array(raw['schemes']).first
67
+ end
68
+
69
+ def operations
70
+ @operations ||= parse_operations
71
+ end
72
+
73
+ def security
74
+ @security ||= parse_security
75
+ end
76
+
77
+ def service_backend_version
78
+ # default authentication mode if no security requirement
79
+ return '1' if security.nil?
80
+
81
+ case security[:type]
82
+ when 'oauth2'
83
+ 'oidc'
84
+ when 'apiKey'
85
+ '1'
86
+ else
87
+ raise ThreeScaleToolbox::Error, "Unexpected security scheme type #{security[:type]}"
88
+ end
89
+ end
90
+
91
+ def set_server_url(spec, url)
92
+ URI(url).tap do |uri|
93
+ spec['host'] = "#{uri.host}:#{uri.port}"
94
+ spec['schemes'] = [uri.scheme]
95
+ spec['basePath'] = uri.path
96
+ end
97
+ end
98
+
99
+ ##
100
+ # Update given spec with urls
101
+ # It is expected identified security scheme to be oauth2 type
102
+ def set_oauth2_urls(spec, sec_scheme_id, authorization_url, token_url)
103
+ sec_scheme_obj = spec.dig('securityDefinitions', sec_scheme_id)
104
+ if sec_scheme_obj.nil? || sec_scheme_obj['type'] != 'oauth2'
105
+ raise ThreeScaleToolbox::Error, "Expected security scheme {#{sec_scheme_id}} not found or not oauth2"
106
+ end
107
+
108
+ sec_scheme_obj['authorizationUrl'] = authorization_url if %w[implicit accessCode].include?(sec_scheme_obj['flow'])
109
+ sec_scheme_obj['tokenUrl'] = token_url if %w[password application accessCode].include?(sec_scheme_obj['flow'])
110
+ end
111
+
112
+ private
113
+
114
+ def initialize(raw)
115
+ @raw = raw
116
+ end
117
+
118
+ def parse_operations
119
+ raw['paths'].flat_map do |path, path_obj|
120
+ path_obj.flat_map do |method, operation|
121
+ next unless %w[get head post put patch delete trace options].include? method
122
+
123
+ {
124
+ verb: method,
125
+ path: path,
126
+ description: operation['description'],
127
+ operation_id: operation['operationId']
128
+ }
129
+ end.compact
130
+ end
131
+ end
132
+
133
+ def parse_security
134
+ raise ThreeScaleToolbox::Error, 'Invalid OAS: multiple security requirements' \
135
+ if global_security_requirements.size > 1
136
+
137
+ global_security_requirements.first
138
+ end
139
+
140
+ def global_security_requirements
141
+ @global_security_requirements ||= parse_global_security_reqs
142
+ end
143
+
144
+ def parse_global_security_reqs
145
+ security_requirements.flat_map do |sec_req|
146
+ sec_req.map do |sec_item_name, sec_item|
147
+ sec_def = fetch_security_definition(sec_item_name)
148
+ {
149
+ id: sec_item_name,
150
+ type: sec_def['type'],
151
+ name: sec_def['name'],
152
+ in_f: sec_def['in'],
153
+ flow: convert_flow(sec_def['flow']),
154
+ scopes: sec_item
155
+ }
156
+ end
157
+ end
158
+ end
159
+
160
+ def fetch_security_definition(name)
161
+ security_definitions.fetch(name) do |el|
162
+ raise ThreeScaleToolbox::Error, "Swagger parsing error: #{el} not found in security definitions"
163
+ end
164
+ end
165
+
166
+ def security_requirements
167
+ raw['security'] || []
168
+ end
169
+
170
+ def security_definitions
171
+ raw['securityDefinitions'] || {}
172
+ end
173
+
174
+ def convert_flow(flow_name)
175
+ return nil if flow_name.nil?
176
+
177
+ case flow_name
178
+ when 'implicit'
179
+ :implicit_flow_enabled
180
+ when 'password'
181
+ :direct_access_grants_enabled
182
+ when 'application'
183
+ :service_accounts_enabled
184
+ when 'accessCode'
185
+ :standard_flow_enabled
186
+ else
187
+ raise ThreeScaleToolbox::Error, "Unexpected security flow field #{flow_name}"
188
+ end
189
+ end
190
+ end
191
+ end
192
+ end