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