Dynamic menu according to user on Rails - ruby-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

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.

Proper way to use CanCan+Rolify on Rails 4

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).

CanCan based access with multiple views

I'm working on a Rails 4 app and im trying to come up with a solution. I was wondering how i could implement CanCan to allow users to access certain data. Such as a guest can only view certain parts of the content. An owner can have full access to the content and a collaborator could have partial access.
My app consists of a
User
- Developer
- Organization
Developer
- Has many apps on its own
- Has many organizations as founder or collaborator
Organization
- Has many founders and collaborators
- Has many apps
How can i restrict this to guests who aren't logged in can view some aspects of a developer/organization/app profile, founders has full access to the organization, owners of apps have full access and collaborators have some access. Does this make sense?
cancan only works with current_user method. I dont no if there is a way to customize this
the code example below can guide you through managing contents by only the owner
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, Content
end
if user
can :create, Content
can :manage, Content do |content|
content.try(:user) == user
end
end
end
end

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

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