#20 Restricting Access
Restrigindo acesso
No último episódio, criamos links para criar, editar e apagar episódios no site ASCIIcasts. Os links funcionam, mas, um pouco bem demais, pois podem ser clicados por quem visita o site.
A página de listas de epsódios, com os links de admini visível para todos os usuários.
O que temos que fazer é restringir os links somente para aqueles usuários que têm permissão para editar os episódios. Vamos editar o nosso episódio parcial apenas para renderiza a edição
e destruição
dos links se um método chamado for admin?
retornar verdadeiro. (Nós vamos fazer o mesmo com o novo link, mas não mostra o código aqui.)
<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>
O episódio com os parciais admin?
verificar o envolvimento de edição e destruir dos links.
Em seguida, precisamos escrever o método admin?
, mas onde ela deve ir? Como estamos chamando o método de uma view, o local imediatamente óbvio está no arquivo application helper, mas gostaríamos que ele fosse disponível nos controllers também, então vamos colocar no application controller em vez disso.
class ApplicationController < ActionController::Base helper_method :admin? protected def admin? false end end
O método admin?
adicionado ao ApplicationController
.
Por enquanto, o nosso método admin?
, irá retornar falso
, (iremos aplicar totalmente no próximo episódio). Como também queremos usá-lo em nossas views, temos que utilizado o método helper_method
para torna disponível a partir do código da view.
Quase acabando
Agora nós temos que escrever nosso método admin?
, nossos links são escondidas dos usuários não-administrador. Há ainda um problema embora: alguém ainda pode visitar as páginas de administração direta e adicionar ou editar episódios dessa maneira. Podemos consertar isso usando um 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
No controlador de episódios (com o método bodies removido).
O before_filter
acima irá executar um método chamado authorize
antes de qualquer método em nosso controlador é chamado, exceto para os métodos de index
e show
. Agora é necessário escrever o método authorize
. Vamos colocá-lo no application controller, para que ele esteja disponível para todos os 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
No ApplicationController
, foi dicionado o método authorize
.
O método verifica se o usuário é um administrador, se não, mostra um método flash e redireciona para a página inicial. Por último ele retornará falso, para que nenhuma outra ação é executada. Agora, se tentarmos visitar a página do novo episódio seremos redirecionados para a página inicial. Como alternativa, se não quiser que os usuários não autorizados saibam que a página existe poderíamos jogar um erro 404 (página não encontrada) no lugar.
#TODO:
Nosso sistema de administração está quase lá, mas ainda necessitamos implementar o método admin?
. Iremos mostrar para você como fazer isso no próximo episódio.