Ich verwende derzeit Devise, CanCan und Rolify zu handhaben Authentifizierung und Autorisierung für meine Rails App und ich habe eine wirklich harte Zeit zu verstehen, wie man es so macht dass ein user
nur :show
und :update
eine spezifische Instanz eines Modells, das der Benutzer gehört (aka meine user
hat eine client_id
Spalte, nicht umgekehrt).CanCanCan zeigen nur Instanz des Modells, dass Benutzer gehört
Das Update Teil meiner definiert Abilities.rb
für die user
mit der :client
Rolle arbeitet, fein, dh wenn current_user.client_id = 3
dann kann er nur einen Client aktualisieren, bei denen Client.id = 3
jedoch, dass gleiche Benutzer eine Instanz des Client
Modell sehen und ich Ich kann nicht begreifen, wie ich das begrenzen kann.
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
...
Jeder Benutzer hat keine index
alle Clients
, so dass nach der Erforschung ich can [:read, :update], Client, ..
-:show
geändert, aber die Benutzer können immer noch die anderen clients
aber das :update
Teil sehen, ob es funktioniert gut Ich bin hier wirklich ratlos. Ich habe die letzten paar Stunden gegoogelt und die gesamte CanCan-Dokumentation durchgelesen, von der ich anerkenne, dass sie vielleicht angesprochen wurde, aber ich kann es nicht herausfinden.
Ich habe versucht, es von der Steuerungsseite zu begrenzen, wie unten gezeigt, aber das nicht funktioniert, entweder:
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
Also, wenn jemand mir voll wie CanCan Griffe verstehen helfen könnte Rollenbasierte Autorisierung für eine Instanz eines Modells, dann würde ich es sehr schätzen. Danke im Voraus!
Aktualisiert-Code
Entfernt alle @client
Beispiel lädt in 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
voll 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
Ein paar Dinge zuerst: Die Variable @ Clients in den Methoden ist eigentlich ein @ Client, oder? (singular, nicht plural, bitte ändere das), zweitens: das wird schon über 'load_and_authorize_resource' geladen, also warum lädst du es nochmal? Kannst du auch den Rest deiner Fähigkeit posten? Rb? danke – coorasse
Ich bemerkte tatsächlich, dass durch die Docs letzte Nacht hatte ich bereits die meisten der Controller und so gebaut, bevor ich CanCan implementiert und ich glaube, ich habe es nie geändert, aber jetzt getan haben. Ich ging durch all meine Ansichten und änderte '@ clients' zu' @ client' und postete meine aktualisierte 'external/clients_controller.rb' sowie meine volle' fähigkeit.rb'. Danke, dass du mir geholfen hast. –
Sie haben eine Regel, die besagt, dass ein Benutzer "kann: lesen,: alle", wenn es kein Admin ist. Dadurch können alle Benutzer ohne Administratorrechte alle Modelle lesen. – coorasse