lib/oath/controller_helpers.rb
require 'bcrypt'
require 'active_support/concern'
module Oath
# Mixin to be included in Rails controllers.
# @since 0.0.15
module ControllerHelpers
extend ActiveSupport::Concern
included do
if respond_to?(:helper_method)
helper_method :current_user, :signed_in?
end
end
# Sign in a user
#
# @note Uses the {Oath::Services::SignIn} service to create a session
#
# @param user [User] the user object to sign in
# @yield Yields to the block if the user is successfully signed in
# @return [Object] returns the value from calling perform on the {Oath::Services::SignIn} service
def sign_in user
Oath.config.sign_in_service.new(user, warden).perform.tap do |status|
if status && block_given?
yield
end
end
end
# Sign out the current session
#
# @note Uses the {Oath::Services::SignOut} service to destroy the session
#
# @return [Object] returns the value from calling perform on the {Oath::Services::SignOut} service
def sign_out
Oath.config.sign_out_service.new(warden).perform
end
# Sign up a user
#
# @note Uses the {Oath::Services::SignUp} service to create a user
#
# @param user_params [Hash] params containing lookup and token fields
# @yield Yields to the block if the user is signed up successfully
# @return [Object] returns the value from calling perform on the {Oath::Services::SignUp} service
def sign_up user_params
Oath.config.sign_up_service.new(user_params).perform.tap do |status|
if status && block_given?
yield
end
end
end
# Authenticates a session.
#
# @note Uses the {Oath::Services::Authentication} service to verify the user's details
#
# @param session_params [Hash] params containing lookup and token fields
# @param field_map [Hash] Field map used for allowing users to sign in with multiple fields e.g. email and username
# @return [User] if authentication succeeded
# @return [nil] if authentication failed
# @example Basic usage
# class SessionsController < ApplicationController
# def create
# user = authenticate_session(session_params)
#
# if sign_in(user)
# redirect_to(root_path)
# else
# render :new
# end
# end
#
# private
#
# def session_params
# params.require(:session).permit(:email, :password)
# end
#
# end
# @example Using the field map to authenticate using multiple lookup fields
# class SessionsController < ApplicationController
# def create
# user = authenticate_session(session_params, email_or_username: [:email, :username])
#
# if sign_in(user)
# redirect_to(root_path)
# else
# render :new
# end
# end
#
# private
#
# def session_params
# params.require(:session).permit(:email_or_username, :password)
# end
#
# end
def authenticate_session session_params, field_map = nil
token_field = Oath.config.user_token_field
params_hash = Oath.transform_params(session_params).symbolize_keys
password = params_hash.fetch(token_field)
user = Oath.lookup(params_hash.except(token_field), field_map)
authenticate(user, password)
end
# Authenticates a user given a password
#
# @note Uses the {Oath::Services::Authentication} service to verify the user's credentials
#
# @param user [User] the user
# @param password [String] the password
# @return [User] if authentication succeeded
# @return [nil] if authentication failed
def authenticate user, password
Oath.config.authentication_service.new(user, password).perform
end
# Resets a user's password
#
# @note Uses the {Oath::Services::PasswordReset} service to change a user's password
#
# @param user [User] the user
# @param password [String] the password
def reset_password user, password
Oath.config.password_reset_service.new(user, password).perform
end
# @api private
def warden
request.env['warden']
end
# helper_method that returns the current user
#
# @return [User] if user is signed in
# @return [nil] if user is not signed in
def current_user
@current_user ||= warden.user
end
# helper_method that checks if there is a user signed in
#
# @return [User] if user is signed in
# @return [nil] if user is not signed in
def signed_in?
warden.user
end
# before_action that determines what to do when the user is not signed in
#
# @note Uses the no login handler
def require_login
unless signed_in?
Oath.config.no_login_handler.call(self)
end
end
end
end