Need help to configure CanCanCan for activeadmin - ruby-on-rails

I need help to configure CanCanCan using ActiveAdmin. I have everything else working including devise. I can restrict menus using devise but if you know the URL lets say for edit you can still edit that resource. I want to restrict a normal user from editing/creating any resources but it does not seem to work.
Active_Admin.rb
config.cancan_ability_class = ActiveAdmin::CanCanAdapter
Ability.rb (simple out of the box)
class Ability
include CanCan::Ability
def initialize(user)
# Define abilities for the passed in user here. For example:
#
# user ||= User.new # guest user (not logged in)
if user.admin?
can :manage, Student
else
can :read, Student
end
end
end
User model.
admin:boolean
and if I login with a user who is not an admin i can still create/edit/delete, I just want to restrict them to read only.
Please help i am struggling with this only feature that I need to complete.
Thanks in advance

Change this thinks:
config.authorization_adapter = ActiveAdmin::CanCanAdapter
config.cancan_ability_class = Ability
authorization_adapter tells active admin which adapter it should be use.
cancan_ability_class tells the adapter which class it should use.
If that still doesn't work, try to rename Ability to AdminAbility.

Related

Rails: cancancan gem condition is not working

In my project, I have a user class working with Devise authentication. Each user have one role associated with. For exemple, a manager is the role #1.
Role is a class and there is an association beetween role and user based on role_id. So a manager will have a role_id of 1.
I installed cancancan gem to manage permission for each user. Only a manager can create user account. So, I wrote this in the ability class:
def initialize(user)
user ||= User.new # guest user (not logged in)
if user.role_id == 1
can :manage, :user
else
cannot :manage, :user
end
end
In my user controller, I have this:
def new
#user = User.new
authorize! :manage, #user
end
The problem is when I login with my manager and try to access to new user page, I receive the message from cancancan saying that I don't have the permission to access the page.
I don't know if it's my condition or when I'm trying to access to user.role_id or...
Thanks for your help.
See cancancan gem : https://github.com/CanCanCommunity/cancancan
Edit:
It's normal if my IDE says that it cannot find current_user?
Also, if you check on github, there is an example of how to use cancancan:
As you see, there is an #article after the read permission. So I don't think I need to put current_user instead of #user
Finally:
Problem was the :user that was not correct. When it's a model, you need to write a capital letter first for the name of the model without ":". So instead of :user, it should be User
current_user relies on a Rails session. Since this is your #new action on your Users Controller, you don't have an active session, thus no current_user.

fetching logged in user associated record in rails_admin

I have installed rails_admin gem without any error its display models crud too,but i have requirement in which i need to show current_user logged in associated data
e.g User has many Books so in rails admin i want only that user book but currently it's showing all users books which is default behaviour of rails_admin
i have also try to use cancancan gem for achieve same thing but its not working my rails_admin initializers config as below
rails_admin.rb
RailsAdmin.config do |config|
### Popular gems integration
## == Devise ==
config.authenticate_with do
warden.authenticate! scope: :user
end
config.current_user_method(&:current_user)
config.parent_controller = 'ApplicationController'
## == Cancan ==
config.authorize_with :cancan,UserAbility
## == Pundit ==
# config.authorize_with :pundit
config.included_models = ["Book","User"]
config.actions do
dashboard # mandatory
index # mandatory
new
export
bulk_delete
show
edit
delete
show_in_app
end
end
UserAbility Class is implemented as below
class UserAbility
include CanCan::Ability
def initialize(user)
# Define abilities for the passed in user here. For example:
if user.present?
can :access, :dashboard
can :manage, :Book,id:user.id
end
end
end
Instead of can :manage, :Book,id:user.id, try using:
can :read, Book, user_id: user.id
So the abilities together look like:
can :access, :rails_admin
can :dashboard
can :read, Book, user_id: user.id
I think you're misunderstanding the scope of Rails Admin. In essence, it's a snapshot of your database, and is meant for more administrative operations like querying your database for something specific.
The only thing you'd reasonably be able to do is to look up all Books for a given user, with the default falling to all books for all users. Filters exist within the display to be able to narrow down based on a user's specific credentials, such as user name, email, or ID.
For a conceptual check, a user in Rails Admin isn't treated or regarded the same as a user in your application. Instead, think of using Rails Admin as a way to check the data in your database as opposed to showing data for a specific, authenticated person.
As you describe, the more appropriate Rails way to do this would be to create a controller and route for this data, and to simply use current_user.books to get all of the books for the current user.

CanCan Abilities Definition

In my rails application, my user is able to login once and switch between accounts as they please. When they do, I need to reinitialize their abilities since the permissions are set at the account level in the database.
My initial thought is to initialize the ability class when I detect a change in the account but not sure how to accomplish this.
I am of course open to any other idea. I am new to CanCan.
The Ability class is where all user permissions are defined.
Example:
class Ability
include CanCan::Ability
def initialize(user)
user ||= User.new # guest user (not logged in)
if user.admin?
can :manage, :all
else
can :read, :all
end
end
end
The 'can' method is used to define permissions and requires two arguments. The first one is the action you're setting the permission for, the second one is the class of object you're setting it on.

Understanding CanCan Ability and Users

I have Rails Admin with CanCan support in my rails app. I'm confused on one issue though. How does CanCan know what user is signed in? For example, my users can have different roles and through CanCan I assign roles for certain access into each table. When I go to localhost:3000/admin, I receive the error
CanCan::AccessDenied in RailsAdmin::MainController#dashboard
My Ability.rb file
def initialize(user)
if user and user.role.eql? :super_admin
can :manage, :all # allow superadmins to do anything
elsif user and user.role.eql? :admin
can :manage, [Location, School] # allow admins to manage only Locations and Schools
end
end
So what do I do so that user's have the ability to sign in into Rails Admin? Do I have to manually create it?
By default, CanCan will use whatever is returned by current_user. If you are using Devise within a namespace though (admin for example) then Devise actually will use current_admin_user instead. You can either create a current_user method in your ApplicationController (or some other base controller) that returns current_admin_user or overwrite the current_ability method to instantiate the Ability with current_admin_user instead.
(this is all assuming your Devise is using a namespace. By default Devise will use current_user)
You need to have a current_user method available in your controller. Assuming you have that, if you aren't signed you won't have access to a current user, so you'll need to assign a user in your ability file if it doesn't exist. In your initialize method, add user ||= User.new to make the assignment if a user doesn't already exist.
def initialize(user)
user ||= User.new
if user and user.role.eql? :super_admin
can :manage, :all # allow superadmins to do anything
elsif user and user.role.eql? :admin
can :manage, [Location, School] # allow admins to manage only Locations and Schools
end
end

How can i allow user with admin role to edit the role of the other users?

I use devise for authentication and only an admin can create a user.
I use cancan to assign roles to the user during user creation.
I want the admin to view all the users roles and the admin should be able to edit the roles of the users.
How can I do this?
Check out https://github.com/marklocklear/devise_multi_tentant. In ability.rb I have...
class Ability
include CanCan::Ability
def initialize(user)
can :manage, :all if user.role == "admin"
end
end
You can add a role attributes for User model.
Then, when user go to admin dashboard, you can check user's role. If user isn't admin, redirect to another page (using before_filter :function)
But, instead doing everything manually, you can use gem cancan instead, it's so popular and easy to use!
You can find the document here: GitHub
Or in rails cast episodes 192
Basically, it'll create a ability model, and you will declare privilege for user, a sample ability class
class Ability
include CanCan::Ability
def initialize(user)
user ||= User.new # guest user (not logged in)
if user.admin?
can :update, User
end
end
end
After that, you can authorize for user in action, controller or views, like the example see this link
PS: sorry if my English was too bad, thanks:)

Resources