On rails 5. I'm trying to integrate cancancan 3.0.1 with rails_admin (1.4.2) and for the most part it works. My problem is that I can only get routing acccest to work if I give the user can :manage, :all otherwise I get an access Denied from cancancan
Here's my cancancan ability code. In this case the super admin gains access whereas the normal admin with can :manage, Project does not:
class Ability
include CanCan::Ability
def initialize(user)
can :read, :all # allow everyone to read everything
return unless user && user.admin?
can :access, :rails_admin
can :read, :dashboard # allow access to dashboard
if user.superadmin?
can :manage, :all # allow superadmins to do anything
elsif user.admin?
can :manage, Project
end
end
end
Is there anyway to allow users onto this route without manage :all?
Related
I have 5 models in my rails 4 application, and using cancancan gem I want to give access to specific users to a specific model only.
This means:
user1 is allowed to access 1,2 model
user 2 is allowed to access 3,4 model
user 3 is allowed to access all models.
Please guide me.
You should use rolify with cancan to accomplish that. You can assign a certain role with rolify to represent your "user 1" or "user 2" like this:
user = User.find(1)
user.add_role :limited_user_1
and your "user 3" that has access to everything can be an admin
user = User.find(3)
user.add_role :admin
Then with cancan it's as simple as checking if the user has the specified role. In this case :manage means the user has access to all actions, such as :read, :create, :update, :destroy.
class Ability
include CanCan::Ability
def initialize(user)
user ||= User.new # guest user (not logged in)
if user.admin?
can :manage, :all
elsif user.limited_user_1?
can :manage, :model_1
can :manage, :model_2
elsif user.limited_user_2?
can :manage, :model_3
can :manage, :model_4
end
end
end
A simpler version of Mike's answer would be as follows:
#app/models/ability.rb
class Ability
include CanCan::Ability
def initialize(user)
user ||= User.new # guest user (not logged in)
case user.role_id
when 1
can :read, Model
can :read, Model2
when 2
can :read, Model3
can :read, Model4
when 3
can, :manage, :all
end
end
end
You'll have to add a way to define whether a User is 1,2,3 etc, which is why Mike suggested rolify.
I am using cancan to manage authorizations in an activeadmin environment. I have recently used the active_skin gem to improve the looks, but only the super admin with manage:all access could see the new looks. May I know how I could make it visible to others?
Here is a sample Ability file:
if user.is? :admin
can :manage, :all
else
# Admin users can only manage their own posts
can :manage, Post, :organization_id => user.organization_id
end
1- You can use this
can :read, :all
2- Suggest you use new CanCanCan asCanCan no longer updated. Switching is no drama
Pierre
in my application for the User model I have an attribute username (should probably be name). Username is the name the user signs in with. In the sample code below I check if the current user is admin level and then if the username == admin they can manage all else they can only read all. The puts statements are for checking purposes.
class Ability
include CanCan::Ability
def initialize(user)
user ||= User.new # guest user
if user
if user.is? :admin
puts "-------"
name = user.username
puts "username = " + name.to_s
puts "-------"
if name == "admin"
can :manage, :all
else
can :read, :all
end
elsif user.is? :user
can :manage, Drill
I have an app that has two roles, super and admin. Super can do everything and admin should be able to do everything except categories. I've implemented the following, but it is still allowing access to categories for admin:
def initialize(user)
user ||= User.new # guest user (not logged in)
if user.has_role? :super
can :manage, :all
elsif user.has_role? :admin
cannot :manage, :categories
can :manage, :all
end
end
If I change it to the below, it locks admin out of everything.
def initialize(user)
user ||= User.new # guest user (not logged in)
if user.has_role? :super
can :manage, :all
elsif user.has_role? :admin
can :manage, :all
cannot :manage, :categories
end
end
I have load_and_authorize_resource in all of my controllers, but still having no luck figuring it out.
The rules are finally concluded in an array.
In your first example, when you use cannot, such rule got deleted from the array. But then you define can :manage, :all, so the deleted ones recovered.
In the later example, cannot is put at last so the deletion actually have taken effect.
I've got an app that uses Devise, CanCan and Rolify to deal with authentication and authorization. But I don't think I'm using these gems to the full extent. Right now the only thing in my ability class is this:
class Ability
include CanCan::Ability
def initialize(user)
user ||= User.new # guest user (not logged in)
if user.has_role? :admin
can :manage, :all
else
can :read, :all
end
end
end
I found a security hole where an authenticated user is able to look at other user profiles. I fixed it by changing some code in the user controller.
def show
#user = current_user.has_role?(:admin) ? User.find(params[:id]) : current_user
end
Is this the best way to deal with this hole? Is there a best practice or a rails convention that addresses this in a different way?
From the doc:
can :read, ModelName, :user_id => user.id
So I've implemented the rails admin gem, and even with the cancan gem, I can't figure out a way to password protect localhost:3000/admin
Could someone give me a step by step guide for doing this? I can't really find a view or controller for the admin panel, so I'm not sure how to password protect it.
This page describes how you should be using Cancan : https://github.com/sferik/rails_admin/wiki/CanCan
# in config/initializers/rails_admin.rb
RailsAdmin.config do |config|
config.authorize_with :cancan
end
Their ability.rb example may be a bit more than you need this is mine :
class Ability
include CanCan::Ability
def initialize(user)
user ||= User.new # guest user (not logged in)
if user.has_role? :admin
can :manage, :all
can :access, :rails_admin # grant access to rails_admin
can :dashboard # grant access to the dashboard
end
end
end
You must then give the admin role to a user.
you can do this at the rails console as so :
user = User.find(1) #find user with ID 1
user.add_role :admin #assign role
user.has_role? :admin #should evaluate to True