rails_admin with devise and single admin user - ruby-on-rails

I'm using Rails 5, rails_admin and devise with the standard devise user model setup:
config.authenticate_with do
warden.authenticate! scope: :user
end
config.current_user_method(&:current_user)
I would like a single user to be able to access the /admin area. Without having to create a new "isAdmin" attribute in the User model, is it possible to simply tell rails_admin that user.id=1 is the only user that can access the /admin area?

This worked for me. In rails_admin.rb, I removed the devise configuration and simply checked for current_user.id to equal 1.
config.authorize_with do
if user_signed_in?
redirect_to main_app.root_path unless current_user.id == 1
else
redirect_to main_app.root_path
end
end
This is simple and does not give away there is an /admin area unless you are the current signed in user and your id == 1

Related

NoMethodError in RailsAdmin::MainController#dashboard undefined method `is_admin?' for #<User:0x007fc87c140c48> Did you mean? is_haml?

Currently I'm using devise and rails_admin on Rails 5.0.0.1, when I open admin panel this error is showing up.
After I added below lines in rails_admin.rb file for authorization, above error arises
config.authorize_with do
redirect_to main_app.root_path unless current_user.is_admin?
end
The error states that is_admin? method is not defined for a user instance. I assume you have an admin attribute in your model. You can either define the method in the model like
class User < ActiveRecord::Base
def is_admin?
self.admin #returns a boolean
end
...
end
Or replace the block with
config.authorize_with do
redirect_to main_app.root_path unless current_user.admin
end
current_user.admin will return a boolean value based on the field admin in the users table.
Hope this helps!
I was experiencing the same issue and was able to find a solution.
Add this to rails_admin.rb:
config.authorize_with do
redirect_to main_app.root_path unless current_user.admin?
end
if you are working with devise add it underneath the devise section like so:
RailsAdmin.config do |config|
### Popular gems integration
## == Devise ==
config.authenticate_with do
warden.authenticate! scope: :user
end
config.current_user_method(&:current_user)
config.authorize_with do
redirect_to main_app.root_path unless current_user.admin?
end

Devise multiple model session in same browser

I have two devise model User and Admin. Now does devise support multiple model session in same browser in different tabs. If yes than how can i assign two different layout with two session in progress.
I tried this
layout :layout_by_resource
def layout_by_resource
if devise_controller? and admin_signed_in?
'admin'
elsif devise_controller? and user_signed_in?
'user'
else
'application'
end
end
but this won't work because admin and user both already signed in.
If devise does not support two different model session in same browser then what is the purpose of using devise and how can i accomplish my requirement.
If you follow this https://github.com/plataformatec/devise/wiki/How-To:-Add-an-Admin-Role
You can simply check current_user.admin?
def layout_by_resource
if current_user.admin?
'admin'
elsif current_user
'user'
else
'application'
end
end

Login in to main app from active admin

I have app, and connected active admin. I'm trying to let admin user login as any user via active admin without password using devises's sign_in #user method. Is it possible to achieve this out of box?
I can make redirect with username in params/session, but that isnt secure, as if i wouldnt like to pass anything outside active admin.
Any ideas?
I'm not sure exactly what you mean by "not secure"; the devise internals can make sure that you are an admin user, etc, and all you need to pass around is the username of the new user. That said, the code below is entirely within ActiveAdmin and will achieve what you want.
N.B. I can't think of an easy way to sign the Admin user back in (I use the same Devise for all users and use role-based auth).
member_action :sign_in_as, :method => :put do
user = User.find(params[:id])
sign_in user, bypass: true
redirect_to root_path
end
action_item :only => :show do
link_to('Sign in As', sign_in_as_admin_user_path(user), method: 'put')
end
you can do this by using additional method to authenticate admin first like this,
def authenticate_any!
if authenticate_admin_user!
true
else
authenticate_user!
end
end
or overriding devise
module Devise
module Controllers
module Helpers
def authenticate_user!
if authenticate_admin_user!
return true
end
super
end
end
end
end

Authenticate rails_admin with admin attribute

I want to be able to just let the users that have an admin attribute set to true to access rails_admin. So, if a user has the is_admin attribute to true, they can access the rails_admin interface.
I have checked their documentation and all I can find about authentication is here: https://github.com/sferik/rails_admin/wiki/Authentication
Please, could you help me to do so?
Thanks
From https://github.com/sferik/rails_admin/wiki/Authorization
config.authorize_with do
redirect_to main_app.root_path unless current_user.is_admin?
end
The documentation already explains, what you have to do:
In your rails_admin.rb initializer:
config.authenticate_with do
warden.authenticate! :scope => :admin
end
config.current_user_method { current_admin } # hook to your 'current_user' method
And in your User Model you generate the current_admin method:
def current_admin
current_user && current_user.is_admin
end
I think this should work.

Identifying the user after sign out for after_sign_out_path_for method in Devise

For after sign in path, you can do the following:
def after_sign_in_path_for(resource)
if resource.class == User
if resource.sign_in_count < 2
'/dashboard'
else
'/dashboard/home'
end
elsif resource.class == AdminUser
I18n.locale = "en"
'/admin/dashboard'
else
I18n.locale = "en"
'/'
end
end
But, how can I check if my user is a User or an AdminUser after sign_out?
def after_sign_out_path_for(resource_or_scope)
if resource_or_scope == AdminUser
This does not work. Is there any way to check it?
Note: Although I have done a monkey patch and defined new root for admin and my problem is solved, but I want to know if there is any way to implement using after_sign_out_path_for method of Devise?
Devise gives you the current_user after you sign in which is the logged in user. There is nothing like whether the user is admin or the general user.
So its not that you can use for.
You can use other ways to get what you want.
The one is Cancan which works well with Devise, you can define user roles.
With Cancan, you can define a column in your users table, say role, with values for each user like admin or general user. So then there will be Ability.rb file for Cancan and there you can define your logic.
You can use conditions -
if user.role? :admin
#admin related logic
elsif user.role? :general
#general user related logic
end
This will work here.
def after_sign_out_path_for(resource_or_scope)
if resource_or_scope == :user
redirect_to ... # users path
elsif resource_or_scope == :admin
redirect_to .... # admins path
end
end
Devise will call the method after_sign_out_path_for with the symbol of the class name as the parameter, hence we can check the condition based on that symbol.
In your user model you could do something like this if you have a column for specifying the user role.
def admin?
role == "admin"
end
then all you do is
def after_sign_out_path_for(user)
if user.admin?

Resources