Allow creation of a limited user only with CanCanCan - ruby-on-rails

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

Related

CanCan Ability in Rails - Giving partial manage

I have three roles of AdminUsers:
admin
editor
student
I need the editor to have the ability to manage(add/view/delete) AdminUser accounts that its role is student.Yet, he can't see whose role is admin or editor.
With the following code, he could view only without creation/deletion/edit
if user.role?(:admin)
can :manage, :all
elsif user.role?(:editor)
can :read, ActiveAdmin::Page, :name => "Dashboard"
can :manage, :all
cannot :manage, AdminUser
can :manage, AdminUser, :role => :student
else
can :read, :all
end
If I understand you correctly, you're saying that a user who is an editor should be able to manage the account of another user who is a student. If that's the case, this should work:
if user.role?(:admin)
can :manage, :all
elsif user.role?(:editor)
can :read, ActiveAdmin::Page, :name => "Dashboard"
can :manage, AdminUser, :role => :student
else
can :read, :all
end

With CanCan, how do i limit ability based on association / child attribute

I have a db setup where there are many users, which have roles of member or admin. Each user has many cars. Each car has many timeslips
So, how do i limit a user's ability to edit a Timeslip only if he is the owner of the parent car.
In CanCan:
class Ability
include CanCan::Ability
def initialize(user)
user ||= User.new # guest user (not logged in)
if user.has_role? :admin
can :manage, :all
elsif user.has_role? :member
can :manage, Car, :user_id => user.id
can :manage, Timeslip, :car => {:user_id => user.id}
end
end
end
so the line can :manage, Timeslip, :car => {:user_id => user.id} is where i need some help.
Because Timeslip is an association/child of Car, i need to check that its parent car.user_id = the Cancan user.id
I thought how i wrote this is in line with the CanCan docs, but where have I gone wrong?
There might be a shorter way to write it, but this will work:
can :manage, Timeslip do |timeslip|
timeslip.car.user_id == user.id
end
This is what's working for me: can :manage, Timeslip, car: { roles: { id: user.role_ids } }

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

CanCan gem | cannot :index, User

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

Resources