Module: CryptIdent

Defined in:
lib/crypt_ident.rb,
lib/crypt_ident/config.rb,
lib/crypt_ident/sign_in.rb,
lib/crypt_ident/sign_up.rb,
lib/crypt_ident/version.rb,
lib/crypt_ident/sign_out.rb,
lib/crypt_ident/reset_password.rb,
lib/crypt_ident/change_password.rb,
lib/crypt_ident/session_expired.rb,
lib/crypt_ident/generate_reset_token.rb,
lib/crypt_ident/update_session_expiry.rb

Overview

Include and interact with CryptIdent to add authentication to a Hanami controller action.

Note the emphasis on controller action; this module interacts with session data, which is quite theoretically possible in an Interactor but practically quite the PITA. YHBW.

Author:

  • Jeff Dickey

Version:

  • 0.1.0

Defined Under Namespace

Classes: Config

Constant Summary collapse

VERSION =

Version number for Gem. Uses Semantic Versioning.

'0.1.2'

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#cryptid_configObject (readonly)

Memoised configuration object.


29
30
31
# File 'lib/crypt_ident.rb', line 29

def cryptid_config
  @cryptid_config
end

Class Method Details

.configure_crypt_ident {|config| ... } ⇒ CryptIdent::Config

Set configuration information at the class (actually, module) level.

IMPORTANT: Even though we follow time-honoured convention here and call the variable yielded by the CryptIdent.configure_crypt_ident block config, settings are not being stored in an instance variable called @config. That is too likely to conflict with something Important; remember, we're a module, not a class, and good table manners are also Important.

This is normally run from the controller.prepare block inside your app's apps/<app name>/application.rb file, where the default for app_name in a Hanami app is web.

Examples:

CryptIdent.configure_crypt_ident do |config| # show defaults
  config.error_key = :error
  config.guest_user = nil
  config.hashing_cost = 8
  config.repository = UserRepository.new
  config.guest_user = config.repository.guest_user
  config.reset_expiry = (24 * 60 * 60)
  config.session_expiry = 900
  config.success_key = :success
  config.token_bytes = 24
end

Yield Parameters:

  • config (Struct)

    Mutable Struct initialised to default config.

Yield Returns:

  • (void)

Returns:

Since:

  • 0.1.0

Required Authentication Status:

  • Irrelevant; normally called during framework setup.

Session Data Interacted With:

  • Irrelevant; normally called during framework setup.

Ubiquitous Language Terms:

  • None; only related to demonstrated configuration settings.


70
71
72
73
74
# File 'lib/crypt_ident.rb', line 70

def self.configure_crypt_ident
  config = _starting_config
  yield config if block_given?
  @cryptid_config = Config.new(config.to_h)
end

.reset_crypt_ident_configCryptIdent::Config

Reset configuration information to default values.

This should primarily be used during testing, and would normally be run from a before block for a test suite.

Examples:

Show how a modified configuration value is reset.

CryptIdent.configure_crypt_ident do |config|
  config.hashing_cost = 20 # default 8
end
# ...
foo = CryptIdent.cryptid_config.hashing_cost # 20
# ...
CryptIdent.reset_crypt_ident_config
foo == CryptIdent.cryptid_config.hashing_cost # default, 8

Returns:

Since:

  • 0.1.0

Required Authentication Status:

  • Irrelevant; normally called during framework setup.

Session Data Interacted With:

  • Irrelevant; normally called during testing

Ubiquitous Language Terms:

  • None; only related to demonstrated configuration settings.


108
109
110
# File 'lib/crypt_ident.rb', line 108

def self.reset_crypt_ident_config
  @cryptid_config = Config.new
end

Instance Method Details

#change_password(user_in, current_password, new_password, repo: nil) {|result| ... }

This method returns an undefined value.

Change an Authenticated User's password.

To change an Authenticated User's password, an Entity for that User, the current Clear-Text Password, and the new Clear-Text Password are required. The method accepts an optional repo parameter to specify a Repository instance to which the updated User Entity should be persisted; if none is specified (i.e., if the parameter has its default value of nil), then the UserRepository specified in the Configuration is used.

The method requires a block, to which a result indicating success or failure is yielded. That block must in turn call both result.success and result.failure to handle success and failure results, respectively. On success, the block yielded to by result.success is called and passed a user: parameter, which is identical to the user parameter passed in to #change_password except that the :password_hash attribute has been updated to reflect the changed password. The updated value for the encrypted password will also have been saved to the Repository.

On failure, the result.failure call will yield a code: parameter to its block, which indicates the cause of failure as follows:

If the specified password did not match the passed-in user Entity, then the code: for failure will be :bad_password.

If the specified user was other than a User Entity representing a Registered User, then the code: for failure will be :invalid_user.

Note that no check for the Current User is done here; this method trusts the Controller Action Class that (possibly indirectly) invokes it to guard that contingency properly.

Examples:

for a Controller Action Class (refactor in real use; demo only)

def call(params)
  user_in = session[:current_user]
  error_code = :unassigned
  config = CryptIdent.cryptid_config
  change_password(user_in, params[:password],
                  params[:new_password]) do |result|
    result.success do |user:|
      @user = user
      flash[config.success_key] = "User #{user.name} password changed."
      redirect_to routes.root_path
    end
    result.failure do |code:|
      flash[config.error_key] = error_message_for(code)
    end
  end
end

private

def error_message_for(code)
  # ...
end

Parameters:

  • user_in (User)

    The User Entity from which to get the valid Encrypted Password and other non-Password attributes

  • current_password (String)

    The current Clear-Text Password for the specified User

  • new_password (String)

    The new Clear-Text Password to encrypt and add to the returned Entity, and persist to the Repository

  • repo (Object, nil)

    The Repository to which the updated User Entity is to be persisted. If the default value of nil, then the UserRepository specified in the default configuration is used.

Yield Parameters:

  • result (Dry::Matcher::Evaluator)

    Indicates whether the attempt to create a new User succeeded or failed. Block must call both result.success and result.failure methods, where the block passed to result.success accepts parameters for config: (which is the active configuration for the call) and user: (which is the newly-created User Entity). The block passed to result.failure accepts parameters for config: (as before) and code:, which is a Symbol reporting the reason for the failure (as described above).

Yield Returns:

  • (void)

    Use the result.success and result.failure method-call blocks to retrieve data from the method.

Since:

  • 0.1.0

Required Authentication Status:

  • Must be Authenticated.

Session Data Interacted With:

  • Implies that :current_user must be an Entity for a Registered User

Ubiquitous Language Terms:

    • Authentication
    • Clear-Text Password
    • Encrypted Password
    • Entity
    • Guest User
    • Registered User
    • Repository

459
460
461
462
463
464
# File 'lib/crypt_ident.rb', line 459

def change_password(user_in, current_password, new_password, repo: nil)
  new_params = { config: CryptIdent.cryptid_config, repo: repo,
                 user: user_in }
  call_params = [current_password, new_password]
  ChangePassword.new(new_params).call(*call_params) { |result| yield result }
end

#generate_reset_token(user_name, repo: nil, current_user: nil) {|result| ... }

This method returns an undefined value.

Generate a Password Reset Token

Password Reset Tokens are useful for verifying that the person requesting a Password Reset for an existing User is sufficiently likely to be the person who Registered that User or, if not, that no compromise or other harm is done.

Typically, this is done by sending a link through email or other such medium to the address previously associated with the User purportedly requesting the Password Reset. CryptIdent does not automate generation or sending of the email message. What it does provide is a method to generate a new Password Reset Token to be embedded into an HTML anchor link within an email that you construct, and then another method (#reset_password) to actually change the password given a valid, correct token.

It also implements an expiry system, such that if the confirmation of the Password Reset request is not completed within a configurable time, that the token is no longer valid (and so cannot be later reused by unauthorised persons).

This method requires a block, to which a result indicating success or failure is yielded. That block must in turn call both result.success and result.failure to handle success and failure results, respectively. On success, the block yielded to by result.success is called and passed a user: parameter, which is identical to the user parameter passed in to #generate_reset_token except that the :token and :password_reset_expires_at attributes have been updated to reflect the token request. An updated record matching that :user Entity will also have been saved to the Repository.

On failure, the result.failure call will yield three parameters: :code, :current_user, and :name, and will be set as follows:

If the :code value is :user_logged_in, that indicates that the current_user parameter to this method represented a Registered User. In this event, the :current_user value passed in to the result.failure call will be the same User Entity passed into the method, and the :name value will be :unassigned.

If the :code value is :user_not_found, the named User was not found in the Repository. The :current_user parameter will be the Guest User Entity, and the :name parameter to the result.failure block will be the user_name value passed into the method.

Examples:

Demonstrating a (refactorable) Controller Action Class #call method


def call(params)
  config = CryptIdent.cryptid_config
  other_params = { current_user: session[:current_user] }
  generate_reset_token(params[:name], other_params) do |result|
    result.success do |user:|
      @user = user
      flash[config.success_key] = 'Request for #{user.name} sent'
    end
    result.failure do |code:, current_user:, name:| do
      respond_to_error(code, current_user, name)
    end
  end
end

private

def respond_to_error(code, current_user, name)
  # ...
end

Parameters:

  • user_name (String)

    The name of the User for whom a Password Reset Token is to be generated.

  • repo (Object, nil)

    The Repository to which the Entity for the named User is persisted after "updating" it with Token and Password Reset Set At attributes. If the default value of nil, then the UserRepository specified in the default configuration is used.

  • current_user (User)

    Entity representing the currently Authenticated User Entity. This must be a Registered User.

Yield Parameters:

  • result (Dry::Matcher::Evaluator)

    Indicates whether the attempt to generate a new Reset Token succeeded or failed. The lock must call both result.success and result.failure methods, where the block passed to result.success accepts a parameter for user:, which is a User Entity with the specified name value as well as non-nil values for its :token and :password_reset_expires_at attributes. The block passed to result.failure accepts parameters for code:, current_user:, and name as described above.

Yield Returns:

  • (void)

    Use the result.success and result.failure method-call blocks to retrieve data from the method.

Since:

  • 0.1.0

Required Authentication Status:

  • Must not be Authenticated.

Session Data Interacted With:

  • :current_user must not be a Registered User.

Ubiquitous Language Terms:

    • Authentication
    • Password Reset Token
    • Registered User

561
562
563
564
565
566
# File 'lib/crypt_ident.rb', line 561

def generate_reset_token(user_name, repo: nil, current_user: nil)
  other_params = { repo: repo, current_user: current_user }
  GenerateResetToken.new.call(user_name, other_params) do |result|
    yield result
  end
end

#reset_password(token, new_password, repo: nil, current_user: nil) {|result| ... }

This method returns an undefined value.

Reset the password for the User associated with a Password Reset Token.

After a Password Reset Token has been generated and sent to a User, that User would then exercise the Client system and perform a Password Reset.

Calling #reset_password is different than calling #change_password in one vital respect: with #change_password, the User involved must be the Current User (as presumed by passing the appropriate User Entity in as the current_user: parameter), whereas #reset_password must not be called with any User other than the Guest User as the current_user: parameter (and, again presumably, the Current User for the session). How can we assure ourselves that the request is legitimate for a specific User? By use of the Token generated by a previous call to #generate_reset_token, which is used in place of a User Name for this request.

Given a valid set of parameters, and given that the updated User is successfully persisted, the method calls the required block with a result whose result.success matcher is yielded a user: parameter with the updated User as its value.

NOTE: Each of the error returns documented below calls the required block with a result whose result.failure matcher is yielded a code: parameter as described; a config: parameter of the active Configuration (including the Repository used to retrieve the relevant User record); and a token: parameter that has the same value as the passed-in token parameter.

If the passed-in token parameter matches the token field of a record in the Repository and that Token is determined to have Expired, then the code: parameter mentioned earlier will have the value :expired_token.

If the passed-in token parameter does not match the token field of any record in the Repository, then the code: parameter will have the value :token_not_found.

If the passed-in current_user: parameter is a Registered User, then the code: parameter will have the value :invalid_current_user.

In no event are session values, including the Current User, changed. After a successful Password Reset, the User must Authenticate as usual.

Examples:

def call(params)
  reset_password(params[:token], params[:new_password],
                 current_user: session[:current_user]) do |result
    result.success do |user:|
      @user = user
      message = "Password for #{user.name} successfully reset."
      config = CryptIdent.cryptid_config
      flash[config.success_key] = message
      redirect_to routes.root_path
    end
    result.failure do |code:, config:, token:|
      flash[config.failure_key] = failure_message_for(code, config, token)
    end
  end
end

private

def failure_message_for(code, config, token)
  # ...
end

Parameters:

  • token (String)

    The Password Reset Token previously communicated to the User.

  • new_password (String)

    New Clear-Text Password to encrypt and add to return value

Yield Parameters:

  • result (Dry::Matcher::Evaluator)

    Indicates whether the attempt to generate a new Reset Token succeeded or failed. The lock must call both result.success and result.failure methods, where the block passed to result.success accepts a parameter for user:, which is a User Entity with the specified name value as well as non-nil values for its :token and :password_reset_expires_at attributes. The block passed to result.failure accepts parameters for code:, current_user:, and name as described above.

Yield Returns:

  • (void)

    Use the result.success and result.failure method-call blocks to retrieve data from the method.

Since:

  • 0.1.0

Required Authentication Status:

  • Must not be Authenticated.

Session Data Interacted With:

  • :current_user must not be a Registered User.

Ubiquitous Language Terms:

    • Authentication
    • Clear-Text Password
    • Encrypted Password
    • Password Reset Token
    • Registered User

660
661
662
663
664
665
# File 'lib/crypt_ident.rb', line 660

def reset_password(token, new_password, repo: nil, current_user: nil)
  other_params = { repo: repo, current_user: current_user }
  ResetPassword.new.call(token, new_password, other_params) do |result|
    yield result
  end
end

#session_expired?(session_data = {}) ⇒ Boolean

Determine whether the Session has Expired due to User inactivity.

This is one of two methods in CryptIdent (the other being #update_session_expiry?) which does not follow the result/success/failure monad workflow. This is because there is no success/failure division in the workflow. Calling the method determines if the Current User session has Expired. If the passed-in :current_user is a Registered User, then this will return true if the current time is later than the passed-in :expires_at value; for the Guest User, it should always return false. (Guest User sessions never expire; after all, what would you change the session state to?).

The client code is responsible for applying these values to its own actual session data, as described by the sample session-management code shown in the README.

Examples:

As used in module included by Controller Action Class (see README)

def validate_session
  updates = update_session_expiry(session)
  if !session_expired?(session)
    session[:expires_at] = updates[:expires_at]
    return
  end

  # ... sign out and redirect appropriately ...
end

Parameters:

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

    The Rack session data of interest to the method. If the :current_user entry is defined, it must be either a User Entity or nil, signifying the Guest User. If the :expires_at entry is defined, its value in the returned Hash will be different.

Returns:

  • (Boolean)

Since:

  • 0.1.0

Required Authentication Status:

  • Must be Authenticated.

Session Data Interacted With:

  • :current_user must be an Entity for a Registered User on entry :expires_at read during determination of expiry status

Ubiquitous Language Terms:

    • Authentication
    • Current User
    • Guest User
    • Registered User
    • Session Expiration

712
713
714
# File 'lib/crypt_ident.rb', line 712

def session_expired?(session_data = {})
  SessionExpired.new.call(session_data)
end

#sign_in(user_in, password, current_user: nil) {|result| ... }

This method returns an undefined value.

Attempt to Authenticate a User, passing in an Entity for that User (which must contain a password_hash attribute), and a Clear-Text Password. It also passes in the Current User.

If the Current User is not a Registered User, then Authentication of the specified User Entity against the specified Password is accomplished by comparing the User Entity's password_hash attribute to the passed-in Clear-Text Password.

The method requires a block, to which a result indicating success or failure is yielded. That block must in turn call both result.success and result.failure to handle success and failure results, respectively. On success, the block yielded to by result.success is called and passed a user: parameter, which is the Authenticated User (and is the same Entity as the user parameter passed in to #sign_in).

On failure, the result.failure call will yield a code: parameter to its block, which indicates the cause of failure as follows:

If the specified password did not match the passed-in user Entity, then the code: for failure will be :invalid_password.

If the specified user was not a Registered User, then the code: for failure will be :user_is_guest.

If the specified current_user is neither the Guest User nor the user passed in as a parameter to #sign_in, then the code: for failure will be :illegal_current_user.

On success, the Controller-level client code must set:

  • session[:expires_at] to the expiration time for the session. This is ordinarily computed by adding the current time as returned by Time.now to the :session_expiry value in the current configuration.
  • session[:current_user] to tne returned Entity for the successfully Authenticated User. This is to eliminate possible repeated reads of the Repository.

On failure, the Controller-level client code should set:

  • session[:expires_at] to some sufficiently-past time to always trigger #session_expired?; Hanami::Utils::Kernel.Time(0) does this quite well (returning midnight GMT on 1 January 1970, converted to local time).
  • session[:current_user] to either nil or the Guest User.

Examples:

As in a Controller Action Class (which you'd refactor somewhat):

def call(params)
  user = UserRepository.new.find_by_email(params[:email])
  guest_user = CryptIdent::cryptid_config.guest_user
  return update_session_data(guest_user, 0) unless user

  current_user = session[:current_user]
  config = CryptId.cryptid_config
  sign_in(user, params[:password], current_user: current_user) do |result|
    result.success do |user:|
      @user = user
      update_session_data(user, config, Time.now)
      flash[config.success_key] = "User #{user.name} signed in."
      redirect_to routes.root_path
    end

    result.failure do |code:|
      update_session_data(guest_user, config, 0)
      flash[config.error_key] = error_message_for(code)
    end
  end

private

def error_message_for(code)
  # ...
end

def update_session_data(user, config, time)
  session[:current_user] = user
  expiry = Time.now + config.session_expiry
  session[:expires_at] == Hanami::Utils::Kernel.Time(expiry)
end

Parameters:

  • user_in (User)

    Entity representing a User to be Authenticated.

  • password (String)

    Claimed Clear-Text Password for the specified User.

  • current_user (User, nil)

    Entity representing the currently Authenticated User Entity; either nil or the Guest User if none.

Yield Parameters:

  • result (Dry::Matcher::Evaluator)

    Indicates whether the attempt to Authenticate a User succeeded or failed. Block must call both result.success and result.failure methods, where the block passed to result.success accepts a parameter for user: (which is the newly-created User Entity). The block passed to result.failure accepts a parameter for code:, which is a Symbol reporting the reason for the failure (as described above).

Yield Returns:

  • (void)

Since:

  • 0.1.0

Required Authentication Status:

  • Must not be Authenticated as a different User.

Session Data Interacted With:

  • :current_user must not be a Registered User

Ubiquitous Language Terms:

    • Authenticated User
    • Authentication
    • Clear-Text Password
    • Entity
    • Guest User
    • Registered User

300
301
302
303
# File 'lib/crypt_ident.rb', line 300

def (user_in, password, current_user: nil)
  params = { user: user_in, password: password, current_user: current_user }
  SignIn.new.call(params) { |result| yield result }
end

#sign_out(current_user:) {|result| ... }

This method returns an undefined value.

Sign out a previously Authenticated User.

The method requires a block, to which a result indicating success or failure is yielded. (Presently, any call to #sign_out results in success.) That block must in turn call both result.success and result.failure (even though no failure is implemented) to handle success and failure results, respectively. On success, the block yielded to by result.success is called and passed a config: parameter, which is simply the value returned from CryptIdent.cryptid_config with no modifier block), It may safely be ignored.

Examples:

Controller Action Class method example resetting values

def call(_params)
  sign_out(session[:current_user]) do |result|
    result.success do |config|
      session[:current_user] = config.guest_user
      session[:expires_at] = Hanami::Utils::Kernel.Time(0)
    end

    result.failure { next }
  end
end

Controller Action Class method example deleting values

def call(_params)
  sign_out(session[:current_user]) do |result|
    result.success do |config|
      session[:current_user] = nil
      session[:expires_at] = nil
    end

    result.failure { next }
  end
end

Parameters:

  • current_user (User, `nil`)

    Entity representing the currently Authenticated User Entity. This should be a Registered User.

Yield Parameters:

  • result (Dry::Matcher::Evaluator)

    Normally, used to report whether a method succeeded or failed. The block must call both result.success and result.failure methods. In practice, parameters to both may presently be safely ignored; config is passed to success as a convenience.

Yield Returns:

  • (void)

Since:

  • 0.1.0

Required Authentication Status:

  • Should be Authenticated.

Session Data Interacted With:

  • See method description above.

Ubiquitous Language Terms:

    • Authenticated User
    • Authentication
    • Controller Action Class
    • Entity
    • Guest User
    • Interactor
    • Repository

365
366
367
# File 'lib/crypt_ident.rb', line 365

def sign_out(current_user:)
  SignOut.new.call(current_user: current_user) { |result| yield result }
end

#sign_up(attribs, current_user:, repo: nil) {|result| ... }

This method returns an undefined value.

Persist a new User to a Repository based on passed-in attributes, where the resulting Entity (on success) contains a :password_hash attribute containing the encrypted value of a random Clear-Text Password; any password value within attribs is ignored.

The method requires a block, to which a result indicating success or failure is yielded. That block must in turn call both result.success and result.failure to handle success and failure results, respectively. On success, the block yielded to by result.success is called and passed config: and user: parameters, which are the Config object active while creating the new User, and the newly-created User Entity itself respectively.

If the call fails, the result.success block is yielded to, and passed config: and code: parameters. The config: parameter is the active configuration as described earlier for result.success. The code: parameter will contain one of the following symbols:

  • :current_user_exists indicates that the method was called with a Registered User as the current_user parameter.
  • :user_already_created indicates that the specified name attribute matches a record that already exists in the underlying Repository.
  • :user_creation_failed indicates that the Repository was unable to create the new User for some other reason, such as an internal error.

NOTE that the incoming params are expected to have been whitelisted at the Controller Action Class level.

Examples:

in a Controller Action Class

def call(_params)
  (params, current_user: session[:current_user]) do |result|
    result.success do |config:, user:|
      @user = user
      message = "#{user.name} successfully created. You may sign in now."
      flash[config.success_key] = message
      redirect_to routes.root_path
    end

    result.failure do |code:, config:|
      # `#error_message_for` is a method on the same class, not shown
      flash[config.failure_key] = error_message_for(code, params)
    end
  end
end

Parameters:

  • attribs (Hash)

    Hash-like object of attributes for new User Entity and record. Must include name and any other attributes required by the underlying database schema. Any password attribute will be ignored.

  • current_user (User, nil)

    Entity representing the current Authenticated User, or the Guest User. A value of nil is treated as though the Guest User had been specified.

  • repo (Hanami::Repository, nil)

    Repository to be used for accessing User data. A value of nil indicates that the default Repository specified in the Configuration should be used.

Yield Parameters:

  • result (Dry::Matcher::Evaluator)

    Indicates whether the attempt to create a new User succeeded or failed. Block must call both result.success and result.failure methods, where the block passed to result.success accepts parameters for config: (which is the active configuration for the call) and user: (which is the newly-created User Entity). The block passed to result.failure accepts parameters for config: (as before) and code:, which is a Symbol reporting the reason for the failure (as described above).

Since:

  • 0.1.0

Required Authentication Status:

  • Must not be Authenticated.

Session Data Interacted With:

  • :current_user must not be a Registered User.

Ubiquitous Language Terms:

    • Authentication
    • Clear-Text Password
    • Entity
    • Guest User
    • Registered User
    • Repository

189
190
191
192
193
# File 'lib/crypt_ident.rb', line 189

def (attribs, current_user:, repo: nil)
  SignUp.new(repo).call(attribs, current_user: current_user) do |result|
    yield result
  end
end

#update_session_expiry(session_data = {}) ⇒ Hash

Generate a Hash containing an updated Session Expiration timestamp, which can then be used for session management.

This is one of two methods in CryptIdent (the other being #session_expired?) which does not follow the result/success/failure monad workflow. This is because there is no success/failure division in the workflow. Calling the method only makes sense if there is a Registered User as the Current User, but all this method does is build a Hash with :current_user and :expires_at entries. The returned :current_user is the passed-in :current_user if a Registered User, or the Guest User if not. The returned :updated_at value, for a Registered User, is the configured Session Expiry added to the current time, and for the Guest User, a time far enough in the future that any call to #session_expired? will be highly unlikely to ever return true.

The client code is responsible for applying these values to its own actual session data, as described by the sample session-management code shown in the README.

Examples:

As used in module included by Controller Action Class (see README)

def validate_session
  updates = update_session_expiry(session)
  if !session_expired?(session)
    session[:expires_at] = updates[:expires_at]
    return
  end

  # ... sign out and redirect appropriately ...
end

Parameters:

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

    The Rack session data of interest to the method. If the :current_user entry is defined, it must be either a User Entity or nil, signifying the Guest User. If the :expires_at entry is defined, its value in the returned Hash will be different.

Returns:

  • (Hash)

    A Hash with entries to be used to update session data. expires_at will have a value of the current time plus the configuration-specified session_expiry offset if the supplied :current_user value is a Registered User; otherwise it will have a value far enough in advance of the current time (e.g., by 100 years) that the #session_expired? method is highly unlikely to ever return true. The :current_user value will be the passed-in session_data[:current_user] value if that represents a Registered User, or the Guest User otherwise.

Since:

  • 0.1.0

Required Authentication Status:

  • Must be Authenticated.

Session Data Interacted With:

  • :current_user must be a User Entity or nil for the Guest User :expires_at set to the session-expiration time on exit, which will be arbitrarily far in the future for the Guest User.

Ubiquitous Language Terms:

    • Authentication
    • Guest User
    • Registered User
    • Session Expiration
    • User

774
775
776
# File 'lib/crypt_ident.rb', line 774

def update_session_expiry(session_data = {})
  UpdateSessionExpiry.new.call(session_data)
end