On Github EtienneDepaulis / lyonrb_lt_pundit
LyonRB lightning talks / @EtienneDepaulis
AuthorizeObjectService.new(user).can_write?(contract_from_user) # => true/false
BudgetLogicService.new(budget).can_update? # => true/false
alias_action :create, :update, :destroy, :to => :write service = AuthorizeObjectService.new(user) can :write, Budget do |budget| service.can_write?(budget) end
alias_action :create, :update, :destroy, :to => :write service = AuthorizeObjectService.new(user) can :write, Budget do |budget| service.can_write?(budget) end cannot [:update, :destroy], Budget do |budget| !BudgetAbilitiesService.new(budget).can_update? end ...
BudgetLogicService.new(budget).permitted_attributes # => [:id, :status, ...]
class ApplicationPolicy attr_reader :user, :record def initialize(user, record) @user = user @record = record end def index? ; true; end def show? ; false; end def create? ; false; end alias_method :new?, :create? ... end
def user_index? ; true; end def user_show? ; false; end def method_missing(method_sym, *arguments, &block) # to only catch create? and not user_create? (avoiding ∞ loops) if method_sym.to_s !~ /^user_/ && method_sym.to_s =~ /^(.*)*\?$/ return true if user.admin? public_send("user_#{method_sym}", *arguments) else false # by default, nothing is authorized end end
def create @budget = Budget.new(budget_params) @budget.creator = current_user authorize @budget end
class BudgetPolicy < ApplicationPolicy def user_show? can_read? end def user_create? can_write? end alias_method :user_new?, :user_create? end
class BudgetPolicy < ApplicationPolicy Scope = Struct.new(:user, :scope) do def resolve return scope if user.power? AuthorizeScopeService.new(user, scope).call.collection end end end
@budgets = policy_scope(Budget)
describe UserPolicy do subject { UserPolicy.new(current_user, object) } context "for a lambda user" do let(:current_user) { build_stubbed :user } let(:object) { build_stubbed :user } permits :none end context "for himself" do let(:current_user) { build_stubbed :user } let(:object) { current_user } permits [:edit, :update] end context "for a power user" do let(:current_user) { build_stubbed :power_user } permits :all end end
http://thunderboltlabs.com/blog/2013/03/27/testing-pundit-policies-with-rspec/
team@per-angusta.com
CreateUserService.new(@user).call
def create # initiate the service if success # send an email redirect_to users_path, success: "You rock !" else redirect_to users_path, error: "You suck ..." end end