module PrxAuth::Rails::Controller

Constants

PRX_ACCOUNT_MAPPING_SESSION_KEY
PRX_AUTH_ENV_KEY
PRX_JWT_REFRESH_TTL
PRX_JWT_SESSION_KEY
PRX_REFRESH_BACK_KEY
PRX_USER_INFO_SESSION_KEY

Public Instance Methods

account_for(account_id) click to toggle source
# File lib/prx_auth/rails/ext/controller.rb, line 87
def account_for(account_id)
  lookup_accounts([account_id]).first
end
account_name_for(account_id) click to toggle source
# File lib/prx_auth/rails/ext/controller.rb, line 83
def account_name_for(account_id)
  account_for(account_id).try(:[], :name)
end
accounts_for(account_ids) click to toggle source
# File lib/prx_auth/rails/ext/controller.rb, line 91
def accounts_for(account_ids)
  lookup_accounts(account_ids)
end
after_sign_in_user_redirect() click to toggle source
# File lib/prx_auth/rails/ext/controller.rb, line 75
def after_sign_in_user_redirect
  session.delete(PRX_REFRESH_BACK_KEY)
end
authenticate!() click to toggle source
# File lib/prx_auth/rails/ext/controller.rb, line 34
def authenticate!
  return true if current_user.present?

  redirect_to PrxAuth::Rails::Engine.routes.url_helpers.new_sessions_path
end
current_user() click to toggle source
# File lib/prx_auth/rails/ext/controller.rb, line 44
def current_user
  prx_auth_token
end
current_user_apps() click to toggle source
# File lib/prx_auth/rails/ext/controller.rb, line 56
def current_user_apps
  apps = (current_user_info.try(:[], 'apps') || []).map do |name, url|
    label = name.sub(/^https?:\/\//, '').sub(/\..+/, '').capitalize
    ["PRX #{label}", url]
  end

  # only return entire list in development
  if ::Rails.env.production? || ::Rails.env.staging?
    apps.to_h.select { |k, v| v.match?(/\.(org|tech)/) }
  else
    apps.to_h
  end
end
current_user_info() click to toggle source
# File lib/prx_auth/rails/ext/controller.rb, line 48
def current_user_info
  session[PRX_USER_INFO_SESSION_KEY] ||= fetch_userinfo
end
current_user_name() click to toggle source
# File lib/prx_auth/rails/ext/controller.rb, line 52
def current_user_name
  current_user_info['name'] || current_user_info['preferred_username'] || current_user_info['email']
end
prx_auth_needs_refresh?(jwt_ttl) click to toggle source
# File lib/prx_auth/rails/ext/controller.rb, line 40
def prx_auth_needs_refresh?(jwt_ttl)
  request.get? && jwt_ttl < PRX_JWT_REFRESH_TTL
end
prx_auth_token() click to toggle source
# File lib/prx_auth/rails/ext/controller.rb, line 16
def prx_auth_token
  env_token || session_token
rescue SessionTokenExpiredError
  session.delete(PRX_JWT_SESSION_KEY)
  session.delete(PRX_ACCOUNT_MAPPING_SESSION_KEY)
  session.delete(PRX_USER_INFO_SESSION_KEY)
  session[PRX_REFRESH_BACK_KEY] = request.fullpath
  redirect_to PrxAuth::Rails::Engine.routes.url_helpers.new_sessions_path
end
prx_authenticated?() click to toggle source
# File lib/prx_auth/rails/ext/controller.rb, line 30
def prx_authenticated?
  !!prx_auth_token
end
prx_jwt() click to toggle source
# File lib/prx_auth/rails/ext/controller.rb, line 26
def prx_jwt
  session[PRX_JWT_SESSION_KEY]
end
sign_in_user(token) click to toggle source
# File lib/prx_auth/rails/ext/controller.rb, line 70
def sign_in_user(token)
  session[PRX_JWT_SESSION_KEY] = token
  accounts_for(current_user.resources)
end
sign_out_user() click to toggle source
# File lib/prx_auth/rails/ext/controller.rb, line 79
def sign_out_user
  reset_session
end

Private Instance Methods

env_token() click to toggle source

token from data set by prx_auth rack middleware

# File lib/prx_auth/rails/ext/controller.rb, line 129
def env_token
  @env_token_data ||= if request.env[PRX_AUTH_ENV_KEY]
    token_data = request.env[PRX_AUTH_ENV_KEY]
    PrxAuth::Rails::Token.new(token_data)
  end
end
fetch(path, token = nil) click to toggle source
# File lib/prx_auth/rails/ext/controller.rb, line 120
def fetch(path, token = nil)
  url = "https://#{PrxAuth::Rails.configuration.id_host}#{path}"
  options = {}
  options[:ssl_verify_mode] = OpenSSL::SSL::VERIFY_NONE if ::Rails.env.development?
  options['Authorization'] = "Bearer #{token}" if token
  JSON.parse(URI.open(url, options).read)
end
fetch_accounts(ids) click to toggle source
# File lib/prx_auth/rails/ext/controller.rb, line 111
def fetch_accounts(ids)
  ids_param = ids.map(&:to_s).join(',')
  fetch("/api/v1/accounts?account_ids=#{ids_param}")['accounts']
end
fetch_userinfo() click to toggle source
# File lib/prx_auth/rails/ext/controller.rb, line 116
def fetch_userinfo
  fetch("/userinfo?scope=apps+email+profile", prx_jwt)
end
lookup_accounts(ids) click to toggle source
# File lib/prx_auth/rails/ext/controller.rb, line 97
def lookup_accounts(ids)
  session[PRX_ACCOUNT_MAPPING_SESSION_KEY] ||= {}

  # fetch any accounts we don't have yet
  missing = ids - session[PRX_ACCOUNT_MAPPING_SESSION_KEY].keys
  if missing.present?
    fetch_accounts(missing).each do |account|
      session[PRX_ACCOUNT_MAPPING_SESSION_KEY][account['id']] = account.with_indifferent_access
    end
  end

  ids.map { |id| session[PRX_ACCOUNT_MAPPING_SESSION_KEY][id] }
end
session_token() click to toggle source

token from jwt stored in session

# File lib/prx_auth/rails/ext/controller.rb, line 137
def session_token
  @session_prx_auth_token ||= if prx_jwt
    # NOTE: we already validated this jwt - so just decode it
    validator = Rack::PrxAuth::AuthValidator.new(prx_jwt)

    # does this jwt need to be refreshed?
    if prx_auth_needs_refresh?(validator.time_to_live)
      raise SessionTokenExpiredError.new
    end

    # create new data/token from access claims
    token_data = Rack::PrxAuth::TokenData.new(validator.claims)
    PrxAuth::Rails::Token.new(token_data)
  end
end