Proper way to use CanCan+Rolify on Rails 4 - ruby-on-rails

I am just wondering what is the proper way to use CanCan+Rolify in the simplest and most effective way.
I was under the impression that if I had an Ability model like below
user ||= User.new # guest user (not logged in)
if user.admin?
can :manage, :all
else
can :read, :all
end
And I have a resource, let`s say, Product that has
resourcify
declared, that a user that does not have the :admin role, would not be able to Create, Update or Delete such resource...
But it seems that more code is necessary to implement this behaviour, because I tested and a non :admin user IS able to delete and create a Product.
What am I missing?

Try to set load_and_authorize_resource to your Products controller (assuming that you want to make Products CRUDable only by certain roles of users).

Related

Prevent admins deleting other admins

This is a problem I haven't run into yet, but feel I will do.
Here's my Ability file:
user ||= User.create # create random name here
if user.has_role? :admin
can :manage, User
end
If Admins are simply User instances that have a role of admin. So won't this mean that admins will be able to delete other admins? How can I stop this happening and create a superadmin for this task?
Try constraints like this,
if user.has_role? :admin
can :manage, User, !has_role?(:admin)
end

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.

Dynamic menu according to user on Rails

I'm developing a manual access control on Rails and need some help with dynamic menus.
I have 3 models: User, Group and Functionality
User has one group
Group has many users
Groups has many functionalities
Users has many functionalities through Groups.
K. Now, when I login with 'admin' I want to render a dynamic menu with Administrator's group functionalities.
How can I do that?
Along the lines of this as a Helper
def admin_content(current_user)
if current_user.admin?
render 'partial'
end
end
You can then call it in your view.
Have a look at CanCan that "is an authorization library for Ruby on Rails which restricts what resources a given user is allowed to access."
You can then use an initialize method like they give on the example to have a better control over your menu.
def initialize(user)
user ||= User.new # guest user (not logged in)
if user.admin?
can :manage, :all
else
can :read, :all
end
end

How to make the first User an admin with ability file (cancan)

class Ability
include CanCan::Ability
def initialize(user)
user ||= User.new
if user.admin == 1 #admin
can :manage, :all
elsif
user.id != nil # registred users
can :read, :all
can :create, Post
cannot :manage, User
else
can :read, :all # guest user (not logged in)
cannot :manage, User
end
Here is my ability file. I want it to make the first registered user the admin and give them all the permissions to edit the whole web page, whilst the User has limited access to only managing Posts and a guest User is only allowed to read posts. However when I use
if can? in my code, the admin is given the same amount of access as a normal user. What am I doing wrong?
In my work I have to do the same thing but with Company.
Every Company creation I check if is the first, if it is, I set it as admin, otherwise, normal user.
The if can? is used here to define if a menu will be hidden or visible. With only that, the user will still access the page if he types the URL so you need to add load_and_authorize_resource so the user gets a message about not having permission.
Is that what you need? =)

cancan gem simple question

models/ability.rb
class Ability
include CanCan::Ability
def initialize(user)
user ||= User.new # guest user
if user.role? :admin
can :manage, :all
else
can :read, :all
can :create, Comment
can :update, Comment do |comment|
comment.try(:user) == user || user.role?(:moderator)
end
if user.role?(:author)
can :create, Article
can :update, Article do |article|
article.try(:user) == user
end
end
end
end
end
In Railscasts there are methods user.role? :admin & if user.role?(:author).I dont get it. Do i need to create a method in model to make it work?
I'm storing roles in Users table as a role column.
Yes, you need to write this yourself. However, the CanCan project has a wiki page describing how to do this.
The first line of the wiki says:
"CanCan is decoupled from how you
implement roles in the User model, but
how might one set up basic role-based
authorization?"
Note that I disagree almost completely with the example on that page that uses a role_mask, but the page is still good and should give you some ideas.
There is also the Separate Role Model example, which I personally like better. It depends on where you want to store your role information.
If you're looking for a gem that is plug-and-play, then check out Declarative Authorization.
Raynb says that he developed Cancan because DA was overkill for some projects here: http://railscasts.com/episodes/192-authorization-with-cancan?autoplay=true

Resources