raise error for unescaped ampersands in external tool urls
test plan: * Create an external tool "by xml", with a "launch_url" tag (or any custom property of name "url"), that includes an unescaped ampersand: (e.g. "www.example.com?a=1&b=2") * Confirm that an error is raised indicating the ampersand needs to be escaped (e.g. "www.example.com?a=1&b=2") fixes #CNVS-1324 Change-Id: Id90d216e2d9039187e8a8f4327e2413d07164b04 Reviewed-on: https://gerrit.instructure.com/18872 Tested-by: Jenkins <jenkins@instructure.com> Product-Review: Bracken Mosbacker <bracken@instructure.com> Reviewed-by: Brad Humphrey <brad@instructure.com> QA-Review: Adam Phillipps <adam@instructure.com>
This commit is contained in:
parent
64ec546d20
commit
de2ce63ee0
|
@ -101,12 +101,32 @@ module CC::Importer
|
|||
def convert_blti_xml(xml)
|
||||
doc = Nokogiri::XML(xml)
|
||||
begin
|
||||
convert_blti_link(doc)
|
||||
tool = convert_blti_link(doc)
|
||||
check_for_unescaped_url_properties(tool) if tool
|
||||
rescue Nokogiri::XML::XPath::SyntaxError
|
||||
raise CCImportError.new(I18n.t(:invalid_xml_syntax, "invalid xml syntax"))
|
||||
raise CCImportError.new(I18n.t(:invalid_xml_syntax, "Invalid xml syntax"))
|
||||
end
|
||||
tool
|
||||
end
|
||||
|
||||
def check_for_unescaped_url_properties(obj)
|
||||
# Recursively look for properties named 'url'
|
||||
if obj.is_a?(Hash)
|
||||
obj.select{|k, v| k.to_s == 'url' && v.is_a?(String)}.each do |k, v|
|
||||
check_for_unescaped_url(v)
|
||||
end
|
||||
obj.each{|k, v| check_for_unescaped_url_properties(v)}
|
||||
elsif obj.is_a?(Array)
|
||||
obj.each{|o| check_for_unescaped_url_properties(o)}
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
def check_for_unescaped_url(url)
|
||||
if (url =~ /(.*[^\=]*\?*\=)[^\&]*\=/)
|
||||
raise CCImportError.new(I18n.t(:invalid_url_in_xml, "Invalid url in xml. Ampersands must be escaped."))
|
||||
end
|
||||
end
|
||||
|
||||
def retrieve_and_convert_blti_url(url)
|
||||
begin
|
||||
uri = URI.parse(url)
|
||||
|
|
|
@ -285,7 +285,7 @@ describe ExternalToolsController do
|
|||
response.should_not be_success
|
||||
assigns[:tool].should be_new_record
|
||||
json = json_parse(response.body)
|
||||
json['errors']['base'][0]['message'].should == I18n.t(:invalid_xml_syntax, 'invalid xml syntax')
|
||||
json['errors']['base'][0]['message'].should == I18n.t(:invalid_xml_syntax, 'Invalid xml syntax')
|
||||
|
||||
course_with_teacher_logged_in(:active_all => true)
|
||||
xml = "<a><b>c</b></a>"
|
||||
|
@ -293,7 +293,7 @@ describe ExternalToolsController do
|
|||
response.should_not be_success
|
||||
assigns[:tool].should be_new_record
|
||||
json = json_parse(response.body)
|
||||
json['errors']['base'][0]['message'].should == I18n.t(:invalid_xml_syntax, 'invalid xml syntax')
|
||||
json['errors']['base'][0]['message'].should == I18n.t(:invalid_xml_syntax, 'Invalid xml syntax')
|
||||
end
|
||||
|
||||
it "should handle advanced xml configurations by URL retrieval" do
|
||||
|
|
|
@ -334,5 +334,58 @@ describe BasicLTI do
|
|||
BasicLTI.user_lti_data(teacher, @course2)['role_types'].should == ['urn:lti:sysrole:ims/lis/None']
|
||||
BasicLTI.user_lti_data(student, @course2)['role_types'].should == ['urn:lti:sysrole:ims/lis/None']
|
||||
end
|
||||
|
||||
it "xml converter should use raise an error when unescaped ampersands are used in launch url" do
|
||||
xml = <<-XML
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<cartridge_basiclti_link xmlns="http://www.imsglobal.org/xsd/imslticc_v1p0"
|
||||
xmlns:blti = "http://www.imsglobal.org/xsd/imsbasiclti_v1p0"
|
||||
xmlns:lticm ="http://www.imsglobal.org/xsd/imslticm_v1p0"
|
||||
xmlns:lticp ="http://www.imsglobal.org/xsd/imslticp_v1p0"
|
||||
xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation = "http://www.imsglobal.org/xsd/imslticc_v1p0 http://www.imsglobal.org/xsd/lti/ltiv1p0/imslticc_v1p0.xsd
|
||||
http://www.imsglobal.org/xsd/imsbasiclti_v1p0 http://www.imsglobal.org/xsd/lti/ltiv1p0/imsbasiclti_v1p0.xsd
|
||||
http://www.imsglobal.org/xsd/imslticm_v1p0 http://www.imsglobal.org/xsd/lti/ltiv1p0/imslticm_v1p0.xsd
|
||||
http://www.imsglobal.org/xsd/imslticp_v1p0 http://www.imsglobal.org/xsd/lti/ltiv1p0/imslticp_v1p0.xsd">
|
||||
<blti:title>Other Name</blti:title>
|
||||
<blti:description>Description</blti:description>
|
||||
<blti:launch_url>http://example.com/other_url?unescapedampersands=1&arebadnews=2</blti:launch_url>
|
||||
<cartridge_bundle identifierref="BLTI001_Bundle"/>
|
||||
<cartridge_icon identifierref="BLTI001_Icon"/>
|
||||
</cartridge_basiclti_link>
|
||||
XML
|
||||
lti = CC::Importer::BLTIConverter.new
|
||||
lambda {lti.convert_blti_xml(xml)}.should raise_error
|
||||
end
|
||||
|
||||
it "xml converter should use raise an error when unescaped ampersands are used in custom url properties" do
|
||||
xml = <<-XML
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<cartridge_basiclti_link xmlns="http://www.imsglobal.org/xsd/imslticc_v1p0"
|
||||
xmlns:blti = "http://www.imsglobal.org/xsd/imsbasiclti_v1p0"
|
||||
xmlns:lticm ="http://www.imsglobal.org/xsd/imslticm_v1p0"
|
||||
xmlns:lticp ="http://www.imsglobal.org/xsd/imslticp_v1p0"
|
||||
xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation = "http://www.imsglobal.org/xsd/imslticc_v1p0 http://www.imsglobal.org/xsd/lti/ltiv1p0/imslticc_v1p0.xsd
|
||||
http://www.imsglobal.org/xsd/imsbasiclti_v1p0 http://www.imsglobal.org/xsd/lti/ltiv1p0/imsbasiclti_v1p0.xsd
|
||||
http://www.imsglobal.org/xsd/imslticm_v1p0 http://www.imsglobal.org/xsd/lti/ltiv1p0/imslticm_v1p0.xsd
|
||||
http://www.imsglobal.org/xsd/imslticp_v1p0 http://www.imsglobal.org/xsd/lti/ltiv1p0/imslticp_v1p0.xsd">
|
||||
<blti:title>Other Name</blti:title>
|
||||
<blti:description>Description</blti:description>
|
||||
<blti:launch_url>http://example.com</blti:launch_url>
|
||||
<blti:extensions platform="canvas.instructure.com">
|
||||
<lticm:property name="privacy_level">public</lticm:property>
|
||||
<lticm:options name="course_navigation">
|
||||
<lticm:property name="url">https://example.com/attendance?param1=1¶m2=2</lticm:property>
|
||||
<lticm:property name="enabled">true</lticm:property>
|
||||
</lticm:options>
|
||||
</blti:extensions>
|
||||
<cartridge_bundle identifierref="BLTI001_Bundle"/>
|
||||
<cartridge_icon identifierref="BLTI001_Icon"/>
|
||||
</cartridge_basiclti_link>
|
||||
XML
|
||||
lti = CC::Importer::BLTIConverter.new
|
||||
lambda {lti.convert_blti_xml(xml)}.should raise_error
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue