Module: BetterService::Concerns::Serviceable::Authorizable
- Extended by:
- ActiveSupport::Concern
- Included in:
- Services::Base
- Defined in:
- lib/better_service/concerns/serviceable/authorizable.rb
Overview
Authorizable adds authorization support to services.
Use the authorize_with DSL to define authorization logic that runs BEFORE the search phase (fail fast principle).
The authorization block has access to:
-
user: The current user object
-
params: The validated parameters
If authorization fails (block returns false/nil), the service stops immediately and raises AuthorizationError with code :unauthorized.
Example:
class Product::UpdateService < BetterService::UpdateService
do
user.admin? || product_belongs_to_user?
end
def product_belongs_to_user?
Product.find(params[:id]).user_id == user.id
end
end
Works with any authorization library (Pundit, CanCanCan, custom):
# Pundit style
do
ProductPolicy.new(user, resource).update?
end
# CanCanCan style
do
Ability.new(user).can?(:update, :product)
end
# Custom logic
do
user.has_role?(:editor) && params[:status] != 'published'
end
Instance Method Summary collapse
-
#authorize! ⇒ void
Execute authorization check if defined.
Instance Method Details
#authorize! ⇒ void
This method returns an undefined value.
Execute authorization check if defined.
Runs the authorization block defined with authorize_with. Has access to user and params.
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 |
# File 'lib/better_service/concerns/serviceable/authorizable.rb', line 85 def return unless self.class. = instance_exec(&self.class.) return if # Raise AuthorizationError instead of returning hash raise Errors::Runtime::AuthorizationError.new( "Not authorized to perform this action", code: ErrorCodes::UNAUTHORIZED, context: { service: self.class.name, user: user&.id || "nil", params: @params } ) end |