Merge pull request #7140 from betagouv/only_safe_pj_in_zip
fix(archive): exporte uniquement les fichiers sans virus
This commit is contained in:
commit
9b1f9f9a21
4 changed files with 85 additions and 13 deletions
|
@ -165,6 +165,7 @@ class PiecesJustificativesService
|
|||
ActiveStorage::Attachment
|
||||
.includes(:blob)
|
||||
.where(record_type: "Champ", record_id: champ_id_dossier_id.keys)
|
||||
.filter { |a| safe_attachment(a) }
|
||||
.map do |a|
|
||||
dossier_id = champ_id_dossier_id[a.record_id]
|
||||
ActiveStorage::DownloadableFile.pj_and_path(dossier_id, a)
|
||||
|
@ -181,6 +182,7 @@ class PiecesJustificativesService
|
|||
ActiveStorage::Attachment
|
||||
.includes(:blob)
|
||||
.where(record_type: "Commentaire", record_id: commentaire_id_dossier_id.keys)
|
||||
.filter { |a| safe_attachment(a) }
|
||||
.map do |a|
|
||||
dossier_id = commentaire_id_dossier_id[a.record_id]
|
||||
ActiveStorage::DownloadableFile.pj_and_path(dossier_id, a)
|
||||
|
@ -212,6 +214,7 @@ class PiecesJustificativesService
|
|||
ActiveStorage::Attachment
|
||||
.includes(:blob)
|
||||
.where(record_type: "Dossier", name: "justificatif_motivation", record_id: dossiers)
|
||||
.filter { |a| safe_attachment(a) }
|
||||
.map do |a|
|
||||
dossier_id = a.record_id
|
||||
ActiveStorage::DownloadableFile.pj_and_path(dossier_id, a)
|
||||
|
@ -262,4 +265,10 @@ class PiecesJustificativesService
|
|||
.where(record_type: "BillSignature", record_id: bill_ids)
|
||||
.map { |bill| ActiveStorage::DownloadableFile.bill_and_path(bill) }
|
||||
end
|
||||
|
||||
def self.safe_attachment(attachment)
|
||||
attachment
|
||||
.blob
|
||||
.metadata[:virus_scan_result] == ActiveStorage::VirusScanner::SAFE
|
||||
end
|
||||
end
|
||||
|
|
|
@ -23,6 +23,16 @@ describe PiecesJustificativesService do
|
|||
it { expect(subject).to match_array([pj_champ.call(dossier).piece_justificative_file.attachment]) }
|
||||
end
|
||||
|
||||
context 'with a pj not safe on a champ' do
|
||||
let(:procedure) { create(:procedure, :with_piece_justificative) }
|
||||
let(:dossier) { create(:dossier, procedure: procedure) }
|
||||
let(:pj_champ) { -> (d) { d.champs.find { |c| c.type == 'Champs::PieceJustificativeChamp' } } }
|
||||
|
||||
before { attach_file_to_champ(pj_champ.call(dossier), safe = false) }
|
||||
|
||||
it { expect(subject).to be_empty }
|
||||
end
|
||||
|
||||
context 'with a private pj champ' do
|
||||
let(:procedure) { create(:procedure) }
|
||||
let(:dossier) { create(:dossier, procedure: procedure) }
|
||||
|
@ -64,12 +74,26 @@ describe PiecesJustificativesService do
|
|||
let(:dossier) { create(:dossier) }
|
||||
let(:witness) { create(:dossier) }
|
||||
|
||||
let!(:commentaire) { create(:commentaire, :with_file, dossier: dossier) }
|
||||
let!(:witness_commentaire) { create(:commentaire, :with_file, dossier: witness) }
|
||||
let!(:commentaire) { create(:commentaire, dossier: dossier) }
|
||||
let!(:witness_commentaire) { create(:commentaire, dossier: witness) }
|
||||
|
||||
before do
|
||||
attach_file(commentaire.piece_jointe)
|
||||
attach_file(witness_commentaire.piece_jointe)
|
||||
end
|
||||
|
||||
it { expect(subject).to match_array(dossier.commentaires.first.piece_jointe.attachment) }
|
||||
end
|
||||
|
||||
context 'with a pj not safe on a commentaire' do
|
||||
let(:dossier) { create(:dossier) }
|
||||
let!(:commentaire) { create(:commentaire, dossier: dossier) }
|
||||
|
||||
before { attach_file(commentaire.piece_jointe, safe = false) }
|
||||
|
||||
it { expect(subject).to be_empty }
|
||||
end
|
||||
|
||||
context 'with a motivation' do
|
||||
let(:dossier) { create(:dossier, :with_justificatif) }
|
||||
let!(:witness) { create(:dossier, :with_justificatif) }
|
||||
|
@ -77,6 +101,14 @@ describe PiecesJustificativesService do
|
|||
it { expect(subject).to match_array(dossier.justificatif_motivation.attachment) }
|
||||
end
|
||||
|
||||
context 'with a motivation not safe' do
|
||||
let(:dossier) { create(:dossier) }
|
||||
|
||||
before { attach_file(dossier.justificatif_motivation, safe = false) }
|
||||
|
||||
it { expect(subject).to be_empty }
|
||||
end
|
||||
|
||||
context 'with an attestation' do
|
||||
let(:dossier) { create(:dossier, :with_attestation) }
|
||||
let!(:witness) { create(:dossier, :with_attestation) }
|
||||
|
@ -167,12 +199,20 @@ describe PiecesJustificativesService do
|
|||
end
|
||||
end
|
||||
|
||||
def attach_file_to_champ(champ)
|
||||
attach_file(champ.piece_justificative_file)
|
||||
def attach_file_to_champ(champ, safe = true)
|
||||
attach_file(champ.piece_justificative_file, safe)
|
||||
end
|
||||
|
||||
def attach_file(attachable)
|
||||
attachable
|
||||
.attach(io: StringIO.new("toto"), filename: "toto.png", content_type: "image/png")
|
||||
def attach_file(attachable, safe = true)
|
||||
to_be_attached = {
|
||||
io: StringIO.new("toto"),
|
||||
filename: "toto.png", content_type: "image/png"
|
||||
}
|
||||
|
||||
if safe
|
||||
to_be_attached[:metadata] = { virus_scan_result: ActiveStorage::VirusScanner::SAFE }
|
||||
end
|
||||
|
||||
attachable.attach(to_be_attached)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -90,8 +90,22 @@ describe 'Inviting an expert:' do
|
|||
let(:commentaire) { create(:commentaire, instructeur: instructeur, dossier: dossier) }
|
||||
|
||||
before do
|
||||
champ.piece_justificative_file.attach(io: File.open(path), filename: "piece_justificative_0.pdf", content_type: "application/pdf")
|
||||
dossier.champs_private << create(:champ_piece_justificative, :with_piece_justificative_file, private: true, dossier: dossier)
|
||||
champ
|
||||
.piece_justificative_file
|
||||
.attach(io: File.open(path),
|
||||
filename: "piece_justificative_0.pdf",
|
||||
content_type: "application/pdf",
|
||||
metadata: { virus_scan_result: ActiveStorage::VirusScanner::SAFE })
|
||||
|
||||
dossier.champs_private << create(:champ_piece_justificative, private: true, dossier: dossier)
|
||||
|
||||
dossier.champs_private
|
||||
.first
|
||||
.piece_justificative_file
|
||||
.attach(io: File.open(path),
|
||||
filename: "piece_justificative_0.pdf",
|
||||
content_type: "application/pdf",
|
||||
metadata: { virus_scan_result: ActiveStorage::VirusScanner::SAFE })
|
||||
end
|
||||
|
||||
scenario 'An Expert can download an archive containing attachments without any private champ, bill signature and operations logs' do
|
||||
|
@ -102,7 +116,7 @@ describe 'Inviting an expert:' do
|
|||
click_on '1 avis à donner'
|
||||
click_on avis.dossier.user.email
|
||||
|
||||
find(:css, '.attached').click
|
||||
find(:css, '[aria-controls=print-pj-menu]').click
|
||||
click_on 'Télécharger le dossier et toutes ses pièces jointes'
|
||||
# For some reason, clicking the download link does not trigger the download in the headless browser ;
|
||||
# So we need to go to the download link directly
|
||||
|
|
|
@ -194,14 +194,18 @@ describe 'Instructing a dossier:', js: true do
|
|||
|
||||
before do
|
||||
dossier.passer_en_instruction!(instructeur: instructeur)
|
||||
champ.piece_justificative_file.attach(io: File.open(path), filename: "piece_justificative_0.pdf", content_type: "application/pdf")
|
||||
champ.piece_justificative_file
|
||||
.attach(io: File.open(path),
|
||||
filename: "piece_justificative_0.pdf",
|
||||
content_type: "application/pdf",
|
||||
metadata: { virus_scan_result: ActiveStorage::VirusScanner::SAFE })
|
||||
|
||||
log_in(instructeur.email, password)
|
||||
visit instructeur_dossier_path(procedure, dossier)
|
||||
end
|
||||
|
||||
scenario 'A instructeur can download an archive containing a single attachment' do
|
||||
find(:css, '.attached').click
|
||||
find(:css, '[aria-controls=print-pj-menu]').click
|
||||
click_on 'Télécharger le dossier et toutes ses pièces jointes'
|
||||
# For some reason, clicking the download link does not trigger the download in the headless browser ;
|
||||
# So we need to go to the download link directly
|
||||
|
@ -219,7 +223,12 @@ describe 'Instructing a dossier:', js: true do
|
|||
end
|
||||
|
||||
scenario 'A instructeur can download an archive containing several identical attachments' do
|
||||
commentaire.piece_jointe.attach(io: File.open(path), filename: "piece_justificative_0.pdf", content_type: "application/pdf")
|
||||
commentaire
|
||||
.piece_jointe
|
||||
.attach(io: File.open(path),
|
||||
filename: "piece_justificative_0.pdf",
|
||||
content_type: "application/pdf",
|
||||
metadata: { virus_scan_result: ActiveStorage::VirusScanner::SAFE })
|
||||
|
||||
visit telecharger_pjs_instructeur_dossier_path(procedure, dossier)
|
||||
DownloadHelpers.wait_for_download
|
||||
|
|
Loading…
Reference in a new issue