devise_masquerade 0.6.5 → 1.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/.github/FUNDING.yml +1 -0
- data/.github/workflows/brakeman-analysis.yml +44 -0
- data/.github/workflows/rubocop-analysis.yml +39 -0
- data/.gitignore +1 -2
- data/.ruby-version +1 -1
- data/.travis.yml +3 -4
- data/Gemfile +16 -10
- data/Gemfile.lock +307 -0
- data/Makefile +6 -1
- data/README.md +33 -1
- data/app/controllers/devise/masquerades_controller.rb +75 -59
- data/devise_masquerade.gemspec +5 -4
- data/features/back.feature +0 -1
- data/features/multiple_masquerading_models.feature +17 -0
- data/features/step_definitions/auth_steps.rb +1 -0
- data/features/step_definitions/back_steps.rb +18 -3
- data/features/step_definitions/url_helpers_steps.rb +11 -0
- data/features/support/env.rb +23 -4
- data/features/url_helpers.feature +14 -0
- data/lib/devise_masquerade.rb +3 -9
- data/lib/devise_masquerade/controllers/helpers.rb +27 -8
- data/lib/devise_masquerade/controllers/url_helpers.rb +16 -2
- data/lib/devise_masquerade/models.rb +9 -0
- data/lib/devise_masquerade/models/masqueradable.rb +13 -0
- data/lib/devise_masquerade/rails.rb +14 -4
- data/lib/devise_masquerade/routes.rb +11 -8
- data/lib/devise_masquerade/version.rb +1 -1
- data/spec/controllers/admin/dashboard_controller_spec.rb +3 -4
- data/spec/controllers/dashboard_controller_spec.rb +3 -5
- data/spec/controllers/devise/masquerades_controller_spec.rb +62 -38
- data/spec/controllers/masquerades_tests_controller_spec.rb +41 -0
- data/spec/dummy/app/controllers/admin/dashboard_controller.rb +1 -2
- data/spec/dummy/app/controllers/application_controller.rb +2 -0
- data/spec/dummy/app/controllers/dashboard_controller.rb +5 -2
- data/spec/dummy/app/controllers/masquerades_tests_controller.rb +7 -0
- data/spec/dummy/app/controllers/students_controller.rb +8 -0
- data/spec/dummy/app/models/admin/user.rb +0 -7
- data/spec/dummy/app/models/student.rb +3 -0
- data/spec/dummy/app/models/user.rb +1 -10
- data/spec/dummy/app/views/admin/dashboard/index.html.erb +0 -2
- data/spec/dummy/app/views/dashboard/extra_params.html.erb +7 -0
- data/spec/dummy/app/views/dashboard/index.html.erb +0 -2
- data/spec/dummy/app/views/layouts/application.html.erb +7 -1
- data/spec/dummy/app/views/students/_student.html.erb +6 -0
- data/spec/dummy/app/views/students/index.html.erb +1 -0
- data/spec/dummy/app/views/users/_user.html.erb +1 -1
- data/spec/dummy/config/application.rb +2 -0
- data/spec/dummy/config/environment.rb +1 -0
- data/spec/dummy/config/routes.rb +9 -5
- data/spec/dummy/db/.gitignore +1 -0
- data/spec/dummy/db/migrate/20121119085620_devise_create_users.rb +1 -1
- data/spec/dummy/db/migrate/20140418160449_create_admin_users.rb +1 -1
- data/spec/dummy/db/migrate/20191022100000_create_students.rb +14 -0
- data/spec/dummy/db/schema.rb +37 -31
- data/spec/models/user_spec.rb +3 -30
- data/spec/orm/active_record.rb +5 -2
- data/spec/spec_helper.rb +3 -3
- data/spec/support/factories.rb +13 -9
- metadata +57 -19
- data/lib/devise_masquerade/model.rb +0 -42
- data/spec/controllers/masquerades_controller_spec.rb +0 -42
- data/spec/dummy/app/controllers/masquerades_controller.rb +0 -5
data/lib/devise_masquerade.rb
CHANGED
@@ -1,22 +1,16 @@
|
|
1
1
|
require 'devise'
|
2
|
-
|
3
|
-
require 'action_controller'
|
4
|
-
require 'action_controller/base'
|
5
2
|
require 'devise_masquerade/version'
|
6
3
|
require 'devise_masquerade/routes'
|
7
4
|
require 'devise_masquerade/controllers/helpers'
|
8
5
|
require 'devise_masquerade/controllers/url_helpers'
|
9
6
|
require 'devise_masquerade/rails'
|
10
7
|
|
11
|
-
module DeviseMasquerade
|
12
|
-
end
|
13
|
-
|
14
8
|
module Devise
|
15
9
|
mattr_accessor :masquerade_param
|
16
10
|
@@masquerade_param = 'masquerade'
|
17
11
|
|
18
12
|
mattr_accessor :masquerade_expires_in
|
19
|
-
@@masquerade_expires_in =
|
13
|
+
@@masquerade_expires_in = 1.minute
|
20
14
|
|
21
15
|
mattr_accessor :masquerade_key_size
|
22
16
|
@@masquerade_key_size = 16
|
@@ -42,5 +36,5 @@ module Devise
|
|
42
36
|
@@helpers << DeviseMasquerade::Controllers::Helpers
|
43
37
|
end
|
44
38
|
|
45
|
-
Devise.add_module :masqueradable, :
|
46
|
-
:
|
39
|
+
Devise.add_module :masqueradable, controller: :masquerades,
|
40
|
+
model: 'devise_masquerade/models', route: :masquerade
|
@@ -6,23 +6,44 @@ module DeviseMasquerade
|
|
6
6
|
class_name = mapping.class_name
|
7
7
|
|
8
8
|
class_eval <<-METHODS, __FILE__, __LINE__ + 1
|
9
|
+
def masquerade!
|
10
|
+
return if params["#{Devise.masquerade_param}"].blank?
|
11
|
+
|
12
|
+
klass = unless params[:masqueraded_resource_class].blank?
|
13
|
+
params[:masqueraded_resource_class].constantize
|
14
|
+
else
|
15
|
+
if Devise.masqueraded_resource_class
|
16
|
+
Devise.masqueraded_resource_class
|
17
|
+
elsif defined?(User)
|
18
|
+
User
|
19
|
+
end
|
20
|
+
end
|
21
|
+
return unless klass
|
22
|
+
|
23
|
+
resource = GlobalID::Locator.locate_signed params[Devise.masquerade_param], for: 'masquerade'
|
24
|
+
|
25
|
+
if resource
|
26
|
+
masquerade_sign_in(resource)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
9
30
|
def masquerade_#{name}!
|
10
31
|
return if params["#{Devise.masquerade_param}"].blank?
|
11
32
|
|
12
|
-
|
33
|
+
resource = GlobalID::Locator.locate_signed params[Devise.masquerade_param], for: 'masquerade'
|
13
34
|
|
14
|
-
if
|
15
|
-
masquerade_sign_in(
|
35
|
+
if resource
|
36
|
+
masquerade_sign_in(resource)
|
16
37
|
end
|
17
38
|
end
|
18
39
|
|
19
40
|
def #{name}_masquerade?
|
20
|
-
|
41
|
+
::Rails.cache.exist?(:"devise_masquerade_#{name}").present?
|
21
42
|
end
|
22
43
|
|
23
44
|
def #{name}_masquerade_owner
|
24
45
|
return nil unless send(:#{name}_masquerade?)
|
25
|
-
|
46
|
+
GlobalID::Locator.locate_signed(Rails.cache.read(:"devise_masquerade_#{name}"), for: 'masquerade')
|
26
47
|
end
|
27
48
|
|
28
49
|
private
|
@@ -32,7 +53,7 @@ module DeviseMasquerade
|
|
32
53
|
if respond_to?(:bypass_sign_in)
|
33
54
|
bypass_sign_in(resource)
|
34
55
|
else
|
35
|
-
sign_in(resource, :
|
56
|
+
sign_in(resource, bypass: true)
|
36
57
|
end
|
37
58
|
else
|
38
59
|
sign_in(resource)
|
@@ -50,5 +71,3 @@ module DeviseMasquerade
|
|
50
71
|
end
|
51
72
|
end
|
52
73
|
end
|
53
|
-
|
54
|
-
ActionController::Base.send(:include, DeviseMasquerade::Controllers::Helpers)
|
@@ -1,16 +1,30 @@
|
|
1
|
+
require 'securerandom'
|
2
|
+
|
1
3
|
module DeviseMasquerade
|
2
4
|
module Controllers
|
5
|
+
|
3
6
|
module UrlHelpers
|
4
7
|
def masquerade_path(resource, *args)
|
5
8
|
scope = Devise::Mapping.find_scope!(resource)
|
6
|
-
|
9
|
+
|
10
|
+
opts = args.shift || {}
|
11
|
+
opts.merge!(masqueraded_resource_class: resource.class.name)
|
12
|
+
|
13
|
+
opts.merge!(Devise.masquerade_param => resource.masquerade_key)
|
14
|
+
|
15
|
+
send("#{scope}_masquerade_index_path", opts, *args)
|
7
16
|
end
|
8
17
|
|
9
18
|
def back_masquerade_path(resource, *args)
|
10
19
|
scope = Devise::Mapping.find_scope!(resource)
|
11
|
-
|
20
|
+
|
21
|
+
opts = args.first || {}
|
22
|
+
opts.merge!(masqueraded_resource_class: resource.class.name)
|
23
|
+
|
24
|
+
send("back_#{scope}_masquerade_index_path", opts, *args)
|
12
25
|
end
|
13
26
|
end
|
27
|
+
|
14
28
|
end
|
15
29
|
end
|
16
30
|
|
@@ -1,7 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module DeviseMasquerade
|
2
|
-
|
3
|
-
|
4
|
-
|
4
|
+
module Rails
|
5
|
+
|
6
|
+
class Engine < ::Rails::Engine
|
7
|
+
initializer "devise.url_helpers" do
|
8
|
+
Devise.include_helpers(DeviseMasquerade::Controllers)
|
9
|
+
end
|
10
|
+
|
11
|
+
ActiveSupport.on_load(:action_controller) do
|
12
|
+
include DeviseMasquerade::Controllers::Helpers
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
5
16
|
end
|
6
17
|
end
|
7
|
-
|
@@ -1,17 +1,20 @@
|
|
1
|
-
module
|
2
|
-
|
3
|
-
|
4
|
-
protected
|
1
|
+
module DeviseMasquerade
|
2
|
+
module Routes
|
5
3
|
|
6
4
|
def devise_masquerade(mapping, controllers)
|
7
5
|
resources :masquerade,
|
8
|
-
:
|
9
|
-
:
|
10
|
-
:
|
6
|
+
path: mapping.path_names[:masquerade],
|
7
|
+
controller: controllers[:masquerades],
|
8
|
+
only: [] do
|
11
9
|
|
12
|
-
|
10
|
+
collection do
|
11
|
+
get :show
|
12
|
+
get :back
|
13
|
+
end
|
13
14
|
end
|
14
15
|
end
|
16
|
+
|
15
17
|
end
|
16
18
|
end
|
17
19
|
|
20
|
+
ActionDispatch::Routing::Mapper.send :include, DeviseMasquerade::Routes
|
@@ -5,14 +5,13 @@ describe Admin::DashboardController, type: :controller do
|
|
5
5
|
before { admin_logged_in }
|
6
6
|
|
7
7
|
context 'and admin masquerade by user' do
|
8
|
-
let!(:
|
8
|
+
let!(:mask) { create(:admin_user) }
|
9
9
|
|
10
10
|
before do
|
11
|
-
|
12
|
-
get :index, :masquerade => user.masquerade_key
|
11
|
+
get :index, params: { masquerade: mask.masquerade_key, masqueraded_resource_class: 'Admin::User' }
|
13
12
|
end
|
14
13
|
|
15
|
-
it { expect(current_admin_user.reload).to eq(
|
14
|
+
it { expect(current_admin_user.reload).to eq(mask) }
|
16
15
|
end
|
17
16
|
end
|
18
17
|
end
|
@@ -5,15 +5,13 @@ describe DashboardController, type: :controller do
|
|
5
5
|
before { logged_in }
|
6
6
|
|
7
7
|
context 'and admin masquerade by user' do
|
8
|
-
let!(:
|
8
|
+
let!(:mask) { create(:user) }
|
9
9
|
|
10
10
|
before do
|
11
|
-
|
12
|
-
|
13
|
-
get :index, :masquerade => user.masquerade_key
|
11
|
+
get :index, params: { masquerade: mask.masquerade_key }
|
14
12
|
end
|
15
13
|
|
16
|
-
it { expect(current_user.reload).to eq(
|
14
|
+
it { expect(current_user.reload).to eq(mask) }
|
17
15
|
end
|
18
16
|
end
|
19
17
|
end
|
@@ -7,73 +7,97 @@ describe Devise::MasqueradesController, type: :controller do
|
|
7
7
|
context 'when logged in' do
|
8
8
|
before { logged_in }
|
9
9
|
|
10
|
+
context 'with masqueradable_class param' do
|
11
|
+
let(:mask) { create(:student) }
|
12
|
+
|
13
|
+
before do
|
14
|
+
get :show, params: { id: mask.to_param, masqueraded_resource_class: mask.class.name, masquerade: mask.masquerade_key }
|
15
|
+
end
|
16
|
+
|
17
|
+
it { expect(Rails.cache.read('devise_masquerade_student')).to be }
|
18
|
+
|
19
|
+
it 'should have warden keys defined' do
|
20
|
+
expect(session["warden.user.student.key"].first.first).to eq(mask.id)
|
21
|
+
end
|
22
|
+
|
23
|
+
it { should redirect_to('/') }
|
24
|
+
end
|
25
|
+
|
10
26
|
describe '#masquerade user' do
|
11
27
|
let(:mask) { create(:user) }
|
12
28
|
|
13
29
|
before do
|
14
|
-
|
15
|
-
get :show, :id => mask.to_param
|
30
|
+
get :show, params: { id: mask.to_param, masquerade: mask.masquerade_key }
|
16
31
|
end
|
17
32
|
|
18
|
-
it { expect(
|
33
|
+
it { expect(Rails.cache.read('devise_masquerade_user')).to be }
|
19
34
|
it { expect(session["warden.user.user.key"].first.first).to eq(mask.id) }
|
20
|
-
it { should redirect_to(
|
35
|
+
it { should redirect_to('/') }
|
21
36
|
|
22
37
|
context 'and back' do
|
23
38
|
before { get :back }
|
24
39
|
|
25
40
|
it { should redirect_to(masquerade_page) }
|
26
41
|
it { expect(current_user.reload).to eq(@user) }
|
27
|
-
it { expect(
|
42
|
+
it { expect(Rails.cache.read('devise_masquerade_user')).not_to be }
|
28
43
|
end
|
44
|
+
end
|
29
45
|
|
30
|
-
|
31
|
-
|
32
|
-
|
46
|
+
# Configure masquerade_routes_back setting
|
47
|
+
describe 'config#masquerade_routes_back' do
|
48
|
+
let(:mask) { create(:user) }
|
33
49
|
|
34
|
-
|
35
|
-
before { expect(SecureRandom).to receive(:urlsafe_base64) { "secure_key" } }
|
50
|
+
before { Devise.setup { |c| c.masquerade_routes_back = true } }
|
36
51
|
|
37
|
-
|
38
|
-
before do
|
39
|
-
@request.env['HTTP_REFERER'] = 'previous_location'
|
40
|
-
get :show, id: mask.to_param
|
41
|
-
end # before
|
52
|
+
after { Devise.masquerade_routes_back = false }
|
42
53
|
|
43
|
-
|
44
|
-
|
54
|
+
context 'show' do
|
55
|
+
context 'with http referrer' do
|
56
|
+
before do
|
57
|
+
@request.env['HTTP_REFERER'] = 'previous_location'
|
58
|
+
get :show, params: { id: mask.to_param, masquerade: mask.masquerade_key }
|
59
|
+
end # before
|
45
60
|
|
46
|
-
|
47
|
-
|
48
|
-
allow_any_instance_of(described_class).to receive(:after_masquerade_path_for).and_return("/dashboard?color=red")
|
49
|
-
end
|
61
|
+
it { should redirect_to('previous_location') }
|
62
|
+
end # context
|
50
63
|
|
51
|
-
|
64
|
+
context 'no http referrer' do
|
65
|
+
before do
|
66
|
+
allow_any_instance_of(described_class).to(
|
67
|
+
receive(:after_masquerade_path_for).and_return("/dashboard?color=red"))
|
68
|
+
end
|
52
69
|
|
53
|
-
|
54
|
-
|
70
|
+
before { get :show, params: { id: mask.to_param, masquerade: mask.masquerade_key } }
|
71
|
+
|
72
|
+
it { should redirect_to("/dashboard?color=red") }
|
55
73
|
end # context
|
74
|
+
end # context
|
56
75
|
|
57
|
-
|
58
|
-
|
76
|
+
context 'and back' do
|
77
|
+
before do
|
78
|
+
get :show, params: { id: mask.to_param, masquerade: mask.masquerade_key }
|
59
79
|
|
60
|
-
|
61
|
-
end
|
80
|
+
get :back
|
81
|
+
end
|
62
82
|
|
63
|
-
|
64
|
-
|
65
|
-
@request.env['HTTP_REFERER'] = 'previous_location'
|
66
|
-
get :back
|
67
|
-
end
|
83
|
+
it { should redirect_to(masquerade_page) }
|
84
|
+
end # context
|
68
85
|
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
86
|
+
context 'and back fallback if http_referer not present' do
|
87
|
+
before do
|
88
|
+
get :show, params: { id: mask.to_param, masquerade: mask.masquerade_key }
|
89
|
+
|
90
|
+
@request.env['HTTP_REFERER'] = 'previous_location'
|
91
|
+
get :back
|
92
|
+
end
|
93
|
+
|
94
|
+
it { should redirect_to('previous_location') }
|
95
|
+
end # context
|
96
|
+
end # describe
|
73
97
|
end
|
74
98
|
|
75
99
|
context 'when not logged in' do
|
76
|
-
before { get :show, :id
|
100
|
+
before { get :show, params: { id: 'any_id' } }
|
77
101
|
|
78
102
|
it { should redirect_to(new_user_session_path) }
|
79
103
|
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe MasqueradesTestsController, type: :controller do
|
4
|
+
before { @request.env['devise.mapping'] = Devise.mappings[:user] }
|
5
|
+
|
6
|
+
context 'no access for masquerade' do
|
7
|
+
before do
|
8
|
+
session.clear
|
9
|
+
allow_any_instance_of(MasqueradesTestsController).to receive(:masquerade_authorized?) { false }
|
10
|
+
end
|
11
|
+
|
12
|
+
before { logged_in }
|
13
|
+
|
14
|
+
let(:mask) { create(:user) }
|
15
|
+
|
16
|
+
before { get :show, params: { id: mask.to_param, masquerade: mask.masquerade_key } }
|
17
|
+
|
18
|
+
it { expect(response.status).to eq(403) }
|
19
|
+
it { expect(Rails.cache.read('devise_masquerade_user')).not_to be }
|
20
|
+
it { expect(session['warden.user.user.key'].first.first).not_to eq(mask.id) }
|
21
|
+
end
|
22
|
+
|
23
|
+
context 'access for masquerade' do
|
24
|
+
before do
|
25
|
+
session.clear
|
26
|
+
allow_any_instance_of(MasqueradesTestsController).to receive(:masquerade_authorized?) { true }
|
27
|
+
end
|
28
|
+
|
29
|
+
before { logged_in }
|
30
|
+
|
31
|
+
let(:mask) { create(:user) }
|
32
|
+
|
33
|
+
before do
|
34
|
+
get :show, params: { id: mask.to_param, masquerade: mask.masquerade_key }
|
35
|
+
end
|
36
|
+
|
37
|
+
it { expect(response.status).to eq(302) }
|
38
|
+
it { expect(Rails.cache.read('devise_masquerade_user')).to be }
|
39
|
+
it { expect(session['warden.user.user.key'].first.first).to eq(mask.id) }
|
40
|
+
end
|
41
|
+
end
|
@@ -1,6 +1,5 @@
|
|
1
1
|
class Admin::DashboardController < ApplicationController
|
2
|
-
|
3
|
-
before_filter :masquerade_admin_user!
|
2
|
+
before_action :authenticate_admin_user!
|
4
3
|
|
5
4
|
def index
|
6
5
|
@users = Admin::User.where("admin_users.id != ?", current_admin_user.id).all
|