ims-lti 1.2.2 → 2.3.2

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 (115) hide show
  1. checksums.yaml +5 -5
  2. data/Changelog.txt +0 -0
  3. data/LICENSE.txt +22 -0
  4. data/README.md +25 -91
  5. data/lib/ims/lis/context_type/handles.rb +10 -0
  6. data/lib/ims/lis/context_type/urns.rb +10 -0
  7. data/lib/ims/lis/roles/context/handles.rb +60 -0
  8. data/lib/ims/lis/roles/context/urns.rb +60 -0
  9. data/lib/ims/lis/roles/institution/handles.rb +22 -0
  10. data/lib/ims/lis/roles/institution/urns.rb +22 -0
  11. data/lib/ims/lis/roles/system/handles.rb +15 -0
  12. data/lib/ims/lis/roles/system/urns.rb +15 -0
  13. data/lib/ims/lis/statuses/simple_names.rb +9 -0
  14. data/lib/ims/lis/statuses/uris.rb +9 -0
  15. data/lib/ims/lis.rb +14 -0
  16. data/lib/ims/lti/converters/time_json_converter.rb +13 -0
  17. data/lib/ims/lti/converters.rb +5 -0
  18. data/lib/ims/lti/errors/authentication_failed_error.rb +11 -0
  19. data/lib/ims/lti/errors/invalid_lti_config_error.rb +4 -0
  20. data/lib/ims/lti/errors/invalid_tool_consumer_profile.rb +4 -0
  21. data/lib/ims/lti/errors/tool_proxy_registration_error.rb +15 -0
  22. data/lib/ims/lti/errors.rb +8 -0
  23. data/lib/ims/lti/models/base_url_choice.rb +15 -0
  24. data/lib/ims/lti/models/base_url_selector.rb +5 -0
  25. data/lib/ims/lti/models/contact.rb +5 -0
  26. data/lib/ims/lti/models/content_item_container.rb +14 -0
  27. data/lib/ims/lti/models/content_item_placement.rb +20 -0
  28. data/lib/ims/lti/models/content_items/content_item.rb +32 -0
  29. data/lib/ims/lti/models/content_items/file_item.rb +15 -0
  30. data/lib/ims/lti/models/content_items/lti_link_item.rb +14 -0
  31. data/lib/ims/lti/models/content_items.rb +7 -0
  32. data/lib/ims/lti/models/icon_endpoint.rb +5 -0
  33. data/lib/ims/lti/models/icon_info.rb +6 -0
  34. data/lib/ims/lti/models/image.rb +7 -0
  35. data/lib/ims/lti/models/localized_name.rb +12 -0
  36. data/lib/ims/lti/models/localized_text.rb +12 -0
  37. data/lib/ims/lti/models/lti_model.rb +227 -0
  38. data/lib/ims/lti/models/membership_service/agent.rb +11 -0
  39. data/lib/ims/lti/models/membership_service/container.rb +11 -0
  40. data/lib/ims/lti/models/membership_service/context.rb +11 -0
  41. data/lib/ims/lti/models/membership_service/lis_membership_container.rb +13 -0
  42. data/lib/ims/lti/models/membership_service/lis_person.rb +14 -0
  43. data/lib/ims/lti/models/membership_service/membership.rb +14 -0
  44. data/lib/ims/lti/models/membership_service/organization.rb +14 -0
  45. data/lib/ims/lti/models/membership_service/page.rb +16 -0
  46. data/lib/ims/lti/models/membership_service/person.rb +13 -0
  47. data/lib/ims/lti/models/membership_service.rb +16 -0
  48. data/lib/ims/lti/models/message_handler.rb +14 -0
  49. data/lib/ims/lti/models/messages/basic_lti_launch_request.rb +24 -0
  50. data/lib/ims/lti/models/messages/content_item_selection.rb +32 -0
  51. data/lib/ims/lti/models/messages/content_item_selection_request.rb +26 -0
  52. data/lib/ims/lti/models/messages/message.rb +239 -0
  53. data/lib/ims/lti/models/messages/registration_request.rb +20 -0
  54. data/lib/ims/lti/models/messages/request_message.rb +12 -0
  55. data/lib/ims/lti/models/messages/tool_proxy_update_request.rb +15 -0
  56. data/lib/ims/lti/models/messages.rb +11 -0
  57. data/lib/ims/lti/models/parameter.rb +28 -0
  58. data/lib/ims/lti/models/product_family.rb +8 -0
  59. data/lib/ims/lti/models/product_info.rb +26 -0
  60. data/lib/ims/lti/models/product_instance.rb +10 -0
  61. data/lib/ims/lti/models/resource_handler.rb +22 -0
  62. data/lib/ims/lti/models/resource_type.rb +6 -0
  63. data/lib/ims/lti/models/rest_service.rb +30 -0
  64. data/lib/ims/lti/models/rest_service_profile.rb +15 -0
  65. data/lib/ims/lti/models/security_contract.rb +21 -0
  66. data/lib/ims/lti/models/security_profile.rb +10 -0
  67. data/lib/ims/lti/models/serializable.rb +12 -0
  68. data/lib/ims/lti/models/service_owner.rb +26 -0
  69. data/lib/ims/lti/models/service_provider.rb +11 -0
  70. data/lib/ims/lti/models/tool_consumer_profile.rb +45 -0
  71. data/lib/ims/lti/models/tool_profile.rb +35 -0
  72. data/lib/ims/lti/models/tool_proxy.rb +21 -0
  73. data/lib/ims/lti/models/tool_setting.rb +12 -0
  74. data/lib/ims/lti/models/tool_setting_container.rb +14 -0
  75. data/lib/ims/lti/models/vendor.rb +28 -0
  76. data/lib/ims/lti/models.rb +38 -0
  77. data/lib/ims/lti/serializers/base.rb +125 -0
  78. data/lib/ims/lti/serializers/membership_service/agent_serializer.rb +5 -0
  79. data/lib/ims/lti/serializers/membership_service/container_serializer.rb +6 -0
  80. data/lib/ims/lti/serializers/membership_service/context_serializer.rb +9 -0
  81. data/lib/ims/lti/serializers/membership_service/lis_membership_container_serializer.rb +9 -0
  82. data/lib/ims/lti/serializers/membership_service/lis_person_serializer.rb +12 -0
  83. data/lib/ims/lti/serializers/membership_service/membership_serializer.rb +7 -0
  84. data/lib/ims/lti/serializers/membership_service/organization_serializer.rb +8 -0
  85. data/lib/ims/lti/serializers/membership_service/page_serializer.rb +10 -0
  86. data/lib/ims/lti/serializers/membership_service/person_serializer.rb +8 -0
  87. data/lib/ims/lti/serializers/membership_service.rb +13 -0
  88. data/lib/ims/lti/serializers.rb +6 -0
  89. data/lib/ims/lti/services/authentication_service.rb +67 -0
  90. data/lib/ims/lti/services/message_authenticator.rb +80 -0
  91. data/lib/ims/lti/services/oauth2_client.rb +18 -0
  92. data/lib/ims/lti/{tool_config.rb → services/tool_config.rb} +26 -34
  93. data/lib/ims/lti/services/tool_consumer_profile_service.rb +16 -0
  94. data/lib/ims/lti/services/tool_proxy_registration_service.rb +84 -0
  95. data/lib/ims/lti/services/tool_proxy_validator.rb +182 -0
  96. data/lib/ims/lti/services.rb +11 -0
  97. data/lib/ims/lti/version.rb +5 -0
  98. data/lib/ims/lti.rb +13 -63
  99. data/lib/ims.rb +4 -1
  100. metadata +280 -36
  101. data/Changelog +0 -51
  102. data/LICENSE +0 -18
  103. data/lib/ims/lti/deprecated_role_checks.rb +0 -52
  104. data/lib/ims/lti/extensions/canvas.rb +0 -122
  105. data/lib/ims/lti/extensions/content.rb +0 -209
  106. data/lib/ims/lti/extensions/outcome_data.rb +0 -199
  107. data/lib/ims/lti/extensions.rb +0 -45
  108. data/lib/ims/lti/launch_params.rb +0 -166
  109. data/lib/ims/lti/outcome_request.rb +0 -210
  110. data/lib/ims/lti/outcome_response.rb +0 -166
  111. data/lib/ims/lti/request_validator.rb +0 -56
  112. data/lib/ims/lti/role_checks.rb +0 -101
  113. data/lib/ims/lti/tool_base.rb +0 -29
  114. data/lib/ims/lti/tool_consumer.rb +0 -86
  115. data/lib/ims/lti/tool_provider.rb +0 -143
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 2e3945deaa6d79358bb3ea7ad294db2f2896d0fe
4
- data.tar.gz: 659184a29bcfc8a0e2c316c2477c09a3a93a67bb
2
+ SHA256:
3
+ metadata.gz: 6de9bbbf79d7c9a876eadd145ec7317b05268aa095ab1df5202db6c96d08599a
4
+ data.tar.gz: 3122f727f095833a7a3a380c46698da81f638a670f8bf49c72124327bf8fd1bb
5
5
  SHA512:
6
- metadata.gz: 95beb0b61c86abfc375cfc0d3a3bdddae2827d5b3beef379a8b8c116f4c7c0e122f04e8a183195a86da34078b4d247e0e1b5e5540d44f59578e2089e782b8a4a
7
- data.tar.gz: 8e0a8437e91a3dcdce57fae87263664d60872d6b01b9f41272135deedc41e82b7d02eb5294ce1c296ccc56c65cde672a9d526f5edec842547227a2f058c44168
6
+ metadata.gz: 8c6f21d78459aa18c5953e7e4d40f59882abc5e927eff0c3fedb9672208ac89d4ee4bced6222498cf86b4ef7f9f0803f64ca7f0a99af79dcb6283f6cced63c0d
7
+ data.tar.gz: 8032a4d4d4ffb044a7fb915467b5267fcc0bbbeb07683f5d7d920cdd1d9ee4942f8a394da50c92c9c7c5ae2bbe27cee599b997ab60019931cf6ada666425ed9d
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,50 @@
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
+ [![Build Status](https://travis-ci.org/instructure/ims-lti.svg?branch=2.1.x)](https://travis-ci.org/instructure/ims-lti)
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
5
+ LTI ruby implementation
11
6
 
12
- To require the library in your project:
13
-
14
- require 'ims/lti'
7
+ ## Installation
15
8
 
16
- To validate the OAuth signatures you need to require the appropriate request
17
- proxy for your application. For example:
9
+ Add this line to your application's Gemfile:
18
10
 
19
- # For a Rails 5 (and 2.3) app:
20
- require 'oauth/request_proxy/action_controller_request'
11
+ gem 'ims-lti'
21
12
 
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
13
+ And then execute:
26
14
 
27
- For further information see the [oauth-ruby](https://github.com/oauth-xx/oauth-ruby) project.
15
+ $ bundle
28
16
 
29
- As a quick debugging note, if you forget that step, you'll get an error like:
17
+ Or install it yourself as:
30
18
 
31
- OAuth::RequestProxy::UnknownRequestType
19
+ $ gem install lti
32
20
 
33
21
  ## 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
22
 
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
23
 
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`.
24
+ ### LTI 1.x
44
25
 
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).
26
+ #### Validating Launches
47
27
 
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:
28
+ You can use the classes in the IMS::LTI::Models::Messages module to valdiate Launches
59
29
 
30
+ For example in a rails app you would do the following
60
31
  ```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
- ```
32
+ authenticator = IMS::LTI::Services::MessageAuthenticator.new(request.url, request.request_parameters, shared_secret)
71
33
 
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.
34
+ #Check if the signature is valid
35
+ return false unless authenticator.valid_signature?
76
36
 
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).
37
+ # check if `params['oauth_nonce']` has already been used
80
38
 
81
- You can check whether the TC is expecting a grade write-back:
39
+ #check if the message is too old
40
+ return false if DateTime.strptime(request.request_parameters['oauth_timestamp'],'%s') < 5.minutes.ago
82
41
 
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
42
  ```
106
43
 
107
- You can see the error code documentation
108
- [here](http://www.imsglobal.org/gws/gwsv1p0/imsgws_baseProfv1p0.html#1639667).
109
-
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)
44
+ ## Contributing
114
45
 
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)
46
+ 1. Fork it ( http://github.com/instructure/ims-lti/fork )
47
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
48
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
49
+ 4. Push to the branch (`git push origin my-new-feature`)
50
+ 5. Create new Pull Request
@@ -0,0 +1,10 @@
1
+ module IMS::LIS
2
+ module ContextType
3
+ module Handles
4
+ CourseTemplate = "CourseTemplate"
5
+ CourseOffering = "CourseOffering"
6
+ CourseSection = "CourseSection"
7
+ Group = "Group"
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ module IMS::LIS
2
+ module ContextType
3
+ module URNs
4
+ CourseTemplate = "urn:lti:context-type:ims/lis/CourseTemplate"
5
+ CourseOffering = "urn:lti:context-type:ims/lis/CourseOffering"
6
+ CourseSection = "urn:lti:context-type:ims/lis/CourseSection"
7
+ Group = "urn:lti:context-type:ims/lis/Group"
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,60 @@
1
+ module IMS::LIS
2
+ module Roles
3
+ module Context
4
+ module Handles
5
+ Learner = "Learner"
6
+ Learner_Learner = "Learner/Learner"
7
+ Learner_NonCreditLearner = "Learner/NonCreditLearner"
8
+ Learner_GuestLearner = "Learner/GuestLearner"
9
+ Learner_ExternalLearner = "Learner/ExternalLearner"
10
+ Learner_Instructor = "Learner/Instructor"
11
+ Instructor = "Instructor"
12
+ Instructor_PrimaryInstructor = "Instructor/PrimaryInstructor"
13
+ Instructor_Lecturer = "Instructor/Lecturer"
14
+ Instructor_GuestInstructor = "Instructor/GuestInstructor"
15
+ Instructor_ExternalInstructor = "Instructor/ExternalInstructor"
16
+ ContentDeveloper = "ContentDeveloper"
17
+ ContentDeveloper_ContentDeveloper = "ContentDeveloper/ContentDeveloper"
18
+ ContentDeveloper_Librarian = "ContentDeveloper/Librarian"
19
+ ContentDeveloper_ContentExpert = "ContentDeveloper/ContentExpert"
20
+ ContentDeveloper_ExternalContentExpert = "ContentDeveloper/ExternalContentExpert"
21
+ Member = "Member"
22
+ Member_Member = "Member/Member"
23
+ Manager = "Manager"
24
+ Manager_AreaManager = "Manager/AreaManager"
25
+ Manager_CourseCoordinator = "Manager/CourseCoordinator"
26
+ Manager_Observer = "Manager/Observer"
27
+ Manager_ExternalObserver = "Manager/ExternalObserver"
28
+ Mentor = "Mentor"
29
+ Mentor_Mentor = "Mentor/Mentor"
30
+ Mentor_Reviewer = "Mentor/Reviewer"
31
+ Mentor_Advisor = "Mentor/Advisor"
32
+ Mentor_Auditor = "Mentor/Auditor"
33
+ Mentor_Tutor = "Mentor/Tutor"
34
+ Mentor_LearningFacilitator = "Mentor/LearningFacilitator"
35
+ Mentor_ExternalMentor = "Mentor/ExternalMentor"
36
+ Mentor_ExternalReviewer = "Mentor/ExternalReviewer"
37
+ Mentor_ExternalAdvisor = "Mentor/ExternalAdvisor"
38
+ Mentor_ExternalAuditor = "Mentor/ExternalAuditor"
39
+ Mentor_ExternalTutor = "Mentor/ExternalTutor"
40
+ Mentor_ExternalLearningFacilitator = "Mentor/ExternalLearningFacilitator"
41
+ Administrator = "Administrator"
42
+ Administrator_Administrator = "Administrator/Administrator"
43
+ Administrator_Support = "Administrator/Support"
44
+ Administrator_Developer = "Administrator/Developer"
45
+ Administrator_SystemAdministrator = "Administrator/SystemAdministrator"
46
+ Administrator_ExternalSystemAdministrator = "Administrator/ExternalSystemAdministrator"
47
+ Administrator_ExternalDeveloper = "Administrator/ExternalDeveloper"
48
+ Administrator_ExternalSupport = "Administrator/ExternalSupport"
49
+ TeachingAssistant = "TeachingAssistant"
50
+ TeachingAssistant_TeachingAssistant = "TeachingAssistant/TeachingAssistant"
51
+ TeachingAssistant_TeachingAssistantSection = "TeachingAssistant/TeachingAssistantSection"
52
+ TeachingAssistant_TeachingAssistantSectionAssociation = "TeachingAssistant/TeachingAssistantSectionAssociation"
53
+ TeachingAssistant_TeachingAssistantOffering = "TeachingAssistant/TeachingAssistantOffering"
54
+ TeachingAssistant_TeachingAssistantTemplate = "TeachingAssistant/TeachingAssistantTemplate"
55
+ TeachingAssistant_TeachingAssistantGroup = "TeachingAssistant/TeachingAssistantGroup"
56
+ TeachingAssistant_Grader = "TeachingAssistant/Grader"
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,60 @@
1
+ module IMS::LIS
2
+ module Roles
3
+ module Context
4
+ module URNs
5
+ Learner = "urn:lti:role:ims/lis/Learner"
6
+ Learner_Learner = "urn:lti:role:ims/lis/Learner/Learner"
7
+ Learner_NonCreditLearner = "urn:lti:role:ims/lis/Learner/NonCreditLearner"
8
+ Learner_GuestLearner = "urn:lti:role:ims/lis/Learner/GuestLearner"
9
+ Learner_ExternalLearner = "urn:lti:role:ims/lis/Learner/ExternalLearner"
10
+ Learner_Instructor = "urn:lti:role:ims/lis/Learner/Instructor"
11
+ Instructor = "urn:lti:role:ims/lis/Instructor"
12
+ Instructor_PrimaryInstructor = "urn:lti:role:ims/lis/Instructor/PrimaryInstructor"
13
+ Instructor_Lecturer = "urn:lti:role:ims/lis/Instructor/Lecturer"
14
+ Instructor_GuestInstructor = "urn:lti:role:ims/lis/Instructor/GuestInstructor"
15
+ Instructor_ExternalInstructor = "urn:lti:role:ims/lis/Instructor/ExternalInstructor"
16
+ ContentDeveloper = "urn:lti:role:ims/lis/ContentDeveloper"
17
+ ContentDeveloper_ContentDeveloper = "urn:lti:role:ims/lis/ContentDeveloper/ContentDeveloper"
18
+ ContentDeveloper_Librarian = "urn:lti:role:ims/lis/ContentDeveloper/Librarian"
19
+ ContentDeveloper_ContentExpert = "urn:lti:role:ims/lis/ContentDeveloper/ContentExpert"
20
+ ContentDeveloper_ExternalContentExpert = "urn:lti:role:ims/lis/ContentDeveloper/ExternalContentExpert"
21
+ Member = "urn:lti:role:ims/lis/Member"
22
+ Member_Member = "urn:lti:role:ims/lis/Member/Member"
23
+ Manager = "urn:lti:role:ims/lis/Manager"
24
+ Manager_AreaManager = "urn:lti:role:ims/lis/Manager/AreaManager"
25
+ Manager_CourseCoordinator = "urn:lti:role:ims/lis/Manager/CourseCoordinator"
26
+ Manager_Observer = "urn:lti:role:ims/lis/Manager/Observer"
27
+ Manager_ExternalObserver = "urn:lti:role:ims/lis/Manager/ExternalObserver"
28
+ Mentor = "urn:lti:role:ims/lis/Mentor"
29
+ Mentor_Mentor = "urn:lti:role:ims/lis/Mentor/Mentor"
30
+ Mentor_Reviewer = "urn:lti:role:ims/lis/Mentor/Reviewer"
31
+ Mentor_Advisor = "urn:lti:role:ims/lis/Mentor/Advisor"
32
+ Mentor_Auditor = "urn:lti:role:ims/lis/Mentor/Auditor"
33
+ Mentor_Tutor = "urn:lti:role:ims/lis/Mentor/Tutor"
34
+ Mentor_LearningFacilitator = "urn:lti:role:ims/lis/Mentor/LearningFacilitator"
35
+ Mentor_ExternalMentor = "urn:lti:role:ims/lis/Mentor/ExternalMentor"
36
+ Mentor_ExternalReviewer = "urn:lti:role:ims/lis/Mentor/ExternalReviewer"
37
+ Mentor_ExternalAdvisor = "urn:lti:role:ims/lis/Mentor/ExternalAdvisor"
38
+ Mentor_ExternalAuditor = "urn:lti:role:ims/lis/Mentor/ExternalAuditor"
39
+ Mentor_ExternalTutor = "urn:lti:role:ims/lis/Mentor/ExternalTutor"
40
+ Mentor_ExternalLearningFacilitator = "urn:lti:role:ims/lis/Mentor/ExternalLearningFacilitator"
41
+ Administrator = "urn:lti:role:ims/lis/Administrator"
42
+ Administrator_Administrator = "urn:lti:role:ims/lis/Administrator/Administrator"
43
+ Administrator_Support = "urn:lti:role:ims/lis/Administrator/Support"
44
+ Administrator_Developer = "urn:lti:role:ims/lis/Administrator/Developer"
45
+ Administrator_SystemAdministrator = "urn:lti:role:ims/lis/Administrator/SystemAdministrator"
46
+ Administrator_ExternalSystemAdministrator = "urn:lti:role:ims/lis/Administrator/ExternalSystemAdministrator"
47
+ Administrator_ExternalDeveloper = "urn:lti:role:ims/lis/Administrator/ExternalDeveloper"
48
+ Administrator_ExternalSupport = "urn:lti:role:ims/lis/Administrator/ExternalSupport"
49
+ TeachingAssistant = "urn:lti:role:ims/lis/TeachingAssistant"
50
+ TeachingAssistant_TeachingAssistant = "urn:lti:role:ims/lis/TeachingAssistant/TeachingAssistant"
51
+ TeachingAssistant_TeachingAssistantSection = "urn:lti:role:ims/lis/TeachingAssistant/TeachingAssistantSection"
52
+ TeachingAssistant_TeachingAssistantSectionAssociation = "urn:lti:role:ims/lis/TeachingAssistant/TeachingAssistantSectionAssociation"
53
+ TeachingAssistant_TeachingAssistantOffering = "urn:lti:role:ims/lis/TeachingAssistant/TeachingAssistantOffering"
54
+ TeachingAssistant_TeachingAssistantTemplate = "urn:lti:role:ims/lis/TeachingAssistant/TeachingAssistantTemplate"
55
+ TeachingAssistant_TeachingAssistantGroup = "urn:lti:role:ims/lis/TeachingAssistant/TeachingAssistantGroup"
56
+ TeachingAssistant_Grader = "urn:lti:role:ims/lis/TeachingAssistant/Grader"
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,22 @@
1
+ module IMS::LIS
2
+ module Roles
3
+ module Institution
4
+ module Handles
5
+ Student = "Student"
6
+ Faculty = "Faculty"
7
+ Member = "Member"
8
+ Learner = "Learner"
9
+ Instructor = "Instructor"
10
+ Mentor = "Mentor"
11
+ Staff = "Staff"
12
+ Alumni = "Alumni"
13
+ ProspectiveStudent = "ProspectiveStudent"
14
+ Guest = "Guest"
15
+ Other = "Other"
16
+ Administrator = "Administrator"
17
+ Observer = "Observer"
18
+ None = "None"
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,22 @@
1
+ module IMS::LIS
2
+ module Roles
3
+ module Institution
4
+ module URNs
5
+ Student = "urn:lti:instrole:ims/lis/Student"
6
+ Faculty = "urn:lti:instrole:ims/lis/Faculty"
7
+ Member = "urn:lti:instrole:ims/lis/Member"
8
+ Learner = "urn:lti:instrole:ims/lis/Learner"
9
+ Instructor = "urn:lti:instrole:ims/lis/Instructor"
10
+ Mentor = "urn:lti:instrole:ims/lis/Mentor"
11
+ Staff = "urn:lti:instrole:ims/lis/Staff"
12
+ Alumni = "urn:lti:instrole:ims/lis/Alumni"
13
+ ProspectiveStudent = "urn:lti:instrole:ims/lis/ProspectiveStudent"
14
+ Guest = "urn:lti:instrole:ims/lis/Guest"
15
+ Other = "urn:lti:instrole:ims/lis/Other"
16
+ Administrator = "urn:lti:instrole:ims/lis/Administrator"
17
+ Observer = "urn:lti:instrole:ims/lis/Observer"
18
+ None = "urn:lti:instrole:ims/lis/None"
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,15 @@
1
+ module IMS::LIS
2
+ module Roles
3
+ module System
4
+ module Handles
5
+ SysAdmin = "SysAdmin"
6
+ SysSupport = "SysSupport"
7
+ Creator = "Creator"
8
+ AccountAdmin = "AccountAdmin"
9
+ User = "User"
10
+ Administrator = "Administrator"
11
+ None = "None"
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ module IMS::LIS
2
+ module Roles
3
+ module System
4
+ module URNs
5
+ SysAdmin = "urn:lti:sysrole:ims/lis/SysAdmin"
6
+ SysSupport = "urn:lti:sysrole:ims/lis/SysSupport"
7
+ Creator = "urn:lti:sysrole:ims/lis/Creator"
8
+ AccountAdmin = "urn:lti:sysrole:ims/lis/AccountAdmin"
9
+ User = "urn:lti:sysrole:ims/lis/User"
10
+ Administrator = "urn:lti:sysrole:ims/lis/Administrator"
11
+ None = "urn:lti:sysrole:ims/lis/None"
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,9 @@
1
+ module IMS::LIS
2
+ module Statuses
3
+ module SimpleNames
4
+ Active = 'Active'
5
+ Deleted = 'Deleted'
6
+ Inactive = 'Inactive'
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ module IMS::LIS
2
+ module Statuses
3
+ module URIs
4
+ Active = 'http://purl.imsglobal.org/vocab/lis/v2/status#Active'
5
+ Deleted = 'http://purl.imsglobal.org/vocab/lis/v2/status#Deleted'
6
+ Inactive = 'http://purl.imsglobal.org/vocab/lis/v2/status#Inactive'
7
+ end
8
+ end
9
+ end
data/lib/ims/lis.rb ADDED
@@ -0,0 +1,14 @@
1
+ module IMS
2
+ module LIS
3
+ require_relative 'lis/context_type/handles'
4
+ require_relative 'lis/context_type/urns'
5
+ require_relative 'lis/roles/institution/handles'
6
+ require_relative 'lis/roles/institution/urns'
7
+ require_relative 'lis/roles/system/handles'
8
+ require_relative 'lis/roles/system/urns'
9
+ require_relative 'lis/roles/context/handles'
10
+ require_relative 'lis/roles/context/urns'
11
+ require_relative 'lis/statuses/simple_names'
12
+ require_relative 'lis/statuses/uris'
13
+ end
14
+ end
@@ -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,11 @@
1
+ module IMS::LTI::Errors
2
+ class AuthenticationFailedError < StandardError
3
+
4
+ attr_reader :response
5
+
6
+ def initialize(response: nil)
7
+ @response = response
8
+ end
9
+
10
+ end
11
+ end
@@ -0,0 +1,4 @@
1
+ module IMS::LTI::Errors
2
+ class InvalidLTIConfigError < StandardError
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module IMS::LTI::Errors
2
+ class InvalidToolConsumerProfile < StandardError
3
+ end
4
+ end
@@ -0,0 +1,15 @@
1
+ module IMS::LTI::Errors
2
+ class ToolProxyRegistrationError < StandardError
3
+ attr_reader :response_status, :response_body
4
+
5
+ def initialize(response_status, response_body = nil)
6
+ @response_status = response_status
7
+ @response_body = response_body
8
+ super <<-EOF
9
+ Unexpected response for tool proxy registration.
10
+ HTTP Response Status: #{response_status}
11
+ HTTP Response Body: #{response_body}
12
+ EOF
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,8 @@
1
+ module IMS::LTI
2
+ module Errors
3
+ require_relative 'errors/invalid_lti_config_error'
4
+ require_relative 'errors/tool_proxy_registration_error'
5
+ require_relative 'errors/invalid_tool_consumer_profile'
6
+ require_relative 'errors/authentication_failed_error'
7
+ end
8
+ 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.nil? || (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,14 @@
1
+ module IMS::LTI::Models
2
+ class ContentItemContainer < IMS::LTI::Models::LTIModel
3
+ add_attribute :context, json_key: '@context'
4
+ add_attribute :graph, json_key: '@graph', relation: 'IMS::LTI::Models::ContentItems::ContentItem'
5
+
6
+ CONTENT_ITEM_CONTAINER_CONTEXT = 'http://purl.imsglobal.org/ctx/lti/v1/ContentItem'
7
+
8
+ def initialize(opts = {})
9
+ super(opts)
10
+ self.context = CONTENT_ITEM_CONTAINER_CONTEXT
11
+ end
12
+
13
+ end
14
+ end
@@ -0,0 +1,20 @@
1
+ module IMS::LTI::Models
2
+ class ContentItemPlacement < LTIModel
3
+
4
+ DOCUMENT_TARGETS = {
5
+ embed: 'http://purl.imsglobal.org/vocab/lti/v2/lti#embed',
6
+ frame: 'http://purl.imsglobal.org/vocab/lti/v2/lti#frame',
7
+ iframe: 'http://purl.imsglobal.org/vocab/lti/v2/lti#iframe',
8
+ none: 'http://purl.imsglobal.org/vocab/lti/v2/lti#none',
9
+ overlay: 'http://purl.imsglobal.org/vocab/lti/v2/lti#overlay',
10
+ popup: 'http://purl.imsglobal.org/vocab/lti/v2/lti#popup',
11
+ window: 'http://purl.imsglobal.org/vocab/lti/v2/lti#window'
12
+ }
13
+
14
+ add_attribute :display_height, json_key: 'displayHeight'
15
+ add_attribute :display_width, json_key: 'displayWidth'
16
+ add_attribute :window_target, json_key: 'windowTarget'
17
+ add_attribute :presentation_document_target, json_key: 'presentationDocumentTarget'
18
+
19
+ end
20
+ end
@@ -0,0 +1,32 @@
1
+ module IMS::LTI::Models::ContentItems
2
+ class ContentItem < IMS::LTI::Models::LTIModel
3
+
4
+ add_attributes :text, :title, :url, :confirmUrl
5
+ add_attribute :media_type, json_key: 'mediaType'
6
+ add_attribute :type, json_key: '@type'
7
+ add_attribute :id, json_key: '@id'
8
+ add_attribute :icon, relation: 'IMS::LTI::Models::Image'
9
+ add_attribute :placement_advice, json_key:'placementAdvice', relation: 'IMS::LTI::Models::ContentItemPlacement'
10
+ add_attribute :thumbnail, relation: 'IMS::LTI::Models::Image'
11
+
12
+ TYPE = "ContentItem"
13
+
14
+ def initialize(attributes = {})
15
+ super(attributes)
16
+ self.type = TYPE
17
+ end
18
+
19
+ def self.from_json(json)
20
+ data = json.is_a?(String) ? JSON.parse(json) : json
21
+ case data['@type']
22
+ when 'FileItem'
23
+ FileItem.new.from_json(data)
24
+ when 'LtiLinkItem', 'LtiLink'
25
+ LtiLinkItem.new.from_json(data)
26
+ else
27
+ ContentItem.new.from_json(data)
28
+ end
29
+ end
30
+
31
+ end
32
+ end
@@ -0,0 +1,15 @@
1
+ module IMS::LTI::Models::ContentItems
2
+ class FileItem < ContentItem
3
+
4
+ add_attribute :copy_advice, json_key: 'copyAdvice'
5
+ add_attribute :expires_at, json_key: 'expiresAt'
6
+
7
+ TYPE = "FileItem"
8
+
9
+ def initialize(attributes = {})
10
+ super(attributes)
11
+ self.type = TYPE
12
+ end
13
+
14
+ end
15
+ end
@@ -0,0 +1,14 @@
1
+ module IMS::LTI::Models::ContentItems
2
+ class LtiLinkItem < ContentItem
3
+
4
+ add_attributes :custom
5
+
6
+ TYPE = "LtiLinkItem"
7
+
8
+ def initialize(attributes = {})
9
+ super(attributes)
10
+ self.type = TYPE
11
+ end
12
+
13
+ end
14
+ end