Skip to content

Commit 3f0968b

Browse files
committed
application/json+canvas-string-ids Accept header
fixes CNVS-7597 when given this header, data structures passed to render :json are pre-processed before serialization to json such that any integer values in 'id', 'foo_id', or 'foo_ids' fields (also 'ids' fields, but we don't have any of those currently that I'm aware off), at any level (e.g. within a nested data structure), are cast to strings. test-plan: - full regression testing of both the UI (as it makes API calls) and the documented API - no UI behavior should change - API behavior should change only as described above Change-Id: I4e0a68957038be063cf488dd9ec2262452dea3cf Reviewed-on: https://gerrit.instructure.com/23956 Reviewed-by: Jacob Fugal <jacob@instructure.com> Product-Review: Jacob Fugal <jacob@instructure.com> QA-Review: Jacob Fugal <jacob@instructure.com> Tested-by: Jenkins <jenkins@instructure.com>
1 parent b12791a commit 3f0968b

17 files changed

Lines changed: 154 additions & 33 deletions

File tree

app/coffeescripts/gradebook2/Gradebook.coffee

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ define [
5757
@rows = []
5858
@assignmentsToHide = userSettings.contextGet('hidden_columns') || []
5959
@sectionToShow = userSettings.contextGet 'grading_show_only_section'
60+
@sectionToShow = @sectionToShow && String(@sectionToShow)
6061
@show_attendance = userSettings.contextGet 'show_attendance'
6162
@include_ungraded_assignments = userSettings.contextGet 'include_ungraded_assignments'
6263
@userFilterRemovedRows = []
@@ -586,7 +587,7 @@ define [
586587
)()
587588
$('#section_to_show').after($sectionToShowMenu).show().kyleMenu()
588589
$sectionToShowMenu.bind 'menuselect', (event, ui) =>
589-
@sectionToShow = Number($sectionToShowMenu.find('[aria-checked="true"] input[name="section_to_show_radio"]').val()) || undefined
590+
@sectionToShow = $sectionToShowMenu.find('[aria-checked="true"] input[name="section_to_show_radio"]').val()
590591
userSettings[ if @sectionToShow then 'contextSet' else 'contextRemove']('grading_show_only_section', @sectionToShow)
591592
updateSectionBeingShownText()
592593
@buildRows()

app/coffeescripts/views/DraggableCollectionView.coffee

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,8 @@ define [
7373
# Internal: get an item's ID from the ui element
7474
# Assumes that the first child DOM element will have the id in the data-item-id attribute
7575
_getItemId: (item) ->
76-
parseInt item.children(":first").data('item-id')
76+
id = item.children(":first").data('item-id')
77+
id && String(id)
7778

7879
# Internal: When an item is moved from one group to another
7980
# Assumes that the first child DOM element will have the id of the model in the data-item-id attribute

app/coffeescripts/views/collaborations/CollaboratorPickerView.coffee

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,9 @@ define [
6363
#
6464
# Returns nothing.
6565
createLists: ->
66+
currentUser = ENV.current_user_id && String(ENV.current_user_id)
6667
@userList = new ListView
67-
currentUser: ENV.current_user_id
68+
currentUser: currentUser
6869
el: @$userList
6970
fetchOptions: @fetchOptions
7071
type: 'user'
@@ -73,7 +74,7 @@ define [
7374
fetchOptions: @fetchOptions
7475
type: 'group'
7576
@memberList = new MemberListView
76-
currentUser: ENV.current_user_id
77+
currentUser: currentUser
7778
el: @$memberList
7879

7980
# Internal: Trigger initial fetch actions on each collection.

app/coffeescripts/views/content_migrations/subviews/CourseFindSelectView.coffee

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ define [
7070

7171
# Build a list of courses that our template and autocomplete can use
7272
# objects look like
73-
# {label: 'Plant Science', value: 'Plant Science', id: 42}
73+
# {label: 'Plant Science', value: 'Plant Science', id: '42'}
7474
# @api private
7575

7676
autocompleteCourses: ->
@@ -93,7 +93,7 @@ define [
9393
# @api private
9494

9595
updateSearch: (event) =>
96-
value = parseInt(event.target.value, 10)
96+
value = event.target.value && String(event.target.value)
9797
@setSourceCourseId value
9898

9999
courses = @autocompleteCourses()

app/coffeescripts/views/conversations/AutocompleteView.coffee

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,7 @@ define [
181181
#
182182
# Returns a model object.
183183
_getModel: (id) ->
184+
id = id && String(id)
184185
result = @resultCollection.find((model) -> model.id == id)
185186

186187
# Internal: Remove the "selected" class from result list items.

app/coffeescripts/views/courses/roster/EditSectionsView.coffee

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ define [
7171

7272
enrollment = @model.findEnrollmentByRole(@model.currentRole)
7373
currentIds = _.map @model.sectionEditableEnrollments(), (en) -> en.course_section_id
74-
sectionIds = _.map $('#user_sections').find('input'), (i) -> parseInt($(i).val().split('_')[1])
74+
sectionIds = _.map $('#user_sections').find('input'), (i) -> $(i).val().split('_')[1]
7575
newSections = _.reject sectionIds, (i) => _.include currentIds, i
7676
newEnrollments = []
7777
deferreds = []

app/controllers/application_controller.rb

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1406,11 +1406,15 @@ def set_layout_options
14061406
(@body_classes ||= []) << 'embedded' if @embedded_view
14071407
end
14081408

1409+
def stringify_json_ids?
1410+
request.headers['Accept'] =~ %r{application/json\+canvas-string-ids}
1411+
end
1412+
14091413
def render(options = nil, extra_options = {}, &block)
14101414
set_layout_options
14111415
if options && options.key?(:json)
14121416
json = options.delete(:json)
1413-
json = ActiveSupport::JSON.encode(json) unless json.is_a?(String)
1417+
json = ActiveSupport::JSON.encode(json, stringify_json_ids: stringify_json_ids?) unless json.is_a?(String)
14141418
# prepend our CSRF protection to the JSON response, unless this is an API
14151419
# call that didn't use session auth, or a non-GET request.
14161420
if prepend_json_csrf?

app/controllers/context_controller.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -312,7 +312,7 @@ def roster
312312
load_all_contexts(:context => @context)
313313
js_env({
314314
:ALL_ROLES => all_roles,
315-
:SECTIONS => sections.map { |s| { :id => s.id, :name => s.name } },
315+
:SECTIONS => sections.map { |s| { :id => s.id.to_s, :name => s.name } },
316316
:USER_LISTS_URL => polymorphic_path([@context, :user_lists], :format => :json),
317317
:ENROLL_USERS_URL => course_enroll_users_url(@context),
318318
:SEARCH_URL => search_recipients_url,

app/controllers/conversations_controller.rb

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,8 +153,11 @@ def index
153153
load_all_contexts :permissions => [:manage_user_notes]
154154
notes_enabled = @current_user.associated_accounts.any?{|a| a.enable_user_notes }
155155
can_add_notes_for_account = notes_enabled && @current_user.associated_accounts.any?{|a| a.grants_right?(@current_user, nil, :manage_students) }
156+
157+
current_user_json = conversation_user_json(@current_user, @current_user, session, :include_participant_avatars => true)
158+
current_user_json[:id] = current_user_json[:id].to_s
156159
hash = {:CONVERSATIONS => {
157-
:USER => conversation_users_json([@current_user], @current_user, session, :include_participant_contexts => false).first,
160+
:USER => current_user_json,
158161
:CONTEXTS => @contexts,
159162
:NOTES_ENABLED => notes_enabled,
160163
:CAN_ADD_NOTES_FOR_ACCOUNT => can_add_notes_for_account,

app/views/gradebooks/speed_grader.html.erb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
jammit_css :speed_grader
44
js_env({
55
:RUBRIC_ASSESSMENT => {
6-
:assessor_id => @current_user ? @current_user.id : "null",
6+
:assessor_id => @current_user.id.to_s,
77
:assessment_type => can_do(@assignment, @current_user, :grade) ? "grading" : "peer_review"
88
}
99
})

0 commit comments

Comments
 (0)