Add $Canvas.assignment.description to LTI launch params

Add support for LTI tools to consume the assignment description
set in canvas.

Test Plan:
 - Specs pass

flag = none

Change-Id: I339d80f91fbe2bf2e9c855f227b9ee015f1bb835
Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/275548
Tested-by: Service Cloud Jenkins <svc.cloudjenkins@instructure.com>
Reviewed-by: Weston Dransfield <wdransfield@instructure.com>
Reviewed-by: Xander Moffatt <xmoffatt@instructure.com>
QA-Review: Alex Slaughter <aslaughter@instructure.com>
Product-Review: Alex Slaughter <aslaughter@instructure.com>
This commit is contained in:
Alex Slaughter 2021-10-10 03:28:14 -07:00
parent 9248549b78
commit 30f0a02445
8 changed files with 81 additions and 1 deletions

View File

@ -413,6 +413,7 @@ class Assignment < ActiveRecord::Base
def secure_params
body = {}
body[:lti_assignment_id] = self.lti_context_id || SecureRandom.uuid
body[:lti_assignment_description] = self.description
Canvas::Security.create_jwt(body)
end

View File

@ -245,6 +245,15 @@ the `ext_lti_assignment_id` send in various launches and webhooks.
```
"9ae4170c-6b64-444d-9246-0b7dedd5f560"
```
## com.instructure.Assignment.description
The LTI assignment description of an assignment.
**Availability**: *always*
**Launch Parameter**: *com_instructure_assignment_description*
```
"Example Description"
```
## com.instructure.Assignment.allowedFileExtensions
A comma separated list of the file extensions that are allowed for submitting to this
assignment. If there are no limits on what files can be uploaded, an empty string will be
@ -1077,6 +1086,15 @@ Returns the assignment_id of the assignment that was launched.
```
1234
```
## Canvas.assignment.description
Returns the assignment_description of the assignment that was launched.
**Availability**: *when launched as an assignment*
```
"Example Description"
```
## com.instructure.Group.id
Returns the Canvas id of the group the current user is in if launching
from a group assignment.

View File

@ -237,6 +237,7 @@ module Canvas::LiveEvents
updated_at: assignment.updated_at,
points_possible: assignment.points_possible,
lti_assignment_id: assignment.lti_context_id,
lti_assignment_description: assignment.description,
lti_resource_link_id: assignment.lti_resource_link_id,
lti_resource_link_id_duplicated_from: assignment.duplicate_of&.lti_resource_link_id,
submission_types: assignment.submission_types

View File

@ -130,7 +130,16 @@ module Lti
secure_params = Canvas::Security.decode_jwt(secure_params)
secure_params[:lti_assignment_id]
rescue Canvas::Security::InvalidToken
return nil
nil
end
def self.decoded_lti_assignment_description(secure_params)
return if secure_params.blank?
secure_params = Canvas::Security.decode_jwt(secure_params)
secure_params[:lti_assignment_description]
rescue Canvas::Security::InvalidToken
nil
end
end
end

View File

@ -97,6 +97,7 @@ module Lti
ORIGINALITY_REPORT_GUARD = -> { @originality_report.present? }
ORIGINALITY_REPORT_ATTACHMENT_GUARD = -> { @originality_report&.attachment.present? }
LTI_ASSIGN_ID = -> { @assignment.present? || @originality_report.present? || @secure_params.present? }
LTI_ASSIGN_DESCRIPTION = -> { @assignment.present? || @originality_report.present? || @secure_params.present? }
EDITOR_GUARD = -> { @editor_contents.present? }
STUDENT_ASSIGNMENT_GUARD = -> { @context.is_a?(Course) && @context.user_is_student?(@current_user) && @assignment }
@ -265,6 +266,25 @@ module Lti
LTI_ASSIGN_ID,
default_name: 'com_instructure_assignment_lti_id'
# The LTI assignment description of an assignment.
# @launch_parameter com_instructure_assignment_lti_description
# @example
# ```
# "Example Description"
# ```
register_expansion 'com.instructure.Assignment.description', [],
-> do
if @assignment
@assignment.description
elsif @originality_report
@originality_report.submission.assignment.description
elsif @secure_params.present?
Lti::Security.decoded_lti_assignment_description(@secure_params)
end
end,
LTI_ASSIGN_DESCRIPTION,
default_name: 'com_instructure_assignment_description'
# A comma separated list of the file extensions that are allowed for submitting to this
# assignment. If there are no limits on what files can be uploaded, an empty string will be
# returned. If the assignment does not allow file uploads as a submission type, then no
@ -1196,6 +1216,16 @@ module Lti
-> { @assignment.id },
ASSIGNMENT_GUARD
# Returns the assignment_description of the assignment that was launched.
#
# @example
# ```
# "Example Description"
# ```
register_expansion 'Canvas.assignment.description', [],
-> { @assignment.description },
ASSIGNMENT_GUARD
# Returns the Canvas id of the group the current user is in if launching
# from a group assignment.
#

View File

@ -101,6 +101,7 @@ module Lti
vnd.Canvas.submission.url
Context.title
com.instructure.Assignment.lti.id
com.instructure.Assignment.description
com.instructure.Assignment.allowedFileExtensions
com.instructure.Person.name_sortable
com.instructure.PostMessageToken

View File

@ -81,6 +81,19 @@ describe Lti::Security do
end
end
context '#decoded_lti_assignment_description' do
it 'returns nil if secure params are invalid' do
expect(Lti::Security.decoded_lti_assignment_description('banana')).to be_nil
end
it 'returns the lti assignment description if secure params are valid' do
assignment_id = 12
body = { lti_assignment_description: assignment_id }
secure_params = Canvas::Security.create_jwt(body).to_s
expect(Lti::Security.decoded_lti_assignment_description(secure_params)).to eq assignment_id
end
end
context '.check_and_store_nonce' do
it 'rejects a used nonce' do
enable_cache do

View File

@ -1414,6 +1414,13 @@ module Lti
expect(exp_hash[:test]).to eq 2015
end
it 'has substitution for $Canvas.assignment.description' do
allow(assignment).to receive(:description).and_return('desc')
exp_hash = { test: '$Canvas.assignment.description' }
variable_expander.expand_variables!(exp_hash)
expect(exp_hash[:test]).to eq 'desc'
end
it 'has substitution for $Canvas.assignment.title' do
assignment.title = 'Buy as many ducks as you can'
exp_hash = { test: '$Canvas.assignment.title' }