Skip to content

Authentication: Prohibit Authenticated User

Jeff Dickey edited this page Mar 3, 2019 · 1 revision

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 the Guest User.

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, RequireGuest, the method returns true if a User Entity instantiated from the passed-in attributes returns true from its #guest? method, and false 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 the Guest User Entity as its value. (This is the exact opposite of the logic in ProhibitGuest (here), which guarantees that @current_user.guest? will return false 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 RequireGuest
    # 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 a User other than 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?
    end
  end
end