diff --git a/app/controllers/accounts_controller.rb b/app/controllers/accounts_controller.rb index 314073868fc..6df6d352edc 100644 --- a/app/controllers/accounts_controller.rb +++ b/app/controllers/accounts_controller.rb @@ -324,9 +324,9 @@ class AccountsController < ApplicationController @account.current_sis_batch_id = batch.id @account.save batch.process - render :text => batch.to_json(:include => :sis_batch_log_entries) + render :json => batch.to_json(:include => :sis_batch_log_entries) else - render :text => {:error=>true, :error_message=> t(:sis_import_in_process_notice, "An SIS import is already in process."), :batch_in_progress=>true}.to_json + render :json => {:error=>true, :error_message=> t(:sis_import_in_process_notice, "An SIS import is already in process."), :batch_in_progress=>true}.to_json end end end diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index cde78ac1438..c3be693c62d 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -1049,4 +1049,25 @@ class ApplicationController < ActionController::Base yield if block_given? && (@bank = bank) bank end + + def render(options = nil, extra_options = {}, &block) + if options && options.key?(:json) + json = options.delete(:json) + json = ActiveSupport::JSON.encode(json) unless json.is_a?(String) + # prepend our CSRF protection to the JSON response, unless this is an API + # call that didn't use session auth. + if @pseudonym_session && !@pseudonym_session.used_basic_auth? + json = "while(1);#{json}" + end + + # fix for IE not properly handling json responses to multipart file + # upload forms -- we'll respond with text instead. + if request.headers['CONTENT_TYPE'].to_s =~ %r{multipart/form-data} && params[:format].to_s != 'json' + options[:text] = json + else + options[:json] = json + end + end + super + end end diff --git a/app/controllers/content_imports_controller.rb b/app/controllers/content_imports_controller.rb index b010f9d35c4..66e3c45ba63 100644 --- a/app/controllers/content_imports_controller.rb +++ b/app/controllers/content_imports_controller.rb @@ -77,7 +77,7 @@ class ContentImportsController < ApplicationController render :json => upload_params else @migration.export_content - render :text => @migration.to_json + render :json => @migration.to_json end else render :json => @migration.errors, :status => :bad_request @@ -126,7 +126,7 @@ class ContentImportsController < ApplicationController send_file_or_data(stream, :type => :json, :disposition => 'inline') else logger.error "There was no overview.json file for this content_migration." - render :text => {:success=>false}.to_json + render :json => {:success=>false}.to_json end end end @@ -141,7 +141,7 @@ class ContentImportsController < ApplicationController @content_migration.migration_settings[:migration_ids_to_import] = params @content_migration.save @content_migration.import_content - render :text => {:success => true}.to_json + render :json => {:success => true}.to_json else render :json => @content_migration.to_json end @@ -282,9 +282,9 @@ class ContentImportsController < ApplicationController @attachment = @migration.attachment if block_given? if @attachment && yield - render_for_text @attachment.to_json(:allow => :uuid, :methods => [:uuid,:readable_size,:mime_class,:currently_locked,:scribdable?]) + render :json => @attachment.to_json(:allow => :uuid, :methods => [:uuid,:readable_size,:mime_class,:currently_locked,:scribdable?]) else - render_for_text "", :status => :bad_request + render :text => "", :status => :bad_request end end end diff --git a/app/controllers/conversations_controller.rb b/app/controllers/conversations_controller.rb index f62ba7d5476..ed42cf5d667 100644 --- a/app/controllers/conversations_controller.rb +++ b/app/controllers/conversations_controller.rb @@ -786,11 +786,4 @@ class ConversationsController < ApplicationController hash } end - - def render(options = {}, extra_options = {}, &block) - if options.keys == [:json] && request.headers['CONTENT_TYPE'].to_s =~ %r{multipart/form-data} && params[:format].to_s != 'json' - options[:text] = options.delete(:json).to_json - end - super - end end diff --git a/app/controllers/files_controller.rb b/app/controllers/files_controller.rb index 60e2735a1cc..0b6edc34695 100644 --- a/app/controllers/files_controller.rb +++ b/app/controllers/files_controller.rb @@ -444,12 +444,12 @@ class FilesController < ApplicationController if @attachment && details deleted_attachments = @attachment.handle_duplicates(params[:duplicate_handling]) @attachment.process_s3_details!(details) - render_for_text({ + render :json => { :attachment => @attachment, :deleted_attachment_ids => deleted_attachments.map(&:id) - }.to_json(:allow => :uuid, :methods => [:uuid,:readable_size,:mime_class,:currently_locked,:scribdable?], :permissions => {:user => @current_user, :session => session}, :include_root => false)) + }.to_json(:allow => :uuid, :methods => [:uuid,:readable_size,:mime_class,:currently_locked,:scribdable?], :permissions => {:user => @current_user, :session => session}, :include_root => false) else - render_for_text "" + render :text => "" end end @@ -511,8 +511,8 @@ class FilesController < ApplicationController if success @attachment.move_to_bottom format.html { return_to(params[:return_to], named_context_url(@context, :context_files_url)) } - format.json { render_for_text({ :attachment => @attachment, :deleted_attachment_ids => deleted_attachments.map(&:id) }.to_json(:allow => :uuid, :methods => [:uuid,:readable_size,:mime_class,:currently_locked,:scribdable?,:thumbnail_url], :permissions => {:user => @current_user, :session => session}, :include_root => false))} - format.text { render_for_text({ :attachment => @attachment, :deleted_attachment_ids => deleted_attachments.map(&:id) }.to_json(:allow => :uuid, :methods => [:uuid,:readable_size,:mime_class,:currently_locked,:scribdable?,:thumbnail_url], :permissions => {:user => @current_user, :session => session}, :include_root => false))} + format.json { render :json => { :attachment => @attachment, :deleted_attachment_ids => deleted_attachments.map(&:id) }.to_json(:allow => :uuid, :methods => [:uuid,:readable_size,:mime_class,:currently_locked,:scribdable?,:thumbnail_url], :permissions => {:user => @current_user, :session => session}, :include_root => false)} + format.text { render :json => { :attachment => @attachment, :deleted_attachment_ids => deleted_attachments.map(&:id) }.to_json(:allow => :uuid, :methods => [:uuid,:readable_size,:mime_class,:currently_locked,:scribdable?,:thumbnail_url], :permissions => {:user => @current_user, :session => session}, :include_root => false)} else format.html { render :action => "new" } format.json { render :json => @attachment.errors.to_json } diff --git a/app/controllers/gradebooks_controller.rb b/app/controllers/gradebooks_controller.rb index 7cacb926d9c..241286c9dd8 100644 --- a/app/controllers/gradebooks_controller.rb +++ b/app/controllers/gradebooks_controller.rb @@ -282,14 +282,14 @@ class GradebooksController < ApplicationController render :json => @submissions.to_json(Submission.json_serialization_full_parameters), :status => :created, :location => course_gradebook_url(@assignment.context) } format.text { - render_for_text @submissions.to_json(Submission.json_serialization_full_parameters), :status => :created, :location => course_gradebook_url(@assignment.context) + render :json => @submissions.to_json(Submission.json_serialization_full_parameters), :status => :created, :location => course_gradebook_url(@assignment.context) } else flash[:error] = t('errors.submission_failed', "Submission was unsuccessful: %{error}", :error => @error_message || t('errors.submission_failed_default', 'Submission Failed')) format.html { render :action => "show", :course_id => @assignment.context.id } format.xml { render :xml => {:errors => {:base => @error_message}}.to_xml } format.json { render :json => {:errors => {:base => @error_message}}.to_json, :status => :bad_request } - format.text { render_for_text({:errors => {:base => @error_message}}.to_json) } + format.text { render :json => {:errors => {:base => @error_message}}.to_json, :status => :bad_request } end end end diff --git a/app/controllers/outcome_groups_controller.rb b/app/controllers/outcome_groups_controller.rb index a45e426d57e..55a1e2a3787 100644 --- a/app/controllers/outcome_groups_controller.rb +++ b/app/controllers/outcome_groups_controller.rb @@ -47,9 +47,9 @@ class OutcomeGroupsController < ApplicationController outcome_hash = outcome_hash.with_indifferent_access outcome = group.learning_outcomes.create(params) end - render :text => group.to_json(:include => :learning_outcomes) + render :json => group.to_json(:include => :learning_outcomes) else - render :text => {:errors => {:base => t(:invalid_file, "Invalid outcome group file")}}, :status => :bad_request + render :json => {:errors => {:base => t(:invalid_file, "Invalid outcome group file")}}, :status => :bad_request end end end diff --git a/app/controllers/submissions_controller.rb b/app/controllers/submissions_controller.rb index d546ea4c7e4..3b32b6d8dc1 100644 --- a/app/controllers/submissions_controller.rb +++ b/app/controllers/submissions_controller.rb @@ -272,7 +272,7 @@ class SubmissionsController < ApplicationController format.html { render :action => "show", :id => @assignment.context.id } format.xml { render :xml => {:errors => {:base => @error_message}}.to_xml } format.json { render :json => {:errors => {:base => @error_message}}.to_json, :status => :bad_request } - format.text { render_for_text({:errors => {:base => @error_message}}.to_json) } + format.text { render :json => {:errors => {:base => @error_message}}.to_json, :status => :bad_request } end end end diff --git a/public/javascripts/jquery.instructure_jquery_patches.js b/public/javascripts/jquery.instructure_jquery_patches.js index b83ae91c1d3..558132d06be 100644 --- a/public/javascripts/jquery.instructure_jquery_patches.js +++ b/public/javascripts/jquery.instructure_jquery_patches.js @@ -19,7 +19,9 @@ (function($){ // have UI dialogs default to modal:true - $.widget('instructure.dialog', $.ui.dialog, { options: {modal: true} }); + if ($.ui) { + $.widget('instructure.dialog', $.ui.dialog, { options: {modal: true} }); + } // This is so that if you disable an element, that it also gives it the class disabled. // that way you can add css classes for our friend IE6. so rather than using selector:disabled, @@ -44,6 +46,24 @@ }); }); + // monkey patch jquery's JSON parsing so we can have all of our ajax responses return with + // 'while(1);' prepended to them to protect against a CSRF attack vector. + var _parseJSON = $.parseJSON; + $.parseJSON = function() { + "use strict"; + if (arguments[0]) { + try { + var newData = arguments[0].replace(/^while\(1\);/, ''); + arguments[0] = newData; + } catch (err) { + // data was not a string or something, just pass along to the real parseJSON + // and let it handle errors. + } + } + return _parseJSON.apply($, arguments); + }; + $.ajaxSettings.converters["text json"] = $.parseJSON; + // this is a patch so you can set the "method" atribute on rails' REST-ful forms. $.attrHooks.method = $.extend($.attrHooks.method, { set: function( elem, value ) { @@ -71,7 +91,7 @@ $.windowScrollTop = function() { return ($.browser.safari ? $("body") : $("html")).scrollTop(); }; - + define('jquery.instructure_jquery_patches', [], function() { return $ }); -})(jQuery); \ No newline at end of file +})(jQuery); diff --git a/spec/apis/oauth_spec.rb b/spec/apis/oauth_spec.rb index 51cadc8f627..96cf9ba27d9 100644 --- a/spec/apis/oauth_spec.rb +++ b/spec/apis/oauth_spec.rb @@ -57,9 +57,14 @@ describe "OAuth2", :type => :integration do # don't need developer key when we have an actual application session post '/login', 'pseudonym_session[unique_id]' => 'test1@example.com', 'pseudonym_session[password]' => 'test123' + response.should redirect_to("http://www.example.com/?login_success=1") get "/api/v1/courses.json", {} response.should be_success - JSON.parse(response.body).size.should == 1 + # because this is a normal application session, the response is prepended + # with our anti-csrf measure + json = response.body + json.should match(%r{^while\(1\);}) + JSON.parse(json.sub(%r{^while\(1\);}, '')).size.should == 1 reset! post "/api/v1/courses/#{@course.id}/assignments.json", { :assignment => { :name => 'test assignment', :points_possible => '5.3', :grading_type => 'points' } } diff --git a/spec/apis/v1/general_auth_spec.rb b/spec/apis/v1/general_auth_spec.rb index 3d001ebc148..212f897002d 100644 --- a/spec/apis/v1/general_auth_spec.rb +++ b/spec/apis/v1/general_auth_spec.rb @@ -117,4 +117,39 @@ describe CoursesController, :type => :integration do 'calendar' => { 'ics' => "http://www.example.com/feeds/calendars/user_#{@student.uuid}.ics" }, } end + + it "should not prepend the CSRF protection to API requests" do + user_with_pseudonym(:user => @user) + raw_api_call(:get, "/api/v1/users/self/profile", + :controller => "profile", :action => "show", :user_id => "self", :format => "json") + response.should be_success + raw_json = response.body + raw_json.should_not match(%r{^while\(1\);}) + json = JSON.parse(raw_json) + json['id'].should == @user.id + end + + it "should not prepend the CSRF protection to HTTP Basic API requests" do + user_with_pseudonym(:active_user => true, :username => 'test1@example.com', :password => 'test123') + get "/api/v1/users/self/profile", {}, { :authorization => ActionController::HttpAuthentication::Basic.encode_credentials('test1@example.com', 'test123') } + response.should be_success + raw_json = response.body + raw_json.should_not match(%r{^while\(1\);}) + json = JSON.parse(raw_json) + json['id'].should == @user.id + end + + it "should prepend the CSRF protection for API endpoints, when session auth is used" do + user_with_pseudonym(:active_user => true, :username => 'test1@example.com', :password => 'test123') + post "/login", "pseudonym_session[unique_id]" => "test1@example.com", + "pseudonym_session[password]" => "test123" + assert_response 302 + get "/api/v1/users/self/profile" + response.should be_success + raw_json = response.body + raw_json.should match(%r{^while\(1\);}) + expect { JSON.parse(raw_json) }.to raise_error + json = JSON.parse(raw_json.sub(%r{^while\(1\);}, '')) + json['id'].should == @user.id + end end diff --git a/spec/coffeescripts/jQuery.instructureJqueryPatches.coffee b/spec/coffeescripts/jQuery.instructureJqueryPatches.coffee new file mode 100644 index 00000000000..61bb94ae233 --- /dev/null +++ b/spec/coffeescripts/jQuery.instructureJqueryPatches.coffee @@ -0,0 +1,8 @@ +define [ + 'jquery.instructure_jquery_patches' +], (jQuery) -> + module 'instructure jquery patches' + + test 'parseJSON', -> + deepEqual(jQuery.parseJSON('{ "var1": "1", "var2" : 2 }'), { "var1": "1", "var2" : 2 }, 'should still parse without the prefix') + deepEqual(jQuery.parseJSON('while(1);{ "var1": "1", "var2" : 2 }'), { "var1": "1", "var2" : 2 }, 'should parse with the prefix') diff --git a/spec/controllers/files_controller_spec.rb b/spec/controllers/files_controller_spec.rb index 7314c3e202c..8a88ea1e146 100644 --- a/spec/controllers/files_controller_spec.rb +++ b/spec/controllers/files_controller_spec.rb @@ -138,7 +138,7 @@ describe FilesController do a1 = folder_file get 'index', :course_id => @course.id, :format => 'json' response.should be_success - data = JSON.parse(response.body) rescue nil + data = json_parse data.should_not be_nil data['contexts'].length.should eql(1) data['contexts'][0]['course']['id'].should eql(@course.id) @@ -240,7 +240,7 @@ describe FilesController do it "should mark files as viewed for module progressions if the file is previewed inline" do file_in_a_module get 'show', :course_id => @course.id, :id => @file.id, :inline => 1 - response.body.should eql({:ok => true}.to_json) + json_parse.should == {'ok' => true} @module.reload @module.evaluate_for(@user, true, true).state.should eql(:completed) end @@ -420,7 +420,7 @@ describe FilesController do response.should be_success assigns[:attachment].should_not be_nil assigns[:attachment].id.should_not be_nil - json = JSON.parse(response.body) rescue nil + json = json_parse json.should_not be_nil json['id'].should eql(assigns[:attachment].id) json['upload_url'].should_not be_nil @@ -447,7 +447,7 @@ describe FilesController do response.should be_success assigns[:attachment].should_not be_nil assigns[:attachment].id.should_not be_nil - json = JSON.parse(response.body) rescue nil + json = json_parse json.should_not be_nil json['id'].should eql(assigns[:attachment].id) json['upload_url'].should_not be_nil @@ -498,7 +498,7 @@ describe FilesController do response.should be_success assigns[:attachment].should_not be_nil assigns[:attachment].id.should_not be_nil - json = JSON.parse(response.body) rescue nil + json = json_parse json.should_not be_nil json['id'].should eql(assigns[:attachment].id) json['upload_url'].should_not be_nil diff --git a/spec/controllers/folders_controller_spec.rb b/spec/controllers/folders_controller_spec.rb index 4eeb3c6d4bc..66ea13f4178 100644 --- a/spec/controllers/folders_controller_spec.rb +++ b/spec/controllers/folders_controller_spec.rb @@ -38,13 +38,13 @@ describe FoldersController do file.save! get 'show', :course_id => @course.id, :id => @folder.id, :format => 'json' - json = JSON.parse(response.body) + json = json_parse json['files'].count.should eql(1) file.hidden = true file.save! get 'show', :course_id => @course.id, :id => @folder.id, :format => 'json' - json = JSON.parse(response.body) + json = json_parse json['files'].count.should eql(0) end end diff --git a/spec/controllers/gradebooks_controller_spec.rb b/spec/controllers/gradebooks_controller_spec.rb index 574443e2a48..5e686396676 100644 --- a/spec/controllers/gradebooks_controller_spec.rb +++ b/spec/controllers/gradebooks_controller_spec.rb @@ -100,7 +100,7 @@ describe GradebooksController do assignment2 = @course.assignments.create(:title => "Assignment 2", :group_category => group_category2) get 'show', :course_id => @course.id, :init => 1, :assignments => 1, :format => 'json' response.should be_success - data = JSON.parse(response.body) rescue nil + data = json_parse data.should_not be_nil data.size.should == 4 # 2 assignments + an assignment group + a total data.first(2).sort_by{ |a| a['assignment']['title'] }.map{ |a| a['assignment']['group_category'] }. diff --git a/spec/controllers/groups_controller_spec.rb b/spec/controllers/groups_controller_spec.rb index dcd06b4a296..6dc06542175 100644 --- a/spec/controllers/groups_controller_spec.rb +++ b/spec/controllers/groups_controller_spec.rb @@ -489,7 +489,7 @@ describe GroupsController do get 'unassigned_members', :course_id => @course.id, :category_id => group.group_category.id response.should be_success - data = JSON.parse(response.body) rescue nil + data = json_parse data.should_not be_nil data['users'].map{ |u| u['user_id'] }.sort. should == [u1, u2, u3].map{ |u| u.id }.sort @@ -516,21 +516,21 @@ describe GroupsController do get 'unassigned_members', :course_id => @course.id, :category_id => group1.group_category.id response.should be_success - data = JSON.parse(response.body) rescue nil + data = json_parse data.should_not be_nil data['users'].map{ |u| u['user_id'] }.sort. should == [u2, u3].map{ |u| u.id }.sort get 'unassigned_members', :course_id => @course.id, :category_id => group2.group_category.id response.should be_success - data = JSON.parse(response.body) rescue nil + data = json_parse data.should_not be_nil data['users'].map{ |u| u['user_id'] }.sort. should == [u1, u3].map{ |u| u.id }.sort get 'unassigned_members', :course_id => @course.id, :category_id => group3.group_category.id response.should be_success - data = JSON.parse(response.body) rescue nil + data = json_parse data.should_not be_nil data['users'].map{ |u| u['user_id'] }.should == [ u1.id ] end @@ -544,7 +544,7 @@ describe GroupsController do group.add_user(u1) get 'unassigned_members', :course_id => @course.id, :category_id => group.group_category.id - data = JSON.parse(response.body) rescue nil + data = json_parse data['users'].first['section_id'].should == @course.default_section.id data['users'].first['section_code'].should == @course.default_section.section_code end @@ -558,7 +558,7 @@ describe GroupsController do group.add_user(u1) get 'context_group_members', :group_id => group.id - data = JSON.parse(response.body) rescue nil + data = json_parse data.first['section_id'].should == @course.default_section.id data.first['section_code'].should == @course.default_section.section_code end @@ -643,7 +643,7 @@ describe GroupsController do # group2 instead of group1 post 'assign_unassigned_members', :course_id => @course.id, :category_id => category.id response.should be_success - data = JSON.parse(response.body) rescue nil + data = json_parse data.size.should == 1 data.first['id'].should == group2.id end @@ -660,7 +660,7 @@ describe GroupsController do # student1 shouldn't get assigned, already being in a group post 'assign_unassigned_members', :course_id => @course.id, :category_id => category.id response.should be_success - data = JSON.parse(response.body) rescue nil + data = json_parse data.map{ |g| g['new_members'] }.flatten.map{ |u| u['user_id'] }.should_not be_include(student1.id) end @@ -676,7 +676,7 @@ describe GroupsController do # student2 should get assigned, not being in a group post 'assign_unassigned_members', :course_id => @course.id, :category_id => category.id response.should be_success - data = JSON.parse(response.body) rescue nil + data = json_parse data.map{ |g| g['new_members'] }.flatten.map{ |u| u['user_id'] }.should be_include(student2.id) end @@ -698,7 +698,7 @@ describe GroupsController do # bring them both to three post 'assign_unassigned_members', :course_id => @course.id, :category_id => category.id response.should be_success - data = JSON.parse(response.body) rescue nil + data = json_parse data.size.should == 2 data.map{ |g| g['id'] }.sort.should == [group1.id, group2.id].sort diff --git a/spec/controllers/users_controller_spec.rb b/spec/controllers/users_controller_spec.rb index 73d14fa63a3..f9ea973fac4 100644 --- a/spec/controllers/users_controller_spec.rb +++ b/spec/controllers/users_controller_spec.rb @@ -59,7 +59,7 @@ describe UsersController do get 'manageable_courses', :user_id => @teacher.id, :term => "MyCourse" response.should be_success - courses = ActiveSupport::JSON.decode(response.body) + courses = json_parse courses.map { |c| c['id'] }.should == [course2.id] end diff --git a/spec/integration/course_copy_spec.rb b/spec/integration/course_copy_spec.rb index fa6d70e1383..61afb9abbce 100644 --- a/spec/integration/course_copy_spec.rb +++ b/spec/integration/course_copy_spec.rb @@ -34,16 +34,16 @@ describe ContentImportsController, :type => :integration do post "/courses/#{@copy_to.id}/imports/copy", :copy => {:course_id => @copy_from.id, :all_assignments => 1} response.should be_success - data = JSON.parse(response.body) + data = json_parse dj = Delayed::Job.last api_call(:get, data['status_url'], { :controller => 'content_imports', :action => 'copy_course_status', :course_id => @copy_to.to_param, :id => data['id'].to_param, :format => 'json' }) - JSON.parse(response.body)['workflow_state'].should == 'created' + json_parse['workflow_state'].should == 'created' dj.invoke_job api_call(:get, data['status_url'], { :controller => 'content_imports', :action => 'copy_course_status', :course_id => @copy_to.to_param, :id => data['id'].to_param, :format => 'json' }) - JSON.parse(response.body)['workflow_state'].should == 'completed' + json_parse['workflow_state'].should == 'completed' @copy_to.reload @copy_to.assignments.count.should == 1 @@ -51,4 +51,4 @@ describe ContentImportsController, :type => :integration do end end -end \ No newline at end of file +end diff --git a/spec/integration/security_spec.rb b/spec/integration/security_spec.rb index 28422e427d9..248bb2b11e2 100644 --- a/spec/integration/security_spec.rb +++ b/spec/integration/security_spec.rb @@ -383,7 +383,7 @@ describe "security" do user_session(@teacher) post "/courses/#{@course.id}/user_lists.json", :user_list => "A1234567, A345678" assert_response :success - ActiveSupport::JSON.decode(response.body).should == { + json_parse.should == { "duplicates" => [], "errored_users" => [{"address" => "A345678", "details" => "not_found"}], "users" => [{ "address" => "A1234567", "name" => "test user", "type" => "pseudonym", "user_id" => u.id.to_s }] diff --git a/spec/javascripts/jQuery.instructureJqueryPatches.js b/spec/javascripts/jQuery.instructureJqueryPatches.js new file mode 100644 index 00000000000..e7e3075ab30 --- /dev/null +++ b/spec/javascripts/jQuery.instructureJqueryPatches.js @@ -0,0 +1,15 @@ +(function() { + define(['jquery.instructure_jquery_patches'], function(jQuery) { + module('instructure jquery patches'); + return test('parseJSON', function() { + deepEqual(jQuery.parseJSON('{ "var1": "1", "var2" : 2 }'), { + "var1": "1", + "var2": 2 + }, 'should still parse without the prefix'); + return deepEqual(jQuery.parseJSON('while(1);{ "var1": "1", "var2" : 2 }'), { + "var1": "1", + "var2": 2 + }, 'should parse with the prefix'); + }); + }); +}).call(this); diff --git a/spec/javascripts/support/specs.js b/spec/javascripts/support/specs.js index 83ef058e1e0..96f3af07701 100644 --- a/spec/javascripts/support/specs.js +++ b/spec/javascripts/support/specs.js @@ -6,6 +6,7 @@ require([ 'specs/jQuery.instructureMiscPluginsSpec', 'specs/userNamePartsSpec', 'specs/objectCollectionSpec', - 'specs/util/BackoffPollerSpec' + 'specs/util/BackoffPollerSpec', + 'specs/jQuery.instructureJqueryPatches' ]); diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 2a9ad323b29..2522dc226d7 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -251,6 +251,7 @@ Spec::Runner.configure do |config| session = mock() session.stubs(:record).returns(pseudonym) session.stubs(:session_credentials).returns(nil) + session.stubs(:used_basic_auth?).returns(false) PseudonymSession.stubs(:find).returns(session) end @@ -490,4 +491,8 @@ Spec::Runner.configure do |config| @attachment.save! @attachment end + + def json_parse(json_string = response.body) + JSON.parse(json_string.sub(%r{^while\(1\);}, '')) + end end