lti2 0.0.2 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/lti2/version.rb +1 -1
- data/lti2_tp/Gemfile +14 -0
- data/lti2_tp/Gemfile.lock +94 -0
- data/lti2_tp/MIT-LICENSE +20 -0
- data/lti2_tp/README.md +77 -0
- data/lti2_tp/README.rdoc +3 -0
- data/lti2_tp/Rakefile +31 -0
- data/lti2_tp/app/assets/javascripts/lti2_tp/application.js +13 -0
- data/lti2_tp/app/assets/stylesheets/lti2_tp/application.css +13 -0
- data/lti2_tp/app/controllers/lti2_tp/application_controller.rb +4 -0
- data/lti2_tp/app/controllers/lti2_tp/registrations_controller.rb +200 -0
- data/lti2_tp/app/models/lti2_tp/context.rb +55 -0
- data/lti2_tp/app/models/lti2_tp/registration.rb +180 -0
- data/lti2_tp/app/models/lti2_tp/registry.rb +5 -0
- data/lti2_tp/app/models/lti2_tp/tool.rb +27 -0
- data/lti2_tp/app/models/lti2_tp/tool_deployment.rb +5 -0
- data/lti2_tp/app/models/lti2_tp/tool_provider_registry.rb +21 -0
- data/lti2_tp/app/views/layouts/lti2_tp/application.html.erb +14 -0
- data/lti2_tp/bin/rails +8 -0
- data/lti2_tp/config/initializers/lti2_tp.rb +11 -0
- data/lti2_tp/config/routes.rb +9 -0
- data/lti2_tp/db/migrate/20140826151614_create_lti2_tp_resources.rb +67 -0
- data/lti2_tp/lib/lti2_tp.rb +4 -0
- data/lti2_tp/lib/lti2_tp/engine.rb +5 -0
- data/lti2_tp/lib/lti2_tp/version.rb +3 -0
- data/lti2_tp/lib/tasks/lti2_tp_tasks.rake +4 -0
- data/lti2_tp/lti2_tp.gemspec +27 -0
- data/lti2_tp/test/dummy/README.rdoc +28 -0
- data/lti2_tp/test/dummy/Rakefile +6 -0
- data/lti2_tp/test/dummy/app/assets/javascripts/application.js +13 -0
- data/lti2_tp/test/dummy/app/assets/stylesheets/application.css +13 -0
- data/lti2_tp/test/dummy/app/controllers/application_controller.rb +5 -0
- data/lti2_tp/test/dummy/app/helpers/application_helper.rb +2 -0
- data/lti2_tp/test/dummy/app/views/layouts/application.html.erb +14 -0
- data/lti2_tp/test/dummy/bin/bundle +3 -0
- data/lti2_tp/test/dummy/bin/rails +4 -0
- data/lti2_tp/test/dummy/bin/rake +4 -0
- data/lti2_tp/test/dummy/config.ru +4 -0
- data/lti2_tp/test/dummy/config/application.rb +23 -0
- data/lti2_tp/test/dummy/config/boot.rb +5 -0
- data/lti2_tp/test/dummy/config/database.yml +25 -0
- data/lti2_tp/test/dummy/config/environment.rb +5 -0
- data/lti2_tp/test/dummy/config/environments/development.rb +29 -0
- data/lti2_tp/test/dummy/config/environments/production.rb +80 -0
- data/lti2_tp/test/dummy/config/environments/test.rb +36 -0
- data/lti2_tp/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/lti2_tp/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/lti2_tp/test/dummy/config/initializers/inflections.rb +16 -0
- data/lti2_tp/test/dummy/config/initializers/mime_types.rb +5 -0
- data/lti2_tp/test/dummy/config/initializers/secret_token.rb +12 -0
- data/lti2_tp/test/dummy/config/initializers/session_store.rb +3 -0
- data/lti2_tp/test/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/lti2_tp/test/dummy/config/locales/en.yml +23 -0
- data/lti2_tp/test/dummy/config/routes.rb +4 -0
- data/lti2_tp/test/dummy/db/schema.rb +63 -0
- data/lti2_tp/test/dummy/public/404.html +58 -0
- data/lti2_tp/test/dummy/public/422.html +58 -0
- data/lti2_tp/test/dummy/public/500.html +57 -0
- data/lti2_tp/test/dummy/public/favicon.ico +0 -0
- data/lti2_tp/test/integration/navigation_test.rb +10 -0
- data/lti2_tp/test/lti2_tp_test.rb +7 -0
- data/lti2_tp/test/test_helper.rb +15 -0
- metadata +62 -1
@@ -0,0 +1,55 @@
|
|
1
|
+
module Lti2Tp
|
2
|
+
class Context < ActiveRecord::Base
|
3
|
+
|
4
|
+
SESSION_LTI2_CONTEXT_ID = 'lti2_tc_profile.key'
|
5
|
+
|
6
|
+
class Holder
|
7
|
+
attr_accessor :lti2_context
|
8
|
+
def initialize( id=nil )
|
9
|
+
unless id.nil?
|
10
|
+
@lti2_context = Lti2Tp::Context.find_all_by_id([id]).first
|
11
|
+
end
|
12
|
+
if id.nil? || @lti2_context.blank?
|
13
|
+
@lti2_context = Lti2Tp::Context.create()
|
14
|
+
end
|
15
|
+
begin
|
16
|
+
@context_hash = JSON.load( @lti2_context.content )
|
17
|
+
rescue
|
18
|
+
@context_hash = nil
|
19
|
+
end
|
20
|
+
@context_hash ||= {}
|
21
|
+
self
|
22
|
+
end
|
23
|
+
|
24
|
+
def [] name
|
25
|
+
@context_hash[name]
|
26
|
+
end
|
27
|
+
|
28
|
+
def []= name, value
|
29
|
+
@context_hash[name] = value
|
30
|
+
@lti2_context.content = JSON.dump( @context_hash )
|
31
|
+
@lti2_context.save
|
32
|
+
end
|
33
|
+
|
34
|
+
def clear name
|
35
|
+
@context_hash.delete( name )
|
36
|
+
@lti2_context.content = JSON.dump( @context_hash )
|
37
|
+
@lti2_context.save
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.get_holder( session )
|
42
|
+
# lazy create for holder
|
43
|
+
if session.has_key?( SESSION_LTI2_CONTEXT_ID )
|
44
|
+
result = Lti2Tp::Context::Holder.new( session[SESSION_LTI2_CONTEXT_ID] )
|
45
|
+
end
|
46
|
+
if result.blank?
|
47
|
+
result = Lti2Tp::Context::Holder.new()
|
48
|
+
end
|
49
|
+
# reassert in class new run in same browser session
|
50
|
+
session[SESSION_LTI2_CONTEXT_ID] = result.lti2_context.id
|
51
|
+
result
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,180 @@
|
|
1
|
+
module Lti2Tp
|
2
|
+
class Registration < ActiveRecord::Base
|
3
|
+
|
4
|
+
CORRELATION_ID = 'VND-IMS-CORRELATION-ID'
|
5
|
+
DISPOSITION = 'VND-IMS-DISPOSITION'
|
6
|
+
|
7
|
+
HTTP_CORRELATION_ID = 'HTTP_VND_IMS_CORRELATION_ID'
|
8
|
+
HTTP_DISPOSITION = 'HTTP_VND_IMS_DISPOSITION'
|
9
|
+
|
10
|
+
def create_tool_proxy tool_consumer_profile, tool_proxy_guid, disposition
|
11
|
+
tool_provider_registry = Rails.application.config.tool_provider_registry
|
12
|
+
tool_proxy = {}
|
13
|
+
# clone from provided TCP
|
14
|
+
tool_proxy['@context'] = tool_consumer_profile['@context'].clone
|
15
|
+
tool_proxy['@type'] = 'ToolProxy'
|
16
|
+
tool_proxy['@id'] = "ToolProxyProposal_at_#{Time.now.utc.iso8601}"
|
17
|
+
|
18
|
+
tool_proxy['lti_version'] = 'LTI-2p0'
|
19
|
+
tool_proxy['tool_proxy_guid'] = tool_proxy_guid if disposition == 'reregister'
|
20
|
+
|
21
|
+
tool_proxy['tool_consumer_profile'] = self.tc_profile_url
|
22
|
+
tool_proxy['tool_profile'] = JSON.load( tool_profile_json )
|
23
|
+
tool_proxy['security_contract'] = resolve_security_contract( tool_consumer_profile )
|
24
|
+
|
25
|
+
tool_proxy_wrapper = JsonWrapper.new( tool_proxy )
|
26
|
+
tool_proxy_wrapper.root
|
27
|
+
end
|
28
|
+
|
29
|
+
def get_tool_consumer_profile()
|
30
|
+
tcp_response = invoke_unsigned_service(self.tc_profile_url, 'get', {}, {}, nil, Rails.application.config.wire_log, "Get Tool Consumer Profile")
|
31
|
+
JSON.load( tcp_response.body )
|
32
|
+
end
|
33
|
+
|
34
|
+
def prepare_tool_proxy disposition, tool_proxy_guid
|
35
|
+
tool_consumer_profile = JSON.load( self.tool_consumer_profile_json )
|
36
|
+
tool_proxy = create_tool_proxy(tool_consumer_profile, tool_proxy_guid, disposition)
|
37
|
+
if tool_proxy
|
38
|
+
self.end_registration_id = UUID.generate
|
39
|
+
if disposition == 'register'
|
40
|
+
self.tool_proxy_json = tool_proxy.to_json
|
41
|
+
else
|
42
|
+
self.proposed_tool_proxy_json = tool_proxy.to_json
|
43
|
+
end
|
44
|
+
self.save!
|
45
|
+
|
46
|
+
service_offered = nil
|
47
|
+
tool_consumer_profile['service_offered'].select do |entry|
|
48
|
+
if match_services( entry['@id'] , ':ToolProxy.collection' )
|
49
|
+
service_offered = entry
|
50
|
+
break
|
51
|
+
end
|
52
|
+
end
|
53
|
+
if service_offered.nil?
|
54
|
+
status = create_status(false, nil, "No matching service definition")
|
55
|
+
return_url = self.launch_presentation_return_url + '?status=failure'
|
56
|
+
(redirect_to return_url) and return
|
57
|
+
end
|
58
|
+
|
59
|
+
(tool_proxy_response, err_code, err_msg) = register_tool_proxy service_offered, "post", disposition
|
60
|
+
unless err_code == 201
|
61
|
+
status = create_status(false, nil, "#{err_code}-#{err_msg}")
|
62
|
+
return status
|
63
|
+
end
|
64
|
+
if disposition.blank? || disposition == 'register'
|
65
|
+
# get guid from the response returned by the TC
|
66
|
+
tool_proxy['tool_proxy_guid'] = tool_proxy_response['tool_proxy_guid']
|
67
|
+
|
68
|
+
|
69
|
+
# substitute tool_proxy_guid now in the Proxy where needed
|
70
|
+
tool_proxy_wrapper = JsonWrapper.new( tool_proxy )
|
71
|
+
tool_proxy_wrapper.substitute_text_in_all_nodes( '{', '}', { 'tool_proxy_guid' => tool_proxy['tool_proxy_guid'] } )
|
72
|
+
|
73
|
+
self.tool_proxy_json = tool_proxy.to_json
|
74
|
+
self.status = disposition
|
75
|
+
self.save!
|
76
|
+
|
77
|
+
status = create_status(true, tool_proxy_wrapper.first_at('tool_proxy_guid'))
|
78
|
+
else
|
79
|
+
status = create_status(true)
|
80
|
+
end
|
81
|
+
else
|
82
|
+
status = create_status(false, nil, "Can't access ToolProxy")
|
83
|
+
end
|
84
|
+
|
85
|
+
status
|
86
|
+
end
|
87
|
+
|
88
|
+
def create_status(is_success, tool_guid=nil, message=nil)
|
89
|
+
status = "?"
|
90
|
+
if is_success
|
91
|
+
status += 'status=success&'
|
92
|
+
status += "tool_guid=#{tool_guid}&" if tool_guid.present?
|
93
|
+
else
|
94
|
+
status += 'status=failure&'
|
95
|
+
encoded_message = Rack::Utils.escape( message )
|
96
|
+
status += "lti_errormsg=#{encoded_message}<i_errorlog=#{encoded_message}&"
|
97
|
+
end
|
98
|
+
status
|
99
|
+
end
|
100
|
+
|
101
|
+
def is_status_failure? status
|
102
|
+
status.include? "status=failure&"
|
103
|
+
end
|
104
|
+
|
105
|
+
private
|
106
|
+
|
107
|
+
def match_services( test_service, model_service )
|
108
|
+
service_name_pattern = /.*\W(\w+?\.\w+)$/
|
109
|
+
m = service_name_pattern.match( test_service )
|
110
|
+
if m.present?
|
111
|
+
test_word = m[1]
|
112
|
+
m = service_name_pattern.match( model_service )
|
113
|
+
if m.present?
|
114
|
+
model_word = m[1]
|
115
|
+
return test_word == model_word
|
116
|
+
end
|
117
|
+
end
|
118
|
+
return false
|
119
|
+
end
|
120
|
+
|
121
|
+
def register_tool_proxy service_offered, method, disposition
|
122
|
+
if disposition == 'register'
|
123
|
+
data = self.tool_proxy_json
|
124
|
+
label = 'Register'
|
125
|
+
else
|
126
|
+
data = self.proposed_tool_proxy_json
|
127
|
+
label = 'ReRegister'
|
128
|
+
end
|
129
|
+
|
130
|
+
data = JSON.pretty_generate(JSON.load(data))
|
131
|
+
|
132
|
+
# data = CGI::escape(data)
|
133
|
+
signed_request = create_signed_request \
|
134
|
+
service_offered['endpoint'],
|
135
|
+
method,
|
136
|
+
self.reg_key,
|
137
|
+
self.reg_password,
|
138
|
+
{},
|
139
|
+
data,
|
140
|
+
"application/vnd.ims.lti.v2.toolproxy+json"
|
141
|
+
|
142
|
+
puts "Register request: #{signed_request.signature_base_string}"
|
143
|
+
puts "Register secret: #{self.reg_password}"
|
144
|
+
headers = {}
|
145
|
+
(headers[CORRELATION_ID] = self.end_registration_id) if disposition == 'reregister'
|
146
|
+
response = invoke_service(signed_request, Rails.application.config.wire_log, "#{label} ToolProxy with ToolConsumer",
|
147
|
+
headers)
|
148
|
+
if response.code.between?( 200, 202 )
|
149
|
+
response_body = response.body
|
150
|
+
response_content = JSON.load( response_body ) unless response_body.strip.empty?
|
151
|
+
else
|
152
|
+
response_content = nil
|
153
|
+
end
|
154
|
+
[ response_content, response.code, response.message ]
|
155
|
+
end
|
156
|
+
|
157
|
+
|
158
|
+
def resolve_security_contract tool_consumer_profile
|
159
|
+
security_contract = {}
|
160
|
+
|
161
|
+
security_contract['shared_secret'] = SecureRandom.hex
|
162
|
+
security_contract['tool_service'] = []
|
163
|
+
|
164
|
+
services_offered = tool_consumer_profile['service_offered']
|
165
|
+
services_offered.each { |service_offered|
|
166
|
+
tool_service = {}
|
167
|
+
tool_service['@type'] = 'RestServiceProfile'
|
168
|
+
tool_service['service'] = service_offered['@id']
|
169
|
+
tool_service['action'] = service_offered['action']
|
170
|
+
|
171
|
+
# following may be wrong...check on proper construction of RestService
|
172
|
+
# tool_service['format'] = service_offered['format']
|
173
|
+
security_contract['tool_service'] << tool_service
|
174
|
+
}
|
175
|
+
|
176
|
+
security_contract
|
177
|
+
end
|
178
|
+
|
179
|
+
end
|
180
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Lti2Tp
|
2
|
+
class Tool < ActiveRecord::Base
|
3
|
+
|
4
|
+
def get_tool_profile( tool_options=nil )
|
5
|
+
tool_provider_registry = Rails.application.config.tool_provider_registry
|
6
|
+
tool_profile = Lti2Commons::JsonWrapper.new( self.tool_profile_template )
|
7
|
+
tool_profile.substitute_text_in_all_nodes( '{', '}', tool_provider_registry.registry )
|
8
|
+
|
9
|
+
# only if tool_options, provided prune day available resource_handlers
|
10
|
+
if tool_options
|
11
|
+
resource_handlers = tool_profile.first_at('resource_handler')
|
12
|
+
resource_handlers_to_delete = []
|
13
|
+
resource_handlers.each { |resource_handler|
|
14
|
+
resource_handler_wrapper = Lti2Commons::JsonWrapper.new( resource_handler )
|
15
|
+
unless tool_options.include? resource_handler_wrapper.first_at('resource_name.default_value')
|
16
|
+
resource_handlers_to_delete << resource_handler
|
17
|
+
end
|
18
|
+
}
|
19
|
+
resource_handlers_to_delete.each { |rh|
|
20
|
+
resource_handlers.delete( rh )
|
21
|
+
}
|
22
|
+
end
|
23
|
+
tool_profile.root
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Lti2Tp
|
2
|
+
|
3
|
+
class ToolProviderRegistry
|
4
|
+
|
5
|
+
attr_reader :security_contract_template, :tp_deployment_url, :relaxed_oauth_check, :result_template,
|
6
|
+
:tool_provider_name, :registry
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
registry_entries = Registry.all()
|
10
|
+
@registry = {}
|
11
|
+
registry_entries.each { |entry| @registry[entry.name] = entry.content unless entry.name == 'content' }
|
12
|
+
|
13
|
+
@tp_deployment_url = registry['tp_deployment_url']
|
14
|
+
@relaxed_oauth_check = registry['relaxed_oauth_check']
|
15
|
+
@result_template = registry['result_template']
|
16
|
+
@tool_provider_name = registry['tool_provider_name']
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>Lti2Tp</title>
|
5
|
+
<%= stylesheet_link_tag "lti2_tp/application", media: "all" %>
|
6
|
+
<%= javascript_include_tag "lti2_tp/application" %>
|
7
|
+
<%= csrf_meta_tags %>
|
8
|
+
</head>
|
9
|
+
<body>
|
10
|
+
|
11
|
+
<%= yield %>
|
12
|
+
|
13
|
+
</body>
|
14
|
+
</html>
|
data/lti2_tp/bin/rails
ADDED
@@ -0,0 +1,8 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# This command will automatically be run when you run "rails" with Rails 4 gems installed from the root of your application.
|
3
|
+
|
4
|
+
ENGINE_ROOT = File.expand_path('../..', __FILE__)
|
5
|
+
ENGINE_PATH = File.expand_path('../../lib/lti2_tp/engine', __FILE__)
|
6
|
+
|
7
|
+
require 'rails/all'
|
8
|
+
require 'rails/engine/commands'
|
@@ -0,0 +1,11 @@
|
|
1
|
+
include Lti2Commons
|
2
|
+
include WireLogSupport
|
3
|
+
|
4
|
+
NONCE_TIME_TO_LIVE = 300 # seconds
|
5
|
+
Rails.application.config.nonce_cache = Cache.new :ttl => NONCE_TIME_TO_LIVE
|
6
|
+
|
7
|
+
if ActiveRecord::Base.connection.table_exists? 'lti2_tp_registries'
|
8
|
+
Rails.application.config.tool_provider_registry = Lti2Tp::ToolProviderRegistry.new
|
9
|
+
end
|
10
|
+
|
11
|
+
Rails.application.config.wire_log = WireLog.new "ToolProvider", File.expand_path("../tc_sample_app/public/wirelog.html")
|
@@ -0,0 +1,67 @@
|
|
1
|
+
class CreateLti2TpResources < ActiveRecord::Migration
|
2
|
+
def up
|
3
|
+
create_table :lti2_tp_registrations do |t|
|
4
|
+
t.integer :tool_id
|
5
|
+
t.integer :tenant_id
|
6
|
+
t.string :tenant_name
|
7
|
+
t.string :tenant_basename
|
8
|
+
t.string :user_id
|
9
|
+
t.string :reg_key
|
10
|
+
t.string :reg_password
|
11
|
+
t.string :tc_profile_url
|
12
|
+
t.string :launch_presentation_return_url
|
13
|
+
t.string :status
|
14
|
+
t.string :message_type
|
15
|
+
t.string :lti_version
|
16
|
+
t.string :end_registration_id
|
17
|
+
t.text :tool_consumer_profile_json
|
18
|
+
t.text :tool_profile_json
|
19
|
+
t.text :tool_proxy_json
|
20
|
+
t.text :proposed_tool_proxy_json
|
21
|
+
|
22
|
+
t.timestamps
|
23
|
+
end
|
24
|
+
execute('ALTER TABLE lti2_tp_registrations CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;')
|
25
|
+
execute("ALTER TABLE lti2_tp_registrations MODIFY `tenant_name` VARCHAR(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL;")
|
26
|
+
execute("ALTER TABLE lti2_tp_registrations MODIFY `tenant_basename` VARCHAR(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL;")
|
27
|
+
execute("ALTER TABLE lti2_tp_registrations MODIFY `user_id` VARCHAR(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL;")
|
28
|
+
execute("ALTER TABLE lti2_tp_registrations MODIFY `reg_key` VARCHAR(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL;")
|
29
|
+
execute("ALTER TABLE lti2_tp_registrations MODIFY `reg_password` VARCHAR(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL;")
|
30
|
+
execute("ALTER TABLE lti2_tp_registrations MODIFY `tc_profile_url` VARCHAR(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL;")
|
31
|
+
execute("ALTER TABLE lti2_tp_registrations MODIFY `launch_presentation_return_url` VARCHAR(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL;")
|
32
|
+
execute("ALTER TABLE lti2_tp_registrations MODIFY `status` VARCHAR(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL;")
|
33
|
+
execute("ALTER TABLE lti2_tp_registrations MODIFY `message_type` VARCHAR(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL;")
|
34
|
+
execute("ALTER TABLE lti2_tp_registrations MODIFY `lti_version` VARCHAR(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL;")
|
35
|
+
execute("ALTER TABLE lti2_tp_registrations MODIFY `end_registration_id` VARCHAR(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL;")
|
36
|
+
execute("ALTER TABLE lti2_tp_registrations MODIFY `tool_consumer_profile_json` TEXT CHARACTER SET utf8mb4 NULL;")
|
37
|
+
execute("ALTER TABLE lti2_tp_registrations MODIFY `tool_profile_json` TEXT CHARACTER SET utf8mb4 NULL;")
|
38
|
+
execute("ALTER TABLE lti2_tp_registrations MODIFY `tool_proxy_json` TEXT CHARACTER SET utf8mb4 NULL;")
|
39
|
+
execute("ALTER TABLE lti2_tp_registrations MODIFY `proposed_tool_proxy_json` TEXT CHARACTER SET utf8mb4 NULL;")
|
40
|
+
|
41
|
+
create_table :lti2_tp_registries do |t|
|
42
|
+
t.string :name
|
43
|
+
t.text :content
|
44
|
+
|
45
|
+
t.timestamps
|
46
|
+
end
|
47
|
+
execute('ALTER TABLE lti2_tp_registries CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;')
|
48
|
+
execute("ALTER TABLE lti2_tp_registries MODIFY `name` VARCHAR(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL;")
|
49
|
+
execute("ALTER TABLE lti2_tp_registries MODIFY `content` TEXT CHARACTER SET utf8mb4 NULL;")
|
50
|
+
|
51
|
+
create_table :lti2_tp_tools do |t|
|
52
|
+
t.string :tool_name
|
53
|
+
t.text :tool_profile_template
|
54
|
+
|
55
|
+
t.timestamps
|
56
|
+
end
|
57
|
+
execute('ALTER TABLE lti2_tp_tools CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;')
|
58
|
+
execute("ALTER TABLE lti2_tp_tools MODIFY `tool_name` VARCHAR(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL;")
|
59
|
+
execute("ALTER TABLE lti2_tp_tools MODIFY `tool_profile_template` TEXT CHARACTER SET utf8mb4 NULL;")
|
60
|
+
end
|
61
|
+
|
62
|
+
def down
|
63
|
+
drop_table :lti2_tp_registrations
|
64
|
+
drop_table :lti2_tp_registries
|
65
|
+
drop_table :lti2_tp_tools
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
$:.push File.expand_path( '../lib', __FILE__ )
|
2
|
+
|
3
|
+
# Maintain your gem's version:
|
4
|
+
require 'lti2_tp/version'
|
5
|
+
|
6
|
+
# Describe your gem and declare its dependencies:
|
7
|
+
Gem::Specification.new do |s|
|
8
|
+
|
9
|
+
s.name = 'lti2_tp'
|
10
|
+
s.version = Lti2Tp::VERSION
|
11
|
+
s.authors = ['John Tibbetts']
|
12
|
+
s.email = ['john.tibbetts@ingramcontent.com']
|
13
|
+
s.homepage = 'http://vitalsource.com'
|
14
|
+
s.summary = 'LTI2 Tool Provider'
|
15
|
+
s.description = 'LTI2 Tool Provider'
|
16
|
+
|
17
|
+
s.files = Dir[ '{app,config,db,lib}/**/*', 'MIT-LICENSE', 'Rakefile', 'README.rdoc' ]
|
18
|
+
s.test_files = Dir[ 'test/**/*' ]
|
19
|
+
|
20
|
+
s.required_ruby_version = '~> 2.0.0'
|
21
|
+
|
22
|
+
s.add_dependency 'rails', '~> 4.1.1'
|
23
|
+
s.add_dependency 'mysql2', '~> 0.3.13'
|
24
|
+
|
25
|
+
s.add_development_dependency 'sqlite3'
|
26
|
+
|
27
|
+
end
|