CanCan gem | cannot :index, User - ruby-on-rails

Very basic user model, I wish the admin user to :manage all
else cannot :index, User and some other options, but when I try and block non admin users from viewing the user index, the admin user also has not access.
this is my ability.rb
class Ability
include CanCan::Ability
def initialize(user)
user ||= User.new #guest user
can :manage, :all if user.role == "admin" #if user.admin? can :manage, :all
can :assign_role, User
else
can :read, :all
can :create, User
cannot :assign_role, User
cannot :index, User
can [:show, :edit, :update], User do |current_user|
user.id == current_user.id || user.role == "admin"
end
end
end
What can I do to stop all users being blocked from User index?
Regards
Dan

Something wrong with if-else in code.
if user.role == "admin"
can :manage, :all
can :assign_role, User
else
can :read, :all
can :create, User
cannot :assign_role, User
cannot :index, User
can [:show, :edit, :update], User do |current_user|
user.id == current_user.id || user.role == "admin"
end
end
And also you don't have to deny non-admin user to assign role obviously (cannot :assign_role, User).

Related

Manage controllers with namespace according to user role + cancancan + rails

==> I have a website with two names spaces as below
User::xyz_controller
User::abc_controller
Admin:xyz_controller
Admin:abc_controller
==> User model with three roles
admin
leader
consultant
If the user has role leader or consultant. He should only access the User namespace controllers. and if User has role Admin. Admin should only access the Admin namespace controllers.
==> below is my ability.rb file content.
class Ability
include CanCan::Ability
def initialize(user)
if user.has_role? :Admin
can :manage, :all
elsif user.has_role? :Leader
cannot :manage, User
elsif user.has_role? :Consultant
cannot :manage, User
end
end
end
Application Controller
before_action :current_ability, unless: :devise_controller?
private
def current_ability
controller_name_segments = params[:controller].split('/')
controller_name_segments.pop
controller_namespace = controller_name_segments.join('/').camelize
Ability.new(current_user, controller_namespace)
end
ability.rb
class Ability
include CanCan::Ability
def initialize(user, namespace)
case namespace
when 'Admin'
can :manage, :dashboard if user.has_role? :Admin
can :manage, Company if user.has_role? :Admin
can :manage, CompanyHistory if user.has_role? :Admin
can :manage, Record if user.has_role? :Admin
can :manage, Service if user.has_role? :Admin
can :manage, ProcessTable if user.has_role? :Admin
can :manage, User if user.has_role? :Admin
when 'Users'
can :manage, Company if user.has_role? :Consultant
can :manage, CompanyHistory if user.has_role? :Consultant
can :manage, Record if user.has_role? :Consultant
can :manage, Company if user.has_role? :Leader
can :manage, CompanyHistory if user.has_role? :Leader
can :manage, Record if user.has_role? :Leader
end
end
end
Define in controller
--> Use without class
load_and_authorize_resource class: false
--> Use with class
load_and_authorize_resource class: Company

Allow creation of a limited user only with CanCanCan

I want the Admin user to not have the ability to create users with the role of Super Admin but still be able to create other Admins and Regular Users. How do I accomplish this? Here is my Ability.rb:
class Ability
include CanCan::Ability
def initialize(user)
if user.super_admin?
can :manage, :all
elsif user.admin?
can :manage, [Article, Comment]
can [:destroy, :update], User, :role_id => 2 # If Admin
can [:destroy, :update], User, :role_id => 3 # If User
can :read, User
can :create, User
elsif user.user_regular?
#cannot :read, ActiveAdmin::Page, :name => "Dashboard"
#can :manage, :all
end
end
end
Use cannot with in admin block like cannot :creat, User, :role_id => 1 # let 1 is super admin role id. You can get more info about combine ability at here

ArgumentError in Users::RegistrationsController#new

I am trying to get Cancan to work with Devise on my Rails application. I tried to follow the directions here to set it up:
http://www.tonyamoyal.com/2010/07/28/rails-authentication-with-devise-and-cancan-customizing-devise-controllers/
I am stuck as I am getting the following error:
ArgumentError in Users::RegistrationsController#new
wrong number of arguments (2 for 1)
app/models/ability.rb:7:in initialize'
app/controllers/users/registrations_controller.rb:6:incheck_permissions'
My ability.rb reads as follows:
class Ability
include CanCan::Ability
def initialize(user)
user ||= User.new # guest user
if user.role? :super_admin
can :manage, :all
elsif user.role? :admin
can :manage, :all
elsif user.role? :user
can :read, :all
# manage products, assets he owns
can :manage, Product do |product|
product.try(:owner) == user
end
can :manage, Asset do |asset|
asset.assetable.try(:owner) == user
end
end
end
end
My registrations controller reads:
class Users::RegistrationsController < Devise::RegistrationsController
before_filter :check_permissions, :only => [:new, :create, :cancel]
skip_before_filter :require_no_authentication
def check_permissions
authorize! :create, resource
end
end
This only occurs on the signup page. All other pages within the app are working fine.
When using cancan u have to use following line in your controller.
load_and_authorize_resource

Cancan user permission?

I am using cancan for permissions and I would like it so users cannot see other users when visiting their profile/users page. User should only be able to see themselves.
In my ability.rb file I have
class Ability
include CanCan::Ability
def initialize(user)
user ||= User.new # guest user (not logged in)
if user.role? :admin
can :manage, :all
elsif user.role? :rookie
can [:update, :destroy], [Album, Photo, User]
can :read, :all
end
can :manage, Album, :profile => { :user_id => user.id }
can :manage, Photo, :profile => { :user_id => user.id }
can :manage, Video, :profile => { :user_id => user.id }
can :manage, Comment, :blog => { :profile => { :user_id => user.id } }
can :manage, User, :id => user.id
end
end
In my users_controller I have
class UsersController < ApplicationController
before_filter :authenticate_user!
load_and_authorize_resource
def index
#user = current_user
end
def show
#user = User.find(params[:id])
end
end
The above usually works but since user is the primary model I am not sure how I can resolve this. Rails gives me the error
undefined method `user_id'
It should be:
#ability.rb:
can :manage, User, :id => user.id
I am assuming that most users start with role :rookie and you have ability
can :read, :all
for users with role :rookie. Then this means that all :rookie users will be able to read
all resources.

Rails cancan authorizing nested resources

I have Projects resource which is nested in Users resource.
My Cancan Ability class is:
class Ability
include CanCan::Ability
def initialize(user)
#everyone
can :read, Project
if user.blank?
# guest user
...
else
#every signed in user
case user.role
when User::ROLES[:admin]
#only admin role user
can :manage, :all
when User::ROLES[:member]
#only member role user
can :update, User, :id => user.id
can [:create, :update, :destroy], Project, :user_id => user.id
else
end
end
end
end
And Projects controller:
class ProjectsController < ApplicationController
load_and_authorize_resource :user
load_and_authorize_resource :projects, :through => :user, :shallow => true
...
end
I have few questions:
Is it possible to deny :read User and allow to :read Project, so that everyone could access /users/10/projects, but not /users/10 or /users?
How can I deny user accessing :new action with other user_id? For example, if I add
#everyone
can :read, User
can :read, Project
this code allows user with id 42 to access /user/41/projects/new.
Solved it by doing:
class Ability
include CanCan::Ability
def initialize(user)
#everyone
can :read, Project
can :read, User # required to access nested resources
cannot :index, User
cannot :show, User
if user.blank?
# guest user
...
else
#every signed in user
case user.role
when User::ROLES[:admin]
#only admin role user
can :manage, :all
when User::ROLES[:member]
#only member role user
can :update, User, :id => user.id
can :manage, Project, :user => { :id => user.id }
else
end
end
end
end

Resources