mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2024-12-25 01:03:18 +08:00
Use custom sanitizer config for PDF reports generation [SCI-9368]
This commit is contained in:
parent
9745ef62dc
commit
d9404df361
9 changed files with 58 additions and 35 deletions
|
@ -144,7 +144,7 @@ module ApplicationHelper
|
|||
|
||||
popover_for_user_name(user, team, false, false, base64_encoded_imgs)
|
||||
end
|
||||
new_text
|
||||
sanitize_input(new_text)
|
||||
end
|
||||
|
||||
# Generate smart annotation link for one user object
|
||||
|
|
|
@ -4,8 +4,16 @@ require 'sanitize'
|
|||
require 'cgi'
|
||||
|
||||
module InputSanitizeHelper
|
||||
def sanitize_input(html, _tags = [], _attributes = [], sanitizer_config: Constants::INPUT_SANITIZE_CONFIG)
|
||||
Sanitize.fragment(html, sanitizer_config).html_safe
|
||||
def sanitize_input(html, _tags = [], _attributes = [], sanitizer_config: nil)
|
||||
config =
|
||||
if Rails.application.config.x.custom_sanitizer_config.present?
|
||||
Rails.application.config.x.custom_sanitizer_config
|
||||
elsif sanitizer_config.present?
|
||||
sanitizer_config
|
||||
else
|
||||
Constants::INPUT_SANITIZE_CONFIG
|
||||
end
|
||||
Sanitize.fragment(html, config).html_safe
|
||||
end
|
||||
|
||||
def escape_input(text)
|
||||
|
|
|
@ -34,19 +34,22 @@ module Reports
|
|||
proxy.set_user(user, scope: :user, store: false)
|
||||
ApplicationController.renderer.defaults[:http_host] = Rails.application.routes.default_url_options[:host]
|
||||
renderer = ApplicationController.renderer.new(warden: proxy)
|
||||
Rails.application.config.x.custom_sanitizer_config = build_custom_sanitizer_config
|
||||
|
||||
file << renderer.render(
|
||||
pdf: 'report', header: { html: { template: "reports/templates/#{template}/header",
|
||||
locals: { report: report, user: user, logo: report_logo },
|
||||
layout: 'reports/footer_header' } },
|
||||
footer: { html: { template: "reports/templates/#{template}/footer",
|
||||
locals: { report: report, user: user, logo: report_logo },
|
||||
layout: 'reports/footer_header' } },
|
||||
assigns: { settings: report.settings },
|
||||
locals: { report: report },
|
||||
disable_javascript: false,
|
||||
template: 'reports/report',
|
||||
formats: :pdf
|
||||
pdf: 'report',
|
||||
header: { html: { template: "reports/templates/#{template}/header",
|
||||
locals: { report: report, user: user, logo: report_logo },
|
||||
layout: 'reports/footer_header' } },
|
||||
footer: { html: { template: "reports/templates/#{template}/footer",
|
||||
locals: { report: report, user: user, logo: report_logo },
|
||||
layout: 'reports/footer_header' } },
|
||||
assigns: { settings: report.settings },
|
||||
locals: { report: report },
|
||||
disable_javascript: false,
|
||||
disable_external_links: true,
|
||||
template: 'reports/report',
|
||||
formats: :pdf
|
||||
)
|
||||
|
||||
file.rewind
|
||||
|
@ -69,6 +72,7 @@ module Reports
|
|||
)
|
||||
notification.create_user_notification(user)
|
||||
ensure
|
||||
Rails.application.config.x.custom_sanitizer_config = nil
|
||||
I18n.backend.date_format = nil
|
||||
file.close(true)
|
||||
end
|
||||
|
@ -178,6 +182,15 @@ module Reports
|
|||
'scinote_logo.svg'
|
||||
end
|
||||
|
||||
def build_custom_sanitizer_config
|
||||
sanitizer_config = Constants::INPUT_SANITIZE_CONFIG.deep_dup
|
||||
sanitizer_config[:protocols] = {
|
||||
'a' => { 'href' => ['http', 'https', :relative] },
|
||||
'img' => { 'src' => %w(data) }
|
||||
}
|
||||
sanitizer_config
|
||||
end
|
||||
|
||||
# Overrides method from FailedDeliveryNotifiableJob concern
|
||||
def failed_notification_title
|
||||
I18n.t('projects.reports.index.generation.error_pdf_notification_title')
|
||||
|
|
|
@ -13,7 +13,7 @@ module TinyMceImages
|
|||
before_save :clean_tiny_mce_image_urls
|
||||
after_create :ensure_extracted_image_object_references
|
||||
|
||||
def prepare_for_report(field, base64_encoded_imgs = false)
|
||||
def prepare_for_report(field)
|
||||
description = self[field]
|
||||
|
||||
# Check tinymce for old format
|
||||
|
@ -21,13 +21,9 @@ module TinyMceImages
|
|||
|
||||
tiny_mce_assets.each do |tm_asset|
|
||||
next unless tm_asset&.image&.attached?
|
||||
|
||||
begin
|
||||
new_tm_asset_src =
|
||||
if base64_encoded_imgs
|
||||
tm_asset.convert_variant_to_base64(tm_asset.preview)
|
||||
else
|
||||
tm_asset.preview.processed.url(expires_in: Constants::URL_LONG_EXPIRE_TIME)
|
||||
end
|
||||
new_tm_asset_src = tm_asset.convert_variant_to_base64(tm_asset.preview)
|
||||
rescue ActiveStorage::FileNotFoundError
|
||||
next
|
||||
end
|
||||
|
@ -114,13 +110,17 @@ module TinyMceImages
|
|||
next if asset.object == self
|
||||
next unless asset.can_read?(user)
|
||||
else
|
||||
url = image['src']
|
||||
image_type = FastImage.type(url).to_s
|
||||
next unless image_type
|
||||
|
||||
image_type = nil
|
||||
begin
|
||||
new_image = Down.download(url, max_size: Rails.configuration.x.file_max_size_mb.megabytes)
|
||||
rescue Down::TooLarge => e
|
||||
uri = URI.parse(image['src'])
|
||||
if uri.scheme != 'https'
|
||||
uri.scheme = Rails.application.config.force_ssl ? 'https' : 'http'
|
||||
end
|
||||
image_type = FastImage.type(uri.to_s).to_s
|
||||
next unless image_type
|
||||
|
||||
new_image = Down.download(uri.to_s, max_size: Rails.configuration.x.file_max_size_mb.megabytes)
|
||||
rescue StandardError => e
|
||||
Rails.logger.error e.message
|
||||
next
|
||||
end
|
||||
|
|
|
@ -51,7 +51,7 @@
|
|||
<div class="row">
|
||||
<div class="col-xs-12">
|
||||
<% if my_module.description.present? %>
|
||||
<%= custom_auto_link(my_module.prepare_for_report(:description, export_all),
|
||||
<%= custom_auto_link(my_module.prepare_for_report(:description),
|
||||
team: current_team,
|
||||
simple_format: false,
|
||||
base64_encoded_imgs: export_all) %>
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
</div>
|
||||
<div class="row module-protocol-description">
|
||||
<% if @settings.dig('task', 'protocol', 'description') && protocol.description.present? %>
|
||||
<%= custom_auto_link(protocol.prepare_for_report(:description, export_all),
|
||||
<%= custom_auto_link(protocol.prepare_for_report(:description),
|
||||
team: current_team,
|
||||
simple_format: false,
|
||||
base64_encoded_imgs: export_all) %>
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
<div class="row">
|
||||
<div class="col-xs-12">
|
||||
<div class="text-container ql-editor">
|
||||
<%= custom_auto_link(result_text.prepare_for_report(:text, export_all),
|
||||
<%= custom_auto_link(result_text.prepare_for_report(:text),
|
||||
team: current_team,
|
||||
simple_format: false,
|
||||
tags: %w(img),
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
<div class="report-element report-step-attachment-element report-step-text-element">
|
||||
<div class="report-element-body">
|
||||
<% if step_text.text.present? %>
|
||||
<%= custom_auto_link(step_text.prepare_for_report(:text, export_all),
|
||||
team: current_team,
|
||||
simple_format: false,
|
||||
tags: %w(img),
|
||||
base64_encoded_imgs: export_all) %>
|
||||
<%= custom_auto_link(step_text.prepare_for_report(:text),
|
||||
team: current_team,
|
||||
simple_format: false,
|
||||
tags: %w(img),
|
||||
base64_encoded_imgs: export_all) %>
|
||||
<% else %>
|
||||
<em><%= t('projects.reports.elements.step.no_description') %></em>
|
||||
<% end %>
|
||||
|
|
|
@ -60,6 +60,8 @@ module Scinote
|
|||
|
||||
config.x.connected_devices_enabled = ENV['CONNECTED_DEVICES_ENABLED'] == 'true'
|
||||
|
||||
config.x.custom_sanitizer_config = nil
|
||||
|
||||
# Logging
|
||||
config.log_formatter = proc do |severity, datetime, progname, msg|
|
||||
"[#{datetime}] #{severity}: #{msg}\n"
|
||||
|
|
Loading…
Reference in a new issue