lti_box_engine 0.0.1

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: ed29d85473c8108733a7065619550a82516a9772
4
+ data.tar.gz: d675c633ca88b0f96566dc4eac7ee909eac61d49
5
+ SHA512:
6
+ metadata.gz: 40cc43a14e1bb6eb1370b3e00c4e045e36f01cc6f3c2a42b3dc00ef4bb01a45765250961c335416e745dfcd0b1f415e48f2ecb9c2fab986fadeb439e5a143133
7
+ data.tar.gz: 2cf411615056fc78f45bb7dd5252f79404cf63b670498f714df306b309f5184b11c523f21865847adf22a9d1606e69ab910faaf551969add0936ae9d24a03891
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2014 YOURNAME
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,3 @@
1
+ = LtiBoxEngine
2
+
3
+ This project rocks and uses MIT-LICENSE.
data/Rakefile ADDED
@@ -0,0 +1,40 @@
1
+ begin
2
+ require 'bundler/setup'
3
+ rescue LoadError
4
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
5
+ end
6
+
7
+ require 'rdoc/task'
8
+
9
+ RDoc::Task.new(:rdoc) do |rdoc|
10
+ rdoc.rdoc_dir = 'rdoc'
11
+ rdoc.title = 'LtiBoxEngine'
12
+ rdoc.options << '--line-numbers'
13
+ rdoc.rdoc_files.include('README.rdoc')
14
+ rdoc.rdoc_files.include('lib/**/*.rb')
15
+ end
16
+
17
+ APP_RAKEFILE = File.expand_path("../spec/test_app/Rakefile", __FILE__)
18
+ load 'rails/tasks/engine.rake'
19
+
20
+
21
+
22
+ Bundler::GemHelper.install_tasks
23
+
24
+ Dir[File.join(File.dirname(__FILE__), 'tasks/**/*.rake')].each {|f| load f }
25
+ require 'rspec/core/rake_task'
26
+ RSpec::Core::RakeTask.new(:spec)
27
+ task :default => :spec
28
+
29
+ desc 'Run the test dummy rails app'
30
+ task :run_engine do
31
+ exec 'cd spec/test_app && bundle exec rails s'
32
+ end
33
+
34
+ desc 'Run a pry console'
35
+ task :console do
36
+ require 'pry'
37
+ require '#{name}'
38
+ ARGV.clear
39
+ Pry.start
40
+ end
@@ -0,0 +1,13 @@
1
+ // This is a manifest file that'll be compiled into application.js, which will include all the files
2
+ // listed below.
3
+ //
4
+ // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
5
+ // or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
6
+ //
7
+ // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
8
+ // compiled file.
9
+ //
10
+ // Read Sprockets README (https://github.com/sstephenson/sprockets#sprockets-directives) for details
11
+ // about supported directives.
12
+ //
13
+ //= require_tree .
@@ -0,0 +1,2 @@
1
+ // Place all the behaviors and hooks related to the matching controller here.
2
+ // All this logic will automatically be available in application.js.
@@ -0,0 +1,2 @@
1
+ // Place all the behaviors and hooks related to the matching controller here.
2
+ // All this logic will automatically be available in application.js.
@@ -0,0 +1,17 @@
1
+ @import "bootstrap";
2
+
3
+ body {
4
+ padding-top: 20px;
5
+ background-color: #eee;
6
+ }
7
+
8
+ .content {
9
+ max-width: 330px;
10
+ padding: 15px;
11
+ margin: 0 auto;
12
+ text-align: center;
13
+ }
14
+
15
+ #box-select {
16
+ margin: 20px auto;
17
+ }
@@ -0,0 +1,33 @@
1
+ module LtiBoxEngine
2
+ class ApplicationController < ActionController::Base
3
+ before_action :set_default_headers
4
+ before_filter :cors_preflight_check
5
+ after_filter :cors_set_access_control_headers
6
+
7
+ def set_default_headers
8
+ response.headers['X-Frame-Options'] = 'ALLOWALL'
9
+ end
10
+
11
+ # For all responses in this controller, return the CORS access control headers.
12
+ def cors_set_access_control_headers
13
+ headers['Access-Control-Allow-Origin'] = '*'
14
+ headers['Access-Control-Allow-Methods'] = 'POST, PUT, DELETE, GET, OPTIONS'
15
+ headers['Access-Control-Request-Method'] = '*'
16
+ headers['Access-Control-Allow-Headers'] = 'Origin, X-Requested-With, Content-Type, Accept, Authorization'
17
+ headers['Access-Control-Max-Age'] = "1728000"
18
+ end
19
+
20
+ # If this is a preflight OPTIONS request, then short-circuit the
21
+ # request, return only the necessary headers and return an empty
22
+ # text/plain.
23
+ def cors_preflight_check
24
+ if request.method == :options
25
+ headers['Access-Control-Allow-Origin'] = '*'
26
+ headers['Access-Control-Allow-Methods'] = 'POST, GET, OPTIONS'
27
+ headers['Access-Control-Allow-Headers'] = '*'
28
+ headers['Access-Control-Max-Age'] = '1728000'
29
+ render :text => '', :content_type => 'text/plain'
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,80 @@
1
+ require_dependency "lti_box_engine/application_controller"
2
+ require "ims/lti"
3
+ require "oauth/request_proxy/rack_request"
4
+
5
+ module LtiBoxEngine
6
+ class LtiController < ApplicationController
7
+
8
+ def index
9
+ @client = Client.new
10
+ @tp = @client.authorize!(request, params)
11
+ if @tp
12
+ if @tp.accepts_content?
13
+ @lti_launch = LtiLaunch.create_from_tp(@tp)
14
+ if @tp.accepts_file?
15
+ @link_type = "direct"
16
+ else
17
+ @link_type = "shared"
18
+ end
19
+ else
20
+ # launched via navigation
21
+ redirect_to "https://www.box.com/embed_widget/files/0/f/0"
22
+ end
23
+ else
24
+ # handle invalid auth
25
+ @message = @client.error_message
26
+ render :error
27
+ end
28
+ end
29
+
30
+ def embed
31
+ item = params[:item]
32
+ lti_launch = LtiLaunch.where(id: params[:lti_launch_id]).first
33
+ launch_params = lti_launch.payload
34
+
35
+ tp = IMS::LTI::ToolProvider.new(nil, nil, launch_params)
36
+ tp.extend IMS::LTI::Extensions::Content::ToolProvider
37
+
38
+ if tp.accepts_content?
39
+ if tp.accepts_file?(item['name']) && item['type'] != 'folder'
40
+ redirect_url = tp.file_content_return_url(item['url'], item['name'])
41
+ render json: { redirect_url: redirect_url } and return
42
+ elsif tp.accepts_url?
43
+ # The URL will be to a folder. We need to modify it to load the embed widget
44
+ redirect_url = tp.url_content_return_url(Client.box_url_to_box_embed_url(item['url']), item['name'], item['name'])
45
+ render json: { redirect_url: redirect_url } and return
46
+ else
47
+ render text: 'Unsupported content type', status: 500
48
+ end
49
+ else
50
+ render text: 'Unable to embed content', status: 500
51
+ end
52
+ end
53
+
54
+ def xml_config
55
+ host = "#{request.protocol}#{request.host_with_port}"
56
+ url = "#{host}#{root_path}"
57
+ title = "Box"
58
+ tool_id = "lti_box_engine"
59
+ tc = IMS::LTI::ToolConfig.new(:title => title, :launch_url => url)
60
+ tc.extend IMS::LTI::Extensions::Canvas::ToolConfig
61
+ tc.description = "Embed files from Box.net"
62
+ tc.canvas_privacy_anonymous!
63
+ tc.canvas_domain!(request.host)
64
+ tc.canvas_icon_url!("#{host}/assets/lti_box_engine/icon.png")
65
+ tc.canvas_text!(title)
66
+ tc.set_ext_param('canvas.instructure.com', :tool_id, tool_id)
67
+ tc.canvas_homework_submission!(enabled: true)
68
+ tc.canvas_editor_button!(enabled: true)
69
+ tc.canvas_resource_selection!(enabled: true)
70
+ tc.canvas_course_navigation!(enabled: true)
71
+ tc.canvas_user_navigation!(enabled: true)
72
+ tc.canvas_selector_dimensions!(430, 200)
73
+ render xml: tc.to_xml
74
+ end
75
+
76
+ def health_check
77
+ head 200
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,8 @@
1
+ require_dependency "lti_box_engine/application_controller"
2
+
3
+ module LtiBoxEngine
4
+ class TestController < ApplicationController
5
+ def backdoor
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,4 @@
1
+ module LtiBoxEngine
2
+ module ApplicationHelper
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module LtiBoxEngine
2
+ module LtiHelper
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module LtiBoxEngine
2
+ module TestHelper
3
+ end
4
+ end
@@ -0,0 +1,24 @@
1
+ module LtiBoxEngine
2
+ class LtiLaunch < ActiveRecord::Base
3
+ serialize :payload, Hash
4
+
5
+ class << self
6
+ def valid_nonce?(nonce, min=60)
7
+ nonce_ts = Time.now - (min * 60 * 60)
8
+ where(nonce: nonce).where("request_oauth_timestamp >= ?", nonce_ts).count == 0
9
+ end
10
+
11
+ def cleanup!(num_days=3)
12
+ where("request_oauth_timestamp <= ?", Time.now - num_days.days).destroy_all
13
+ end
14
+
15
+ def create_from_tp(tp)
16
+ create({
17
+ nonce: tp.request_oauth_nonce,
18
+ request_oauth_timestamp: Time.at(tp.request_oauth_timestamp.to_i),
19
+ payload: tp.to_params
20
+ })
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,18 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>Box</title>
5
+ <%= stylesheet_link_tag "lti_box_engine/application", media: "all" %>
6
+ <%= javascript_include_tag "lti_box_engine/application" %>
7
+ <%= csrf_meta_tags %>
8
+ </head>
9
+ <body>
10
+
11
+ <div class="container">
12
+ <div class="content">
13
+ <%= yield %>
14
+ </div>
15
+ </div>
16
+
17
+ </body>
18
+ </html>
@@ -0,0 +1,10 @@
1
+ <div class="container">
2
+ <h4 class="page-header">Embed Code Generated</h4>
3
+ <p>
4
+ You're not in a system that supports auto-inserting content,
5
+ so you'll need to copy and past the following code by hand
6
+ in order to insert it into your content.
7
+ </p>
8
+
9
+ <textarea class="form-control" rows="4"><iframe title="<%= @title %>" width="<%= @width %>" height="<%= @height %>" src="<%= @url %>" /></textarea>
10
+ </div>
@@ -0,0 +1 @@
1
+ <%= @message %>
@@ -0,0 +1,34 @@
1
+ <script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js" ></script>
2
+ <script type="text/javascript" src="https://app.box.com/js/static/select.js"></script>
3
+
4
+ <div id="message">Click the button below to select your content</div>
5
+
6
+ <div id="box-select"
7
+ data-link-type="<%= @link_type %>"
8
+ data-multiselect="false"
9
+ data-client-id="zfwxjp79195xz6to7uxlo0hsoehkgryq"></div>
10
+
11
+ <script type="text/javascript">
12
+ $(document).ready(function() {
13
+ var boxSelect = new BoxSelect();
14
+
15
+ // Register a success callback handler
16
+ boxSelect.success(function(response) {
17
+ var item = response[0];
18
+ $.post('<%= lti_embed_path %>', { item: item, lti_launch_id: <%= @lti_launch.id %> }).then(
19
+ function(data) { // success
20
+ console.log(data.redirect_url);
21
+ window.location = data.redirect_url;
22
+ },
23
+ function(jqXHR) { // error
24
+ $('#message').addClass('alert alert-danger').html(jqXHR.responseText);
25
+ }
26
+ );
27
+ });
28
+
29
+ // Register a cancel callback handler
30
+ boxSelect.cancel(function() {
31
+ $('#message').removeClass('alert alert-danger').html("Click the button below to select your content");
32
+ });
33
+ });
34
+ </script>
@@ -0,0 +1,4 @@
1
+ <p>Form to access root page via POST. Used for tests.</p>
2
+ <%= form_tag root_path do %>
3
+ <button type="submit" id="submit">Submit</button>
4
+ <% end %>
data/config/routes.rb ADDED
@@ -0,0 +1,11 @@
1
+ LtiBoxEngine::Engine.routes.draw do
2
+ post "embed" => "lti#embed", as: :lti_embed
3
+ match "launch" => "lti#launch", as: :launch, via: [:get, :post]
4
+ get "config(.xml)" => "lti#xml_config", as: :lti_xml_config
5
+ get "health_check" => "lti#health_check"
6
+ match "/" => "lti#index", via: [:get, :post]
7
+ match "/picker" => "lti#picker", via: [:get, :post]
8
+ root "lti#index"
9
+ get "lti/index"
10
+ get "test/backdoor"
11
+ end
@@ -0,0 +1,11 @@
1
+ class CreateLtiBoxEngineLtiLaunches < ActiveRecord::Migration
2
+ def change
3
+ create_table :lti_box_engine_lti_launches do |t|
4
+ t.string :nonce
5
+ t.text :payload
6
+ t.timestamp :request_oauth_timestamp
7
+
8
+ t.timestamps
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,9 @@
1
+ require "lti_box_engine/engine"
2
+ require "lti_box_engine/client"
3
+ require "bootstrap-sass"
4
+
5
+ # Enable oauth 10 support
6
+ OAUTH_10_SUPPORT = true
7
+
8
+ module LtiBoxEngine
9
+ end
@@ -0,0 +1,49 @@
1
+ require 'ims/lti'
2
+
3
+ module LtiBoxEngine
4
+ class Client
5
+
6
+ $oauth_creds = { "key" => "secret" }
7
+
8
+ attr_accessor :error_message
9
+
10
+ def initialize
11
+ @error_message = nil
12
+ end
13
+
14
+ def register_error(message)
15
+ @error_message = message
16
+ end
17
+
18
+ def self.box_url_to_box_embed_url(url)
19
+ embed_id = url.strip.split('/').last
20
+ "https://app.box.com/embed_widget/s/#{embed_id}?view=list&sort=name&direction=ASC&theme=blue"
21
+ end
22
+
23
+ def authorize!(request, opts = {})
24
+ @error_message = nil
25
+ key = opts['oauth_consumer_key']
26
+ tp = IMS::LTI::ToolProvider.new(key, $oauth_creds[key], opts)
27
+
28
+ if !tp.valid_request?(request)
29
+ register_error("The OAuth signature was invalid")
30
+ return nil
31
+ end
32
+
33
+ if Time.now.utc.to_i - tp.request_oauth_timestamp.to_i > 60*60
34
+ register_error("Your request is too old.")
35
+ return nil
36
+ end
37
+
38
+ if !LtiLaunch.valid_nonce?(tp.request_oauth_nonce, 60)
39
+ register_error("Nonce has already been used.")
40
+ return nil
41
+ end
42
+
43
+ tp.extend IMS::LTI::Extensions::Content::ToolProvider
44
+
45
+ return tp
46
+ end
47
+
48
+ end
49
+ end
@@ -0,0 +1,9 @@
1
+ module LtiBoxEngine
2
+ class Engine < ::Rails::Engine
3
+ isolate_namespace LtiBoxEngine
4
+
5
+ config.generators do |g|
6
+ g.test_framework :rspec
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,3 @@
1
+ module LtiBoxEngine
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,9 @@
1
+ task "assets:precompile" do
2
+ #Copy assets to a non-fingerprinted version
3
+ fingerprint = /\-[0-9a-f]{32}\./
4
+ for file in Dir["public/assets/lti_box_engine/**/*"]
5
+ next unless file =~ fingerprint && !file.end_with?('.css', '.css.gz', '.js', '.js.gz')
6
+ nondigest = file.sub fingerprint, '.'
7
+ FileUtils.cp file, nondigest, verbose: true
8
+ end
9
+ end
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :lti_box_engine do
3
+ # # Task goes here
4
+ # end
metadata ADDED
@@ -0,0 +1,186 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: lti_box_engine
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Brad Humphrey
8
+ - Eric Berry
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2014-04-03 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rails
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - ~>
19
+ - !ruby/object:Gem::Version
20
+ version: 4.0.4
21
+ type: :runtime
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ~>
26
+ - !ruby/object:Gem::Version
27
+ version: 4.0.4
28
+ - !ruby/object:Gem::Dependency
29
+ name: sass-rails
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - '>='
33
+ - !ruby/object:Gem::Version
34
+ version: '3.2'
35
+ type: :runtime
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - '>='
40
+ - !ruby/object:Gem::Version
41
+ version: '3.2'
42
+ - !ruby/object:Gem::Dependency
43
+ name: bootstrap-sass
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ~>
47
+ - !ruby/object:Gem::Version
48
+ version: 3.1.0
49
+ type: :runtime
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ~>
54
+ - !ruby/object:Gem::Version
55
+ version: 3.1.0
56
+ - !ruby/object:Gem::Dependency
57
+ name: ims-lti
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - '>='
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ type: :runtime
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ - !ruby/object:Gem::Dependency
71
+ name: sqlite3
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - '>='
82
+ - !ruby/object:Gem::Version
83
+ version: '0'
84
+ - !ruby/object:Gem::Dependency
85
+ name: rspec-rails
86
+ requirement: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - '>='
89
+ - !ruby/object:Gem::Version
90
+ version: '0'
91
+ type: :development
92
+ prerelease: false
93
+ version_requirements: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - '>='
96
+ - !ruby/object:Gem::Version
97
+ version: '0'
98
+ - !ruby/object:Gem::Dependency
99
+ name: capybara
100
+ requirement: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - '>='
103
+ - !ruby/object:Gem::Version
104
+ version: '0'
105
+ type: :development
106
+ prerelease: false
107
+ version_requirements: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - '>='
110
+ - !ruby/object:Gem::Version
111
+ version: '0'
112
+ - !ruby/object:Gem::Dependency
113
+ name: poltergeist
114
+ requirement: !ruby/object:Gem::Requirement
115
+ requirements:
116
+ - - '>='
117
+ - !ruby/object:Gem::Version
118
+ version: '0'
119
+ type: :development
120
+ prerelease: false
121
+ version_requirements: !ruby/object:Gem::Requirement
122
+ requirements:
123
+ - - '>='
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
126
+ description: Box.net LTI Application as a mountable Rails engine
127
+ email:
128
+ - brad@instructure.com
129
+ - ericb@instructure.com
130
+ executables: []
131
+ extensions: []
132
+ extra_rdoc_files: []
133
+ files:
134
+ - MIT-LICENSE
135
+ - README.rdoc
136
+ - Rakefile
137
+ - app/assets/images/lti_box_engine/icon.png
138
+ - app/assets/javascripts/lti_box_engine/application.js
139
+ - app/assets/javascripts/lti_box_engine/lti.js
140
+ - app/assets/javascripts/lti_box_engine/test.js
141
+ - app/assets/stylesheets/lti_box_engine/application.scss
142
+ - app/controllers/lti_box_engine/application_controller.rb
143
+ - app/controllers/lti_box_engine/lti_controller.rb
144
+ - app/controllers/lti_box_engine/test_controller.rb
145
+ - app/helpers/lti_box_engine/application_helper.rb
146
+ - app/helpers/lti_box_engine/lti_helper.rb
147
+ - app/helpers/lti_box_engine/test_helper.rb
148
+ - app/models/lti_box_engine/lti_launch.rb
149
+ - app/views/layouts/lti_box_engine/application.html.erb
150
+ - app/views/lti_box_engine/lti/embed.html.erb
151
+ - app/views/lti_box_engine/lti/error.html.erb
152
+ - app/views/lti_box_engine/lti/index.html.erb
153
+ - app/views/lti_box_engine/test/backdoor.html.erb
154
+ - config/routes.rb
155
+ - db/migrate/20140401155717_create_lti_box_engine_lti_launches.rb
156
+ - lib/lti_box_engine.rb
157
+ - lib/lti_box_engine/client.rb
158
+ - lib/lti_box_engine/engine.rb
159
+ - lib/lti_box_engine/version.rb
160
+ - lib/tasks/assets.rake
161
+ - lib/tasks/lti_box_engine_tasks.rake
162
+ homepage: https://github.com/instructure/lti-box-engine
163
+ licenses: []
164
+ metadata: {}
165
+ post_install_message:
166
+ rdoc_options: []
167
+ require_paths:
168
+ - lib
169
+ required_ruby_version: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - '>='
172
+ - !ruby/object:Gem::Version
173
+ version: '0'
174
+ required_rubygems_version: !ruby/object:Gem::Requirement
175
+ requirements:
176
+ - - '>='
177
+ - !ruby/object:Gem::Version
178
+ version: '0'
179
+ requirements: []
180
+ rubyforge_project:
181
+ rubygems_version: 2.2.1
182
+ signing_key:
183
+ specification_version: 4
184
+ summary: Box.net LTI Application
185
+ test_files: []
186
+ has_rdoc: