From 1252e7324f5ff56d678ea9f4bdfd39cc487c1cb9 Mon Sep 17 00:00:00 2001
From: Robin Ward <robin.ward@gmail.com>
Date: Tue, 7 Oct 2014 12:25:25 -0400
Subject: [PATCH] Added easy impersonate route while in development mode

---
 app/controllers/session_controller.rb       | 13 ++++++++++++-
 config/routes.rb                            |  3 ++-
 spec/controllers/session_controller_spec.rb | 18 ++++++++++++++++++
 3 files changed, 32 insertions(+), 2 deletions(-)

diff --git a/app/controllers/session_controller.rb b/app/controllers/session_controller.rb
index e44cf9eef..1f8680e31 100644
--- a/app/controllers/session_controller.rb
+++ b/app/controllers/session_controller.rb
@@ -3,7 +3,7 @@ require_dependency 'rate_limiter'
 class SessionController < ApplicationController
 
   skip_before_filter :redirect_to_login_if_required
-  skip_before_filter :check_xhr, only: ['sso', 'sso_login']
+  skip_before_filter :check_xhr, only: ['sso', 'sso_login', 'become']
 
   def csrf
     render json: {csrf: form_authenticity_token }
@@ -17,6 +17,17 @@ class SessionController < ApplicationController
     end
   end
 
+  # For use in development mode only when login options could be limited or disabled.
+  # NEVER allow this to work in production.
+  def become
+    raise Discourse::InvalidAccess.new unless Rails.env.development?
+    user = User.find_by_username(params[:session_id])
+    raise "User #{params[:session_id]} not found" if user.blank?
+
+    log_on_user(user)
+    redirect_to "/"
+  end
+
   def sso_login
     unless SiteSetting.enable_sso
       render nothing: true, status: 404
diff --git a/config/routes.rb b/config/routes.rb
index 8da9d9b2e..66c373631 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -177,7 +177,8 @@ Discourse::Application.routes.draw do
   get "email/unsubscribe/:key" => "email#unsubscribe", as: "email_unsubscribe"
   post "email/resubscribe/:key" => "email#resubscribe", as: "email_resubscribe"
 
-  resources :session, id: USERNAME_ROUTE_FORMAT, only: [:create, :destroy] do
+  resources :session, id: USERNAME_ROUTE_FORMAT, only: [:create, :destroy, :become] do
+    get 'become'
     collection do
       post "forgot_password"
     end
diff --git a/spec/controllers/session_controller_spec.rb b/spec/controllers/session_controller_spec.rb
index f306c79d1..a46c6b9c0 100644
--- a/spec/controllers/session_controller_spec.rb
+++ b/spec/controllers/session_controller_spec.rb
@@ -2,6 +2,24 @@ require 'spec_helper'
 
 describe SessionController do
 
+  describe 'become' do
+    let!(:user) { Fabricate(:user) }
+
+    it "does not work when not in development mode" do
+      Rails.env.stubs(:development?).returns(false)
+      get :become, session_id: user.username
+      response.should_not be_redirect
+      session[:current_user_id].should be_blank
+    end
+
+    it "works in developmenet mode" do
+      Rails.env.stubs(:development?).returns(true)
+      get :become, session_id: user.username
+      response.should be_redirect
+      session[:current_user_id].should == user.id
+    end
+  end
+
   describe '.sso_login' do
 
     before do