Skip to content

Repository files navigation

Pretender

As an admin, there are times you want to see exactly what another user sees. Meet Pretender.

  • Easily to switch between users
  • Minimal code changes
  • Plays nicely with Action Cable and auditing tools

💥 Rock on

Pretender is flexible and lightweight - less than 100 lines of code :-)

Works with any authentication system - Devise, Authlogic, and Sorcery to name a few.

🍊 Battle-tested at Instacart

Installation

Add this line to your application’s Gemfile:

gem'pretender'

And add this to your ApplicationController:

classApplicationController < ActionController::Baseimpersonates:userend

How It Works

Sign in as another user with:

impersonate_user(user)

The current_user method now returns the impersonated user.

You can access the true user with:

true_user

And stop impersonating with:

stop_impersonating_user

Sample Implementation

Create a controller

classUsersController < ApplicationControllerbefore_action:require_admin!# your authorization methoddefindex@users=User.order(:id)enddefimpersonateuser=User.find(params[:id])impersonate_user(user)redirect_toroot_pathenddefstop_impersonatingstop_impersonating_userredirect_toroot_pathendend

Add routes

resources:users,only: [:index]dopost:impersonate,on: :memberpost:stop_impersonating,on: :collectionend

Create an index view

<ul><%@users.eachdo |user| %><li>Sign in as <%=link_touser.name,impersonate_user_path(user),method: :post%></li><%end%></ul>

And show when someone is signed in as another user in your application layout

<% if current_user != true_user %>
You (<%= true_user.name %>) are signed in as <%= current_user.name %><%= link_to "Back to admin", stop_impersonating_users_path, method: :post %><% end %>

Audits

If you keep audit logs with a library like Audited, make sure it uses the true user.

Audited.current_user_method=:true_user

Action Cable

And add this to your ApplicationCable::Connection:

moduleApplicationCableclassConnection < ActionCable::Connection::Baseidentified_by:current_user,:true_userimpersonates:userdefconnectself.current_user=find_verified_userreject_unauthorized_connectionunlesscurrent_userendprivatedeffind_verified_userenv["warden"].user# for Deviseendendend

The current_user method now returns the impersonated user in channels.

Configuration

Pretender is super flexible. You can change the names of methods and even impersonate multiple roles at the same time. Here’s the default configuration.

impersonates:user,method: :current_user,with: ->(id){User.find_by(id: id)}

Mold it to fit your application.

impersonates:account,method: :authenticated_account,with: ->(id){EnterpriseAccount.find_by(id: id)}

This creates three methods:

true_accountimpersonate_accountstop_impersonating_account

Contributing

Everyone is encouraged to help improve this project. Here are a few ways you can help:

About

private clone of pretender

Resources

Stars

0 stars

Watchers

17 watching

Forks

Releases

Packages

Used by

Contributors

Languages