Permalink
Browse files

added can_impersonate? functionality

  • Loading branch information...
1 parent d568e3e commit 7b05fce4918288893bf8f50a2c4d83a839e034bc @DaveSanders committed Jun 28, 2013
View
@@ -75,6 +75,7 @@ To support this Rails engine, you need to add some things.
* `current_user` helper within controllers & helpers
* `current_user.staff?` - your `User` model needs a `staff?` to identify if the current user is allowed to impersonate other users; if missing, no user can access impersonation system
+* `current_user.can_impersonate?(user_id)` - optional method on your `User` model that can be used to check permissions on whether this user can impersonate a specific user
### User#staff?
@@ -85,6 +86,20 @@ rails g migration add_staff_flag_to_users staff:boolean
rake db:migrate db:test:prepare
```
+### User#can_impersonate?(user_id)
+
+This method allows you to create logic to decide whether one user can impersonate another. For example, you may have a customer service rep who can impersonate users, but not administrators. This method will get passed the user_id that is to be impersonated, but the logic is up to you to decide. For example:
+
+```
+def can_impersonate?(user_id)
+ target_user = User.find(user_id)
+ return false if self.role == 'customer service' && target_user.role == 'admin'
+ true
+end
+```
+
+Note that this method is optional. If you don't want to limit who can impersonate whom, then simply don't declare the method in your configuration.
+
## Customization
### Header
@@ -153,10 +168,11 @@ You can fix this default behavior in `config/initializers/user_impersonate.rb`,
# config/initializers/user_impersonate.rb
module UserImpersonate
class Engine < Rails::Engine
- config.user_class = "User"
- config.user_finder = "find" # User.find
- config.user_id_column = "id" # Such that User.find(aUser.id) works
- config.user_is_staff_method = "staff?" # current_user.staff?
+ config.user_class = "User"
+ config.user_finder = "find" # User.find
+ config.user_id_column = "id" # Such that User.find(aUser.id) works
+ config.user_is_staff_method = "staff?" # current_user.staff?
+ config.user_can_impersonate_method = nil # current_user.can_impersonate?(user_id)
end
end
```
@@ -4,6 +4,7 @@ module UserImpersonate
class ImpersonateController < ApplicationController
before_filter :authenticate_the_user
before_filter :current_user_must_be_staff!, except: ["destroy"]
+ before_filter :current_user_can_impersonate!, only: ["create"]
# Display list of all users, except current (staff) user
# Is this exclusion unnecessary complexity?
@@ -58,6 +59,15 @@ def current_user_must_be_staff!
redirect_to '/'
end
+ def current_user_can_impersonate!
+ unless user_can_impersonate?(current_user, params[:user_id])
+ flash[:error] = "You don't have access to this section."
+ redirect_to :back
+ end
+ rescue ActionController::RedirectBackError
+ redirect_to '/'
+ end
+
# current_user changes from a staff user to
# +new_user+; current user stored in +session[:staff_user_id]+
def impersonate(new_user)
@@ -95,6 +105,12 @@ def user_is_staff?(user)
current_user.send(user_is_staff_method.to_sym)
end
+ def user_can_impersonate?(user, impersonate_id)
+ return true if user_can_impersonate_method.nil?
+ current_user.respond_to?(user_can_impersonate_method.to_sym) &&
+ current_user.send(user_can_impersonate_method.to_sym, impersonate_id)
+ end
+
def user_finder_method
(config_or_default :user_finder, "find").to_sym
end
@@ -122,6 +138,10 @@ def user_name_column
def user_is_staff_method
config_or_default :user_is_staff_method, "staff?"
end
+
+ def user_can_impersonate_method
+ config_or_default :user_can_impersonate_method, nil
+ end
def redirect_on_impersonate(impersonated_user)
url = config_or_default :redirect_on_impersonate, main_app.root_url
@@ -1,10 +1,11 @@
module UserImpersonate
class Engine < Rails::Engine
- config.user_class = "User"
- config.user_finder = "find" # User.find
- config.user_id_column = "id" # Such that User.find(aUser.id) works
- config.user_name_column = "name" # Such that User.where("#{user_name_column} like ?", "%#{params[:search]}%") works
- config.user_is_staff_method = "staff?" # current_user.staff?
+ config.user_class = "User"
+ config.user_finder = "find" # User.find
+ config.user_id_column = "id" # Such that User.find(aUser.id) works
+ config.user_name_column = "name" # Such that User.where("#{user_name_column} like ?", "%#{params[:search]}%") works
+ config.user_is_staff_method = "staff?" # current_user.staff?
+ config.user_can_impersonate_method = nil # current_user.can_impersonate?
config.redirect_on_impersonate = "/"
config.redirect_on_revert = "/impersonate"

0 comments on commit 7b05fce

Please sign in to comment.