mirror of
https://0xacab.org/sutty/sutty
synced 2025-02-21 11:41:48 +00:00
Merge branch 'usar-sutty-editor' into panel.sutty.nl
This commit is contained in:
commit
e9ed87afdf
3 changed files with 78 additions and 15 deletions
|
@ -24,7 +24,11 @@ class MetadataContent < MetadataTemplate
|
||||||
end
|
end
|
||||||
|
|
||||||
def to_s
|
def to_s
|
||||||
sanitizer.sanitize value, tags: [], attributes: []
|
Nokogiri::HTML.fragment(value).tap do |html|
|
||||||
|
html.css('[src^="public/"]').each do |element|
|
||||||
|
element['src'] = convert_internal_path_to_src element['src']
|
||||||
|
end
|
||||||
|
end.to_s
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
@ -47,16 +51,17 @@ class MetadataContent < MetadataTemplate
|
||||||
|
|
||||||
# Eliminar elementos sin src y comprobar su origen
|
# Eliminar elementos sin src y comprobar su origen
|
||||||
html.css(elements).each do |element|
|
html.css(elements).each do |element|
|
||||||
unless element['src']
|
|
||||||
element.remove
|
|
||||||
next
|
|
||||||
end
|
|
||||||
|
|
||||||
begin
|
begin
|
||||||
|
raise URI::Error unless element['src'].present?
|
||||||
|
|
||||||
uri = URI element['src']
|
uri = URI element['src']
|
||||||
|
|
||||||
# No permitimos recursos externos
|
# No permitimos recursos externos
|
||||||
element.remove unless uri.scheme == 'https' && uri.hostname.end_with?(Site.domain)
|
raise URI::Error unless Rails.application.config.hosts.include?(uri.hostname)
|
||||||
|
|
||||||
|
element['src'] = convert_src_to_internal_path uri
|
||||||
|
|
||||||
|
raise URI::Error if element['src'].blank?
|
||||||
rescue URI::Error
|
rescue URI::Error
|
||||||
element.remove
|
element.remove
|
||||||
end
|
end
|
||||||
|
@ -73,16 +78,74 @@ class MetadataContent < MetadataTemplate
|
||||||
end
|
end
|
||||||
|
|
||||||
# Elimina los estilos salvo los que asigne el editor
|
# Elimina los estilos salvo los que asigne el editor
|
||||||
html.css('*').each do |element|
|
html.css('[style]').each do |element|
|
||||||
next if elements_with_style.include? element.name.downcase
|
if (style = sanitize_style(element['style'])).present?
|
||||||
|
element['style'] = style
|
||||||
element.remove_attribute('style')
|
else
|
||||||
|
element.remove_attribute('style')
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
html.to_s.html_safe
|
html.to_s.html_safe
|
||||||
end
|
end
|
||||||
|
|
||||||
def elements_with_style
|
# Limpia estilos en base a una lista de permitidos
|
||||||
@elements_with_style ||= %w[div mark].freeze
|
#
|
||||||
|
# @param style [String]
|
||||||
|
# @return [String]
|
||||||
|
def sanitize_style(style)
|
||||||
|
style.split(';').reduce({}) do |style_hash, style_string|
|
||||||
|
key, value = style_string.split(':', 2)
|
||||||
|
|
||||||
|
style_hash[key] ||= value
|
||||||
|
style_hash
|
||||||
|
end.slice(*allowed_styles).map do |style_pair|
|
||||||
|
style_pair.join(':')
|
||||||
|
end.join(';')
|
||||||
|
end
|
||||||
|
|
||||||
|
# Estilos permitidos
|
||||||
|
#
|
||||||
|
# @return [Array<String>]
|
||||||
|
def allowed_styles
|
||||||
|
@allowed_styles ||= %w[text-align color background-color]
|
||||||
|
end
|
||||||
|
|
||||||
|
# Convierte una ubicación local al sitio en una URL de ActiveStorage
|
||||||
|
#
|
||||||
|
# XXX: Por qué son tan díficiles de encontrar las rutas de AS
|
||||||
|
#
|
||||||
|
# @param path [String]
|
||||||
|
# @return [String]
|
||||||
|
def convert_internal_path_to_src(path)
|
||||||
|
key = path.split('/').second
|
||||||
|
blob = ActiveStorage::Blob.find_by(service_name: site.name, key: key)
|
||||||
|
|
||||||
|
return unless blob
|
||||||
|
|
||||||
|
"/rails/active_storage/blobs/#{blob.signed_id}/#{blob.filename}"
|
||||||
|
end
|
||||||
|
|
||||||
|
# Convierte una URI en una ruta interna del sitio actual
|
||||||
|
#
|
||||||
|
# XXX: No verifica si el archivo existe o no. Se supone que existe
|
||||||
|
# porque ya fue subido antes.
|
||||||
|
#
|
||||||
|
# @param uri [URI]
|
||||||
|
# @return [String,nil]
|
||||||
|
def convert_src_to_internal_path(uri)
|
||||||
|
signed_id = uri.path.split('/').fifth
|
||||||
|
blob = ActiveStorage::Blob.find_signed(signed_id)
|
||||||
|
|
||||||
|
return unless blob
|
||||||
|
return unless blob.service_name == site.name
|
||||||
|
|
||||||
|
blob_path = Pathname.new(blob.service.path_for(blob.key)).realpath
|
||||||
|
site_path = Pathname.new(site.path).realpath
|
||||||
|
|
||||||
|
blob_path.relative_path_from(site_path).to_s
|
||||||
|
rescue ActiveSupport::MessageVerifier::InvalidSignature => e
|
||||||
|
ExceptionNotifier.notify_exception(e, data: { site: site.name })
|
||||||
|
nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -4,6 +4,6 @@
|
||||||
post: post, attribute: attribute, metadata: metadata
|
post: post, attribute: attribute, metadata: metadata
|
||||||
|
|
||||||
.new-editor.content{ id: attribute }
|
.new-editor.content{ id: attribute }
|
||||||
= text_area_tag "#{base}[#{attribute}]", metadata.value.html_safe,
|
= text_area_tag "#{base}[#{attribute}]", metadata.to_s.html_safe,
|
||||||
dir: dir, lang: locale,
|
dir: dir, lang: locale,
|
||||||
**field_options(attribute, metadata), class: 'd-none'
|
**field_options(attribute, metadata), class: 'd-none'
|
||||||
|
|
|
@ -38,4 +38,4 @@
|
||||||
|
|
||||||
- cache [metadata, I18n.locale] do
|
- cache [metadata, I18n.locale] do
|
||||||
%section.content.pb-3{ id: attr, dir: dir }
|
%section.content.pb-3{ id: attr, dir: dir }
|
||||||
= @post.public_send(attr).value.html_safe
|
= @post.public_send(attr).to_s.html_safe
|
||||||
|
|
Loading…
Reference in a new issue