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
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'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
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? =)
If a user is logged in with a specific role - vendor - they should only see items that they have created in their store. They should not be able to see products from other vendors.
So I am trying to do this in my authorization (using Devise, CanCan, Rolify).
I tried this:
user ||= User.new # guest user (not logged in)
if user.has_role? :vendor
can :dashboard
can :manage, [Product, Vendor], :vendor_id => user.id
can :view, [Product], :vendor_id => user.id
end
But....haven't had much luck with that...what am I missing?
Edit 1
I know that I can restrict the products in the controller like:
#product = current_user.products
But that's not what I am looking for. In this case, a vendor (i.e. user with role :vendor) should only be able to see products they added to the store, but they shouldn't be able to see products that other vendors add. However, a buyer (i.e. a user with role :buyer) should be able to see all the products from all buyers (as will an admin/etc). A buyer won't be able to see the prices, and some other attributes on some of the products, etc.
How can I achieve all of that?
In the controller you can only find the products belonging to that user.
def show
#product = #user.products.find(params[:id])
...
Same applies to edit and update action. Cancan in this case is not required.
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:)