Class: NucleusApi
- Inherits:
-
Object
- Object
- NucleusApi
- Defined in:
- lib/domain/project/api.rb,
lib/service/api/nucleus.rb
Instance Attribute Summary collapse
-
#api_key ⇒ Object
readonly
Returns the value of attribute api_key.
-
#archive_dir ⇒ Object
readonly
Returns the value of attribute archive_dir.
-
#base_url ⇒ Object
readonly
Returns the value of attribute base_url.
-
#download_dir ⇒ Object
readonly
Returns the value of attribute download_dir.
Instance Method Summary collapse
- #download(path) ⇒ Object
- #download_file(request) ⇒ Object
- #download_project_report(id, report_id, dir = nil) ⇒ Object
- #extract_report_id(filename) ⇒ Object
- #fetch(model_class) ⇒ Object
- #fetch_project(id) ⇒ Object
- #fetch_project_report_details(spreadsheet, report_id:, tabsheet_name: 'Scan Data') ⇒ Object
- #fetch_project_report_findings(spreadsheet, report_id:) ⇒ Object
- #fetch_project_report_vulns(spreadsheet, report_id:, tabsheet_name:) ⇒ Object
- #fetch_project_reports(id, start: 0, limit: 1) ⇒ Object
- #fetch_projects ⇒ Object
- #find_all_project_report_by(id, report_name:, since: nil) ⇒ Object
-
#find_first_project_report_name(id, name) ⇒ Object
Return the first project report with the correct name.
- #find_project_report_if(id, condition) ⇒ Object
-
#get(path, params = {}) ⇒ Object
Generic GET request.
-
#initialize(base_url:, api_key:, download_dir:, archive_dir:) ⇒ NucleusApi
constructor
A new instance of NucleusApi.
-
#post(path, body) ⇒ Object
Generic POST request.
-
#put(path, body) ⇒ Object
Generic PUT request.
-
#run_request(request) ⇒ Object
Runs the request and handles the response.
Constructor Details
#initialize(base_url:, api_key:, download_dir:, archive_dir:) ⇒ NucleusApi
Returns a new instance of NucleusApi.
12 13 14 15 16 17 18 19 20 21 22 |
# File 'lib/service/api/nucleus.rb', line 12 def initialize(base_url:, api_key:, download_dir:, archive_dir:) @options = { headers: { 'Accept' => 'application/json', 'x-apikey' => api_key } } @base_url = base_url @download_dir = download_dir @archive_dir = archive_dir end |
Instance Attribute Details
#api_key ⇒ Object (readonly)
Returns the value of attribute api_key.
7 8 9 |
# File 'lib/service/api/nucleus.rb', line 7 def api_key @api_key end |
#archive_dir ⇒ Object (readonly)
Returns the value of attribute archive_dir.
7 8 9 |
# File 'lib/service/api/nucleus.rb', line 7 def archive_dir @archive_dir end |
#base_url ⇒ Object (readonly)
Returns the value of attribute base_url.
7 8 9 |
# File 'lib/service/api/nucleus.rb', line 7 def base_url @base_url end |
#download_dir ⇒ Object (readonly)
Returns the value of attribute download_dir.
7 8 9 |
# File 'lib/service/api/nucleus.rb', line 7 def download_dir @download_dir end |
Instance Method Details
#download(path) ⇒ Object
78 79 80 81 82 83 84 85 |
# File 'lib/service/api/nucleus.rb', line 78 def download(path) download_request = Typhoeus::Request.new( "#{base_url}#{path}", method: :get, headers: @options[:headers].merge('Accept' => 'application/octet-stream') ) download_file(download_request) end |
#download_file(request) ⇒ Object
87 88 89 90 91 92 93 94 95 |
# File 'lib/service/api/nucleus.rb', line 87 def download_file(request) response = request.run if response.success? response.body else puts "Failed to download file: HTTP #{response.code}" nil end end |
#download_project_report(id, report_id, dir = nil) ⇒ Object
73 74 75 76 77 78 79 80 81 82 |
# File 'lib/domain/project/api.rb', line 73 def download_project_report(id, report_id, dir = nil) endpoint = [Project.url_path, id, 'reports', report_id, 'download'].join('/') file_content = download(endpoint) raise 'Download failed.' if file_content.nil? dir ||= download_dir filename ||= "#{dir}/project_#{id}_report_#{report_id}.xlsx" File.open(filename, 'wb') { |file| file.write(file_content) } end |
#extract_report_id(filename) ⇒ Object
84 85 86 87 |
# File 'lib/domain/project/api.rb', line 84 def extract_report_id(filename) match_data = filename.match(/project_\d+_report_(\d+)\.xlsx/) match_data[1] if match_data end |
#fetch(model_class) ⇒ Object
24 25 26 27 28 29 |
# File 'lib/service/api/nucleus.rb', line 24 def fetch(model_class) get(model_class.url_path).map do |data| # p data model_class.new(data) end end |
#fetch_project(id) ⇒ Object
12 13 14 15 |
# File 'lib/domain/project/api.rb', line 12 def fetch_project(id) endpoint = [Project.url_path, id].join('/') Project.new get(endpoint) end |
#fetch_project_report_details(spreadsheet, report_id:, tabsheet_name: 'Scan Data') ⇒ Object
89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 |
# File 'lib/domain/project/api.rb', line 89 def fetch_project_report_details(spreadsheet, report_id:, tabsheet_name: 'Scan Data') xlsx = Roo::Excelx.new(spreadsheet) sheet = xlsx.sheet(tabsheet_name) headers = xlsx.row(1) details = [] row_id = 1 total_rows = sheet.last_row - 1 return [] if total_rows.zero? = ProgressBar.create( title: "Fetching #{total_rows} details", total: total_rows, format: '%a %B %p%% %t' ) xlsx.each_row_streaming(offset: 1) do |row| values = row.map(&:value) hash = Hash[headers.zip(values)] hash['report_id'] = report_id hash['row_id'] = row_id details << ProjectReportDetail.new(hash) row_id += 1 .increment end details end |
#fetch_project_report_findings(spreadsheet, report_id:) ⇒ Object
116 117 118 119 120 |
# File 'lib/domain/project/api.rb', line 116 def fetch_project_report_findings(spreadsheet, report_id:) ProjectReportFinding::SEVERITIES.flat_map do |severity| fetch_project_report_vulns(spreadsheet, report_id:, tabsheet_name: severity) end end |
#fetch_project_report_vulns(spreadsheet, report_id:, tabsheet_name:) ⇒ Object
122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 |
# File 'lib/domain/project/api.rb', line 122 def fetch_project_report_vulns(spreadsheet, report_id:, tabsheet_name:) xlsx = Roo::Excelx.new(spreadsheet) return [] unless xlsx.sheets.include?(tabsheet_name) sheet = xlsx.sheet(tabsheet_name) headers = xlsx.row(1) total_rows = sheet.last_row - 1 return [] if total_rows.zero? findings = [] = ProgressBar.create( title: "Fetching #{total_rows} #{tabsheet_name} findings", total: total_rows, format: '%a %B %p%% %t' ) xlsx.each_row_streaming(offset: 1) do |row| values = row.map(&:value) hash = Hash[headers.zip(values)] hash['severity'] = tabsheet_name hash['report_id'] = report_id findings << ProjectReportFinding.new(hash) .increment end findings end |
#fetch_project_reports(id, start: 0, limit: 1) ⇒ Object
67 68 69 70 71 |
# File 'lib/domain/project/api.rb', line 67 def fetch_project_reports(id, start: 0, limit: 1) endpoint = [Project.url_path, id, 'reports'].join('/') reports = get(endpoint, { start:, limit: }) reports.map { |report| ProjectReport.new(report.merge('project_id' => id)) } end |
#fetch_projects ⇒ Object
8 9 10 |
# File 'lib/domain/project/api.rb', line 8 def fetch_projects fetch(Project) end |
#find_all_project_report_by(id, report_name:, since: nil) ⇒ Object
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
# File 'lib/domain/project/api.rb', line 26 def find_all_project_report_by( id, report_name:, since: nil ) since ||= Date.new(2024, 1, 1) condition = lambda do |report| report.name == report_name end reports = [] find_project_report_if(id, condition) do |report| return reports if Date.parse(report.created_on) < since reports << report end reports end |
#find_first_project_report_name(id, name) ⇒ Object
Return the first project report with the correct name
18 19 20 21 22 23 24 |
# File 'lib/domain/project/api.rb', line 18 def find_first_project_report_name(id, name) condition = ->(report) { report.name == name } find_project_report_if(id, condition) do |report| return report end nil end |
#find_project_report_if(id, condition) ⇒ Object
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
# File 'lib/domain/project/api.rb', line 44 def find_project_report_if(id, condition) start = 0 limit = 50 found_reports = [] loop do reports = fetch_project_reports(id, start:, limit:) break if reports.empty? reports.each do |report| # puts "#{report.created_on}" next unless condition.call(report) if block_given? yield(report) else found_reports << report end end start += limit end found_reports unless block_given? end |
#get(path, params = {}) ⇒ Object
Generic GET request
32 33 34 35 36 37 38 39 40 |
# File 'lib/service/api/nucleus.rb', line 32 def get(path, params = {}) request = Typhoeus::Request.new( "#{base_url}#{path}", method: :get, headers: @options[:headers], params: ) run_request(request) end |
#post(path, body) ⇒ Object
Generic POST request
43 44 45 46 47 48 49 50 51 |
# File 'lib/service/api/nucleus.rb', line 43 def post(path, body) request = Typhoeus::Request.new( "#{base_url}#{path}", method: :post, headers: @options[:headers], body: body.to_json ) run_request(request) end |
#put(path, body) ⇒ Object
Generic PUT request
54 55 56 57 58 59 60 61 62 |
# File 'lib/service/api/nucleus.rb', line 54 def put(path, body) request = Typhoeus::Request.new( "#{base_url}#{path}", method: :put, headers: @options[:headers], body: body.to_json ) run_request(request) end |
#run_request(request) ⇒ Object
Runs the request and handles the response
65 66 67 68 69 70 71 72 73 74 75 76 |
# File 'lib/service/api/nucleus.rb', line 65 def run_request(request) response = request.run if response.success? JSON.parse(response.body) elsif response.timed_out? { error: 'Request timed out' } elsif response.code == 0 { error: response. } else { error: 'HTTP request failed', status_code: response.code } end end |