module Keycard::ControllerMethods
Mixin for conveniences in controllers.
These methods depend on a `notary` method in your controller that returns a configured {Keycard::Notary} instance.
Constants
- DEFAULT_SESSION_TIMEOUT
The default session timeout is 24 hours, in seconds.
Public Instance Methods
Require that some authentication method successfully identifies a user/account, raising an exception if there is a failure for active credentials or no applicable credentials are presented.
@raise [AuthenticationFailed] if credentials for an attempted
authentication method are incorrect
@raise [AuthenticationRequired] if all authentication methods are skipped
and authentication could not be attempted
@return nil
# File lib/keycard/controller_methods.rb, line 55 def authenticate! raise AuthenticationFailed if authentication.failed? raise AuthenticationRequired unless authentication.authenticated? end
Log an account in without checking any credentials, starting a session.
@param account [User|Account] the user/account object to consider current;
must have an #id property.
# File lib/keycard/controller_methods.rb, line 76 def auto_login(account) request.env["keycard.authentication"] = notary.waive(account) setup_session end
Retrieve the user/account to which the current request is attributed.
@return [User/Account] the user/account that has been authenticated; nil
if no one is logged in
# File lib/keycard/controller_methods.rb, line 25 def current_user authentication.account end
Check whether the current request is authenticated as coming from a known person or account.
@return [Boolean] true if any of the {Notary}'s configured authentication
methods succeeds
# File lib/keycard/controller_methods.rb, line 17 def logged_in? authentication.authenticated? end
Attempt to authenticate, optionally with user-supplied credentials, and establish a session.
@param credentials [Hash|kwargs] user-supplied credentials that will be
passed to each authentication method
@return [Boolean] whether the login attempt was successful
# File lib/keycard/controller_methods.rb, line 66 def login(**credentials) authentication(credentials).authenticated?.tap do |success| setup_session if success end end
Clear authentication status and terminate any open session.
# File lib/keycard/controller_methods.rb, line 82 def logout request.env["keycard.authentication"] = notary.reject reset_session end
Validate the session, resetting it if expired.
This should be called as a before_action before {#authenticate!} when working with session-based logins. It preserves a CSRF token, if present, so login forms and the like will pass forgery protection.
# File lib/keycard/controller_methods.rb, line 34 def validate_session csrf_token = session[:_csrf_token] elapsed = begin Time.now - Time.at(session[:timestamp] || 0) rescue StandardError session_timeout end reset_session if elapsed >= session_timeout session[:_csrf_token] = csrf_token session[:timestamp] = Time.now.to_i if session.key?(:timestamp) end
Private Instance Methods
# File lib/keycard/controller_methods.rb, line 89 def authentication(**credentials) request.env["keycard.authentication"] ||= notary.authenticate(request, session, credentials) end
The session timeout, in seconds. Sessions will be cleared before any further authentication unless there is a timestamp younger than this many seconds old. The default is 24 hours.
@return [Integer] session timeout, in seconds
# File lib/keycard/controller_methods.rb, line 99 def session_timeout DEFAULT_SESSION_TIMEOUT end
# File lib/keycard/controller_methods.rb, line 103 def setup_session return_url = session[:return_to] reset_session session[:return_to] = return_url session[:user_id] = current_user.id session[:timestamp] = Time.now.to_i end