class JSONAPI::Authorization::AuthorizingProcessor

Public Instance Methods

authorize_create_resource() click to toggle source
# File lib/jsonapi/authorization/authorizing_processor.rb, line 127
def authorize_create_resource
  source_class = resource_klass._model_class
  authorizer.create_resource(
    source_class: source_class,
    related_records_with_context: related_models_with_context
  )
end
authorize_create_to_many_relationships() click to toggle source
# File lib/jsonapi/authorization/authorizing_processor.rb, line 170
def authorize_create_to_many_relationships
  source_record = @resource_klass.find_by_key(
    params[:resource_id],
    context: context
  )._model

  relationship_type = params[:relationship_type].to_sym
  related_models = model_class_for_relationship(relationship_type).find(params[:data])

  authorizer.create_to_many_relationship(
    source_record: source_record,
    new_related_records: related_models,
    relationship_type: relationship_type
  )
end
authorize_find() click to toggle source
# File lib/jsonapi/authorization/authorizing_processor.rb, line 51
def authorize_find
  authorizer.find(source_class: @resource_klass._model_class)
end
authorize_include_directive() click to toggle source
# File lib/jsonapi/authorization/authorizing_processor.rb, line 36
def authorize_include_directive
  return if result.is_a?(::JSONAPI::ErrorsOperationResult)
  resources = Array.wrap(
    if result.respond_to?(:resources)
      result.resources
    elsif result.respond_to?(:resource)
      result.resource
    end
  )

  resources.each do |resource|
    authorize_model_includes(resource._model)
  end
end
authorize_remove_resource() click to toggle source
# File lib/jsonapi/authorization/authorizing_processor.rb, line 135
def authorize_remove_resource
  record = @resource_klass.find_by_key(
    operation_resource_id,
    context: context
  )._model

  authorizer.remove_resource(source_record: record)
end
authorize_remove_to_many_relationships() click to toggle source
# File lib/jsonapi/authorization/authorizing_processor.rb, line 203
def authorize_remove_to_many_relationships
  source_resource = @resource_klass.find_by_key(
    params[:resource_id],
    context: context
  )
  source_record = source_resource._model

  relationship_type = params[:relationship_type].to_sym

  related_resources = @resource_klass
    ._relationship(relationship_type)
    .resource_klass
    .find_by_keys(
      params[:associated_keys],
      context: context
    )

  related_records = related_resources.map(&:_model)

  if related_records.size != params[:associated_keys].uniq.size
    fail JSONAPI::Exceptions::RecordNotFound, params[:associated_keys]
  end

  authorizer.remove_to_many_relationship(
    source_record: source_record,
    related_records: related_records,
    relationship_type: relationship_type
  )
end
authorize_remove_to_one_relationship() click to toggle source
# File lib/jsonapi/authorization/authorizing_processor.rb, line 233
def authorize_remove_to_one_relationship
  source_record = @resource_klass.find_by_key(
    params[:resource_id],
    context: context
  )._model

  relationship_type = params[:relationship_type].to_sym

  authorizer.remove_to_one_relationship(
    source_record: source_record, relationship_type: relationship_type
  )
end
authorize_replace_fields() click to toggle source
# File lib/jsonapi/authorization/authorizing_processor.rb, line 116
def authorize_replace_fields
  source_record = @resource_klass.find_by_key(
    params[:resource_id],
    context: context
  )._model
  authorizer.replace_fields(
    source_record: source_record,
    related_records_with_context: related_models_with_context
  )
end
authorize_replace_polymorphic_to_one_relationship() click to toggle source
# File lib/jsonapi/authorization/authorizing_processor.rb, line 246
def authorize_replace_polymorphic_to_one_relationship
  return authorize_remove_to_one_relationship if params[:key_value].nil?

  source_resource = @resource_klass.find_by_key(
    params[:resource_id],
    context: context
  )
  source_record = source_resource._model

  # Fetch the name of the new class based on the incoming polymorphic
  # "type" value. This will fail if there is no associated resource for the
  # incoming "type" value so this shouldn't leak constants
  related_record_class_name = source_resource
    .send(:_model_class_name, params[:key_type])

  # Fetch the underlying Resource class for the new record to-be-associated
  related_resource_klass = @resource_klass.resource_for(related_record_class_name)

  new_related_resource = related_resource_klass
    .find_by_key(
      params[:key_value],
      context: context
    )
  new_related_record = new_related_resource._model unless new_related_resource.nil?

  relationship_type = params[:relationship_type].to_sym
  authorizer.replace_to_one_relationship(
    source_record: source_record,
    new_related_record: new_related_record,
    relationship_type: relationship_type
  )
end
authorize_replace_to_many_relationships() click to toggle source
# File lib/jsonapi/authorization/authorizing_processor.rb, line 186
def authorize_replace_to_many_relationships
  source_resource = @resource_klass.find_by_key(
    params[:resource_id],
    context: context
  )
  source_record = source_resource._model

  relationship_type = params[:relationship_type].to_sym
  new_related_records = model_class_for_relationship(relationship_type).find(params[:data])

  authorizer.replace_to_many_relationship(
    source_record: source_record,
    new_related_records: new_related_records,
    relationship_type: relationship_type
  )
end
authorize_replace_to_one_relationship() click to toggle source
# File lib/jsonapi/authorization/authorizing_processor.rb, line 144
def authorize_replace_to_one_relationship
  return authorize_remove_to_one_relationship if params[:key_value].nil?

  source_resource = @resource_klass.find_by_key(
    params[:resource_id],
    context: context
  )
  source_record = source_resource._model

  relationship_type = params[:relationship_type].to_sym
  new_related_resource = @resource_klass
    ._relationship(relationship_type)
    .resource_klass
    .find_by_key(
      params[:key_value],
      context: context
    )
  new_related_record = new_related_resource._model unless new_related_resource.nil?

  authorizer.replace_to_one_relationship(
    source_record: source_record,
    new_related_record: new_related_record,
    relationship_type: relationship_type
  )
end
authorize_show() click to toggle source
# File lib/jsonapi/authorization/authorizing_processor.rb, line 55
def authorize_show
  record = @resource_klass.find_by_key(
    operation_resource_id,
    context: context
  )._model

  authorizer.show(source_record: record)
end
authorize_show_relationship() click to toggle source
# File lib/jsonapi/authorization/authorizing_processor.rb, line 64
def authorize_show_relationship
  parent_resource = @resource_klass.find_by_key(
    params[:parent_key],
    context: context
  )

  relationship = @resource_klass._relationship(params[:relationship_type].to_sym)

  related_resource =
    case relationship
    when JSONAPI::Relationship::ToOne
      parent_resource.public_send(params[:relationship_type].to_sym)
    when JSONAPI::Relationship::ToMany
      # Do nothing — already covered by policy scopes
    else
      raise "Unexpected relationship type: #{relationship.inspect}"
    end

  parent_record = parent_resource._model
  related_record = related_resource._model unless related_resource.nil?
  authorizer.show_relationship(source_record: parent_record, related_record: related_record)
end

Private Instance Methods

authorize_include_item(resource_klass, source_record, include_item) click to toggle source
# File lib/jsonapi/authorization/authorizing_processor.rb, line 349
def authorize_include_item(resource_klass, source_record, include_item)
  case include_item
  when Hash
    # e.g. {articles: [:comments, :author]} when ?include=articles.comments,articles.author
    include_item.each do |rel_name, deep|
      authorize_include_item(resource_klass, source_record, rel_name)
      relationship = resource_klass._relationship(rel_name)
      next_resource_klass = relationship.resource_klass
      Array.wrap(
        source_record.public_send(
          relationship.relation_name(context: context)
        )
      ).each do |next_source_record|
        deep.each do |next_include_item|
          authorize_include_item(
            next_resource_klass,
            next_source_record,
            next_include_item
          )
        end
      end
    end
  when Symbol
    relationship = resource_klass._relationship(include_item)
    case relationship
    when JSONAPI::Relationship::ToOne
      related_record = source_record.public_send(
        relationship.relation_name(context: context)
      )
      return if related_record.nil?
      authorizer.include_has_one_resource(
        source_record: source_record, related_record: related_record
      )
    when JSONAPI::Relationship::ToMany
      authorizer.include_has_many_resource(
        source_record: source_record,
        record_class: relationship.resource_klass._model_class
      )
    else
      raise "Unexpected relationship type: #{relationship.inspect}"
    end
  else
    raise "Unknown include directive: #{include_item}"
  end
end
authorize_model_includes(source_record) click to toggle source
# File lib/jsonapi/authorization/authorizing_processor.rb, line 341
def authorize_model_includes(source_record)
  if params[:include_directives]
    params[:include_directives].model_includes.each do |include_item|
      authorize_include_item(@resource_klass, source_record, include_item)
    end
  end
end
authorizer() click to toggle source
# File lib/jsonapi/authorization/authorizing_processor.rb, line 281
def authorizer
  @authorizer ||= ::JSONAPI::Authorization.configuration.authorizer.new(context: context)
end
model_class_for_relationship(assoc_name) click to toggle source
# File lib/jsonapi/authorization/authorizing_processor.rb, line 301
def model_class_for_relationship(assoc_name)
  resource_class_for_relationship(assoc_name)._model_class
end
operation_resource_id() click to toggle source

TODO: Communicate with upstream to fix this nasty hack

# File lib/jsonapi/authorization/authorizing_processor.rb, line 286
def operation_resource_id
  case operation_type
  when :show
    params[:id]
  when :show_related_resources
    params[:source_id]
  else
    params[:resource_id]
  end
end
resource_class_for_relationship(assoc_name) click to toggle source
# File lib/jsonapi/authorization/authorizing_processor.rb, line 297
def resource_class_for_relationship(assoc_name)
  @resource_klass._relationship(assoc_name).resource_klass
end