I apologize in advance for my English and knowledge of ruby :)
I making admin panel with RailsAdmin, authentication with Devise, authorisation with CanCanCan, so, I have three boolean fields in User:
add_column :users, :superadmin_role, :boolean, default: false
enter code hereadd_column :users, :manager_role, :boolean, default:
So, in ability.rb i have this:
class Ability
include CanCan::Ability
def initialize(user)
user ||= User.new # guest user (not logged in)
can :access, :dashboard # allow access to dashboard
can :access, :rails_admin # access Rails Admin for Admin-users
if user.superadmin_role?
can :manage, :all
end # role works correct
if user.manager_role?
can :read, :all
end #role works incorrect
end
end
SUPERADMIN_ROLE works correct and allow to enter to RailsAdmin and etc., but MANAGER_ROLE is doesn't work - when user try enter in Dashboard, there is an Access Denied error message is showing:
How to provide access for manager_role to dashboard and RailsAdmin interface - have broke the whole brain.
I will be glad to any help (ready code, links #where to read and etc) and constructive criticism
cancancan2 needs a different adapter for RailsAdmin. Please look at this issue: https://github.com/CanCanCommunity/cancancan/issues/413 and this issue: https://github.com/sferik/rails_admin/issues/2901.
On the first link you will find the code needed to create an adapter.
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 have installed rails_admin gem without any error its display models crud too,but i have requirement in which i need to show current_user logged in associated data
e.g User has many Books so in rails admin i want only that user book but currently it's showing all users books which is default behaviour of rails_admin
i have also try to use cancancan gem for achieve same thing but its not working my rails_admin initializers config as below
rails_admin.rb
RailsAdmin.config do |config|
### Popular gems integration
## == Devise ==
config.authenticate_with do
warden.authenticate! scope: :user
end
config.current_user_method(&:current_user)
config.parent_controller = 'ApplicationController'
## == Cancan ==
config.authorize_with :cancan,UserAbility
## == Pundit ==
# config.authorize_with :pundit
config.included_models = ["Book","User"]
config.actions do
dashboard # mandatory
index # mandatory
new
export
bulk_delete
show
edit
delete
show_in_app
end
end
UserAbility Class is implemented as below
class UserAbility
include CanCan::Ability
def initialize(user)
# Define abilities for the passed in user here. For example:
if user.present?
can :access, :dashboard
can :manage, :Book,id:user.id
end
end
end
Instead of can :manage, :Book,id:user.id, try using:
can :read, Book, user_id: user.id
So the abilities together look like:
can :access, :rails_admin
can :dashboard
can :read, Book, user_id: user.id
I think you're misunderstanding the scope of Rails Admin. In essence, it's a snapshot of your database, and is meant for more administrative operations like querying your database for something specific.
The only thing you'd reasonably be able to do is to look up all Books for a given user, with the default falling to all books for all users. Filters exist within the display to be able to narrow down based on a user's specific credentials, such as user name, email, or ID.
For a conceptual check, a user in Rails Admin isn't treated or regarded the same as a user in your application. Instead, think of using Rails Admin as a way to check the data in your database as opposed to showing data for a specific, authenticated person.
As you describe, the more appropriate Rails way to do this would be to create a controller and route for this data, and to simply use current_user.books to get all of the books for the current user.
I'm working on my abilities model on my Rails app to define my user authorization/abilities using cancancan. At the moment, here's what my ability.rb file looks like this:
class Ability
include CanCan::Ability
def initialize(user)
user ||= User.new # guest user (not logged in)
if user.admin?
can :manage, :all
else
can :manage, Application
can :read, User
end
end
end
I'm testing my app now. when I log into an account that doesn't have the admin boolean and go to to say /users, they can access that page, but clicking the show buttons or anything else leads them to the root page and says that they don't have permission. Currently I have an Applications controller/model (poor naming convention, realized later). But I simply wanted to make it so that any user who has a boolean FALSE for if they're admin has different abilities. I want the admin? true person to be able to do anything, but I want everyone else to be only able to SEE THEIR OWN own application (not everything entered by all users), only be able to create one application, and only be able to see their own information on the user show page, and only be able to edit their own user information. Can anyone explain how to specify for the things only the users create and such? Thank you!
define role column into your database and insert following line into your model
generate migration:
class AddRoleToUser < ActiveRecord::Migration
def change
add_column :users, :role, :integer
end
end
insert this into your model like (User.rb)
enum role: [:Admin, :Client, :Enduser, :ClientUser, :Moderator]
then you can manage your permission using cancancan
class Ability
include CanCan::Ability
def initialize(user)
user ||= User.new # guest user (not logged in)
if user.admin?
can :manage, :all
else
can [:new,:create, :update, :destroy], User
end
end
end
I have Rails_admin installed with devise and I want to restrict the /admin dashboard to only admins. For the moment my code looks like :
config.authenticate_with do
warden.authenticate! scope: :user
end
config.current_user_method(&:current_user)
As you can see users can get in to the dashboard so I want only the users with a boolean true in the admin column of the user table to get access to the dashboard.
How would you suggest I do this ?
If you dont want to use cancan you can do this:
config.authorize_with do
redirect_to main_app.root_path unless current_user.try(:admin?)
end
I use this and it works fine.
I would recommend you to use an authorization gem called cancancan (is the updated version of cancan) it's super easy to use and it will let you to give certain permissions to different kind of users. If you don't know nothing about this gem i will recommend you to see this railscasts that will teach you how to use it properly.
So after you installed the cancancan gem in the ability.rb file you just need to do something like this to limit the admin access
models/ability.rb
class Ability
include CanCan::Ability
def initialize(user)
user ||= User.new # guest user (not logged in)
if user && user.admin?
can :access, :rails_admin # only allow admin users to access Rails Admin
can :dashboard
can :manage, :all
else
can :read, :all # allow everyone to read everything
end
end
end
And don't forget to tell to the rails_admin gem that you are using cancancan to validate the authorization
config/initializers/rails_admin.rb
RailsAdmin.config do |config|
## == Cancan ==
config.authorize_with :cancan
end
To user the "user.admin?" method you must create it into the user model, but it will only work if you have a role model that has_many users and users belongs_to role otherwise you will need other way to verify the role, so it will be something like this
models/role.rb
has_many :users
models/user.rb
belongs_to :role
def admin?
role_id == 0 # If you have id == 0 for admin
end
Also i will recommend you to use a role model or enum to manage the different roles with ease.
I hope it helps :D
So I've implemented the rails admin gem, and even with the cancan gem, I can't figure out a way to password protect localhost:3000/admin
Could someone give me a step by step guide for doing this? I can't really find a view or controller for the admin panel, so I'm not sure how to password protect it.
This page describes how you should be using Cancan : https://github.com/sferik/rails_admin/wiki/CanCan
# in config/initializers/rails_admin.rb
RailsAdmin.config do |config|
config.authorize_with :cancan
end
Their ability.rb example may be a bit more than you need this is mine :
class Ability
include CanCan::Ability
def initialize(user)
user ||= User.new # guest user (not logged in)
if user.has_role? :admin
can :manage, :all
can :access, :rails_admin # grant access to rails_admin
can :dashboard # grant access to the dashboard
end
end
end
You must then give the admin role to a user.
you can do this at the rails console as so :
user = User.find(1) #find user with ID 1
user.add_role :admin #assign role
user.has_role? :admin #should evaluate to True