devise_masquerade 1.1.0 → 1.2.0
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.
Potentially problematic release.
This version of devise_masquerade might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/README.md +2 -1
- data/app/controllers/devise/masquerades_controller.rb +35 -18
- data/lib/devise_masquerade.rb +1 -1
- data/lib/devise_masquerade/controllers/helpers.rb +4 -4
- data/lib/devise_masquerade/controllers/url_helpers.rb +9 -0
- data/lib/devise_masquerade/models/masqueradable.rb +10 -1
- data/lib/devise_masquerade/version.rb +1 -1
- data/spec/controllers/devise/masquerades_controller_spec.rb +44 -40
- data/spec/controllers/masquerades_tests_controller_spec.rb +8 -5
- data/spec/models/user_spec.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a3d9619a76cbee988888a5168f0cf57b74a59fd7b5c3cfbbac3113458c5cb60c
|
4
|
+
data.tar.gz: 9d04f07b596f095533e4e766f0ed1e0672f0078ae5fcecf696571326ed3d3b8d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 82d09ecc8063ce935f4125d7c8ecd73772a5d7ad5e5a9e6a909cb18e899793229a473ffdceb6a1c5a1eb36ddd244c2646f248e205f62b4d0c70ad47ef1cadbe9
|
7
|
+
data.tar.gz: 8c9456b986f8761a5258d1099777d0e8a0d71974de41e1e220c50e6cd7cfec362956d5f41b7ab1466cddbc7d49c350c04febe852f9920bca99a27c1e043ce024
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -42,7 +42,8 @@ In the model you'll need to add the parameter :masqueradable to the existing com
|
|
42
42
|
devise :invitable, :confirmable, :database_authenticatable, :registerable, :masqueradable
|
43
43
|
```
|
44
44
|
|
45
|
-
Add into your application_controller.rb
|
45
|
+
Add into your `application_controller.rb` if you want to have custom way on sign in by using masquerade token otherwise you can still
|
46
|
+
use only `masquerade_path` in your view to generate temporary token and link to make `Login As`:
|
46
47
|
|
47
48
|
```ruby
|
48
49
|
before_action :masquerade_user!
|
@@ -1,4 +1,11 @@
|
|
1
1
|
class Devise::MasqueradesController < DeviseController
|
2
|
+
Devise.mappings.each do |name, _|
|
3
|
+
class_eval <<-METHODS, __FILE__, __LINE__ + 1
|
4
|
+
skip_before_action :masquerade_#{name}!, raise: false
|
5
|
+
METHODS
|
6
|
+
end
|
7
|
+
skip_before_action :masquerade!, raise: false
|
8
|
+
|
2
9
|
prepend_before_action :authenticate_scope!, :masquerade_authorize!
|
3
10
|
|
4
11
|
before_action :save_masquerade_owner_session, only: :show
|
@@ -13,8 +20,7 @@ class Devise::MasqueradesController < DeviseController
|
|
13
20
|
redirect_to(new_user_session_path) and return
|
14
21
|
end
|
15
22
|
|
16
|
-
|
17
|
-
request.env["devise.skip_trackable"] = "1"
|
23
|
+
request.env['devise.skip_trackable'] = '1'
|
18
24
|
|
19
25
|
masquerade_sign_in(resource)
|
20
26
|
|
@@ -51,7 +57,10 @@ class Devise::MasqueradesController < DeviseController
|
|
51
57
|
end
|
52
58
|
|
53
59
|
def find_resource
|
54
|
-
masqueraded_resource_class.
|
60
|
+
masqueraded_resource_class.
|
61
|
+
find_by_masquerade_key(params[Devise.masquerade_param]).
|
62
|
+
where(id: params[:id]).
|
63
|
+
first
|
55
64
|
end
|
56
65
|
|
57
66
|
def go_back(user, path:)
|
@@ -69,7 +78,11 @@ class Devise::MasqueradesController < DeviseController
|
|
69
78
|
unless params[:masqueraded_resource_class].blank?
|
70
79
|
params[:masqueraded_resource_class].constantize
|
71
80
|
else
|
72
|
-
|
81
|
+
unless session[session_key_masqueraded_resource_class].blank?
|
82
|
+
session[session_key_masquerading_resource_class].constantize
|
83
|
+
else
|
84
|
+
Devise.masqueraded_resource_class || resource_class
|
85
|
+
end
|
73
86
|
end
|
74
87
|
end
|
75
88
|
end
|
@@ -83,7 +96,11 @@ class Devise::MasqueradesController < DeviseController
|
|
83
96
|
unless params[:masquerading_resource_class].blank?
|
84
97
|
params[:masquerading_resource_class].constantize
|
85
98
|
else
|
86
|
-
|
99
|
+
unless session[session_key_masquerading_resource_class].blank?
|
100
|
+
session[session_key_masquerading_resource_class].constantize
|
101
|
+
else
|
102
|
+
Devise.masquerading_resource_class || resource_class
|
103
|
+
end
|
87
104
|
end
|
88
105
|
end
|
89
106
|
end
|
@@ -101,19 +118,7 @@ class Devise::MasqueradesController < DeviseController
|
|
101
118
|
end
|
102
119
|
|
103
120
|
def after_masquerade_full_path_for(resource)
|
104
|
-
|
105
|
-
"#{after_masquerade_path_for(resource)}&#{after_masquerade_param_for(resource)}"
|
106
|
-
else
|
107
|
-
"#{after_masquerade_path_for(resource)}?#{after_masquerade_param_for(resource)}"
|
108
|
-
end
|
109
|
-
end
|
110
|
-
|
111
|
-
def after_masquerade_param_for(resource)
|
112
|
-
[
|
113
|
-
"#{Devise.masquerade_param}=#{resource.masquerade_key}",
|
114
|
-
"masquerading_resource_class=#{masquerading_resource_class}",
|
115
|
-
"masqueraded_resource_class=#{masqueraded_resource_class}",
|
116
|
-
].join('&')
|
121
|
+
after_masquerade_path_for(resource)
|
117
122
|
end
|
118
123
|
|
119
124
|
def after_back_masquerade_path_for(resource)
|
@@ -123,14 +128,26 @@ class Devise::MasqueradesController < DeviseController
|
|
123
128
|
def save_masquerade_owner_session
|
124
129
|
unless session.key?(session_key)
|
125
130
|
session[session_key] = send("current_#{masquerading_resource_name}").id
|
131
|
+
session[session_key_masquerading_resource_class] = masquerading_resource_class.name
|
132
|
+
session[session_key_masqueraded_resource_class] = masqueraded_resource_class.name
|
126
133
|
end
|
127
134
|
end
|
128
135
|
|
129
136
|
def cleanup_masquerade_owner_session
|
130
137
|
session.delete(session_key)
|
138
|
+
session.delete(session_key_masqueraded_resource_class)
|
139
|
+
session.delete(session_key_masquerading_resource_class)
|
131
140
|
end
|
132
141
|
|
133
142
|
def session_key
|
134
143
|
"devise_masquerade_#{masqueraded_resource_name}".to_sym
|
135
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
|
136
153
|
end
|
data/lib/devise_masquerade.rb
CHANGED
@@ -20,7 +20,7 @@ module DeviseMasquerade
|
|
20
20
|
end
|
21
21
|
return unless klass
|
22
22
|
|
23
|
-
resource = klass.find_by_masquerade_key(params["#{Devise.masquerade_param}"])
|
23
|
+
resource = klass.find_by_masquerade_key(params["#{Devise.masquerade_param}"]).first
|
24
24
|
|
25
25
|
if resource
|
26
26
|
masquerade_sign_in(resource)
|
@@ -30,7 +30,7 @@ module DeviseMasquerade
|
|
30
30
|
def masquerade_#{name}!
|
31
31
|
return if params["#{Devise.masquerade_param}"].blank?
|
32
32
|
|
33
|
-
resource = ::#{class_name}.find_by_masquerade_key(params["#{Devise.masquerade_param}"])
|
33
|
+
resource = ::#{class_name}.find_by_masquerade_key(params["#{Devise.masquerade_param}"]).first
|
34
34
|
|
35
35
|
if resource
|
36
36
|
masquerade_sign_in(resource)
|
@@ -43,7 +43,7 @@ module DeviseMasquerade
|
|
43
43
|
|
44
44
|
def #{name}_masquerade_owner
|
45
45
|
return nil unless send(:#{name}_masquerade?)
|
46
|
-
::#{class_name}.to_adapter.find_first(:
|
46
|
+
::#{class_name}.to_adapter.find_first(id: session[:"devise_masquerade_#{name}"])
|
47
47
|
end
|
48
48
|
|
49
49
|
private
|
@@ -53,7 +53,7 @@ module DeviseMasquerade
|
|
53
53
|
if respond_to?(:bypass_sign_in)
|
54
54
|
bypass_sign_in(resource)
|
55
55
|
else
|
56
|
-
sign_in(resource, :
|
56
|
+
sign_in(resource, bypass: true)
|
57
57
|
end
|
58
58
|
else
|
59
59
|
sign_in(resource)
|
@@ -1,18 +1,27 @@
|
|
1
|
+
require 'securerandom'
|
2
|
+
|
1
3
|
module DeviseMasquerade
|
2
4
|
module Controllers
|
3
5
|
|
4
6
|
module UrlHelpers
|
5
7
|
def masquerade_path(resource, *args)
|
6
8
|
scope = Devise::Mapping.find_scope!(resource)
|
9
|
+
|
7
10
|
opts = args.first || {}
|
8
11
|
opts.merge!(masqueraded_resource_class: resource.class.name)
|
12
|
+
|
13
|
+
resource.masquerade!
|
14
|
+
opts.merge!(Devise.masquerade_param => resource.masquerade_key)
|
15
|
+
|
9
16
|
send("#{scope}_masquerade_path", resource, opts, *args)
|
10
17
|
end
|
11
18
|
|
12
19
|
def back_masquerade_path(resource, *args)
|
13
20
|
scope = Devise::Mapping.find_scope!(resource)
|
21
|
+
|
14
22
|
opts = args.first || {}
|
15
23
|
opts.merge!(masqueraded_resource_class: resource.class.name)
|
24
|
+
|
16
25
|
send("back_#{scope}_masquerade_index_path", opts, *args)
|
17
26
|
end
|
18
27
|
end
|
@@ -30,7 +30,16 @@ module DeviseMasquerade
|
|
30
30
|
# clean up the cached masquerade key value
|
31
31
|
remove_masquerade_key!(key)
|
32
32
|
|
33
|
-
where(id: id)
|
33
|
+
where(id: id)
|
34
|
+
end
|
35
|
+
|
36
|
+
def find_by_masquerade_key(key)
|
37
|
+
id = ::Rails.cache.read(cache_masquerade_key_by(key))
|
38
|
+
|
39
|
+
# clean up the cached masquerade key value
|
40
|
+
remove_masquerade_key!(key)
|
41
|
+
|
42
|
+
where(id: id)
|
34
43
|
end
|
35
44
|
end # ClassMethods
|
36
45
|
end
|
@@ -10,9 +10,10 @@ describe Devise::MasqueradesController, type: :controller do
|
|
10
10
|
context 'with masqueradable_class param' do
|
11
11
|
let(:mask) { create(:student) }
|
12
12
|
|
13
|
+
before { mask.masquerade! }
|
14
|
+
|
13
15
|
before do
|
14
|
-
|
15
|
-
get :show, params: { id: mask.to_param, masqueraded_resource_class: mask.class.name }
|
16
|
+
get :show, params: { id: mask.to_param, masqueraded_resource_class: mask.class.name, masquerade: mask.masquerade_key }
|
16
17
|
end
|
17
18
|
|
18
19
|
it { expect(session.keys).to include('devise_masquerade_student') }
|
@@ -21,20 +22,21 @@ describe Devise::MasqueradesController, type: :controller do
|
|
21
22
|
expect(session["warden.user.student.key"].first.first).to eq(mask.id)
|
22
23
|
end
|
23
24
|
|
24
|
-
it { should redirect_to(
|
25
|
+
it { should redirect_to('/') }
|
25
26
|
end
|
26
27
|
|
27
28
|
describe '#masquerade user' do
|
28
29
|
let(:mask) { create(:user) }
|
29
30
|
|
31
|
+
before { mask.masquerade! }
|
32
|
+
|
30
33
|
before do
|
31
|
-
|
32
|
-
get :show, params: { id: mask.to_param }
|
34
|
+
get :show, params: { id: mask.to_param, masquerade: mask.masquerade_key }
|
33
35
|
end
|
34
36
|
|
35
37
|
it { expect(session.keys).to include('devise_masquerade_user') }
|
36
38
|
it { expect(session["warden.user.user.key"].first.first).to eq(mask.id) }
|
37
|
-
it { should redirect_to(
|
39
|
+
it { should redirect_to('/') }
|
38
40
|
|
39
41
|
context 'and back' do
|
40
42
|
before { get :back }
|
@@ -43,53 +45,55 @@ describe Devise::MasqueradesController, type: :controller do
|
|
43
45
|
it { expect(current_user.reload).to eq(@user) }
|
44
46
|
it { expect(session.keys).not_to include('devise_masquerade_user') }
|
45
47
|
end
|
48
|
+
end
|
46
49
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
+
# Configure masquerade_routes_back setting
|
51
|
+
describe 'config#masquerade_routes_back' do
|
52
|
+
let(:mask) { create(:user) }
|
50
53
|
|
51
|
-
|
54
|
+
before { Devise.setup { |c| c.masquerade_routes_back = true } }
|
52
55
|
|
53
|
-
|
54
|
-
before { expect(SecureRandom).to receive(:urlsafe_base64) { "secure_key" } }
|
56
|
+
after { Devise.masquerade_routes_back = false }
|
55
57
|
|
56
|
-
|
57
|
-
before do
|
58
|
-
@request.env['HTTP_REFERER'] = 'previous_location'
|
59
|
-
get :show, params: { id: mask.to_param }
|
60
|
-
end # before
|
58
|
+
before { mask.masquerade! }
|
61
59
|
|
62
|
-
|
63
|
-
|
60
|
+
context 'show' do
|
61
|
+
context 'with http referrer' do
|
62
|
+
before do
|
63
|
+
@request.env['HTTP_REFERER'] = 'previous_location'
|
64
|
+
get :show, params: { id: mask.to_param, masquerade: mask.masquerade_key }
|
65
|
+
end # before
|
64
66
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
67
|
+
it { should redirect_to('previous_location') }
|
68
|
+
end # context
|
69
|
+
|
70
|
+
context 'no http referrer' do
|
71
|
+
before do
|
72
|
+
allow_any_instance_of(described_class).to(
|
73
|
+
receive(:after_masquerade_path_for).and_return("/dashboard?color=red"))
|
74
|
+
end
|
70
75
|
|
71
|
-
|
76
|
+
before { get :show, params: { id: mask.to_param, masquerade: mask.masquerade_key } }
|
72
77
|
|
73
|
-
|
74
|
-
end # context
|
78
|
+
it { should redirect_to("/dashboard?color=red") }
|
75
79
|
end # context
|
80
|
+
end # context
|
76
81
|
|
77
|
-
|
78
|
-
|
82
|
+
context 'and back' do
|
83
|
+
before { get :back }
|
79
84
|
|
80
|
-
|
81
|
-
|
85
|
+
it { should redirect_to(masquerade_page) }
|
86
|
+
end # context
|
82
87
|
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
+
context 'and back fallback if http_referer not present' do
|
89
|
+
before do
|
90
|
+
@request.env['HTTP_REFERER'] = 'previous_location'
|
91
|
+
get :back
|
92
|
+
end
|
88
93
|
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
end
|
94
|
+
it { should redirect_to('previous_location') }
|
95
|
+
end # context
|
96
|
+
end # describe
|
93
97
|
end
|
94
98
|
|
95
99
|
context 'when not logged in' do
|
@@ -13,11 +13,13 @@ describe MasqueradesTestsController, type: :controller do
|
|
13
13
|
|
14
14
|
let(:mask) { create(:user) }
|
15
15
|
|
16
|
-
before {
|
16
|
+
before { mask.masquerade! }
|
17
|
+
|
18
|
+
before { get :show, params: { id: mask.to_param, masquerade: mask.masquerade_key } }
|
17
19
|
|
18
20
|
it { expect(response.status).to eq(403) }
|
19
21
|
it { expect(session.keys).not_to include('devise_masquerade_user') }
|
20
|
-
it { expect(session[
|
22
|
+
it { expect(session['warden.user.user.key'].first.first).not_to eq(mask.id) }
|
21
23
|
end
|
22
24
|
|
23
25
|
context 'access for masquerade' do
|
@@ -30,13 +32,14 @@ describe MasqueradesTestsController, type: :controller do
|
|
30
32
|
|
31
33
|
let(:mask) { create(:user) }
|
32
34
|
|
35
|
+
before { mask.masquerade! }
|
36
|
+
|
33
37
|
before do
|
34
|
-
|
35
|
-
get :show, params: { id: mask.to_param }
|
38
|
+
get :show, params: { id: mask.to_param, masquerade: mask.masquerade_key }
|
36
39
|
end
|
37
40
|
|
38
41
|
it { expect(response.status).to eq(302) }
|
39
42
|
it { expect(session.keys).to include('devise_masquerade_user') }
|
40
|
-
it { expect(session[
|
43
|
+
it { expect(session['warden.user.user.key'].first.first).to eq(mask.id) }
|
41
44
|
end
|
42
45
|
end
|
data/spec/models/user_spec.rb
CHANGED
@@ -31,7 +31,7 @@ describe User do
|
|
31
31
|
allow(Rails.cache).to receive(:read).with("users:#{user.masquerade_key}:masquerade") { user.id }
|
32
32
|
allow(Rails.cache).to receive(:delete).with("users:#{user.masquerade_key}:masquerade")
|
33
33
|
|
34
|
-
new_user = User.find_by_masquerade_key(user.masquerade_key)
|
34
|
+
new_user = User.find_by_masquerade_key(user.masquerade_key).first
|
35
35
|
|
36
36
|
expect(new_user).to eq(user)
|
37
37
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: devise_masquerade
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alexandr Korsak
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-10-
|
11
|
+
date: 2019-10-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|