JSONAPI-Resources / JSONAPI-Resources/jsonapi-resources

[0.9.12] Need to add handle the invalid request

Aperta
#1,375 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

Lingua principale
Ruby
Stelle
2.3k
Fork
546
Metriche di merge delle PR
Nessuna PR unita negli ultimi 30g

Descrizione

Need to add handle the invalid request
The bug report below shows the necessary cases

begin
  require 'bundler/inline'
  require 'bundler'
rescue LoadError => e
  STDERR.puts 'Bundler version 1.10 or later is required. Please update your Bundler'
  raise e
end

gemfile(true, ui: ENV['SILENT'] ? Bundler::UI::Silent.new : Bundler::UI::Shell.new) do
  source 'https://rubygems.org'

  gem 'rails', require: false
  gem 'sqlite3', platform: :mri
  gem 'byebug'

  gem 'activerecord-jdbcsqlite3-adapter',
      git: 'https://github.com/jruby/activerecord-jdbc-adapter',
      platform: :jruby

  if ENV['JSONAPI_RESOURCES_PATH']
    gem 'jsonapi-resources', path: ENV['JSONAPI_RESOURCES_PATH'], require: false
  else
    gem 'jsonapi-resources', git: 'https://github.com/cerebris/jsonapi-resources', require: false
  end

end

# prepare active_record database
require 'active_record'

class NullLogger < Logger
  def initialize(*_args) end

  def add(*_args, &_block) end
end

ActiveRecord::Base.establish_connection(adapter: 'sqlite3', database: ':memory:')
ActiveRecord::Base.logger = ENV['SILENT'] ? NullLogger.new : Logger.new(STDOUT)
ActiveRecord::Migration.verbose = !ENV['SILENT']

ActiveRecord::Schema.define do
  # Add your schema here
  create_table :authors, force: true do |t|
    t.string :name
  end

  create_table :books, force: true do |t|
    t.string :text
    t.references :author
  end
end

# create models
class Author < ActiveRecord::Base
  has_many :books
end

class Comment < ActiveRecord::Base
  belongs_to :author
end

# prepare rails app
require 'action_controller/railtie'
# require 'action_view/railtie'
require 'jsonapi-resources'

class ApplicationController < ActionController::Base
end

# prepare jsonapi resources and controllers
class AuthorsController < ApplicationController
  include JSONAPI::ActsAsResourceController
end

class BooksController < ApplicationController
  include JSONAPI::ActsAsResourceController
end

class AuthorResource < JSONAPI::Resource
  attribute :name
  has_many :books, polymorphic: true, class_name: 'Book'
end

class BookResource < JSONAPI::Resource
  attribute :text
end

class TestApp < Rails::Application
  config.root = File.dirname(__FILE__)
  config.logger = ENV['SILENT'] ? NullLogger.new : Logger.new(STDOUT)
  Rails.logger = config.logger

  secrets.secret_token = 'secret_token'
  secrets.secret_key_base = 'secret_key_base'

  config.eager_load = false
end

Rails.application.configure do
  config.hosts << 'example.org'
end

# initialize app
Rails.application.initialize!

JSONAPI.configure do |config|
  config.json_key_format = :underscored_key
  config.route_format = :underscored_key
end

# draw routes
Rails.application.routes.draw do
  jsonapi_resources :authors, only: [:show, :update]
end

# prepare tests
require 'minitest/autorun'
require 'rack/test'

# Replace this with the code necessary to make your test fail.
class BugTest < Minitest::Test
  include Rack::Test::Methods

  def json_api_headers
    { 'Accept' => JSONAPI::MEDIA_TYPE, 'CONTENT_TYPE' => JSONAPI::MEDIA_TYPE }
  end

  def test_relationships_as_array
    author = Author.create!
    json_request = {
      data: {
        id: author.id.to_s,
        type: 'authors',
        relationships: []
      }
    }
    patch "/authors/#{author.id}", json_request.to_json, json_api_headers
    assert last_response.bad_request?
  end

  def test_relationships_as_nil
    author = Author.create!
    json_request = {
      data: {
        id: author.id.to_s,
        type: 'authors',
        relationships: nil
      }
    }
    patch "/authors/#{author.id}", json_request.to_json, json_api_headers
    assert last_response.bad_request?
  end

  def test_attributes_as_nil
    author = Author.create!
    json_request = {
      data: {
        id: author.id.to_s,
        type: 'authors',
        attributes: nil
      }
    }
    patch "/authors/#{author.id}", json_request.to_json, json_api_headers
    assert last_response.bad_request?
  end

  def test_relationship_name_in_attributes
    author = Author.create!
    json_request = {
      data: {
        id: author.id.to_s,
        type: 'authors',
        attributes: {
          books: []
        }
      }
    }
    patch "/authors/#{author.id}", json_request.to_json, json_api_headers
    assert last_response.bad_request?
  end

  private

  def app
    Rails.application
  end
end

Solution:
Need update method verify_permitted_params
https://github.com/cerebris/jsonapi-resources/blob/dc96280141715fa531665faada63e88ce356dc92/lib/jsonapi/request_parser.rb#L583

def verify_permitted_params(params, allowed_fields)
  formatted_allowed_fields = allowed_fields.collect { |field| format_key(field).to_sym }
  params_not_allowed = []

  params.each do |key, value|
    case key.to_s
    when 'relationships'
    raise JSONAPI::Exceptions::TypeMismatch.new(nil) unless value.is_a?(ActionController::Parameters) # ADDED THIS LINE

      value.keys.each do |links_key|
        unless formatted_allowed_fields.include?(links_key.to_sym)
          if JSONAPI.configuration.raise_if_parameters_not_allowed
            fail JSONAPI::Exceptions::ParameterNotAllowed.new(links_key)
          else
            params_not_allowed.push(links_key)
            value.delete links_key
          end
        end
      end
    when 'attributes'
    raise JSONAPI::Exceptions::TypeMismatch.new(nil) unless value.is_a?(ActionController::Parameters) # ADDED THIS LINE
    
    attributes = formatted_allowed_fields - resource_klass._relationships.keys # ADDED THIS LINE
      value.each do |attr_key, attr_value|
        unless formatted_allowed_fields.include?(attr_key.to_sym)
          if JSONAPI.configuration.raise_if_parameters_not_allowed
            fail JSONAPI::Exceptions::ParameterNotAllowed.new(attr_key)
          else
            params_not_allowed.push(attr_key)
            value.delete attr_key
          end
        end
      end
    when 'type'
    when 'id'
      unless formatted_allowed_fields.include?(:id)
        if JSONAPI.configuration.raise_if_parameters_not_allowed
          fail JSONAPI::Exceptions::ParameterNotAllowed.new(:id)
        else
          params_not_allowed.push(:id)
          params.delete :id
        end
      end
    else
      if JSONAPI.configuration.raise_if_parameters_not_allowed
        fail JSONAPI::Exceptions::ParameterNotAllowed.new(key)
      else
        params_not_allowed.push(key)
        params.delete key
      end
    end
  end

  if params_not_allowed.length > 0
    params_not_allowed_warnings = params_not_allowed.map do |param|
      JSONAPI::Warning.new(code: JSONAPI::PARAM_NOT_ALLOWED,
                           title: 'Param not allowed',
                           detail: "#{param} is not allowed.")
    end
    self.warnings.concat(params_not_allowed_warnings)
  end
end

Guida per i contributori

Nessuna guida per i contributori indicizzata per questo repository

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Direzione di ricerca

Inizia da verify_permitted_params in lib/jsonapi/request_parser.rb intorno alla riga 583, quindi esegui il riproduttore inline Minitest BugTest dell’issue. La modifica è completa quando i quattro payload PATCH malformati vengono rifiutati come richieste non valide senza causare un’eccezione imprevista.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Valutazione

Stack tecnologico
rails, ruby, sqlite
Ambito
api, backend
Tipo di issue
Bug
Difficoltà
2/5
Tempo stimato
1-3 ore
Stato di attività
Ferma
Chiarezza
Specificata chiaramente
Idoneità per principianti
55/100

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.