When a new PJ is uploaded enqueue a anti virus scan job

This commit is contained in:
Mathieu Magnin 2018-05-11 14:59:20 +02:00
parent 927cd3c6f4
commit cd4615b10d
8 changed files with 105 additions and 0 deletions

View file

@ -0,0 +1,20 @@
class AntiVirusJob < ApplicationJob
include ActiveStorage::Downloading
attr_reader :blob
def perform(virus_scan)
@blob = ActiveStorage::Blob.find_by(key: virus_scan.blob_key)
if @blob.present?
download_blob_to_tempfile do |file|
if ClamavService.safe_file?(file.path)
status = "safe"
else
status = "infected"
end
virus_scan.update(scanned_at: Time.now, status: status)
end
end
end
end

View file

@ -1,2 +1,12 @@
class Champs::PieceJustificativeChamp < Champ
after_commit :create_virus_scan
def create_virus_scan
if self.piece_justificative_file&.attachment&.blob.present?
VirusScan.where(champ: self).where.not(blob_key: self.piece_justificative_file.blob.key).delete_all
VirusScan.find_or_create_by!(champ: self, blob_key: self.piece_justificative_file.blob.key) do |virus_scan|
virus_scan.status = "pending"
end
end
end
end

View file

@ -47,6 +47,7 @@ Rails.application.configure do
}
config.active_job.queue_adapter = :test
config.active_storage.service = :test
# Raises error for missing translations
# config.action_view.raise_on_missing_translations = true

View file

@ -1,3 +1,7 @@
local:
service: Disk
root: <%= Rails.root.join("storage") %>
test:
service: Disk
root: <%= Rails.root.join("tmp/storage") %>

View file

@ -17,5 +17,15 @@ FactoryBot.define do
trait :dossier_link do
type_de_champ { create(:type_de_champ_dossier_link) }
end
trait :piece_justificative do
type_de_champ { create(:type_de_champ_piece_justificative) }
end
trait :with_piece_justificative_file do
after(:create) do |champ, evaluator|
champ.piece_justificative_file.attach(io: StringIO.new("toto"), filename: "toto.txt", content_type: "text/plain")
end
end
end
end

View file

@ -0,0 +1,4 @@
FactoryBot.define do
factory :virus_scan do
end
end

View file

@ -0,0 +1,32 @@
RSpec.describe AntiVirusJob, type: :job do
let(:champ) do
champ = create(:champ, :piece_justificative)
champ.piece_justificative_file.attach(io: StringIO.new("toto"), filename: "toto.txt", content_type: "text/plain")
champ
end
let(:virus_scan) { create(:virus_scan, status: "pending", champ: champ, blob_key: champ.piece_justificative_file.blob.key) }
subject { AntiVirusJob.new.perform(virus_scan) }
context "when no virus is found" do
let(:virus_found?) { true }
before do
allow(ClamavService).to receive(:safe_file?).and_return(virus_found?)
subject
end
it { expect(virus_scan.reload.status).to eq("safe") }
end
context "when a virus is found" do
let(:virus_found?) { false }
before do
allow(ClamavService).to receive(:safe_file?).and_return(virus_found?)
subject
end
it { expect(virus_scan.reload.status).to eq("infected") }
end
end

View file

@ -127,4 +127,28 @@ describe Champ do
it { expect(champ.for_export).to eq('Crétinier, Mousserie') }
end
end
describe '#enqueue_virus_check' do
let(:champ) { type_de_champ.champ.build(value: nil) }
context 'when type_champ is type_de_champ_piece_justificative' do
let(:type_de_champ) { create(:type_de_champ_piece_justificative) }
context 'and there is a blob' do
before { champ.piece_justificative_file.attach(io: StringIO.new("toto"), filename: "toto.txt", content_type: "text/plain") }
it { expect{ champ.save }.to change(VirusScan, :count).by(1) }
end
context 'and there is no blob' do
it { expect{ champ.save }.to_not change(VirusScan, :count) }
end
end
context 'when type_champ is not type_de_champ_piece_justificative' do
let(:type_de_champ) { create(:type_de_champ_textarea) }
it { expect{ champ.save }.to_not change(VirusScan, :count) }
end
end
end