ims-lti 1.2.4 → 2.2.3

Sign up to get free protection for your applications and to get access to all the features.
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 +13 -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 +222 -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 +11 -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 +266 -44
  101. data/Changelog +0 -54
  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 -216
  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 -225
  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
- SHA256:
3
- metadata.gz: 224820ab40ce08a13bfda880f3107740a2b46cd31f672719b72d1d8e8cf3cc50
4
- data.tar.gz: b0c4c73930312bd6a27c7d6c8ea74b9dd33d83fd8cf8d240db14ea2b3e27e29f
2
+ SHA1:
3
+ metadata.gz: 1ecba7e383b26f256f513d977ce7a1a5ddc6cf4d
4
+ data.tar.gz: cbb2dcd2d373cb968b72d8ec689d6d1bb4e1b8df
5
5
  SHA512:
6
- metadata.gz: 4d787b098d9fe7b9dba586cf77eff9d3a76cb31697685f29d5cd9f8add1d2950a8ac55385d1419a27559e688f1629f11ce33e394bb24191e447d6876a3b692fd
7
- data.tar.gz: 4f0b4d72b52cd2ad3b936da67d64709734194c6dd321f4883b91131a8625e33193b40ed804d3ea1d633bf254fb3c9656829d04450ad26ca250899dfaf43799de
6
+ metadata.gz: 1eee3ca7972a1c446be5e4a0abb85eba9c6aed471af0891c6cfad4999a876393349a89adbf84865e401b77732bd8da7bec9803adbb4e7d6fd054675a7f99bb49
7
+ data.tar.gz: ef39d166b973161e51f2b91f01e39a26e26fe71fdde1ecee3d4f37f178db9bc5a9bdbf8b04afe9923385862bcea0b162a6ef23ce967778b11792ea0ea773108e
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