2010-01-29 16 views
5

He estado leyendo sobre cuestiones de seguridad de los raíles y el que más me preocupa es la asignación masiva. Mi aplicación está haciendo uso de attr_accessible, sin embargo, no estoy seguro si sé exactamente cuál es la mejor forma de manejar las relaciones expuestas. Supongamos que tenemos un sitio web básico de creación/propiedad de contenido. Un usuario puede crear publicaciones de blog y tener una categoría asociada a esa publicación de blog.rails: preocupación por la seguridad de asignación de masa con relationships_to relationships

así que tengo tres modelos:

  • usuario
  • mensaje: pertenece a un usuario y una categoría
  • categoría: pertenece al usuario

I permitir la asignación masiva en el id_categoría, por lo que el usuario podría anularlo, c colgarlo en una de sus categorías, o mediante la asignación masiva, supongo que podrían cambiarlo a la categoría de otra persona. Ahí es donde no estoy seguro de cuál sería la mejor manera de proceder.

los recursos que han investigado (particularmente railscast #178 y una resource que se proporcionó a partir de ese Railscast), ambos mencionar que la asociación no debe ser masa asignable, que tiene sentido. Simplemente no estoy seguro de qué otra manera permitir al usuario cambiar lo que la categoría de la publicación sería de una manera railsy.

¿Alguna idea sobre la mejor manera de resolver esto? ¿Lo estoy mirando de la manera incorrecta?

ACTUALIZACIÓN: Espero aclarar mi preocupación un poco más.

Digamos que estoy en Post, debo tener algo como lo siguiente:

def create 
    @post = Post.new(params[:category]) 

    @post.user_id = current_user.id 

    # CHECK HERE IF REQUESTED CATEGORY_ID IS OWNED BY USER 

    # continue on as normal here 
end 

Eso parece mucho trabajo? Tendría que verificarlo en cada controlador tanto en la actualización como en la acción de creación. Tenga en cuenta que hay más de una relación belongs_to.

Respuesta

0

OK, por lo buscado un poco, y finalmente se me ocurrió algo viable para mí.Me gusta mantener la lógica de los controladores cuando sea posible, por lo que esta solución es una solución basada en el modelo:

# Post.rb 
validates_each :asset_category_id do |record, attr, value| 
    self.validates_associated_permission(record, attr, value) 
end 

# This can obviously be put in a base class/utility class of some sort. 
def self.validates_associated_permission(record, attr, value) 
    return if value.blank? 
    class_string = attr.to_s.gsub(/_id$/, '') 
    klass = class_string.camelize.constantize 

    # Check here that the associated record is the users 
    # I'm leaving this part as pseudo code as everyone's auth code is 
    # unique. 
    if klass.find_by_id(value).can_write(current_user) 
    record.errors.add attr, 'cannot be found.' 
    end 
end 

También encontré que los carriles 3.0 tendrá una mejor manera de especificar esto en vez de las 3 líneas requeridas para el ultra generic validates_each.

http://ryandaigle.com/articles/2009/8/11/what-s-new-in-edge-rails-independent-model-validators

+0

Otra respuesta fue muy útil, pero esto es lo que realmente resolvió mi problema, por lo tanto lo estoy aceptando. – dpb

5

Su usuario puede cambiarlo a través de un formulario de edición de algún tipo, supongo.

Basado en eso, Mass Assignment es realmente para tipos nefastos que buscan meterse con su aplicación a través de cosas como curl. Los llamo niños rizos.

Todo lo que quiere decir, si usa attr_protected - (aquí pone los campos que no desea que cambien) o el favorito attr_accessible (los campos que están OK para cambiar).

Usted escuchará argumentos para ambos, pero si se utiliza attr_protected :user_id en su modelo, y luego en sus CategoryController # crear una acción que puede hacer algo como

def create 
    @category = Category.new(params[:category]) 

    @category.user_id = current_user.id 
    respond_to do |format| 
....#continue on as normal here 
end 
+0

Gracias @pjammer. Estoy particularmente interesado en el ejemplo anterior. Lo que has escrito es correcto, pero estoy más interesado en el belongs_to de Publicar en Categoría. Ya tengo algo así (aunque lo tengo en el modelo) para el usuario_actual en Publicaciones y Categoría. – dpb

Cuestiones relacionadas