devise_masquerade 0.5.3 → 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 +93 -8
- data/app/controllers/devise/masquerades_controller.rb +85 -71
- data/devise_masquerade.gemspec +13 -12
- 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/controllers/helpers.rb +40 -15
- data/lib/devise_masquerade/controllers/url_helpers.rb +18 -4
- data/lib/devise_masquerade/models/masqueradable.rb +13 -0
- data/lib/devise_masquerade/models.rb +9 -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/lib/devise_masquerade.rb +7 -11
- 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 +63 -35
- 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 -41
- data/spec/controllers/masquerades_controller_spec.rb +0 -42
- data/spec/dummy/app/controllers/masquerades_controller.rb +0 -5
|
@@ -1,84 +1,43 @@
|
|
|
1
1
|
class Devise::MasqueradesController < DeviseController
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
2
|
+
Devise.mappings.each do |name, _|
|
|
3
|
+
class_eval <<-METHODS, __FILE__, __LINE__ + 1
|
|
4
|
+
skip_before_action :masquerade_#{name}!, raise: false
|
|
5
|
+
METHODS
|
|
6
6
|
end
|
|
7
|
+
skip_before_action :masquerade!, raise: false
|
|
7
8
|
|
|
8
|
-
|
|
9
|
-
before_action :save_masquerade_owner_session, :only => :show
|
|
10
|
-
else
|
|
11
|
-
before_filter :save_masquerade_owner_session, :only => :show
|
|
12
|
-
end
|
|
9
|
+
prepend_before_action :authenticate_scope!, :masquerade_authorize!
|
|
13
10
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
after_filter :cleanup_masquerade_owner_session, :only => :back
|
|
18
|
-
end
|
|
11
|
+
before_action :save_masquerade_owner_session, only: :show
|
|
12
|
+
|
|
13
|
+
after_action :cleanup_masquerade_owner_session, only: :back
|
|
19
14
|
|
|
20
15
|
def show
|
|
21
|
-
self.resource =
|
|
16
|
+
self.resource = find_resource
|
|
22
17
|
|
|
23
|
-
unless
|
|
18
|
+
unless resource
|
|
24
19
|
flash[:error] = "#{masqueraded_resource_class} not found."
|
|
25
20
|
redirect_to(new_user_session_path) and return
|
|
26
21
|
end
|
|
27
22
|
|
|
28
|
-
|
|
29
|
-
request.env["devise.skip_trackable"] = "1"
|
|
23
|
+
request.env['devise.skip_trackable'] = '1'
|
|
30
24
|
|
|
31
|
-
|
|
32
|
-
if respond_to?(:bypass_sign_in)
|
|
33
|
-
bypass_sign_in(self.resource)
|
|
34
|
-
else
|
|
35
|
-
sign_in(self.resource, :bypass => true)
|
|
36
|
-
end
|
|
37
|
-
else
|
|
38
|
-
sign_in(self.resource)
|
|
39
|
-
end
|
|
25
|
+
masquerade_sign_in(resource)
|
|
40
26
|
|
|
41
|
-
|
|
42
|
-
redirect_back(fallback_location: "#{after_masquerade_param_for(self.resource)}?#{after_masquerade_param_for(resource)}")
|
|
43
|
-
elsif Devise.masquerade_routes_back && request.env['HTTP_REFERER'].present?
|
|
44
|
-
redirect_to :back
|
|
45
|
-
else
|
|
46
|
-
redirect_to("#{after_masquerade_path_for(self.resource)}?#{after_masquerade_param_for(resource)}")
|
|
47
|
-
end
|
|
27
|
+
go_back(resource, path: after_masquerade_full_path_for(resource))
|
|
48
28
|
end
|
|
49
29
|
|
|
50
30
|
def back
|
|
51
|
-
|
|
31
|
+
self.resource = find_owner_resource
|
|
52
32
|
|
|
53
|
-
|
|
54
|
-
masquerading_resource_class.to_adapter.find_first(:id => user_id)
|
|
55
|
-
else
|
|
56
|
-
send(:"current_#{masquerading_resource_name}")
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
if masquerading_resource_class != masqueraded_resource_class
|
|
33
|
+
if resource.class != masqueraded_resource_class
|
|
60
34
|
sign_out(send("current_#{masqueraded_resource_name}"))
|
|
61
35
|
end
|
|
62
36
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
bypass_sign_in(owner_user)
|
|
66
|
-
else
|
|
67
|
-
sign_in(owner_user, :bypass => true)
|
|
68
|
-
end
|
|
69
|
-
else
|
|
70
|
-
sign_in(owner_user)
|
|
71
|
-
end
|
|
72
|
-
request.env["devise.skip_trackable"] = nil
|
|
37
|
+
masquerade_sign_in(resource)
|
|
38
|
+
request.env['devise.skip_trackable'] = nil
|
|
73
39
|
|
|
74
|
-
|
|
75
|
-
# If using the masquerade_routes_back and Rails 5
|
|
76
|
-
redirect_back(fallback_location: after_back_masquerade_path_for(owner_user))
|
|
77
|
-
elsif Devise.masquerade_routes_back && request.env['HTTP_REFERER'].present?
|
|
78
|
-
redirect_to :back
|
|
79
|
-
else
|
|
80
|
-
redirect_to after_back_masquerade_path_for(owner_user)
|
|
81
|
-
end
|
|
40
|
+
go_back(resource, path: after_back_masquerade_path_for(resource))
|
|
82
41
|
end
|
|
83
42
|
|
|
84
43
|
protected
|
|
@@ -91,49 +50,104 @@ class Devise::MasqueradesController < DeviseController
|
|
|
91
50
|
true
|
|
92
51
|
end
|
|
93
52
|
|
|
53
|
+
def find_resource
|
|
54
|
+
GlobalID::Locator.locate_signed params[Devise.masquerade_param], for: 'masquerade'
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def find_owner_resource
|
|
58
|
+
GlobalID::Locator.locate_signed(Rails.cache.read(session_key), for: 'masquerade')
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def go_back(user, path:)
|
|
62
|
+
if Devise.masquerade_routes_back
|
|
63
|
+
redirect_back(fallback_location: path)
|
|
64
|
+
else
|
|
65
|
+
redirect_to path
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
94
69
|
private
|
|
95
70
|
|
|
96
71
|
def masqueraded_resource_class
|
|
97
|
-
|
|
72
|
+
@masqueraded_resource_class ||= begin
|
|
73
|
+
unless params[:masqueraded_resource_class].blank?
|
|
74
|
+
params[:masqueraded_resource_class].constantize
|
|
75
|
+
else
|
|
76
|
+
unless session[session_key_masqueraded_resource_class].blank?
|
|
77
|
+
session[session_key_masquerading_resource_class].constantize
|
|
78
|
+
else
|
|
79
|
+
Devise.masqueraded_resource_class || resource_class
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
98
83
|
end
|
|
99
84
|
|
|
100
85
|
def masqueraded_resource_name
|
|
101
|
-
Devise.masqueraded_resource_name ||
|
|
86
|
+
Devise.masqueraded_resource_name || masqueraded_resource_class.model_name.param_key
|
|
102
87
|
end
|
|
103
88
|
|
|
104
89
|
def masquerading_resource_class
|
|
105
|
-
|
|
90
|
+
@masquerading_resource_class ||= begin
|
|
91
|
+
unless params[:masquerading_resource_class].blank?
|
|
92
|
+
params[:masquerading_resource_class].constantize
|
|
93
|
+
else
|
|
94
|
+
unless session[session_key_masquerading_resource_class].blank?
|
|
95
|
+
session[session_key_masquerading_resource_class].constantize
|
|
96
|
+
else
|
|
97
|
+
Devise.masquerading_resource_class || resource_class
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
end
|
|
106
101
|
end
|
|
107
102
|
|
|
108
103
|
def masquerading_resource_name
|
|
109
|
-
Devise.masquerading_resource_name ||
|
|
104
|
+
Devise.masquerading_resource_name || masquerading_resource_class.model_name.param_key
|
|
110
105
|
end
|
|
111
106
|
|
|
112
107
|
def authenticate_scope!
|
|
113
|
-
send(:"authenticate_#{masquerading_resource_name}!", :
|
|
108
|
+
send(:"authenticate_#{masquerading_resource_name}!", force: true)
|
|
114
109
|
end
|
|
115
110
|
|
|
116
111
|
def after_masquerade_path_for(resource)
|
|
117
|
-
|
|
112
|
+
'/'
|
|
118
113
|
end
|
|
119
114
|
|
|
120
|
-
def
|
|
121
|
-
|
|
115
|
+
def after_masquerade_full_path_for(resource)
|
|
116
|
+
after_masquerade_path_for(resource)
|
|
122
117
|
end
|
|
123
118
|
|
|
124
119
|
def after_back_masquerade_path_for(resource)
|
|
125
|
-
|
|
120
|
+
'/'
|
|
126
121
|
end
|
|
127
122
|
|
|
128
123
|
def save_masquerade_owner_session
|
|
129
|
-
|
|
124
|
+
resource_gid = send("current_#{masquerading_resource_name}").to_sgid(
|
|
125
|
+
expires_in: Devise.masquerade_expires_in, for: 'masquerade')
|
|
126
|
+
# skip sharing owner id via session
|
|
127
|
+
Rails.cache.write(session_key, resource_gid, expires_in: Devise.masquerade_expires_in)
|
|
128
|
+
|
|
129
|
+
unless session.key?(session_key)
|
|
130
|
+
session[session_key_masquerading_resource_class] = masquerading_resource_class.name
|
|
131
|
+
session[session_key_masqueraded_resource_class] = masqueraded_resource_class.name
|
|
132
|
+
end
|
|
130
133
|
end
|
|
131
134
|
|
|
132
135
|
def cleanup_masquerade_owner_session
|
|
133
|
-
|
|
136
|
+
Rails.cache.delete(session_key)
|
|
137
|
+
|
|
138
|
+
session.delete(session_key_masqueraded_resource_class)
|
|
139
|
+
session.delete(session_key_masquerading_resource_class)
|
|
134
140
|
end
|
|
135
141
|
|
|
136
142
|
def session_key
|
|
137
143
|
"devise_masquerade_#{masqueraded_resource_name}".to_sym
|
|
138
144
|
end
|
|
145
|
+
|
|
146
|
+
def session_key_masqueraded_resource_class
|
|
147
|
+
"devise_masquerade_masqueraded_resource_class"
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
def session_key_masquerading_resource_class
|
|
151
|
+
"devise_masquerade_masquerading_resource_class"
|
|
152
|
+
end
|
|
139
153
|
end
|
data/devise_masquerade.gemspec
CHANGED
|
@@ -1,27 +1,28 @@
|
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
|
2
|
+
|
|
2
3
|
lib = File.expand_path('../lib', __FILE__)
|
|
3
4
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
5
|
require 'devise_masquerade/version'
|
|
5
6
|
|
|
6
7
|
Gem::Specification.new do |gem|
|
|
7
|
-
gem.name =
|
|
8
|
+
gem.name = 'devise_masquerade'
|
|
8
9
|
gem.version = DeviseMasquerade::VERSION
|
|
9
|
-
gem.authors = [
|
|
10
|
-
gem.email = [
|
|
11
|
-
gem.description =
|
|
12
|
-
gem.summary =
|
|
13
|
-
gem.homepage =
|
|
10
|
+
gem.authors = ['Alexandr Korsak']
|
|
11
|
+
gem.email = ['alex.korsak@gmail.com']
|
|
12
|
+
gem.description = 'devise masquerade library'
|
|
13
|
+
gem.summary = 'use for login as functionallity on your admin users pages'
|
|
14
|
+
gem.homepage = 'http://github.com/oivoodoo/devise_masquerade'
|
|
14
15
|
|
|
15
16
|
gem.files = `git ls-files`.split($/)
|
|
16
|
-
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
|
17
|
+
gem.executables = gem.files.grep(%r{^bin/}).map { |f| File.basename(f) }
|
|
17
18
|
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
|
18
|
-
gem.require_paths = [
|
|
19
|
+
gem.require_paths = ['lib']
|
|
19
20
|
|
|
20
21
|
gem.license = 'MIT'
|
|
21
22
|
|
|
22
|
-
gem.add_development_dependency('bundler', '>=
|
|
23
|
+
gem.add_development_dependency('bundler', '>= 2.0.0')
|
|
23
24
|
|
|
24
|
-
gem.add_runtime_dependency('railties', '>=
|
|
25
|
-
gem.add_runtime_dependency('devise', '>=
|
|
25
|
+
gem.add_runtime_dependency('railties', '>= 5.2.0')
|
|
26
|
+
gem.add_runtime_dependency('devise', '>= 4.7.0')
|
|
27
|
+
gem.add_runtime_dependency('globalid', '>= 0.3.6')
|
|
26
28
|
end
|
|
27
|
-
|
data/features/back.feature
CHANGED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
Feature: Use various models for masquerading
|
|
2
|
+
In order to use various models for masquerading
|
|
3
|
+
As an masquerade user
|
|
4
|
+
I want to be able to press press masquerade as link for different models
|
|
5
|
+
|
|
6
|
+
Scenario: Use masquerade button on student and user models
|
|
7
|
+
Given I logged in
|
|
8
|
+
And I have a user for masquerade
|
|
9
|
+
And I have a student for masquerade
|
|
10
|
+
|
|
11
|
+
When I am on the users page
|
|
12
|
+
And I login as one user
|
|
13
|
+
Then I should be login as this user
|
|
14
|
+
|
|
15
|
+
When I am on the students page
|
|
16
|
+
And I login as one student
|
|
17
|
+
Then I should be login as this student
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
Given /^I have a user for masquerade$/ do
|
|
2
|
-
@
|
|
2
|
+
@user_mask = create(:user)
|
|
3
3
|
end
|
|
4
4
|
|
|
5
5
|
When /^I am on the users page$/ do
|
|
@@ -7,11 +7,11 @@ When /^I am on the users page$/ do
|
|
|
7
7
|
end
|
|
8
8
|
|
|
9
9
|
When /^I login as one user$/ do
|
|
10
|
-
|
|
10
|
+
find('.login_as').click
|
|
11
11
|
end
|
|
12
12
|
|
|
13
13
|
Then /^I should be login as this user$/ do
|
|
14
|
-
find('.current_user').should have_content(@
|
|
14
|
+
find('.current_user').should have_content(@user_mask.email)
|
|
15
15
|
end
|
|
16
16
|
|
|
17
17
|
When /^I press back masquerade button$/ do
|
|
@@ -22,3 +22,18 @@ Then /^I should be login as owner user$/ do
|
|
|
22
22
|
find('.current_user').should have_content(@user.email)
|
|
23
23
|
end
|
|
24
24
|
|
|
25
|
+
Given /^I have a student for masquerade$/ do
|
|
26
|
+
@student_mask = create(:student)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
When /^I am on the students page$/ do
|
|
30
|
+
visit '/students'
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
When /^I login as one student$/ do
|
|
34
|
+
find('.login_as').click
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
Then /^I should be login as this student$/ do
|
|
38
|
+
find('.current_student').should have_content(@student_mask.email)
|
|
39
|
+
end
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
Then("I should see maquerade url") do
|
|
2
|
+
page.html.should include('href="/users/masquerade?masquerade=')
|
|
3
|
+
end
|
|
4
|
+
|
|
5
|
+
When("I am on the users page with extra params") do
|
|
6
|
+
visit '/extra_params'
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
Then("I should see maquerade url with extra params") do
|
|
10
|
+
page.html.should include('href="/users/masquerade?key1=value1&masquerade=')
|
|
11
|
+
end
|
data/features/support/env.rb
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
require 'cucumber/rails'
|
|
2
|
-
require '
|
|
2
|
+
require 'factory_bot'
|
|
3
3
|
require 'database_cleaner'
|
|
4
4
|
require 'cucumber/rspec/doubles'
|
|
5
5
|
|
|
@@ -9,9 +9,11 @@ ENV["RAILS_ENV"] = "test"
|
|
|
9
9
|
|
|
10
10
|
Capybara.default_selector = :css
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
ActiveSupport.on_load(:action_controller) do
|
|
13
|
+
self.allow_rescue = false
|
|
14
|
+
end
|
|
13
15
|
|
|
14
|
-
World(
|
|
16
|
+
World(FactoryBot::Syntax::Methods)
|
|
15
17
|
|
|
16
18
|
begin
|
|
17
19
|
DatabaseCleaner.strategy = :transaction
|
|
@@ -20,7 +22,24 @@ rescue NameError
|
|
|
20
22
|
end
|
|
21
23
|
|
|
22
24
|
Cucumber::Rails::Database.javascript_strategy = :truncation
|
|
23
|
-
|
|
25
|
+
|
|
26
|
+
Capybara.register_driver :chrome do |app|
|
|
27
|
+
Capybara::Selenium::Driver.new(app, browser: :chrome)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
Capybara.register_driver :headless_chrome do |app|
|
|
31
|
+
caps = Selenium::WebDriver::Remote::Capabilities.chrome(loggingPrefs: { browser: 'ALL' })
|
|
32
|
+
opts = Selenium::WebDriver::Chrome::Options.new
|
|
33
|
+
|
|
34
|
+
chrome_args = %w[--headless --window-size=1920,1080 --no-sandbox --disable-dev-shm-usage]
|
|
35
|
+
chrome_args.each { |arg| opts.add_argument(arg) }
|
|
36
|
+
Capybara::Selenium::Driver.new(app, browser: :chrome, options: opts, desired_capabilities: caps)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
Capybara.configure do |config|
|
|
40
|
+
# change this to :chrome to observe tests in a real browser
|
|
41
|
+
config.javascript_driver = :headless_chrome
|
|
42
|
+
end
|
|
24
43
|
|
|
25
44
|
Before do
|
|
26
45
|
allow_any_instance_of(DeviseController).to receive(:devise_mapping) { Devise.mappings[:user] }
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
Feature: Use masquerade path to generate routes on page
|
|
2
|
+
In order to have the way to render masquerade path
|
|
3
|
+
As an user
|
|
4
|
+
I want to be able to see the url and use it
|
|
5
|
+
|
|
6
|
+
Scenario: Use masquerade path helper
|
|
7
|
+
Given I logged in
|
|
8
|
+
And I have a user for masquerade
|
|
9
|
+
|
|
10
|
+
When I am on the users page
|
|
11
|
+
Then I should see maquerade url
|
|
12
|
+
|
|
13
|
+
When I am on the users page with extra params
|
|
14
|
+
Then I should see maquerade url with extra params
|
|
@@ -6,31 +6,58 @@ 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
|
-
|
|
16
|
-
if respond_to?(:bypass_sign_in)
|
|
17
|
-
bypass_sign_in(#{name})
|
|
18
|
-
else
|
|
19
|
-
sign_in(#{name}, :bypass => true)
|
|
20
|
-
end
|
|
21
|
-
else
|
|
22
|
-
sign_in(#{name})
|
|
23
|
-
end
|
|
35
|
+
if resource
|
|
36
|
+
masquerade_sign_in(resource)
|
|
24
37
|
end
|
|
25
38
|
end
|
|
26
39
|
|
|
27
40
|
def #{name}_masquerade?
|
|
28
|
-
|
|
41
|
+
::Rails.cache.exist?(:"devise_masquerade_#{name}").present?
|
|
29
42
|
end
|
|
30
43
|
|
|
31
44
|
def #{name}_masquerade_owner
|
|
32
45
|
return nil unless send(:#{name}_masquerade?)
|
|
33
|
-
|
|
46
|
+
GlobalID::Locator.locate_signed(Rails.cache.read(:"devise_masquerade_#{name}"), for: 'masquerade')
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
private
|
|
50
|
+
|
|
51
|
+
def masquerade_sign_in(resource)
|
|
52
|
+
if Devise.masquerade_bypass_warden_callback
|
|
53
|
+
if respond_to?(:bypass_sign_in)
|
|
54
|
+
bypass_sign_in(resource)
|
|
55
|
+
else
|
|
56
|
+
sign_in(resource, bypass: true)
|
|
57
|
+
end
|
|
58
|
+
else
|
|
59
|
+
sign_in(resource)
|
|
60
|
+
end
|
|
34
61
|
end
|
|
35
62
|
METHODS
|
|
36
63
|
|
|
@@ -44,5 +71,3 @@ module DeviseMasquerade
|
|
|
44
71
|
end
|
|
45
72
|
end
|
|
46
73
|
end
|
|
47
|
-
|
|
48
|
-
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
|
-
def masquerade_path(resource)
|
|
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
|
-
def back_masquerade_path(resource)
|
|
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
|
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
|
|
@@ -27,18 +21,20 @@ module Devise
|
|
|
27
21
|
mattr_accessor :masquerade_routes_back
|
|
28
22
|
@@masquerade_routes_back = false
|
|
29
23
|
|
|
24
|
+
# Example: Devise.masqueraded_resource_class = User
|
|
30
25
|
mattr_accessor :masqueraded_resource_class
|
|
31
26
|
|
|
27
|
+
# Example: Devise.masqueraded_resource_name = :user
|
|
32
28
|
mattr_accessor :masqueraded_resource_name
|
|
33
|
-
@@masqueraded_resource_name = :user
|
|
34
29
|
|
|
30
|
+
# Example: Devise.masquerading_resource_class = AdminUser
|
|
35
31
|
mattr_accessor :masquerading_resource_class
|
|
36
32
|
|
|
33
|
+
# Example: Devise.masquerading_resource_name = :admin_user
|
|
37
34
|
mattr_accessor :masquerading_resource_name
|
|
38
|
-
@@masquerading_resource_name = :user
|
|
39
35
|
|
|
40
36
|
@@helpers << DeviseMasquerade::Controllers::Helpers
|
|
41
37
|
end
|
|
42
38
|
|
|
43
|
-
Devise.add_module :masqueradable, :
|
|
44
|
-
|
|
39
|
+
Devise.add_module :masqueradable, controller: :masquerades,
|
|
40
|
+
model: 'devise_masquerade/models', route: :masquerade
|
|
@@ -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
|