Skip to content

Authentication: Require Authn for Access

Jeff Dickey edited this page Mar 3, 2019 · 2 revisions

This is one of the three example modules discussed in this Wiki that provide "drop-in" Authentication support for Controller Action Classes, or CACs for short. Including this module in your CAC will first include the CommonAuthn module and call its setup_callbacks on inclusion.

Including the module will define a before callback to CommonAuthn#authorize, which will be called prior to the CAC's #call method. If that method returns without any redirects, halts, or other changes of control flow, then the #call method will be called and can assume that @current_user is a valid, Authenticated User instance.

That CommonAuthn module references but does not implement a private method, #valid_current_user(user_attrs). That method, by convention, should return true if the user attributes passed in describe a User Entity that is permitted to access the HTTP endpoint implemented by the CAC, or false otherwise. In this module, ProhibitGuest, the method returns false if a User Entity instantiated from the passed-in attributes returns true from its #guest? method, and true otherwise. This is the only logic that need be implemented to achieve this module's objective.

This module, courtesy of logic implemented in CommonAuthn, will also expose a @current_user instance variable that, by the time your CAC's #call method is entered, has a valid, non-Guest User Entity as its value. (This is the exact opposite of the logic in RequireGuest (here), which guarantees that @current_user.guest? will return true when called from your #call method).

As discussed, this is a refinement of the "common authentication" module:

# frozen_string_literal: true

require_relative './common_authn'

module Web
  # ...other source comments elided for this annotation...
  module ProhibitGuest
    # NOTE: `CommonAuthn`, included, does most of the heavy lifting.
    #   We specialise here.
    include CommonAuthn

    # NOTE: As noted earlier, set up callback and exposed variable.
    def self.included(other)
      CommonAuthn.setup_callbacks(other)
    end

    private

    # NOTE: This is all that's needed to prohibit the Guest User from accessing
    #   the `#call` method of the CAC which includes this module, assuming session
    #   data is correctly set.
    def valid_current_user?(user_attrs)
      User.new(user_attrs).guest? == false
    end
  end
end