Skip to content

Instantly share code, notes, and snippets.

@reshadman
Created June 27, 2024 18:17

Revisions

  1. reshadman created this gist Jun 27, 2024.
    80 changes: 80 additions & 0 deletions auth.rb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,80 @@
    module Authentication
    extend ActiveSupport::Concern
    include SessionLookup

    included do
    before_action :require_authentication
    helper_method :signed_in?

    protect_from_forgery with: :exception, unless: -> { authenticated_by.bot_key? }
    end

    class_methods do
    def require_unauthenticated_access(**options)
    allow_unauthenticated_access **options
    before_action :redirect_signed_in_user_to_root, **options
    end

    def allow_unauthenticated_access(**options)
    skip_before_action :require_authentication, **options
    before_action :restore_authentication, **options
    end
    end

    private
    def signed_in?
    Current.user.present?
    end

    def require_authentication
    restore_authentication || request_authentication
    end

    def restore_authentication
    if session = find_session_by_cookie
    resume_session session
    end
    end

    def request_authentication
    session[:return_to_after_authenticating] = request.url
    redirect_to new_session_url
    end

    def redirect_signed_in_user_to_root
    redirect_to root_url if signed_in?
    end

    def start_new_session_for(user)
    user.sessions.start!(user_agent: request.user_agent, ip_address: request.remote_ip).tap do |session|
    authenticated_as session
    end
    end

    def resume_session(session)
    session.resume user_agent: request.user_agent, ip_address: request.remote_ip
    authenticated_as session
    end

    def authenticated_as(session)
    Current.user = session.user
    set_authenticated_by(:session)
    cookies.signed.permanent[:session_token] = { value: session.token, httponly: true, same_site: :lax }
    end

    def post_authenticating_url
    session.delete(:return_to_after_authenticating) || root_url
    end

    def reset_authentication
    cookies.delete(:session_token)
    end

    def set_authenticated_by(method)
    @authenticated_by = method.to_s.inquiry
    end

    def authenticated_by
    @authenticated_by ||= "".inquiry
    end
    end