allow basic lti links from arbitrary content

Basic LTI links before could only be added as items in context
modules.  This extends that functionality to also support inserting
Basic LTI links into rich content fields.  There is no UI provided
for inserting these links, that comes in another commit.

test plan:
- create an external tool in a course with a specific url
- manually create a URL to
  /courses/:id/external_tools/retrieve?url=<url>
- the tool should be loaded at the given url

Change-Id: I658b838b8c9a2a6826cf803fd41cb9924fb287ef
Reviewed-on: https://gerrit.instructure.com/5428
Tested-by: Hudson <hudson@instructure.com>
Reviewed-by: Bracken Mosbacker <bracken@instructure.com>
This commit is contained in:
Brian Whitmer 2011-08-17 23:55:25 -06:00
parent 632c66096c
commit 047842784f
5 changed files with 99 additions and 1 deletions

View File

@ -20,6 +20,24 @@ class ExternalToolsController < ApplicationController
end
end
def retrieve
get_context
if authorized_action(@context, @current_user, :read)
@tool = ContextExternalTool.find_external_tool(params[:url], @context)
if !@tool
flash[:error] = t "#application.errors.invalid_external_tool", "Couldn't find valid settings for this link"
redirect_to named_context_url(@context, :context_url)
return
end
@resource_title = @tool.name
@resource_url = params[:url]
@opaque_id = @context.opaque_identifier(:asset_string)
add_crumb(@context.name, named_context_url(@context, :context_url))
@return_url = url_for(@context)
render :template => 'external_tools/tool_show'
end
end
def show
get_context
@tool = ContextExternalTool.find_for(params[:id], @context, "#{@context.class.base_ar_class.to_s.downcase}_navigation")

View File

@ -155,7 +155,7 @@ ActionController::Routing::Routes.draw do |map|
course.resources :assignment_groups, :collection => {:reorder => :post} do |group|
group.reorder_assignments 'reorder', :controller => 'assignment_groups', :action => 'reorder_assignments'
end
course.resources :external_tools do |tools|
course.resources :external_tools, :collection => {:retrieve => :get} do |tools|
tools.finished 'finished', :controller => 'external_tools', :action => 'finished'
end
course.resources :submissions

View File

@ -79,6 +79,7 @@ module UserContent
'wiki' => WikiPage,
'grades' => nil,
'users' => nil,
'external_tools' => nil,
'file_contents' => nil,
'modules' => ContextModule,
}

View File

@ -0,0 +1,58 @@
#
# Copyright (C) 2011 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/>.
#
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
describe ExternalToolsController do
describe "GET 'retrieve'" do
it "should require authentication" do
course_with_teacher(:active_all => true)
user_model
user_session(@user)
get 'retrieve', :course_id => @course.id
assert_unauthorized
end
it "should find tools matching by exact url" do
course_with_teacher_logged_in(:active_all => true)
tool = @course.context_external_tools.new(:name => "bob", :consumer_key => "bob", :shared_secret => "bob")
tool.url = "http://www.example.com/basic_lti"
tool.save!
get 'retrieve', :course_id => @course.id, :url => "http://www.example.com/basic_lti"
response.should be_success
assigns[:tool].should == tool
end
it "should find tools matching by domain" do
course_with_teacher_logged_in(:active_all => true)
tool = @course.context_external_tools.new(:name => "bob", :consumer_key => "bob", :shared_secret => "bob")
tool.domain = "example.com"
tool.save!
get 'retrieve', :course_id => @course.id, :url => "http://www.example.com/basic_lti"
response.should be_success
assigns[:tool].should == tool
end
it "should redirect if no matching tools are found" do
course_with_teacher_logged_in(:active_all => true)
get 'retrieve', :course_id => @course.id, :url => "http://www.example.com"
response.should be_redirect
flash[:error].should == "Couldn't find valid settings for this link"
end
end
end

View File

@ -548,6 +548,27 @@ describe "Canvas Cartridge importing" do
page_2.body.should == (body_with_link % [ @copy_to.id, @copy_to.id, @copy_to.id, @copy_to.id, @copy_to.id, mod2.id, @copy_to.id, to_att.id ]).gsub(/png">/, 'png" />')
end
it "should import migrate inline external tool URLs in wiki pages" do
# make sure that the wiki page we're linking to in the test below exists
page = @copy_from.wiki.wiki_pages.create!(:title => "blti-link", :body => "<a href='/courses/#{@copy_from.id}/external_tools/retrieve?url=#{CGI.escape('http://www.example.com')}'>link</a>")
@copy_from.save!
#export to html file
migration_id = CC::CCHelper.create_key(page)
exported_html = CC::CCHelper::HtmlContentExporter.new(@copy_from, @from_teacher).html_page(page.body, page.title, migration_id)
#convert to json
doc = Nokogiri::HTML(exported_html)
hash = @converter.convert_wiki(doc, 'blti-link')
hash = hash.with_indifferent_access
#import into new course
WikiPage.import_from_migration(hash, @copy_to)
page_2 = @copy_to.wiki.wiki_pages.find_by_migration_id(migration_id)
page_2.title.should == page.title
page_2.url.should == page.url
page_2.body.should match(/\/courses\/#{@copy_to.id}\/external_tools\/retrieve/)
end
it "should import assignments" do
body_with_link = %{<p>Watup? <strong>eh?</strong><a href="/courses/%s/assignments">Assignments</a></p>
<div>