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:
James Williams 2013-03-21 14:58:57 -06:00
parent 64ec546d20
commit de2ce63ee0
3 changed files with 78 additions and 5 deletions

View File

@ -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)

View File

@ -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

View File

@ -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&param2=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