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? =)
Related
I am using Rails Admin gem as an admin dashboard in my rails app, it works perfectly and shows all my models. Am using devise for authentication and have two types of users, Users that signup and devise guest user (users are saved till they sign up or sign in as guest user with an example email). In rails admin Users section, it shows all of the users even the guest user. I want to hide this guest user from there.
What i tried:
user.rb
scope :verified, -> { where(guest: false) }
rails_admin.rb
config.model User do
list do
scopes [:verified]
end
end
it did not work...is there any way to use permanent filters here as my normal users have many fields like location and username...so am thinking of doing something like showing only users who have username.
What you tried would filter the guest users on the list, not the access to the list itself.
The rails admin recommended way to solve this is with an authorization framework, see the cancancan documentation to get it working.
https://github.com/sferik/rails_admin/wiki/Cancancan
I successfully configured this per user.
Example of how it would work:
class Ability
include CanCan::Ability
def initialize(user)
return unless user && user.admin?
can :access, :rails_admin # only allow admin users to access Rails Admin
can :read, :dashboard # allow access to dashboard
if user.role? :superadmin
can :manage, :all # allow superadmins to do anything
elsif user.role? :manager
can :manage, [User, Product] # allow managers to do anything to products and users
elsif user.role? :sales
can :update, Product, hidden: false # allow sales to only update visible products
end
end
end
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).
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.
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:)
In my ability.rb file, how can I set it so that only defined users can do things, else (an undefined/not logged in user) cannot do anything?
Example:
def initialize(user)
user ||= User.new #not logged in user
if user.admin_user?
can :manage, :all
else
#can't do anything. Cannot view, edit, or update.
end
end
Thanks!
I've never really used CanCan, but I looked over the docs, and I don't think you need to explicitly define what the user can't do.
You should just be able do something like this in your controller:
if cannot? :destroy, #project
# redirect the user or do something else to disallow access
end
cannot? should return true if the user wasn't assigned a role that has any abilities defined. Conversely can? would return false.
You could try a simple conditional set in your initialize function:
# app/models/ability.rb
def initialize(user)
if user && user.admin_user?
# Abilities for registered admin users
can :manage, :all
elsif user
# Abilities for registered users
can :read, :all
else
# Abilities for no user
end
end
When initialize is called, user will likely (depending on your authentication solution) be nil for not logged in users, which will trigger the last branch.