Submitted by
(... press space for next slides ...)
Pundit Gem - Minimal authorization through OO design and pure Ruby classes.
It is a really simple Ruby Gem, that does nothing more that you could have done yourself. Here is the power!
Pundit set some helpers to :
gem "pundit"
Include Pundit in your application controller:
class ApplicationController < ActionController::Base include Pundit protect_from_forgery end
Application Controller
class ApplicationController < ActionController::Base
# Includes Authorization mechanism
include Pundit
# Prevent CSRF attacks by raising an exception.
# For APIs, you may want to use :null_session instead.
protect_from_forgery with: :exception
# Globally rescue Authorization Errors in controller.
# Returning 403 Forbidden if permission is denied
rescue_from Pundit::NotAuthorizedError, with: :permission_denied
private
def permission_denied
head 403
end
end
Optionally, you can run the generator, which will set up an application policy with some useful defaults for you:
rails g pundit:install
Policy are placed in
app/policies/
class ApplicationPolicyattr_reader :user, :recorddef initialize(user, record)@user = user@record = recordenddef user_activities@user.roles.select(:activities).distinct.map(&:activities).flattenend
def scope
Pundit.policy_scope!(user, record.class)
end
end
class PostPolicy < ApplicationPolicy
attr_reader :user, :post
def initialize(user, post)
@user = user
@post = post
end
def update?
user.admin? or not post.published?
end
end
Supposing that you have an instance of class Post, Pundit now lets you do this in your controller:
def update
@post = Post.find(params[:id])
authorize @post
if @post.update(post_params)
redirect_to @post
else
render :edit
end
end
class PostPolicy < ApplicationPolicy
class Scope
attr_reader :user, :scope
def initialize(user, scope)
@user = user
@scope = scope
end
def resolve
if user.admin?
scope.all
else
scope.where(:published => true)
end
end
end
def update?
user.admin? or not post.published?
end
end
You can now use this class from your controller via the policy_scope method:
def index
@posts = policy_scope(Post)
end
There is a lot more out there
Make sure you check
[ https://github.com/elabs/pundit ]