pundit
DESCRIPTION
Pundit Simple Rails AuthorizationTRANSCRIPT
![Page 1: Pundit](https://reader033.vdocument.in/reader033/viewer/2022051314/557cb23ed8b42ab37c8b4701/html5/thumbnails/1.jpg)
Pundit simple Rails authorization
Ruby::AZ - July 15, 2014
Bruce White Software Ops developer [email protected]
![Page 2: Pundit](https://reader033.vdocument.in/reader033/viewer/2022051314/557cb23ed8b42ab37c8b4701/html5/thumbnails/2.jpg)
We Build Mobile App Systems
![Page 3: Pundit](https://reader033.vdocument.in/reader033/viewer/2022051314/557cb23ed8b42ab37c8b4701/html5/thumbnails/3.jpg)
Authorization vs Authentication
Today we’re talking about authorization
• Authentication is about who you are
• Authorization is about what you can do
• To work, authorization requires authentication (need to know who you are to determine what you can do)
![Page 4: Pundit](https://reader033.vdocument.in/reader033/viewer/2022051314/557cb23ed8b42ab37c8b4701/html5/thumbnails/4.jpg)
Rails Authorization: A Retrospective
• 10 years ago, in the beginning of The Enlightenment, authorization was a “roll your own” thing
• 4 years ago, CanCan shook the Rails world to the core
• A year ago, Pundit arrives on the scene
![Page 5: Pundit](https://reader033.vdocument.in/reader033/viewer/2022051314/557cb23ed8b42ab37c8b4701/html5/thumbnails/5.jpg)
Pundit The world’s foremost authority
• Written by Elabs
• Simple, uses pure Ruby classes
• Popular and well maintained
• Second most popular Rails authorization gem
![Page 6: Pundit](https://reader033.vdocument.in/reader033/viewer/2022051314/557cb23ed8b42ab37c8b4701/html5/thumbnails/6.jpg)
Pundit Setup
• Include in Gemfile
• Optionally run generator
• Include in ApplicationControllerclass ApplicationController < ActionController::Base include Pundit protect_from_forgery after_action :verify_authorized, :except => :index after_action :verify_policy_scoped, :only => :index …
rails g pundit:install
gem "pundit"
![Page 7: Pundit](https://reader033.vdocument.in/reader033/viewer/2022051314/557cb23ed8b42ab37c8b4701/html5/thumbnails/7.jpg)
Policies
• Authorization in Pundit is controlled by Policy classes
• Policies go in app/policies
• Policies are PORC
![Page 8: Pundit](https://reader033.vdocument.in/reader033/viewer/2022051314/557cb23ed8b42ab37c8b4701/html5/thumbnails/8.jpg)
Policy Example
class PostPolicy < ApplicationPolicy … def update? user.admin? or not post.published? end …
![Page 9: Pundit](https://reader033.vdocument.in/reader033/viewer/2022051314/557cb23ed8b42ab37c8b4701/html5/thumbnails/9.jpg)
Pundit In Controllers
def update @post = Post.find(params[:id]) authorize @post if @post.update(post_params) redirect_to @post else render :edit end end
![Page 10: Pundit](https://reader033.vdocument.in/reader033/viewer/2022051314/557cb23ed8b42ab37c8b4701/html5/thumbnails/10.jpg)
Pundit In Views
<% if policy(@post).update? %> <%= link_to "Edit post", edit_post_path(@post) %> <% end %>
![Page 11: Pundit](https://reader033.vdocument.in/reader033/viewer/2022051314/557cb23ed8b42ab37c8b4701/html5/thumbnails/11.jpg)
Pundit Scopes
class PostPolicy < ApplicationPolicy class Scope < Scope def resolve if user.admin? scope.all else scope.where(:published => true) end end end …
![Page 12: Pundit](https://reader033.vdocument.in/reader033/viewer/2022051314/557cb23ed8b42ab37c8b4701/html5/thumbnails/12.jpg)
Pundit Scopes In Controllers
def index @posts = policy_scope(Post) end
![Page 13: Pundit](https://reader033.vdocument.in/reader033/viewer/2022051314/557cb23ed8b42ab37c8b4701/html5/thumbnails/13.jpg)
Pundit Scopes In Views
<% policy_scope(@user.posts).each do |post| %> <p> <% link_to post.title, post_path(post) %> </p> <% end %>
![Page 14: Pundit](https://reader033.vdocument.in/reader033/viewer/2022051314/557cb23ed8b42ab37c8b4701/html5/thumbnails/14.jpg)
Pundit Strong Parameters 1/2
class PostPolicy < ApplicationPolicy … def permitted_attributes if user.admin? || user.owner_of?(post) [:title, :body, :tag_list] else [:tag_list] end end …
![Page 15: Pundit](https://reader033.vdocument.in/reader033/viewer/2022051314/557cb23ed8b42ab37c8b4701/html5/thumbnails/15.jpg)
Pundit Strong Parameters 2/2
class PostsController < ApplicationController … private !
def post_params params.require(:post).permit( *policy(@post || Post).permitted_attributes ) end …
![Page 16: Pundit](https://reader033.vdocument.in/reader033/viewer/2022051314/557cb23ed8b42ab37c8b4701/html5/thumbnails/16.jpg)
Pundit with an API 1/4custom Pundit users
class APIController < ActionController::Base … !
private !
def pundit_user current_device end …
![Page 17: Pundit](https://reader033.vdocument.in/reader033/viewer/2022051314/557cb23ed8b42ab37c8b4701/html5/thumbnails/17.jpg)
Pundit with an API 2/4custom Pundit users
class APIController < ActionController::Base … Context = Struct.new(:app, :device, :app_instance, :user) … private !
def pundit_user Context.new( current_app, current_device, current_app_instance, current_user ) end …
![Page 18: Pundit](https://reader033.vdocument.in/reader033/viewer/2022051314/557cb23ed8b42ab37c8b4701/html5/thumbnails/18.jpg)
Pundit with an API 3/4custom Pundit users
AppInstancePolicy < ApplicationPolicy … def update? app_instance == current.app_instance end …
![Page 19: Pundit](https://reader033.vdocument.in/reader033/viewer/2022051314/557cb23ed8b42ab37c8b4701/html5/thumbnails/19.jpg)
Pundit with an API 4/4
class DeliveriesController < APIController … def cancel @delivery = Delivery.find(params[:id]) authorize @delivery @delivery.cancel !
respond_with @delivery end …
![Page 20: Pundit](https://reader033.vdocument.in/reader033/viewer/2022051314/557cb23ed8b42ab37c8b4701/html5/thumbnails/20.jpg)
Pundit Is PORC
You can:
• Encapsulate a set of permissions into an included module
• Use alias_method to make permissions behave the same
• Inherit from a base set of permissions
• Use metaprogramming
![Page 21: Pundit](https://reader033.vdocument.in/reader033/viewer/2022051314/557cb23ed8b42ab37c8b4701/html5/thumbnails/21.jpg)
Questions?