3scale_toolbox 0.12.4 → 0.17.0

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