├── README.md └── lms_lrs.md /README.md: -------------------------------------------------------------------------------- 1 | launch 2 | ====== 3 | 4 | Incorporating a TinCan LRS into an LMS 5 | 6 | 7 | ## License 8 | Licensed under the 9 | Creative Commons Attribution 3.0 License 10 | ![CC License Icon](https://i.creativecommons.org/l/by/3.0/88x31.png) 11 | -------------------------------------------------------------------------------- /lms_lrs.md: -------------------------------------------------------------------------------- 1 | ## Incorporating a TinCan LRS into an LMS 2 | 3 | If you are not familiar with Project Tin Can, the TinCan API, and the term LRS, please 4 | refer first to the [Tin Can API specification](http://www.adlnet.gov/wp-content/uploads/2013/05/20130521_xAPI_v1.0.0-FINAL-correx.pdf). 5 | 6 | Since an LRS is meant to be a component with limited but well defined capabilities, we 7 | expect that in many cases it will be desirable to integrate an LRS into an LMS, and that 8 | it will be beneficial to define expected behaviors for such an LMS. This document was 9 | created to define those expected behaviors without cluttering the core LRS 10 | documentation. 11 | 12 | In particular, content packaging, launch, and import should be defined for an LMS, but 13 | not for an LRS -- it just stores and retrieves learning records, not content. 14 | 15 | 16 | ### Packaging 17 | 18 | Content, activity definitions, and activity provider definitions may be packaged for 19 | TinCan. The primary object being packaged is always activity definitions. It is valid to 20 | create a package that contains only activity definitions, however content and activity 21 | provider definitions may only be packaged with an associated activity definition. 22 | 23 | A TinCan package must always include a TinCan metadata file, this is a file named 24 | “tincan.xml”, conforming to the TinCan 25 | schema. If not including content, this file 26 | itself may be used as the TinCan package. If content is to be included, then this file 27 | must be placed into a zip file with the content. 28 | 29 | A TinCan package must contain exactly one “tincan.xml” file. The location of the 30 | “tincan.xml” file is considered the “root” of the package. All files within the package 31 | should be under the root. So, it is valid for tincan.xml to be in a nested directory 32 | structure within the zip, but only if every directory above it contains nothing but a 33 | single sub-directory. 34 | 35 | If HTML files are included in the content package, they may link to each other, or other 36 | resources within the package, using relative paths based on the package structure. They 37 | may also link to external resources using absolute paths. 38 | 39 | ### Activity Definition 40 | 41 | The activity definition section of tincan.xml maps to the activity definition defined in 42 | the TCAPI document, with the exception of “launch” and “resource”. 43 | 44 | Launch is an absolute or relative path to a document which can be launched by the LMS in 45 | a web browser in order to “deliver” this activity. 46 | 47 | Resource is an absolute or relative path to something that a person can either read or 48 | download which will enable them to experience this activity, for example: an application 49 | to run, a video to view, or directions to a physical location for an event. 50 | 51 | __Only one activity definition within a package may contain launch or resource elements.__ 52 | This limitation should be lifted in future TinCan versions but the implementation 53 | consequences of multiple launchable activities per package need more thought first. 54 | 55 | __NOTE:__ Activities do not have a hierarchy, and are declared as a flat list. Any 56 | hierarchical context must be reported by the activity provider, using the “context” 57 | portion of each statement. (if that context is to be preserved). If emulating a 58 | traditional SCORM package using TinCan, consider adding a “grouping” activity to each 59 | statement, which corresponds to your “root of the activity tree”, and also a “parent” 60 | activity. 61 | 62 | ### Activity Provider Definition, activity groups. 63 | 64 | The tincan.xml file includes one or more groups of activities. The reason for breaking 65 | up activities into groups is to enable defining different authorized activity providers 66 | for each group. Each group of activities has a “provider” section, which MAY be used to 67 | declare to the LMS/LRS what applications (activity providers) should be allowed to 68 | report statements about each group of activities. The elements in this section reflect 69 | the information that must be registered during the OAuth application registration 70 | process, and provide a way to get this information into an LMS without the administrator 71 | having to go through a registration UI. 72 | 73 | The schema for tincan.xml is: http://projecttincan.com/tincan.xsd 74 | 75 | tincan.xml doesn't have to have all activity IDs that will be used in it, what it should 76 | have is: 77 | 78 | 1) The activity ID that is considered the root activity for this package, along with a 79 | launch link, so the LMS knows what to launch. 80 | 81 | 2) Any activity details (such as activity descriptions) that should be available to 82 | reporting systems, but will not be (or may not be) sent by the activity provider when 83 | reporting statements. That is, tincan.xml may be used to describe activities to the LRS, 84 | as an alternative to doing that description at runtime. 85 | 86 | ### Import 87 | 88 | When importing a TinCan package, all the content, activity definitions, and activity 89 | provider definitions in the package will be imported. 90 | 91 | If any activity definitions are loaded then all the files within the package starting 92 | from the “root”, and excluding the file “tincan.xml”, must be placed in an accessible 93 | location by the LMS. For any activity definitions that have “launch” or “resource” 94 | defined, the LMS will store those values as activity profile entries in its associated 95 | LRS. Any relative URLs will be transformed into absolute URLs based on the location the 96 | LRS stored the content. 97 | 98 | ### Language / Internationalization 99 | 100 | Many of the entries in the TinCan schema have an xml:lang attribute. Where the language 101 | of the associated entry is known, it should be declared. Where an entry is available in 102 | multiple languages, it should be repeated for each language. If the language is unknown, 103 | then the attribute should be left blank. 104 | 105 | 106 | ### Launch 107 | 108 | TinCan APs(?) do not need to be launched from an LMS, however it is still an option. When 109 | an LMS launches a Tin Can AP, it will provide the necessary information for that AP to 110 | track back to the LRS (endpoint, learner information, credentials, and optionally 111 | registration, activity ID, platform,language, and grouping). The format of the launch 112 | URL will be as follows: 113 | 114 | ``` 115 | /?endpoint=&auth=&actor=[®istration=][&activity_id=[&activity_platform=][&Accept-Language=][&grouping=] 116 | ``` 117 | 118 | Note that some of the parameter values include reserved characters, and even other 119 | URLS, and therefore must be URL encoded. 120 | 121 | Example launch link (shown without URL encoding and with line breaks for readability): 122 | 123 | ``` 124 | http://example.scorm.com/TCActivityProvider/ 125 | ?endpoint=http://example.scorm.com/lrs/ 126 | &auth=OjFjMGY4NTYxNzUwOGI4YWY0NjFkNzU5MWUxMzE1ZGQ1 127 | &actor={ "name" : ["Project Tin Can"], "mbox" : ["mailto:tincan@scorm.com"] } 128 | ®istration=760e3480-ba55-4991-94b0-01820dbd23a2 129 | &activity_id=http://example.scorm.com/tincan/example/simplestatement 130 | ``` 131 | 132 | Partial launch information may also be provided by an LMS in the form of a launch link, 133 | which may consist of only endpoint information, or may include learner information but 134 | not credentials. In this case, the AP would have to have been configured with or prompt 135 | for the necessary information. 136 | 137 | The LMS should specify Accept-Language, if it knows the learner’s language preferences. 138 | Except for its location in the query string instead of the header, Accept-Language 139 | should be constructed and interpreted according to 140 | RFC 2616 (HTTP 1.1). 141 | 142 | The LMS should specify a grouping activity if the activity being launched is considered, 143 | by the LMS, to be part of a larger group of activities for reporting purposes. The 144 | grouping activity specified should then be added to the context of each statement the 145 | activity being launch reports, so that these statements can later be identified as all 146 | being related to the grouping activity. 147 | 148 | The LMS should specify a registration on a launch link if the launch is logically part 149 | of an LMS “registration”. The Activity Provider will then store the specified 150 | registration in context when reporting statements. 151 | 152 | Any parameters that are not defined here which are passed on a launch link should be 153 | echoed back to the LRS when reporting statements associated with that launch. This 154 | allows an LMS that is integrated with an LRS to pass through additional context 155 | information. 156 | 157 | If no launch information is provided, then the AP must minimally be configured with the 158 | LRS endpoint it should track to. The AP may also be configured with credentials from the 159 | LRS, in which case credentials need not be obtained for each learner. 160 | 161 | If launch refers to an activity with associated protected content, the launch link will 162 | include additional parameters to support access to that protected content. (see 163 | Private Content Access and Tin Can 164 | 165 | ### OAuth 166 | 167 | If the activity being launched has an associated registered OAuth application with the 168 | LMS, the LMS should not include an “auth” parameter in the launch link. The Activity 169 | Provider / OAuth application is expected to authenticate using OAuth, which may involve 170 | asking the learner to re-authenticate. 171 | 172 | ### Other Scenarios 173 | 174 | The process of getting launch information from an LMS to an AP in a manner other than a 175 | launch link (URL) is not defined. Although it is a goal of the Tin Can API to support out of 176 | browser scenarios, this is supported by allowing the AP to pass information to a LRS 177 | about learners and activities that have not been previously defined in the LRS. That is, 178 | out of browser scenarios are supported by removing the requirement for the LRS to launch 179 | the activity. Minimally, the AP must be configured with the LRS endpoint, and usually 180 | will also need authentication credentials. 181 | 182 | 183 | 184 | ### Private Content Access and TinCan 185 | 186 | This section describes a companion specification to the Tin Can API for the purpose of 187 | gaining access to content that is stored on an LMS, but which requires authentication to 188 | retrieve. This is needed since even though TinCan allows tracking of experiences for 189 | which the content is not stored on an LMS, or for which there is no traditional content, 190 | the LMS is still a convenient place to store the content associated with a learning 191 | experience. Since TinCan does not require an active browser session, the content may no 192 | longer be retrieved by relying on that session. 193 | 194 | Since the problem is accessing content which is stored on an LMS, and to avoid the need 195 | for a complex permissions scheme, this access method will apply only to content that has 196 | been uploaded in a TinCan package, and only where the accessor of that content has been 197 | launched using a TinCan launch link. 198 | 199 | In addition to the launch link parameters described in the launch 200 | section, the following parameters will be provided as needed: 201 | 202 | * __content_token:__ The authorization token to be included on requests to the content 203 | endpoint. If missing, the content is not protected and must be accessed directly. 204 | 205 | * __content_endpoint:__ the absolute URL to use to access protected content. If content token 206 | is specified, but the endpoint is not, the TCAPI endpoint, with the postfix “content/” 207 | is to be used as the content endpoint. 208 | 209 | When a client application needs to access a protected resource, it will first determine 210 | the path to the protected resource based on the content endpoint, and the relative path 211 | of the protected resource within the Tin Can package. 212 | 213 | For example, in the Golf Example TinCan package, there is a resource 214 | ‘Etiquette/distracting.jpg’. If the content endpoint is: 215 | https://example.com/TCAPI/content/, then the following path would be built to access 216 | this protected resource, and the specified content_token is added to that URL. It should 217 | not be necessary to merge the content token with other query string parameters, as even 218 | though content may use query string parameters when loaded to determine how to behave, 219 | they should not be necessary for retrieving a resource from the server. Note that this 220 | methodology works for retrieving 1 resource at a time, an HTML document loaded in this 221 | way which includes relative paths would have broken links. 222 | 223 | https://example.com/TCAPI/content/Etiquette/distracting.jpg?content_token=b50607fb-956e- 224 | 429f-b89e-388c43dbbbcf 225 | 226 | The client may then issue an HTTP GET to this URL to access the resource. 227 | 228 | In order to retrieve an entire content package, the content endpoint would be combined 229 | with the content token, with no additional path information. So the following URL would 230 | retrieve the entire content package, in zip format: 231 | https://example.com/TCAPI/content/?content_token=b50607fb-956e-429f-b89e-388c43dbbbcf 232 | 233 | The server will not enforce any authentication scheme on the content endpoint, except 234 | validation of the content token. The content token will serve both the validate the 235 | request, and look up what TinCan package the request is associated with. The content 236 | token will remain valid as long as the ‘auth’ parameter sent in the launch link remains 237 | valid. 238 | 239 | Upon receiving a request on the content endpoint, and validating the content token, it 240 | is recommended that the server issue a 301 redirect to the URL on the LMS where the 241 | content may be accessed, and include on the URL a signature that the LMS will recognize 242 | to allow access to the content. 243 | 244 | If the above behavior is not practical, the server must instead handle GET, HEAD (should this be READ?), and 245 | OPTIONS requests according to the HTTP 1.1 specification, as if the server was hosting 246 | the content at the specified URL. Note that this includes properly supporting headers 247 | such as ETag, Range, if-*, etc. 248 | 249 | The behavior described above is intended to allow clients to access individual protected 250 | resources without implementing any TinCan behavior. For example, this is important in 251 | order to enable handing off a URL to a video player, that player needs only support 252 | HTTP, it does not need to have any Tin Can specific logic. It will be still be necessary 253 | for the TinCan client application to generate the correct URL for each protected 254 | resource. So a resource which when loaded then refers to other resources (such as a web 255 | page), must be loaded by a client with additional logic to fix those links. 256 | --------------------------------------------------------------------------------