Integrating MIT Applications with Open edX using Tutor
Application | PORT | Domain |
---|---|---|
MITxPro | 8053 | xpro.odl.local |
MITxOnline | 8013 | mitxonline.odl.local |
In order to create user accounts in Open edX and permit authentication from MIT Application to Open edX, you need to configure MIT Application as an OAuth2 provider for Open edX.
These instructions should work for a Tutor Dev or Tutor Nightly deployment as well. Specify `--tutor-dev` instead of `--tutor` when running `configure_instance` so the URLs have a port on them.
Preliminary Step
pyenv
(and pyenv-virtualenv
) are highly recommended for managing local Python versions. Use the instructions on their GitHub page to install if you haven’t already installed it.
You’ll want to create at least a virtualenv for Tutor. As of this writing, Tutor uses Python 3.8.12 (in the LMS container at least); I have also successfully used 3.9.16. 3.11 has not worked for me.
Tutor Setup, Part One
Note that no hosts file changes are needed if you use the default `local.openedx.io` domain - that's a real domain with a wildcard subdomain cname that points to 127.0.0.1.
To begin, you need to follow the Installing Tutor for development instructions provided by Tutor for local development installations. Do this with your Tutor virtualenv activated.
Once Tutor has bootstrapped itself and is available, create a superuser account:
tutor dev do createuser --staff --superuser edx edx@example.org
Supply a password (the one used by devstack is edx
so use that if you want to be consistent with it).
Create a service worker for MITx Application
tutor dev do createuser --staff mit_Application_serviceworker service@mitx.odl.local
Supply a password (this one doesn’t matter for a local deployment, you won’t ever actually use the account).
For MITxOnline Only
For best results, create two new courses within edX. The MITxOnline configure_instance
command expects a couple of courses to exist in edX (because they come with the devstack package):
Course ID | Course Title |
---|---|
course-v1:edX+DemoX+Demo_Course | Demonstration Course |
course-v1:edX+E2E-101+course | E2E Test Course |
If you have a devstack instance handy, you can export these and import them into Tutor. Otherwise, just create them and make sure to set dates for the courses (they default to 2030 otherwise).
Configure Open edX user and token for use with MITx Application management commands
- In Open edX, under
http://local.openedx.io:8000/admin/oauth2_provider/accesstoken/
add access token with that newly created staff user.
MIT Application Setup
To set up MIT Application:
- Get the gateway IP for the
EDX_APP
- Linux users: The gateway IP of the docker-compose networking setup for edx LMS
docker network inspect tutor_dev_default | grep Gateway
. - OSX users: Use
host.docker.internal
- Linux users: The gateway IP of the docker-compose networking setup for edx LMS
-
Set up your
.env
file. These settings need particular attention:OPENEDX_IP
: set to the gateway IP from the first step.OPENEDX_API_BASE_URL
: set tohttp://<EDX_HOSTNAME>:<PORT>
OPENEDX_SERVICE_WORKER_USERNAME
: set tomit_Application_serviceworker
(unless you changed this)OPENEDX_SERVICE_WORKER_API_TOKEN
: set to the token you just generated
Run the configure_instance command
docker-compose run --rm web ./manage.py configure_instance linux --gateway <ip> --tutor-dev
Where <ip>
is the IP from the first step.(On macOS, specify macos instead of linux. You can also skip –gateway.) You will need to supply passwords for the MITx Application superuser and test learner accounts. Make a note of the client ID and secret that it will print out at the end.
Tutor Setup, Part Two
Note that some of these steps require editing the main configuration files for the production instance (which is also used for a local deployment). Most of the settings that need to be adjusted to get integration working are overridden by the default Tutor configuration, so you can’t update them by setting config.yml
. If you’re using the development Tutor build, you’ll likely need to edit development.py
rather than production.py
as necessary.
These steps will also disable the AuthN SSO MFE, so from here on you’ll get normal edX authentication screens (if you’re not being bounced to MITx Application).
-
Get the gateway IP of the
mitxApplication_default
Docker network. Example:docker network inspect mitxpro_default | grep Gateway
- Log into to edX using your superuser account, and make sure your session stays open. Sessions are pretty long-lived so this just means not closing the browser that you started the session in. (Part of this process will involve mostly breaking authentication so it’s important that you are able to get into the admin.)
- Stop Tutor:
tutor dev stop
-
Add extra requirements required for OAuth Configuration:
tutor config save --append OPENEDX_EXTRA_PIP_REQUIREMENTS=social-auth-mitxpro tutor config save --append OPENEDX_EXTRA_PIP_REQUIREMENTS=openedx-companion-auth
NOTE: Reference for Installing extra xblocks and requirements
-
If you have cloned and mounted
edx-platform
while setting up the Tutor, do this step and skip steps 6, 7, and 8. You can createprivate.py
file atedx-platform/lms/envs/{here}
and add the following configurations to allow additional OAuth providersfrom .production import AUTHENTICATION_BACKENDS, FEATURES, IDA_LOGOUT_URI_LIST, REGISTRATION_EXTRA_FIELDS FEATURES["ALLOW_PUBLIC_ACCOUNT_CREATION"] = True FEATURES["SKIP_EMAIL_VALIDATION"] = True REGISTRATION_EXTRA_FIELDS["country"] = "hidden" THIRD_PARTY_AUTH_BACKENDS = ["social_auth_mitxpro.backends.MITxProOAuth2",] AUTHENTICATION_BACKENDS = list(THIRD_PARTY_AUTH_BACKENDS) + list(AUTHENTICATION_BACKENDS) IDA_LOGOUT_URI_LIST = list(IDA_LOGOUT_URI_LIST) + list(["http://{Domain}:{PORT}/logout"]) SOCIAL_AUTH_OAUTH_SECRETS = { "mitxpro-oauth2": <mit_app_client_secret> // you just copied from configure_instance command output }
-
Change into the configuration root for Tutor:
cd "$(tutor config printroot)"
-
Edit the
env/apps/openedx/config/lms.env.yml
file and add:FEATURES: ALLOW_PUBLIC_ACCOUNT_CREATION: true SKIP_EMAIL_VALIDATION: true
The
FEATURES
block (should be at the top). -
Edit the
env/apps/openedx/settings/lms/development.py
settings file.-
Add to the end of the file:
THIRD_PARTY_AUTH_BACKENDS = ['social_auth_mitxpro.backends.MITxProOAuth2']
REGISTRATION_EXTRA_FIELDS["country"] = "hidden"
AUTHENTICATION_BACKENDS.append('social_auth_mitxpro.backends.MITxProOAuth2')
SOCIAL_AUTH_OAUTH_SECRETS = {"mitxpro-oauth2": <MIT_Client_Secret> }
- Client Secret that you just copied afterconfigure_instance
management commandIDA_LOGOUT_URI_LIST.append('http://{Domain}:{PORT}/logout/')
-
Find and update:
FEATURES['ENABLE_AUTHN_MICROFRONTEND'] = False
(defaults to True)
-
- Build a new
openedx
image:tutor images build openedx-dev
(this will take a long time) - Run a Docker Compse rebuild:
tutor dev dc build
(this should be pretty quick - it’s likely not required, just doing it here for safety) - Restart Tutor:
tutor dev start -d
(omit-d
if you want to watch the logs) -
Check your settings. There’s a
print_setting
command that you can use to verify everything is set properly:tutor dev run lms ./manage.py lms print_setting REGISTRATION_EXTRA_FIELDS
tutor dev run lms ./manage.py lms print_setting AUTHENTICATION_BACKENDS
tutor dev run lms ./manage.py lms print_setting FEATURES
- will print a lot of stufftutor dev run lms ./manage.py lms print_setting THIRD_PARTY_AUTH_BACKENDS
- If you do have weird errors or settings not showing properly, make sure you edited the right yaml files and that they’re using the right whitespace (i.e. don’t use tabs).
- In a separate browser session of some kind (incognito/private browsing/other browser entirely), try to navigate to
http://local.openedx.io:8000
. It should load but it should give you an error message. In the LMS logs, you should see an error message for “Can’t fetch settings for disabled provider.” This is proper operation - the OAuth2 settings aren’t in place yet. - In the superuser session you have open, go to
http://local.openedx.io:8000/admin
. This should work. If you’ve been logged out, you should still be able to get in. If you can’t (for instance, if you’re getting 500 errors), you will need to turn offENABLE_THIRD_PARTY_AUTH
inFEATURES
, restart Tutor usingtutor dev stop
andstart
, not usingreboot
, then try again. -
Go to
http://local.openedx.io:8000/admin/third_party_auth/oauth2providerconfig/add/
and add a provider configuration:- Enabled is checked.
- Name:
Login with MIT App
- Slug:
mitxpro-oauth2
- Site:
local.openedx.io:8000
- Skip hinted login dialog is checked.
- Skip registration form is checked.
- Skip email verification is checked.
- Sync learner profile data is checked.
- Enable sso id verification is checked.
- Backend name:
mitxpro-oauth2
Client ID
andClient Secret
: from record created byconfigure_instance
when you set up MITx Application.-
Other settings:
{ "AUTHORIZATION_URL": "http://{Domain}:{PORT}/oauth2/authorize/", "ACCESS_TOKEN_URL": "http://<MITxApplication_GATEWAY_IP>:<PORT>/oauth2/token/", "API_ROOT": "http://<MITxApplication_GATEWAY_IP>:<PORT>/" }
where MITxApplication_GATEWAY_IP is the IP from the
mitxApplication_default
network from the first step. Mac users, usehost.docker.internal
for MITxApplication_GATEWAY_IP.
Configure Open edX to support OAuth2 authentication from MITx Application
- Go to
http://local.openedx.io:8000/admin/oauth2_provider/application/
and add/edit theedx-oauth-app
entry. -
Ensure these settings are set:
- Name:
edx-oauth-app
- Redirect uris:
http://{Domain}:{PORT}/login/_private/complete
- Client type:
Confidential
- Authorization grant type:
Authorization code
- Skip authorization is checked.
- Name:
- Save
Client id
andClient secret
.
Update your MIT Application .env
file. Set OPENEDX_API_CLIENT_ID
and OPENEDX_API_CLIENT_SECRET
to the values from the record you created or updated in the last step.
Also set the LOGOUT_REDIRECT_URL in .env
:
LOGOUT_REDIRECT_URL=http://local.openedx.io:8000/logout
- Build the MIT Application:
docker-compose build
You should now be able to run some MIT Application management commands to ensure the service worker is set up properly:
sync_courserun --all ALL
should sync the two test courses (if you made them).sync_courseruns --all ALL
in MITxPro
repair_missing_courseware_records
should also work.
In the separate browser session, attempt to log in again. This time, you should be able to log in through MIT Application, and you should be able to get to the edX LMS dashboard. If not, then double-check your provider configuration settings and try again.
- If you are still getting “Can’t fetch settings” errors, make sure your Site is set properly - there are three options by default and only one works. (This was typically the problem I had.)
Optionally, log into the LMS Django Admin and make your MIT Application superuser account a superuser there too.
Other Notes
Trying to set configuration settings via tutor config
will undo the specialty configuration above. If you need to make changes to the configuration, either manually edit the env/apps/openedx/config/lms.env.yml
file or the env/apps/openedx/settings/lms/production.py
file and restart your Tutor instance.
Make sure your service worker account is active. It’s an easy checkbox to miss.
Restarting If you want to rebuild from scratch, make sure you docker image prune
. It’s also recommended to remove the Tutor project root folder - tutor config printroot
will tell you where that is.
Running Multiple Tutor Instances If you want to run more than one Tutor instance, it’s pretty important to specify the project root explicitly or you may end up with one instance trying to use config files from another and things getting confused from there. See the Tutor documentation for this.
(A suggestion: configure aliases to the tutor
command that run tutor --root=<whatever>
so you don’t have to rely on environment variables, especially if you keep multiple terminal sessions going.)