From e6147fb8e51e4293a5b00aa6862aec4ca711b7ec Mon Sep 17 00:00:00 2001 From: Dylan Jhaveri Date: Tue, 17 Feb 2015 13:16:08 -0800 Subject: [PATCH 01/50] Devise provider- don't store sign_in details * closes https://github.com/flyerhzm/switch_user/issues/67 * warden#set_user sets current_sign_in_at, last_sign_in_at, current_sign_in_ip, sign_in_count, current_sign_in_ip, last_sign_in_ip * use SessionSerialializer#store to bypass the updating of these columns * thanks https://github.com/rajagopals/switch_user/commit/7437c5c3b039df1c7f9acd83bf672971a02e3f28 --- lib/switch_user/provider/devise.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/switch_user/provider/devise.rb b/lib/switch_user/provider/devise.rb index 930e0a8..c6a9183 100644 --- a/lib/switch_user/provider/devise.rb +++ b/lib/switch_user/provider/devise.rb @@ -7,7 +7,7 @@ def initialize(controller) end def login(user, scope = :user) - @warden.set_user(user, :scope => scope) + @warden.session_serializer.store(user, scope) end def logout(scope = :user) From fe984ead52039992d7621899017b75b0cccce733 Mon Sep 17 00:00:00 2001 From: Sergey Alekseev Date: Wed, 25 Mar 2015 21:03:26 +0300 Subject: [PATCH 02/50] security :guardsman: --- app/controllers/switch_user_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/switch_user_controller.rb b/app/controllers/switch_user_controller.rb index 722fb20..3aaf835 100644 --- a/app/controllers/switch_user_controller.rb +++ b/app/controllers/switch_user_controller.rb @@ -19,7 +19,7 @@ def remember_user private def developer_modes_only - render :text => "Permission Denied", :status => 403 unless available? + raise ActionController::RoutingError.new('Do not try to hack us.') unless available? end def available? From bc007ed069beb21c0ec18e029848b9f0cc3434b8 Mon Sep 17 00:00:00 2001 From: Richard Huang Date: Tue, 16 Jun 2015 19:16:15 +0800 Subject: [PATCH 03/50] Revert "Allow routes to be disabled" This reverts commit fb611a252629b6610f17815b132e559cb95f75b0. --- config/routes.rb | 8 +++----- .../switch_user/install/templates/switch_user.rb | 3 --- lib/switch_user.rb | 2 -- 3 files changed, 3 insertions(+), 10 deletions(-) diff --git a/config/routes.rb b/config/routes.rb index 023e9c2..6308783 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,6 +1,4 @@ -if SwitchUser.generate_routes - Rails.application.routes.draw do - get :switch_user, :to => 'switch_user#set_current_user' - get 'switch_user/remember_user', :to => 'switch_user#remember_user' - end +Rails.application.routes.draw do + get :switch_user, :to => 'switch_user#set_current_user' + get 'switch_user/remember_user', :to => 'switch_user#remember_user' end diff --git a/lib/generators/switch_user/install/templates/switch_user.rb b/lib/generators/switch_user/install/templates/switch_user.rb index e5ff6ec..879ae5a 100644 --- a/lib/generators/switch_user/install/templates/switch_user.rb +++ b/lib/generators/switch_user/install/templates/switch_user.rb @@ -1,7 +1,4 @@ SwitchUser.setup do |config| - # have switch user add routes to its controllers automatically - # config.generate_routes = true - # provider may be :devise, :authlogic, :clearance, :restful_authentication, :sorcery, or :session config.provider = :devise diff --git a/lib/switch_user.rb b/lib/switch_user.rb index 56be5a8..067ddd3 100644 --- a/lib/switch_user.rb +++ b/lib/switch_user.rb @@ -12,7 +12,6 @@ module SwitchUser class InvalidScope < Exception; end - mattr_accessor :generate_routes mattr_accessor :provider mattr_accessor :available_users mattr_accessor :available_users_identifiers @@ -53,7 +52,6 @@ def self.data_sources end def self.reset_config - self.generate_routes = true self.provider = :devise self.available_users = { :user => lambda { User.all } } self.available_users_identifiers = { :user => :id } From d18b4536ddf3887a2ba70d3b488333c0fde94ae4 Mon Sep 17 00:00:00 2001 From: Richard Huang Date: Tue, 16 Jun 2015 19:28:13 +0800 Subject: [PATCH 04/50] Revert "Devise provider- don't store sign_in details" This reverts commit e6147fb8e51e4293a5b00aa6862aec4ca711b7ec. --- lib/switch_user/provider/devise.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/switch_user/provider/devise.rb b/lib/switch_user/provider/devise.rb index c6a9183..930e0a8 100644 --- a/lib/switch_user/provider/devise.rb +++ b/lib/switch_user/provider/devise.rb @@ -7,7 +7,7 @@ def initialize(controller) end def login(user, scope = :user) - @warden.session_serializer.store(user, scope) + @warden.set_user(user, :scope => scope) end def logout(scope = :user) From aab2f22feade6d7e198009867e0c26542094b821 Mon Sep 17 00:00:00 2001 From: Richard Huang Date: Tue, 16 Jun 2015 21:46:23 +0800 Subject: [PATCH 05/50] use rspec 3.3.0 --- .../switch_user_controller_spec.rb | 20 +++++++++---------- spec/integration/switch_user_spec.rb | 18 ++++++++--------- spec/provider/authlogic_spec.rb | 2 +- spec/provider/clearance_spec.rb | 2 +- spec/provider/devise_spec.rb | 14 ++++++------- spec/provider/dummy_spec.rb | 2 +- spec/provider/restful_authentication_spec.rb | 2 +- spec/provider/session_spec.rb | 2 +- spec/provider/sorcery_spec.rb | 2 +- spec/provider_spec.rb | 4 ++-- spec/spec_helper.rb | 1 + spec/support/provider.rb | 20 +++++++++---------- spec/switch_user/data_source_spec.rb | 18 ++++++++--------- spec/switch_user/lambda_guard_spec.rb | 6 +++--- spec/switch_user/user_loader_spec.rb | 14 ++++++------- spec/switch_user/user_set_spec.rb | 20 +++++++++---------- spec/switch_user_spec.rb | 6 +++--- switch_user.gemspec | 3 ++- 18 files changed, 79 insertions(+), 77 deletions(-) diff --git a/spec/controllers/switch_user_controller_spec.rb b/spec/controllers/switch_user_controller_spec.rb index d5efae3..93f068b 100644 --- a/spec/controllers/switch_user_controller_spec.rb +++ b/spec/controllers/switch_user_controller_spec.rb @@ -2,7 +2,7 @@ require 'switch_user' require 'switch_user_controller' -describe SwitchUserController, :type => :controller do +RSpec.describe SwitchUserController, :type => :controller do before do SwitchUser.provider = :dummy end @@ -18,14 +18,14 @@ allow(controller).to receive(:available?).and_return(true) get :set_current_user, :scope_identifier => "user_1" - response.should redirect_to("/path") + expect(response).to redirect_to("/path") end it "denies access according to the guard block" do SwitchUser.controller_guard = lambda {|_,_,_| false } - get :set_current_user - - response.should be_forbidden + expect { + get :set_current_user + }.to raise_error(ActionController::RoutingError) end describe "requests with a privileged original_user" do @@ -37,11 +37,11 @@ it "allows access using the original_user param" do allow(controller).to receive(:provider).and_return(provider) - provider.should_receive(:logout_all) + expect(provider).to receive(:logout_all) get :set_current_user - response.should be_redirect + expect(response).to be_redirect end end end @@ -52,18 +52,18 @@ SwitchUser.switch_back = true end it "can remember the current user" do - provider.should_receive(:remember_current_user).with(true) + expect(provider).to receive(:remember_current_user).with(true) get :remember_user, :remember => "true" end it "can forget the current user" do - provider.should_receive(:remember_current_user).with(false) + expect(provider).to receive(:remember_current_user).with(false) get :remember_user, :remember => "false" end it "does nothing if switch_back is not enabled" do SwitchUser.switch_back = false - provider.should_not_receive(:remember_current_user) + expect(provider).not_to receive(:remember_current_user) get :remember_user, :remember => "true" end diff --git a/spec/integration/switch_user_spec.rb b/spec/integration/switch_user_spec.rb index c1ddd8c..2f467ba 100644 --- a/spec/integration/switch_user_spec.rb +++ b/spec/integration/switch_user_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe "Using SwitchUser", :type => :request do +RSpec.describe "Using SwitchUser", :type => :request do let(:user) { User.create!(:email => "foo@bar.com", :admin => true) } let(:other_user) { User.create!(:email => "other@bar.com", :admin => false) } before do @@ -12,14 +12,14 @@ it "signs a user in using switch_user" do # can't access protected url get "/dummy/protected" - response.should be_redirect + expect(response).to be_redirect get "/switch_user?scope_identifier=user_#{other_user.id}" - response.should be_redirect + expect(response).to be_redirect # now that we are logged in via switch_user we can access get "/dummy/protected" - response.should be_success + expect(response).to be_success end context "using switch_back" do before do @@ -35,23 +35,23 @@ # have SwitchUser remember us get "/switch_user/remember_user", :remember => true - session["original_user_scope_identifier"].should be_present + expect(session["original_user_scope_identifier"]).to be_present # check that we can switch to another user get "/switch_user?scope_identifier=user_#{other_user.id}" - session["user_id"].should == other_user.id + expect(session["user_id"]).to eq other_user.id # logout get "/logout" - session["user_id"].should be_nil + expect(session["user_id"]).to be_nil # check that we can still switch to another user get "/switch_user?scope_identifier=user_#{user.id}" - session["user_id"].should == user.id + expect(session["user_id"]).to eq user.id # check that we can be un-remembered get "/switch_user/remember_user", :remember => false - session["original_user"].should be_nil + expect(session["original_user"]).to be_nil end end end diff --git a/spec/provider/authlogic_spec.rb b/spec/provider/authlogic_spec.rb index 2dbe3c3..cb19877 100644 --- a/spec/provider/authlogic_spec.rb +++ b/spec/provider/authlogic_spec.rb @@ -29,7 +29,7 @@ def current_user_session end end -describe SwitchUser::Provider::Authlogic do +RSpec.describe SwitchUser::Provider::Authlogic do let(:controller) { AuthlogicController.new } let(:provider) { SwitchUser::Provider::Authlogic.new(controller) } diff --git a/spec/provider/clearance_spec.rb b/spec/provider/clearance_spec.rb index 43257e5..5de9ff7 100644 --- a/spec/provider/clearance_spec.rb +++ b/spec/provider/clearance_spec.rb @@ -15,7 +15,7 @@ def current_user end end -describe SwitchUser::Provider::Clearance do +RSpec.describe SwitchUser::Provider::Clearance do let(:controller) { ClearanceController.new } let(:provider) { SwitchUser::Provider::Clearance.new(controller) } diff --git a/spec/provider/devise_spec.rb b/spec/provider/devise_spec.rb index 48a1920..f59a11c 100644 --- a/spec/provider/devise_spec.rb +++ b/spec/provider/devise_spec.rb @@ -32,7 +32,7 @@ def current_user end end -describe SwitchUser::Provider::Devise do +RSpec.describe SwitchUser::Provider::Devise do let(:controller) { DeviseController.new } let(:provider) { SwitchUser::Provider::Devise.new(controller) } let(:user) { double(:user) } @@ -43,7 +43,7 @@ def current_user user = double(:user) provider.login(user, :admin) - provider.current_user(:admin).should == user + expect(provider.current_user(:admin)).to eq user end describe "#login_exclusive" do @@ -54,11 +54,11 @@ def current_user end it "logs the user in" do - provider.current_user.should == user + expect(provider.current_user).to eq user end it "logs out other scopes" do - provider.current_user(:admin).should be_nil + expect(provider.current_user(:admin)).to be_nil end end @@ -70,8 +70,8 @@ def current_user provider.logout_all - provider.current_user(:admin).should be_nil - provider.current_user(:user).should be_nil + expect(provider.current_user(:admin)).to be_nil + expect(provider.current_user(:user)).to be_nil end end @@ -80,7 +80,7 @@ def current_user allow(SwitchUser).to receive(:available_users).and_return({:user => nil, :admin => nil}) provider.login(user, :admin) - provider.current_users_without_scope.should == [user] + expect(provider.current_users_without_scope).to eq [user] end end end diff --git a/spec/provider/dummy_spec.rb b/spec/provider/dummy_spec.rb index 8366532..07b1d93 100644 --- a/spec/provider/dummy_spec.rb +++ b/spec/provider/dummy_spec.rb @@ -4,7 +4,7 @@ class SessionController < TestController end -describe SwitchUser::Provider::Session do +RSpec.describe SwitchUser::Provider::Session do let(:controller) { SessionController.new } let(:provider) { SwitchUser::Provider::Dummy.new(controller) } diff --git a/spec/provider/restful_authentication_spec.rb b/spec/provider/restful_authentication_spec.rb index c433eef..91119df 100644 --- a/spec/provider/restful_authentication_spec.rb +++ b/spec/provider/restful_authentication_spec.rb @@ -9,7 +9,7 @@ def logout_killing_session! end end -describe SwitchUser::Provider::RestfulAuthentication do +RSpec.describe SwitchUser::Provider::RestfulAuthentication do let(:controller) { RestfulAuthenticationController.new } let(:provider) { SwitchUser::Provider::RestfulAuthentication.new(controller) } diff --git a/spec/provider/session_spec.rb b/spec/provider/session_spec.rb index b545ce5..9af32e8 100644 --- a/spec/provider/session_spec.rb +++ b/spec/provider/session_spec.rb @@ -7,7 +7,7 @@ def current_user end end -describe SwitchUser::Provider::Session do +RSpec.describe SwitchUser::Provider::Session do before do SwitchUser.session_key = :uid end diff --git a/spec/provider/sorcery_spec.rb b/spec/provider/sorcery_spec.rb index c43a565..3e3512c 100644 --- a/spec/provider/sorcery_spec.rb +++ b/spec/provider/sorcery_spec.rb @@ -16,7 +16,7 @@ def current_user end end -describe SwitchUser::Provider::Sorcery do +RSpec.describe SwitchUser::Provider::Sorcery do let(:controller) { SorceryController.new } let(:provider) { SwitchUser::Provider::Sorcery.new(controller) } diff --git a/spec/provider_spec.rb b/spec/provider_spec.rb index 2367ff3..97100fc 100644 --- a/spec/provider_spec.rb +++ b/spec/provider_spec.rb @@ -1,10 +1,10 @@ require 'spec_helper' module SwitchUser - describe Provider do + RSpec.describe Provider do it "initializes the provider" do SwitchUser.provider = :dummy - Provider.init(double(:controller)).should be_a(Provider::Dummy) + expect(Provider.init(double(:controller))).to be_a(Provider::Dummy) end end end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index ce15ee2..fe51143 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -10,6 +10,7 @@ config.filter_run :focus => true config.run_all_when_everything_filtered = true config.use_transactional_fixtures = true + config.expose_dsl_globally = false end class TestController diff --git a/spec/support/provider.rb b/spec/support/provider.rb index 6161c39..a2e85a4 100644 --- a/spec/support/provider.rb +++ b/spec/support/provider.rb @@ -1,11 +1,11 @@ -shared_examples_for "a provider" do +RSpec.shared_examples_for "a provider" do let(:user) { User.create! } let(:other_user) { User.create! } it "can log a user in" do provider.login(user) - provider.current_user.should == user + expect(provider.current_user).to eq user end it "can log a user out" do @@ -13,21 +13,21 @@ provider.logout - provider.current_user.should == nil + expect(provider.current_user).to eq nil end it "responds to login_exclusive" do - provider.should respond_to(:login_exclusive) + expect(provider).to respond_to(:login_exclusive) end it "responds to login_exclusive" do - provider.should respond_to(:login_inclusive) + expect(provider).to respond_to(:login_inclusive) end it "knows if there are any users logged in" do provider.login(user) - provider.current_users_without_scope.should == [user] + expect(provider.current_users_without_scope).to eq [user] end it "can lock the original user, allowing us to change current_user" do @@ -35,17 +35,17 @@ provider.remember_current_user(true) provider.login_exclusive(other_user, scope: "user") - provider.original_user.should == user - provider.current_user.should == other_user + expect(provider.original_user).to eq user + expect(provider.current_user).to eq other_user end it "can forget the original_user" do provider.login(user) provider.remember_current_user(true) - provider.original_user.should == user + expect(provider.original_user).to eq user provider.remember_current_user(false) - provider.original_user.should == nil + expect(provider.original_user).to eq nil end end diff --git a/spec/switch_user/data_source_spec.rb b/spec/switch_user/data_source_spec.rb index 6bd6738..b6ca0d5 100644 --- a/spec/switch_user/data_source_spec.rb +++ b/spec/switch_user/data_source_spec.rb @@ -1,22 +1,22 @@ require 'switch_user/data_source' module SwitchUser - describe DataSource do + RSpec.describe DataSource do it "can load users" do loader = lambda { [ double, double] } source = DataSource.new(loader, :user, :id, :email) - source.users.should have(2).records + expect(source.users.size).to eq 2 end end - describe DataSources do + RSpec.describe DataSources do it "aggregates multiple data_sources" do user = double(:user) s1 = double(:s1, :users => [user]) source = DataSources.new([s1,s1]) - source.users.should == [user, user] + expect(source.users).to eq [user, user] end describe "#find_source_id" do @@ -26,12 +26,12 @@ module SwitchUser s2 = double(:s1, :users => [user]) source = DataSources.new([s1,s2]) - source.find_scope_id("user_10").should == user + expect(source.find_scope_id("user_10")).to eq user end end end - describe Record do + RSpec.describe Record do it "can be compared to a identifier string" do id1 = "user_100" id2 = "user_101" @@ -41,9 +41,9 @@ module SwitchUser record = Record.new(user, source) - record.should be_equivalent(id1) - record.should_not be_equivalent(id2) - record.should_not be_equivalent(id3) + expect(record).to be_equivalent(id1) + expect(record).not_to be_equivalent(id2) + expect(record).not_to be_equivalent(id3) end end end diff --git a/spec/switch_user/lambda_guard_spec.rb b/spec/switch_user/lambda_guard_spec.rb index b13f8b4..360ac4c 100644 --- a/spec/switch_user/lambda_guard_spec.rb +++ b/spec/switch_user/lambda_guard_spec.rb @@ -1,7 +1,7 @@ require 'spec_helper' module SwitchUser - describe LambdaGuard do + RSpec.describe LambdaGuard do describe "#controller_available?" do it "calls the controller_guard proc" do controller = double.as_null_object @@ -9,10 +9,10 @@ module SwitchUser guard = SwitchUser::LambdaGuard.new(controller, provider) SwitchUser.controller_guard = lambda {|a| a } - guard.should be_controller_available + expect(guard).to be_controller_available SwitchUser.controller_guard = lambda {|a| !a } - guard.should_not be_controller_available + expect(guard).not_to be_controller_available end end end diff --git a/spec/switch_user/user_loader_spec.rb b/spec/switch_user/user_loader_spec.rb index 9f0d36c..5edfd11 100644 --- a/spec/switch_user/user_loader_spec.rb +++ b/spec/switch_user/user_loader_spec.rb @@ -1,7 +1,7 @@ require 'spec_helper' require 'switch_user/user_loader' -describe SwitchUser::UserLoader do +RSpec.describe SwitchUser::UserLoader do let(:user) { double(:user) } let(:user_result) { [user] } @@ -17,12 +17,12 @@ it "can be loaded from a scope and identifier" do loaded_user = SwitchUser::UserLoader.prepare("user","1").user - loaded_user.should == user + expect(loaded_user).to eq user end it "can be loaded by a passing an unprocessed scope identifier" do loaded_user = SwitchUser::UserLoader.prepare(:scope_identifier => "user_1").user - loaded_user.should == user + expect(loaded_user).to eq user end it "raises an error for an invalid scope" do expect { @@ -36,14 +36,14 @@ loader = SwitchUser::UserLoader.new("user", 1) - loader.user.should == user + expect(loader.user).to eq user end it "returns nil if no user is found" do loader = SwitchUser::UserLoader.new("user", 3) - User.find_by_id(3).should be_nil - loader.user.should == nil + expect(User.find_by_id(3)).to be_nil + expect(loader.user).to eq nil end it "loads a user with an alternate identifier column" do @@ -51,6 +51,6 @@ SwitchUser.available_users_identifiers = {:user => :email} loader = SwitchUser::UserLoader.new("user", 2) - loader.user.should == user + expect(loader.user).to eq user end end diff --git a/spec/switch_user/user_set_spec.rb b/spec/switch_user/user_set_spec.rb index c9cc177..1ddabbe 100644 --- a/spec/switch_user/user_set_spec.rb +++ b/spec/switch_user/user_set_spec.rb @@ -2,33 +2,33 @@ require 'switch_user/user_set' module SwitchUser - describe UserSet do + RSpec.describe UserSet do let!(:user) { User.create(:email => "test@example.com") } let(:set) { UserSet.new(:user, :id, :email, lambda { User.all }) } after { User.delete_all } it "returns an object that knows it's scope, id and label" do found_user = set[user.id] - found_user.id.should == user.id - found_user.scope.should == :user - found_user.label.should == "test@example.com" + expect(found_user.id).to eq user.id + expect(found_user.scope).to eq :user + expect(found_user.label).to eq "test@example.com" end it "returns all available users for a scope" do - set.users.should == [user] + expect(set.users).to eq [user] end it "chains the where on to the provided scope" do set = UserSet.new(:user, :id, :email, lambda { User.all }) - set.find_user(user.id).label.should == user.email + expect(set.find_user(user.id).label).to eq user.email end end - describe UserSet::Record do + RSpec.describe UserSet::Record do it "correctly configures the record using the set" do user = double(:user, :id => 100, :email => "test@example.com") set = double(:set, :identifier => :id, :label => :email, :scope => :user) record = UserSet::Record.build(user, set) - record.id.should == 100 - record.label.should == "test@example.com" - record.scope.should == :user + expect(record.id).to eq 100 + expect(record.label).to eq "test@example.com" + expect(record.scope).to eq :user end end end diff --git a/spec/switch_user_spec.rb b/spec/switch_user_spec.rb index be42491..c7b68e7 100644 --- a/spec/switch_user_spec.rb +++ b/spec/switch_user_spec.rb @@ -1,10 +1,10 @@ require 'spec_helper' require 'switch_user' -describe SwitchUser do +RSpec.describe SwitchUser do describe "#available_scopes" do it "returns a list of available scopes" do - SwitchUser.available_scopes.should == [:user] + expect(SwitchUser.available_scopes).to eq [:user] end end @@ -12,7 +12,7 @@ it "sets the provider" do # ensure we aren't breaking existing functionality SwitchUser.provider = :sorcery - SwitchUser.provider.should == :sorcery + expect(SwitchUser.provider).to eq :sorcery end end end diff --git a/switch_user.gemspec b/switch_user.gemspec index e453285..06d5002 100644 --- a/switch_user.gemspec +++ b/switch_user.gemspec @@ -18,7 +18,8 @@ Gem::Specification.new do |s| s.add_development_dependency "bundler", ">= 1.0.0" s.add_development_dependency "actionpack" s.add_development_dependency "railties" - s.add_development_dependency "rspec-rails", "~> 2.14.0" + s.add_development_dependency "rspec" + s.add_development_dependency "rspec-rails" s.add_development_dependency "tzinfo" s.add_development_dependency "sqlite3" s.add_development_dependency "activerecord" From a979673d704c941e443ce5a69c65e572d9306c60 Mon Sep 17 00:00:00 2001 From: Richard Huang Date: Wed, 17 Jun 2015 07:44:27 +0800 Subject: [PATCH 06/50] add travis-ci --- .travis.yml | 6 ++++++ README.md | 6 ++++-- 2 files changed, 10 insertions(+), 2 deletions(-) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..0b73e54 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,6 @@ +language: ruby +rvm: + - 2.2 +env: + - DB=sqlite +script: bundle exec rspec spec diff --git a/README.md b/README.md index b0c9370..c6328b6 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # switch_user +[![Build Status](https://secure.travis-ci.org/flyerhzm/switch_user.png)](http://travis-ci.org/flyerhzm/switch_user) + Inspired from [hobo][0], switch_user provides a convenient way to switch current user without needing to log out and log in manually. ## Use Case @@ -138,7 +140,7 @@ This example would allow an admin user to user switch_user, but would only let y ### How it works Click the checkbox next to switch_user_select menu to remember that user for this session. Once this -has been checked, that user is passed in as the 3rd option to the view and controller guards. +has been checked, that user is passed in as the 3rd option to the view and controller guards. This allows you to check against current_user as well as that original_user to see if the switch_user action should be allowed. @@ -148,6 +150,6 @@ This feature should be used with extreme caution because of the security implica ## Credit -Copyright © 2010 - 2012 Richard Huang (flyerhzm@gmail.com), released under the MIT license +Copyright © 2010 - 2015 Richard Huang (flyerhzm@gmail.com), released under the MIT license [0]: https://github.com/tablatom/hobo From 837f3acc036f32d27805dbc7bdd655842cc90b20 Mon Sep 17 00:00:00 2001 From: Dylan Jhaveri Date: Tue, 16 Jun 2015 17:47:36 -0700 Subject: [PATCH 07/50] Devise provider- don't store sign_in details * re-implement e6147fb8 (reverted in d18b4536ddf3) * closes flyerhzm/switch_user#67 * warden#set_user sets current_sign_in_at, last_sign_in_at, current_sign_in_ip, sign_in_count, current_sign_in_ip, last_sign_in_ip * use SessionSerialializer#store to bypass the updating of these columns * fix tests --- lib/switch_user/provider/devise.rb | 2 +- spec/provider/devise_spec.rb | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/lib/switch_user/provider/devise.rb b/lib/switch_user/provider/devise.rb index 930e0a8..c6a9183 100644 --- a/lib/switch_user/provider/devise.rb +++ b/lib/switch_user/provider/devise.rb @@ -7,7 +7,7 @@ def initialize(controller) end def login(user, scope = :user) - @warden.set_user(user, :scope => scope) + @warden.session_serializer.store(user, scope) end def logout(scope = :user) diff --git a/spec/provider/devise_spec.rb b/spec/provider/devise_spec.rb index f59a11c..59b8ec6 100644 --- a/spec/provider/devise_spec.rb +++ b/spec/provider/devise_spec.rb @@ -1,6 +1,17 @@ require 'spec_helper' require 'switch_user/provider/devise' +class FakeWardenSessionSerializer + attr_accessor :user_hash + + + def store(user, scope) + return unless user + user_hash[scope] = user + end + +end + class FakeWarden attr_reader :user_hash @@ -13,6 +24,12 @@ def set_user(user, args) @user_hash[scope] = user end + def session_serializer + serializer = FakeWardenSessionSerializer.new + serializer.user_hash = @user_hash + serializer + end + def user(scope) @user_hash[scope] end From 5b536325f82f1c9e5a2e5074cde1586f05ed1a92 Mon Sep 17 00:00:00 2001 From: Dylan Jhaveri Date: Tue, 16 Jun 2015 17:49:51 -0700 Subject: [PATCH 08/50] add README note to run tests --- README.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index c6328b6..62e321e 100644 --- a/README.md +++ b/README.md @@ -148,8 +148,14 @@ switch_user action should be allowed. This feature should be used with extreme caution because of the security implications. This is especially true in a production environment. +## Contributing + +#### Run tests + +`bundle exec rspec spec` + ## Credit Copyright © 2010 - 2015 Richard Huang (flyerhzm@gmail.com), released under the MIT license -[0]: https://github.com/tablatom/hobo +[0]: https://github.com/tablatom/hobo \ No newline at end of file From cdef8398652e0a0bbd0ec89270a8afc3498fc8fb Mon Sep 17 00:00:00 2001 From: Richard Huang Date: Sat, 20 Jun 2015 21:05:56 +0800 Subject: [PATCH 09/50] only load necessary data #72 SwitchUser.all_users only selects identifier and name columns. SwitchUser.data_sources.find_scope_id only queries that user. --- lib/switch_user.rb | 4 +- lib/switch_user/data_source.rb | 66 ++++++++++++------- spec/integration/switch_user_spec.rb | 4 ++ spec/switch_user/data_source_spec.rb | 98 +++++++++++++++++++--------- 4 files changed, 116 insertions(+), 56 deletions(-) diff --git a/lib/switch_user.rb b/lib/switch_user.rb index 067ddd3..9205766 100644 --- a/lib/switch_user.rb +++ b/lib/switch_user.rb @@ -38,7 +38,7 @@ def self.guard_class=(klass) end def self.all_users - data_sources.users + data_sources.all end def self.data_sources @@ -47,7 +47,7 @@ def self.data_sources name = available_users_names.fetch(scope) DataSource.new(loader, scope, identifier, name) end - sources.unshift(GuestDataSource.new("Guest")) if helper_with_guest + sources.unshift(GuestDataSource.new) if helper_with_guest DataSources.new(sources) end diff --git a/lib/switch_user/data_source.rb b/lib/switch_user/data_source.rb index 05246b3..709a7d5 100644 --- a/lib/switch_user/data_source.rb +++ b/lib/switch_user/data_source.rb @@ -1,50 +1,55 @@ module SwitchUser - DataSource = Struct.new(:loader, :scope, :identifier, :name) do - def users - loader.call.map {|u| Record.new(u, self) } - end - end + class DataSources + attr_reader :sources - GuestRecord = Struct.new(:scope) do - def equivalent?(other_scope_id) - scope_id == other_scope_id + def initialize(sources) + @sources = sources end - def label - "Guest" + def all + sources.flat_map { |source| source.all } end - def scope_id + def find_scope_id(scope_id) + sources.map {|source| source.find_scope_id(scope_id) }.compact.first end end - class GuestDataSource - def initialize(name) + class DataSource + attr_reader :loader, :scope, :identifier, :name + + def initialize(loader, scope, identifier, name) + @loader = loader + @scope = scope + @identifier = identifier @name = name end - def users - [ GuestRecord.new(self) ] + def all + loader.call.select(identifier, name).map { |user| Record.new(user, self) } + end + + def find_scope_id(scope_id) + user = loader.call.find_by identifier => scope_id.delete("#{scope}_") + Record.new(user, self) end end - DataSources = Struct.new(:sources) do + class GuestDataSource def users - sources.flat_map {|source| source.users } + [ GuestRecord.new ] end def find_scope_id(scope_id) - users.flat_map.detect {|u| u.scope_id == scope_id } end end - Record = Struct.new(:user, :source) do - def equivalent?(other_scope_id) - scope_id == other_scope_id - end + class Record + attr_reader :user, :source - def scope_id - "#{source.scope}_#{user.send(source.identifier)}" + def initialize(user, source) + @user = user + @source = source end def label @@ -54,5 +59,18 @@ def label def scope source.scope end + + def scope_id + "#{source.scope}_#{user.send(source.identifier)}" + end + end + + class GuestRecord + def label + "Guest" + end + + def scope_id + end end end diff --git a/spec/integration/switch_user_spec.rb b/spec/integration/switch_user_spec.rb index 2f467ba..e192280 100644 --- a/spec/integration/switch_user_spec.rb +++ b/spec/integration/switch_user_spec.rb @@ -3,12 +3,14 @@ RSpec.describe "Using SwitchUser", :type => :request do let(:user) { User.create!(:email => "foo@bar.com", :admin => true) } let(:other_user) { User.create!(:email => "other@bar.com", :admin => false) } + before do SwitchUser.reset_config SwitchUser.provider = :session SwitchUser.controller_guard = lambda { |current_user, request| Rails.env.test? } SwitchUser.redirect_path = lambda {|_,_| "/dummys/open"} end + it "signs a user in using switch_user" do # can't access protected url get "/dummy/protected" @@ -21,6 +23,7 @@ get "/dummy/protected" expect(response).to be_success end + context "using switch_back" do before do SwitchUser.switch_back = true @@ -28,6 +31,7 @@ current_user && current_user.admin? || original_user && original_user.admin? } end + it "can switch back to a different user" do # login post "/login", :id => user.id diff --git a/spec/switch_user/data_source_spec.rb b/spec/switch_user/data_source_spec.rb index b6ca0d5..bff7e10 100644 --- a/spec/switch_user/data_source_spec.rb +++ b/spec/switch_user/data_source_spec.rb @@ -1,49 +1,87 @@ require 'switch_user/data_source' module SwitchUser + RSpec.describe DataSources do + describe '#all' do + it 'aggregates multiple data_sources' do + user = double(:user) + s1 = double(:s1, :all => [user]) + source = DataSources.new([s1, s1]) + + expect(source.all).to eq [user, user] + end + end + + describe '#find_scope_id' do + it 'can find a corresponding record across data sources' do + user = double(:user) + s1 = double(:s1, :find_scope_id => nil) + s2 = double(:s2, :find_scope_id => user) + source = DataSources.new([s1, s2]) + + expect(source.find_scope_id("user_10")).to eq user + end + end + end + RSpec.describe DataSource do - it "can load users" do - loader = lambda { [ double, double] } - source = DataSource.new(loader, :user, :id, :email) + pending # it's tested in integration test, need to find a good way to test it here. + end - expect(source.users.size).to eq 2 + RSpec.describe GuestDataSource do + let(:source) { GuestDataSource.new } + + describe '#users' do + it 'gets a GuestRecord' do + expect(source.users.size).to eq 1 + expect(source.users.first).to be_instance_of GuestRecord + end + end + + describe '#find_scope_id' do + it 'gets nil' do + expect(source.find_scope_id('')).to be_nil + end end end - RSpec.describe DataSources do - it "aggregates multiple data_sources" do - user = double(:user) - s1 = double(:s1, :users => [user]) - source = DataSources.new([s1,s1]) + RSpec.describe Record do + let(:source) { DataSource.new({}, :user, :id, :email) } + let(:user) { double(:user, id: '1', email: 'flyerhzm@gmail.com') } + let(:record) { Record.new(user, source) } - expect(source.users).to eq [user, user] + describe '#label' do + it 'gets user email' do + expect(record.label).to eq 'flyerhzm@gmail.com' + end end - describe "#find_source_id" do - it "can find a corresponding record across data sources" do - user = double(:user, :scope_id => "user_10") - s1 = double(:s1, :users => []) - s2 = double(:s1, :users => [user]) - source = DataSources.new([s1,s2]) + describe '#scope' do + it 'gets user' do + expect(record.scope).to eq :user + end + end - expect(source.find_scope_id("user_10")).to eq user + describe '#scope_id' do + it 'gets scope and id' do + expect(record.scope_id).to eq 'user_1' end end end - RSpec.describe Record do - it "can be compared to a identifier string" do - id1 = "user_100" - id2 = "user_101" - id3 = "staff_100" - user = double(:user, :id => 100, :email => "test@example.com") - source = DataSource.new(nil, :user, :id, :email) - - record = Record.new(user, source) - - expect(record).to be_equivalent(id1) - expect(record).not_to be_equivalent(id2) - expect(record).not_to be_equivalent(id3) + RSpec.describe GuestRecord do + let(:record) { GuestRecord.new } + + describe '#label' do + it 'gets Guest' do + expect(record.label).to eq 'Guest' + end + end + + describe '#scope_id' do + it 'gets nil' do + expect(record.scope_id).to be_nil + end end end end From 3827d60422967eb3ceef1ac8924f251f9e316820 Mon Sep 17 00:00:00 2001 From: Richard Huang Date: Mon, 22 Jun 2015 20:31:21 +0800 Subject: [PATCH 10/50] Bumping version to 1.0.0 --- CHANGELOG.md | 126 +++++++++++++++++++++++++++++++++++++ lib/switch_user/version.rb | 2 +- 2 files changed, 127 insertions(+), 1 deletion(-) create mode 100644 CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..20a4a79 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,126 @@ +# Next Release + +## 4.14.8 + +* compatible with `composite_primary_keys` gem + +## 4.14.7 + +* Fix AR 4.2 SingularAssociation#reader result can be nil +* `perform_out_of_channel_notifications` should always be triggered + +## 4.14.6 + +* Fix false positive with `belongs_to` -> `belongs_to` for active\_record 4.2 +* Activate active\_record hacks only when Bullet already start + +## 4.14.5 + +* Don't execute query when running `to_sql` +* Send backtrace to `uniform_notifier` +* Fix sse response check +* Dynamically delegate available notifiers to UniformNotifier + +## 4.14.4 + +* Fix false N + 1 warnings on Rails 4.2 + +## 4.14.3 + +* Fix false positive on create + +## 4.14.2 + +* Hotfix nil object when `add_impossible_object` + +## 4.14.1 + +* Fix `has_one` then `has_many` associations in rails 4.2 +* Append js and dom to html body in proper position + +## 4.14.0 (10/03/2014) + +* Support rails 4.2 +* Polish notification output +* Fix warning: `*' interpreted as argument prefix + +## 4.13.0 (07/19/2014) + +* Support include? call on ar associations + +## 4.12.0 (07/13/2014) + +* Fix false n+1 queries caused by inversed objects. +* Replace .id with .primary_key_value +* Rename bullet_ar_key to bullet_key +* Fix rails sse detect +* Fix bullet using in test environment +* Memoize whoami + +## 4.11.0 (06/24/2014) + +* Support empty? call on ar associations +* Skip detecting if object is a new record + +## 4.10.0 (06/06/2014) + +* Handle join query smarter +* Support mongoid 4.0 +* Thread safe +* Add debug mode + +## 4.9.0 (04/30/2014) + +* Add Bullet.stacktrace_includes option +* Applied keyword argument fixes on Ruby 2.2.0 +* Add bugsnag notifier +* Support rails 4.1.0 + +## 4.8.0 (02/16/2014) + +* Support rails 4.1.0.beta1 +* Update specs to be RSpec 3.0 compatible +* Update latest minor version activerecord and mongoid on travis + +## 4.7.0 (11/03/2013) + +* Add coverall support +* Add helper to profile code outside a request +* Add activesupport dependency +* Add Bullet.raise notification +* Add Bullet.add_footer notification +* Fix activerecord4 warnings in test code + +## 4.6.0 (04/18/2013) + +* Fix Bullet::Rack to support sinatra + +## 4.5.0 (03/24/2013) + +* Add api way to access captured associatioin +* Allow disable n_plus_one_query, unused_eager_loading and counter_cache respectively +* Add whitelist + +## 4.4.0 (03/15/2013) + +* Remove disable_browser_cache option +* Compatible with Rails 4.0.0.beta1 + +## 4.3.0 (12/28/2012) + +* Fix content-length for non ascii html +* Add mongoid 2.5.x support + +## 4.2.0 (09/29/2012) + +* Add Bullet::Dependency to check AR and mongoid version +* Add Rails 4 support +* Add airbrake notifier support + +## 4.1.0 (05/30/2012) + +* Add mongoid 3 support + +## 4.0.0 (05/09/2012) + +* Add mongoid support diff --git a/lib/switch_user/version.rb b/lib/switch_user/version.rb index 92d8ca4..29ed608 100644 --- a/lib/switch_user/version.rb +++ b/lib/switch_user/version.rb @@ -1,3 +1,3 @@ module SwitchUser - VERSION = "0.9.5" + VERSION = "1.0.0" end From 77ce40a9243e2409dacb8f50db48e0273bfaa770 Mon Sep 17 00:00:00 2001 From: Richard Huang Date: Tue, 23 Jun 2015 05:52:16 +0800 Subject: [PATCH 11/50] update README --- CHANGELOG.md | 128 ++------------------------------------------------- 1 file changed, 5 insertions(+), 123 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 20a4a79..be8011c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,126 +1,8 @@ # Next Release -## 4.14.8 +## 1.0.0 (06/22/2015) -* compatible with `composite_primary_keys` gem - -## 4.14.7 - -* Fix AR 4.2 SingularAssociation#reader result can be nil -* `perform_out_of_channel_notifications` should always be triggered - -## 4.14.6 - -* Fix false positive with `belongs_to` -> `belongs_to` for active\_record 4.2 -* Activate active\_record hacks only when Bullet already start - -## 4.14.5 - -* Don't execute query when running `to_sql` -* Send backtrace to `uniform_notifier` -* Fix sse response check -* Dynamically delegate available notifiers to UniformNotifier - -## 4.14.4 - -* Fix false N + 1 warnings on Rails 4.2 - -## 4.14.3 - -* Fix false positive on create - -## 4.14.2 - -* Hotfix nil object when `add_impossible_object` - -## 4.14.1 - -* Fix `has_one` then `has_many` associations in rails 4.2 -* Append js and dom to html body in proper position - -## 4.14.0 (10/03/2014) - -* Support rails 4.2 -* Polish notification output -* Fix warning: `*' interpreted as argument prefix - -## 4.13.0 (07/19/2014) - -* Support include? call on ar associations - -## 4.12.0 (07/13/2014) - -* Fix false n+1 queries caused by inversed objects. -* Replace .id with .primary_key_value -* Rename bullet_ar_key to bullet_key -* Fix rails sse detect -* Fix bullet using in test environment -* Memoize whoami - -## 4.11.0 (06/24/2014) - -* Support empty? call on ar associations -* Skip detecting if object is a new record - -## 4.10.0 (06/06/2014) - -* Handle join query smarter -* Support mongoid 4.0 -* Thread safe -* Add debug mode - -## 4.9.0 (04/30/2014) - -* Add Bullet.stacktrace_includes option -* Applied keyword argument fixes on Ruby 2.2.0 -* Add bugsnag notifier -* Support rails 4.1.0 - -## 4.8.0 (02/16/2014) - -* Support rails 4.1.0.beta1 -* Update specs to be RSpec 3.0 compatible -* Update latest minor version activerecord and mongoid on travis - -## 4.7.0 (11/03/2013) - -* Add coverall support -* Add helper to profile code outside a request -* Add activesupport dependency -* Add Bullet.raise notification -* Add Bullet.add_footer notification -* Fix activerecord4 warnings in test code - -## 4.6.0 (04/18/2013) - -* Fix Bullet::Rack to support sinatra - -## 4.5.0 (03/24/2013) - -* Add api way to access captured associatioin -* Allow disable n_plus_one_query, unused_eager_loading and counter_cache respectively -* Add whitelist - -## 4.4.0 (03/15/2013) - -* Remove disable_browser_cache option -* Compatible with Rails 4.0.0.beta1 - -## 4.3.0 (12/28/2012) - -* Fix content-length for non ascii html -* Add mongoid 2.5.x support - -## 4.2.0 (09/29/2012) - -* Add Bullet::Dependency to check AR and mongoid version -* Add Rails 4 support -* Add airbrake notifier support - -## 4.1.0 (05/30/2012) - -* Add mongoid 3 support - -## 4.0.0 (05/09/2012) - -* Add mongoid support +* performance improved, only load necessary data. +* Devise provider- don't store sign_in details +* security :guardsman:, raise RoutingError in developer_modes_only +* Restore original user after sorcery logout From 775dd28fbfb37d336ba0e8d08e770f666ff744d8 Mon Sep 17 00:00:00 2001 From: Richard Huang Date: Wed, 24 Jun 2015 06:51:42 +0800 Subject: [PATCH 12/50] GuestDataSource#users should be renamed to GuestDataSource#all #75 --- lib/switch_user/data_source.rb | 2 +- spec/switch_user/data_source_spec.rb | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/switch_user/data_source.rb b/lib/switch_user/data_source.rb index 709a7d5..2541f42 100644 --- a/lib/switch_user/data_source.rb +++ b/lib/switch_user/data_source.rb @@ -36,7 +36,7 @@ def find_scope_id(scope_id) end class GuestDataSource - def users + def all [ GuestRecord.new ] end diff --git a/spec/switch_user/data_source_spec.rb b/spec/switch_user/data_source_spec.rb index bff7e10..bb90447 100644 --- a/spec/switch_user/data_source_spec.rb +++ b/spec/switch_user/data_source_spec.rb @@ -31,10 +31,10 @@ module SwitchUser RSpec.describe GuestDataSource do let(:source) { GuestDataSource.new } - describe '#users' do + describe '#all' do it 'gets a GuestRecord' do - expect(source.users.size).to eq 1 - expect(source.users.first).to be_instance_of GuestRecord + expect(source.all.size).to eq 1 + expect(source.all.first).to be_instance_of GuestRecord end end From 03be237b617c68e3d0d7901dac08021446397277 Mon Sep 17 00:00:00 2001 From: Richard Huang Date: Fri, 26 Jun 2015 21:20:29 +0800 Subject: [PATCH 13/50] allow custom method as available_users_names --- lib/switch_user/data_source.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/switch_user/data_source.rb b/lib/switch_user/data_source.rb index 2541f42..c634243 100644 --- a/lib/switch_user/data_source.rb +++ b/lib/switch_user/data_source.rb @@ -26,7 +26,7 @@ def initialize(loader, scope, identifier, name) end def all - loader.call.select(identifier, name).map { |user| Record.new(user, self) } + loader.call.map { |user| Record.new(user, self) } end def find_scope_id(scope_id) From 501a3725bea058d36eb02fa7b9f7ec15dca64541 Mon Sep 17 00:00:00 2001 From: Richard Huang Date: Fri, 26 Jun 2015 21:23:01 +0800 Subject: [PATCH 14/50] Bumping version to 1.0.1 --- CHANGELOG.md | 11 ++++++++--- lib/switch_user/version.rb | 2 +- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index be8011c..15fb3fe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,13 @@ # Next Release +## 1.0.1 + +* Fix typo in `GuestDataSource` +* Allow custom method as `available_users_names` + ## 1.0.0 (06/22/2015) -* performance improved, only load necessary data. -* Devise provider- don't store sign_in details -* security :guardsman:, raise RoutingError in developer_modes_only +* Performance improved, only load necessary data. +* Devise provider- don't store `sign_in` details +* Security :guardsman:, raise RoutingError in `developer_modes_only` * Restore original user after sorcery logout diff --git a/lib/switch_user/version.rb b/lib/switch_user/version.rb index 29ed608..47b59a7 100644 --- a/lib/switch_user/version.rb +++ b/lib/switch_user/version.rb @@ -1,3 +1,3 @@ module SwitchUser - VERSION = "1.0.0" + VERSION = "1.0.1" end From e8705c0f3b75a38f73d75aa1f71776bf2347b46b Mon Sep 17 00:00:00 2001 From: Eric Tipton Date: Sat, 27 Jun 2015 03:39:47 -0700 Subject: [PATCH 15/50] 1. Use String#sub, not String#delete to remove scope str from scope_id str 2. Don't attempt to query db if scope str isn't in scope_id str --- lib/switch_user/data_source.rb | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/switch_user/data_source.rb b/lib/switch_user/data_source.rb index c634243..26e7ece 100644 --- a/lib/switch_user/data_source.rb +++ b/lib/switch_user/data_source.rb @@ -30,7 +30,10 @@ def all end def find_scope_id(scope_id) - user = loader.call.find_by identifier => scope_id.delete("#{scope}_") + scope_regexp = /\A#{scope}_/ + return unless scope_id =~ scope_regexp + + user = loader.call.find_by identifier => scope_id.sub(scope_regexp, '') Record.new(user, self) end end From 464f28511d5fba7483bf77796b16be4b631cdacf Mon Sep 17 00:00:00 2001 From: Richard Huang Date: Mon, 29 Jun 2015 17:13:16 +0800 Subject: [PATCH 16/50] Bumping version to 1.0.2 --- CHANGELOG.md | 4 ++++ lib/switch_user/version.rb | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 15fb3fe..d8c8b6d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Next Release +## 1.0.2 + +* Don't attempt to query db if scope str isn't in scope_id str + ## 1.0.1 * Fix typo in `GuestDataSource` diff --git a/lib/switch_user/version.rb b/lib/switch_user/version.rb index 47b59a7..223e192 100644 --- a/lib/switch_user/version.rb +++ b/lib/switch_user/version.rb @@ -1,3 +1,3 @@ module SwitchUser - VERSION = "1.0.1" + VERSION = "1.0.2" end From a0e0de12733bfe5f4e6e764f484a36a9df89b29f Mon Sep 17 00:00:00 2001 From: Richard Huang Date: Thu, 2 Jul 2015 05:28:02 +0800 Subject: [PATCH 17/50] rails 3.2 compatibility --- lib/switch_user/data_source.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/switch_user/data_source.rb b/lib/switch_user/data_source.rb index 26e7ece..dabf141 100644 --- a/lib/switch_user/data_source.rb +++ b/lib/switch_user/data_source.rb @@ -33,7 +33,7 @@ def find_scope_id(scope_id) scope_regexp = /\A#{scope}_/ return unless scope_id =~ scope_regexp - user = loader.call.find_by identifier => scope_id.sub(scope_regexp, '') + user = loader.call.where(identifier => scope_id.sub(scope_regexp, '')).first Record.new(user, self) end end From 7d7719de2907d4a050fb04e9529f4b08e333fa74 Mon Sep 17 00:00:00 2001 From: Richard Huang Date: Thu, 2 Jul 2015 05:30:51 +0800 Subject: [PATCH 18/50] Bumping version to 1.1.0 --- CHANGELOG.md | 9 +++------ lib/switch_user/version.rb | 2 +- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d8c8b6d..ce2418e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,12 +1,9 @@ # Next Release -## 1.0.2 +## 1.1.0 (07/01/2015) -* Don't attempt to query db if scope str isn't in scope_id str - -## 1.0.1 - -* Fix typo in `GuestDataSource` +* Rails 3.x compatibility +* Don't attempt to query db if scope str isn't in `scope_id` str * Allow custom method as `available_users_names` ## 1.0.0 (06/22/2015) diff --git a/lib/switch_user/version.rb b/lib/switch_user/version.rb index 223e192..c8bcc23 100644 --- a/lib/switch_user/version.rb +++ b/lib/switch_user/version.rb @@ -1,3 +1,3 @@ module SwitchUser - VERSION = "1.0.2" + VERSION = "1.1.0" end From 1e83673ae66b3bcd3bdae76d4095edf5e04c8d24 Mon Sep 17 00:00:00 2001 From: vkill Date: Sun, 20 Sep 2015 00:36:57 +0800 Subject: [PATCH 19/50] replace select option to group_option --- .gitignore | 2 ++ app/helpers/switch_user_helper.rb | 13 +++++++++++-- app/views/switch_user/_widget.html.erb | 2 +- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index 95cf2de..61982c5 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,8 @@ pkg/* *.gem .bundle .rvmrc +.ruby-version +.versions.conf Gemfile.lock log/*.log .DS_Store diff --git a/app/helpers/switch_user_helper.rb b/app/helpers/switch_user_helper.rb index 258fe9e..e882ad8 100644 --- a/app/helpers/switch_user_helper.rb +++ b/app/helpers/switch_user_helper.rb @@ -9,10 +9,19 @@ def switch_user_select selected_user = nil end + grouped_options_container = {}.tap do |h| + SwitchUser.all_users.each do |record| + scope = record.is_a?(SwitchUser::GuestRecord) ? :Guest : record.scope.to_s.capitalize + h[scope] ||= [] + h[scope] << [record.label, record.scope_id] + end + end + + option_tags = grouped_options_for_select(grouped_options_container, selected_user) + render :partial => "switch_user/widget", :locals => { - :options => SwitchUser.all_users, - :current_scope => selected_user + :option_tags => option_tags } end diff --git a/app/views/switch_user/_widget.html.erb b/app/views/switch_user/_widget.html.erb index a0c5590..0dfae23 100644 --- a/app/views/switch_user/_widget.html.erb +++ b/app/views/switch_user/_widget.html.erb @@ -1,4 +1,4 @@ <% if SwitchUser.switch_back %> <%= check_box_tag "remember_user", "remember_user", provider.original_user.present?, :onchange => "location.href = '/switch_user/remember_user?remember=' + encodeURIComponent(this.checked)" %> <% end %> -<%= select_tag "switch_user_identifier", options_from_collection_for_select(options, :scope_id, :label, current_scope), :onchange => "location.href = '/switch_user?scope_identifier=' + encodeURIComponent(this.options[this.selectedIndex].value)" %> +<%= select_tag "switch_user_identifier", option_tags, :onchange => "location.href = '/switch_user?scope_identifier=' + encodeURIComponent(this.options[this.selectedIndex].value)" %> From bd39823a2a8fd6a3de13cbdf9a060627780d1901 Mon Sep 17 00:00:00 2001 From: vkill Date: Sun, 20 Sep 2015 02:08:49 +0800 Subject: [PATCH 20/50] add helper rspec --- app/helpers/switch_user_helper.rb | 2 +- spec/helpers/switch_user_helper_spec.rb | 134 ++++++++++++++++++++++++ 2 files changed, 135 insertions(+), 1 deletion(-) create mode 100644 spec/helpers/switch_user_helper_spec.rb diff --git a/app/helpers/switch_user_helper.rb b/app/helpers/switch_user_helper.rb index e882ad8..f97511d 100644 --- a/app/helpers/switch_user_helper.rb +++ b/app/helpers/switch_user_helper.rb @@ -4,7 +4,7 @@ def switch_user_select return unless available? if provider.current_user - selected_user = "user_#{current_user.id}" + selected_user = "user_#{provider.current_user.id}" else selected_user = nil end diff --git a/spec/helpers/switch_user_helper_spec.rb b/spec/helpers/switch_user_helper_spec.rb new file mode 100644 index 0000000..85e4d0c --- /dev/null +++ b/spec/helpers/switch_user_helper_spec.rb @@ -0,0 +1,134 @@ +require 'spec_helper' +require 'switch_user' +require 'switch_user_helper' + +RSpec.describe SwitchUserHelper, :type => :helper do + before do + SwitchUser.provider = :dummy + end + + let(:user) { double(:user, :id => 1) } + let(:provider) { + _provider = SwitchUser::Provider::Dummy.new(controller) + _provider.instance_variable_set(:@user, user) + _provider + } + + describe "#switch_user_select" do + let(:guest_record) { SwitchUser::GuestRecord.new } + let(:user_record) { double(:user_record, :scope => :user, :label => 'user1', :scope_id => 'user_1') } + + let(:guest_option_tags) { %Q^^ } + let(:user_option_tags) { %Q^^ } + let(:user_selected_option_tags) { %Q^^ } + + + before do + allow(SwitchUser).to receive(:switch_back).and_return(false) + + allow(helper).to receive(:available?).and_return(true) + + allow(helper).to receive(:provider).and_return(provider) + allow(provider).to receive(:current_user).and_return(user) + + allow(SwitchUser).to receive(:all_users).and_return([guest_record, user_record]) + end + + it "when unavailable" do + allow(helper).to receive(:available?).and_return(false) + + expect(helper.switch_user_select).to eq(nil) + end + + it "when current_user is nil and all_users is []" do + allow(provider).to receive(:current_user).and_return(nil) + allow(SwitchUser).to receive(:all_users).and_return([]) + + expect(helper.switch_user_select).not_to match(%r{}) + end + + it "when current_user is nil and all_users is [guest_record]" do + allow(provider).to receive(:current_user).and_return(nil) + allow(SwitchUser).to receive(:all_users).and_return([guest_record]) + + expect(helper.switch_user_select).to match(%r{#{guest_option_tags}}) + end + + it "when current_user is nil and all_users is [guest_record, user_record]" do + allow(provider).to receive(:current_user).and_return(nil) + allow(SwitchUser).to receive(:all_users).and_return([guest_record, user_record]) + + expect(helper.switch_user_select).to match(%r{#{guest_option_tags}}) + expect(helper.switch_user_select).to match(%r{#{user_option_tags}}) + end + + it "when current_user is user and all_users is []" do + allow(provider).to receive(:current_user).and_return(user) + allow(SwitchUser).to receive(:all_users).and_return([]) + + expect(helper.switch_user_select).not_to match(%r{}) + end + + it "when current_user is user and all_users is [guest_record, user_record]" do + allow(provider).to receive(:current_user).and_return(user) + allow(SwitchUser).to receive(:all_users).and_return([guest_record, user_record]) + + expect(helper.switch_user_select).to match(%r{#{guest_option_tags}}) + expect(helper.switch_user_select).to match(%r{#{user_selected_option_tags}}) + end + + it "when current_user is default allow and all_users is default allow" do + expect(helper.switch_user_select).to match(%r{#{guest_option_tags}}) + expect(helper.switch_user_select).to match(%r{#{user_selected_option_tags}}) + end + + end + + describe "#user_tag_value" do + it "for user" do + user = double(:user, :id => 1) + + expect(helper.send(:user_tag_value, user, :id, :user)).to eq('user_1') + end + end + + describe "#user_tag_label" do + it "when name has call method" do + user = double(:user) + name = ->(user){ 'user1' } + + expect(helper.send(:user_tag_label, user, name)).to eq('user1') + end + + it "when name not has call method" do + user = double(:name, :name => 'user1') + name = :name + + expect(helper.send(:user_tag_label, user, name)).to eq('user1') + end + end + + describe "#available?" do + it "return true" do + allow_any_instance_of(SwitchUser.guard_class).to receive(:view_available?).and_return(true) + + expect(helper.send(:available?)).to eq(true) + end + + it "return false" do + allow_any_instance_of(SwitchUser.guard_class).to receive(:view_available?).and_return(false) + + expect(helper.send(:available?)).to eq(false) + end + end + + describe "#provider" do + it "normal" do + allow(SwitchUser::Provider).to receive(:init).with(controller).and_return(provider) + + expect(helper.send(:provider)).to eq(provider) + end + end + + +end From 57efa2a057466d59e558ab36023c6afe2b64b7e9 Mon Sep 17 00:00:00 2001 From: Richard Huang Date: Tue, 1 Dec 2015 19:48:48 +0800 Subject: [PATCH 21/50] update README for rails 3.2 --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 62e321e..5a8f478 100644 --- a/README.md +++ b/README.md @@ -62,7 +62,7 @@ SwitchUser.setup do |config| # available_users is a hash, # key is the model name of user (:user, :admin, or any name you use), # value is a block that return the users that can be switched. - config.available_users = { :user => lambda { User.all } } + config.available_users = { :user => lambda { User.all } } # use User.scoped instead for rails 3.2 # available_users_identifiers is a hash, # keys in this hash should match a key in the available_users hash @@ -158,4 +158,4 @@ This feature should be used with extreme caution because of the security implica Copyright © 2010 - 2015 Richard Huang (flyerhzm@gmail.com), released under the MIT license -[0]: https://github.com/tablatom/hobo \ No newline at end of file +[0]: https://github.com/tablatom/hobo From 12004c3c020ec2b317326388aed02f5f2d1b75af Mon Sep 17 00:00:00 2001 From: Richard Huang Date: Tue, 1 Dec 2015 19:50:16 +0800 Subject: [PATCH 22/50] Bumping version to 1.2.0 --- CHANGELOG.md | 4 ++++ lib/switch_user/version.rb | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ce2418e..e369a84 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Next Release +## 1.2.0 (12/01/2015) + +* Replace select option to `group_option` + ## 1.1.0 (07/01/2015) * Rails 3.x compatibility diff --git a/lib/switch_user/version.rb b/lib/switch_user/version.rb index c8bcc23..7f92ffa 100644 --- a/lib/switch_user/version.rb +++ b/lib/switch_user/version.rb @@ -1,3 +1,3 @@ module SwitchUser - VERSION = "1.1.0" + VERSION = "1.2.0" end From 075d10f9d532d0a352c3cdc95abad05dcd741c74 Mon Sep 17 00:00:00 2001 From: vkill Date: Tue, 22 Dec 2015 17:47:56 +0800 Subject: [PATCH 23/50] fix grouped_options_for_select bug for rails 3.2 --- app/helpers/switch_user_helper.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/helpers/switch_user_helper.rb b/app/helpers/switch_user_helper.rb index f97511d..2f9511d 100644 --- a/app/helpers/switch_user_helper.rb +++ b/app/helpers/switch_user_helper.rb @@ -17,7 +17,7 @@ def switch_user_select end end - option_tags = grouped_options_for_select(grouped_options_container, selected_user) + option_tags = grouped_options_for_select(grouped_options_container.to_a, selected_user) render :partial => "switch_user/widget", :locals => { From 18cc9f9875fd899058bf94204e6663721b8e878e Mon Sep 17 00:00:00 2001 From: Richard Huang Date: Tue, 22 Dec 2015 20:20:23 +0800 Subject: [PATCH 24/50] Bumping version to 1.2.1 --- CHANGELOG.md | 4 ++++ lib/switch_user/version.rb | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e369a84..dcaf583 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Next Release +## 1.2.1 (12/22/2015) + +* Fix `grouped_options_for_select` for rails 3.2 + ## 1.2.0 (12/01/2015) * Replace select option to `group_option` diff --git a/lib/switch_user/version.rb b/lib/switch_user/version.rb index 7f92ffa..db2e34b 100644 --- a/lib/switch_user/version.rb +++ b/lib/switch_user/version.rb @@ -1,3 +1,3 @@ module SwitchUser - VERSION = "1.2.0" + VERSION = "1.2.1" end From f7df7bfa34aa2b8729cfc350dd91ff70e7b16ce5 Mon Sep 17 00:00:00 2001 From: Weston Ganger Date: Wed, 10 Feb 2016 17:11:31 -0800 Subject: [PATCH 25/50] add class and style options to switch_user_select --- README.md | 6 ++++++ app/helpers/switch_user_helper.rb | 6 ++++-- app/views/switch_user/_widget.html.erb | 2 +- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 5a8f478..28a79c5 100644 --- a/README.md +++ b/README.md @@ -36,6 +36,12 @@ or haml = switch_user_select +If you want to add a class or styles + + <%= switch_user_select class: 'special-select', styles: 'width: 220px' %> + + = switch_user_select class: 'special-select', styles: 'width: 220px' + If there are too many users (on production), the switch_user_select is not a good choice, you should call the switch user request by yourself. <%= link_to user.login, "/switch_user?scope_identifier=user_#{user.id}" %> diff --git a/app/helpers/switch_user_helper.rb b/app/helpers/switch_user_helper.rb index 2f9511d..e6617bc 100644 --- a/app/helpers/switch_user_helper.rb +++ b/app/helpers/switch_user_helper.rb @@ -1,6 +1,6 @@ module SwitchUserHelper SelectOption = Struct.new(:label, :scope_id) - def switch_user_select + def switch_user_select(options = {}) return unless available? if provider.current_user @@ -21,7 +21,9 @@ def switch_user_select render :partial => "switch_user/widget", :locals => { - :option_tags => option_tags + :option_tags => option_tags, + :classes => options[:class], + :styles => options[:style], } end diff --git a/app/views/switch_user/_widget.html.erb b/app/views/switch_user/_widget.html.erb index 0dfae23..32a2331 100644 --- a/app/views/switch_user/_widget.html.erb +++ b/app/views/switch_user/_widget.html.erb @@ -1,4 +1,4 @@ <% if SwitchUser.switch_back %> <%= check_box_tag "remember_user", "remember_user", provider.original_user.present?, :onchange => "location.href = '/switch_user/remember_user?remember=' + encodeURIComponent(this.checked)" %> <% end %> -<%= select_tag "switch_user_identifier", option_tags, :onchange => "location.href = '/switch_user?scope_identifier=' + encodeURIComponent(this.options[this.selectedIndex].value)" %> +<%= select_tag "switch_user_identifier", option_tags, :onchange => "location.href = '/switch_user?scope_identifier=' + encodeURIComponent(this.options[this.selectedIndex].value)", :class => classes, :style => styles %> From 2f283114741a5ed4779f54e546c30b6607399edc Mon Sep 17 00:00:00 2001 From: Richard Huang Date: Thu, 11 Feb 2016 15:48:58 +1000 Subject: [PATCH 26/50] fix travis setting --- .travis.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index 0b73e54..9c8de13 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,4 +3,6 @@ rvm: - 2.2 env: - DB=sqlite +before_install: + - gem update bundler script: bundle exec rspec spec From e7cff856be011770514fbb367e2a205bc54d8ee4 Mon Sep 17 00:00:00 2001 From: vkill Date: Thu, 14 Apr 2016 12:28:26 +0800 Subject: [PATCH 27/50] fix selected_user_of_helper bug --- app/helpers/switch_user_helper.rb | 14 ++++--- lib/switch_user/provider/base.rb | 5 +++ spec/helpers/switch_user_helper_spec.rb | 49 ++++++++++++++++++++++--- spec/provider/devise_spec.rb | 10 +++++ 4 files changed, 68 insertions(+), 10 deletions(-) diff --git a/app/helpers/switch_user_helper.rb b/app/helpers/switch_user_helper.rb index 2f9511d..a56c4b1 100644 --- a/app/helpers/switch_user_helper.rb +++ b/app/helpers/switch_user_helper.rb @@ -3,17 +3,21 @@ module SwitchUserHelper def switch_user_select return unless available? - if provider.current_user - selected_user = "user_#{provider.current_user.id}" - else - selected_user = nil - end + selected_user = nil grouped_options_container = {}.tap do |h| SwitchUser.all_users.each do |record| scope = record.is_a?(SwitchUser::GuestRecord) ? :Guest : record.scope.to_s.capitalize h[scope] ||= [] h[scope] << [record.label, record.scope_id] + + if selected_user.nil? + unless record.is_a?(SwitchUser::GuestRecord) + if provider.current_user?(record.user, record.scope) + selected_user = record.scope_id + end + end + end end end diff --git a/lib/switch_user/provider/base.rb b/lib/switch_user/provider/base.rb index d7c3233..384292a 100644 --- a/lib/switch_user/provider/base.rb +++ b/lib/switch_user/provider/base.rb @@ -55,6 +55,11 @@ def remember_current_user(remember) def clear_original_user @controller.session.delete(:original_user_scope_identifier) end + + def current_user?(user, scope = :user) + current_user(scope) == user + end + end end end diff --git a/spec/helpers/switch_user_helper_spec.rb b/spec/helpers/switch_user_helper_spec.rb index 85e4d0c..1f0c127 100644 --- a/spec/helpers/switch_user_helper_spec.rb +++ b/spec/helpers/switch_user_helper_spec.rb @@ -8,19 +8,22 @@ end let(:user) { double(:user, :id => 1) } - let(:provider) { - _provider = SwitchUser::Provider::Dummy.new(controller) - _provider.instance_variable_set(:@user, user) + let(:admin) { double(:admin, :id => 1) } + let(:provider) { + _provider = SwitchUser::Provider::Dummy.new(controller) _provider } describe "#switch_user_select" do let(:guest_record) { SwitchUser::GuestRecord.new } - let(:user_record) { double(:user_record, :scope => :user, :label => 'user1', :scope_id => 'user_1') } - + let(:user_record) { double(:user_record, :user => user, :scope => :user, :label => 'user1', :scope_id => 'user_1') } + let(:admin_record) { double(:admin_record, :user => admin, :scope => :admin, :label => 'admin1', :scope_id => 'admin_1') } + let(:guest_option_tags) { %Q^^ } let(:user_option_tags) { %Q^^ } let(:user_selected_option_tags) { %Q^^ } + let(:admin_option_tags) { %Q^^ } + let(:admin_selected_option_tags) { %Q^^ } before do @@ -28,7 +31,9 @@ allow(helper).to receive(:available?).and_return(true) + provider.instance_variable_set(:@user, user) allow(helper).to receive(:provider).and_return(provider) + allow(provider).to receive(:current_user).and_return(user) allow(SwitchUser).to receive(:all_users).and_return([guest_record, user_record]) @@ -82,6 +87,40 @@ expect(helper.switch_user_select).to match(%r{#{user_selected_option_tags}}) end + it "when current_user is user and all_users is [guest_record, user_record, admin_record]" do + allow(provider).to receive(:current_user).and_return(user) + allow(SwitchUser).to receive(:all_users).and_return([guest_record, user_record, admin_record]) + + expect(helper.switch_user_select).to match(%r{#{guest_option_tags}}) + expect(helper.switch_user_select).to match(%r{#{user_selected_option_tags}}) + expect(helper.switch_user_select).to match(%r{#{admin_option_tags}}) + end + + it "when current_user is admin and all_users is [guest_record, user_record, admin_record]" do + provider.instance_variable_set(:@user, admin) + allow(helper).to receive(:provider).and_return(provider) + + allow(provider).to receive(:current_user).and_return(admin) + + allow(SwitchUser).to receive(:all_users).and_return([guest_record, user_record, admin_record]) + + expect(helper.switch_user_select).to match(%r{#{guest_option_tags}}) + expect(helper.switch_user_select).to match(%r{#{user_option_tags}}) + expect(helper.switch_user_select).to match(%r{#{admin_selected_option_tags}}) + end + + it "when current_user is admin and all_users is [guest_record, user_record]" do + provider.instance_variable_set(:@user, admin) + allow(helper).to receive(:provider).and_return(provider) + + allow(provider).to receive(:current_user).and_return(admin) + + allow(SwitchUser).to receive(:all_users).and_return([guest_record, user_record]) + + expect(helper.switch_user_select).to match(%r{#{guest_option_tags}}) + expect(helper.switch_user_select).to match(%r{#{user_option_tags}}) + expect(helper.switch_user_select).to_not match(%r{#{admin_option_tags}}) + end end describe "#user_tag_value" do diff --git a/spec/provider/devise_spec.rb b/spec/provider/devise_spec.rb index 59b8ec6..c35e10f 100644 --- a/spec/provider/devise_spec.rb +++ b/spec/provider/devise_spec.rb @@ -100,4 +100,14 @@ def current_user expect(provider.current_users_without_scope).to eq [user] end end + + describe "#current_user?" do + it "logs the user in" do + user = double(:user) + provider.login(user, :user) + + expect(provider.current_user?(user, :user)).to eq true + expect(provider.current_user?(user, :admin)).to eq false + end + end end From a0a0bd774d8a8648e4af1ff1ad0ca09d826dc72f Mon Sep 17 00:00:00 2001 From: vkill Date: Sat, 16 Apr 2016 12:06:21 +0800 Subject: [PATCH 28/50] support capybara --- README.md | 26 ++++++ lib/switch_user/rspec.rb | 13 +++ lib/switch_user/rspec/feature_helpers.rb | 44 +++++++++ spec/rspec/feature_helpers_spec.rb | 113 +++++++++++++++++++++++ spec/support/application.rb | 7 ++ switch_user.gemspec | 1 + 6 files changed, 204 insertions(+) create mode 100644 lib/switch_user/rspec.rb create mode 100644 lib/switch_user/rspec/feature_helpers.rb create mode 100644 spec/rspec/feature_helpers_spec.rb diff --git a/README.md b/README.md index 5a8f478..011fee4 100644 --- a/README.md +++ b/README.md @@ -137,6 +137,32 @@ config.controller_guard = lambda { |current_user, request, original_user| ``` This example would allow an admin user to user switch_user, but would only let you switch back to another user if the original user was a super admin. +## Using SwitchUser with RSpec and Capybara + +Add the following code to spec/support/switch_user.rb or spec/spec_helper.rb : + +```ruby +require 'switch_user/rspec' +``` + +You can now write your specs like so : + +```ruby +feature "Your feature" do + background do + @user = User.make(:email => 'user@example.com', :password => 'password') + end + + scenario "Your scenario" do + switch_user @user + # or + # switch_user :user, @user.id + + visit '/' + end +end +``` + ### How it works Click the checkbox next to switch_user_select menu to remember that user for this session. Once this diff --git a/lib/switch_user/rspec.rb b/lib/switch_user/rspec.rb new file mode 100644 index 0000000..9dee0ac --- /dev/null +++ b/lib/switch_user/rspec.rb @@ -0,0 +1,13 @@ +require 'switch_user/rspec/feature_helpers' + +require 'rspec/core' + +RSpec.configure do |config| + + config.include SwitchUser::RSpecFeatureHelpers, :type => :feature + + config.before(:each) do + allow_any_instance_of(SwitchUserController).to receive(:available?).and_return(true) + end + +end diff --git a/lib/switch_user/rspec/feature_helpers.rb b/lib/switch_user/rspec/feature_helpers.rb new file mode 100644 index 0000000..b789306 --- /dev/null +++ b/lib/switch_user/rspec/feature_helpers.rb @@ -0,0 +1,44 @@ +module SwitchUser + module RSpecFeatureHelpers + + class InvalidArgument < StandardError; end + + def switch_user(user_record_or_scope, user_id=nil) + _user_scope = + case user_record_or_scope + when ActiveRecord::Base + user_record_or_scope.model_name.singular + else + user_record_or_scope + end + + _user_scope = _user_scope.to_s + + unless (SwitchUser.available_scopes.include?(_user_scope) or SwitchUser.available_scopes.include?(_user_scope.to_sym)) + raise SwitchUser::InvalidScope.new("don't allow this user sign in, please check config.available_users") + end + + _user_id = + case user_record_or_scope + when ActiveRecord::Base + identifier = SwitchUser.available_users_identifiers[_user_scope] || SwitchUser.available_users_identifiers[_user_scope.to_sym] + if identifier.nil? + raise SwitchUser::InvalidScope.new("don't allow switch this user, please check config.available_users_identifiers") + end + user_record_or_scope.send identifier + else + user_id + end + + if _user_id.to_s.empty? + raise InvalidArgument.new("don't allow switch this user, user_id is empty") + end + + scope_identifier = "#{_user_scope}_#{_user_id}" + + visit "/switch_user?scope_identifier=#{scope_identifier}" + end + + end + +end diff --git a/spec/rspec/feature_helpers_spec.rb b/spec/rspec/feature_helpers_spec.rb new file mode 100644 index 0000000..626cb91 --- /dev/null +++ b/spec/rspec/feature_helpers_spec.rb @@ -0,0 +1,113 @@ +require 'spec_helper' + +require 'capybara/rspec' +require 'capybara/rails' +Capybara.app = MyApp::Application + +require 'switch_user/rspec' + +RSpec.feature "SwitchUser::RSpecFeatureHelpers", :type => :feature do + background do + @user = User.create!(:email => "foo@bar.com", :admin => true) + @client = Client.create!(:email => "foo@bar.com") + end + + before(:each) do + allow(SwitchUser).to receive(:controller_guard).and_return(lambda{|current_user, request| true}) + + allow(SwitchUser).to receive(:available_users).and_return({:user => lambda { User.all }}) + + allow(SwitchUser).to receive(:available_users_identifiers).and_return({:user => :id}) + end + + scenario "when controller_guard return false" do + allow(SwitchUser).to receive(:controller_guard).and_return(lambda{|current_user, request| false}) + + expect do + switch_user @user + end.to_not raise_error ActionController::RoutingError + end + + scenario "arg is @user, available_users is default, and available_users_identifiers is default" do + expect do + switch_user @user + end.to_not raise_error + end + + scenario "arg is @user, available_users is default, and available_users_identifiers is {user: id}" do + allow(SwitchUser).to receive(:available_users_identifiers).and_return({user: :id}) + + expect do + switch_user @user + end.to_not raise_error + end + + scenario "arg is @user, available_users is default, and available_users_identifiers is {:admin => :id}" do + allow(SwitchUser).to receive(:available_users_identifiers).and_return({:admin => :id}) + + expect do + switch_user @user + end.to raise_error SwitchUser::InvalidScope, /config.available_users_identifiers/ + end + + scenario "arg is @client, available_users is default, and available_users_identifiers is default" do + expect do + switch_user @client + end.to raise_error SwitchUser::InvalidScope, /config.available_users/ + end + + scenario "arg is @client, available_users is {:user => lambda { User.all }, :client => lambda {Client.all}}, and available_users_identifiers is default" do + allow(SwitchUser).to receive(:available_users).and_return({:user => lambda { User.all }, :client => lambda {Client.all}}) + + expect do + switch_user @client + end.to raise_error SwitchUser::InvalidScope, /config.available_users_identifiers/ + end + + scenario "arg is @client, available_users is {:user => lambda { User.all }, :client => lambda {Client.all}}, and available_users_identifiers is {:user => id, :client => id}" do + allow(SwitchUser).to receive(:available_users).and_return({:user => lambda { User.all }, :client => lambda {Client.all}}) + + allow(SwitchUser).to receive(:available_users_identifiers).and_return({:user => :id, :client => :id}) + + expect do + switch_user @client + end.to_not raise_error + end + + scenario "args is :user and @user.id, available_users is default, and available_users_identifiers is default" do + expect do + switch_user :user, @user.id + end.to_not raise_error + end + + scenario "arg is :client and @client.id, available_users is default, and available_users_identifiers is default" do + expect do + switch_user :client, @client.id + end.to raise_error SwitchUser::InvalidScope, /config.available_users/ + end + + scenario "args is :user, available_users is default, and available_users_identifiers is default" do + expect do + switch_user :user + end.to raise_error SwitchUser::RSpecFeatureHelpers::InvalidArgument, /user_id is empty/ + end + + scenario "args is :user and nil, available_users is default, and available_users_identifiers is default" do + expect do + switch_user :user, nil + end.to raise_error SwitchUser::RSpecFeatureHelpers::InvalidArgument, /user_id is empty/ + end + + scenario "args is :user and '', available_users is default, and available_users_identifiers is default" do + expect do + switch_user :user, '' + end.to raise_error SwitchUser::RSpecFeatureHelpers::InvalidArgument, /user_id is empty/ + end + + scenario "args is :user and 0, available_users is default, and available_users_identifiers is default" do + expect do + switch_user :user, 0 + end.to_not raise_error + end + +end diff --git a/spec/support/application.rb b/spec/support/application.rb index 523a1d2..5aa6bb2 100644 --- a/spec/support/application.rb +++ b/spec/support/application.rb @@ -67,3 +67,10 @@ class Application < Rails::Application class User < ActiveRecord::Base end + +connection.create_table :clients do |t| + t.column :email, :string +end + +class Client < ActiveRecord::Base +end diff --git a/switch_user.gemspec b/switch_user.gemspec index 06d5002..23cbe01 100644 --- a/switch_user.gemspec +++ b/switch_user.gemspec @@ -25,6 +25,7 @@ Gem::Specification.new do |s| s.add_development_dependency "activerecord" s.add_development_dependency "awesome_print" s.add_development_dependency "pry" + s.add_development_dependency "capybara" s.files = `git ls-files`.split("\n") s.executables = `git ls-files`.split("\n").map{|f| f =~ /^bin\/(.*)/ ? $1 : nil}.compact From 6e8531f7771c2d0b038aa15467154277fca76e2d Mon Sep 17 00:00:00 2001 From: vkill Date: Sat, 16 Apr 2016 13:07:34 +0800 Subject: [PATCH 29/50] fix 'rspec do not raise exception' but --- spec/support/application.rb | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/spec/support/application.rb b/spec/support/application.rb index 523a1d2..d418300 100644 --- a/spec/support/application.rb +++ b/spec/support/application.rb @@ -5,7 +5,7 @@ class ApplicationController < ActionController::Base def require_user - current_user || redirect_to("/tests/open") + current_user || redirect_to("/dummy/open") end def current_user @@ -16,11 +16,13 @@ def login user = User.find(params[:id]) session[SwitchUser.session_key] = user.id - redirect_to("/tests/protected") + redirect_to("/dummy/protected") end def logout session[SwitchUser.session_key] = nil + + redirect_to("/dummy/open") end end @@ -46,6 +48,9 @@ class Application < Rails::Application config.secret_key_base = "abc123" config.eager_load = true config.secret_token = '153572e559247c7aedd1bca5a246874d' + + # should set it + config.action_dispatch.show_exceptions = false end end Rails.application.initialize! From 1019be56a3712a22580d27f5c459033c285e6d77 Mon Sep 17 00:00:00 2001 From: vkill Date: Sat, 16 Apr 2016 13:17:05 +0800 Subject: [PATCH 30/50] rename /dummys/open to /dummy/open --- spec/integration/switch_user_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/integration/switch_user_spec.rb b/spec/integration/switch_user_spec.rb index e192280..a693940 100644 --- a/spec/integration/switch_user_spec.rb +++ b/spec/integration/switch_user_spec.rb @@ -8,7 +8,7 @@ SwitchUser.reset_config SwitchUser.provider = :session SwitchUser.controller_guard = lambda { |current_user, request| Rails.env.test? } - SwitchUser.redirect_path = lambda {|_,_| "/dummys/open"} + SwitchUser.redirect_path = lambda {|_,_| "/dummy/open"} end it "signs a user in using switch_user" do From 0b5d02132485bba0e0e189c433d9f43090f5b9dc Mon Sep 17 00:00:00 2001 From: vkill Date: Sat, 16 Apr 2016 13:34:55 +0800 Subject: [PATCH 31/50] edit rspec/feature_helpers_spec.rb --- spec/rspec/feature_helpers_spec.rb | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/spec/rspec/feature_helpers_spec.rb b/spec/rspec/feature_helpers_spec.rb index 626cb91..e387407 100644 --- a/spec/rspec/feature_helpers_spec.rb +++ b/spec/rspec/feature_helpers_spec.rb @@ -18,6 +18,8 @@ allow(SwitchUser).to receive(:available_users).and_return({:user => lambda { User.all }}) allow(SwitchUser).to receive(:available_users_identifiers).and_return({:user => :id}) + + allow(SwitchUser).to receive(:available_users_names).and_return({:user => :email}) end scenario "when controller_guard return false" do @@ -25,7 +27,17 @@ expect do switch_user @user - end.to_not raise_error ActionController::RoutingError + end.to_not raise_error ActionController::RoutingError, /Do not try to hack us/ + end + + scenario "when controller_guard return false and controller call original available?" do + allow(SwitchUser).to receive(:controller_guard).and_return(lambda{|current_user, request| false}) + + allow_any_instance_of(SwitchUserController).to receive(:available?).and_call_original + + expect do + switch_user @user + end.to raise_error ActionController::RoutingError, /Do not try to hack us/ end scenario "arg is @user, available_users is default, and available_users_identifiers is default" do @@ -42,8 +54,9 @@ end.to_not raise_error end - scenario "arg is @user, available_users is default, and available_users_identifiers is {:admin => :id}" do - allow(SwitchUser).to receive(:available_users_identifiers).and_return({:admin => :id}) + scenario "arg is @user, available_users is default, and available_users_identifiers is {:client => :id}" do + allow(SwitchUser).to receive(:available_users_identifiers).and_return({:client => :id}) + allow(SwitchUser).to receive(:available_users_names).and_return({:client => :email}) expect do switch_user @user @@ -68,6 +81,7 @@ allow(SwitchUser).to receive(:available_users).and_return({:user => lambda { User.all }, :client => lambda {Client.all}}) allow(SwitchUser).to receive(:available_users_identifiers).and_return({:user => :id, :client => :id}) + allow(SwitchUser).to receive(:available_users_names).and_return({:user => :email, :client => :email}) expect do switch_user @client @@ -80,7 +94,7 @@ end.to_not raise_error end - scenario "arg is :client and @client.id, available_users is default, and available_users_identifiers is default" do + scenario "arg is :client and @client.id, available_users is default, and available_users_identifiers is default" do expect do switch_user :client, @client.id end.to raise_error SwitchUser::InvalidScope, /config.available_users/ From b9ec5e6db44a51e51400d33d84615dcc9bdff607 Mon Sep 17 00:00:00 2001 From: colorfulberry Date: Mon, 18 Apr 2016 21:00:32 +0800 Subject: [PATCH 32/50] Update switch_user_controller.rb before_filter is deprecated and will removed in Rails 5.1. --- app/controllers/switch_user_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/switch_user_controller.rb b/app/controllers/switch_user_controller.rb index 3aaf835..5c703e2 100644 --- a/app/controllers/switch_user_controller.rb +++ b/app/controllers/switch_user_controller.rb @@ -1,5 +1,5 @@ class SwitchUserController < ApplicationController - before_filter :developer_modes_only + before_action :developer_modes_only def set_current_user handle_request(params) From d7d6f9d273afdc99906e71505f087cf848b28a6a Mon Sep 17 00:00:00 2001 From: Weston Ganger Date: Thu, 21 Jul 2016 16:49:29 -0700 Subject: [PATCH 33/50] make it work with relative url root --- README.md | 3 ++- app/views/switch_user/_widget.html.erb | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 28a79c5..8b79948 100644 --- a/README.md +++ b/README.md @@ -53,7 +53,8 @@ If there are too many users (on production), the switch_user_select is not a goo If you have a wildcard route in your project, add a route before the wildcard route. ```ruby # config/routes.rb -get 'switch_user' => 'switch_user#set_current_user' +get 'switch_user', to: 'switch_user#set_current_user' +get 'switch_user/remember_user', to: 'switch_user#remember_user' # wildcard route that will get get ':id' => 'pages#show' ``` diff --git a/app/views/switch_user/_widget.html.erb b/app/views/switch_user/_widget.html.erb index 32a2331..29c04fc 100644 --- a/app/views/switch_user/_widget.html.erb +++ b/app/views/switch_user/_widget.html.erb @@ -1,4 +1,4 @@ <% if SwitchUser.switch_back %> <%= check_box_tag "remember_user", "remember_user", provider.original_user.present?, :onchange => "location.href = '/switch_user/remember_user?remember=' + encodeURIComponent(this.checked)" %> <% end %> -<%= select_tag "switch_user_identifier", option_tags, :onchange => "location.href = '/switch_user?scope_identifier=' + encodeURIComponent(this.options[this.selectedIndex].value)", :class => classes, :style => styles %> +<%= select_tag "switch_user_identifier", option_tags, :onchange => "location.href = '#{Rails.relative_root_url || '/'}switch_user?scope_identifier=' + encodeURIComponent(this.options[this.selectedIndex].value)", :class => classes, :style => styles %> From 3549e35176c14669e7184a495854064c8e8746fc Mon Sep 17 00:00:00 2001 From: Richard Huang Date: Fri, 22 Jul 2016 16:38:18 +0800 Subject: [PATCH 34/50] fix travis --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 9c8de13..44f6b5b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,6 @@ language: ruby rvm: - - 2.2 + - 2.3.0 env: - DB=sqlite before_install: From be1d086f11c162ccaafdac7a55390e69f069edd2 Mon Sep 17 00:00:00 2001 From: Richard Huang Date: Fri, 22 Jul 2016 16:44:31 +0800 Subject: [PATCH 35/50] remove Rails.relative_root_url --- app/views/switch_user/_widget.html.erb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/switch_user/_widget.html.erb b/app/views/switch_user/_widget.html.erb index 29c04fc..32a2331 100644 --- a/app/views/switch_user/_widget.html.erb +++ b/app/views/switch_user/_widget.html.erb @@ -1,4 +1,4 @@ <% if SwitchUser.switch_back %> <%= check_box_tag "remember_user", "remember_user", provider.original_user.present?, :onchange => "location.href = '/switch_user/remember_user?remember=' + encodeURIComponent(this.checked)" %> <% end %> -<%= select_tag "switch_user_identifier", option_tags, :onchange => "location.href = '#{Rails.relative_root_url || '/'}switch_user?scope_identifier=' + encodeURIComponent(this.options[this.selectedIndex].value)", :class => classes, :style => styles %> +<%= select_tag "switch_user_identifier", option_tags, :onchange => "location.href = '/switch_user?scope_identifier=' + encodeURIComponent(this.options[this.selectedIndex].value)", :class => classes, :style => styles %> From fc1e1db6d6858f2e7ef351d79a3feca2deb4cbe9 Mon Sep 17 00:00:00 2001 From: Richard Huang Date: Sat, 23 Jul 2016 13:08:06 +0800 Subject: [PATCH 36/50] apply before each only for type feature --- lib/switch_user/rspec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/switch_user/rspec.rb b/lib/switch_user/rspec.rb index 9dee0ac..996cf13 100644 --- a/lib/switch_user/rspec.rb +++ b/lib/switch_user/rspec.rb @@ -6,7 +6,7 @@ config.include SwitchUser::RSpecFeatureHelpers, :type => :feature - config.before(:each) do + config.before(:each, :type => :feature) do allow_any_instance_of(SwitchUserController).to receive(:available?).and_return(true) end From 25ab0790005894613ed94c9dec6259fc4cb3d81b Mon Sep 17 00:00:00 2001 From: Richard Huang Date: Sat, 23 Jul 2016 13:12:14 +0800 Subject: [PATCH 37/50] Bumping version to 1.3.0 --- CHANGELOG.md | 5 +++++ README.md | 8 ++++---- lib/switch_user/version.rb | 2 +- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dcaf583..5e22aad 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Next Release +## 1.3.0 (07/23/2016) + +* Add capybara support +* Add class and style options to `switch_user_select` + ## 1.2.1 (12/22/2015) * Fix `grouped_options_for_select` for rails 3.2 diff --git a/README.md b/README.md index a7fa72b..8cc3247 100644 --- a/README.md +++ b/README.md @@ -37,11 +37,11 @@ or haml = switch_user_select If you want to add a class or styles - + <%= switch_user_select class: 'special-select', styles: 'width: 220px' %> - + = switch_user_select class: 'special-select', styles: 'width: 220px' - + If there are too many users (on production), the switch_user_select is not a good choice, you should call the switch user request by yourself. <%= link_to user.login, "/switch_user?scope_identifier=user_#{user.id}" %> @@ -155,7 +155,7 @@ require 'switch_user/rspec' You can now write your specs like so : ```ruby -feature "Your feature" do +feature "Your feature", type: :feature do background do @user = User.make(:email => 'user@example.com', :password => 'password') end diff --git a/lib/switch_user/version.rb b/lib/switch_user/version.rb index db2e34b..1e16214 100644 --- a/lib/switch_user/version.rb +++ b/lib/switch_user/version.rb @@ -1,3 +1,3 @@ module SwitchUser - VERSION = "1.2.1" + VERSION = "1.3.0" end From 5258eac20c9fe925a6eb793e5a934940a46f4f0c Mon Sep 17 00:00:00 2001 From: Weston Ganger Date: Fri, 22 Jul 2016 07:32:24 -0700 Subject: [PATCH 38/50] Respect the relative_url_root for applications deployed to sub-directories --- app/views/switch_user/_widget.html.erb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/views/switch_user/_widget.html.erb b/app/views/switch_user/_widget.html.erb index 32a2331..f16d236 100644 --- a/app/views/switch_user/_widget.html.erb +++ b/app/views/switch_user/_widget.html.erb @@ -1,4 +1,8 @@ <% if SwitchUser.switch_back %> <%= check_box_tag "remember_user", "remember_user", provider.original_user.present?, :onchange => "location.href = '/switch_user/remember_user?remember=' + encodeURIComponent(this.checked)" %> <% end %> +<<<<<<< 1a474df14a16dfcec697be5d50ac67512afd6cea <%= select_tag "switch_user_identifier", option_tags, :onchange => "location.href = '/switch_user?scope_identifier=' + encodeURIComponent(this.options[this.selectedIndex].value)", :class => classes, :style => styles %> +======= +<%= select_tag "switch_user_identifier", option_tags, :onchange => "location.href = '#{ActionController::Base.relative_url_root || '/'}switch_user?scope_identifier=' + encodeURIComponent(this.options[this.selectedIndex].value)", :class => classes, :style => styles %> +>>>>>>> Respect the relative_url_root for applications deployed to sub-directories From e7b4f98c21c3b81fa8ff4bee38c382e13c50d0ab Mon Sep 17 00:00:00 2001 From: Weston Ganger Date: Sat, 23 Jul 2016 08:54:07 -0700 Subject: [PATCH 39/50] Respect relative_url_root --- app/views/switch_user/_widget.html.erb | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/app/views/switch_user/_widget.html.erb b/app/views/switch_user/_widget.html.erb index f16d236..8fae500 100644 --- a/app/views/switch_user/_widget.html.erb +++ b/app/views/switch_user/_widget.html.erb @@ -1,8 +1,4 @@ <% if SwitchUser.switch_back %> - <%= check_box_tag "remember_user", "remember_user", provider.original_user.present?, :onchange => "location.href = '/switch_user/remember_user?remember=' + encodeURIComponent(this.checked)" %> + <%= check_box_tag "remember_user", "remember_user", provider.original_user.present?, :onchange => "location.href = '#{ActionController::Base.relative_url_root || '/'}switch_user/remember_user?remember=' + encodeURIComponent(this.checked)" %> <% end %> -<<<<<<< 1a474df14a16dfcec697be5d50ac67512afd6cea -<%= select_tag "switch_user_identifier", option_tags, :onchange => "location.href = '/switch_user?scope_identifier=' + encodeURIComponent(this.options[this.selectedIndex].value)", :class => classes, :style => styles %> -======= <%= select_tag "switch_user_identifier", option_tags, :onchange => "location.href = '#{ActionController::Base.relative_url_root || '/'}switch_user?scope_identifier=' + encodeURIComponent(this.options[this.selectedIndex].value)", :class => classes, :style => styles %> ->>>>>>> Respect the relative_url_root for applications deployed to sub-directories From 35fdffa1ff1ad5446afa0e0d4ec74a7a71b258fd Mon Sep 17 00:00:00 2001 From: Richard Huang Date: Sun, 21 Aug 2016 20:54:01 +0800 Subject: [PATCH 40/50] Bumping version to 1.3.1 --- CHANGELOG.md | 5 +++++ lib/switch_user/version.rb | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5e22aad..f035a7c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Next Release +## 1.3.1 + +* Respect `relative_url_root` +* Fix `selected_user_of_helper` bug + ## 1.3.0 (07/23/2016) * Add capybara support diff --git a/lib/switch_user/version.rb b/lib/switch_user/version.rb index 1e16214..abea0a3 100644 --- a/lib/switch_user/version.rb +++ b/lib/switch_user/version.rb @@ -1,3 +1,3 @@ module SwitchUser - VERSION = "1.3.0" + VERSION = "1.3.1" end From 92d4e00c7952ad47cf27714b0570018dfc1f1f13 Mon Sep 17 00:00:00 2001 From: Weston Ganger Date: Mon, 3 Oct 2016 12:59:23 -0700 Subject: [PATCH 41/50] add ability to store_sign_in info with devise provider --- README.md | 2 +- lib/switch_user/provider.rb | 11 +++++++++-- lib/switch_user/provider/devise.rb | 6 +++++- 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 8cc3247..08a22ec 100644 --- a/README.md +++ b/README.md @@ -63,7 +63,7 @@ get ':id' => 'pages#show' By default, you can switch between Guest and all users in users table, you don't need to do anything. The following is some of the more commonly used configuration options. ```ruby SwitchUser.setup do |config| - # provider may be :devise, :authlogic, :clearance, :restful_authentication or :sorcery + # provider may be :devise, :authlogic, :clearance, :restful_authentication, :sorcery, or {name: :devise, store_sign_in: true} config.provider = :devise # available_users is a hash, diff --git a/lib/switch_user/provider.rb b/lib/switch_user/provider.rb index 2d873a6..d0c4d18 100644 --- a/lib/switch_user/provider.rb +++ b/lib/switch_user/provider.rb @@ -10,8 +10,15 @@ module Provider autoload :Session, "switch_user/provider/session" def self.init(controller) - klass_part = SwitchUser.provider.to_s.classify - klass = "SwitchUser::Provider::#{klass_part}".constantize + if SwitchUser.provider.is_a?(Hash) + klass_part = SwitchUser.provider[:name] + else + klass_part = SwitchUser.provider + end + + klass_part = klass_part.to_s.classify + + klass = "SwitchUser::Provider::#{klass_part}".constantize klass.new(controller) end diff --git a/lib/switch_user/provider/devise.rb b/lib/switch_user/provider/devise.rb index c6a9183..3981e61 100644 --- a/lib/switch_user/provider/devise.rb +++ b/lib/switch_user/provider/devise.rb @@ -7,7 +7,11 @@ def initialize(controller) end def login(user, scope = :user) - @warden.session_serializer.store(user, scope) + if SwitchUser.provider.is_a?(Hash) && SwitchUser.provider[:store_sign_in] + @warden.set_user(user, scope: scope) + else + @warden.session_serializer.store(user, scope) + end end def logout(scope = :user) From e2a7bb868c50db6a21b68db9ac00e57f7e611fb3 Mon Sep 17 00:00:00 2001 From: Richard Huang Date: Fri, 21 Oct 2016 17:46:37 +0800 Subject: [PATCH 42/50] Bumping version to 1.4.0 --- CHANGELOG.md | 6 ++---- lib/switch_user/version.rb | 2 +- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f035a7c..0c15023 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,8 @@ # Next Release -## 1.3.1 +## 1.4.0 (10/21/2016) +* Add ability to `store_sign_in` info with devise provider * Respect `relative_url_root` * Fix `selected_user_of_helper` bug @@ -9,9 +10,6 @@ * Add capybara support * Add class and style options to `switch_user_select` - -## 1.2.1 (12/22/2015) - * Fix `grouped_options_for_select` for rails 3.2 ## 1.2.0 (12/01/2015) diff --git a/lib/switch_user/version.rb b/lib/switch_user/version.rb index abea0a3..ab7f5eb 100644 --- a/lib/switch_user/version.rb +++ b/lib/switch_user/version.rb @@ -1,3 +1,3 @@ module SwitchUser - VERSION = "1.3.1" + VERSION = "1.4.0" end From dd0b6b13669f93c0b011290053fafafacd314ffd Mon Sep 17 00:00:00 2001 From: Marcus Vieira Date: Tue, 25 Oct 2016 15:20:29 -0700 Subject: [PATCH 43/50] Allow `SwitchUser.switch_back` to be considered even when not calling `#remember_user`. We need to be able to tell the gem that we want the user to be remembered so that we can switch back to it. It was unclear how it should've been done, so this is making sure that we don't have to make two calls to the `SwitchUser API`, just to make sure the original user will be remembered. Related Issue: flyerhzm/switch_user/issues/55 --- app/controllers/switch_user_controller.rb | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/app/controllers/switch_user_controller.rb b/app/controllers/switch_user_controller.rb index 5c703e2..b923bec 100644 --- a/app/controllers/switch_user_controller.rb +++ b/app/controllers/switch_user_controller.rb @@ -1,5 +1,5 @@ class SwitchUserController < ApplicationController - before_action :developer_modes_only + before_action :developer_modes_only, :switch_back def set_current_user handle_request(params) @@ -8,16 +8,17 @@ def set_current_user end def remember_user - # NOOP unless the user has explicity enabled this feature - if SwitchUser.switch_back - provider.remember_current_user(params[:remember] == "true") - end - redirect_to(SwitchUser.redirect_path.call(request, params)) end private + def switch_back + if SwitchUser.switch_back + provider.remember_current_user(params[:remember] == "true") + end + end + def developer_modes_only raise ActionController::RoutingError.new('Do not try to hack us.') unless available? end From 1d45ec950d5c36453970cab6f8fc74f3779dd84e Mon Sep 17 00:00:00 2001 From: Prem Prakash Date: Wed, 16 Nov 2016 14:11:17 -0200 Subject: [PATCH 44/50] change controller and add spec fix scope in devise provider --- app/controllers/switch_user_controller.rb | 3 ++- lib/switch_user/provider/devise.rb | 6 +++--- spec/integration/switch_user_spec.rb | 25 ++++++++++++++++++++++- spec/provider/devise_spec.rb | 2 +- spec/support/provider.rb | 4 ++-- 5 files changed, 32 insertions(+), 8 deletions(-) diff --git a/app/controllers/switch_user_controller.rb b/app/controllers/switch_user_controller.rb index b923bec..ebe3fb8 100644 --- a/app/controllers/switch_user_controller.rb +++ b/app/controllers/switch_user_controller.rb @@ -15,7 +15,8 @@ def remember_user def switch_back if SwitchUser.switch_back - provider.remember_current_user(params[:remember] == "true") + provider.remember_current_user(true) if params[:remember] == "true" + provider.remember_current_user(false) if params[:remember] == "false" end end diff --git a/lib/switch_user/provider/devise.rb b/lib/switch_user/provider/devise.rb index 3981e61..ff70f57 100644 --- a/lib/switch_user/provider/devise.rb +++ b/lib/switch_user/provider/devise.rb @@ -6,7 +6,7 @@ def initialize(controller) @warden = @controller.warden end - def login(user, scope = :user) + def login(user, scope = nil) if SwitchUser.provider.is_a?(Hash) && SwitchUser.provider[:store_sign_in] @warden.set_user(user, scope: scope) else @@ -14,11 +14,11 @@ def login(user, scope = :user) end end - def logout(scope = :user) + def logout(scope = nil) @warden.logout(scope) end - def current_user(scope = :user) + def current_user(scope = nil) @warden.user(scope) end end diff --git a/spec/integration/switch_user_spec.rb b/spec/integration/switch_user_spec.rb index a693940..3582b93 100644 --- a/spec/integration/switch_user_spec.rb +++ b/spec/integration/switch_user_spec.rb @@ -32,7 +32,7 @@ } end - it "can switch back to a different user" do + it "can switch back to a different user through remember_user endpoint" do # login post "/login", :id => user.id follow_redirect! @@ -57,5 +57,28 @@ get "/switch_user/remember_user", :remember => false expect(session["original_user"]).to be_nil end + + it "can switch back to a different user without hitting remember_user endpoint" do + # login + post "/login", :id => user.id + follow_redirect! + + # check that we can switch to another user + get "/switch_user?scope_identifier=user_#{other_user.id}", :remember => true + expect(session["user_id"]).to eq other_user.id + expect(session["original_user_scope_identifier"]).to_not be_nil + + # logout + get "/logout" + expect(session["user_id"]).to be_nil + + # check that we can still switch to another user + get "/switch_user?scope_identifier=user_#{user.id}" + expect(session["user_id"]).to eq user.id + + # check that we can be un-remembered + get "/switch_user/remember_user", :remember => false + expect(session["original_user"]).to be_nil + end end end diff --git a/spec/provider/devise_spec.rb b/spec/provider/devise_spec.rb index c35e10f..116849f 100644 --- a/spec/provider/devise_spec.rb +++ b/spec/provider/devise_spec.rb @@ -71,7 +71,7 @@ def current_user end it "logs the user in" do - expect(provider.current_user).to eq user + expect(provider.current_user(:user)).to eq user end it "logs out other scopes" do diff --git a/spec/support/provider.rb b/spec/support/provider.rb index a2e85a4..ff10a7c 100644 --- a/spec/support/provider.rb +++ b/spec/support/provider.rb @@ -25,7 +25,7 @@ end it "knows if there are any users logged in" do - provider.login(user) + provider.login(user, :user) expect(provider.current_users_without_scope).to eq [user] end @@ -36,7 +36,7 @@ provider.login_exclusive(other_user, scope: "user") expect(provider.original_user).to eq user - expect(provider.current_user).to eq other_user + expect(provider.current_user(:user)).to eq other_user end it "can forget the original_user" do From aa57c81e68279e3894ea227944e4c9ba94ab72b6 Mon Sep 17 00:00:00 2001 From: Denis Date: Fri, 20 Jan 2017 13:37:40 +0300 Subject: [PATCH 45/50] Rails.env.production? --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 08a22ec..058ac12 100644 --- a/README.md +++ b/README.md @@ -117,11 +117,11 @@ config.available_users_names = { :user => :login } ``` If you only allow switching from admin to user in production environment ```ruby -config.controller_guard = lambda { |current_user, request| Rails.env == "production" and current_user.admin? } +config.controller_guard = lambda { |current_user, request| Rails.env.production? and current_user.admin? } ``` If you only want to display switch user select box for admins in production environment ```ruby -config.view_guard = lambda { |current_user, request| Rails.env == "production" and current_user and current_user.admin? } +config.view_guard = lambda { |current_user, request| Rails.env.production? and current_user and current_user.admin? } ``` If you want to redirect user to "/dashboard" page ```ruby From 86d2e1f58c598ba04765addfa77923e15cc68a09 Mon Sep 17 00:00:00 2001 From: Richard Huang Date: Sat, 18 Feb 2017 10:39:58 +0800 Subject: [PATCH 46/50] use new syntax --- README.md | 36 +++++++-------- app/controllers/switch_user_controller.rb | 4 +- app/helpers/switch_user_helper.rb | 10 ++--- app/views/switch_user/_widget.html.erb | 4 +- config/routes.rb | 4 +- .../install/templates/switch_user.rb | 12 ++--- lib/switch_user.rb | 12 ++--- lib/switch_user/provider/base.rb | 2 +- lib/switch_user/rspec.rb | 4 +- lib/switch_user/user_set.rb | 2 +- .../switch_user_controller_spec.rb | 24 +++++----- spec/helpers/switch_user_helper_spec.rb | 16 +++---- spec/integration/switch_user_spec.rb | 20 ++++----- spec/provider/devise_spec.rb | 8 ++-- spec/rspec/feature_helpers_spec.rb | 44 +++++++++---------- spec/spec_helper.rb | 2 +- spec/support/application.rb | 22 +++++----- spec/switch_user/data_source_spec.rb | 8 ++-- spec/switch_user/lambda_guard_spec.rb | 4 +- spec/switch_user/user_loader_spec.rb | 12 ++--- spec/switch_user/user_set_spec.rb | 10 ++--- 21 files changed, 127 insertions(+), 133 deletions(-) diff --git a/README.md b/README.md index 058ac12..4408daa 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ switch_user is very useful in such use cases ## Example -Visit here: , switch the current user in the select box. +Visit here: , switch the current user in the select box. And source code here: @@ -69,7 +69,7 @@ SwitchUser.setup do |config| # available_users is a hash, # key is the model name of user (:user, :admin, or any name you use), # value is a block that return the users that can be switched. - config.available_users = { :user => lambda { User.all } } # use User.scoped instead for rails 3.2 + config.available_users = { user: -> { User.all } } # use User.scoped instead for rails 3.2 # available_users_identifiers is a hash, # keys in this hash should match a key in the available_users hash @@ -77,55 +77,55 @@ SwitchUser.setup do |config| # defaults to id # this hash is to allow you to specify a different column to # expose for instance a username on a User model instead of id - config.available_users_identifiers = { :user => :id } + config.available_users_identifiers = { user: :id } # available_users_names is a hash, # keys in this hash should match a key in the available_users hash # value is the column name which will be displayed in select box - config.available_users_names = { :user => :email } + config.available_users_names = { user: :email } # controller_guard is a block, # if it returns true, the request will continue, # else the request will be refused and returns "Permission Denied" # if you switch from "admin" to user, the current_user param is "admin" - config.controller_guard = lambda { |current_user, request| Rails.env.development? } + config.controller_guard = ->(current_user, request) { Rails.env.development? } # view_guard is a block, # if it returns true, the switch user select box will be shown, # else the select box will not be shown # if you switch from admin to "user", the current_user param is "user" - config.view_guard = lambda { |current_user, request| Rails.env.development? } + config.view_guard = ->(current_user, request) { Rails.env.development? } # redirect_path is a block, it returns which page will be redirected # after switching a user. - config.redirect_path = lambda { |request, params| '/' } + config.redirect_path = ->(request, params) { '/' } end ``` If you need to override the default configuration, run rails g switch_user:install and a copy of the configuration file will be copied to config/initializers/switch_user.rb in your project. If you want to switch both available users and available admins ```ruby -config.available_users = { :user => lambda { User.available }, :admin => lambda { Admin.available } } +config.available_users = { user => -> { User.available }, :admin => -> { Admin.available } } ``` If you want to use name column as the user identifier ```ruby -config.available_users_identifiers => { :user => :name } +config.available_users_identifiers => { user: :name } ``` If you want to display the login field in switch user select box ```ruby -config.available_users_names = { :user => :login } +config.available_users_names = { user: :login } ``` If you only allow switching from admin to user in production environment ```ruby -config.controller_guard = lambda { |current_user, request| Rails.env.production? and current_user.admin? } +config.controller_guard = ->(current_user, request) { Rails.env.production? && current_user.admin? } ``` If you only want to display switch user select box for admins in production environment ```ruby -config.view_guard = lambda { |current_user, request| Rails.env.production? and current_user and current_user.admin? } +config.view_guard = ->(current_user, request) { Rails.env.production? && current_user && current_user.admin? } ``` If you want to redirect user to "/dashboard" page ```ruby -config.redirect_path = lambda { |request, params| "/dashboard" } +config.redirect_path = ->(request, params) { "/dashboard" } ``` If you want to hide a 'Guest' item in the helper dropdown list ```ruby @@ -137,16 +137,14 @@ Sometimes you'll want to be able to switch to an unprivileged user and then back You will need to make the following modifications to your configuration: ```ruby config.switch_back = true -config.controller_guard = lambda { |current_user, request, original_user| - current_user && current_user.admin? || original_user && original_user.super_admin? -} +config.controller_guard = ->(current_user, request, original_user) { current_user && current_user.admin? || original_user && original_user.super_admin? } # Do something similar for the view_guard as well. ``` This example would allow an admin user to user switch_user, but would only let you switch back to another user if the original user was a super admin. ## Using SwitchUser with RSpec and Capybara -Add the following code to spec/support/switch_user.rb or spec/spec_helper.rb : +Add the following code to spec/support/switch_user.rb or spec/spec_helper.rb: ```ruby require 'switch_user/rspec' @@ -157,7 +155,7 @@ You can now write your specs like so : ```ruby feature "Your feature", type: :feature do background do - @user = User.make(:email => 'user@example.com', :password => 'password') + @user = User.make(email: 'user@example.com', password: 'password') end scenario "Your scenario" do @@ -189,6 +187,6 @@ This feature should be used with extreme caution because of the security implica ## Credit -Copyright © 2010 - 2015 Richard Huang (flyerhzm@gmail.com), released under the MIT license +Copyright © 2010 - 2017 Richard Huang (flyerhzm@gmail.com), released under the MIT license [0]: https://github.com/tablatom/hobo diff --git a/app/controllers/switch_user_controller.rb b/app/controllers/switch_user_controller.rb index ebe3fb8..0b5366f 100644 --- a/app/controllers/switch_user_controller.rb +++ b/app/controllers/switch_user_controller.rb @@ -38,9 +38,9 @@ def handle_request(params) return end if SwitchUser.login_exclusive - provider.login_exclusive(record.user, :scope => record.scope) + provider.login_exclusive(record.user, scope: record.scope) else - provider.login_inclusive(record.user, :scope => record.scope) + provider.login_inclusive(record.user, scope: record.scope) end end end diff --git a/app/helpers/switch_user_helper.rb b/app/helpers/switch_user_helper.rb index fa01764..c57d7b5 100644 --- a/app/helpers/switch_user_helper.rb +++ b/app/helpers/switch_user_helper.rb @@ -23,11 +23,11 @@ def switch_user_select(options = {}) option_tags = grouped_options_for_select(grouped_options_container.to_a, selected_user) - render :partial => "switch_user/widget", - :locals => { - :option_tags => option_tags, - :classes => options[:class], - :styles => options[:style], + render partial: "switch_user/widget", + locals: { + option_tags: option_tags, + classes: options[:class], + styles: options[:style], } end diff --git a/app/views/switch_user/_widget.html.erb b/app/views/switch_user/_widget.html.erb index 8fae500..c397c1f 100644 --- a/app/views/switch_user/_widget.html.erb +++ b/app/views/switch_user/_widget.html.erb @@ -1,4 +1,4 @@ <% if SwitchUser.switch_back %> - <%= check_box_tag "remember_user", "remember_user", provider.original_user.present?, :onchange => "location.href = '#{ActionController::Base.relative_url_root || '/'}switch_user/remember_user?remember=' + encodeURIComponent(this.checked)" %> + <%= check_box_tag "remember_user", "remember_user", provider.original_user.present?, onchange: "location.href = '#{ActionController::Base.relative_url_root || '/'}switch_user/remember_user?remember=' + encodeURIComponent(this.checked)" %> <% end %> -<%= select_tag "switch_user_identifier", option_tags, :onchange => "location.href = '#{ActionController::Base.relative_url_root || '/'}switch_user?scope_identifier=' + encodeURIComponent(this.options[this.selectedIndex].value)", :class => classes, :style => styles %> +<%= select_tag "switch_user_identifier", option_tags, onchange: "location.href = '#{ActionController::Base.relative_url_root || '/'}switch_user?scope_identifier=' + encodeURIComponent(this.options[this.selectedIndex].value)", class: classes, style: styles %> diff --git a/config/routes.rb b/config/routes.rb index 6308783..6d341b7 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,4 +1,4 @@ Rails.application.routes.draw do - get :switch_user, :to => 'switch_user#set_current_user' - get 'switch_user/remember_user', :to => 'switch_user#remember_user' + get :switch_user, to: 'switch_user#set_current_user' + get 'switch_user/remember_user', to: 'switch_user#remember_user' end diff --git a/lib/generators/switch_user/install/templates/switch_user.rb b/lib/generators/switch_user/install/templates/switch_user.rb index 879ae5a..f954b94 100644 --- a/lib/generators/switch_user/install/templates/switch_user.rb +++ b/lib/generators/switch_user/install/templates/switch_user.rb @@ -5,7 +5,7 @@ # available_users is a hash, # key is the model name of user (:user, :admin, or any name you use), # value is a block that return the users that can be switched. - config.available_users = { :user => lambda { User.all } } + config.available_users = { user: -> { User.all } } # available_users_identifiers is a hash, # keys in this hash should match a key in the available_users hash @@ -13,28 +13,28 @@ # defaults to id # this hash is to allow you to specify a different column to # expose for instance a username on a User model instead of id - config.available_users_identifiers = { :user => :id } + config.available_users_identifiers = { user: :id } # available_users_names is a hash, # keys in this hash should match a key in the available_users hash # value is the column name which will be displayed in select box - config.available_users_names = { :user => :email } + config.available_users_names = { user: :email } # controller_guard is a block, # if it returns true, the request will continue, # else the request will be refused and returns "Permission Denied" # if you switch from "admin" to user, the current_user param is "admin" - config.controller_guard = lambda { |current_user, request| Rails.env.development? } + config.controller_guard = ->(current_user, request) { Rails.env.development? } # view_guard is a block, # if it returns true, the switch user select box will be shown, # else the select box will not be shown # if you switch from admin to "user", the current_user param is "user" - config.view_guard = lambda { |current_user, request| Rails.env.development? } + config.view_guard = ->(current_user, request) { Rails.env.development? } # redirect_path is a block, it returns which page will be redirected # after switching a user. - config.redirect_path = lambda { |request, params| '/' } + config.redirect_path = ->(request, params) { '/' } # helper_with_guest is a boolean value, if it set to false # the guest item in the helper won't be shown diff --git a/lib/switch_user.rb b/lib/switch_user.rb index 9205766..0d864a9 100644 --- a/lib/switch_user.rb +++ b/lib/switch_user.rb @@ -53,13 +53,13 @@ def self.data_sources def self.reset_config self.provider = :devise - self.available_users = { :user => lambda { User.all } } - self.available_users_identifiers = { :user => :id } - self.available_users_names = { :user => :email } + self.available_users = { user: -> { User.all } } + self.available_users_identifiers = { user: :id } + self.available_users_names = { user: :email } self.guard_class = "SwitchUser::LambdaGuard" - self.controller_guard = lambda { |current_user, request| Rails.env.development? } - self.view_guard = lambda { |current_user, request| Rails.env.development? } - self.redirect_path = lambda { |request, params| request.env["HTTP_REFERER"] ? :back : root_path } + self.controller_guard = ->(current_user, request) { Rails.env.development? } + self.view_guard = ->(current_user, request) { Rails.env.development? } + self.redirect_path = ->(request, params) { request.env["HTTP_REFERER"] ? :back : root_path } self.session_key = :user_id self.helper_with_guest = true self.switch_back = false diff --git a/lib/switch_user/provider/base.rb b/lib/switch_user/provider/base.rb index 384292a..83a44e0 100644 --- a/lib/switch_user/provider/base.rb +++ b/lib/switch_user/provider/base.rb @@ -33,7 +33,7 @@ def original_user user_identifier = @controller.session[:original_user_scope_identifier] if user_identifier - UserLoader.prepare(:scope_identifier => user_identifier).user + UserLoader.prepare(scope_identifier: user_identifier).user end end diff --git a/lib/switch_user/rspec.rb b/lib/switch_user/rspec.rb index 996cf13..a97f24e 100644 --- a/lib/switch_user/rspec.rb +++ b/lib/switch_user/rspec.rb @@ -4,9 +4,9 @@ RSpec.configure do |config| - config.include SwitchUser::RSpecFeatureHelpers, :type => :feature + config.include SwitchUser::RSpecFeatureHelpers, type: :feature - config.before(:each, :type => :feature) do + config.before(:each, type: :feature) do allow_any_instance_of(SwitchUserController).to receive(:available?).and_return(true) end diff --git a/lib/switch_user/user_set.rb b/lib/switch_user/user_set.rb index a007f36..ed7454e 100644 --- a/lib/switch_user/user_set.rb +++ b/lib/switch_user/user_set.rb @@ -24,7 +24,7 @@ def initialize(scope, identifier, label, base_scope) end def find_user(id) - Record.build(users.where(:id => id).first, self) + Record.build(users.where(id: id).first, self) end alias :[] :find_user diff --git a/spec/controllers/switch_user_controller_spec.rb b/spec/controllers/switch_user_controller_spec.rb index 93f068b..8525e35 100644 --- a/spec/controllers/switch_user_controller_spec.rb +++ b/spec/controllers/switch_user_controller_spec.rb @@ -2,27 +2,27 @@ require 'switch_user' require 'switch_user_controller' -RSpec.describe SwitchUserController, :type => :controller do +RSpec.describe SwitchUserController, type: :controller do before do SwitchUser.provider = :dummy end - let(:admin) { double(:admin, :admin? => true) } + let(:admin) { double(:admin, admin?: true) } let(:provider) { double(:provider, - :original_user => admin, - :current_user => nil) + original_user: admin, + current_user: nil) } describe "#set_current_user" do it "redirects the user to the specified location" do - SwitchUser.redirect_path = lambda {|_,_| "/path"} + SwitchUser.redirect_path = ->(_,_) { "/path" } allow(controller).to receive(:available?).and_return(true) - get :set_current_user, :scope_identifier => "user_1" + get :set_current_user, scope_identifier: "user_1" expect(response).to redirect_to("/path") end it "denies access according to the guard block" do - SwitchUser.controller_guard = lambda {|_,_,_| false } + SwitchUser.controller_guard = ->(_,_,_) { false } expect { get :set_current_user }.to raise_error(ActionController::RoutingError) @@ -30,9 +30,7 @@ describe "requests with a privileged original_user" do before do - SwitchUser.controller_guard = lambda {|current_user, _, original_user| - current_user.try(:admin?) || original_user.try(:admin?) - } + SwitchUser.controller_guard = ->(current_user, _, original_user) { current_user.try(:admin?) || original_user.try(:admin?) } end it "allows access using the original_user param" do allow(controller).to receive(:provider).and_return(provider) @@ -54,18 +52,18 @@ it "can remember the current user" do expect(provider).to receive(:remember_current_user).with(true) - get :remember_user, :remember => "true" + get :remember_user, remember: "true" end it "can forget the current user" do expect(provider).to receive(:remember_current_user).with(false) - get :remember_user, :remember => "false" + get :remember_user, remember: "false" end it "does nothing if switch_back is not enabled" do SwitchUser.switch_back = false expect(provider).not_to receive(:remember_current_user) - get :remember_user, :remember => "true" + get :remember_user, remember: "true" end end end diff --git a/spec/helpers/switch_user_helper_spec.rb b/spec/helpers/switch_user_helper_spec.rb index 1f0c127..5c9cd25 100644 --- a/spec/helpers/switch_user_helper_spec.rb +++ b/spec/helpers/switch_user_helper_spec.rb @@ -2,13 +2,13 @@ require 'switch_user' require 'switch_user_helper' -RSpec.describe SwitchUserHelper, :type => :helper do +RSpec.describe SwitchUserHelper, type: :helper do before do SwitchUser.provider = :dummy end - let(:user) { double(:user, :id => 1) } - let(:admin) { double(:admin, :id => 1) } + let(:user) { double(:user, id: 1) } + let(:admin) { double(:admin, id: 1) } let(:provider) { _provider = SwitchUser::Provider::Dummy.new(controller) _provider @@ -16,8 +16,8 @@ describe "#switch_user_select" do let(:guest_record) { SwitchUser::GuestRecord.new } - let(:user_record) { double(:user_record, :user => user, :scope => :user, :label => 'user1', :scope_id => 'user_1') } - let(:admin_record) { double(:admin_record, :user => admin, :scope => :admin, :label => 'admin1', :scope_id => 'admin_1') } + let(:user_record) { double(:user_record, user: user, scope: :user, label: 'user1', scope_id: 'user_1') } + let(:admin_record) { double(:admin_record, user: admin, scope: :admin, label: 'admin1', scope_id: 'admin_1') } let(:guest_option_tags) { %Q^^ } let(:user_option_tags) { %Q^^ } @@ -125,7 +125,7 @@ describe "#user_tag_value" do it "for user" do - user = double(:user, :id => 1) + user = double(:user, id: 1) expect(helper.send(:user_tag_value, user, :id, :user)).to eq('user_1') end @@ -134,13 +134,13 @@ describe "#user_tag_label" do it "when name has call method" do user = double(:user) - name = ->(user){ 'user1' } + name = ->(user) { 'user1' } expect(helper.send(:user_tag_label, user, name)).to eq('user1') end it "when name not has call method" do - user = double(:name, :name => 'user1') + user = double(:name, name: 'user1') name = :name expect(helper.send(:user_tag_label, user, name)).to eq('user1') diff --git a/spec/integration/switch_user_spec.rb b/spec/integration/switch_user_spec.rb index 3582b93..9f472c6 100644 --- a/spec/integration/switch_user_spec.rb +++ b/spec/integration/switch_user_spec.rb @@ -1,14 +1,14 @@ require 'spec_helper' -RSpec.describe "Using SwitchUser", :type => :request do - let(:user) { User.create!(:email => "foo@bar.com", :admin => true) } - let(:other_user) { User.create!(:email => "other@bar.com", :admin => false) } +RSpec.describe "Using SwitchUser", type: :request do + let(:user) { User.create!(email: "foo@bar.com", admin: true) } + let(:other_user) { User.create!(email: "other@bar.com", admin: false) } before do SwitchUser.reset_config SwitchUser.provider = :session - SwitchUser.controller_guard = lambda { |current_user, request| Rails.env.test? } - SwitchUser.redirect_path = lambda {|_,_| "/dummy/open"} + SwitchUser.controller_guard = ->(current_user, request) { Rails.env.test? } + SwitchUser.redirect_path = ->(_,_) { "/dummy/open" } end it "signs a user in using switch_user" do @@ -27,18 +27,16 @@ context "using switch_back" do before do SwitchUser.switch_back = true - SwitchUser.controller_guard = lambda { |current_user, request, original_user| - current_user && current_user.admin? || original_user && original_user.admin? - } + SwitchUser.controller_guard = ->(current_user, request, original_user) { current_user && current_user.admin? || original_user && original_user.admin? } end it "can switch back to a different user through remember_user endpoint" do # login - post "/login", :id => user.id + post "/login", id: user.id follow_redirect! # have SwitchUser remember us - get "/switch_user/remember_user", :remember => true + get "/switch_user/remember_user", remember: true expect(session["original_user_scope_identifier"]).to be_present # check that we can switch to another user @@ -54,7 +52,7 @@ expect(session["user_id"]).to eq user.id # check that we can be un-remembered - get "/switch_user/remember_user", :remember => false + get "/switch_user/remember_user", remember: false expect(session["original_user"]).to be_nil end diff --git a/spec/provider/devise_spec.rb b/spec/provider/devise_spec.rb index 116849f..5f8a9a4 100644 --- a/spec/provider/devise_spec.rb +++ b/spec/provider/devise_spec.rb @@ -65,9 +65,9 @@ def current_user describe "#login_exclusive" do before do - allow(SwitchUser).to receive(:available_users).and_return({:user => nil, :admin => nil}) + allow(SwitchUser).to receive(:available_users).and_return({user: nil, admin: nil}) provider.login(user, :admin) - provider.login_exclusive(user, :scope => "user") + provider.login_exclusive(user, scope: "user") end it "logs the user in" do @@ -81,7 +81,7 @@ def current_user describe "#logout_all" do it "logs out users under all scopes" do - allow(SwitchUser).to receive(:available_users).and_return({:user => nil, :admin => nil}) + allow(SwitchUser).to receive(:available_users).and_return({user: nil, admin: nil}) provider.login(user, :admin) provider.login(user, :user) @@ -94,7 +94,7 @@ def current_user describe "#all_current_users" do it "pulls users from an alternate scope" do - allow(SwitchUser).to receive(:available_users).and_return({:user => nil, :admin => nil}) + allow(SwitchUser).to receive(:available_users).and_return({user: nil, admin: nil}) provider.login(user, :admin) expect(provider.current_users_without_scope).to eq [user] diff --git a/spec/rspec/feature_helpers_spec.rb b/spec/rspec/feature_helpers_spec.rb index e387407..72c4edf 100644 --- a/spec/rspec/feature_helpers_spec.rb +++ b/spec/rspec/feature_helpers_spec.rb @@ -6,32 +6,32 @@ require 'switch_user/rspec' -RSpec.feature "SwitchUser::RSpecFeatureHelpers", :type => :feature do +RSpec.feature "SwitchUser::RSpecFeatureHelpers", type: :feature do background do - @user = User.create!(:email => "foo@bar.com", :admin => true) - @client = Client.create!(:email => "foo@bar.com") + @user = User.create!(email: "foo@bar.com", admin: true) + @client = Client.create!(email: "foo@bar.com") end - before(:each) do - allow(SwitchUser).to receive(:controller_guard).and_return(lambda{|current_user, request| true}) + before(:example) do + allow(SwitchUser).to receive(:controller_guard).and_return(->(current_user, request) { true }) - allow(SwitchUser).to receive(:available_users).and_return({:user => lambda { User.all }}) + allow(SwitchUser).to receive(:available_users).and_return({user: -> { User.all }}) - allow(SwitchUser).to receive(:available_users_identifiers).and_return({:user => :id}) + allow(SwitchUser).to receive(:available_users_identifiers).and_return({user: :id}) - allow(SwitchUser).to receive(:available_users_names).and_return({:user => :email}) + allow(SwitchUser).to receive(:available_users_names).and_return({user: :email}) end scenario "when controller_guard return false" do - allow(SwitchUser).to receive(:controller_guard).and_return(lambda{|current_user, request| false}) + allow(SwitchUser).to receive(:controller_guard).and_return(->(current_user, request) { false }) expect do switch_user @user - end.to_not raise_error ActionController::RoutingError, /Do not try to hack us/ + end.not_to raise_error end scenario "when controller_guard return false and controller call original available?" do - allow(SwitchUser).to receive(:controller_guard).and_return(lambda{|current_user, request| false}) + allow(SwitchUser).to receive(:controller_guard).and_return(->(current_user, request) { false }) allow_any_instance_of(SwitchUserController).to receive(:available?).and_call_original @@ -43,7 +43,7 @@ scenario "arg is @user, available_users is default, and available_users_identifiers is default" do expect do switch_user @user - end.to_not raise_error + end.not_to raise_error end scenario "arg is @user, available_users is default, and available_users_identifiers is {user: id}" do @@ -51,12 +51,12 @@ expect do switch_user @user - end.to_not raise_error + end.not_to raise_error end scenario "arg is @user, available_users is default, and available_users_identifiers is {:client => :id}" do - allow(SwitchUser).to receive(:available_users_identifiers).and_return({:client => :id}) - allow(SwitchUser).to receive(:available_users_names).and_return({:client => :email}) + allow(SwitchUser).to receive(:available_users_identifiers).and_return({client: :id}) + allow(SwitchUser).to receive(:available_users_names).and_return({client: :email}) expect do switch_user @user @@ -70,7 +70,7 @@ end scenario "arg is @client, available_users is {:user => lambda { User.all }, :client => lambda {Client.all}}, and available_users_identifiers is default" do - allow(SwitchUser).to receive(:available_users).and_return({:user => lambda { User.all }, :client => lambda {Client.all}}) + allow(SwitchUser).to receive(:available_users).and_return({user: -> { User.all }, client: -> { Client.all }}) expect do switch_user @client @@ -78,20 +78,20 @@ end scenario "arg is @client, available_users is {:user => lambda { User.all }, :client => lambda {Client.all}}, and available_users_identifiers is {:user => id, :client => id}" do - allow(SwitchUser).to receive(:available_users).and_return({:user => lambda { User.all }, :client => lambda {Client.all}}) + allow(SwitchUser).to receive(:available_users).and_return({user: -> { User.all }, client: -> { Client.all }}) - allow(SwitchUser).to receive(:available_users_identifiers).and_return({:user => :id, :client => :id}) - allow(SwitchUser).to receive(:available_users_names).and_return({:user => :email, :client => :email}) + allow(SwitchUser).to receive(:available_users_identifiers).and_return({user: :id, client: :id}) + allow(SwitchUser).to receive(:available_users_names).and_return({user: :email, client: :email}) expect do switch_user @client - end.to_not raise_error + end.not_to raise_error end scenario "args is :user and @user.id, available_users is default, and available_users_identifiers is default" do expect do switch_user :user, @user.id - end.to_not raise_error + end.not_to raise_error end scenario "arg is :client and @client.id, available_users is default, and available_users_identifiers is default" do @@ -121,7 +121,7 @@ scenario "args is :user and 0, available_users is default, and available_users_identifiers is default" do expect do switch_user :user, 0 - end.to_not raise_error + end.not_to raise_error end end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index fe51143..908f817 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -7,7 +7,7 @@ require 'awesome_print' RSpec.configure do |config| - config.filter_run :focus => true + config.filter_run focus: true config.run_all_when_everything_filtered = true config.use_transactional_fixtures = true config.expose_dsl_globally = false diff --git a/spec/support/application.rb b/spec/support/application.rb index 7b27f89..b59c382 100644 --- a/spec/support/application.rb +++ b/spec/support/application.rb @@ -27,18 +27,18 @@ def logout end class DummyController < ApplicationController - before_filter :require_user, :only => :protected + before_action :require_user, only: :protected def authenticated - render :text => current_user.inspect + render text: current_user.inspect end def open - render :text => view_context.switch_user_select + render text: view_context.switch_user_select end def protected - render :text => view_context.switch_user_select + render text: view_context.switch_user_select end end @@ -55,13 +55,13 @@ class Application < Rails::Application end Rails.application.initialize! Rails.application.routes.draw do - get 'dummy/protected', :to => "dummy#protected" - get 'dummy/open', :to => "dummy#open" - post 'login', :to => "dummy#login" - get 'logout', :to => "dummy#logout" - get 'authenticated', :to => "dummy#authenticated" - get :switch_user, :to => 'switch_user#set_current_user' - get 'switch_user/remember_user', :to => 'switch_user#remember_user' + get 'dummy/protected', to: "dummy#protected" + get 'dummy/open', to: "dummy#open" + post 'login', to: "dummy#login" + get 'logout', to: "dummy#logout" + get 'authenticated', to: "dummy#authenticated" + get :switch_user, to: 'switch_user#set_current_user' + get 'switch_user/remember_user', to: 'switch_user#remember_user' end connection = ActiveRecord::Base.connection diff --git a/spec/switch_user/data_source_spec.rb b/spec/switch_user/data_source_spec.rb index bb90447..a2efea4 100644 --- a/spec/switch_user/data_source_spec.rb +++ b/spec/switch_user/data_source_spec.rb @@ -5,7 +5,7 @@ module SwitchUser describe '#all' do it 'aggregates multiple data_sources' do user = double(:user) - s1 = double(:s1, :all => [user]) + s1 = double(:s1, all: [user]) source = DataSources.new([s1, s1]) expect(source.all).to eq [user, user] @@ -15,8 +15,8 @@ module SwitchUser describe '#find_scope_id' do it 'can find a corresponding record across data sources' do user = double(:user) - s1 = double(:s1, :find_scope_id => nil) - s2 = double(:s2, :find_scope_id => user) + s1 = double(:s1, find_scope_id: nil) + s2 = double(:s2, find_scope_id: user) source = DataSources.new([s1, s2]) expect(source.find_scope_id("user_10")).to eq user @@ -25,7 +25,7 @@ module SwitchUser end RSpec.describe DataSource do - pending # it's tested in integration test, need to find a good way to test it here. + skip # it's tested in integration test, need to find a good way to test it here. end RSpec.describe GuestDataSource do diff --git a/spec/switch_user/lambda_guard_spec.rb b/spec/switch_user/lambda_guard_spec.rb index 360ac4c..1effbc3 100644 --- a/spec/switch_user/lambda_guard_spec.rb +++ b/spec/switch_user/lambda_guard_spec.rb @@ -8,10 +8,10 @@ module SwitchUser provider = double.as_null_object guard = SwitchUser::LambdaGuard.new(controller, provider) - SwitchUser.controller_guard = lambda {|a| a } + SwitchUser.controller_guard = ->(a) { a } expect(guard).to be_controller_available - SwitchUser.controller_guard = lambda {|a| !a } + SwitchUser.controller_guard = ->(a) { !a } expect(guard).not_to be_controller_available end end diff --git a/spec/switch_user/user_loader_spec.rb b/spec/switch_user/user_loader_spec.rb index 5edfd11..5502b4d 100644 --- a/spec/switch_user/user_loader_spec.rb +++ b/spec/switch_user/user_loader_spec.rb @@ -11,8 +11,8 @@ describe ".user" do before do - SwitchUser.available_users_identifiers = {:user => :id} - allow(User).to receive(:where).with(:id => "1").and_return(user_result) + SwitchUser.available_users_identifiers = {user: :id} + allow(User).to receive(:where).with(id: "1").and_return(user_result) end it "can be loaded from a scope and identifier" do loaded_user = SwitchUser::UserLoader.prepare("user","1").user @@ -20,7 +20,7 @@ expect(loaded_user).to eq user end it "can be loaded by a passing an unprocessed scope identifier" do - loaded_user = SwitchUser::UserLoader.prepare(:scope_identifier => "user_1").user + loaded_user = SwitchUser::UserLoader.prepare(scope_identifier: "user_1").user expect(loaded_user).to eq user end @@ -32,7 +32,7 @@ end it "returns a user" do - allow(User).to receive(:where).with(:id => 1).and_return(user_result) + allow(User).to receive(:where).with(id: 1).and_return(user_result) loader = SwitchUser::UserLoader.new("user", 1) @@ -47,8 +47,8 @@ end it "loads a user with an alternate identifier column" do - allow(User).to receive(:where).with(:email => 2).and_return(user_result) - SwitchUser.available_users_identifiers = {:user => :email} + allow(User).to receive(:where).with(email: 2).and_return(user_result) + SwitchUser.available_users_identifiers = {user: :email} loader = SwitchUser::UserLoader.new("user", 2) expect(loader.user).to eq user diff --git a/spec/switch_user/user_set_spec.rb b/spec/switch_user/user_set_spec.rb index 1ddabbe..2cbef41 100644 --- a/spec/switch_user/user_set_spec.rb +++ b/spec/switch_user/user_set_spec.rb @@ -3,8 +3,8 @@ module SwitchUser RSpec.describe UserSet do - let!(:user) { User.create(:email => "test@example.com") } - let(:set) { UserSet.new(:user, :id, :email, lambda { User.all }) } + let!(:user) { User.create(email: "test@example.com") } + let(:set) { UserSet.new(:user, :id, :email, -> { User.all }) } after { User.delete_all } it "returns an object that knows it's scope, id and label" do found_user = set[user.id] @@ -17,14 +17,14 @@ module SwitchUser expect(set.users).to eq [user] end it "chains the where on to the provided scope" do - set = UserSet.new(:user, :id, :email, lambda { User.all }) + set = UserSet.new(:user, :id, :email, -> { User.all }) expect(set.find_user(user.id).label).to eq user.email end end RSpec.describe UserSet::Record do it "correctly configures the record using the set" do - user = double(:user, :id => 100, :email => "test@example.com") - set = double(:set, :identifier => :id, :label => :email, :scope => :user) + user = double(:user, id: 100, email: "test@example.com") + set = double(:set, identifier: :id, label: :email, scope: :user) record = UserSet::Record.build(user, set) expect(record.id).to eq 100 expect(record.label).to eq "test@example.com" From e8286465a0796dea389af669b1f1e61bdcad6e23 Mon Sep 17 00:00:00 2001 From: Ruben Izmailyan Date: Thu, 2 Mar 2017 10:30:35 -0600 Subject: [PATCH 47/50] Fix 'available_users' config syntax --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4408daa..fc977b5 100644 --- a/README.md +++ b/README.md @@ -105,7 +105,7 @@ If you need to override the default configuration, run rails g switch_user If you want to switch both available users and available admins ```ruby -config.available_users = { user => -> { User.available }, :admin => -> { Admin.available } } +config.available_users = { :user => -> { User.available }, :admin => -> { Admin.available } } ``` If you want to use name column as the user identifier ```ruby From 9f799fbc358aa3718bcbf5ed6b9eb3bef25238ff Mon Sep 17 00:00:00 2001 From: Ace Suares Date: Sat, 18 Mar 2017 08:06:50 -0400 Subject: [PATCH 48/50] updated documentation about before_action in Rails < 4 --- README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README.md b/README.md index fc977b5..1678a75 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,14 @@ Add in Gemfile. ```ruby gem "switch_user" ``` +### Rails < 4 + +If you get the following error: + + undefined method `before_action' for SwitchUserController:Class + +then you are probably using an older version of Rails (<4). You can use this gem: https://github.com/pschambacher/rails3-before_action + ## Usage Add following code into your layout page. From 1d3208097aa13a076173573bb4e01683394220d0 Mon Sep 17 00:00:00 2001 From: Ace Suares Date: Sat, 18 Mar 2017 08:08:59 -0400 Subject: [PATCH 49/50] updated documentation about before_action in Rails < 4 --- README.md | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/README.md b/README.md index 1678a75..79a7c72 100644 --- a/README.md +++ b/README.md @@ -24,13 +24,8 @@ Add in Gemfile. ```ruby gem "switch_user" ``` -### Rails < 4 -If you get the following error: - - undefined method `before_action' for SwitchUserController:Class - -then you are probably using an older version of Rails (<4). You can use this gem: https://github.com/pschambacher/rails3-before_action +If you get the following error: **undefined method `before_action' for SwitchUserController:Class**, you are probably using an older version of Rails (<4). You can use this gem: https://github.com/pschambacher/rails3-before_action ## Usage From 89af98f950d73b581c07654b5c261dd0e9ff3578 Mon Sep 17 00:00:00 2001 From: Ahmed O Date: Mon, 1 May 2017 10:34:30 -0400 Subject: [PATCH 50/50] bump version --- lib/switch_user/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/switch_user/version.rb b/lib/switch_user/version.rb index ab7f5eb..8260abc 100644 --- a/lib/switch_user/version.rb +++ b/lib/switch_user/version.rb @@ -1,3 +1,3 @@ module SwitchUser - VERSION = "1.4.0" + VERSION = "1.4.0.1" end