Uso de Declarative_Authorization para limitar los resultados en el modelo
-
28-10-2019 - |
Pregunta
Estoy utilizando la GEM de autorización declarativa para permisos en un proyecto Rails y estoy tratando de limitar la salida del modelo basado en los permisos de usuario.
Mi archivo de autorización abreviado se ve así:
roles do
role :supervisor
has_permission_on :people, :to => :manage_all
end
role :basic_user
has_permission_on :people, :to => :manage_subordinates
end
end
privileges do
privilege :manage_subordinates do
includes :subordinate_records
end
privilege :manage_all do
includes :all_records
end
end
En mi modelo de gente, tengo un método estático que quiero lucir así
def self.supervised_by(user)
if user.permitted_to? :all_records
#return all of the records
elsif user.permitted_to? :subordinate_records
#return some of the records
else
#return none of the records
end
end
Parece que hay soporte para esto utilizando el objeto AuthorizationInModel en la documentación usando with_permissions_to o permitido_to. No he podido descubrir cómo usar esas funciones en función de la documentación o cómo devolver una lista de los privilegios del usuario actual en el modelo actual.
¿Algunas ideas?
Solución
Encontré una solución alternativa utilizando el método IF-Attribute integrado. Originalmente me alejé de él porque estaba usando modelos sin nombre de nombres y controladores y vistas con nombres. Esta estructura es un artefacto de la versión original del proyecto en el que estoy trabajando. La mayor parte de mi trabajo ha recibido una autorización declarativa para tratar esta estructura.
La principal información que no me fue clara fue cómo nombrar los permisos en un entorno parcialmente lleno de nombres. El modelo esperaba el nombre del modelo (: personas), el controlador esperaba el espacio de nombres y el modelo (: staff_people), y las vistas no les importaba mientras eligiera uno. La solución que elegí fue usar el nombre del modelo y establecer explícitamente el contexto en cada controlador. Si el contexto no se establece en el controlador, usar filtre_access_to no funciona porque buscaría el permiso del personal_people en lugar del permiso correcto, las personas.
En el archivo de configuración de autorización declarativa, estoy dando permisos completos a la administración y permisos parciales al supervisor. persona. Supervised Devuelve una matriz de sí misma y de todas las demás personas supervisadas.
roles do
role :administrator
has_permission_on :people, :to => [:create, :read, :update, :delete]
end
role :supervisor
has_permission_on :people do
to => [:create, :read, :update, :delete]
if_attribute :id => is_in { Person.find_by_user_id(user.id).supervised }
end
end
end
Para acceder a esta información en un controlador lleno de nombres, estoy usando filer_resource_access.
module Staff
class PeopleController < ApplicationController
filter_resource_access :context => :people
def index
@people = People.with_permissions_to(:read)
end
Encontré que usando
filter_access_to :all, :with_attribute => true
no funcionó para los métodos que necesitan usar with_permissions_to y un permiso de IF_ATtribute. No estoy seguro de por qué esto fue un problema
Todavía es necesario usar filter_access_to para acciones del controlador no estándar que no incluyan una identificación que obtenga un solo registro como parte de los argumentos. Por ejemplo, si una acción llamada Part_Timers devuelve una lista de personas, esta solución parece que debería funcionar:
filter_resource_access :context => :people, :additional_member => { :part_timers => :read }
La solución correcta es mantener el filtro_resource_access tal cual y agregar un filtro_access_to para esa acción
filter_resource_access :context => :people
fitler_access_to :part_timers, :required => :read, :context => people
Otros consejos
Puede haber una mejor manera de hacer esto, pero esto debería funcionar para su supervised_by
Método si todo lo demás está configurado correctamente.
def self.supervised_by(user)
if Person.new.permitted_to? :all_records, :user=>user
#return all of the records
elsif Person.new.permitted_to? :subordinate_records, :user=>user
#return some of the records
else
#return none of the records
end
end