Mejor manera de aplicar permisos: ¿controlador o restricción?

Tengo un plugin que agrega un modelo, server, el cual tiene un campo user_id. Quiero que solo el propietario del server pueda realizar una POST (o quizás debería ser un PUT? —la acción ejecutará una reconstrucción desde la línea de comandos de una instancia de Discourse en su servidor—; no estoy seguro de cuál sería la mejor práctica.)

En config/routes.rb está esto:

post “/upgrade/:id” => “servers#queue_upgrade”, constraints: PfaffmanagerConstraint.new

¿Se recomienda que matches? en pfaffmanager_constraint.rb verifique path_parameters[:action] y aplique el permiso allí, o hacerlo en servers_controller.rb?

Además, creo que lo que realmente debería hacer es mover esta ruta bajo namespace :user, por lo que quizás después de resolver eso, este problema se solucionará como parte de ese cambio. Sin embargo, esto casi funciona y me gustaría pasar a que otras personas prueben este código.

La ruta de Rails tiene esto:
https://github.com/pfaffman/discourse-pfaffmanager/blob/master/config/routes.rb#L12

Y mi controlador intenta aplicar los permisos:

https://github.com/pfaffman/discourse-pfaffmanager/blob/master/app/controllers/pfaffmanager/servers_controller.rb#L53-L70

Pero mi spec está devolviendo un 200 cuando otro usuario realiza el post:

https://github.com/pfaffman/discourse-pfaffmanager/blob/master/spec/requests/servers_controller_spec.rb#L149-L157

Supongo que necesito hacer que Ember preste atención a esto de alguna manera.

1 me gusta

¿No puedes pasar un método a before_action para verificar tu condición?

1 me gusta

Creo que los permisos deben aplicarse en el controlador o en las restricciones. El modelo no sabe quién lo está llamando, creo.

Muchas gracias por pensar en esto.

1 me gusta

Creo que necesitas un método de guardian para verificar si un usuario tiene permiso para realizar una acción determinada. Por ejemplo, can_upgrade_server?

Además, una vez que lo hagas, puedes usar el método guardian.ensure_can_upgrade_server!, que verifica la condición y lanza una excepción, lo cual creo que es exactamente lo que necesitas.

2 Me gusta

¡Oh, oh! ¡El método Guardian! ¡Sí! ¡Los miraré! Gracias.

2 Me gusta

El único modelo que utiliza guardian es el modelo de usuario. Parece que la mayor parte de la acción con guardian se encuentra en los controladores.

Por ejemplo, el controlador de categorías utiliza ensure_can_create_category, que creo que se crea de manera mágica en lib/guardian.rb.

Pero por ahora, no estoy usando guardian porque tengo dificultades para averiguar cómo instanciarlo correctamente. Tengo esto en mi controlador:

https://github.com/pfaffman/discourse-pfaffmanager/blob/master/app/controllers/pfaffmanager/servers_controller.rb#L54-L75

Y aquí están las pruebas que lo verifican:

https://github.com/pfaffman/discourse-pfaffmanager/blob/master/spec/requests/servers_controller_spec.rb#L154-L181