Merge pull request #8044 from tchak/fix-export-polling

fix(turbo-stream): read delay on turbo-stream element
This commit is contained in:
Paul Chavard 2022-11-16 11:28:58 +01:00 committed by GitHub
commit 9df860f9b9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 60 additions and 122 deletions

View file

@ -4,19 +4,14 @@ module Administrateurs
before_action :ensure_not_super_admin!
def download
export = Export.find_or_create_export(export_format, all_groupe_instructeurs, **export_options)
if export.available? && export.old? && force_export?
export.destroy
export = Export.find_or_create_export(export_format, all_groupe_instructeurs, **export_options)
end
export = Export.find_or_create_export(export_format, all_groupe_instructeurs, force: force_export?, **export_options)
@dossiers_count = export.count
assign_exports
if export.available?
respond_to do |format|
format.turbo_stream do
@dossiers_count = export.count
assign_exports
flash.notice = "Lexport au format \"#{export_format}\" est prêt. Vous pouvez le <a href=\"#{export.file.service_url}\">télécharger</a>"
flash.notice = export.flash_message
end
format.html do
@ -25,18 +20,13 @@ module Administrateurs
end
else
respond_to do |format|
notice_message = "Nous générons cet export. Veuillez revenir dans quelques minutes pour le télécharger."
format.turbo_stream do
@dossiers_count = export.count
assign_exports
if !params[:no_progress_notification]
flash.notice = notice_message
flash.notice = export.flash_message
end
end
format.html do
redirect_to admin_procedure_archives_url(@procedure), notice: notice_message
redirect_to admin_procedure_archives_url(@procedure), notice: export.flash_message
end
end
end

View file

@ -158,21 +158,17 @@ module Instructeurs
.visible_by_administration
.exists?(groupe_instructeur_id: groupe_instructeur_ids) && !instructeur_as_manager?
export = Export.find_or_create_export(export_format, groupe_instructeurs, **export_options)
export = Export.find_or_create_export(export_format, groupe_instructeurs, force: force_export?, **export_options)
if export.available? && export.old? && force_export?
export.destroy
export = Export.find_or_create_export(export_format, groupe_instructeurs, **export_options)
end
@procedure = procedure
@statut = export_options[:statut]
@dossiers_count = export.count
assign_exports
if export.available?
respond_to do |format|
format.turbo_stream do
@procedure = procedure
@statut = export_options[:statut]
@dossiers_count = export.count
assign_exports
flash.notice = "Lexport au format \"#{export_format}\" est prêt. Vous pouvez le <a href=\"#{export.file.service_url}\">télécharger</a>"
flash.notice = export.flash_message
end
format.html do
@ -181,20 +177,13 @@ module Instructeurs
end
else
respond_to do |format|
notice_message = "Nous générons cet export. Veuillez revenir dans quelques minutes pour le télécharger."
format.turbo_stream do
@procedure = procedure
@statut = export_options[:statut]
@dossiers_count = export.count
assign_exports
if !params[:no_progress_notification]
flash.notice = notice_message
flash.notice = export.flash_message
end
end
format.html do
redirect_to instructeur_procedure_url(procedure), notice: notice_message
redirect_to instructeur_procedure_url(procedure), notice: export.flash_message
end
end
end

View file

@ -3,7 +3,7 @@ import morphdom from 'morphdom';
const hide: TurboStreamAction = function () {
this.targetElements.forEach((element: Element) => {
const delay = element.getAttribute('delay');
const delay = this.getAttribute('delay');
const hide = () => element.classList.add('hidden');
if (delay) {
setTimeout(hide, parseInt(delay, 10));
@ -14,7 +14,7 @@ const hide: TurboStreamAction = function () {
};
const show: TurboStreamAction = function () {
this.targetElements.forEach((element: Element) => {
const delay = element.getAttribute('delay');
const delay = this.getAttribute('delay');
const show = () => element.classList.remove('hidden');
if (delay) {
setTimeout(show, parseInt(delay, 10));

View file

@ -72,7 +72,7 @@ class Export < ApplicationRecord
end
def old?
updated_at < 20.minutes.ago || filters_changed?
updated_at < 10.minutes.ago || filters_changed?
end
def filters_changed?
@ -83,13 +83,23 @@ class Export < ApplicationRecord
procedure_presentation_id.present?
end
def self.find_or_create_export(format, groupe_instructeurs, time_span_type: time_span_types.fetch(:everything), statut: statuts.fetch(:tous), procedure_presentation: nil)
create_with(groupe_instructeurs: groupe_instructeurs, procedure_presentation: procedure_presentation, procedure_presentation_snapshot: procedure_presentation&.snapshot)
.includes(:procedure_presentation)
.create_or_find_by(format: format,
time_span_type: time_span_type,
statut: statut,
key: generate_cache_key(groupe_instructeurs.map(&:id), procedure_presentation))
def flash_message
if available?
"Lexport au format \"#{format}\" est prêt. Vous pouvez le <a href=\"#{file.service_url}\">télécharger</a>"
else
"Nous générons cet export. Veuillez revenir dans quelques minutes pour le télécharger."
end
end
def self.find_or_create_export(format, groupe_instructeurs, time_span_type: time_span_types.fetch(:everything), statut: statuts.fetch(:tous), procedure_presentation: nil, force: false)
export = create_or_find_export(format, groupe_instructeurs, time_span_type: time_span_type, statut: statut, procedure_presentation: procedure_presentation)
if export.available? && export.old? && force
export.destroy
create_or_find_export(format, groupe_instructeurs, time_span_type: time_span_type, statut: statut, procedure_presentation: procedure_presentation)
else
export
end
end
def self.find_for_groupe_instructeurs(groupe_instructeurs_ids, procedure_presentation)
@ -121,6 +131,15 @@ class Export < ApplicationRecord
}
end
def self.create_or_find_export(format, groupe_instructeurs, time_span_type:, statut:, procedure_presentation:)
create_with(groupe_instructeurs: groupe_instructeurs, procedure_presentation: procedure_presentation, procedure_presentation_snapshot: procedure_presentation&.snapshot)
.includes(:procedure_presentation)
.create_or_find_by(format: format,
time_span_type: time_span_type,
statut: statut,
key: generate_cache_key(groupe_instructeurs.map(&:id), procedure_presentation))
end
def self.generate_cache_key(groupe_instructeurs_ids, procedure_presentation = nil)
if procedure_presentation.present?
[

View file

@ -1,25 +1,5 @@
{
"ignored_warnings": [
{
"warning_type": "Redirect",
"warning_code": 18,
"fingerprint": "170b506bd3d25eb50f464703f9d993bf2e124d5cbc8478ce9d9d06a15b4bc55e",
"check_name": "Redirect",
"message": "Possible unprotected redirect",
"file": "app/controllers/instructeurs/exports_controller.rb",
"line": 26,
"link": "https://brakemanscanner.org/docs/warning_types/redirect/",
"code": "redirect_to(Export.find_or_create_export(export_format, groupe_instructeurs, **export_options).file.service_url)",
"render_path": null,
"location": {
"type": "method",
"class": "Instructeurs::ExportsController",
"method": "download"
},
"user_input": "Export.find_or_create_export(export_format, groupe_instructeurs, **export_options).file.service_url",
"confidence": "High",
"note": ""
},
{
"warning_type": "Cross-Site Scripting",
"warning_code": 2,
@ -35,7 +15,7 @@
"type": "controller",
"class": "Users::DossiersController",
"method": "merci",
"line": 204,
"line": 232,
"file": "app/controllers/users/dossiers_controller.rb",
"rendered": {
"name": "users/dossiers/merci",
@ -92,63 +72,23 @@
"confidence": "Weak",
"note": "explicitely sanitized even if we are using html_safe"
},
{
"warning_type": "SQL Injection",
"warning_code": 0,
"fingerprint": "4254ed68100af9b496883716b1fd658e1943b2385a0d08de5a6ef5c600c1a8f9",
"check_name": "SQL",
"message": "Possible SQL injection",
"file": "app/models/traitement.rb",
"line": 52,
"link": "https://brakemanscanner.org/docs/warning_types/sql_injection/",
"code": "ActiveRecord::Base.connection.execute(\"select date_trunc('month', r1.processed_at::TIMESTAMPTZ AT TIME ZONE '#{Time.zone.formatted_offset}'::INTERVAL) as month, count(r1.processed_at)\\nfrom (#{Traitement.select(\"max(traitements.processed_at) as processed_at\").termine.where(:dossier => Dossier.state_termine.where(:groupe_instructeur => groupe_instructeurs)).group(:dossier_id).to_sql}) as r1\\ngroup by date_trunc('month', r1.processed_at::TIMESTAMPTZ AT TIME ZONE '#{Time.zone.formatted_offset}'::INTERVAL)\\norder by month desc\\n\")",
"render_path": null,
"location": {
"type": "method",
"class": "Traitement",
"method": "Traitement.count_dossiers_termines_by_month"
},
"user_input": "Time.zone.formatted_offset",
"confidence": "Medium",
"note": ""
},
{
"warning_type": "Redirect",
"warning_code": 18,
"fingerprint": "589e457617e6ad3d35f454b4af8ed326817930d6a724febcf680d7e03c6aeaa2",
"fingerprint": "8a1ccc92988486094b2c89e586902a3b6fcbd43910d6363dce14b9981ca8ddeb",
"check_name": "Redirect",
"message": "Possible unprotected redirect",
"file": "app/controllers/targeted_user_links_controller.rb",
"line": 7,
"file": "app/controllers/instructeurs/procedures_controller.rb",
"line": 175,
"link": "https://brakemanscanner.org/docs/warning_types/redirect/",
"code": "redirect_to(TargetedUserLink.find(params[:id]).redirect_url(Rails.application.routes.url_helpers))",
"code": "redirect_to(Export.find_or_create_export(export_format, current_instructeur.groupe_instructeurs.where(:procedure => procedure), :force => force_export?, **export_options).file.service_url)",
"render_path": null,
"location": {
"type": "method",
"class": "TargetedUserLinksController",
"method": "show"
"class": "Instructeurs::ProceduresController",
"method": "download_export"
},
"user_input": "TargetedUserLink.find(params[:id]).redirect_url(Rails.application.routes.url_helpers)",
"confidence": "High",
"note": ""
},
{
"warning_type": "Redirect",
"warning_code": 18,
"fingerprint": "8f8133f0679f6301e098c4b9c61c2217224126856963abd02cdc5e54efb4e818",
"check_name": "Redirect",
"message": "Possible unprotected redirect",
"file": "app/controllers/administrateurs/exports_controller.rb",
"line": 22,
"link": "https://brakemanscanner.org/docs/warning_types/redirect/",
"code": "redirect_to(Export.find_or_create_export(export_format, all_groupe_instructeurs, **export_options).file.service_url)",
"render_path": null,
"location": {
"type": "method",
"class": "Administrateurs::ExportsController",
"method": "download"
},
"user_input": "Export.find_or_create_export(export_format, all_groupe_instructeurs, **export_options).file.service_url",
"user_input": "Export.find_or_create_export(export_format, current_instructeur.groupe_instructeurs.where(:procedure => procedure), :force => force_export?, **export_options).file.service_url",
"confidence": "High",
"note": ""
},
@ -159,7 +99,7 @@
"check_name": "SQL",
"message": "Possible SQL injection",
"file": "app/models/concerns/dossier_filtering_concern.rb",
"line": 25,
"line": 30,
"link": "https://brakemanscanner.org/docs/warning_types/sql_injection/",
"code": "where(\"#{values.count} OR #{\"(#{ProcedurePresentation.sanitized_column(table, column)} ILIKE ?)\"}\", *values.map do\n \"%#{value}%\"\n end)",
"render_path": null,
@ -175,24 +115,24 @@
{
"warning_type": "Redirect",
"warning_code": 18,
"fingerprint": "eae88be293b3849e07be81a18de99c04b08c7b2c045cc4a43ca3624ea178d965",
"fingerprint": "e2220b7cda7df5d02de77e7c3ce137653126e0d8e91ce445676b63ec4c94bbcb",
"check_name": "Redirect",
"message": "Possible unprotected redirect",
"file": "app/controllers/instructeurs/procedures_controller.rb",
"line": 168,
"file": "app/controllers/administrateurs/exports_controller.rb",
"line": 18,
"link": "https://brakemanscanner.org/docs/warning_types/redirect/",
"code": "redirect_to(Export.find_or_create_export(export_format, current_instructeur.groupe_instructeurs.where(:procedure => procedure), **export_options).file.service_url)",
"code": "redirect_to(Export.find_or_create_export(export_format, all_groupe_instructeurs, :force => force_export?, **export_options).file.service_url)",
"render_path": null,
"location": {
"type": "method",
"class": "Instructeurs::ProceduresController",
"method": "download_export"
"class": "Administrateurs::ExportsController",
"method": "download"
},
"user_input": "Export.find_or_create_export(export_format, current_instructeur.groupe_instructeurs.where(:procedure => procedure), **export_options).file.service_url",
"user_input": "Export.find_or_create_export(export_format, all_groupe_instructeurs, :force => force_export?, **export_options).file.service_url",
"confidence": "High",
"note": ""
}
],
"updated": "2022-07-08 13:14:19 +0200",
"updated": "2022-11-15 23:04:53 +0100",
"brakeman_version": "5.2.2"
}