ims-lti 1.2.8 → 2.0.0.beta.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.
Files changed (57) hide show
  1. checksums.yaml +5 -5
  2. data/Changelog.txt +0 -0
  3. data/LICENSE.txt +22 -0
  4. data/README.md +15 -103
  5. data/lib/ims/lti/converters/time_json_converter.rb +13 -0
  6. data/lib/ims/lti/converters.rb +5 -0
  7. data/lib/ims/lti/models/base_url_choice.rb +15 -0
  8. data/lib/ims/lti/models/base_url_selector.rb +5 -0
  9. data/lib/ims/lti/models/contact.rb +5 -0
  10. data/lib/ims/lti/models/icon_endpoint.rb +5 -0
  11. data/lib/ims/lti/models/icon_info.rb +6 -0
  12. data/lib/ims/lti/models/localized_name.rb +11 -0
  13. data/lib/ims/lti/models/localized_text.rb +11 -0
  14. data/lib/ims/lti/models/lti_model.rb +169 -0
  15. data/lib/ims/lti/models/message_handler.rb +6 -0
  16. data/lib/ims/lti/models/messages/basic_lti_launch_request.rb +8 -0
  17. data/lib/ims/lti/models/messages/message.rb +43 -0
  18. data/lib/ims/lti/models/messages/registration_request.rb +17 -0
  19. data/lib/ims/lti/models/messages.rb +6 -0
  20. data/lib/ims/lti/models/parameter.rb +5 -0
  21. data/lib/ims/lti/models/product_family.rb +8 -0
  22. data/lib/ims/lti/models/product_info.rb +19 -0
  23. data/lib/ims/lti/models/product_instance.rb +10 -0
  24. data/lib/ims/lti/models/resource_handler.rb +18 -0
  25. data/lib/ims/lti/models/resource_type.rb +6 -0
  26. data/lib/ims/lti/models/rest_service.rb +14 -0
  27. data/lib/ims/lti/models/rest_service_profile.rb +7 -0
  28. data/lib/ims/lti/models/security_contract.rb +9 -0
  29. data/lib/ims/lti/models/service_owner.rb +8 -0
  30. data/lib/ims/lti/models/service_provider.rb +11 -0
  31. data/lib/ims/lti/models/tool_consumer_profile.rb +20 -0
  32. data/lib/ims/lti/models/tool_profile.rb +22 -0
  33. data/lib/ims/lti/models/tool_proxy.rb +11 -0
  34. data/lib/ims/lti/models/vendor.rb +28 -0
  35. data/lib/ims/lti/models.rb +29 -0
  36. data/lib/ims/lti/services/message_service.rb +40 -0
  37. data/lib/ims/lti/services.rb +5 -0
  38. data/lib/ims/lti/version.rb +5 -0
  39. data/lib/ims/lti.rb +6 -64
  40. data/lib/ims.rb +3 -1
  41. metadata +58 -56
  42. data/Changelog +0 -54
  43. data/LICENSE +0 -18
  44. data/lib/ims/lti/deprecated_role_checks.rb +0 -52
  45. data/lib/ims/lti/extensions/canvas.rb +0 -122
  46. data/lib/ims/lti/extensions/content.rb +0 -258
  47. data/lib/ims/lti/extensions/outcome_data.rb +0 -240
  48. data/lib/ims/lti/extensions.rb +0 -45
  49. data/lib/ims/lti/launch_params.rb +0 -166
  50. data/lib/ims/lti/outcome_request.rb +0 -225
  51. data/lib/ims/lti/outcome_response.rb +0 -166
  52. data/lib/ims/lti/request_validator.rb +0 -56
  53. data/lib/ims/lti/role_checks.rb +0 -101
  54. data/lib/ims/lti/tool_base.rb +0 -29
  55. data/lib/ims/lti/tool_config.rb +0 -231
  56. data/lib/ims/lti/tool_consumer.rb +0 -86
  57. data/lib/ims/lti/tool_provider.rb +0 -145
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA256:
3
- metadata.gz: fd3a02081dfe2714b9f8e53f518bb79fbf680778e9766d373adb3d323fe461bc
4
- data.tar.gz: b0aac62837a91c996b60aa062bc34f527fe675533444dea10c4772957de2c6f8
2
+ SHA1:
3
+ metadata.gz: d9a9be3ac5b5acb2c58f5c961cb68be59accfa3f
4
+ data.tar.gz: d5dba5360e965a35e54fe010800735e4d087fe25
5
5
  SHA512:
6
- metadata.gz: c999b9041264a369d4285d965f12d8808d4acd6a89de7ceaa8747ca93303fe8ae452a26e1ec5a42ea268a694bf02a171add2493944b3f9a64773f041436ad769
7
- data.tar.gz: c42d32e837ee89c6a464ba7028469042ce3bdec25eeba826f26134761912558d57a42b9efac2659190170b7893655f6d2bdf34e0cb687793b2f4559e572437bb
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,116 +1,28 @@
1
1
  # IMS LTI
2
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).
3
+ #Version 2.x is currently BETA
5
4
 
6
- ## Installation
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
5
+ LTI ruby implementation
32
6
 
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).
47
-
48
- ### Tool Provider
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
- ```
7
+ ## Installation
71
8
 
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.
9
+ Add this line to your application's Gemfile:
76
10
 
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).
11
+ gem 'lti'
80
12
 
81
- You can check whether the TC is expecting a grade write-back:
13
+ And then execute:
82
14
 
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
- ```
15
+ $ bundle
90
16
 
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:
17
+ Or install it yourself as:
93
18
 
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
- ```
19
+ $ gem install lti
106
20
 
107
- You can see the error code documentation
108
- [here](http://www.imsglobal.org/gws/gwsv1p0/imsgws_baseProfv1p0.html#1639667).
109
21
 
110
- ### Tool Consumer
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)
22
+ ## Contributing
114
23
 
115
- Here is an example of a simple TC Sinatra app using this gem:
116
- [LTI Tool Consumer](https://github.com/instructure/lti_tool_consumer_example)
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,13 @@
1
+ module IMS::LTI::Converters
2
+ class TimeJSONConverter
3
+
4
+ def self.to_json_value(time)
5
+ time
6
+ end
7
+
8
+ def self.from_json_value(json_val)
9
+ Time.parse(json_val)
10
+ end
11
+
12
+ end
13
+ end
@@ -0,0 +1,5 @@
1
+ module IMS::LTI
2
+ module Converters
3
+ require_relative 'converters/time_json_converter'
4
+ end
5
+ end
@@ -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,5 @@
1
+ module IMS::LTI::Models
2
+ class BaseUrlSelector < LTIModel
3
+ add_attribute :applies_to
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ module IMS::LTI::Models
2
+ class Contact < LTIModel
3
+ add_attributes :email
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ module IMS::LTI::Models
2
+ class IconEndpoint < LTIModel
3
+ add_attribute :path
4
+ end
5
+ end
@@ -0,0 +1,6 @@
1
+ module IMS::LTI::Models
2
+ class IconInfo < LTIModel
3
+ add_attributes :key, :icon_style
4
+ add_attribute :default_location, relation: 'IMS::LTI::Models::IconEndpoint'
5
+ end
6
+ end
@@ -0,0 +1,11 @@
1
+ module IMS::LTI::Models
2
+ class LocalizedName < LTIModel
3
+ add_attributes :default_value, :key
4
+
5
+ def initialize(default_value = nil, key = nil)
6
+ @default_value = default_value
7
+ @key = key
8
+ end
9
+
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ module IMS::LTI::Models
2
+ class LocalizedText < LTIModel
3
+ add_attributes :default_value, :key
4
+
5
+ def initialize(default_value = nil, key = nil)
6
+ @default_value = default_value
7
+ @key = key
8
+ end
9
+
10
+ end
11
+ 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,6 @@
1
+ module IMS::LTI::Models
2
+ class MessageHandler < LTIModel
3
+ add_attributes :message_type, :path, :enabled_capability, :parameter
4
+ add_attribute :parameter, relation:'IMS::LTI::Models::Parameter'
5
+ end
6
+ 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,6 @@
1
+ module IMS::LTI::Models
2
+ module Messages
3
+ require_relative 'messages/message'
4
+ require_relative 'messages/registration_request'
5
+ end
6
+ end
@@ -0,0 +1,5 @@
1
+ module IMS::LTI::Models
2
+ class Parameter < LTIModel
3
+ add_attributes :name, :variable, :fixed
4
+ end
5
+ end
@@ -0,0 +1,8 @@
1
+ module IMS::LTI::Models
2
+ class ProductFamily < LTIModel
3
+ add_attributes :code
4
+ add_attribute :id, json_key: '@id'
5
+ add_attribute :vendor, relation: 'IMS::LTI::Models::Vendor'
6
+
7
+ end
8
+ 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,6 @@
1
+ module IMS::LTI::Models
2
+ class ResourceType < LTIModel
3
+ add_attribute :code
4
+
5
+ end
6
+ 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,7 @@
1
+ module IMS::LTI::Models
2
+ class RestServiceProfile < LTIModel
3
+ add_attributes :service, :action
4
+ add_attribute :type, json_key: '@type'
5
+
6
+ end
7
+ 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