Authorization is determining if given user has access to given resource.
The term originates from the Sanskrit term pandit (paṇḍitá), meaning "learned". It refers to someone who is erudite in various subjects and who conducts religious ceremonies and offers counsel to the king.
Nowadays, a pundit (sometimes called a talking head) is a person who offers to mass media their opinion or commentary on a particular subject area on which they are knowledgeable (or can at least appear to be knowledgeable), or considered a scholar in said area.
class Ability
include CanCan::Ability
def initialize(user)
user ||= User.new
unless user.new_record?
can :comment, Part
can :rate, Part
cannot :rate, Part, :story => { :user => user }
can :comment, Article
can :comment, NewsPost
can :create, Story
can :update, User, :id => user.id
can :update, Story, :user => user
can :update, Part, :story => { :user => user, :status => Story::OPEN }
can :update, Part, :story => { :user => user, :story_type => Story::SINGLE }
cannot :add_fragment_to, Story, :story_type => Story::SINGLE
can :add_fragment_to, Story, :user => user, :status => Story::OPEN
end
if user.has_role?(:news_editor)
can :manage, NewsPost
end
if user.has_role?(:stories_editor)
can :manage, Story
can :manage, Part
end
if user.has_role?(:users_manager)
can :manage, User
end
if user.has_role?(:comments_editor)
can :manage, Comment
end
if user.has_role?(:articles_editor)
can :manage, Article
end
end
end
app/policies/document_policy.rb
class DocumentPolicy
attr_reader :user, :document
def initialize(user, document)
@user = user
@document = document
end
def view?
@document.user == user
end
end
user = current_user
document (resource) = any kind of ruby object
def show
@document = Document.find(params[:id])
@document_file = @document.last_file
authorize @document, :view?
if File.exists?(@document_file.file.path)
send_file @document_file.file.path, type: 'application/pdf',
disposition: 'inline'
else
render :file_not_found
end
end
# policy
class PostPolicy < ApplicationPolicy
def update?
user.admin? or not record.published?
end
end
# controller
def update
@post = Post.find(params[:id])
authorize @post
if @post.update(post_params)
redirect_to @post
else
render :edit
end
end
# Pundit
<% if policy(@post).update? %>
<%= link_to "Edit post", edit_post_path(@post) %>
<% end %>
# CanCan
<% if can? :update, @article %>
<%= link_to "Edit", edit_article_path(@article) %>
<% end %>
class ApplicationController < ActionController::Base
include Pundit
rescue_from Pundit::NotAuthorizedError, with: :permission_denied
def permission_denied
render 'shared/permission_denied'
end
end
This was (hopefully) a part of Gems 101 series, where we discuss how it's done without Framework and why it's better/worse way.