lib/pundit/resource.rb in pundit-resources-1.0.0 vs lib/pundit/resource.rb in pundit-resources-1.0.1
- old
+ new
@@ -12,59 +12,75 @@
module ClassMethods
def records(options = {})
warn_if_show_defined
context = options[:context]
+ context[:policy_used]&.call
Pundit.policy_scope!(context[:current_user], _model_class)
end
private
def warn_if_show_defined
policy_class = Pundit::PolicyFinder.new(_model_class.new).policy!
- if policy_class.method_defined?(:show?)
+ if policy_class.instance_methods(false).include?(:show?)
puts "WARN: pundit-resources does not use the show? action."
puts " #{policy_class::Scope} will be used instead."
end
end
end
protected
+ def can(method)
+ context[:policy_used]&.call
+ policy.public_send(method)
+ end
+
def current_user
context&.[](:current_user)
end
def policy
Pundit.policy!(current_user, _model)
end
def authorize_create_or_update
action = _model.new_record? ? :create : :update
- not_authorized!(action) unless policy.public_send(:"#{action}?")
+ not_authorized!(action) unless can :"#{action}?"
end
def authorize_destroy
- not_authorized! :destroy unless policy.destroy?
+ not_authorized! :destroy unless can :destroy?
end
def records_for(association_name, options={})
- association_reflection = _model.class.reflect_on_association(association_name)
+ relationships = self.class._relationships.
+ values.
+ select { |r| r.relation_name(context: @context) == association_name }.
+ uniq(&:class)
- if association_reflection.macro == :has_many
+ unless relationships.count == 1
+ raise "Can't infer relationship type for #{association_name}"
+ end
+
+ relationship = relationships.first
+
+ case relationship
+ when JSONAPI::Relationship::ToMany
records = _model.public_send(association_name)
policy_scope = Pundit.policy_scope!(
context[:current_user],
- association_reflection.class_name.constantize
+ records
)
records.merge(policy_scope)
- elsif [:has_one, :belongs_to].include?(association_reflection.macro)
+ when JSONAPI::Relationship::ToOne
record = _model.public_send(association_name)
# Don't rely on policy.show? being defined since it isn't used for
# show actions directly and should always have the same behaviour.
- if record && show?(Pundit.policy!(context[:current_user], record))
+ if record && show?(Pundit.policy!(context[:current_user], record), record.id)
record
else
nil
end
end
@@ -75,10 +91,10 @@
def not_authorized!(action)
options = { query: action, record: _model, policy: policy }
raise Pundit::NotAuthorizedError, options
end
- def show?(policy)
- policy.scope.where(id: policy.record.id).exists?
+ def show?(policy, record_id)
+ policy.scope.where(id: record_id).exists?
end
end
end