parent_frame_context to external_content#success
closes: INTEROP-7744 flag=none test plan: - Add this to ui/shared/tinymce-external-tools/react/components/ExternalToolDialog.js (after line 180) `<input type="hidden" name="parent_frame_context" value="{id of tool}" />` - add a debugger statement to ui/features/external_content_success/index.js just before line 64 - Launch a 1.1 tool from RCE - choose "return link content item to Canvas" - when the debugger stops in the browser inspect the window of the frame, and `window.ENV.DEEP_LINKING_POST_MESSAGE_ORIGIN` should be the origin of the tool Change-Id: Ifd281c75b259c5617cb3275f928e179ae091ae98 Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/306014 Reviewed-by: Evan Battaglia <ebattaglia@instructure.com> QA-Review: Evan Battaglia <ebattaglia@instructure.com> Tested-by: Service Cloud Jenkins <svc.cloudjenkins@instructure.com> Product-Review: Paul Gray <paul.gray@instructure.com>
This commit is contained in:
parent
a5d18d91db
commit
0f1b7658c9
|
@ -23,6 +23,7 @@ IMS::LTI::Models::ContentItems::ContentItem.add_attribute :canvas_url, json_key:
|
|||
|
||||
class ExternalContentController < ApplicationController
|
||||
include Lti::Concerns::Oembed
|
||||
include Lti::Concerns::ParentFrame
|
||||
|
||||
protect_from_forgery except: [:selection_test, :success], with: :exception
|
||||
|
||||
|
@ -87,6 +88,12 @@ class ExternalContentController < ApplicationController
|
|||
error_message: param_if_set(:lti_errormsg),
|
||||
error_log: param_if_set(:lti_errorlog)
|
||||
})
|
||||
tool_origin = parent_frame_origin(params[:parent_frame_context])
|
||||
if tool_origin
|
||||
js_env({
|
||||
DEEP_LINKING_POST_MESSAGE_ORIGIN: tool_origin
|
||||
}, true)
|
||||
end
|
||||
end
|
||||
|
||||
def normalize_deprecated_data!
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
#
|
||||
# Copyright (C) 2020 - present Instructure, Inc.
|
||||
#
|
||||
# This file is part of Canvas.
|
||||
#
|
||||
# Canvas is free software: you can redistribute it and/or modify it under
|
||||
# the terms of the GNU Affero General Public License as published by the Free
|
||||
# Software Foundation, version 3 of the License.
|
||||
#
|
||||
# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
# details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License along
|
||||
# with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
module Lti::Concerns
|
||||
module ParentFrame
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
# Takes an id of a tool and returns the origin of that tool if it exists
|
||||
# otherwise returns nil
|
||||
def parent_frame_origin(tool_id)
|
||||
tool = tool_id ? ContextExternalTool.find_by(id: tool_id) : nil
|
||||
return nil unless tool&.active? && tool&.developer_key&.internal_service
|
||||
|
||||
if tool.url
|
||||
override_parent_frame_origin(tool.url)
|
||||
elsif tool.domain
|
||||
"https://#{tool.domain}"
|
||||
end
|
||||
end
|
||||
|
||||
def override_parent_frame_origin(url)
|
||||
uri = URI.parse(url)
|
||||
origin = URI("#{uri.scheme}://#{uri.host}:#{uri.port}")
|
||||
origin.to_s
|
||||
end
|
||||
end
|
||||
end
|
|
@ -26,6 +26,7 @@ module Lti
|
|||
|
||||
include Lti::IMS::Concerns::DeepLinkingServices
|
||||
include Lti::IMS::Concerns::DeepLinkingModules
|
||||
include Lti::Concerns::ParentFrame
|
||||
|
||||
before_action :require_context
|
||||
before_action :validate_jwt
|
||||
|
@ -153,23 +154,16 @@ module Lti
|
|||
moduleCreated: module_created
|
||||
}.compact
|
||||
})
|
||||
parent_frame_context = return_url_parameters[:parent_frame_context]
|
||||
parent_frame_tool = parent_frame_context ? ContextExternalTool.find_by(id: parent_frame_context) : nil
|
||||
if parent_frame_tool&.active? && parent_frame_tool&.developer_key&.internal_service
|
||||
tool_origin = parent_frame_origin(return_url_parameters[:parent_frame_context])
|
||||
if tool_origin
|
||||
js_env({
|
||||
DEEP_LINKING_POST_MESSAGE_ORIGIN: origin(parent_frame_tool.url)
|
||||
DEEP_LINKING_POST_MESSAGE_ORIGIN: tool_origin
|
||||
}, true)
|
||||
end
|
||||
|
||||
render layout: "bare"
|
||||
end
|
||||
|
||||
def origin(url)
|
||||
uri = URI.parse(url)
|
||||
origin = URI("#{uri.scheme}://#{uri.host}:#{uri.port}")
|
||||
origin.to_s
|
||||
end
|
||||
|
||||
def require_context_update_rights
|
||||
return unless create_resources_from_content_items?
|
||||
|
||||
|
|
|
@ -101,6 +101,80 @@ describe ExternalContentController do
|
|||
lti_errorlog: '{"html"=>"errorlog somehtml"}'
|
||||
)
|
||||
end
|
||||
|
||||
describe "DEEP_LINKING_POST_MESSAGE_ORIGIN" do
|
||||
subject do
|
||||
post(
|
||||
:success,
|
||||
params: {
|
||||
service: "external_tool_dialog",
|
||||
course_id: c.id,
|
||||
parent_frame_context: tool.id
|
||||
}
|
||||
)
|
||||
end
|
||||
|
||||
let(:tool) do
|
||||
c.context_external_tools.create!(
|
||||
{
|
||||
name: "test tool",
|
||||
domain: "test.com",
|
||||
consumer_key: "fake_oauth_consumer_key",
|
||||
shared_secret: "secret",
|
||||
developer_key: developer_key,
|
||||
url: "http://test.com/login",
|
||||
}
|
||||
)
|
||||
end
|
||||
let(:developer_key) do
|
||||
key = DeveloperKey.new
|
||||
key.generate_rsa_keypair!
|
||||
key.save!
|
||||
key.developer_key_account_bindings.first.update!(
|
||||
workflow_state: "on"
|
||||
)
|
||||
key
|
||||
end
|
||||
|
||||
context "when returning from a non-internal service" do
|
||||
it "does not set the DEEP_LINKING_POST_MESSAGE_ORIGIN value in jsenv" do
|
||||
expect(controller).not_to receive(:js_env).with({ DEEP_LINKING_POST_MESSAGE_ORIGIN: "http://test.com" }, true)
|
||||
subject
|
||||
end
|
||||
end
|
||||
|
||||
context "when returning from an internal service" do
|
||||
before do
|
||||
developer_key.update!(internal_service: true)
|
||||
end
|
||||
|
||||
it "sets the DEEP_LINKING_POST_MESSAGE_ORIGIN value in jsenv" do
|
||||
allow(controller).to receive(:js_env)
|
||||
subject
|
||||
expect(controller).to have_received(:js_env).with({ DEEP_LINKING_POST_MESSAGE_ORIGIN: "http://test.com" }, true)
|
||||
end
|
||||
|
||||
context "when the tool has a domain and not a url" do
|
||||
let(:tool) do
|
||||
c.context_external_tools.create!(
|
||||
{
|
||||
name: "test tool",
|
||||
domain: "test.com",
|
||||
consumer_key: "fake_oauth_consumer_key",
|
||||
shared_secret: "secret",
|
||||
developer_key: developer_key,
|
||||
}
|
||||
)
|
||||
end
|
||||
|
||||
it "sets the DEEP_LINKING_POST_MESSAGE_ORIGIN value in jsenv" do
|
||||
allow(controller).to receive(:js_env)
|
||||
subject
|
||||
expect(controller).to have_received(:js_env).with({ DEEP_LINKING_POST_MESSAGE_ORIGIN: "https://test.com" }, true)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "external_tool service_id" do
|
||||
|
|
Loading…
Reference in New Issue