#20 Restricting Access
En el episodio anterior, vimos como crear links para las acciones create, edit y destroy del sitio web de ASCIIcasts. Los links funcionaban, pero de una manera bastante permisiva con usuarios públicos.
La página del listado de episodios con links para administración visibles por todos los usuarios.
Lo que tenemos que hacer es restringir los links para que solo puedan ser vistos por usuarios que tengan permisos para editar episodios. Vamos a editar nuestro partial para episodios para que renderice solamente los links edit
y destroy
, si un método llamado admin?
devuelve true (haremos lo mismo con el link new
, pero no mostraremos el código aquí.)
<li> <p class="episodeId"><%= episode.episode_id %></p> <h3><%= link_to episode.title, episode_path(episode.identifier) %></h3> <p class="summary"><%= episode.summary %></p> <p class="tagList"> Tags: <% episode.tags.each do |tag| %><%= link_to tag.title, tag_path(tag.title) %><% end %> </p> <% if admin? %> <p class="adminActions"> <%= link_to "Edit", edit_episode_path(episode) %> <%= link_to "Destroy", episode_path(episode), :confirm => "Are you sure?", :method => :delete %> </p> <% end %> </li>
El partial de episodio con la verificación admin? encerrando los links edit
y destroy
.
A continuación, necesitaremos escribir el método admin?
, ¿pero dónde deberíamos colocarlo?. Como estamos llamando al método desde la vista, obviamente, por consiguiente lo tendremos que colocar en el archivo helper de la aplicación. Pero, ¿si también quisiéramos que fuera accesible por los controladores?. Entonces, mejor lo vamos a colocar en el controlador de aplicación.
class ApplicationController < ActionController::Base helper_method :admin? protected def admin? false end end
El método admin?
Agregado al ApplicationController
.
Por ahora, nuestro método admin?
solamente va a devolver false
, (vamos a terminar de implementarlo en el siguiente episodio). Como también vamos a querer utilizarlo en nuestras vistas, hemos utilizado el método helper_method
que lo hace visible desde el código de las vistas.
Casi terminamos
Ahora que ya hemos escrito nuestro método admin?
, nuestros links están ocultos para usuarios que no son administradores. Aunque, todavía nos queda un problema: cualquier persona puede entrar a las páginas de administración y agregar o borrar episodios. Lo vamos a resolver utilizando un before_filter
.
class EpisodesController < ApplicationController before_filter :authorize, :except => [:index, :show ] def index @episodes = Episode.find(:all) end # show, new, create, edit, update and destroy methods hidden. end
El controlador de episodios sin los cuerpos de los métodos.
El before_filter
de arriba, va a ejecutar un método llamado authorize
antes que cada método de nuestro controlador sea llamado. Lo vamos a colocar en el controlador de aplicación para que esté disponible para todos los controladores.
class ApplicationController < ActionController::Base helper_method :admin? protected def admin? false end def authorize unless admin? flash[:error] = “Unauthorized access” redirect_to home_path false end end end
El controlador de Aplicación con el método authorize
.
El método revisa que el usuario sea un administrador, de lo contrario, muestra un método flash y redirecciona a la página principal. Finalmente, devuelve false
para que ninguna otra acción sea ejecutada. Ahora, si intentamos visitar la página nuevo episodio vamos a ser redireccionados a la página principal. De manera alternativa, si no quisiéramos que usuarios sin autorización sepan que la página existe, podríamos mostrar un error 404 (Página no encontrada).
#TODO:
Nuestro sistema de administración está casi terminado pero, todavía, tenemos que implementar el método admin?
. Vamos a mostrarle como hacerlo en el siguiente episodio.