ims-lti 1.2.9 → 2.0.0.beta.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/Changelog.txt +0 -0
- data/LICENSE.txt +22 -0
- data/README.md +15 -116
- data/lib/ims/lti/converters/time_json_converter.rb +13 -0
- data/lib/ims/lti/converters.rb +5 -0
- data/lib/ims/lti/models/base_url_choice.rb +15 -0
- data/lib/ims/lti/models/base_url_selector.rb +5 -0
- data/lib/ims/lti/models/contact.rb +5 -0
- data/lib/ims/lti/models/icon_endpoint.rb +5 -0
- data/lib/ims/lti/models/icon_info.rb +6 -0
- data/lib/ims/lti/models/localized_name.rb +11 -0
- data/lib/ims/lti/models/localized_text.rb +11 -0
- data/lib/ims/lti/models/lti_model.rb +169 -0
- data/lib/ims/lti/models/message_handler.rb +6 -0
- data/lib/ims/lti/models/messages/basic_lti_launch_request.rb +8 -0
- data/lib/ims/lti/models/messages/message.rb +43 -0
- data/lib/ims/lti/models/messages/registration_request.rb +17 -0
- data/lib/ims/lti/models/messages.rb +6 -0
- data/lib/ims/lti/models/parameter.rb +5 -0
- data/lib/ims/lti/models/product_family.rb +8 -0
- data/lib/ims/lti/models/product_info.rb +19 -0
- data/lib/ims/lti/models/product_instance.rb +10 -0
- data/lib/ims/lti/models/resource_handler.rb +18 -0
- data/lib/ims/lti/models/resource_type.rb +6 -0
- data/lib/ims/lti/models/rest_service.rb +14 -0
- data/lib/ims/lti/models/rest_service_profile.rb +7 -0
- data/lib/ims/lti/models/security_contract.rb +9 -0
- data/lib/ims/lti/models/service_owner.rb +8 -0
- data/lib/ims/lti/models/service_provider.rb +11 -0
- data/lib/ims/lti/models/tool_consumer_profile.rb +20 -0
- data/lib/ims/lti/models/tool_profile.rb +22 -0
- data/lib/ims/lti/models/tool_proxy.rb +11 -0
- data/lib/ims/lti/models/vendor.rb +28 -0
- data/lib/ims/lti/models.rb +29 -0
- data/lib/ims/lti/services/message_service.rb +40 -0
- data/lib/ims/lti/services.rb +5 -0
- data/lib/ims/lti/version.rb +1 -1
- data/lib/ims/lti.rb +6 -64
- data/lib/ims.rb +3 -1
- metadata +57 -50
- data/Changelog +0 -76
- data/LICENSE +0 -18
- data/lib/ims/lti/deprecated_role_checks.rb +0 -52
- data/lib/ims/lti/extensions/canvas.rb +0 -122
- data/lib/ims/lti/extensions/content.rb +0 -258
- data/lib/ims/lti/extensions/outcome_data.rb +0 -240
- data/lib/ims/lti/extensions.rb +0 -45
- data/lib/ims/lti/launch_params.rb +0 -166
- data/lib/ims/lti/outcome_request.rb +0 -225
- data/lib/ims/lti/outcome_response.rb +0 -166
- data/lib/ims/lti/request_validator.rb +0 -56
- data/lib/ims/lti/role_checks.rb +0 -101
- data/lib/ims/lti/tool_base.rb +0 -29
- data/lib/ims/lti/tool_config.rb +0 -231
- data/lib/ims/lti/tool_consumer.rb +0 -86
- data/lib/ims/lti/tool_provider.rb +0 -145
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: d9a9be3ac5b5acb2c58f5c961cb68be59accfa3f
|
4
|
+
data.tar.gz: d5dba5360e965a35e54fe010800735e4d087fe25
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9b45fee316f01a2681c78bc047d7710e3d7ad502afb170407a15e00e2f1f3305742e03024b92d9feca47b650bc93792d1b9ab26176fd92f3ea00137200961350
|
7
|
+
data.tar.gz: 947ca33099a7285791b82e5e0b9d1fa92202d1370a36a0fae5fb83f2d35fb84cbb790f40cff88fc57a18b1e2e0525018b5585e26995547ff7108ede73768acb7
|
data/Changelog.txt
ADDED
File without changes
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 Instructure
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
CHANGED
@@ -1,129 +1,28 @@
|
|
1
1
|
# IMS LTI
|
2
2
|
|
3
|
-
|
4
|
-
[IMS LTI standard](http://www.imsglobal.org/lti/index.html).
|
3
|
+
#Version 2.x is currently BETA
|
5
4
|
|
6
|
-
|
7
|
-
This is packaged as the `ims-lti` rubygem, so you can just add the dependency to
|
8
|
-
your Gemfile or install the gem on your system:
|
9
|
-
|
10
|
-
gem install ims-lti
|
11
|
-
|
12
|
-
To require the library in your project:
|
13
|
-
|
14
|
-
require 'ims/lti'
|
15
|
-
|
16
|
-
To validate the OAuth signatures you need to require the appropriate request
|
17
|
-
proxy for your application. For example:
|
18
|
-
|
19
|
-
# For a Rails 5 (and 2.3) app:
|
20
|
-
require 'oauth/request_proxy/action_controller_request'
|
21
|
-
|
22
|
-
# For a Sinatra or a Rails 3 or 4 app:
|
23
|
-
require 'oauth/request_proxy/rack_request'
|
24
|
-
# You also need to explicitly enable OAuth 1 support in the environment.rb or an initializer:
|
25
|
-
OAUTH_10_SUPPORT = true
|
26
|
-
|
27
|
-
For further information see the [oauth-ruby](https://github.com/oauth-xx/oauth-ruby) project.
|
28
|
-
|
29
|
-
As a quick debugging note, if you forget that step, you'll get an error like:
|
30
|
-
|
31
|
-
OAuth::RequestProxy::UnknownRequestType
|
32
|
-
|
33
|
-
## Usage
|
34
|
-
This readme won't cover the LTI standard, just how to use the library. It will be
|
35
|
-
very helpful to read the [LTI documentation](http://www.imsglobal.org/lti/index.html)
|
36
|
-
|
37
|
-
In LTI there are Tool Providers (TP) and Tool Consumers (TC), this library is
|
38
|
-
useful for implementing both. Here is an overview of the communication process:
|
39
|
-
[LTI 1.1 Introduction](http://www.imsglobal.org/LTI/v1p1/ltiIMGv1p1.html#_Toc319560461)
|
40
|
-
|
41
|
-
This library doesn't help you manage the consumer keys and secrets. The POST
|
42
|
-
headers/parameters will contain the `oauth_consumer_key` and your app can use
|
43
|
-
that to look up the appropriate `oauth_consumer_secret`.
|
44
|
-
|
45
|
-
Your app will also need to manage the OAuth nonce to make sure the same nonce
|
46
|
-
isn't used twice with the same timestamp. [Read the LTI documentation on OAuth](http://www.imsglobal.org/LTI/v1p1/ltiIMGv1p1.html#_Toc319560468).
|
5
|
+
LTI ruby implementation
|
47
6
|
|
48
|
-
|
49
|
-
As a TP your app will receive a POST request with a bunch of
|
50
|
-
[LTI launch data](http://www.imsglobal.org/LTI/v1p1/ltiIMGv1p1.html#_Toc319560465)
|
51
|
-
and it will be signed with OAuth using a key/secret that both the TP and TC share.
|
52
|
-
This is covered in the [LTI security model](http://www.imsglobal.org/LTI/v1p1/ltiIMGv1p1.html#_Toc319560466)
|
53
|
-
|
54
|
-
Here is an example of a simple TP Sinatra app using this gem:
|
55
|
-
[LTI Tool Provider](https://github.com/instructure/lti1_tool_provider_example)
|
56
|
-
|
57
|
-
Once you find the `oauth_consumer_secret` based on the `oauth_consumer_key` in
|
58
|
-
the request, you can initialize a `ToolProvider` object with them and the post parameters:
|
59
|
-
|
60
|
-
```ruby
|
61
|
-
# Initialize TP object with OAuth creds and post parameters
|
62
|
-
provider = IMS::LTI::ToolProvider.new(consumer_key, consumer_secret, params)
|
63
|
-
|
64
|
-
# Verify OAuth signature by passing the request object
|
65
|
-
if provider.valid_request?(request)
|
66
|
-
# success
|
67
|
-
else
|
68
|
-
# handle invalid OAuth
|
69
|
-
end
|
70
|
-
```
|
71
|
-
|
72
|
-
Once your TP object is initialized and verified you can load your tool. All of the
|
73
|
-
[launch data](http://www.imsglobal.org/LTI/v1p1/ltiIMGv1p1.html#_Toc319560465)
|
74
|
-
is available in the TP object along with some convenience methods like `provider.username`
|
75
|
-
which will try to find the name from the 3 potential name launch data attributes.
|
76
|
-
|
77
|
-
#### Returning Results of a Quiz/Assignment
|
78
|
-
If your TP provides some kind of assessment service you can write grades back to
|
79
|
-
the TC. This is documented in the LTI docs [here](http://www.imsglobal.org/LTI/v1p1/ltiIMGv1p1.html#_Toc319560471).
|
80
|
-
|
81
|
-
You can check whether the TC is expecting a grade write-back:
|
82
|
-
|
83
|
-
```ruby
|
84
|
-
if provider.outcome_service?
|
85
|
-
# ready for grade write-back
|
86
|
-
else
|
87
|
-
# normal tool launch without grade write-back
|
88
|
-
end
|
89
|
-
```
|
90
|
-
|
91
|
-
To write the grade back to the TC your tool will do a POST directly back to the
|
92
|
-
URL the TC passed in the launch data. You can use the TP object to do that for you:
|
93
|
-
|
94
|
-
```ruby
|
95
|
-
# post the score to the TC, score should be a float >= 0.0 and <= 1.0
|
96
|
-
# this returns an OutcomeResponse object
|
97
|
-
response = provider.post_replace_result!(score)
|
98
|
-
if response.success?
|
99
|
-
# grade write worked
|
100
|
-
elsif response.processing?
|
101
|
-
elsif response.unsupported?
|
102
|
-
else
|
103
|
-
# failed
|
104
|
-
end
|
105
|
-
```
|
106
|
-
|
107
|
-
You can see the error code documentation
|
108
|
-
[here](http://www.imsglobal.org/gws/gwsv1p0/imsgws_baseProfv1p0.html#1639667).
|
7
|
+
## Installation
|
109
8
|
|
110
|
-
|
111
|
-
As a Tool Consumer your app will POST an OAuth-signed launch requests to TPs with the necessary
|
112
|
-
[LTI launch data](http://www.imsglobal.org/LTI/v1p1/ltiIMGv1p1.html#_Toc319560465).
|
113
|
-
This is covered in the [LTI security model](http://www.imsglobal.org/LTI/v1p1/ltiIMGv1p1.html#_Toc319560466)
|
9
|
+
Add this line to your application's Gemfile:
|
114
10
|
|
115
|
-
|
11
|
+
gem 'lti'
|
116
12
|
|
117
|
-
|
13
|
+
And then execute:
|
118
14
|
|
119
|
-
|
15
|
+
$ bundle
|
120
16
|
|
121
|
-
|
17
|
+
Or install it yourself as:
|
122
18
|
|
123
|
-
|
19
|
+
$ gem install lti
|
124
20
|
|
125
|
-
```
|
126
21
|
|
127
22
|
## Contributing
|
128
|
-
|
129
|
-
|
23
|
+
|
24
|
+
1. Fork it ( http://github.com/instructure/lti/fork )
|
25
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
26
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
27
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
28
|
+
5. Create new Pull Request
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module IMS::LTI::Models
|
2
|
+
class BaseUrlChoice < LTIModel
|
3
|
+
add_attributes :default_base_url, :secure_base_url
|
4
|
+
add_attribute :selector, relation:'IMS::LTI::Models::BaseUrlSelector'
|
5
|
+
|
6
|
+
def default_message_url
|
7
|
+
if selector && selector.applies_to && selector.applies_to.include?('MessageHandler')
|
8
|
+
secure_base_url || default_base_url
|
9
|
+
else
|
10
|
+
''
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,169 @@
|
|
1
|
+
module IMS::LTI::Models
|
2
|
+
class LTIModel
|
3
|
+
LTI_VERSION_2P0 = 'LTI-2p0'
|
4
|
+
|
5
|
+
def initialize(attributes = {})
|
6
|
+
self.attributes = attributes
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.add_attributes(attribute, *attrs)
|
10
|
+
attrs.unshift(attribute)
|
11
|
+
self.attributes += attrs
|
12
|
+
attr_accessor(attrs.shift, *attrs)
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.add_attribute(attribute, options = {})
|
16
|
+
@serialization_options ||= {}
|
17
|
+
options.each do |k, v|
|
18
|
+
@serialization_options[k] ||= {}
|
19
|
+
@serialization_options[k][attribute] = v
|
20
|
+
end
|
21
|
+
self.attributes += [attribute]
|
22
|
+
attr_accessor(attribute)
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.inherit_attributes(attrs)
|
26
|
+
attributes ||= []
|
27
|
+
self.attributes += attrs
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.inherited(subclass)
|
31
|
+
subclass.inherit_attributes(self.attributes)
|
32
|
+
end
|
33
|
+
|
34
|
+
def attributes
|
35
|
+
attrs = {}
|
36
|
+
self.class.attributes.each do |a|
|
37
|
+
value = instance_variable_get("@#{a.to_s}")
|
38
|
+
attrs[a.to_s] = value unless value == nil
|
39
|
+
end
|
40
|
+
attrs
|
41
|
+
end
|
42
|
+
|
43
|
+
def attributes=(attrs)
|
44
|
+
attrs.each do |k, v|
|
45
|
+
instance_variable_set("@#{k.to_s}", v)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def as_json(options = {})
|
50
|
+
json_hash = attributes
|
51
|
+
serialization_attrs_for(:json_key).each { |attr| json_hash.delete(attr.to_s) }
|
52
|
+
serialization_attrs_for(:relation).each do |attr|
|
53
|
+
val = attributes[attr.to_s]
|
54
|
+
json_hash[json_key(attr)] = val.as_json if val
|
55
|
+
end
|
56
|
+
json_hash.merge! to_json_conversions
|
57
|
+
json_hash.merge! to_json_keys
|
58
|
+
json_hash
|
59
|
+
end
|
60
|
+
|
61
|
+
def to_json
|
62
|
+
self.as_json.to_json
|
63
|
+
end
|
64
|
+
|
65
|
+
def from_json(json)
|
66
|
+
data = JSON.parse(json)
|
67
|
+
if data.is_a? Array
|
68
|
+
data.map { |hash| self.class.new.from_json(hash.to_json) }
|
69
|
+
else
|
70
|
+
process_json_hash(data)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
private
|
75
|
+
|
76
|
+
def process_json_hash(hash)
|
77
|
+
change_json_keys_to_attrs!(hash)
|
78
|
+
hash.merge! from_json_conversions(hash)
|
79
|
+
deserialize_json_relations!(hash)
|
80
|
+
self.attributes=(hash)
|
81
|
+
self
|
82
|
+
end
|
83
|
+
|
84
|
+
def serialization_attrs_for(*keys)
|
85
|
+
Array.new(serialization_options.keys & keys).map { |opt| serialization_options[opt].keys }.flatten.uniq
|
86
|
+
end
|
87
|
+
|
88
|
+
def to_json_conversions
|
89
|
+
result = {}
|
90
|
+
if converters = serialization_options[:json_converter]
|
91
|
+
converters.each do |attr, converter|
|
92
|
+
value = attributes[attr.to_s]
|
93
|
+
result[json_key(attr)] = get_constant(converter).to_json_value(value) if value
|
94
|
+
end
|
95
|
+
end
|
96
|
+
result
|
97
|
+
end
|
98
|
+
|
99
|
+
def to_json_keys
|
100
|
+
result = {}
|
101
|
+
if attrs = serialization_attrs_for(:json_key)
|
102
|
+
conversion_attrs = serialization_attrs_for(:json_converter)
|
103
|
+
attrs.each { |attr| result[json_key(attr)] = attributes[attr.to_s] unless conversion_attrs.include?(attr) || attributes[attr.to_s].nil? }
|
104
|
+
end
|
105
|
+
result
|
106
|
+
end
|
107
|
+
|
108
|
+
def change_json_keys_to_attrs!(json_hash)
|
109
|
+
if attrs = serialization_attrs_for(:json_key)
|
110
|
+
attrs.each do |attr|
|
111
|
+
key = json_key(attr)
|
112
|
+
json_hash[attr.to_s] = json_hash.delete(key) if json_hash.has_key?(key)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
def from_json_conversions(hash)
|
118
|
+
result = {}
|
119
|
+
if converters = serialization_options[:json_converter]
|
120
|
+
converters.each do |attr, converter|
|
121
|
+
result[attr] = get_constant(converter).from_json_value(hash[attr.to_s]) if hash[attr.to_s]
|
122
|
+
end
|
123
|
+
end
|
124
|
+
result
|
125
|
+
end
|
126
|
+
|
127
|
+
def deserialize_json_relations!(hash)
|
128
|
+
if relations = serialization_options[:relation]
|
129
|
+
attrs = {}
|
130
|
+
relations.each do |attr, relation|
|
131
|
+
hash_val = hash.delete(attr.to_s)
|
132
|
+
attrs[attr.to_s] = get_constant(relation).new.from_json(hash_val.to_json) if hash_val
|
133
|
+
end
|
134
|
+
self.attributes = attrs
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
def json_key(attr)
|
139
|
+
if json_keys = serialization_options[:json_key]
|
140
|
+
json_keys[attr] || attr
|
141
|
+
else
|
142
|
+
attr
|
143
|
+
end.to_s
|
144
|
+
end
|
145
|
+
|
146
|
+
def self.attributes
|
147
|
+
@attributes || []
|
148
|
+
end
|
149
|
+
|
150
|
+
def self.attributes=(attribs)
|
151
|
+
@attributes = attribs
|
152
|
+
end
|
153
|
+
|
154
|
+
def self.serialization_options
|
155
|
+
@serialization_options ||= {}
|
156
|
+
end
|
157
|
+
|
158
|
+
def serialization_options
|
159
|
+
self.class.serialization_options
|
160
|
+
end
|
161
|
+
|
162
|
+
def get_constant(constant)
|
163
|
+
obj = Object
|
164
|
+
constant.split('::').each { |c| obj = obj.const_get(c) }
|
165
|
+
obj
|
166
|
+
end
|
167
|
+
|
168
|
+
end
|
169
|
+
end
|
@@ -0,0 +1,8 @@
|
|
1
|
+
module IMS::LTI::Models::Messages
|
2
|
+
class BasicLTILaunchRequest < IMS::LTI::Models::LTIModel
|
3
|
+
|
4
|
+
add_attributes :context_id, :context_type, :launch_presentation_return_url, :resource_link_id, :role_scope_mentor,
|
5
|
+
:tool_consumer_instance_guid, :user_image
|
6
|
+
|
7
|
+
end
|
8
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module IMS::LTI::Models::Messages
|
2
|
+
class Message < IMS::LTI::Models::LTIModel
|
3
|
+
LAUNCH_TARGET_IFRAME = 'iframe'
|
4
|
+
LAUNCH_TARGET_WINDOW = 'window'
|
5
|
+
|
6
|
+
add_attributes :lti_message_type, :lti_version, :user_id, :roles, :launch_presentation_local,
|
7
|
+
:launch_presentation_document_target, :launch_presentation_css_url, :launch_presentation_width,
|
8
|
+
:launch_presentation_height
|
9
|
+
|
10
|
+
def initialize(attrs = {})
|
11
|
+
super(attrs)
|
12
|
+
@custom_params = {}
|
13
|
+
@ext_params = {}
|
14
|
+
end
|
15
|
+
|
16
|
+
def post_params
|
17
|
+
get_custom_params.merge(get_ext_params).merge(attributes)
|
18
|
+
end
|
19
|
+
|
20
|
+
def get_ext_params
|
21
|
+
params = {}
|
22
|
+
@ext_params.each { |k, v| params["ext_#{k}"] = v }
|
23
|
+
params
|
24
|
+
end
|
25
|
+
|
26
|
+
def get_custom_params
|
27
|
+
params = {}
|
28
|
+
@custom_params.each { |k, v| params["custom_#{k}"] = v }
|
29
|
+
params
|
30
|
+
end
|
31
|
+
|
32
|
+
def method_missing(meth, *args, &block)
|
33
|
+
if match = /^(custom|ext)_([^=$]*)/.match(meth)
|
34
|
+
param_type, key = match.captures
|
35
|
+
param_hash = instance_variable_get("@#{param_type}_params".to_sym)
|
36
|
+
meth =~ /=$/ ? param_hash[key] = args[0] : param_hash[key]
|
37
|
+
else
|
38
|
+
super
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module IMS::LTI::Models::Messages
|
2
|
+
class RegistrationRequest < Message
|
3
|
+
add_attributes :reg_key, :reg_password, :tc_profile_url, :launch_presentation_return_url
|
4
|
+
|
5
|
+
REGISTRATION_REQUEST_MESSAGE_TYPE = 'ToolProxyRegistrationRequest'
|
6
|
+
|
7
|
+
def initialize(attributes = {})
|
8
|
+
super(attributes)
|
9
|
+
self.lti_message_type = REGISTRATION_REQUEST_MESSAGE_TYPE
|
10
|
+
end
|
11
|
+
|
12
|
+
def generate_key_and_password
|
13
|
+
self.reg_key, self.reg_password = 2.times.map { SecureRandom.uuid }
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module IMS::LTI::Models
|
2
|
+
class ProductInfo < LTIModel
|
3
|
+
add_attribute :product_version
|
4
|
+
add_attribute :product_family, relation: 'IMS::LTI::Models::ProductFamily'
|
5
|
+
add_attribute :description, relation: 'IMS::LTI::Models::LocalizedText'
|
6
|
+
add_attribute :product_name, relation: 'IMS::LTI::Models::LocalizedName'
|
7
|
+
add_attribute :technical_description, relation: 'IMS::LTI::Models::LocalizedText'
|
8
|
+
|
9
|
+
def create_product_name(name, key = 'product.name')
|
10
|
+
@product_name = LocalizedName.new(name, key)
|
11
|
+
end
|
12
|
+
|
13
|
+
def create_description(name, key = 'product.description')
|
14
|
+
@description = LocalizedText.new(name, key)
|
15
|
+
end
|
16
|
+
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
module IMS::LTI::Models
|
2
|
+
class ProductInstance < LTIModel
|
3
|
+
add_attributes :guid
|
4
|
+
add_attribute :product_info, relation:'IMS::LTI::Models::ProductInfo'
|
5
|
+
add_attribute :service_owner, relation:'IMS::LTI::Models::ServiceOwner'
|
6
|
+
add_attribute :support, relation:'IMS::LTI::Models::ServiceProvider'
|
7
|
+
add_attribute :service_provider, relation:'IMS::LTI::Models::Contact'
|
8
|
+
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module IMS::LTI::Models
|
2
|
+
class ResourceHandler < LTIModel
|
3
|
+
add_attribute :resource_type, relation: 'IMS::LTI::Models::ResourceType'
|
4
|
+
add_attribute :resource_name, relation: 'IMS::LTI::Models::LocalizedName'
|
5
|
+
add_attribute :description, relation: 'IMS::LTI::Models::LocalizedText'
|
6
|
+
add_attribute :message, relation: 'IMS::LTI::Models::MessageHandler'
|
7
|
+
add_attribute :icon_info, relation: 'IMS::LTI::Models::IconInfo'
|
8
|
+
|
9
|
+
def default_name
|
10
|
+
resource_name && resource_name.default_value
|
11
|
+
end
|
12
|
+
|
13
|
+
def default_description
|
14
|
+
description && description.default_value
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module IMS::LTI::Models
|
2
|
+
class RestService < LTIModel
|
3
|
+
TYPE = 'RestService'
|
4
|
+
|
5
|
+
add_attributes :endpoint, :format, :action
|
6
|
+
add_attribute :id, json_key:'@id'
|
7
|
+
add_attribute :type, json_key: '@type'
|
8
|
+
|
9
|
+
def initialize
|
10
|
+
@type = TYPE
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
module IMS::LTI::Models
|
2
|
+
class SecurityContract < LTIModel
|
3
|
+
|
4
|
+
add_attribute :shared_secret
|
5
|
+
add_attribute :tool_service, relation: 'IMS::LTI::Models::RestServiceProfile'
|
6
|
+
add_attribute :end_user_service, relation: 'IMS::LTI::Models::RestServiceProfile'
|
7
|
+
|
8
|
+
end
|
9
|
+
end
|
@@ -0,0 +1,8 @@
|
|
1
|
+
module IMS::LTI::Models
|
2
|
+
class ServiceOwner < LTIModel
|
3
|
+
add_attribute :description, relation: 'IMS::LTI::Models::LocalizedText'
|
4
|
+
add_attribute :timestamp, json_converter:'IMS::LTI::Converters::TimeJSONConverter'
|
5
|
+
add_attribute :service_owner_name, relation: 'IMS::LTI::Models::LocalizedName'
|
6
|
+
|
7
|
+
end
|
8
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
module IMS::LTI::Models
|
2
|
+
class ServiceProvider < LTIModel
|
3
|
+
add_attribute :guid
|
4
|
+
add_attribute :id, json_key:'@id'
|
5
|
+
add_attribute :service_provider_name, relation:'IMS::LTI::Models::LocalizedName'
|
6
|
+
add_attribute :description, relation:'IMS::LTI::Models::LocalizedText'
|
7
|
+
add_attribute :support, relation:'IMS::LTI::Models::Contact'
|
8
|
+
add_attribute :timestamp, json_converter: 'IMS::LTI::Converters::TimeJSONConverter'
|
9
|
+
|
10
|
+
end
|
11
|
+
end
|