Add liquid tag for Soundcloud (#844)
* Add liquid tag for Soundcloud Adds a liquid tag for soundcloud links. Currently does not support customizing autplay, display for comments, or color. * Strip HTML from Soundcloud tag input We want to prevent potential XSS exploits, so we sanitize all link input * Add Soundcloud tag documentation to editor guide
This commit is contained in:
parent
85abcb957d
commit
3a81c82b28
4 changed files with 99 additions and 0 deletions
46
app/liquid_tags/soundcloud_tag.rb
Normal file
46
app/liquid_tags/soundcloud_tag.rb
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
class SoundcloudTag < LiquidTagBase
|
||||
def initialize(tag_name, link, tokens)
|
||||
super
|
||||
@link = parse_link(link)
|
||||
@height = 166
|
||||
end
|
||||
|
||||
def render(_context)
|
||||
# src = build_src
|
||||
html = <<-HTML
|
||||
<iframe
|
||||
width="100%"
|
||||
height="#{@height}"
|
||||
scrolling="no"
|
||||
frameborder="no"
|
||||
allow="autoplay"
|
||||
src="https://w.soundcloud.com/player/?url=#{@link}&auto_play=false&color=%23000000&hide_related=false&show_comments=true&show_user=true&show_reposts=false&show_teaser=true">
|
||||
</iframe>
|
||||
HTML
|
||||
finalize_html(html)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def parse_link(link)
|
||||
stripped_link = sanitize_link(link)
|
||||
raise_error unless valid_link?(stripped_link)
|
||||
stripped_link
|
||||
end
|
||||
|
||||
def sanitize_link(link)
|
||||
link = ActionController::Base.helpers.strip_tags(link)
|
||||
link = ActionController::Base.helpers.sanitize(link)
|
||||
link.tr(" ", "")
|
||||
end
|
||||
|
||||
def valid_link?(link)
|
||||
link.include?("soundcloud.com")
|
||||
end
|
||||
|
||||
def raise_error
|
||||
raise StandardError, "Invalid Soundcloud URL"
|
||||
end
|
||||
end
|
||||
|
||||
Liquid::Template.register_tag("soundcloud", SoundcloudTag)
|
||||
|
|
@ -144,6 +144,10 @@
|
|||
{% speakerdeck <span style="color: orange;">7e9f8c0fa0c949bd8025457181913fd0</span> %}
|
||||
</pre>
|
||||
|
||||
<h3><strong>Soundcloud Embed</strong></h3>
|
||||
<p>Just enter the full URL of the Soundcloud track you are trying to embed.</p>
|
||||
<code>{% soundcloud https://soundcloud.com/user-261265215/dev-to-review-episode-1 %}</code>
|
||||
|
||||
<h3><strong>Parsing Liquid Tags as a Code Example</strong></h3>
|
||||
<p>To parse Liquid tags as code, simply wrap it with a single backtick or triple backticks.</p>
|
||||
<p><code>`{% mytag %}{{ site.SOMETHING }}{% endmytag %}`</code></p>
|
||||
|
|
|
|||
43
spec/liquid_tags/soundcloud_tag_spec.rb
Normal file
43
spec/liquid_tags/soundcloud_tag_spec.rb
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
require "rails_helper"
|
||||
require "nokogiri"
|
||||
|
||||
RSpec.describe SoundcloudTag, type: :liquid_template do
|
||||
describe "#link" do
|
||||
let(:soundcloud_link) { "https://soundcloud.com/user-261265215/dev-to-review-episode-2" }
|
||||
let(:evil_string) { "<SCRIPT SRC=//xss.rocks/.j>soundcloud.com</SCRIPT>" }
|
||||
let(:url_segment) { "https://w.soundcloud.com/player/?url" }
|
||||
|
||||
def generate_new_liquid(link)
|
||||
Liquid::Template.register_tag("soundcloud", SoundcloudTag)
|
||||
Liquid::Template.parse("{% soundcloud #{link} %}")
|
||||
end
|
||||
|
||||
def extract_iframe_src(rendered_iframe)
|
||||
parsed_iframe = Nokogiri.HTML(rendered_iframe)
|
||||
iframe_src = parsed_iframe.xpath("//iframe/@src")
|
||||
CGI::parse(iframe_src[0].value)
|
||||
end
|
||||
|
||||
it "accepts soundcloud link" do
|
||||
liquid = generate_new_liquid(soundcloud_link)
|
||||
rendered_soundcloud_iframe = liquid.render
|
||||
Approvals.verify(rendered_soundcloud_iframe, name: "soundcloud_liquid_tag", format: :html)
|
||||
end
|
||||
|
||||
it "rejects invalid soundcloud link" do
|
||||
expect do
|
||||
generate_new_liquid("invalid_soundcloud_link")
|
||||
end.to raise_error(StandardError)
|
||||
end
|
||||
|
||||
it "strips script input" do
|
||||
allow(ActionController::Base.helpers).to receive(:strip_tags).and_return(evil_string)
|
||||
|
||||
liquid = generate_new_liquid(evil_string)
|
||||
rendered_soundcloud_iframe = liquid.render
|
||||
iframe_src = extract_iframe_src(rendered_soundcloud_iframe)
|
||||
|
||||
expect(iframe_src[url_segment]).not_to include("<SCRIPT SRC=//xss.rocks/.j>")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<body>
|
||||
<iframe width="100%" height="166" scrolling="no" frameborder="no" allow="autoplay" src="https://w.soundcloud.com/player/?url=https://soundcloud.com/user-261265215/dev-to-review-episode-2&auto_play=false&color=%23000000&hide_related=false&show_comments=true&show_user=true&show_reposts=false&show_teaser=true"> </iframe>
|
||||
</body>
|
||||
</html>
|
||||
Loading…
Add table
Reference in a new issue