lib/pragma/operation/authorization.rb in pragma-operation-1.4.0 vs lib/pragma/operation/authorization.rb in pragma-operation-1.5.0
- old
+ new
@@ -12,33 +12,27 @@
module ClassMethods # :nodoc:
# Sets the policy to use for authorizing this operation.
#
# @param klass [Class] a subclass of +Pragma::Policy::Base+
- def policy(klass)
- @policy = klass
+ #
+ # @yield A block which will be called with the operation's context which should return
+ # the policy class. The block can also return +nil+ if authorization should be skipped.
+ def policy(klass = nil, &block)
+ if !klass && !block_given?
+ fail ArgumentError, 'You must pass either a policy class or a block'
+ end
+
+ @policy = klass || block
end
# Returns the policy class.
#
# @return [Class]
def policy_klass
@policy
end
-
- # Builds the policy for the given user and resource, using the previous defined policy
- # class.
- #
- # @param user [Object]
- # @param resource [Object]
- #
- # @return [Pragma::Policy::Base]
- #
- # @see #policy
- def build_policy(user:, resource:)
- policy_klass.new(user: user, resource: resource)
- end
end
module InstanceMethods # :nodoc:
# Builds the policy for the current user and the given resource, using the previously
# defined policy class.
@@ -48,28 +42,33 @@
# @return [Pragma::Policy::Base]
#
# @see .policy
# @see .build_policy
def build_policy(resource)
- self.class.build_policy(user: current_user, resource: resource)
+ policy_klass = compute_policy_klass
+ return resource unless policy_klass
+
+ policy_klass.new(user: current_user, resource: resource)
end
# Authorizes this operation on the provided resource or policy.
#
# If no policy was defined, simply returns true.
#
# @param authorizable [Pragma::Policy::Base|Object] resource or policy
#
# @return [Boolean] whether the operation is authorized
def authorize(authorizable)
- return true unless self.class.policy_klass
+ return true unless compute_policy_klass
- policy = if self.class.policy_klass && authorizable.is_a?(self.class.policy_klass)
+ # rubocop:disable Metrics/LineLength
+ policy = if Object.const_defined?('Pragma::Policy::Base') && authorizable.is_a?(Pragma::Policy::Base)
authorizable
else
build_policy(authorizable)
end
+ # rubocop:enable Metrics/LineLength
params.each_pair do |name, value|
next unless policy.resource.respond_to?("#{name}=")
policy.resource.send("#{name}=", value)
end
@@ -100,15 +99,24 @@
#
# @param collection [Enumerable]
#
# @return [Pragma::Decorator::Base|Enumerable]
def authorize_collection(collection)
- return collection unless self.class.policy_klass
+ policy_klass = compute_policy_klass
+ return collection unless policy_klass
- self.class.policy_klass.accessible_by(
+ policy_klass.accessible_by(
user: current_user,
scope: collection
)
+ end
+
+ def compute_policy_klass
+ if self.class.policy_klass.is_a?(Proc)
+ self.class.policy_klass.call(context)
+ else
+ self.class.policy_klass
+ end
end
end
end
end
end