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.
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 -116
  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 +1 -1
  39. data/lib/ims/lti.rb +6 -64
  40. data/lib/ims.rb +3 -1
  41. metadata +57 -50
  42. data/Changelog +0 -76
  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: 801e423357504d51cc0289e45e364d026abd4bbad20dfca90107725796cd258f
4
- data.tar.gz: cfdcb37216eef088886486f951af05f719b086f7f32f7d8d83dc04f3020b563e
2
+ SHA1:
3
+ metadata.gz: d9a9be3ac5b5acb2c58f5c961cb68be59accfa3f
4
+ data.tar.gz: d5dba5360e965a35e54fe010800735e4d087fe25
5
5
  SHA512:
6
- metadata.gz: fcc31ec46d3fccb7585bbe3d6dff5ab88227ccea12b4c056a2f8c588a864b26bb9d74d13601e2b08f7bcc404d215b4b0be14a3b96b613b79e795edfeb8ad2d0c
7
- data.tar.gz: 0bfa98f889d2b848e03200a22f76447bab3df748c9b6a351d42d5ec9218838ba749f5751af59efd5ae8f7db701a28fcf5b8b92cecb253ebfc097cce3cfb7ff59
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
- 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
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
- ### 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
- ```
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
- ### 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)
9
+ Add this line to your application's Gemfile:
114
10
 
115
- ```ruby
11
+ gem 'lti'
116
12
 
117
- params = { user_id: '123', lti_message_type: IMS::LTI::Models::Messages::BasicLTILaunchRequest::MESSAGE_TYPE }
13
+ And then execute:
118
14
 
119
- header = SimpleOAuth::Header.new(:post, 'https://yoursite.com', params, consumer_key: oauth_consumer_key, consumer_secret: secret)
15
+ $ bundle
120
16
 
121
- signed_params = header.signed_attributes.merge(params)
17
+ Or install it yourself as:
122
18
 
123
- IMS::LTI::Services::MessageAuthenticator.new(launch_url, signed_params, secret)
19
+ $ gem install lti
124
20
 
125
- ```
126
21
 
127
22
  ## Contributing
128
- Here is an example of a simple TC Sinatra app using this gem:
129
- [LTI Tool Consumer](https://github.com/instructure/lti_tool_consumer_example)
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,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