Autorización de acciones
¡Entra CanCan!
CanCanCan es el estándar para desarrollar sistemas que requieren autorización en el mundo de RoR, es una gema bastante popular y sin duda muy útil. Comenzaremos con instalarla, como es usual, abre Gemfile y añadela:
# Gemfile
gem 'cancancan', '~> 1.10'
A continuación, corre el comando bundle:
$ bundle
Ahora que tenemos CanCan instalada, debemos generar una clase “Ability” usando CanCan, por lo tanto desde tu terminal escribe:
$ rails g cancan:ability
Un nuevo archivo se abra creado en tu directorio de modelos, ábrelo y haremos los primeros cambios:
class Ability
include CanCan::Ability
def initialize(user)
if user.has_role? :admin
can :manage, :all
else
can :read, :all
can :create, :all
end
can :update, Fact do |fact|
fact.user == user
end
can :destroy, Fact do |fact|
fact.user == user
end
end
end
Puede verse un poco aterrador pero esto es lo que esta sucediendo:
- Si el usuario tiene el rol de admin, puede manejar todos los recursos a su antojo (crear, editar, eliminar…). Como podrás darte cuenta aún no tenemos roles, ¡lo configuraremos en un momento!
- Si el mismo usuario que esta logeado es el que creo un Fact, puede editarlo o eliminarlo, no sería divertido que otras personas eliminaran tus Facts sin tu consentimiento.
Necesitamos usar CanCan en nuestro controlador, por lo tanto ábrelo y añade la linea:
# facts_controller.rb
load_and_authorize_resource :except => [:index, :show]
Esto viene de la documentación de CanCan, lo que hacemos es verificar si el usuario tiene los privilegios para hacer cualquier cosa excepto en los métodos Index y Show (todos pueden ver los facts).
Como tenemos todo hasta ahora, si los usuarios visitan una acción que no pueden realizar les aparecerá un error muy grande de Rails diciendoles que no pueden hacer eso, buscamos redirigirlos al index de nuestra página y mostrarles el error en su lugar.
# application_controller.rb
rescue_from CanCan::AccessDenied do |exception|
redirect_to root_path, :alert => exception.message
end
Ahora solo falta validar quienes pueden ver los botones para editar o eliminar un fact. Esto se realiza de la siguiente forma:
<% if can? :METODO, @MODELO %>
...
<% end %>
Por lo tanto nuestras dos acciones (editar y eliminar) quedarían así:
<% if can? :update, @fact %>
<%= link_to "Edit fact", edit_fact_path(@fact), class: "ui teal small button" %>
<% end %>
<% if can? :destroy, @fact %>
<%= link_to "Delete", edit_fact_path(@fact), method: :delete, data: {confirm: "Are you sure?"}, class: "ui red small button" %>
<% end %>
Finalmente nuestra vista quedaría así:
Roles utilizando Rolify
Como te podrás haber dado cuenta ya, en Ruby existe una gema para casi todo lo que se te ocurra, el caso de roles no es una excepción. Usaremos Rolify para administrar nuestros roles.
Instala la gema como es usual, en Gemfile añadela y luego corre bundle:
# Gemfile
gem "rolify"
Terminal:
$ bundle
Ahora, debemos generar el rol de usuario:
$ rails g rolify Role User
Corremos migraciones:
$ rails db:migrate
Ahora en nuestro modelo de Facts añade:
resourcify
Ahora en nuestra terminal dirigirte al directorio donde tienes el proyecto y abre la consola con:
$ rails c
Finalmente, si tienes una cuenta creada usa su id para darte el rol de administrador:
user = User.find(1)
user.add_role :admin
¡Todo debería estar funcionando ahora! En el próximo artículo crearemos los comentarios.