forked from instructure/lti1_tool_provider_example
-
Notifications
You must be signed in to change notification settings - Fork 0
/
tool_provider.rb
110 lines (90 loc) · 2.99 KB
/
tool_provider.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
require 'sinatra'
require 'ims/lti'
# must include the oauth proxy object
require 'oauth/request_proxy/rack_request'
enable :sessions
set :protection, :except => :frame_options
get '/' do
erb :index
end
# the consumer keys/secrets
$oauth_creds = {"test" => "secret", "testing" => "supersecret"}
def show_error(message)
@message = message
erb :error
end
def authorize!
if key = params['oauth_consumer_key']
if secret = $oauth_creds[key]
@tp = IMS::LTI::ToolProvider.new(key, secret, params)
else
@tp = IMS::LTI::ToolProvider.new(nil, nil, params)
@tp.lti_msg = "Your consumer didn't use a recognized key."
@tp.lti_errorlog = "You did it wrong!"
return show_error "Consumer key wasn't recognized"
end
else
return show_error "No consumer key"
end
if [email protected]_request?(request)
return show_error "The OAuth signature was invalid"
end
if Time.now.utc.to_i - @tp.request_oauth_timestamp.to_i > 60*60
return show_error "Your request is too old."
end
# this isn't actually checking anything like it should, just want people
# implementing real tools to be aware they need to check the nonce
if was_nonce_used_in_last_x_minutes?(@tp.request_oauth_nonce, 60)
return show_error "Why are you reusing the nonce?"
end
# save the launch parameters for use in later request
session['launch_params'] = @tp.to_params
@username = @tp.username("Dude")
end
# The url for launching the tool
# It will verify the OAuth signature
post '/lti_tool' do
authorize!
if @tp.outcome_service?
# It's a launch for grading
erb :assessment
else
# normal tool launch without grade write-back
@tp.lti_msg = "Sorry that tool was so boring"
erb :boring_tool
end
end
# post the assessment results
post '/assessment' do
if session['launch_params']
key = session['launch_params']['oauth_consumer_key']
else
return show_error "The tool never launched"
end
@tp = IMS::LTI::ToolProvider.new(key, $oauth_creds[key], session['launch_params'])
if [email protected]_service?
return show_error "This tool wasn't lunched as an outcome service"
end
# post the given score to the TC
res = @tp.post_replace_result!(params['score'])
if res.success?
@score = params['score']
@tp.lti_msg = "Message shown when arriving back at Tool Consumer."
erb :assessment_finished
else
@tp.lti_errormsg = "The Tool Consumer failed to add the score."
show_error "Your score was not recorded: #{res.description}"
end
end
get '/tool_config.xml' do
host = request.scheme + "://" + request.host_with_port
url = host + "/lti_tool"
tc = IMS::LTI::ToolConfig.new(:title => "Example Sinatra Tool Provider", :launch_url => url)
tc.description = "This example LTI Tool Provider supports LIS Outcome pass-back."
headers 'Content-Type' => 'text/xml'
tc.to_xml(:indent => 2)
end
def was_nonce_used_in_last_x_minutes?(nonce, minutes=60)
# some kind of caching solution or something to keep a short-term memory of used nonces
false
end