mr_mime 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f3e2047a91eb58ca1d3f799031c3649fc8e4add6
4
- data.tar.gz: b08268e26e4b204ac74b67d8aea4d7efec4b4482
3
+ metadata.gz: 46b3168826cd9ed3532de109b2b15953cf8430b8
4
+ data.tar.gz: 123556f6e10c5e994ee771417e5b74120ee8c7b7
5
5
  SHA512:
6
- metadata.gz: 3cdf3560ca2b5b0fcf659633cfeefbcb0c5fad2cde0020eb2ee34a38ebaaaf01881a62d7be38d3ba5ac94ca7fad4b54b51ccafdbb055e51e255bbcf4f7a90906
7
- data.tar.gz: 7da15de7885351774d7230e7580045783a21de7dc989dc1a07597d6e1e160b57264cac6fd9d0827d7a4e95284278bc3d295cc75d2015c6522ea5c830777abef0
6
+ metadata.gz: a7312bcd3eadb43e4b859bbf86a9cf6ec583d0908a0f0cbafdcc3450405e84fb82d99ec953fd81a21abb992bd46923a23f325518eea67d8e8c739d6bfb6e2e57
7
+ data.tar.gz: 65433e6d3fce5b555565e24889aff8d014392c69b7d4533c49fc47bc8e0d4515527ed14f503f0bfb2ab0fba7f026d47cf03f1cb9e7d9318567c011453ea18a35
@@ -1,10 +1,10 @@
1
1
  module MrMime
2
2
  class ImpersonationsController < MrMime::ApplicationController
3
- before_filter :require_login
3
+ before_action :require_login
4
4
 
5
5
  def create
6
6
  if impersonation.save
7
- redirect_to main_app.root_url, notice: 'Impersonation started'
7
+ redirect_to after_impersonation_url, notice: 'Impersonation started'
8
8
  else
9
9
  redirect_to :back, flash: { error: impersonation.error_messages }
10
10
  end
@@ -13,7 +13,7 @@ module MrMime
13
13
  def destroy
14
14
  impersonation.revert
15
15
 
16
- redirect_to impersonation.return_to, notice: 'Impersonation ended'
16
+ redirect_to return_to_url, notice: 'Impersonation ended'
17
17
  end
18
18
 
19
19
  private
@@ -45,5 +45,18 @@ module MrMime
45
45
  }
46
46
  end
47
47
  end
48
+
49
+ def after_impersonation_url
50
+ MrMime::UrlResolver.resolve(
51
+ MrMime::Config.after_impersonation_url,
52
+ context: self,
53
+ args: current_user,
54
+ default: main_app.root_url
55
+ )
56
+ end
57
+
58
+ def return_to_url
59
+ impersonation.return_to || main_app.root_url
60
+ end
48
61
  end
49
62
  end
@@ -3,5 +3,9 @@ module MrMime
3
3
  def button_to_impersonate(user_id, options = {})
4
4
  render 'mr_mime/impersonate_button', options.merge(user_id: user_id)
5
5
  end
6
+
7
+ def impersonated_email
8
+ current_user.try(:email)
9
+ end
6
10
  end
7
11
  end
@@ -1,9 +1,11 @@
1
1
  module MrMime
2
2
  module Adapters
3
3
  class DeviseAdapter < Base
4
+ delegate :user_class, to: MrMime::Config
5
+
4
6
  def set_current_user(user)
5
7
  context.sign_out
6
- context.sign_in(user)
8
+ context.sign_in user.becomes(user_class)
7
9
  end
8
10
  end
9
11
  end
@@ -0,0 +1,39 @@
1
+ module MrMime
2
+ class UrlResolver
3
+ delegate :main_app, to: :context, allow_nil: true
4
+
5
+ def self.resolve(*args)
6
+ new(*args).resolve
7
+ end
8
+
9
+ def initialize(url, options = {})
10
+ @url = evaluate(url, *options[:args])
11
+ @context = options[:context]
12
+ @default = options[:default]
13
+ end
14
+
15
+ def resolve
16
+ case
17
+ when method_name? then main_app.send(url)
18
+ when url_name? then url
19
+ else default
20
+ end
21
+ end
22
+
23
+ private
24
+
25
+ attr_reader :url, :context, :default
26
+
27
+ def method_name?
28
+ url.is_a?(Symbol)
29
+ end
30
+
31
+ def url_name?
32
+ url.is_a?(String)
33
+ end
34
+
35
+ def evaluate(url, *args)
36
+ url.is_a?(Proc) ? url.call(*args) : url
37
+ end
38
+ end
39
+ end
@@ -1,6 +1,6 @@
1
1
  <% if impersonator? %>
2
2
  <div class='mr-mime-impersonation-footer'>
3
- You are impersonating <strong><%= current_user.email %></strong>. At any time you may
3
+ You are impersonating <strong><%= impersonated_email %></strong>. At any time you may
4
4
  <%= link_to 'return to your regular account', mr_mime.impersonation_path, method: :delete %>.
5
5
  </div>
6
6
  <% end %>
@@ -12,4 +12,16 @@ MrMime.configure do |config|
12
12
  # If the method returns truthy, the user will be permitted to impersonate
13
13
  # Default: nil
14
14
  # config.user_permission_check = :admin?
15
+
16
+ # Configure the URL that users will be redirected to after beginning impersonation.
17
+ # Accepts the following formats (with examples):
18
+ #
19
+ # -- String: A literal URL string
20
+ # config.after_impersonation_url = '/'
21
+ #
22
+ # -- Proc/Lambda: Must return the desired URL. The impersonated user will be passed in.
23
+ # config.after_impersonation_url = Proc.new { |impersonated| user_url(impersonated) }
24
+ #
25
+ # -- Symbol: The name of a URL helper method within your application
26
+ config.after_impersonation_url = :root_url
15
27
  end
@@ -9,6 +9,9 @@ module MrMime
9
9
  mattr_accessor :user_permission_check
10
10
  @@user_permission_check = nil
11
11
 
12
+ mattr_accessor :after_impersonation_url
13
+ @@after_impersonation_url = :root_url
14
+
12
15
  def self.adapters
13
16
  {
14
17
  sorcery: MrMime::Adapters::SorceryAdapter,
@@ -1 +1 @@
1
- VERSION = '0.0.1'
1
+ VERSION = '0.0.3'
@@ -0,0 +1,173 @@
1
+ require 'spec_helper'
2
+ require 'models/mr_mime/store'
3
+ require 'models/mr_mime/adapters/base'
4
+ require 'models/mr_mime/impersonation_policy'
5
+ require 'models/mr_mime/impersonation'
6
+ require 'models/mr_mime/url_resolver'
7
+ require 'helpers/mr_mime/impersonation_helper'
8
+ require 'controllers/mr_mime/impersonation_behavior'
9
+ require 'controllers/mr_mime/application_controller'
10
+ require 'controllers/mr_mime/impersonations_controller'
11
+
12
+ module MrMime
13
+ class DummyUser; end
14
+ class DummyAdapter < Adapters::Base
15
+ def set_current_user(user)
16
+ context.session[:current_user_id] = user.id
17
+ end
18
+ end
19
+
20
+ RSpec.describe ImpersonationsController, type: :controller do
21
+ let(:main_app) { double(root_url: 'root_url', test_url: 'test') }
22
+ let(:request) { double(referer: 'test_url') }
23
+ let(:session) { { current_user_id: 1 } }
24
+ let(:controller) { described_class.new }
25
+ let(:users) { [double(id: 1), double(id: 2)] }
26
+
27
+ before do
28
+ stub_config
29
+ stub_controller_messages
30
+ end
31
+
32
+ describe '#create' do
33
+ context 'with a valid impersonation' do
34
+ before do
35
+ set_params impersonated_id: 2
36
+ end
37
+
38
+ it 'sets the current user' do
39
+ controller.create
40
+ expect(controller.current_user).to eq users.last
41
+ end
42
+
43
+ it 'sets the impersonator_id in the session' do
44
+ controller.create
45
+ expect(session['mr_mime.impersonator_id']).to eq 1
46
+ end
47
+
48
+ it 'sets the return_to url in the session' do
49
+ controller.create
50
+ expect(session['mr_mime.return_to']).to eq 'test_url'
51
+ end
52
+
53
+ it 'redirects to the root_url if no after_impersonation_url is set' do
54
+ expect(controller).to receive(:redirect_to).with('root_url', anything)
55
+ controller.create
56
+ end
57
+
58
+ it 'redirects to the correct after_impersonation_url if string' do
59
+ MrMime::Config.after_impersonation_url = 'string_url'
60
+ expect(controller).to receive(:redirect_to).with('string_url', anything)
61
+ controller.create
62
+ end
63
+
64
+ it 'redirects to the correct after_impersonation_url if symbol' do
65
+ MrMime::Config.after_impersonation_url = :test_url
66
+ expect(controller).to receive(:redirect_to).with('test', anything)
67
+ controller.create
68
+ end
69
+
70
+ it 'redirects to the correct after_impersonation_url if proc' do
71
+ MrMime::Config.after_impersonation_url = Proc.new { |user| "users/#{user.id}" }
72
+ expect(controller).to receive(:redirect_to).with('users/2', anything)
73
+ controller.create
74
+ end
75
+ end
76
+
77
+ context 'with an invalid impersonation' do
78
+ before do
79
+ set_params impersonated_id: nil
80
+ end
81
+
82
+ it 'does not change the current user' do
83
+ controller.create
84
+ expect(controller.current_user).to eq users.first
85
+ end
86
+
87
+ it 'does not set the impersonator_id' do
88
+ controller.create
89
+ expect(session).to_not have_key('mr_mime.impersonator_id')
90
+ end
91
+
92
+ it 'does not set the return_to url' do
93
+ controller.create
94
+ expect(session).to_not have_key('mr_mime.return_to')
95
+ end
96
+
97
+ it 'redirects back with error messages' do
98
+ expect(controller).to receive(:redirect_to)
99
+ .with(:back, {
100
+ flash: {
101
+ error: "Impersonated can't be blank"
102
+ }
103
+ })
104
+ controller.create
105
+ end
106
+ end
107
+ end
108
+
109
+ describe '#destroy' do
110
+ before { create_impersonation }
111
+
112
+ it 'sets the current user' do
113
+ controller.destroy
114
+ expect(controller.current_user).to eq users.first
115
+ end
116
+
117
+ it 'clears the impersonator_id in the session' do
118
+ controller.destroy
119
+ expect(session['mr_mime.impersonator_id']).to be_blank
120
+ end
121
+
122
+ it 'clears the return_to url in the session' do
123
+ controller.destroy
124
+ expect(session['mr_mime.return_to']).to be_blank
125
+ end
126
+
127
+ it 'redirects to the return_to url' do
128
+ expect(controller).to receive(:redirect_to).with('test_path', anything)
129
+ controller.destroy
130
+ end
131
+ end
132
+
133
+ def stub_config
134
+ allow(DummyUser).to receive(:find_by) { |options| find_user(options) }
135
+ allow(MrMime::Config).to receive_messages(
136
+ user_class: DummyUser,
137
+ adapter_class: DummyAdapter
138
+ )
139
+ end
140
+
141
+ def stub_controller_messages
142
+ allow(controller).to receive(:current_user) do
143
+ find_user(id: session[:current_user_id])
144
+ end
145
+
146
+ allow(controller).to receive_messages(
147
+ main_app: main_app,
148
+ request: request,
149
+ session: session,
150
+ redirect_to: nil
151
+ )
152
+ end
153
+
154
+ def create_impersonation
155
+ set_params
156
+ session.merge!(
157
+ current_user_id: 2,
158
+ 'mr_mime.impersonator_id' => 1,
159
+ 'mr_mime.return_to' => 'test_path'
160
+ )
161
+ end
162
+
163
+ def set_params(params = {})
164
+ allow(controller).to receive_message_chain(:params, :fetch)
165
+ .with(:impersonation, {})
166
+ .and_return(params)
167
+ end
168
+
169
+ def find_user(id: id)
170
+ users.detect{ |user| user.id == id }
171
+ end
172
+ end
173
+ end
@@ -0,0 +1,49 @@
1
+ require 'spec_helper'
2
+ require 'models/mr_mime/url_resolver'
3
+
4
+ module MrMime
5
+ RSpec.describe UrlResolver, type: :model do
6
+ let(:main_app) { double(url_method: '/method_url', foo: '/proc_url/bar') }
7
+ let(:model) { double(name: 'foo') }
8
+
9
+ describe '.resolve' do
10
+ it 'returns the correct url for a method proc' do
11
+ expect_url '/proc_url/bar', from: url_method_proc
12
+ end
13
+
14
+ it 'returns the correct url for a string proc' do
15
+ expect_url '/proc_url/foo', from: url_string_proc
16
+ end
17
+
18
+ it 'returns the correct url for a method name' do
19
+ expect_url '/method_url', from: :url_method
20
+ end
21
+
22
+ it 'returns the correct url for a url string' do
23
+ expect_url '/url_string', from: '/url_string'
24
+ end
25
+
26
+ it 'returns the default url if the given url does not resolve' do
27
+ expect_url '/default_url', from: double
28
+ end
29
+ end
30
+
31
+ def expect_url(url, options = {})
32
+ expect(
33
+ described_class.resolve(options[:from],
34
+ context: double(main_app: main_app),
35
+ args: model,
36
+ default: '/default_url'
37
+ )
38
+ ).to eq url
39
+ end
40
+
41
+ def url_method_proc
42
+ Proc.new { |model| model.name.to_sym }
43
+ end
44
+
45
+ def url_string_proc
46
+ Proc.new { |model| "/proc_url/#{model.name}" }
47
+ end
48
+ end
49
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mr_mime
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kyle Edson
@@ -71,6 +71,7 @@ files:
71
71
  - app/models/mr_mime/impersonation.rb
72
72
  - app/models/mr_mime/impersonation_policy.rb
73
73
  - app/models/mr_mime/store.rb
74
+ - app/models/mr_mime/url_resolver.rb
74
75
  - app/views/mr_mime/_impersonate_button.html.erb
75
76
  - app/views/mr_mime/_impersonation_warning.html.erb
76
77
  - config/routes.rb
@@ -81,9 +82,11 @@ files:
81
82
  - lib/mr_mime/engine.rb
82
83
  - lib/mr_mime/version.rb
83
84
  - spec/controllers/mr_mime/impersonation_behavior_spec.rb
85
+ - spec/controllers/mr_mime/impersonations_controller_spec.rb
84
86
  - spec/models/mr_mime/impersonation_policy_spec.rb
85
87
  - spec/models/mr_mime/impersonation_spec.rb
86
88
  - spec/models/mr_mime/store_spec.rb
89
+ - spec/models/mr_mime/url_resolver_spec.rb
87
90
  - spec/spec_helper.rb
88
91
  homepage: http://www.github.com/foraker/mr_mime
89
92
  licenses:
@@ -105,13 +108,15 @@ required_rubygems_version: !ruby/object:Gem::Requirement
105
108
  version: '0'
106
109
  requirements: []
107
110
  rubyforge_project:
108
- rubygems_version: 2.4.5.1
111
+ rubygems_version: 2.6.10
109
112
  signing_key:
110
113
  specification_version: 4
111
114
  summary: User impersonation for Rails applications
112
115
  test_files:
113
116
  - spec/controllers/mr_mime/impersonation_behavior_spec.rb
117
+ - spec/controllers/mr_mime/impersonations_controller_spec.rb
114
118
  - spec/models/mr_mime/impersonation_policy_spec.rb
115
119
  - spec/models/mr_mime/impersonation_spec.rb
116
120
  - spec/models/mr_mime/store_spec.rb
121
+ - spec/models/mr_mime/url_resolver_spec.rb
117
122
  - spec/spec_helper.rb