mr_mime 0.0.2 → 0.0.3

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 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