Authorization with Pundit
Prevent unauthorized access to your application with Pundit; an authorization library for Ruby on Rails which restricts what resources a given user is allowed to access.
SummaryPrevent unauthorized access to your application with Pundit; an authorization library for Ruby on Rails which restricts what resources a given user is allowed to access.
class ApplicationController < ActionController::Base # Prevent CSRF attacks by raising an exception. # For APIs, you may want to use :null_session instead. include Pundit protect_from_forgery with: :exception rescue_from Pundit::NotAuthorizedError do redirect_to root_url, alert: 'You do not have access to this page' end end
<%= link_to 'Edit', edit_article_path(@article) if policy(@article).update? %> <%= link_to 'Delete', article_path(@article), method: :delete if policy(@article).destroy? %>
class ArticlePolicy < ApplicationPolicy class Scope < Scope def resolve scope.where(published: true).or(scope.where(user_id: @user.try(:id))) end end def new? ; user_is_owner_of_record? ; end def create? ; user_is_owner_of_record? ; end def show? user_is_owner_of_record? || @record.published end def update? ; user_is_owner_of_record? ; end def destroy? ; user_is_owner_of_record? ; end private def user_is_owner_of_record? @user == @record.user end end
class ArticlesController < ApplicationController before_action :authenticate_user!, except: :index before_action :set_article, only: [:show, :edit, :update, :destroy] after_action :verify_authorized, except: :index after_action :verify_policy_scoped, only: :index def index # @articles = Article.all # @articles = Article.where(published: true) @articles = policy_scope(Article).reverse end def show end def new @article = current_user.articles.new authorize @article end def edit end def create @article = current_user.articles.create(article_params) authorize @article if @article.save redirect_to @article, notice: 'Article was successfully created.' else render :new end end def update if @article.update(article_params) redirect_to @article, notice: 'Article was successfully updated.' else render :edit end end def destroy @article.destroy redirect_to articles_url, notice: 'Article was successfully destroyed.' end private def set_article @article = Article.find(params[:id]) authorize @article end def article_params params.require(:article).permit(:title, :user_id, :content, :published) end end