mr_mime 0.0.2
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 +7 -0
- data/app/assets/stylesheets/mr_mime/_mr_mime.css +16 -0
- data/app/controllers/mr_mime/application_controller.rb +5 -0
- data/app/controllers/mr_mime/impersonation_behavior.rb +20 -0
- data/app/controllers/mr_mime/impersonations_controller.rb +49 -0
- data/app/helpers/mr_mime/impersonation_helper.rb +7 -0
- data/app/models/mr_mime/adapters/base.rb +13 -0
- data/app/models/mr_mime/adapters/devise_adapter.rb +10 -0
- data/app/models/mr_mime/adapters/sorcery_adapter.rb +9 -0
- data/app/models/mr_mime/impersonation.rb +85 -0
- data/app/models/mr_mime/impersonation_policy.rb +22 -0
- data/app/models/mr_mime/store.rb +17 -0
- data/app/views/mr_mime/_impersonate_button.html.erb +11 -0
- data/app/views/mr_mime/_impersonation_warning.html.erb +6 -0
- data/config/routes.rb +3 -0
- data/lib/generators/mr_mime/install_generator.rb +16 -0
- data/lib/generators/templates/mr_mime.rb +15 -0
- data/lib/mr_mime/config.rb +27 -0
- data/lib/mr_mime/engine.rb +11 -0
- data/lib/mr_mime/version.rb +1 -0
- data/lib/mr_mime.rb +9 -0
- data/spec/controllers/mr_mime/impersonation_behavior_spec.rb +73 -0
- data/spec/models/mr_mime/impersonation_policy_spec.rb +26 -0
- data/spec/models/mr_mime/impersonation_spec.rb +151 -0
- data/spec/models/mr_mime/store_spec.rb +33 -0
- data/spec/spec_helper.rb +2 -0
- metadata +117 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: f3e2047a91eb58ca1d3f799031c3649fc8e4add6
|
4
|
+
data.tar.gz: b08268e26e4b204ac74b67d8aea4d7efec4b4482
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 3cdf3560ca2b5b0fcf659633cfeefbcb0c5fad2cde0020eb2ee34a38ebaaaf01881a62d7be38d3ba5ac94ca7fad4b54b51ccafdbb055e51e255bbcf4f7a90906
|
7
|
+
data.tar.gz: 7da15de7885351774d7230e7580045783a21de7dc989dc1a07597d6e1e160b57264cac6fd9d0827d7a4e95284278bc3d295cc75d2015c6522ea5c830777abef0
|
@@ -0,0 +1,16 @@
|
|
1
|
+
.mr-mime-impersonation-footer {
|
2
|
+
padding-top: 25px;
|
3
|
+
font-size: 20px;
|
4
|
+
position: fixed;
|
5
|
+
height: 75px;
|
6
|
+
bottom: 0px;
|
7
|
+
background-color: #fbefd9;
|
8
|
+
width: 100%;
|
9
|
+
z-index: 10;
|
10
|
+
text-align: center;
|
11
|
+
border-top: 3px solid #4a4a4a;
|
12
|
+
}
|
13
|
+
|
14
|
+
.mr-mime-new-impersonation {
|
15
|
+
display: inline-block;
|
16
|
+
}
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module MrMime
|
2
|
+
module ImpersonationBehavior
|
3
|
+
def self.included(base)
|
4
|
+
base.helper_method :current_impersonator, :impersonator?, :impersonator_id
|
5
|
+
base.helper MrMime::ImpersonationHelper
|
6
|
+
end
|
7
|
+
|
8
|
+
def current_impersonator
|
9
|
+
MrMime::Config.user_class.find_by(id: impersonator_id) if impersonator?
|
10
|
+
end
|
11
|
+
|
12
|
+
def impersonator?
|
13
|
+
impersonator_id.present?
|
14
|
+
end
|
15
|
+
|
16
|
+
def impersonator_id
|
17
|
+
session['mr_mime.impersonator_id']
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module MrMime
|
2
|
+
class ImpersonationsController < MrMime::ApplicationController
|
3
|
+
before_filter :require_login
|
4
|
+
|
5
|
+
def create
|
6
|
+
if impersonation.save
|
7
|
+
redirect_to main_app.root_url, notice: 'Impersonation started'
|
8
|
+
else
|
9
|
+
redirect_to :back, flash: { error: impersonation.error_messages }
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def destroy
|
14
|
+
impersonation.revert
|
15
|
+
|
16
|
+
redirect_to impersonation.return_to, notice: 'Impersonation ended'
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def impersonation
|
22
|
+
@impersonation ||= MrMime::Impersonation.new(
|
23
|
+
context: self,
|
24
|
+
store: session,
|
25
|
+
params: impersonation_params
|
26
|
+
)
|
27
|
+
end
|
28
|
+
|
29
|
+
def impersonation_params
|
30
|
+
params.fetch(:impersonation, {})
|
31
|
+
.merge(
|
32
|
+
impersonator_id: impersonator.id,
|
33
|
+
referer: request.referer
|
34
|
+
)
|
35
|
+
end
|
36
|
+
|
37
|
+
def impersonator
|
38
|
+
current_impersonator || current_user
|
39
|
+
end
|
40
|
+
|
41
|
+
def require_login
|
42
|
+
unless current_user
|
43
|
+
redirect_to main_app.root_url, flash: {
|
44
|
+
error: 'You do not have permission to do this'
|
45
|
+
}
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
require 'active_model'
|
2
|
+
|
3
|
+
module MrMime
|
4
|
+
class Impersonation
|
5
|
+
extend ActiveModel::Naming
|
6
|
+
include ActiveModel::Validations
|
7
|
+
include ActiveModel::Conversion
|
8
|
+
|
9
|
+
validates :impersonator, :impersonated, presence: true
|
10
|
+
validate :impersonation_allowed
|
11
|
+
|
12
|
+
delegate :user_class, :adapter_class, to: MrMime::Config
|
13
|
+
delegate :set_current_user, to: :adapter
|
14
|
+
|
15
|
+
attr_reader :return_to
|
16
|
+
|
17
|
+
def initialize(options = {})
|
18
|
+
@adapter = adapter_class.new(options.fetch(:context))
|
19
|
+
@store = MrMime::Store.new(options[:store] || {})
|
20
|
+
@params = options[:params] || {}
|
21
|
+
@return_to = store.get(:return_to)
|
22
|
+
end
|
23
|
+
|
24
|
+
def save
|
25
|
+
if valid?
|
26
|
+
set_user_keys
|
27
|
+
true
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def revert
|
32
|
+
revert_user_keys
|
33
|
+
end
|
34
|
+
|
35
|
+
def impersonator
|
36
|
+
@impersonator ||= find_user(params[:impersonator_id])
|
37
|
+
end
|
38
|
+
|
39
|
+
def impersonated
|
40
|
+
@impersonated ||= find_user(params[:impersonated_id])
|
41
|
+
end
|
42
|
+
|
43
|
+
def error_messages
|
44
|
+
errors.full_messages.join(', ')
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
attr_reader :adapter, :store, :params
|
50
|
+
|
51
|
+
def set_user_keys
|
52
|
+
set_current_user impersonated
|
53
|
+
store.set_keys(
|
54
|
+
impersonator_id: impersonator.id,
|
55
|
+
return_to: params[:referer]
|
56
|
+
)
|
57
|
+
end
|
58
|
+
|
59
|
+
def revert_user_keys
|
60
|
+
set_current_user impersonator
|
61
|
+
store.set_keys(
|
62
|
+
impersonator_id: nil,
|
63
|
+
return_to: nil
|
64
|
+
)
|
65
|
+
end
|
66
|
+
|
67
|
+
def impersonation_allowed
|
68
|
+
unless impersonation_allowed?
|
69
|
+
errors.add(:base, 'You do not have permission to impersonate this user')
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def impersonation_allowed?
|
74
|
+
MrMime::ImpersonationPolicy.allowed?(impersonator, impersonated)
|
75
|
+
end
|
76
|
+
|
77
|
+
def find_user(id)
|
78
|
+
user_class.find_by(id: id)
|
79
|
+
end
|
80
|
+
|
81
|
+
def persisted?
|
82
|
+
false
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module MrMime
|
2
|
+
class ImpersonationPolicy
|
3
|
+
delegate :user_permission_check, to: MrMime::Config
|
4
|
+
|
5
|
+
attr_reader :impersonator, :impersonated
|
6
|
+
|
7
|
+
def self.allowed?(*args)
|
8
|
+
new(*args).allowed?
|
9
|
+
end
|
10
|
+
|
11
|
+
def initialize(impersonator, impersonated)
|
12
|
+
@impersonator = impersonator
|
13
|
+
@impersonated = impersonated
|
14
|
+
end
|
15
|
+
|
16
|
+
def allowed?
|
17
|
+
return true unless user_permission_check
|
18
|
+
|
19
|
+
impersonator.public_send(user_permission_check)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module MrMime
|
2
|
+
class Store < SimpleDelegator
|
3
|
+
PREFIX = 'mr_mime'
|
4
|
+
|
5
|
+
def set_keys(values = {})
|
6
|
+
values.each{ |k,v| set(k, v) }
|
7
|
+
end
|
8
|
+
|
9
|
+
def set(key, value)
|
10
|
+
self["#{PREFIX}.#{key}"] = value
|
11
|
+
end
|
12
|
+
|
13
|
+
def get(key)
|
14
|
+
self["#{PREFIX}.#{key}"]
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
<%=
|
2
|
+
button_to mr_mime.impersonation_url, {
|
3
|
+
class: local_assigns[:button_class],
|
4
|
+
form_class: 'mr-mime-new-impersonation',
|
5
|
+
params: {
|
6
|
+
impersonation: { impersonated_id: user_id }
|
7
|
+
}
|
8
|
+
} do
|
9
|
+
local_assigns[:button_text] || 'Impersonate User'
|
10
|
+
end
|
11
|
+
%>
|
@@ -0,0 +1,6 @@
|
|
1
|
+
<% if impersonator? %>
|
2
|
+
<div class='mr-mime-impersonation-footer'>
|
3
|
+
You are impersonating <strong><%= current_user.email %></strong>. At any time you may
|
4
|
+
<%= link_to 'return to your regular account', mr_mime.impersonation_path, method: :delete %>.
|
5
|
+
</div>
|
6
|
+
<% end %>
|
data/config/routes.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'rails/generators/base'
|
2
|
+
require 'securerandom'
|
3
|
+
|
4
|
+
module MrMime
|
5
|
+
module Generators
|
6
|
+
class InstallGenerator < Rails::Generators::Base
|
7
|
+
source_root File.expand_path('../../templates', __FILE__)
|
8
|
+
|
9
|
+
desc 'Creates a MrMime initializer'
|
10
|
+
|
11
|
+
def copy_initializer
|
12
|
+
template 'mr_mime.rb', 'config/initializers/mr_mime.rb'
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
MrMime.configure do |config|
|
2
|
+
# Configure your user authentication adapter.
|
3
|
+
# Supported adapters are :devise, :sorcery
|
4
|
+
config.adapter = :devise
|
5
|
+
|
6
|
+
# Configure the name of the user model used for authentication.
|
7
|
+
config.user_model = 'User'
|
8
|
+
|
9
|
+
# Configure the user method used for impersonation permission checks.
|
10
|
+
# Your configured user model must respond to this method
|
11
|
+
# If the method returns falsey, the user will not be permitted to impersonate
|
12
|
+
# If the method returns truthy, the user will be permitted to impersonate
|
13
|
+
# Default: nil
|
14
|
+
# config.user_permission_check = :admin?
|
15
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module MrMime
|
2
|
+
module Config
|
3
|
+
mattr_accessor :adapter
|
4
|
+
@@adapter = :devise
|
5
|
+
|
6
|
+
mattr_accessor :user_model
|
7
|
+
@@user_model = 'User'
|
8
|
+
|
9
|
+
mattr_accessor :user_permission_check
|
10
|
+
@@user_permission_check = nil
|
11
|
+
|
12
|
+
def self.adapters
|
13
|
+
{
|
14
|
+
sorcery: MrMime::Adapters::SorceryAdapter,
|
15
|
+
devise: MrMime::Adapters::DeviseAdapter
|
16
|
+
}
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.adapter_class
|
20
|
+
@@adapter_class ||= adapters[@@adapter]
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.user_class
|
24
|
+
@@user_class ||= user_model.constantize
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
VERSION = '0.0.1'
|
data/lib/mr_mime.rb
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'helpers/mr_mime/impersonation_helper'
|
3
|
+
require 'controllers/mr_mime/impersonation_behavior'
|
4
|
+
|
5
|
+
module MrMime
|
6
|
+
class DummyController < ActionController::Base
|
7
|
+
include ImpersonationBehavior
|
8
|
+
end
|
9
|
+
|
10
|
+
RSpec.describe DummyController do
|
11
|
+
let(:controller) { described_class.new }
|
12
|
+
|
13
|
+
before { allow(controller).to receive(:session).and_return({}) }
|
14
|
+
|
15
|
+
describe 'helpers' do
|
16
|
+
it 'correctly includes all relevant helper methods' do
|
17
|
+
expect(described_class.helpers.methods).to include(
|
18
|
+
:current_impersonator,
|
19
|
+
:impersonator?,
|
20
|
+
:impersonator_id,
|
21
|
+
:button_to_impersonate
|
22
|
+
)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe '#current_impersonator' do
|
27
|
+
it 'returns nil if there is no impersonator' do
|
28
|
+
expect(controller.current_impersonator).to be_nil
|
29
|
+
end
|
30
|
+
|
31
|
+
context 'with impersonator' do
|
32
|
+
let(:user_class) { double }
|
33
|
+
|
34
|
+
before do
|
35
|
+
allow(MrMime::Config).to receive(:user_class).and_return(user_class)
|
36
|
+
set_impersonator 21
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'returns nil if the impersonating user cannot be found' do
|
40
|
+
find_user nil
|
41
|
+
expect(controller.current_impersonator).to be_nil
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'returns the impersonating user if present' do
|
45
|
+
user = double
|
46
|
+
find_user user
|
47
|
+
expect(controller.current_impersonator).to eq user
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
describe '#impersonator?' do
|
53
|
+
it 'returns true if an impersonator id exists' do
|
54
|
+
set_impersonator 21
|
55
|
+
expect(controller).to be_impersonator
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'returns false otherwise' do
|
59
|
+
expect(controller).not_to be_impersonator
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def set_impersonator(id)
|
64
|
+
controller.session['mr_mime.impersonator_id'] = id
|
65
|
+
end
|
66
|
+
|
67
|
+
def find_user(return_value)
|
68
|
+
allow(user_class).to receive(:find_by)
|
69
|
+
.with(id: 21)
|
70
|
+
.and_return(return_value)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'models/mr_mime/impersonation_policy'
|
3
|
+
|
4
|
+
module MrMime
|
5
|
+
RSpec.describe ImpersonationPolicy, type: :model do
|
6
|
+
describe '#allow?' do
|
7
|
+
it 'returns true if no permission check is set' do
|
8
|
+
expect(described_class.new(double, double)).to be_allowed
|
9
|
+
end
|
10
|
+
|
11
|
+
context 'with permission check' do
|
12
|
+
before { MrMime::Config.user_permission_check = :check? }
|
13
|
+
|
14
|
+
it 'allows admins to impersonate any user' do
|
15
|
+
impersonator = double(check?: true)
|
16
|
+
expect(described_class.new(impersonator, double)).to be_allowed
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'does not allow a regular user to impersonate' do
|
20
|
+
impersonator = double(check?: false)
|
21
|
+
expect(described_class.new(impersonator, double)).not_to be_allowed
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,151 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'models/mr_mime/store'
|
3
|
+
require 'models/mr_mime/impersonation_policy'
|
4
|
+
require 'models/mr_mime/impersonation'
|
5
|
+
|
6
|
+
module MrMime
|
7
|
+
RSpec.describe Impersonation, type: :model do
|
8
|
+
class UserClass; end
|
9
|
+
class AdapterClass; end
|
10
|
+
|
11
|
+
let(:context) { double }
|
12
|
+
let(:adapter) { double(set_current_user: true) }
|
13
|
+
let(:impersonator) { double(id: 3, email: 'impersonator@example.com') }
|
14
|
+
let(:impersonated) { double(id: 8, email: 'impersonated@example.com') }
|
15
|
+
let(:impersonation) do
|
16
|
+
described_class.new(
|
17
|
+
context: context,
|
18
|
+
store: store,
|
19
|
+
params: params
|
20
|
+
)
|
21
|
+
end
|
22
|
+
|
23
|
+
before do
|
24
|
+
stub_config
|
25
|
+
stub_adapter
|
26
|
+
stub_users
|
27
|
+
end
|
28
|
+
|
29
|
+
describe '#save' do
|
30
|
+
let(:store) { {} }
|
31
|
+
let(:params) do
|
32
|
+
{
|
33
|
+
impersonator_id: impersonator.id,
|
34
|
+
impersonated_id: impersonated.id,
|
35
|
+
referer: 'www.example.com/origin'
|
36
|
+
}
|
37
|
+
end
|
38
|
+
|
39
|
+
context 'with a valid impersonation' do
|
40
|
+
before { stub_policy(true) }
|
41
|
+
|
42
|
+
it 'returns true' do
|
43
|
+
expect(impersonation.save).to be_truthy
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'sets the current user' do
|
47
|
+
expect(adapter).to receive(:set_current_user).with(impersonated)
|
48
|
+
impersonation.save
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'sets the impersonator_id in the store' do
|
52
|
+
impersonation.save
|
53
|
+
expect_store_value :impersonator_id, impersonator.id
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'sets the return_to in the store' do
|
57
|
+
impersonation.save
|
58
|
+
expect_store_value :return_to, 'www.example.com/origin'
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
context 'with an invalid impersonation' do
|
63
|
+
before { stub_policy(false) }
|
64
|
+
|
65
|
+
it 'returns false' do
|
66
|
+
expect(impersonation.save).to be_falsey
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'does not set the current user' do
|
70
|
+
expect(adapter).to_not receive(:set_current_user)
|
71
|
+
impersonation.save
|
72
|
+
end
|
73
|
+
|
74
|
+
it 'does not set the impersonator_id' do
|
75
|
+
impersonation.save
|
76
|
+
expect_store_value :impersonator_id, nil
|
77
|
+
end
|
78
|
+
|
79
|
+
it 'does not set the return_to' do
|
80
|
+
impersonation.save
|
81
|
+
expect_store_value :return_to, nil
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
describe '#revert' do
|
87
|
+
let(:store) do
|
88
|
+
{
|
89
|
+
'mr_mime.impersonator_id' => impersonator.id,
|
90
|
+
'mr_mime.return_to' => 'www.example.com/origin'
|
91
|
+
}
|
92
|
+
end
|
93
|
+
let(:params) do
|
94
|
+
{
|
95
|
+
impersonator_id: impersonator.id,
|
96
|
+
referer: 'www.example.com/new'
|
97
|
+
}
|
98
|
+
end
|
99
|
+
|
100
|
+
it 'reverts the current user' do
|
101
|
+
expect(adapter).to receive(:set_current_user).with(impersonator)
|
102
|
+
impersonation.revert
|
103
|
+
end
|
104
|
+
|
105
|
+
it 'clears the impersonator_id' do
|
106
|
+
impersonation.revert
|
107
|
+
expect_store_value :impersonator_id, nil
|
108
|
+
end
|
109
|
+
|
110
|
+
it 'clears the return_to' do
|
111
|
+
impersonation.revert
|
112
|
+
expect_store_value :return_to, nil
|
113
|
+
end
|
114
|
+
|
115
|
+
it 'retains the correct return_to' do
|
116
|
+
impersonation.revert
|
117
|
+
expect(impersonation.return_to).to eq 'www.example.com/origin'
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
def expect_store_value(key, value)
|
122
|
+
expect(store["mr_mime.#{key}"]).to eq value
|
123
|
+
end
|
124
|
+
|
125
|
+
def stub_config
|
126
|
+
allow(MrMime::Config).to receive_messages(
|
127
|
+
user_class: UserClass,
|
128
|
+
adapter_class: AdapterClass
|
129
|
+
)
|
130
|
+
end
|
131
|
+
|
132
|
+
def stub_adapter
|
133
|
+
allow(AdapterClass).to receive(:new).with(context).and_return(adapter)
|
134
|
+
end
|
135
|
+
|
136
|
+
def stub_users
|
137
|
+
allow(UserClass).to receive(:find_by) do |options|
|
138
|
+
if options[:id] == impersonator.id then impersonator
|
139
|
+
elsif options[:id] == impersonated.id then impersonated
|
140
|
+
else nil
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
def stub_policy(allowed)
|
146
|
+
allow(MrMime::ImpersonationPolicy).to receive(:allowed?)
|
147
|
+
.with(impersonator, impersonated)
|
148
|
+
.and_return(allowed)
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'models/mr_mime/store'
|
3
|
+
|
4
|
+
module MrMime
|
5
|
+
RSpec.describe Store do
|
6
|
+
let(:store) { described_class.new({}) }
|
7
|
+
|
8
|
+
before { stub_const("#{described_class}::PREFIX", 'prefix')}
|
9
|
+
|
10
|
+
describe '#set_keys' do
|
11
|
+
it 'correctly stores all prefixed key-value pairs' do
|
12
|
+
store.set_keys(one: 1, two: 2)
|
13
|
+
|
14
|
+
expect(store['prefix.one']).to eq 1
|
15
|
+
expect(store['prefix.two']).to eq 2
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe '#set' do
|
20
|
+
it 'correctly stores a prefixed key-value pair' do
|
21
|
+
store.set(:one, 1)
|
22
|
+
expect(store['prefix.one']).to eq 1
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe '#get' do
|
27
|
+
it 'correctly retrieves a prefixed key-value pair' do
|
28
|
+
store.set(:one, 1)
|
29
|
+
expect(store.get(:one)).to eq 1
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,117 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: mr_mime
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Kyle Edson
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-04-12 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rails
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '4.0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '4.0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: bundler
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.11'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.11'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '3.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '3.0'
|
55
|
+
description: |-
|
56
|
+
MrMime is a Rails engine built to easily add user
|
57
|
+
impersonation functionality to your existing Rails application
|
58
|
+
email: rubygems@foraker.com
|
59
|
+
executables: []
|
60
|
+
extensions: []
|
61
|
+
extra_rdoc_files: []
|
62
|
+
files:
|
63
|
+
- app/assets/stylesheets/mr_mime/_mr_mime.css
|
64
|
+
- app/controllers/mr_mime/application_controller.rb
|
65
|
+
- app/controllers/mr_mime/impersonation_behavior.rb
|
66
|
+
- app/controllers/mr_mime/impersonations_controller.rb
|
67
|
+
- app/helpers/mr_mime/impersonation_helper.rb
|
68
|
+
- app/models/mr_mime/adapters/base.rb
|
69
|
+
- app/models/mr_mime/adapters/devise_adapter.rb
|
70
|
+
- app/models/mr_mime/adapters/sorcery_adapter.rb
|
71
|
+
- app/models/mr_mime/impersonation.rb
|
72
|
+
- app/models/mr_mime/impersonation_policy.rb
|
73
|
+
- app/models/mr_mime/store.rb
|
74
|
+
- app/views/mr_mime/_impersonate_button.html.erb
|
75
|
+
- app/views/mr_mime/_impersonation_warning.html.erb
|
76
|
+
- config/routes.rb
|
77
|
+
- lib/generators/mr_mime/install_generator.rb
|
78
|
+
- lib/generators/templates/mr_mime.rb
|
79
|
+
- lib/mr_mime.rb
|
80
|
+
- lib/mr_mime/config.rb
|
81
|
+
- lib/mr_mime/engine.rb
|
82
|
+
- lib/mr_mime/version.rb
|
83
|
+
- spec/controllers/mr_mime/impersonation_behavior_spec.rb
|
84
|
+
- spec/models/mr_mime/impersonation_policy_spec.rb
|
85
|
+
- spec/models/mr_mime/impersonation_spec.rb
|
86
|
+
- spec/models/mr_mime/store_spec.rb
|
87
|
+
- spec/spec_helper.rb
|
88
|
+
homepage: http://www.github.com/foraker/mr_mime
|
89
|
+
licenses:
|
90
|
+
- MIT
|
91
|
+
metadata: {}
|
92
|
+
post_install_message:
|
93
|
+
rdoc_options: []
|
94
|
+
require_paths:
|
95
|
+
- lib
|
96
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
97
|
+
requirements:
|
98
|
+
- - ">="
|
99
|
+
- !ruby/object:Gem::Version
|
100
|
+
version: '0'
|
101
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
102
|
+
requirements:
|
103
|
+
- - ">="
|
104
|
+
- !ruby/object:Gem::Version
|
105
|
+
version: '0'
|
106
|
+
requirements: []
|
107
|
+
rubyforge_project:
|
108
|
+
rubygems_version: 2.4.5.1
|
109
|
+
signing_key:
|
110
|
+
specification_version: 4
|
111
|
+
summary: User impersonation for Rails applications
|
112
|
+
test_files:
|
113
|
+
- spec/controllers/mr_mime/impersonation_behavior_spec.rb
|
114
|
+
- spec/models/mr_mime/impersonation_policy_spec.rb
|
115
|
+
- spec/models/mr_mime/impersonation_spec.rb
|
116
|
+
- spec/models/mr_mime/store_spec.rb
|
117
|
+
- spec/spec_helper.rb
|