Last active
November 17, 2023 20:09
-
-
Save sosolidkk/a1665e0a924a663e7e045ac95b5af662 to your computer and use it in GitHub Desktop.
Devise Middleware Backdoor
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Middlewares | |
# Middleware which allows signing in by passing as=USER_ID in a query | |
# parameter. | |
# | |
# Designed to eliminate time in integration tests wasted by visiting and | |
# submitting the sign in form. | |
# | |
# This code snippet is heavily inspired by and based on the Toughtbot Clearance gem Backdoor | |
# For more details, see the source code here: | |
# https://github.com/thoughtbot/clearance/blob/main/lib/clearance/back_door.rb | |
# | |
# @example Usage in Rails application: | |
# In config/application.rb or an initializer | |
# Rails.application.config.middleware.use Middlewares::Backdoor | |
# | |
# @example Usage URL with query parameter to sign in as a specific user: | |
# http://localhost:3000/some_path?as=123 | |
# | |
class Backdoor | |
# @see https://stackoverflow.com/a/44747266 | |
include Warden::Test::Helpers | |
# Initialize the Backdoor Middleware | |
# | |
# @param [Object] app ActionDispatch::Routing::RouteSet | |
# The application to call. | |
# | |
def initialize(app, &block) | |
raise error_message unless allowed? | |
@app = app | |
@block = block | |
end | |
# Calls the Middleware operation | |
# | |
# @param [Hash] env The Rack environment keys and values. | |
# | |
def call(env) | |
run(env) | |
@app.call(env) | |
end | |
private | |
# Run the Backdoor middleware. | |
# | |
# @param [Hash] env The Rack environment keys and values. | |
# | |
# @return [void] | |
# | |
def run(env) | |
params = Rack::Utils.parse_query(env['QUERY_STRING']) | |
user_param = params.fetch('as') | |
return if user_param.blank? | |
user = User.find_by(id: user_param) | |
return if user.blank? | |
login_as(user, scope: :user) | |
Rails.logger.info("Backdoor: Signed in as User #{user.username} [id: #{user.id}]") | |
end | |
# Check if the Backdoor is allowed in the current environment. | |
# | |
# @return [Boolean] true if allowed, false otherwise. | |
# | |
def allowed? | |
allowed_environments.include?(Rails.env) | |
end | |
# List of environments where the Backdoor is allowed. | |
# | |
# @return [Array<String>] List of allowed environments. | |
# | |
def allowed_environments | |
%w[staging development] | |
end | |
# Error message when Backdoor is not allowed in the current environment. | |
# | |
# @return [String] The error message. | |
# | |
def error_message | |
<<-MSG.squish | |
Can't use auth backdoor outside of | |
configured environments (#{allowed_environments.join(', ')}). | |
MSG | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment