diff --git a/app/controllers/sis_imports_api_controller.rb b/app/controllers/sis_imports_api_controller.rb index 810ab49fb6c..314bc98b3ec 100644 --- a/app/controllers/sis_imports_api_controller.rb +++ b/app/controllers/sis_imports_api_controller.rb @@ -90,13 +90,20 @@ class SisImportsApiController < ApplicationController file_obj.set_file_attributes("sis_import.#{params[:extension]}", Attachment.mimetype("sis_import.#{params[:extension]}")) else + env = request.env.dup + env['CONTENT_TYPE'] = env["ORIGINAL_CONTENT_TYPE"] + # copy of request with original content type restored + request2 = Rack::Request.new(env) + charset = request2.media_type_params['charset'] + if charset.present? && charset.downcase != 'utf-8' + return render :json => { :error => "Invalid content type, UTF-8 required" }, :status => 400 + end params[:extension] ||= {"application/zip" => "zip", "text/xml" => "xml", "text/plain" => "csv", - "text/csv" => "csv"}[ - request.env['ORIGINAL_CONTENT_TYPE']] || "zip" + "text/csv" => "csv"}[request2.media_type] || "zip" file_obj.set_file_attributes("sis_import.#{params[:extension]}", - request.env['ORIGINAL_CONTENT_TYPE']) + request2.media_type) end end batch = SisBatch.create_with_attachment(@account, params[:import_type], file_obj) diff --git a/spec/apis/v1/sis_imports_api_spec.rb b/spec/apis/v1/sis_imports_api_spec.rb index f4b42f5a239..73737f3d71d 100644 --- a/spec/apis/v1/sis_imports_api_spec.rb +++ b/spec/apis/v1/sis_imports_api_spec.rb @@ -112,4 +112,42 @@ describe SisImportsApiController, :type => :integration do batch.batch_mode_term.should == term end + it "should allow raw post without charset" do + json = api_call(:post, + "/api/v1/accounts/#{@account.id}/sis_imports.json?import_type=instructure_csv", + { :controller => 'sis_imports_api', :action => 'create', + :format => 'json', :account_id => @account.id.to_s, + :import_type => 'instructure_csv' }, + {}, + { 'content-type' => 'text/csv' }) + batch = SisBatch.last + batch.attachment.filename.should == "sis_import.csv" + batch.attachment.content_type.should == "text/csv" + end + + it "should handle raw post content-types with attributes" do + json = api_call(:post, + "/api/v1/accounts/#{@account.id}/sis_imports.json?import_type=instructure_csv", + { :controller => 'sis_imports_api', :action => 'create', + :format => 'json', :account_id => @account.id.to_s, + :import_type => 'instructure_csv' }, + {}, + { 'content-type' => 'text/csv; charset=utf-8' }) + batch = SisBatch.last + batch.attachment.filename.should == "sis_import.csv" + batch.attachment.content_type.should == "text/csv" + end + + it "should reject non-utf-8 encodings on content-type" do + json = raw_api_call(:post, + "/api/v1/accounts/#{@account.id}/sis_imports.json?import_type=instructure_csv", + { :controller => 'sis_imports_api', :action => 'create', + :format => 'json', :account_id => @account.id.to_s, + :import_type => 'instructure_csv' }, + {}, + { 'content-type' => 'text/csv; charset=ISO-8859-1-Windows-3.0-Latin-1' }) + response.status.should match(/400/) + SisBatch.count.should == 0 + end + end