lib/pragma/policy/base.rb in pragma-policy-0.1.0 vs lib/pragma/policy/base.rb in pragma-policy-2.0.0

- old
+ new

@@ -1,43 +1,63 @@ # frozen_string_literal: true + module Pragma module Policy - # This is the base policy class that all your resource-specific policies should inherit from. + # This is the base policy class that all your record-specific policies should inherit from. # # A policy provides predicate methods for determining whether a user can perform a specific - # action on a resource. + # action on a record. # # @author Alessandro Desantis # # @abstract Subclass and implement action methods to create a policy. class Base - # @!attribute [r] user - # @return [Object] the user operating on the resource + # Authorizes AR scopes and other relations by only returning the records accessible by the + # current user. Used, for instance, in index operations. # - # @!attribute [r] resource - # @return [Object] the resource being operated on - attr_reader :user, :resource + # @author Alessandro Desantis + class Scope + # @!attribute [r] user + # @return [Object] the user accessing the records + # + # @!attribute [r] scope + # @return [Object] the relation to use as a base + attr_reader :user, :scope - # Returns the records accessible by the given user. - # - # @param user [Object] the user accessing the records - # @param relation [Object] the relation to use as a base - # - # @return [Object] - # - # @abstract Override to implement retrieving the accessible records - def self.accessible_by(user, relation:) # rubocop:disable Lint/UnusedMethodArgument - fail NotImplementedError + # Initializes the scope. + # + # @param user [Object] the user accessing the records + # @param scope [Object] the relation to use as a base + def initialize(user, scope) + @user = user + @scope = scope + end + + # Returns the records accessible by the given user. + # + # @return [Object] + # + # @abstract Override to implement retrieving the accessible records + def resolve + fail NotImplementedError + end end + # @!attribute [r] user + # @return [Object] the user operating on the record + # + # @!attribute [r] record + # @return [Object] the record being operated on + attr_reader :user, :record + # Initializes the policy. # - # @param user [Object] the user operating on the resource - # @param resource [Object] the resource being operated on - def initialize(user:, resource:) + # @param user [Object] the user operating on the record + # @param record [Object] the record being operated on + def initialize(user, record) @user = user - @resource = resource + @record = record end # Returns whether the policy responds to the provided missing method. # # Supports bang forms of predicates (+create!+, +update!+ etc.). @@ -69,69 +89,20 @@ # # @raise [ArgumentError] if the action is not defined in this policy # @raise [ForbiddenError] if the user is not authorized to perform the action def authorize(action) unless respond_to?("#{action}?") - fail( - ArgumentError, - "'#{action}' is not a valid action for this policy." - ) + fail(ArgumentError, "'#{action}' is not a valid action for this policy.") end return if send("#{action}?") fail( - ForbiddenError, + NotAuthorizedError, user: user, action: action, - resource: resource + record: record ) - end - - protected - - # Authorizes a resource attribute. - # - # @param attribute [Symbol] the name of the attribute - # @param options [Hash] options (see {AttributeAuthorizer#authorize} for allowed options) - # - # @return [Boolean] whether the attribute's value is allowed - def authorize_attr(attribute, options = {}) - AttributeAuthorizer.new( - resource: resource, - attribute: attribute - ).authorize(options) - end - end - - # This error is raised when a user attempts to perform an unauthorized operation on a - # resource. - # - # @author Alessandro Desantis - class ForbiddenError < StandardError - MESSAGE = "User is not authorized to perform the '%{action}' action on this resource." - - # @!attribtue [r] user - # @return [Object] the user operating on the resource - # - # @!attribute [r] action - # @return [Symbol] the attempted action - # - # @!attribute [r] resource - # @return [Object] the resource being operated on - attr_reader :user, :action, :resource - - # Initializes the error. - # - # @param user [Object] the user operating on the resource - # @param action [Symbol] the attempted action - # @param resource [Object] the resource being operated on - def initialize(user:, action:, resource:) - @user = user - @action = action.to_sym - @resource = resource - - super MESSAGE.gsub('%{action}', action.to_s) end end end end