by mark-b-kauffman



See for the license pertaining to the portions of this application specific to Blackboard Learn. Note that it states that you bear the entire liability for any issues arising from the use of this software.

See for the Phoenix Framework License

phoenixDSK3LO is the 3-Legged OAuth version of phoenixDSK.

This is a work in progress. I first focused on building this out, based on the phoenixDSK code, to demonstrate three-legged OAuth flow. That works, but more work needs doing to handle multiple users. Currently the 3LO works for one user, but once you've logged in using 3LO, anyone else can access the web application without having to log in. The only thing 'securing' the application at that point is whether the URL is known & accessable. Don't leave this up and running on Heroku. Better to build and use it on your desktop, OR use phoenixDSK's HTTP Basic Authentication mechanism requires every individual browser session to log in.

Demo use of 3LO with Learn REST Application. 3LO is not necessary for the DSK tool because the admin will stand it up for their own use, not for others' use. 3LO lets you use Learn authentication to login to then REST App. The phoenixDSK application lets you give that REST APP a unique username and password that only you know and can log in with. Then phoenixDSK uses the secure 2LO mechanism to connect to the Learn server that you specify. phoenixDSK is fine for a Learn Admin wanting to use the app to manage DSKs and row status of records on her Learn system.

We're just building this 3LO version out to demo 3LO authentication using a Learn account vs. setting up unique, separate, login to phoenixDSK. You'll need to sign in to Learn with a Learn admin account to use this application.

Quick and Easy Deployment to Heroku:

(Read the above warning before you do this.)

  1. Get an application ID, key, and Secret from
  2. Set up the REST application on your Learn server using the application ID from #1.
  3. Click the Deploy button and fill in the application key, secret, and Learn URL.


  1. Wait a bit while the application deploys to your Heroku server.
  2. Click the View button.
  3. Remove the trailing /register in the address of the page that is displayed, then hit enter to view the application.

Note: The Heroku configuration is contained in the top-level file app.json.

Notes for building and deploying locally:

2017.05.27 MBK I built this as a default Phoenix project using an Ecto Repo on to of Postgres. Since I'm not using any of that functionality for this project I decided to remove it. I did so using the procedure described with the following:

git reset --hard origin/master Then copy the hidden dev.exs file for use. If you don't have a hidden dev.exs file, then modify the one you've pulled from github to have your key and secret. Then, because of the mods made to run this on Heroku, you will need to set 3 environment variables to run locally. The following works on the Mac OSX with a Bash shell. $ export LEARNSERVER= $ export APP_KEY= $ export APP_SECRET=

2015.05.30 MBK TODO HTTPoison, Verify Cert for SSL, eliminate possibility of MITM Refresh REST Auth token on expiration Paging on the dsks and users index pages.

To try the different modules in iex:

  • $ iex -S mix

To start this Phoenix app you must do the following the first time after checkout:

  • Install dependencies with mix deps.get
  • Install Node.js dependencies with npm install

The above only need doing the first time, after that you can just start the server with the following:

  • Start Phoenix endpoint with mix phoenix.server

Now you can visit localhost:4000 from your browser.

Ready to run in production? Please check our deployment guides.


If things stop working between builds, try wiping everything that gets built and start back with the instructions above for first time after checkout:

  • rm mix.lock
  • rm -rf deps
  • rm -rf _build
  • rm -rf priv
  • rm -rf node_modules
  • sudo rm -rf ~/.npm
  • Install dependencies with mix deps.get
  • Install Node.js dependencies with npm install

Learn more

This specific application's organization follows:

LearnRestClient and LearnRestUtil encapsulate code necessary to make REST calls to a Learn server. LearnRestClient uses an Elixir Agent to hold the state of a REST client for multiple Learn servers.

When you start the client you're associating a FQDN with the client. Example: LearnRestClient.start_client("") The above starts an Agent named String.to_atom("") and tells it that the state it will encapsulate is a Map. Then start_client calls the Learn OAuth endpoint to get the token used for successive calls. The result is JSON which we store in a Map, tokenMap. This tokenMap is stored in the LearnRestClient Map, and the key is "tokenMap". The last thing that LearnRestClient.start_client does is to call the Learn endpoint to get the Learn system's DSKs. Here the result is a list of DSKs where each DSK is a Map. We turn the list into a map of maps, so that we can quickly access a given DSK.

The rest of this application is a Phoenix MVC web application. We store the public configuration in config/config.exs. This only consists of learnserver: and learnserverAtom, the Learn server that we work with for the demo. Our private configuration is in confi/dev.exs, consisting of the login information to our local database, and our REST application key and secret.

Before we run this web app we must define a REST application on Then we use the provided key and secret in the dev.exs file, as this is the application. We configure the Learn server REST integration for this application using the provided Application ID.

The last piece that is unique to this web app is that we define a worker in phoenixDSK3LO/restclientagent.ex. This worker will start the LearnRestClient for us when we load the application, connecting to the :learnserver we defined in config.exs. We tell this application to start the worker in the start section of lib/phoenixDSK3LO.ex with the line: worker(PhoenixDSK3LO.RestClientAgent,[])

Defining config in config.exs lets us do things like: Application.get_env(:phoenixDSK3LO, PhoenixDSK3LO.Endpoint)[:appkey] Application.get_env(:phoenixDSK3LO, PhoenixDSK3LO.Endpoint)[:learnserver] Application.get_env(:phoenixDSK3LO, PhoenixDSK3LO.Endpoint)[:learnserverAtom] anywhere in the application.

Because the LearnRestClient was started by a worker, we can use it anywhere. Examples: fqdn=Application.get_env(:phoenixDSK3LO, PhoenixDSK3LO.Endpoint)[:learnserver] {:ok, users} = LearnRestClient.get_users(fqdn)