Enabling LTI Provider in tutor

I’m trying out a fresh tutor install using the default local docker install. Part of what I want to evaluate is the LTI provider capability.

To enable this, I tried doing it the “right” way for tutor, by creating a plugin with the following code, enabling the plugin, saving the config, and restarting tutor:

from tutor import hooks


When I enabled the plugin and restarted, I’m getting the following error:

Model class lms.djangoapps.lti_provider.models.LtiConsumer doesn't declare an explicit app_label and isn't in an application in INSTALLED_APPS.

This seems to indicate that perhaps it isn’t enabling the LTI provider app completely? When I enable it by editing lms.env.yml directly and adding “ENABLE_LTI_PROVIDER: true” to FEATURES, it worked fine, and I was able to run the DB migrations and get everything working.

Is there some other step that I’m missing to enable this the “right” way?

This is a bit of a shot in the dark, but did you try using the lms-env-features patch?

from tutor import hooks

        "ENABLE_LTI_PROVIDER: true"
1 Like

In tutor when overriding a featuer it’s important to note it should done at the env level, e.g. use a patch that shall mutate lms.env.yml or cms.env.yml This important because some featuers require furter settings/configuration to be applied for instance ENABLE_LTI_PROVIDER requires to install/add djnagoapps hence your error and this:


ref: edx-platform/production.py at d111be537519dc78b8604c6eebfd0c4e992c97b2 · openedx/edx-platform · GitHub
In the other words the above code wouldn’t run/evalute if you change it at the settings level but on config level (as suggested above by @michael) would make it evaluate.

And lastly some featuer requires other setup, may be you already aware of but just in case refer to this.

1 Like

I think that @ghassan’s answer is the right one.

@rael9 How did your evaluation of Open edX as an LTI provider go? Do you think that this feature should be enabled by default? If yes, we should make a change in Tutor.

Hi @rael9! I am also looking in to the LTI Provider functionality, I enabled it with a simple yaml plugin and was able to get things working with the anonymous authentication.

However, now I am stuck on trying to set up TPA for LTI, is that something you are looking into as well? Were you able to make that work? I also tried asking in the #lti channel in Slack but discussions there seem to be more focused on the Consumer XBlock and I haven’t gotten any replies yet :confused:

Thanks @regis. I’m still working on it at the moment, but will update with my results. I’m not sure how often LTI gets used in reality, it’s hard to judge based on internet chatter. I would think there’s probably been a bit of an uptick in interest after the last couple of years, but I don’t know what the future holds.

Maybe it would be a good idea to allow any of the “batteries included” features of Open edX to be enabled in the tutor config.yml?

Thanks @michael, I think that’s probably correct. I’ll try that today. I was going off of the plugin tutorial for tutor, and didn’t see that patch.

I haven’t tried setting up TPA yet, @mrtmm. I’m uncertain if we’ll need it for our project, as things are still up in the air as to how we’re going to implement everything. What sort of issues are you having setting it up?

Hi @rael9, I can get as far as the docs go about testing the TPA Provider I guess.

I use saLTIre: LTI Platform emulator and http://{your_URL}/auth/login/lti/ as the URL but I am not sure where to go from that.
If I log in with credentials to an existing account in the provider platform there, my account does get the LTI TPA provider linked under account/settings. If relaunch the same request I get logged in with the linked user and land on the dashboard, just as the docs say.

However, if I then try to display any content on that platform with the same user info, I get a white page. From logs I can see:

2022-09-27 15:43:49,990 INFO 23 [oauthlib.oauth1.rfc5849.endpoints.signature_only] [user None] [ip] signature_only.py:81 - [Failure] request verification failed.
2022-09-27 15:43:49,990 INFO 23 [oauthlib.oauth1.rfc5849.endpoints.signature_only] [user None] [ip] signature_only.py:82 - Valid client: False
2022-09-27 15:43:49,990 INFO 23 [oauthlib.oauth1.rfc5849.endpoints.signature_only] [user None] [ip] signature_only.py:83 - Valid signature: False
[pid: 23|app: 0|req: 132/464] () {48 vars in 1089 bytes} [Tue Sep 27 15:43:49 2022] POST /lti_provider/courses/{course_id}/{usage_id} => generated 0 bytes in 33 msecs (HTTP/1.1 403) 7 headers in 263 bytes (1 switches on core 0)

After linking the accounts, I am using the URL https://{host}/lti_provider/courses/{course_id}/{usage_id} that works fine with the anonymous authentication.
I have tried various configurations in the LTIProviderConfig, but it’s still unclear to me how this is supposed to work.
I would be curious if there is a way to successfully authenticate an existing user or register a new user on the provider platform and display some content with one request, perhaps using the tpa-hinted links?
How can I display some more specific content for the linked user, other that just the dashboard?