---
# System prepended metadata

title: A+ LTI integration

---

# A+ LTI integration
## 14.2.2022
### State of LTI on A+ now

- "consumer" (= platfrom) with LTI version 1.1. (?) (rubyric thingy?)
- So far the A+ - MyCourses integration done via a plugin called Astra: https://github.com/apluslms/moodle-mod_astra/blob/master/astra/README.md

### What state LTI on A+ should be in

- both *platform* (= consumer) and *tool* (= provider) for LTI version 1.3.
    - *tool* for MyCourses to be able to import exercises / other course material; this is the more time-critical case to maintain existing functionality
    - *platform* for being able to import exercises / material from other services into A+
- Background & other info by Anni: https://wiki.aalto.fi/pages/viewpage.action?pageId=175521118

### Timeframe

- Mycourses is updated to Moodle4 in summer which probably breaks Astra => A+ should be at least LTI tool before that
- Pasi mentioned that we could do a minimal POC first but unsure what the POC should contain, like POC for LTI overall or LTI for some mock A+ or what

### Things that are still unclear to us

- how difficult/time consuming this thing actually is
    - according to EDIT pretty time consuming?
    - according to skimming some stuff and eyeballing the problem not that time consuming?
    - can we/should we make any promises regarding timeframes
        - Not on thursday, but ofc as soon as we know better

### Things that should be clear to us on thursday so we can tell EDIT something

- Whether CS-IT takes over the task
    - yes
    - who in CS-IT does stuff for it, I suppose at least Markus and probably MikkoM depending on what stuff comes up/if the workload is something that can be somewhat naturally divided

## 17.2.2022

- Meeting on Wed 23rd for details regarding implementation

## 23.02.2022

- Setting up dev env
    - Moodle container in the aplus dev env docker-compose.yml 
- Where should code be (own directory?)
    - lti_tool dir or such
    - some /launch_lti url
    - 
- Resources for moodle:
    - https://github.com/apluslms/run-moodle-astra
    - https://hub.docker.com/r/apluslms/run-moodle-astra
    - (https://github.com/moodlehq/moodle-docker)
    - https://github.com/apluslms/run-moodle-astra/blob/master/docker-compose-moodle.yml

- Initial POC
    - Just login, if possible
    - If not, then some simple lti tool launch

## 08.03.2022 thoughts / open questions

- Use `ExercisePlainView.as_view()` to render an exercise
    - hacky `request.method = 'GET'` currently - is there a way to force the GET behaviour?
- User registration + enrollment on lti launch? Is enrolment required or can a generic "LTI User" or such be used?
    - Register + enroll probably, since then remaining submissions etc can be tracked
- Storing exercise results on A+ side: y/n?
    - Probably yes - otherwise find out mechanic on moodle side to track submissions (messy)
- Recognizing users - email or username? (username is in LTI message params .../claim/ext --> user_username )
- Should LTI users be matched to users logged in through Aalto/HAKA logins?
- Specifying the level of embedded content (e.g. course, module, exercise)
- Do all requests start from lti_launch() and branch from there?
- Are class based views better in the long run?
- Are courses that are used in an LTI context to only be available through LTI, or also through the main A+ UI? Should the same student be able to complete a course using both UIs?
- How does current astra solution setup stuff on moodle side?

Relevant files/functions for above thoughts:
- exercise/views.py: ExerciseView.get(), ExercisePlainView

## 14.03.2022 meeting

- Astra has automatic course import
    - 1 A+ module = 1 moodle activity
- LTI version: iframes / new windows / whatever with content generated by A+
- Save exercise results etc on A+ side. If points to be saved in moodle, it's mostly an extra offthought feature
- Match users moodle - A+
    - Note: many users can have the same email; google user, A+ aalto user. Prefer A+ aalto user
    - If user does not exist in A+ side, create new aalto user
    - get username, student number if possible

## 16.03.2022 content selection testing

- Tried to get the "Select content" thing working since UX is fun
- Turns out this is essentially the "Deep Linking" part of the LTI specification, pyLTI has functions for handling this
- After a lot of struggle got (again hardcoded) stuff working, meaning config fields will be pre-populated, and user does not have to know course codes and whatnot (once user actually able to select stuff)
    - The private and public keys configured need to be in a PKCS8 format, NOT PKCS1 - e.g. "BEGIN PRIVATE KEY", and NOT "BEGIN RSA PRIVATE KEY". Moodle's php thing is unable to parse if in PKCS1.
    - See e.g. https://stackoverflow.com/questions/44474516/how-to-create-public-and-private-key-with-openssl to generate correct format key pair

## 17.03.2022 LTI "login", sessions

- User from the LTI launch params can be logged in with login(request, user) (once user has been created / matched with existing). Sets necessary session params etc.
- Sessions can be used to store LTI launch ID, which in turn can be used to access the rest of the launch data
    - https://github.com/dmitry-viskov/pylti1.3#accessing-cached-launch-requests
    - this will be needed on content selection - the launch request will return content selection form, which will be submitted to A+ to another endpoint, which will access the launch data based on launch id, and return the auto-submitted form (https://github.com/dmitry-viskov/pylti1.3#accessing-cached-launch-requests)
    - not sure if required in normal use e.g. browsing course content and submitting, but good to know anyway

## 18.03.2022 CS-IT meeting

- Definition of done? Discuss with EDIT

## 21.03.2022

- Cookies + iframe = sad. Seems like `SESSION_COOKIE_SAMESITE = "None"` would be required in iframe embeds. Not sure. Just making note here if later wondering why submissions don't work.
- Not sure how to do branching sub class views with same url. Can do with different urls but same url would be cool.
- TODO: "no permission to see this content" - something with access_mode stuff? Missing some attribute / method?
- TODO: Navigation within the content selection

## 22.03.2022

- Adventures in A+ View/Mixin inheritance tree
- Figured that instead of responding to the initial LTI launch post requests with the templates, should redirect to another view
    - Makes more sense in that the redirects will be GET requests, allowing for better re-use of existing code
    - Can also fan out to different views depending on launch type, e.g. deep link / resource launch, and whether course, module, or exercise is requested
- Pondering about whether to replicate some of the relevant A+ url pattern configs, or to redirect to the existing urls altogether
- Replication:
    - Less bloat in "main" functionality
    - Able to inherit existing views
    - More url bloat? Not necessarily problem
- Existing urls:
    - Less redundant work
    - More complexity in main code

## 11.04.2022

- Submitting exercises via POST to new url /lti/{course}/{module}/...
    - ExerciseView.post(): Submission.get_absolute_url() redirects to non-lti version. Tried to set ABSOLUTE_URL_NAME to a @property method, and to save lti/no-lti status in Submission.meta_data, to fetch desired page
    - Above has the issue that if the same submission is fetched from A+ interface, it would show the LTI version which is probably not desired
    - Thus the LTI/no-lti page decision should be made depending on the request (is LTI session or isn't)
    - Requires either stabbing ExerciseView.post() or overriding the method
    - Latter requires further knowledge about ExercisePage and different ways of submitting exercises
    - Look into `url` templatefilter and its params - e.g. in submissions list there's {% submission | url %} which could be {% submission | url:urltemplateparam %}, with the param having some default and just being overridden in Lti-versions of views

## Meeting with EDIT start of May

- Questions
    - Use case examples?
    - List of desired features?

- Up next
    - Assignments & grades service e.g. getting grades from A+ to moodle
    - Teacher demo of what's been done so far
    - Check "view as role" settings in regards to enrollments (teachers enrolled as students by accident?)

06.06.2022 Demo meeting with teachers/AaltoIT

- Courses that should be imported by multiple people on different (moodle) courses
    - Should probably have separate A+ course instances per moodle course

TODO: Save LTI launch id on submission