Sto usando cancan per autorizzare le azioni del mio controller. Una delle classi in cui l'accesso è autorizzato da cancan è un albero, implementato con acts_as_ancestry. Sto riscontrando problemi nell'uso di load_and_authorize_resource
quando l'utente non è autorizzato ad accedere al livello di root, ma è consentito l'accesso a partire da un nodo interno.Come posso impostare una relazione ancestrale con cancan su un nodo interno dell'albero?
Ecco alcune definizioni di classe relavant:
class User < ActiveRecord::Base
belongs_to :organization, :inverse_of => :users
end
class Post < ActiveRecord::Base
belongs_to :organization, :inverse_of => :posts
end
class Organization < ActiveRecord::Base
has_ancestry :cache_depth => true
has_many :users, :inverse_of => :organization
has_many :posts, :inverse_of => :organization
end
Le regole per la gestione dei messaggi sono "È possibile gestire i messaggi in qualsiasi organizzazione sotto la vostra". Il mio cancan definizione abilità è questa:
class Ability
include CanCan::Ability
def initialize(user)
user ||= User.new
# subtree_ids is added by acts_as_ancestry
can :manage, Post, {:organization_id => user.organization.subtree_ids}
end
end
Nel controllore, ho questo (altre azioni omesso)
class PostsController < ApplicationController
load_and_authorize_resource :post
def index
end
def new
end
end
Tutto funziona bene quando l'utente autorizzato appartiene all'organizzazione root. Tuttavia, quando accedo come utente autorizzato su un nodo interno, l'azione index funziona correttamente, ma quando viene richiamata la nuova azione, ottengo un errore di autorizzazione can can.
Ecco quello che vedo nel registro:
Access denied on new #<Post id: nil, organization_id: 1>
Il organization_id 1
(la radice) è venuta dallo schema:
create_table "posts", :force => true do |t|
t.integer "organization_id", :default => 1
end
Con Cancan, la nuova azione costruirà un nuovo Post
e assegnarlo a @post
. Quando esegue questa operazione, inizializzerà tutti gli attributi con i valori presi dalla definizione can
in Abilities.rb. Tuttavia, non farà nulla se quegli attributi sono Array, Hash o Ranges e il valore predefinito finisce sullo schema.
Come autorizzare gli utenti a gestire i post nella loro sottostruttura, ma quando creano un nuovo post, lo impostano automaticamente sulla loro organizzazione?
Così ho fatto il seguente progetto per testare il tuo problema ed è qui: https://github.com/robmathews/cancan_test.git – Rob