With the AuthConfig created, we are set up to use the Auth ability in the service to ensure that the appropriate todos are served to each user.

The Auth library provides a handler called oauth2.handler for use with any Routes based HTTP service. It also appends the following routes to the service:

  • /login - Redirects the user to the identity provider's login page
  • /logout - Logs the user out and redirects them to the home page
  • /oauth/redirect - A callback used for completing the OAuth2 flow

📓 Instructions

routes.todoService defines the todo app's current endpoints. Change the ex4_oauth.deploy function to pass routes.todoService to the oauth2.handler function before the routes are given as an argument to Route.run.

Save the scratch file and update your codebase.

On to the routes.todoService function proper! view it in the UCM to see how the current UserId works:

exercises.ex4_oauth.todoService :
  OrderedTable (ex4_oauth.UserId, Text) TodoItem
  -> Database
  -> '{Route, Exception, Storage, Remote, Log} ()
exercises.ex4_oauth.todoService html todoTable db =
  _ = "Oh no, we need a real UserId!"
  userIdSession = ex4_oauth.UserId.UserId "stubValue"
  [...]

We'll be adding calls to getSession and requireSession for endpoints where a user should be signed in to access todos. Let's reiterate the "business logic" of the todo-app in simple Auth ability terms:

  • If a user lands on the home page, "/", use requireSession to redirect the user to sign in.
  • If a user issues a request to add, delete, edit, or view todos, check if they're signed in with getSession. If the value from getSession is Optional.None, the service should return a 401 response.
  • If the user is able to authenticate, the Auth functions return a UserId as the session type. The UserId is then used for database lookups.

📓 Instructions

  cloud-start/main> edit ex4_oauth.todoService

Change the home page route which serves the todo form to call requireSession.

Then change the remaining routes in the ex4_oauth.todoService function to get the authenticated user's UserId from the Auth ability. Return a 401 Unauthorized response if the user is not authenticated.

No changes to the database schema or query logic are needed for this exercise!

Save the scratch file and update your codebase. Test the login flow by running the deploy function in the UCM.

cloud-start/main> run ex4_oauth.deploy

Remember you can sign in with the "/login" and sign out with the "/logout" route of your service! They're freebies from the Auth ecosystem.

When you're ready, submit your solution for validation.

cloud-start/main> run submit.ex4_oauth.roundtrip

Congratulations! You've added authentication to a Cloud service! 🥳