Module: Securial::Identity

Extended by:
ActiveSupport::Concern
Defined in:
app/controllers/concerns/securial/identity.rb

Overview

Identity Concern

Provides authentication and user identification functionality for controllers. This concern adds before_action hooks for user identification and authentication, and provides helper methods for accessing the current user and enforcing authentication.

Instance Method Summary collapse

Instance Method Details

#authenticate_admin!void

This method returns an undefined value.

Ensures the current user has admin privileges.

This method checks if a user is authenticated and has admin privileges. If the user is not an admin, it renders a forbidden response. If no user is authenticated, it calls authenticate_user! to handle the unauthorized case.



78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'app/controllers/concerns/securial/identity.rb', line 78

def authenticate_admin!
  if current_user
    return if current_user.is_admin?

    render status: :forbidden,
           json: {
            errors: ["You are not authorized to perform this action"],
            instructions: "Please contact an administrator if you believe this is an error.",
          }
  else
    authenticate_user!
  end
end

#authenticate_user!void (private)

This method returns an undefined value.

Ensures a user is authenticated before proceeding.

This method checks if a user has been successfully identified. If not, it renders an unauthorized response and halts the request. Internal Rails requests are exempt from authentication requirements.



135
136
137
138
139
140
141
142
143
144
# File 'app/controllers/concerns/securial/identity.rb', line 135

def authenticate_user!
  return if internal_rails_request?
  return if Current.session&.user

  render status: :unauthorized,
         json: {
           errors: ["You are not signed in"],
           instructions: "Please sign in to access this resource.",
           } and return
end

#current_userSecurial::User?

Returns the currently authenticated user or nil if no user is authenticated.

This method provides access to the current user object from the session tracked in Current.session.

Returns:



66
67
68
# File 'app/controllers/concerns/securial/identity.rb', line 66

def current_user
  Current.session&.user
end

#identify_uservoid (private)

This method returns an undefined value.

Identifies the current user from the Authorization header.

This method attempts to identify the user by:

  1. Checking for a valid Bearer token in the Authorization header

  2. Decoding the token to extract the session ID

  3. Finding and validating the corresponding session

  4. Ensuring IP address and user agent match for security

If identification succeeds, the session is stored in Current.session



106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# File 'app/controllers/concerns/securial/identity.rb', line 106

def identify_user
  return if internal_rails_request?

  Current.session = nil
  auth_header = request.headers["Authorization"]
  if auth_header.present? && auth_header.start_with?("Bearer ")
    token = auth_header.split(" ").last
    begin
      decoded_token = Securial::Auth::AuthEncoder.decode(token)
      session = Session.find_by(id: decoded_token["jti"], revoked: false)
      if session.present? &&
         session.is_valid_session? &&
         session.ip_address == request.remote_ip &&
         session.user_agent == request.user_agent
        Current.session = session
      end
    rescue Securial::Error::Auth::TokenDecodeError, ActiveRecord::RecordNotFound => e
      Securial.logger.debug "Authentication failed: #{e.message}"
    end
  end
end

#internal_rails_request?Boolean (private)

Determines if the current request is from internal Rails controllers.

This method checks if the current controller is one of Rails’ internal controllers (Info, Mailers, Welcome) which should bypass authentication.

Returns:

  • (Boolean)

    true if the request is from internal Rails controllers, false otherwise



152
153
154
155
156
# File 'app/controllers/concerns/securial/identity.rb', line 152

def internal_rails_request?
  defined?(Rails::InfoController) && is_a?(Rails::InfoController) ||
  defined?(Rails::MailersController) && is_a?(Rails::MailersController) ||
  defined?(Rails::WelcomeController) && is_a?(Rails::WelcomeController)
end

#skip_authentication!(options = {}) ⇒ void

This method returns an undefined value.

Skips authentication for specified controller actions, making them publicly accessible.

This class method allows you to bypass the ‘authenticate_user!` before_action that is applied by default to all controller actions when including the Identity concern. It’s useful for endpoints that should be publicly accessible, such as landing pages, password reset, login, or registration.

Examples:

Skip authentication for login and registration actions

class SessionsController < ApplicationController
  include Securial::Identity

  skip_authentication! only: [:new, :create]

  def new
    # Login form action
  end

  def create
    # Authentication logic
  end
end

Skip authentication for all actions except protected ones

class PublicController < ApplicationController
  include Securial::Identity

  skip_authentication! except: [:dashboard, :account]
end

Parameters:

  • options (Hash) (defaults to: {})

    Options to pass to skip_before_action

Options Hash (options):

  • :only (Symbol, Array<Symbol>)

    Specific action(s) to skip authentication for

  • :except (Symbol, Array<Symbol>)

    Action(s) to exclude from skipping



52
53
54
55
56
# File 'app/controllers/concerns/securial/identity.rb', line 52

class_methods do
  def skip_authentication!(**options)
    skip_before_action :authenticate_user!, **options
  end
end