tenable-ruby-sdk 0.2.3 → 0.2.4

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: b6d43ebf62504ff612798c1da4e1b9ab3139fce82074ba5c45030d8369106cfd
4
- data.tar.gz: 919847851066083b7cf95d137b0eb7b376b522333ca4866a004337cdf0d32cc1
3
+ metadata.gz: 86589e9deaec4440aa70b20ecfeba69a3416a89e1bf878bcb487b64b89fcf718
4
+ data.tar.gz: cebd719560c8d982d71a0306ffa310da52af29a430b6943fd962b8301f467cf9
5
5
  SHA512:
6
- metadata.gz: fa1c0b19a4921747e86d7e5a5eb884ac3842b1db46cf1b7289920b026f55328536fe3ba6fbaddecd7b0bafce920dc1e6268fc54fd660ab797c32d8a5d9eb8b31
7
- data.tar.gz: d58116b3a1d534878c8dc0c10f6081bb686b64bb663744595472daee50429364cce5dd9221ab0edd83267485b7ac608bbeb90290c46ec2ef23c3dffe85636e1b
6
+ metadata.gz: c54b804d1fd9f24b320c6c645c552b7cdafe6eb6600fb8289500629c1d18a3fb525181655ad7b40f142fd6c95367398ccd79c5cc70c1ddce3c9ad1c504d2e539
7
+ data.tar.gz: c7060d7a71ad818ef898f1687694d81e22ac409c2b5e68a3feb0cb63bd1cb8e4e16b51e0dc09678f3a60e058d4be37238ad11c437a7672e8fced715f6907d444
@@ -1,11 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'uri'
4
+
3
5
  module Tenable
4
6
  module Resources
5
7
  # Provides access to the Tenable.io scan management endpoints.
6
8
  class Scans < Base
7
9
  # Supported scan export formats.
8
- SUPPORTED_EXPORT_FORMATS = %w[pdf csv nessus].freeze
10
+ SUPPORTED_EXPORT_FORMATS = %w[nessus html pdf csv db].freeze
9
11
 
10
12
  # @return [Integer] default seconds between export status polls
11
13
  DEFAULT_EXPORT_POLL_INTERVAL = 5
@@ -163,20 +165,21 @@ module Tenable
163
165
  # Initiates a scan report export.
164
166
  #
165
167
  # @param scan_id [Integer, String] the scan ID
166
- # @param format [String] export format — one of "pdf", "csv", or "nessus"
168
+ # @param format [String, Symbol] export format — one of "nessus", "html", "pdf", "csv", or "db"
169
+ # @param history_id [Integer, nil] optional scan history ID query parameter; required for "db" exports
167
170
  # @param body [Hash] additional export parameters (e.g., +chapters+ for PDF)
168
171
  # @return [Hash] response containing the file ID under +"file"+ key
169
- # @raise [ArgumentError] if the format is not supported
172
+ # @raise [ArgumentError] if required parameters are missing or format is not supported
170
173
  #
171
174
  # @example
172
175
  # client.scans.export_request(123, format: 'pdf', chapters: 'vuln_hosts_summary')
173
- def export_request(scan_id, format:, **body)
176
+ def export_request(scan_id, format:, history_id: nil, **body)
174
177
  validate_path_segment!(scan_id, name: 'scan_id')
175
- unless SUPPORTED_EXPORT_FORMATS.include?(format)
176
- raise ArgumentError, "Unsupported format '#{format}'. Must be one of: #{SUPPORTED_EXPORT_FORMATS.join(', ')}"
177
- end
178
+ format = normalize_export_format(format)
179
+ validate_export_format!(format)
180
+ validate_export_request!(format, history_id: history_id, body: body)
178
181
 
179
- post("/scans/#{scan_id}/export", body.merge(format: format))
182
+ post(export_request_path(scan_id, history_id), body.merge(format: format))
180
183
  end
181
184
 
182
185
  # Retrieves the status of a scan export.
@@ -222,7 +225,7 @@ module Tenable
222
225
  # Convenience method: requests an export, waits for completion, and downloads the result.
223
226
  #
224
227
  # @param scan_id [Integer, String] the scan ID
225
- # @param format [String] export format — one of "pdf", "csv", or "nessus"
228
+ # @param format [String, Symbol] export format — one of "nessus", "html", "pdf", "csv", or "db"
226
229
  # @param save_path [String, nil] if provided, writes binary content to this file path.
227
230
  # The caller is responsible for ensuring the path is safe and writable.
228
231
  # This value is used as-is with +File.binwrite+ — no sanitization is performed.
@@ -251,6 +254,49 @@ module Tenable
251
254
  content
252
255
  end
253
256
  end
257
+
258
+ private
259
+
260
+ def normalize_export_format(format)
261
+ format.to_s
262
+ end
263
+
264
+ def validate_export_format!(format)
265
+ return if SUPPORTED_EXPORT_FORMATS.include?(format)
266
+
267
+ raise ArgumentError, "Unsupported format '#{format}'. Must be one of: #{SUPPORTED_EXPORT_FORMATS.join(', ')}"
268
+ end
269
+
270
+ def validate_export_request!(format, history_id:, body:)
271
+ validate_chapters_requirement!(format, body[:chapters])
272
+ validate_db_requirements!(format, history_id: history_id, body: body)
273
+ end
274
+
275
+ def validate_chapters_requirement!(format, chapters)
276
+ return unless %w[pdf html].include?(format)
277
+ return unless blank_value?(chapters)
278
+
279
+ raise ArgumentError, "chapters is required when format is '#{format}'"
280
+ end
281
+
282
+ def validate_db_requirements!(format, history_id:, body:)
283
+ return unless format == 'db'
284
+
285
+ raise ArgumentError, "history_id is required when format is 'db'" if history_id.nil?
286
+ raise ArgumentError, "asset_id is required when format is 'db'" if blank_value?(body[:asset_id])
287
+ raise ArgumentError, "password is required when format is 'db'" if blank_value?(body[:password])
288
+ end
289
+
290
+ def export_request_path(scan_id, history_id)
291
+ path = "/scans/#{scan_id}/export"
292
+ return path if history_id.nil?
293
+
294
+ "#{path}?#{URI.encode_www_form(history_id: history_id)}"
295
+ end
296
+
297
+ def blank_value?(value)
298
+ value.nil? || value.to_s.strip.empty?
299
+ end
254
300
  end
255
301
  end
256
302
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Tenable
4
- VERSION = '0.2.3'
4
+ VERSION = '0.2.4'
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tenable-ruby-sdk
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.3
4
+ version: 0.2.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - vudx00