J'utilise actuellement Devise, CanCan et Rolify pour gérer l'authentification et l'autorisation de mon application rails et j'ai du mal à comprendre comment le faire qu'un user
peut uniquement :show
et :update
une instance spécifique d'un modèle auquel appartient l'utilisateur (alias mon user
a une colonne client_id
, et non l'inverse).CanCanCan afficher uniquement l'instance du modèle auquel l'utilisateur appartient
La partie mise à jour de mon défini Abilities.rb
pour le user
avec le rôle :client
, fonctionne très bien, à savoir si current_user.client_id = 3
alors il ne peut mettre à jour un client où Client.id = 3
, cependant, ce même utilisateur peut voir une instance du modèle Client
et je ne peut pas sembler saisir comment limiter cela.
Ability.rb
...
if user.has_role? :client
can [:read, :update], [Property, Order], client_id: user.client_id
can [:read, :update], Owner
can :create, [Property, Order, Owner]
can :manage, User, id: user.id
can [:show, :update], Client, id: user.client_id
end
...
Chaque utilisateur ne dispose pas d'un index
de tous Clients
, donc après la recherche que j'ai changé can [:read, :update], Client, ..
-:show
mais les utilisateurs peuvent toujours voir l'autre clients
mais la partie :update
si elle fonctionne bien , donc je suis vraiment perdue ici. Je fais des recherches sur Google depuis quelques heures et je lis toute la documentation de CanCan dont je reconnais qu'elle a peut-être été traitée, mais je n'arrive pas à comprendre.
J'ai essayé limiter du côté du contrôleur comme indiqué ci-dessous, mais cela ne fonctionne pas non plus:
external/clients_controller.rb
class External::ClientsController < ApplicationController
load_and_authorize_resource
before_filter :client_only
def index
@clients = Client.paginate(page: params[:page], per_page: 15)
end
def show
@clients = Client.find(params[:id])
@client_users = User.where(client_id: params[:id])
@client_orders = Order.where(client_id: params[:id]).includes(:property, :owners)
can? :show, @clients
end
def edit
@clients = Client.find(params[:id])
respond_to do |format|
format.html { @clients.save }
format.js
end
end
def update
@clients = Client.find(params[:id])
@clients.update_attributes(client_params)
respond_to do |format|
format.html { if @clients.save
flash[:success] = "Client Updated Successfully"
redirect_to client_path(@clients)
else
render 'edit'
end
}
format.js
end
end
private
def client_params
params.require(:client).permit(:uuid, :company, :first_name, :last_name, :phone, :email, :address1, :address2, :city, :state, :zip, :notes)
end
def client_only
redirect_to root_path unless current_user.is_client?
end
end
Donc, si quelqu'un pouvait me aider à bien comprendre comment les poignées Cancan autorisation basée sur le rôle pour une instance d'un modèle alors je l'apprécierais grandement. Merci d'avance!
code mis à jour
Removed toutes les charges d'instance @client
dans external/clients_controller.rb
class External::ClientsController < ApplicationController
load_and_authorize_resource
before_filter :client_only
def show
@client_users = User.where(client_id: params[:id])
@client_orders = Order.where(client_id: params[:id]).includes(:property, :owners).paginate(page: params[:page], per_page: 15).order("order_number DESC")
end
def edit
respond_to do |format|
format.html
format.js
end
end
def update
if params[:client][:state].blank?
params[:client][:state] = @client.try(:state)
end
@client.update_attributes(client_params)
respond_to do |format|
format.html { if @client.save
flash[:success] = "Client Updated Successfully"
redirect_to external_client_path(@client)
else
render 'edit'
end
}
format.js
end
end
private
def client_params
params.require(:client).permit(:uuid, :company, :first_name, :last_name, :phone, :email, :address1, :address2, :city, :state, :zip, :notes)
end
def client_only
redirect_to root_path unless current_user.is_client?
end
end
plein ability.rb
class Ability
include CanCan::Ability
def initialize(user)
alias_action :show, :to => :view
alias_action :open_external_orders, :completed_external_orders, :to => :client_order_views
user ||= User.new
if user.has_role? :admin
can :manage, :all
can :assign_roles, User
else
can :read, :all
end
if user.has_role? :executive
can :manage, [Property, Deed, Mortgage, Order, Owner, Client, AttachedAsset, User]
cannot :assign_roles, User
end
if user.has_role? :management
can :manage, [Property, Deed, Mortgage, Order, Owner, Client, AttachedAsset]
can :read, User
can :manage, User, id: user.id
cannot :destroy, [Property, Order, Client, User]
end
if user.has_role? :analyst
can :manage, [Property, Deed, Mortgage, Order, Owner, Client, AttachedAsset]
can :manage, User, id: user.id
cannot :destroy, [Property, Order, Client, User]
end
if user.has_role? :it
can :manage, [Property, Deed, Mortgage, Order, Owner, Client, AttachedAsset]
can :manage, User, id: user.id
can :read, User
cannot :destroy, [Property, Order, Client, User]
end
if user.has_role? :client
can [:read, :update], Client, id: user.client_id
can [:read, :update, :client_order_views], [Property, Order], client_id: user.client_id
can [:read, :update], Owner
can :create, [Property, Order, Owner]
can :manage, User, id: user.id
end
end
end
Quelques choses d'abord: la variable '@ clients' dans les méthodes est en fait un' @ client', n'est-ce pas? (singulier, pas pluriel, s'il vous plaît changer cela), deuxième: ceci est déjà chargé via 'load_and_authorize_resource', alors pourquoi le recharger? Pouvez-vous également poster le reste de votre capacité.rb? merci – coorasse
J'ai effectivement remarqué qu'en passant par les docs la nuit dernière, j'avais déjà construit la plupart des contrôleurs et tel avant que j'implémente CanCan et je suppose que je n'ai jamais changé, mais l'ai fait maintenant. J'ai parcouru toutes mes vues et changé '@ clients' en' @ client' et j'ai posté ma mise à jour 'external/clients_controller.rb' ainsi que mon full' ability.rb'. Merci de m'avoir aidé. –
Vous avez une règle qui stipule qu'un utilisateur 'peut: read,: all' si ce n'est pas un admin. Cela permettra à tous les utilisateurs non administrateurs de lire tous les modèles. – coorasse