Following is my setup
devise (4.4.3)
activeadmin (1.3.0)
Rails 5.2
I created a user table with devise. installed active admin and used the normal method and created admin_users table. NO I AM NOT USING THE SAME TABLE. THESE ARE DIFFERENT TABLES (I had to do this cause last time this question was marked as duplicate cause the user thought i used the same table)
Routes file looks like this:
devise_for :users
devise_for :admin_users, ActiveAdmin::Devise.config
ActiveAdmin.routes(self)
devise_scope :user do
authenticated :user do
root 'home#dashboard', as: :authenticated_root
end
unauthenticated do
root 'devise/sessions#new', as: :unauthenticated_root
end
end
Now the issue is root_path '/' redirects correctly and I am able to login as User. But I am not able to login as Admin. It redirects me back to root_path that is unauthenticated user.
But weirdly when I login as user, I can then login as admin_user.
AGAIN I AM USING DIFFERENT TABLES, admin_users and users
Thanks in advance.
I can tell you an easy way to add admin in devise
$rails g migration add_admin_to_user
in the db
def change
add_column :users, :admin , :boolean , {default: false}
end
in user.rb
def admin?
admin
end
<% if current_user && current_user.admin? %>
<% end %>
then i do sign up from the email that i want to be the admin
then in rails c select the email that you want it to be the admin for example
User.last
user=User.last
user.admin=true
user
user.save
Solved this.
So the issue is when you have activeadmin admin_users and users table that is created with devise, and you place the authenticated_user! before_action in application_controller, activeadmin interprets it as authorization failure(though this should not be the case).
Solution to this is, go to active_admin.rb and add the following code
config.skip_before_action :authenticate_user!
This forces activeadmin to listen to only its authrization_adapter.
Related
I'm working on a polling app and use Devise and Cancan for authentication and authorization. I have a User model generated by Devise and a Poll model. A poll belongs to a user. My problem is that I have a custom action in my Polls controller and I can't get Cancan to work with that custom action. This is what I tried to do in my code:
config/routes.rb:
match 'users/:user_id/polls' => 'polls#show_user'
Ability.rb:
def initialize(user)
user ||= User.new
if user.is? :admin
can :manage, :all
else # default
can :read, :all
can :manage, Poll, :user_id => user.id
can :show_user, Poll, :user_id => user.id
end # if else admin
end
polls_controller.rb:
class PollsController < ApplicationController
before_filter :authenticate_user!
load_and_authorize_resource :except => :show_user
def show_user
authorize! :show_user, user
#polls = Poll.find_all_by_user_id(params[:user_id])
render "index"
end
<...>
end
The idea is that a user's polls can be viewed only when the owner of the poll is signed in. However, with this code, when a poll's owner is signed in, that user gets kicked out of that page with a message that says authorization failed. If I remove the line authorize! :show_user, user, then a user who's signed in can view all other user's polls (the authorization doesn't work at all).
Can anyone see what I might be missing? Thanks in advance!
In abiltity.rb, you're verb/noun combination is :show_user and Poll, but in your controller you're using :show_user and user--you would need to use a Poll instead.
If, instead you want to allow the user to view all their own Polls, you might go with something like:
ability.rb:
can :show_polls_for, User, :id => user.id
polls_controller.rb:
def show_user
authorize! :show_polls_for, user
...
end
I am using Devise for my User model. I am also using ActiveAdmin which is using Devise as well for the AdminUser model.
I can sign in using an admin_user and a user independently of each other, but I have noticed if I sign out the User, the AdminUser is signed out as well. The same thing happens if I reverse it and sign out the AdminUser first.
What can I do to hopefully get around this?
routes.rb
devise_for :admin_users, ActiveAdmin::Devise.config
devise_for :users
get "dashboard/home"
ApplicationController
protected
def after_sign_in_path_for(resource)
if resource.is_a?(User)
stored_location_for(:user) || dashboard_home_path
elsif resource.is_a?(AdminUser)
stored_location_for(:admin_user) || admin_root_path(resource)
end
end
What you are looking for is a Devise configuration called sign_out_all_scopes
When a user signs out and it is set to true, all scopes are signed out for this user, both user and admin in your case.
In devise.rb search for sign_out_all_scopes and change its value to true.
I have implemented the cancan with active_admin using below link.
https://github.com/gregbell/active_admin/wiki/How-to-work-with-cancan
Just in my case the only change is below written code.
app/models/ability.rb
class Ability
include CanCan::Ability
def initialize(user)
user ||= AdminUser.new # guest user (not logged in)
if user.id == 1
can :manage, :all
puts ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> manage all"
else
can :read, :all
puts ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> read all"
end
end
end
For now just put condition on user.id.
so when i run my application i can see my puts are on right login.
Question:
so if i login with user whos user.id != 1 then also i can manage all my modules in active_admin.
cancan ability not working for me.
(In short my can :code isn't working in any condition)
Using rails 3.1.1, cancan 1.6.7, activeadmin 0.4.4, ruby 1.9.3
Followed commands in link correctly, double checked.
Used authorize_resource in AdminUser.
Using socery not devise, does this thing affecting the cancan?
I write the following in code in every model in /admin
then my conditions in ability model start working.
menu :if => proc{ can?(:manage, #ModelName) }
controller.authorize_resource
Before posting this question i just written the above code only in admin users
I am attempting to manage users in my app that uses Devise for the authentication. I followed the steps here in order to create a UsersController to allow me to do so. However, when I attempt to sign out, it says that the path /d/users/sign_out cannot be found. Is there anything else I need to add to get this to work?
EDIT: My routes look like:
devise_for :users. :path_prefix => 'd'
resources :users do
# stuff here
end
When I run rake routes, it gives me, for the destroy_user_session_path:
destroy_user_session DELETE /d/users/sign_out(.:format) {:controller=>"devise/sessions", :action=>"destroy"}
When I remove the path_prefix part, it attempts to 'show' a user with the ID sign_out
link_to "sign_out", destroy_user_session_path, method: :delete
do you have the method :delete in your view?
I'm using Devise for the first time with rails, and I'm having trouble with one thing:
I used the provided authenticate_user! method in my user's controller to restrict access to pages like so:
before_filter :authenticate_user!, :only => [:edit, :show, :update, :create, :destroy]
But this allows any signed in user to access any other users :edit action, which I want to restrict to only that user. How would I do that?
In your edit method, you need to do a check to see if the user owns the record:
def edit
#record = Record.find(params[:id])
if #record.user == current_user
#record.update_attributes(params[:record])
else
redirect_to root_path
end
end
You should look into Authorization such as CanCan. Or alternatively create a new method like so:
# Create an admin boolean column for your user table.
def authenticate_admin!
authenticate_user! and current_user.admin?
end