Skip to content

Rails Library Reference

Install

In your Rails app, install the propelauth gem.

$ gem install propelauth

and add the following to your Gemfile

gem "propelauth"

Configure

Go to your PropelAuth project and click Backend Integration in the sidebar. You will see:

  • Auth URL - This is where your authentication pages are hosted, and you will need this for the setup step.
  • API Keys - You will need to create a key for the setup step.
  • Token Verification Metadata - You will pass this into the PropelAuth gem to verify access tokens.

Then in config/application.rb, configure PropelAuth:

    PropelAuth.configure do |config|
      config.auth_url = ENV["AUTH_URL"]
      config.api_key = Rails.application.credentials.propelauth_api_key
      config.public_key = ENV["PUBLIC_KEY_PEM"]
    end

You can either set these values directly, use environment variables, or use the built-in credential store.

Set up

With this backend library, there are two main tasks you can do: 1. Fetching user/organization data from PropelAuth 1. Making sure users are authenticated when they call on of your APIs

You are already set up to do the first one. In order to protect API routes, you'll need to add the following to app/controllers/application.rb:

class ApplicationController < ActionController::API
  include PropelAuth::AuthMethods
end

By including PropelAuth::AuthMethods, your controllers will be able to check if a valid access token was provided.

require_user

class WhoamiController < ApplicationController
  before_action :require_user

  def index
    render json: @user
  end
end

The code example above does a few things:

  1. Checks that a valid access token was provided. If not, the request is rejected with a 401 status code. This all happens in require_user
  2. Set @user with the user's id and organization information
  3. Returns the user to the frontend as json

The @user object looks like:

{
  // the id of the user who's token was provided
  userId: "2667a646-cdef-49da-8580-47e0d73cffa7",
  // OPTIONAL: this is only returned for B2B applications
  // For each organization the user is a member of, this is a dict of the organization's id
  //   to some information about the organization.
  orgIdToOrgMemberInfo: {
    "2ef0e1fc-234f-4dc0-a50c-35adb1bbb7e4": {
      "orgId": "2ef0e1fc-234f-4dc0-a50c-35adb1bbb7e4",
      "orgName": "ExampleOrganization",
      // This is the role of the user within that organization. See UserRole for more information
      "userRole": "Owner",
    }
  }
}

optional_user

Similar to require_user, except if an access token is missing or invalid, the request is allowed to continue, but @user will be nil.

class WhoamiController < ApplicationController
  before_action :optional_user

  def index
    if @user.nil?
      render json: {}
    else
      render json: @user
    end
  end
end

require_org_member

class WhoamiController < ApplicationController
  before_action do
    require_org_member(params[:org_id], minimum_required_role: PropelAuth::UserRole::Admin)
  end

  def index
    # both @user and @org are set
    render json: @org
  end
end

require_org_member is responsible for both checking that the access token belongs to a valid user AND that that user is a member of the specified organization. In the above code snippet, we are taking an org_id from the path parameters, and checking to see if the user is at least an Admin within that organization.

Specifically, it will:

  1. Check that a valid access token was provided. If not, the request is rejected with a 401 status code.
  2. Set @user with the user's information. See require_user for what the @user object looks like.
  3. Check that the user is a member of the specified organization. If not, the request is rejected with a 403 status code.
  4. (Optionally) Check that the user's role in that organization is >= minimum_required_role. If not, the request is rejected with a 403 status code.
  5. Set @org with the organization's information for this user.

The @org object looks like:

{
  "org_id": "2ef0e1fc-234f-4dc0-a50c-35adb1bbb7e4",
  "org_name": "ExampleOrganization",
  // This is the role of the user within that organization. See UserRole for more information
  "user_role": "Owner",
}

fetch_user_metadata_by_user_id

Fetches information for a user based on their userId. Returns a Promise that resolves to either null if no user is found, or the following if a user is found:

PropelAuth::Client.fetch_user_metadata_by_user_id("e9d3520f-836e-403c-82c2-09843517e1ce", include_orgs: true)
{
  "user_id": "e9d3520f-836e-403c-82c2-09843517e1ce",
  "email": "user@example.com",
  "email_confirmed": true,
  // OPTIONAL: username is only returned if you have usernames enabled for your project
  "username": "example",
  // OPTIONAL: first_name is only returned if you have names enabled for your project
  "first_name": "first",
  // OPTIONAL: last_name is only returned if you have names enabled for your project
  "last_name": "last",
  // OPTIONAL: picture_url is only returned if you have names enabled for your project
  "picture_url": "https://...",

  "locked": false,
  "enabled": true,
  "mfa_enabled": false,

  "created_at": 1645131680,
  "last_active_at": 1650654711,

  // OPTIONAL: pass in include_orgs: true to return this information
  "org_id_to_org_info": {
    "2ef0e1fc-234f-4dc0-a50c-35adb1bbb7e4": {
      "org_id": "2ef0e1fc-234f-4dc0-a50c-35adb1bbb7e4", 
      "org_name": "ExampleOrganization", 
      "user_role": "Owner"
    }
  }
}

fetch_user_metadata_by_email

The same as fetch_user_metadata_by_user_id, expect it takes an email as an argument.

fetch_user_metadata_by_username

The same as fetch_user_metadata_by_user_id, expect it takes a username as an argument.

fetch_batch_user_metadata_by_user_ids

Fetches information for a batch of users based on their user_ids. Returns a dictionary where the keys are user_ids and the values are information about that user. Users that are not found are not included in the dictionary.

PropelAuth::Client.fetch_batch_user_metadata_by_user_ids([
    "1be238f3-5908-4c51-b3bf-e53dd763047e",
    "beb00acf-6e48-435d-8388-3758607ec01b",
    "941c99e5-3530-4475-bd0f-bbc5d06603c3"
], include_orgs: true)

The response is:

{
  "1be238f3-5908-4c51-b3bf-e53dd763047e": {
    "user_id": "1be238f3-5908-4c51-b3bf-e53dd763047e",
    "email": "a@example.com",
    // OPTIONAL: username is only returned if you have usernames enabled for your application
    "username": "usera",
    // and first_name, last_name, etc ...
  },
  "beb00acf-6e48-435d-8388-3758607ec01b": {
    "user_id": "beb00acf-6e48-435d-8388-3758607ec01b",
    "email": "b@example.com",
    // OPTIONAL: username is only returned if you have usernames enabled for your application
    "username": "userb",
    // and first_name, last_name, etc ...
  }
  // if 941c99e5-3530-4475-bd0f-bbc5d06603c3 wasn't found, it won't be in the dictionary
}

fetch_batch_user_metadata_by_emails

The same as fetch_batch_user_metadata_by_user_ids, expect it takes a list of emails as an argument, and the keys in the response are emails.

An example response is:

{
  "a@example.com": {
    "user_id": "1be238f3-5908-4c51-b3bf-e53dd763047e",
    "email": "a@example.com",
    // OPTIONAL: username is only returned if you have usernames enabled for your application
    "username": "usera",
    // and first_name, last_name, etc ...
  },
  "b@example.com": {
    "user_id": "beb00acf-6e48-435d-8388-3758607ec01b",
    "email": "b@example.com",
    // OPTIONAL: username is only returned if you have usernames enabled for your application
    "username": "userb",
    // and first_name, last_name, etc ...
  }
  // if c@example.com wasn't found, it won't be in the dictionary
}

fetch_batch_user_metadata_by_usernames

The same as fetchBatchUserMetadataByUserIds, expect it takes a list of usernames as an argument, and the keys in the response are usernames.

An example response is:

// A dictionary where the keys are _found_ usernames, and the values are users
{
  "usera": {
    "user_id": "1be238f3-5908-4c51-b3bf-e53dd763047e",
    "email": "a@example.com",
    "username": "usera",
    // and first_name, last_name, etc ...
  },
  "userb": {
    "user_id": "beb00acf-6e48-435d-8388-3758607ec01b",
    "email": "b@example.com",
    "username": "userb",
    // and first_name, last_name, etc ...
  }
  // if userc wasn't found, it won't be in the dictionary
}

UserRole

An enum of roles within an organization. Values, in order of highest to lowest, include

PropelAuth::UserRole::Owner
PropelAuth::UserRole::Admin
PropelAuth::UserRole::Member