Hacktoberfest 2026:维护者为十月标记出来的 issue,仍然开放、适合新手。 浏览 Hacktoberfest issue

[0.9.12] Need to add handle the invalid request

未关闭
#1,375 0 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

还没有人认领这个 Issue。

评估

难度
2/5
预计耗时
1-3 小时
新手友好度
55/100
Issue 类型
缺陷
描述清晰度
描述清楚
活跃度
停滞
技术栈
rails, ruby, sqlite
领域
api, backend

调研方向

先从 lib/jsonapi/request_parser.rb 中大约第 583 行的 verify_permitted_params 开始,然后运行 issue 中的 inline Minitest BugTest 复现程序。当四个格式错误的 PATCH payload 被作为错误请求拒绝,且不会导致意外异常时,此更改即完成。

由索引模型根据 Issue 内容生成。

描述

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
主要语言
Ruby
星标
2.3k
派生
546
PR 合并指标
30 天内没有已合并 PR

贡献指南

这个仓库没有索引到贡献指南

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

JSONAPI-Resources/jsonapi-resources 的其他 Issue

查看 JSONAPI-Resources/jsonapi-resources 的全部 Issue

相似的 Issue

更多 Ruby Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。