pretender 0.3.1 → 0.4.0

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
- SHA1:
3
- metadata.gz: fc80b6979512a9246224aa4d68f4dbda8b0c70f8
4
- data.tar.gz: 71aadf8f167f0f0350f0c0c3b89743753fe8ef78
2
+ SHA256:
3
+ metadata.gz: bfd83e017e14b15a69e02ffe5d25c6be57657f06d84b30fa276fedd61efb6d07
4
+ data.tar.gz: 55d4d73eb2ab7fa9fe87ba5be1b3da4e6264de02b845cb579612c9e8ae549ae2
5
5
  SHA512:
6
- metadata.gz: c6e774897e0fc2b2b7a4bb2044ce22c6ea32d6263d20cf9ab441dc5a7d83dc6b218fcce333b661076a06c669047ec951671aa9c47f0bdf30c6b833465e60e080
7
- data.tar.gz: 503223df0e48c6afce6e0d830a28ffac72bf55965e0db6ac7d4c8a439ef422a46bad0bbce06a6cfaae560a540c2ded2788f5919c81eec9c3f91dc595f5d94abd
6
+ metadata.gz: 7e7d1306ee4466cf4b9419dbfe71c161d633eb4ded28246252b90404954a57c06597081bbfa1fedfa69effce9cbb3988c2b39043e8abd9db5160b0f652987869
7
+ data.tar.gz: 422366a35f79040ddb0b104f4d3177b637333c590c65124e58bd5934378d13aebcb92987c6c07224ec16d6a5112087c85c2c6401f1517697b0737f66f462b8de
data/CHANGELOG.md CHANGED
@@ -1,17 +1,34 @@
1
- ## 0.3.1
1
+ ## 0.4.0 (2022-01-10)
2
+
3
+ - Dropped support for Ruby < 2.6 and Rails < 5.2
4
+
5
+ ## 0.3.4 (2019-01-31)
6
+
7
+ - Fixed error with Action Cable and eager loading
8
+
9
+ ## 0.3.3 (2018-09-21)
10
+
11
+ - Added support for Action Cable
12
+
13
+ ## 0.3.2 (2018-01-21)
14
+
15
+ - Support for Mongoid `BSON::ObjectId` out of the box
16
+ - Fixed issue with impersonated resource caching
17
+
18
+ ## 0.3.1 (2017-06-18)
2
19
 
3
20
  - Fixed `stack level too deep` error
4
21
 
5
- ## 0.3.0
22
+ ## 0.3.0 (2017-06-11)
6
23
 
7
24
  - Fixed compatibility with Clearance
8
25
  - Added support for Rails API
9
26
  - Added support for custom primary key
10
27
 
11
- ## 0.2.1
28
+ ## 0.2.1 (2016-07-07)
12
29
 
13
30
  - Better error message
14
31
 
15
- ## 0.2.0
32
+ ## 0.2.0 (2016-07-07)
16
33
 
17
34
  - Started changelog
data/LICENSE.txt CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2013 Andrew Kane
1
+ Copyright (c) 2013-2021 Andrew Kane
2
2
 
3
3
  MIT License
4
4
 
data/README.md CHANGED
@@ -1,25 +1,27 @@
1
1
  # Pretender
2
2
 
3
- As an admin, there are times you want to see exactly what another user sees. Meet Pretender.
3
+ As an admin, there are times you want to see exactly what another user sees. Meet Pretender.
4
4
 
5
- - Easily to switch between users
5
+ - Easily switch between users
6
6
  - Minimal code changes
7
- - Plays nicely with auditing tools
7
+ - Plays nicely with Action Cable and auditing tools
8
8
 
9
- :boom: [Rock on](http://www.youtube.com/watch?v=SBjQ9tuuTJQ)
9
+ :boom: [Rock on](https://www.youtube.com/watch?v=SBjQ9tuuTJQ)
10
10
 
11
- Pretender is flexible and lightweight - less than 60 lines of code :-)
11
+ Pretender is flexible and lightweight - less than 100 lines of code :-)
12
12
 
13
- Works with any authentication system - [Devise](https://github.com/plataformatec/devise), [Authlogic](https://github.com/binarylogic/authlogic), and [Sorcery](https://github.com/NoamB/sorcery) to name a few.
13
+ Works with any authentication system - [Devise](https://github.com/plataformatec/devise), [Authlogic](https://github.com/binarylogic/authlogic), and [Sorcery](https://github.com/Sorcery/sorcery) to name a few.
14
14
 
15
15
  :tangerine: Battle-tested at [Instacart](https://www.instacart.com/opensource)
16
16
 
17
+ [![Build Status](https://github.com/ankane/pretender/workflows/build/badge.svg?branch=master)](https://github.com/ankane/pretender/actions)
18
+
17
19
  ## Installation
18
20
 
19
21
  Add this line to your application’s Gemfile:
20
22
 
21
23
  ```ruby
22
- gem 'pretender'
24
+ gem "pretender"
23
25
  ```
24
26
 
25
27
  And add this to your `ApplicationController`:
@@ -58,7 +60,7 @@ Create a controller
58
60
 
59
61
  ```ruby
60
62
  class UsersController < ApplicationController
61
- before_filter :require_admin!
63
+ before_action :require_admin! # your authorization method
62
64
 
63
65
  def index
64
66
  @users = User.order(:id)
@@ -113,14 +115,40 @@ If you keep audit logs with a library like [Audited](https://github.com/collecti
113
115
  Audited.current_user_method = :true_user
114
116
  ```
115
117
 
118
+ ## Action Cable
119
+
120
+ And add this to your `ApplicationCable::Connection`:
121
+
122
+ ```ruby
123
+ module ApplicationCable
124
+ class Connection < ActionCable::Connection::Base
125
+ identified_by :current_user, :true_user
126
+ impersonates :user
127
+
128
+ def connect
129
+ self.current_user = find_verified_user
130
+ reject_unauthorized_connection unless current_user
131
+ end
132
+
133
+ private
134
+
135
+ def find_verified_user
136
+ env["warden"].user # for Devise
137
+ end
138
+ end
139
+ end
140
+ ```
141
+
142
+ The `current_user` method now returns the impersonated user in channels.
143
+
116
144
  ## Configuration
117
145
 
118
- Pretender is super flexible. You can change the names of methods and even impersonate multiple roles at the same time. Here’s the default configuration.
146
+ Pretender is super flexible. You can change the names of methods and even impersonate multiple roles at the same time. Here’s the default configuration.
119
147
 
120
148
  ```ruby
121
149
  impersonates :user,
122
150
  method: :current_user,
123
- with: -> (id) { User.find_by(id: id) }
151
+ with: ->(id) { User.find_by(id: id) }
124
152
  ```
125
153
 
126
154
  Mold it to fit your application.
@@ -128,7 +156,7 @@ Mold it to fit your application.
128
156
  ```ruby
129
157
  impersonates :account,
130
158
  method: :authenticated_account,
131
- with: -> (id) { EnterpriseAccount.find_by(id: id) }
159
+ with: ->(id) { EnterpriseAccount.find_by(id: id) }
132
160
  ```
133
161
 
134
162
  This creates three methods:
@@ -139,6 +167,10 @@ impersonate_account
139
167
  stop_impersonating_account
140
168
  ```
141
169
 
170
+ ## History
171
+
172
+ View the [changelog](https://github.com/ankane/pretender/blob/master/CHANGELOG.md)
173
+
142
174
  ## Contributing
143
175
 
144
176
  Everyone is encouraged to help improve this project. Here are a few ways you can help:
@@ -147,3 +179,12 @@ Everyone is encouraged to help improve this project. Here are a few ways you can
147
179
  - Fix bugs and [submit pull requests](https://github.com/ankane/pretender/pulls)
148
180
  - Write, clarify, or fix documentation
149
181
  - Suggest or add new features
182
+
183
+ To get started with development:
184
+
185
+ ```sh
186
+ git clone https://github.com/ankane/pretender.git
187
+ cd pretender
188
+ bundle install
189
+ bundle exec rake test
190
+ ```
@@ -1,3 +1,3 @@
1
1
  module Pretender
2
- VERSION = "0.3.1"
2
+ VERSION = "0.4.0"
3
3
  end
data/lib/pretender.rb CHANGED
@@ -15,6 +15,7 @@ module Pretender
15
15
  true_method = :"true_#{scope}"
16
16
  session_key = :"impersonated_#{scope}_id"
17
17
  impersonated_var = :"@impersonated_#{scope}"
18
+ stop_impersonating_method = :"stop_impersonating_#{scope}"
18
19
 
19
20
  # define methods
20
21
  if method_defined?(impersonated_method) || private_method_defined?(impersonated_method)
@@ -30,26 +31,39 @@ module Pretender
30
31
  helper_method(true_method) if respond_to?(:helper_method)
31
32
 
32
33
  define_method impersonated_method do
33
- unless instance_variable_get(impersonated_var)
34
- # only fetch impersonation if user is logged in and impersonation_id exists
35
- true_resource = send(true_method)
36
- if session[session_key] && !true_resource
37
- session[session_key] = nil
34
+ impersonated_resource = instance_variable_get(impersonated_var) if instance_variable_defined?(impersonated_var)
35
+
36
+ if !impersonated_resource && request.session[session_key]
37
+ # only fetch impersonation if user is logged in
38
+ # this is a safety check (once per request) so
39
+ # if a user logs out without session being destroyed
40
+ # or stop_impersonating_user being called,
41
+ # we can stop the impersonation
42
+ if send(true_method)
43
+ impersonated_resource = impersonate_with.call(request.session[session_key])
44
+ instance_variable_set(impersonated_var, impersonated_resource) if impersonated_resource
45
+ else
46
+ # TODO better message
47
+ warn "[pretender] Stopping impersonation due to safety check"
48
+ send(stop_impersonating_method)
38
49
  end
39
- value = (session[session_key] && impersonate_with.call(session[session_key])) || true_resource
40
- instance_variable_set(impersonated_var, value) if value
41
50
  end
42
- instance_variable_get(impersonated_var)
51
+
52
+ impersonated_resource || send(true_method)
43
53
  end
44
54
 
45
55
  define_method :"impersonate_#{scope}" do |resource|
56
+ raise ArgumentError, "No resource to impersonate" unless resource
57
+ raise Pretender::Error, "Must be logged in to impersonate" unless send(true_method)
58
+
46
59
  instance_variable_set(impersonated_var, resource)
47
- session[session_key] = resource.id
60
+ # use to_s for Mongoid for BSON::ObjectId
61
+ request.session[session_key] = resource.id.is_a?(Numeric) ? resource.id : resource.id.to_s
48
62
  end
49
63
 
50
- define_method :"stop_impersonating_#{scope}" do
51
- instance_variable_set(impersonated_var, nil)
52
- session[session_key] = nil
64
+ define_method stop_impersonating_method do
65
+ remove_instance_variable(impersonated_var) if instance_variable_defined?(impersonated_var)
66
+ request.session.delete(session_key)
53
67
  end
54
68
  end
55
69
  end
@@ -58,3 +72,6 @@ end
58
72
  ActiveSupport.on_load(:action_controller) do
59
73
  extend Pretender::Methods
60
74
  end
75
+
76
+ # ActiveSupport.on_load(:action_cable) runs too late with Unicorn
77
+ ActionCable::Connection::Base.extend(Pretender::Methods) if defined?(ActionCable)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pretender
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Kane
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-06-18 00:00:00.000000000 Z
11
+ date: 2022-01-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: actionpack
@@ -16,79 +16,30 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '0'
19
+ version: '5.2'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: '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.3'
34
- type: :development
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - "~>"
39
- - !ruby/object:Gem::Version
40
- version: '1.3'
41
- - !ruby/object:Gem::Dependency
42
- name: rake
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - ">="
46
- - !ruby/object:Gem::Version
47
- version: '0'
48
- type: :development
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - ">="
53
- - !ruby/object:Gem::Version
54
- version: '0'
55
- - !ruby/object:Gem::Dependency
56
- name: minitest
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - ">="
60
- - !ruby/object:Gem::Version
61
- version: '0'
62
- type: :development
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - ">="
67
- - !ruby/object:Gem::Version
68
- version: '0'
69
- description: Simple, powerful user impersonation for Rails
70
- email:
71
- - andrew@chartkick.com
26
+ version: '5.2'
27
+ description:
28
+ email: andrew@ankane.org
72
29
  executables: []
73
30
  extensions: []
74
31
  extra_rdoc_files: []
75
32
  files:
76
- - ".gitignore"
77
33
  - CHANGELOG.md
78
- - Gemfile
79
34
  - LICENSE.txt
80
35
  - README.md
81
- - Rakefile
82
36
  - lib/pretender.rb
83
37
  - lib/pretender/version.rb
84
- - pretender.gemspec
85
- - test/pretender_test.rb
86
- - test/test_helper.rb
87
38
  homepage: https://github.com/ankane/pretender
88
39
  licenses:
89
40
  - MIT
90
41
  metadata: {}
91
- post_install_message:
42
+ post_install_message:
92
43
  rdoc_options: []
93
44
  require_paths:
94
45
  - lib
@@ -96,19 +47,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
96
47
  requirements:
97
48
  - - ">="
98
49
  - !ruby/object:Gem::Version
99
- version: '0'
50
+ version: '2.6'
100
51
  required_rubygems_version: !ruby/object:Gem::Requirement
101
52
  requirements:
102
53
  - - ">="
103
54
  - !ruby/object:Gem::Version
104
55
  version: '0'
105
56
  requirements: []
106
- rubyforge_project:
107
- rubygems_version: 2.6.11
108
- signing_key:
57
+ rubygems_version: 3.3.3
58
+ signing_key:
109
59
  specification_version: 4
110
- summary: Easy to switch back and forth between roles, minimal code changes, and plays
111
- nicely with auditing tools
112
- test_files:
113
- - test/pretender_test.rb
114
- - test/test_helper.rb
60
+ summary: Log in as another user in Rails
61
+ test_files: []
data/.gitignore DELETED
@@ -1,17 +0,0 @@
1
- *.gem
2
- *.rbc
3
- .bundle
4
- .config
5
- .yardoc
6
- Gemfile.lock
7
- InstalledFiles
8
- _yardoc
9
- coverage
10
- doc/
11
- lib/bundler/man
12
- pkg
13
- rdoc
14
- spec/reports
15
- test/tmp
16
- test/version_tmp
17
- tmp
data/Gemfile DELETED
@@ -1,4 +0,0 @@
1
- source "https://rubygems.org"
2
-
3
- # Specify your gem's dependencies in pretender.gemspec
4
- gemspec
data/Rakefile DELETED
@@ -1,8 +0,0 @@
1
- require "bundler/gem_tasks"
2
- require "rake/testtask"
3
-
4
- task default: :test
5
- Rake::TestTask.new do |t|
6
- t.libs << "test"
7
- t.pattern = "test/**/*_test.rb"
8
- end
data/pretender.gemspec DELETED
@@ -1,26 +0,0 @@
1
- # coding: utf-8
2
- lib = File.expand_path("../lib", __FILE__)
3
- $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require "pretender/version"
5
-
6
- Gem::Specification.new do |spec|
7
- spec.name = "pretender"
8
- spec.version = Pretender::VERSION
9
- spec.authors = ["Andrew Kane"]
10
- spec.email = ["andrew@chartkick.com"]
11
- spec.description = "Simple, powerful user impersonation for Rails"
12
- spec.summary = "Easy to switch back and forth between roles, minimal code changes, and plays nicely with auditing tools"
13
- spec.homepage = "https://github.com/ankane/pretender"
14
- spec.license = "MIT"
15
-
16
- spec.files = `git ls-files`.split($INPUT_RECORD_SEPARATOR)
17
- spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
- spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
- spec.require_paths = ["lib"]
20
-
21
- spec.add_dependency "actionpack"
22
-
23
- spec.add_development_dependency "bundler", "~> 1.3"
24
- spec.add_development_dependency "rake"
25
- spec.add_development_dependency "minitest"
26
- end
@@ -1,60 +0,0 @@
1
- require_relative "test_helper"
2
-
3
- module TheTruth
4
- def test_original_state
5
- @controller.current_user = @impersonator
6
-
7
- assert_equal @impersonator, @controller.true_user
8
- assert_equal @impersonator, @controller.current_user
9
- end
10
-
11
- def test_impersonates
12
- @controller.current_user = @impersonator
13
- @controller.impersonate_user @impersonated
14
-
15
- assert_equal @impersonator, @controller.true_user
16
- assert_equal @impersonated, @controller.current_user
17
- end
18
-
19
- def test_impersonated_state
20
- @controller.current_user = @impersonator
21
- @controller.session[:impersonated_user_id] = @impersonated.id
22
-
23
- assert_equal @impersonator, @controller.true_user
24
- assert_equal @impersonated, @controller.current_user
25
- end
26
-
27
- def test_stops_impersonating
28
- @controller.current_user = @impersonator
29
- @controller.session[:impersonated_user_id] = @impersonated.id
30
- @controller.stop_impersonating_user
31
-
32
- assert_equal @impersonator, @controller.true_user
33
- assert_equal @impersonator, @controller.current_user
34
- end
35
- end
36
-
37
- class PretenderTest < Minitest::Test
38
- include TheTruth
39
-
40
- def setup
41
- @impersonator = User.new("impersonator")
42
- @impersonated = User.new("impersonated")
43
- @controller = ApplicationController.new
44
- end
45
- end
46
-
47
- class SuperPretenderTest < Minitest::Test
48
- include TheTruth
49
-
50
- def setup
51
- @impersonator = User.new("impersonator")
52
- @impersonated = User.new("impersonated")
53
- @controller = ApplicationController.new
54
- class << @controller
55
- def current_user
56
- super
57
- end
58
- end
59
- end
60
- end
data/test/test_helper.rb DELETED
@@ -1,26 +0,0 @@
1
- require "bundler/setup"
2
- Bundler.require(:default)
3
- require "minitest/autorun"
4
- require "minitest/pride"
5
- require "action_controller"
6
-
7
- User = Struct.new(:id) do
8
- def self.where(id: nil)
9
- [new(id)]
10
- end
11
- end
12
-
13
- module ActionController
14
- class Base
15
- attr_reader :session
16
-
17
- def initialize
18
- @session = {}
19
- end
20
- end
21
- end
22
-
23
- class ApplicationController < ActionController::Base
24
- attr_accessor :current_user
25
- impersonates :user
26
- end