aj-ims-lti 1.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: b9f32c54ad351ceea8603402a48cb3f7c0c5314469a569595a548d1fe80f50a8
4
+ data.tar.gz: 44257dc66d6311cc408ffd5a3dab25efb8f69bff75c7ee17e998574879500966
5
+ SHA512:
6
+ metadata.gz: 44861b8a0a8d07907568019d8355bfc6e01e046f4a8a98990a0d1924a2c82b0aeeb73a66b002487dbcd65c732bd6aa8cc8fa36223a0ff370aa01261a594499ea
7
+ data.tar.gz: 40d50fb420bd0128e291593ab56a0a09c02f2b8677afae0a4a28900b04f73b3529c3a419aaf7aff6a195ab2f6a277cea9257857ba5e80fccf9ec3a1519a977ed
data/Changelog ADDED
@@ -0,0 +1,34 @@
1
+ 2013-04-24 Version 1.1.3
2
+
3
+ * Corrected lti_version launch parameter
4
+
5
+ 2012-09-05 Version 1.1.2
6
+
7
+ * Added better role checking and convenience methods
8
+
9
+ 2012-09-04 Version 1.1.1
10
+
11
+ * Added cdata value for outcome data extension
12
+
13
+ 2012-08-14 Version 1.1.0
14
+
15
+ * Added framework for LTI extensions
16
+ * Added LTI outcome data extension
17
+ * Fix tests reliant on random ordering
18
+ * Add rails 3 note to readme install docs
19
+ * Create Changelog
20
+
21
+
22
+ 2012-03-14 Version 1.0.2
23
+
24
+ * Refactor OAuth validation into its own module
25
+
26
+
27
+ 2012-03-13 Version 1.0.1
28
+
29
+ * Add gem dependencies to gemspec
30
+
31
+
32
+ 2012-03-11 Version 1.0.0
33
+
34
+ * Publish fully functional and operational IMS LTI library
data/LICENSE ADDED
@@ -0,0 +1,18 @@
1
+ Copyright (c) 2012 Instructure
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
4
+ this software and associated documentation files (the "Software"), to deal in
5
+ the Software without restriction, including without limitation the rights to use,
6
+ copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
7
+ Software, and to permit persons to whom the Software is furnished to do so,
8
+ subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in all
11
+ copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
17
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
18
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,117 @@
1
+ # AJ IMS LTI
2
+
3
+ This ruby library is to help create Tool Providers and Tool Consumers for the
4
+ [IMS LTI standard](http://www.imsglobal.org/lti/index.html).
5
+
6
+ Nearly a fork of the Instructure IMS LTI gem. Top level namespace has been
7
+ changed in order to allow concurrent use of Instructure IMS LTI gem, and this
8
+ gem. Instructure has expressed disinterest in supporting grade writeback, which
9
+ this version of the gem does support.
10
+
11
+ ## Installation
12
+ This is packaged as the `aj-ims-lti` rubygem, so you can just add the dependency to
13
+ your Gemfile or install the gem on your system:
14
+
15
+ gem install aj-ims-lti
16
+
17
+ To require the library in your project:
18
+
19
+ require 'ajims/lti'
20
+
21
+ To validate the OAuth signatures you need to require the appropriate request
22
+ proxy for your application. For example:
23
+
24
+ # For a Sinatra or a Rails 3 app:
25
+ require 'oauth/request_proxy/rack_request'
26
+ # You also need to explicitly enable OAuth 1 support in the environment.rb or an initializer:
27
+ OAUTH_10_SUPPORT = true
28
+
29
+ # For a Rails 2.3 app:
30
+ require 'oauth/request_proxy/action_controller_request'
31
+
32
+ For further information see the [oauth-ruby](https://github.com/oauth-xx/oauth-ruby) project.
33
+
34
+ ## Usage
35
+ This readme won't cover the LTI standard, just how to use the library. It will be
36
+ very helpful to read the [LTI documentation](http://www.imsglobal.org/lti/index.html)
37
+
38
+ In LTI there are Tool Providers (TP) and Tool Consumers (TC), this library is
39
+ useful for implementing both. Here is an overview of the communication process:
40
+ [LTI 1.1 Introduction](http://www.imsglobal.org/lti/v1p1pd/ltiIMGv1p1pd.html#_Toc309649680)
41
+
42
+ This library doesn't help you manage the consumer keys and secrets. The POST
43
+ headers/parameters will contain the `oauth_consumer_key` and your app can use
44
+ that to look up the appropriate `oauth_consumer_secret`.
45
+
46
+ Your app will also need to manage the OAuth nonce to make sure the same nonce
47
+ isn't used twice with the same timestamp. [Read the LTI documentation on OAuth](http://www.imsglobal.org/LTI/v1p1pd/ltiIMGv1p1pd.html#_Toc309649687).
48
+
49
+ ### Tool Provider
50
+ As a TP your app will receive a POST request with a bunch of
51
+ [LTI launch data](http://www.imsglobal.org/lti/v1p1pd/ltiIMGv1p1pd.html#_Toc309649684)
52
+ and it will be signed with OAuth using a key/secret that both the TP and TC share.
53
+ This is covered in the [LTI security model](http://www.imsglobal.org/lti/v1p1pd/ltiIMGv1p1pd.html#_Toc309649685)
54
+
55
+ Here is an example of a simple TP Sinatra app using this gem:
56
+ [LTI Tool Provider](https://github.com/instructure/lti_tool_provider_example)
57
+
58
+ Once you find the `oauth_consumer_secret` based on the `oauth_consumer_key` in
59
+ the request, you can initialize a `ToolProvider` object with them and the post parameters:
60
+
61
+ ```ruby
62
+ # Initialize TP object with OAuth creds and post parameters
63
+ provider = AJIMS::LTI::ToolProvider.new(consumer_key, consumer_secret, params)
64
+
65
+ # Verify OAuth signature by passing the request object
66
+ if provider.valid_request?(request)
67
+ # success
68
+ else
69
+ # handle invalid OAuth
70
+ end
71
+ ```
72
+
73
+ Once your TP object is initialized and verified you can load your tool. All of the
74
+ [launch data](http://www.imsglobal.org/lti/v1p1pd/ltiIMGv1p1pd.html#_Toc309649684)
75
+ is available in the TP object along with some convenience methods like `provider.username`
76
+ which will try to find the name from the 3 potential name launch data attributes.
77
+
78
+ #### Returning Results of a Quiz/Assignment
79
+ If your TP provides some kind of assessment service you can write grades back to
80
+ the TC. This is documented in the LTI docs [here](http://www.imsglobal.org/lti/v1p1pd/ltiIMGv1p1pd.html#_Toc309649690).
81
+
82
+ You can check whether the TC is expecting a grade write-back:
83
+
84
+ ```ruby
85
+ if provider.outcome_service?
86
+ # ready for grade write-back
87
+ else
88
+ # normal tool launch without grade write-back
89
+ end
90
+ ```
91
+
92
+ To write the grade back to the TC your tool will do a POST directly back to the
93
+ URL the TC passed in the launch data. You can use the TP object to do that for you:
94
+
95
+ ```ruby
96
+ # post the score to the TC, score should be a float >= 0.0 and <= 1.0
97
+ # this returns an OutcomeResponse object
98
+ response = provider.post_replace_result!(score)
99
+ if response.success?
100
+ # grade write worked
101
+ elsif response.processing?
102
+ elsif response.unsupported?
103
+ else
104
+ # failed
105
+ end
106
+ ```
107
+
108
+ You can see the error code documentation
109
+ [here](http://www.imsglobal.org/gws/gwsv1p0/imsgws_baseProfv1p0.html#1639667).
110
+
111
+ ### Tool Consumer
112
+ As a Tool Consumer your app will POST an OAuth-signed launch requests to TPs with the necessary
113
+ [LTI launch data](http://www.imsglobal.org/lti/v1p1pd/ltiIMGv1p1pd.html#_Toc309649684).
114
+ This is covered in the [LTI security model](http://www.imsglobal.org/lti/v1p1pd/ltiIMGv1p1pd.html#_Toc309649685)
115
+
116
+ Here is an example of a simple TC Sinatra app using this gem:
117
+ [LTI Tool Consumer](https://github.com/instructure/lti_tool_consumer_example)
data/lib/ajims.rb ADDED
@@ -0,0 +1 @@
1
+ require 'ajims/lti'
data/lib/ajims/lti.rb ADDED
@@ -0,0 +1,51 @@
1
+ require 'oauth'
2
+ require 'builder'
3
+ require "rexml/document"
4
+ require 'uuid'
5
+ require 'cgi'
6
+
7
+ module AJIMS # :nodoc:
8
+
9
+ # :main:IMS::LTI
10
+ # LTI is a standard defined by IMS for creating eduction Tool Consumers/Providers.
11
+ # LTI documentation: http://www.imsglobal.org/lti/index.html
12
+ #
13
+ # When creating these tools you will work primarily with the ToolProvider and
14
+ # ToolConsumer classes.
15
+ #
16
+ # For validating OAuth request be sure to require the necessary proxy request
17
+ # object. See IMS::LTI::RequestValidator#valid_request? for more documentation.
18
+ #
19
+ # == Installation
20
+ # This is packaged as the `ims-lti` rubygem, so you can just add the dependency to
21
+ # your Gemfile or install the gem on your system:
22
+ #
23
+ # gem install ims-lti
24
+ #
25
+ # To require the library in your project:
26
+ #
27
+ # require 'ims/lti'
28
+ module LTI
29
+
30
+ # The versions of LTI this library supports
31
+ VERSIONS = %w{1.0 1.1}
32
+
33
+ class InvalidLTIConfigError < StandardError
34
+ end
35
+
36
+ # Generates a unique identifier
37
+ def self.generate_identifier
38
+ UUID.new
39
+ end
40
+ end
41
+ end
42
+
43
+ require 'ajims/lti/exceptions'
44
+ require 'ajims/lti/extensions'
45
+ require 'ajims/lti/launch_params'
46
+ require 'ajims/lti/request_validator'
47
+ require 'ajims/lti/tool_provider'
48
+ require 'ajims/lti/tool_consumer'
49
+ require 'ajims/lti/outcome_request'
50
+ require 'ajims/lti/outcome_response'
51
+ require 'ajims/lti/tool_config'
@@ -0,0 +1,15 @@
1
+ module AJIMS::LTI
2
+ class XmlParseException < StandardError
3
+ attr_reader :original_exception, :content
4
+ def initialize(content, msg = "Failed to parse XML")
5
+ super(msg)
6
+ @content = content
7
+ end
8
+
9
+ def to_s
10
+ error = super
11
+ error << "\nDOCUMENT:\n#{@content}\nEND OF DOCUMENT\n"
12
+ error
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,45 @@
1
+
2
+ module AJIMS::LTI
3
+ module Extensions
4
+
5
+ # Base functionality for creating LTI extension modules
6
+ # See the test for this class for a simple example of how to create an extension module
7
+ module Base
8
+ def outcome_request_extensions
9
+ []
10
+ end
11
+
12
+ def outcome_response_extensions
13
+ []
14
+ end
15
+
16
+ def extend_outcome_request(request)
17
+ outcome_request_extensions.each do |ext|
18
+ request.extend(ext)
19
+ end
20
+ request
21
+ end
22
+
23
+ def extend_outcome_response(response)
24
+ outcome_response_extensions.each do |ext|
25
+ response.extend(ext)
26
+ end
27
+ response
28
+ end
29
+ end
30
+
31
+ module ExtensionBase
32
+ def outcome_request_extensions
33
+ super
34
+ end
35
+
36
+ def outcome_response_extensions
37
+ super
38
+ end
39
+ end
40
+ end
41
+ end
42
+
43
+ require 'ajims/lti/extensions/outcome_data'
44
+ require 'ajims/lti/extensions/content'
45
+ require 'ajims/lti/extensions/canvas'
@@ -0,0 +1,122 @@
1
+ module AJIMS::LTI
2
+ module Extensions
3
+ # Module that adds Canvas specific LTI extensions
4
+ #
5
+ # It adds convenience methods for generating common canvas use case LTI configurations
6
+ #
7
+ # == Usage
8
+ # To generate an XML configuration:
9
+ #
10
+ # # Create a config object and set some options
11
+ # tc = IMS::LTI::ToolConfig.new(:title => "Example Sinatra Tool Provider", :launch_url => url)
12
+ # tc.description = "This example LTI Tool Provider supports LIS Outcome pass-back."
13
+ #
14
+ # # Extend the Canvas Tool config and add canvas related extensions
15
+ # tc.extend IMS::LTI::Extensions::Canvas::ToolConfig
16
+ # tc.homework_submission! 'http://someplace.com/homework', 'Find Homework'
17
+ #
18
+ # # generate the XML
19
+ # tc.to_xml
20
+ #
21
+ # Or to create a config object from an XML String:
22
+ #
23
+ # tc = IMS::LTI::ToolConfig.create_from_xml(xml)
24
+
25
+ module Canvas
26
+ module ToolConfig
27
+ PLATFORM = 'canvas.instructure.com'
28
+
29
+ # Canvas extension defaults
30
+ # These properties will cascade down to any options that are configured
31
+ def set_canvas_ext_param(key, value)
32
+ set_ext_param(PLATFORM, key, value)
33
+ end
34
+
35
+ def get_canvas_param(param_key)
36
+ get_ext_param PLATFORM, param_key
37
+ end
38
+
39
+ def canvas_privacy_public!()
40
+ set_canvas_ext_param(:privacy_level, 'public')
41
+ end
42
+
43
+ def canvas_privacy_name_only!()
44
+ set_canvas_ext_param(:privacy_level, 'name_only')
45
+ end
46
+
47
+ def canvas_privacy_anonymous!()
48
+ set_canvas_ext_param(:privacy_level, 'anonymous')
49
+ end
50
+
51
+ def canvas_domain!(domain)
52
+ set_canvas_ext_param(:domain, domain)
53
+ end
54
+
55
+ def canvas_text!(text)
56
+ set_canvas_ext_param(:text, text)
57
+ end
58
+
59
+ def canvas_icon_url!(icon_url)
60
+ set_canvas_ext_param(:icon_url, icon_url)
61
+ end
62
+
63
+ def canvas_tool_id!(tool_id)
64
+ set_canvas_ext_param(:tool_id, tool_id)
65
+ end
66
+
67
+ def canvas_selector_dimensions!(width, height)
68
+ set_canvas_ext_param(:selection_width, width)
69
+ set_canvas_ext_param(:selection_height, height)
70
+ end
71
+
72
+ # Canvas options
73
+ # These configure canvas to expose the tool in various locations. Any properties that are set
74
+ # at this level will override the defaults for this launch of the tool
75
+
76
+ # Enables homework submissions via the tool
77
+ # Valid properties are url, text, selection_width, selection_height, enabled
78
+ def canvas_homework_submission!(params = {})
79
+ set_canvas_ext_param(:homework_submission, params)
80
+ end
81
+
82
+ # Adds the tool to canvas' rich text editor
83
+ # Valid properties are url, icon_url, text, selection_width, selection_height, enabled
84
+ def canvas_editor_button!(params = {})
85
+ set_canvas_ext_param(:editor_button, params)
86
+ end
87
+
88
+ # Adds the tool to canvas' resource selector
89
+ # Valid properties are url, text, selection_width, selection_height, enabled
90
+ def canvas_resource_selection!(params = {})
91
+ set_canvas_ext_param(:resource_selection, params)
92
+ end
93
+
94
+ # Adds the tool to account level navigation in canvas
95
+ # Valid properties are url, text, enabled
96
+ def canvas_account_navigation!(params = {})
97
+ set_canvas_ext_param(:account_navigation, params)
98
+ end
99
+
100
+ # Adds the tool to course level navigation in canvas
101
+ # Valid properties are url, text, visibility, default, enabled
102
+ # Visibility describes who will see the navigation element. Possible values are "admins", "members", and nil
103
+ # Default determines if it is on or off by default. Possible values are "admins", "members", and nil
104
+ def canvas_course_navigation!(params = {})
105
+ set_canvas_ext_param(:course_navigation, params)
106
+ end
107
+
108
+ # Adds the tool to user level navigation in canvas
109
+ # Valid properties are url, text, enabled
110
+ def canvas_user_navigation!(params = {})
111
+ set_canvas_ext_param(:user_navigation, params)
112
+ end
113
+
114
+ # Adds canvas environment configurations options
115
+ # Valid properties are launch_url, domain, test_launch_url, test_domain, beta_launch_url, beta_domain
116
+ def canvas_environments!(params = {})
117
+ set_canvas_ext_param(:environments, params)
118
+ end
119
+ end
120
+ end
121
+ end
122
+ end
@@ -0,0 +1,209 @@
1
+ module AJIMS::LTI
2
+ module Extensions
3
+
4
+ # An LTI extension that adds support for content back to the consumer
5
+ #
6
+ # # Initialize TP object with OAuth creds and post parameters
7
+ # provider = IMS::LTI::ToolProvider.new(consumer_key, consumer_secret, params)
8
+ # # add extension
9
+ # provider.extend IMS::LTI::Extensions::Content::ToolProvider
10
+ #
11
+ # If the tool was launched as an content request and it supports the content extension
12
+ # you can redirect the user to the tool consumer using the return url helper methods.
13
+ # The tool consumer is then responsible for consuming the content.
14
+ #
15
+ # #Check if a certain response type is available
16
+ # if provider.accepts_url? do
17
+ # #Generate the URL for the user
18
+ # redirect provider.url_content_return_url(url)
19
+ # end
20
+ #
21
+ module Content
22
+ module ToolProvider
23
+ include AJIMS::LTI::Extensions::ExtensionBase
24
+ include Base
25
+
26
+ # a list of the supported outcome data types
27
+ def accepted_content_types
28
+ return @content_types if @content_types
29
+ @content_types = []
30
+ if val = @ext_params["content_return_types"]
31
+ @content_types = val.split(',').map {|i| i.to_sym}
32
+ end
33
+
34
+ @content_types
35
+ end
36
+
37
+ def accepted_file_extensions
38
+ return @file_extensions if @file_extensions
39
+ @file_extensions = []
40
+ if val = @ext_params["content_file_extensions"]
41
+ @file_extensions = val.split(',').map {|i| i.downcase.strip}
42
+ end
43
+
44
+ @file_extensions
45
+ end
46
+
47
+ def accepts_file?(file_name = nil)
48
+ accepted_content_types.include?(:file) &&
49
+ ( file_name.nil? ||
50
+ accepted_file_extensions.empty? ||
51
+ accepted_file_extensions.any?{|ext| file_name.downcase[/#{ext}$/]} )
52
+ end
53
+
54
+ def accepts_url?
55
+ accepted_content_types.include?(:url)
56
+ end
57
+
58
+ def accepts_lti_launch_url?
59
+ accepted_content_types.include?(:lti_launch_url)
60
+ end
61
+
62
+ def accepts_image_url?
63
+ accepted_content_types.include?(:image_url)
64
+ end
65
+
66
+ def accepts_iframe?
67
+ accepted_content_types.include?(:iframe)
68
+ end
69
+
70
+ def accepts_oembed?
71
+ accepted_content_types.include?(:oembed)
72
+ end
73
+
74
+ def content_intended_use
75
+ @ext_params["content_intended_use"].to_sym if @ext_params["content_intended_use"]
76
+ end
77
+
78
+ # check if the content extension is supported
79
+ def accepts_content?
80
+ !!@ext_params["content_return_types"]
81
+ end
82
+
83
+ # check if the consumer accepts a given type of content
84
+ def accepts_content_type?(content_type)
85
+ accepted_content_types.include? content_type.to_sym
86
+ end
87
+
88
+ #check the use of the content
89
+ def is_content_for? (intended_use)
90
+ content_intended_use == intended_use
91
+ end
92
+
93
+ def content_return_url
94
+ @ext_params["content_return_url"]
95
+ end
96
+
97
+ #generates the return url for file submissions
98
+ def file_content_return_url(url, text, content_type = nil)
99
+ url = CGI::escape(url)
100
+ text = CGI::escape(text)
101
+ content_type = CGI::escape(content_type) if content_type
102
+
103
+ return_url = "#{content_return_url}?return_type=file&url=#{url}&text=#{text}"
104
+ return_url = "#{return_url}&content_type=#{content_type}" if content_type
105
+
106
+ return return_url
107
+ end
108
+
109
+ #generates the return url for url submissions
110
+ def url_content_return_url(url, title = nil, text = 'link', target = '_blank')
111
+ url = CGI::escape(url)
112
+ text = CGI::escape(text)
113
+ target = CGI::escape(target)
114
+
115
+ return_url = "#{content_return_url}?return_type=url&url=#{url}&text=#{text}&target=#{target}"
116
+ return_url = "#{return_url}&title=#{CGI::escape(title)}" if title
117
+
118
+ return return_url
119
+ end
120
+
121
+ #generates the return url for lti launch submissions
122
+ def lti_launch_content_return_url(url, text='link', title=nil)
123
+ url = CGI::escape(url)
124
+ text = CGI::escape(text)
125
+
126
+ return_url = "#{content_return_url}?return_type=lti_launch_url&url=#{url}&text=#{text}"
127
+ return_url = "#{return_url}&title=#{CGI::escape(title)}" if title
128
+
129
+ return return_url
130
+ end
131
+
132
+ #generates the return url for image submissions
133
+ def image_content_return_url(url, width, height, alt = '')
134
+ url = CGI::escape(url)
135
+ width = CGI::escape(width.to_s)
136
+ height = CGI::escape(height.to_s)
137
+ alt = CGI::escape(alt)
138
+
139
+ "#{content_return_url}?return_type=image_url&url=#{url}&width=#{width}&height=#{height}&alt=#{alt}"
140
+ end
141
+
142
+ #generates the return url for iframe submissions
143
+ def iframe_content_return_url(url, width, height, title = nil)
144
+ url = CGI::escape(url)
145
+ width = CGI::escape(width.to_s)
146
+ height = CGI::escape(height.to_s)
147
+
148
+ return_url = "#{content_return_url}?return_type=iframe&url=#{url}&width=#{width}&height=#{height}"
149
+ return_url = "#{return_url}&title=#{CGI::escape(title)}" if title
150
+
151
+ return return_url
152
+ end
153
+
154
+ #generates the return url for oembed submissions
155
+ def oembed_content_return_url(url, endpoint)
156
+ url = CGI::escape(url)
157
+ endpoint = CGI::escape(endpoint)
158
+
159
+ "#{content_return_url}?return_type=oembed&url=#{url}&endpoint=#{endpoint}"
160
+ end
161
+ end
162
+
163
+ module ToolConsumer
164
+ include AJIMS::LTI::Extensions::ExtensionBase
165
+ include Base
166
+
167
+ # a list of the content types accepted
168
+ #
169
+ # tc.add_content_return_types=(['url', 'text'])
170
+ # tc.add_content_return_types=("url,text")
171
+ def content_return_types=(val)
172
+ val = val.join(',') if val.is_a? Array
173
+ set_ext_param('content_return_types', val)
174
+ end
175
+
176
+ # a comma-separated string of the supported outcome data types
177
+ def content_return_types
178
+ get_ext_param('content_return_types')
179
+ end
180
+
181
+ def content_intended_use=(val)
182
+ set_ext_param('content_intended_use', val)
183
+ end
184
+
185
+ def content_intended_use
186
+ get_ext_param('content_intended_use')
187
+ end
188
+
189
+ # convenience method for setting support for homework content
190
+ def support_homework_content!
191
+ self.content_intended_use = 'homework'
192
+ self.content_return_types = 'file,url'
193
+ end
194
+
195
+ # convenience method for setting support for embed content
196
+ def support_embed_content!
197
+ self.content_intended_use = 'embed'
198
+ self.content_return_types = 'oembed,lti_launch_url,url,image_url,iframe'
199
+ end
200
+
201
+ # convenience method for setting support for navigation content
202
+ def support_navigation_content!
203
+ self.content_intended_use = 'navigation'
204
+ self.content_return_types = 'lti_launch_url'
205
+ end
206
+ end
207
+ end
208
+ end
209
+ end