From 922c19d704944d3f0073fe6072dee1f8ca180f4a Mon Sep 17 00:00:00 2001 From: Matthew Ford Date: Sun, 29 Sep 2024 17:31:56 +0100 Subject: [PATCH] lint --- app/jobs/file_scan_job.rb | 13 ++++---- app/models/concerns/scan_files.rb | 2 +- app/models/form_answer_attachment.rb | 2 +- config/initializers/virus_scanner.rb | 6 ++-- lib/virus_scanner.rb | 30 +++++++++--------- spec/lib/virus_scanner_spec.rb | 46 ++++++++++++++-------------- 6 files changed, 50 insertions(+), 49 deletions(-) diff --git a/app/jobs/file_scan_job.rb b/app/jobs/file_scan_job.rb index 64637c713..e7129c98b 100644 --- a/app/jobs/file_scan_job.rb +++ b/app/jobs/file_scan_job.rb @@ -9,8 +9,8 @@ def perform(key, class_name, record_id, attribute_name) begin scan_result = VirusScanner.scan_file(file) - status = scan_result[:malware] ? "infected" : "clean" - record.send("on_scan_#{attribute_name}", status: status) + status = scan_result[:malware] ? :infected : :clean + record.send(:"on_scan_#{attribute_name}", status: status) rescue VirusScanner::AuthenticationError => e handle_authentication_error(record, attribute_name, e) rescue VirusScanner::FileTooLargeError => e @@ -24,20 +24,19 @@ def perform(key, class_name, record_id, attribute_name) def handle_authentication_error(record, attribute_name, error) Rails.logger.error("VirusScanner Authentication Error: #{error.message}") - record.send("on_scan_#{attribute_name}", status: "error") - # Notify administrators about the authentication issue - # notify_admins_about_auth_error + record.send(:"on_scan_#{attribute_name}", status: :error) + notify_admins_about_auth_error end def handle_file_too_large_error(record, attribute_name, error) Rails.logger.warn("File too large for virus scanning: #{error.message}") - record.send("on_scan_#{attribute_name}", status: "error") + record.send(:"on_scan_#{attribute_name}", status: :error) # You might want to add custom handling for oversized files end def handle_scan_error(record, attribute_name, error) Rails.logger.error("VirusScanner Error: #{error.message}") - record.send("on_scan_#{attribute_name}", status: "error") + record.send(:"on_scan_#{attribute_name}", status: :error) # You might want to retry the job or notify administrators end diff --git a/app/models/concerns/scan_files.rb b/app/models/concerns/scan_files.rb index b8eef141a..b83cdfb73 100644 --- a/app/models/concerns/scan_files.rb +++ b/app/models/concerns/scan_files.rb @@ -8,7 +8,7 @@ module ScanFiles def perform_virus_scan self.class.file_attributes_to_scan.each do |attr_name| - send("scan_#{attr_name}!") + send(:"scan_#{attr_name}!") end end diff --git a/app/models/form_answer_attachment.rb b/app/models/form_answer_attachment.rb index 378727864..8007c3aad 100644 --- a/app/models/form_answer_attachment.rb +++ b/app/models/form_answer_attachment.rb @@ -4,7 +4,7 @@ class FormAnswerAttachment < ApplicationRecord belongs_to :attachable, polymorphic: true, optional: true mount_uploader :file, FormAnswerAttachmentUploader - + scan_for_viruses :file scope :uploaded_by_user, -> { where attachable_type: "User" } diff --git a/config/initializers/virus_scanner.rb b/config/initializers/virus_scanner.rb index 18e5d23c2..38da6ac92 100644 --- a/config/initializers/virus_scanner.rb +++ b/config/initializers/virus_scanner.rb @@ -1,5 +1,5 @@ VirusScanner.configure( - base_url: ENV['VIRUS_SCANNER_URL'], - username: ENV['VIRUS_SCANNER_USERNAME'], - password: ENV['VIRUS_SCANNER_PASSWORD'] + base_url: ENV["VIRUS_SCANNER_URL"], + username: ENV["VIRUS_SCANNER_USERNAME"], + password: ENV["VIRUS_SCANNER_PASSWORD"], ) diff --git a/lib/virus_scanner.rb b/lib/virus_scanner.rb index 38e37a99b..459abb047 100644 --- a/lib/virus_scanner.rb +++ b/lib/virus_scanner.rb @@ -1,7 +1,7 @@ -require 'net/http' -require 'uri' -require 'json' -require 'tempfile' +require "net/http" +require "uri" +require "json" +require "tempfile" class VirusScanner class << self @@ -14,18 +14,18 @@ def configure(base_url:, username:, password:) end def scan_file(file) - return { malware: false } if ENV['DISABLE_VIRUS_SCANNER'] == 'true' + return { malware: false } if ENV["DISABLE_VIRUS_SCANNER"] == "true" - uri = URI.join(@base_url, '/v2/scan-chunked') + uri = URI.join(@base_url, "/v2/scan-chunked") request = Net::HTTP::Post.new(uri) request.basic_auth(@username, @password) - request['Content-Type'] = 'application/octet-stream' - request['Transfer-Encoding'] = 'chunked' + request["Content-Type"] = "application/octet-stream" + request["Transfer-Encoding"] = "chunked" temp_file = download_to_tempfile(file) begin request.body_stream = temp_file - response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == 'https') do |http| + response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == "https") do |http| http.request(request) end @@ -39,9 +39,9 @@ def scan_file(file) private def download_to_tempfile(file) - temp_file = Tempfile.new('virus_scan') + temp_file = Tempfile.new("virus_scan") if file.is_a?(String) - File.open(file, 'rb') { |f| IO.copy_stream(f, temp_file) } + File.open(file, "rb") { |f| IO.copy_stream(f, temp_file) } elsif file.respond_to?(:file) # CarrierWave uploader if file.file.respond_to?(:file) @@ -76,14 +76,16 @@ def handle_response(response) def parse_scan_result(body) result = JSON.parse(body) { - malware: result['malware'], - reason: result['reason'], - scan_time: result['time'] + malware: result["malware"], + reason: result["reason"], + scan_time: result["time"], } end end class AuthenticationError < StandardError; end + class FileTooLargeError < StandardError; end + class ScanError < StandardError; end end diff --git a/spec/lib/virus_scanner_spec.rb b/spec/lib/virus_scanner_spec.rb index 9d6f692b6..97d30797a 100644 --- a/spec/lib/virus_scanner_spec.rb +++ b/spec/lib/virus_scanner_spec.rb @@ -1,76 +1,76 @@ require "rails_helper" describe VirusScanner do - let(:base_url) { 'http://example.com' } - let(:username) { 'testuser' } - let(:password) { 'testpass' } - let(:file_path) { '/path/to/test/file.txt' } + let(:base_url) { "http://example.com" } + let(:username) { "testuser" } + let(:password) { "testpass" } + let(:file_path) { "/path/to/test/file.txt" } before do VirusScanner.configure(base_url: base_url, username: username, password: password) end - describe '.configure' do - it 'sets the base_url, username, and password' do + describe ".configure" do + it "sets the base_url, username, and password" do expect(VirusScanner.base_url).to eq(base_url) expect(VirusScanner.username).to eq(username) expect(VirusScanner.password).to eq(password) end end - describe '.scan_file' do - let(:uri) { URI.join(base_url, '/v2/scan-chunked') } + describe ".scan_file" do + let(:uri) { URI.join(base_url, "/v2/scan-chunked") } let(:http_response) { instance_double(Net::HTTPResponse) } let(:http) { instance_double(Net::HTTP) } before do - allow(File).to receive(:open).with(file_path, 'rb').and_yield(StringIO.new('file content')) + allow(File).to receive(:open).with(file_path, "rb").and_yield(StringIO.new("file content")) allow(Net::HTTP).to receive(:start).and_yield(http) allow(http).to receive(:request).and_return(http_response) allow_any_instance_of(Net::HTTP::Post).to receive(:body_stream=) end - context 'when the scan is successful' do + context "when the scan is successful" do let(:response_body) { '{"malware": false, "reason": null, "time": 0.1}' } before do - allow(http_response).to receive(:code).and_return('200') + allow(http_response).to receive(:code).and_return("200") allow(http_response).to receive(:body).and_return(response_body) end - it 'returns the parsed scan result' do + it "returns the parsed scan result" do result = VirusScanner.scan_file(file_path) - expect(result).to eq({malware: false, reason: nil, scan_time: 0.1}) + expect(result).to eq({ malware: false, reason: nil, scan_time: 0.1 }) end end - context 'when authentication fails' do + context "when authentication fails" do before do - allow(http_response).to receive(:code).and_return('401') + allow(http_response).to receive(:code).and_return("401") end - it 'raises an AuthenticationError' do + it "raises an AuthenticationError" do expect { VirusScanner.scan_file(file_path) }.to raise_error(VirusScanner::AuthenticationError) end end - context 'when the file is too large' do + context "when the file is too large" do before do - allow(http_response).to receive(:code).and_return('413') + allow(http_response).to receive(:code).and_return("413") end - it 'raises a FileTooLargeError' do + it "raises a FileTooLargeError" do expect { VirusScanner.scan_file(file_path) }.to raise_error(VirusScanner::FileTooLargeError) end end - context 'when an unexpected error occurs' do + context "when an unexpected error occurs" do before do - allow(http_response).to receive(:code).and_return('500') - allow(http_response).to receive(:message).and_return('Internal Server Error') + allow(http_response).to receive(:code).and_return("500") + allow(http_response).to receive(:message).and_return("Internal Server Error") end - it 'raises a ScanError' do + it "raises a ScanError" do expect { VirusScanner.scan_file(file_path) }.to raise_error(VirusScanner::ScanError, /Unexpected error: 500 Internal Server Error/) end end