Skip to content

Bypass type checking when using loads: with interface #5378

Closed
@IvanChibisov

Description

@IvanChibisov

Describe the bug

The behavior of loads: for mutation arguments changed after the upgrade to 2.5.8. This is likely due to this change:

Visibility: improve performance for loadable? #5355

We use loads: in a mutation with pundit_role: like this:

class ArchiveRecord < BaseMutation
  pundit_role nil

  argument :record_id, Types::GlobalID, loads: ::ArchivableInterface, required: true, pundit_role: :archive

  field :status, String, null: false

  def resolve(record:)
    if record.update(archived: true)
      return { status: "OK" }
    else
      return { status: "ERROR" }
    end
  end
end

So, in version 2.5.7, if someone tries to send a non-archivable record(not implement ArchivableInterface interface), an error message will be returned:

{
  "errors" => [{
     "message" => "No object found for `recordId: ....`"
   }]
}

But now the record is successfully loaded and Pundit integration error is returned.

Click to view exception backtrace
NoMethodError:
       undefined method `archived?' for an instance of RecordPolicy
     # /usr/local/bundle/gems/graphql-pro-1.29.9/lib/graphql/pro/pundit_integration.rb:400:in `public_send'
     # /usr/local/bundle/gems/graphql-pro-1.29.9/lib/graphql/pro/pundit_integration.rb:400:in `authorized_by_policy?'
     # /usr/local/bundle/gems/graphql-pro-1.29.9/lib/graphql/pro/pundit_integration.rb:165:in `authorized_as_type?'
     # /usr/local/bundle/gems/graphql-2.5.8/lib/graphql/schema/argument.rb:161:in `authorized?'
     # /usr/local/bundle/gems/graphql-pro-1.29.9/lib/graphql/pro/pundit_integration.rb:145:in `authorized?'
     # /usr/local/bundle/gems/graphql-2.5.8/lib/graphql/schema/resolver.rb:173:in `block in authorize_arguments'
     # /usr/local/bundle/gems/graphql-2.5.8/lib/graphql/schema/resolver.rb:170:in `each'
     # /usr/local/bundle/gems/graphql-2.5.8/lib/graphql/schema/resolver.rb:170:in `authorize_arguments'
     # /usr/local/bundle/gems/graphql-2.5.8/lib/graphql/schema/has_single_input_argument.rb:156:in `authorize_arguments'
     # /usr/local/bundle/gems/graphql-2.5.8/lib/graphql/schema/resolver.rb:154:in `authorized?'
     # /usr/local/bundle/gems/graphql-2.5.8/lib/graphql/schema/resolver.rb:89:in `block (2 levels) in resolve_with_support'
     # /usr/local/bundle/gems/graphql-2.5.8/lib/graphql/execution/interpreter/runtime.rb:880:in `minimal_after_lazy'
     # /usr/local/bundle/gems/graphql-2.5.8/lib/graphql/query.rb:28:in `after_lazy'
     # /usr/local/bundle/gems/graphql-2.5.8/lib/graphql/schema/resolver.rb:84:in `block in resolve_with_support'
     # /usr/local/bundle/gems/graphql-2.5.8/lib/graphql/execution/interpreter/runtime.rb:880:in `minimal_after_lazy'
     # /usr/local/bundle/gems/graphql-2.5.8/lib/graphql/query.rb:28:in `after_lazy'
     # /usr/local/bundle/gems/graphql-2.5.8/lib/graphql/schema/resolver.rb:72:in `resolve_with_support'
     # /usr/local/bundle/gems/graphql-2.5.8/lib/graphql/schema/has_single_input_argument.rb:36:in `resolve_with_support'
     # /usr/local/bundle/gems/graphql-2.5.8/lib/graphql/schema/relay_classic_mutation.rb:44:in `resolve_with_support'
     # /usr/local/bundle/gems/graphql-2.5.8/lib/graphql/schema/field.rb:750:in `public_send'
     # /usr/local/bundle/gems/graphql-2.5.8/lib/graphql/schema/field.rb:750:in `block (2 levels) in resolve'
     # /usr/local/bundle/gems/graphql-2.5.8/lib/graphql/schema/field.rb:895:in `block in with_extensions'
     # /usr/local/bundle/gems/graphql-2.5.8/lib/graphql/schema/field.rb:931:in `block (2 levels) in run_extensions_before_resolve'
     # /usr/local/bundle/gems/graphql-2.5.8/lib/graphql/schema/field.rb:934:in `run_extensions_before_resolve'
     # /usr/local/bundle/gems/graphql-2.5.8/lib/graphql/schema/field.rb:931:in `block in run_extensions_before_resolve'
     # /usr/local/bundle/gems/graphql-2.5.8/lib/graphql/schema/field_extension.rb:134:in `resolve'
     # /usr/local/bundle/gems/graphql-2.5.8/lib/graphql/schema/field.rb:918:in `run_extensions_before_resolve'
     # /usr/local/bundle/gems/graphql-2.5.8/lib/graphql/schema/field.rb:890:in `with_extensions'
     # /usr/local/bundle/gems/graphql-2.5.8/lib/graphql/schema/field.rb:721:in `block in resolve'
     # /usr/local/bundle/gems/graphql-2.5.8/lib/graphql/execution/interpreter/runtime.rb:880:in `minimal_after_lazy'
     # /usr/local/bundle/gems/graphql-2.5.8/lib/graphql/query.rb:28:in `after_lazy'
     # /usr/local/bundle/gems/graphql-2.5.8/lib/graphql/schema/field.rb:719:in `resolve'
     # /usr/local/bundle/gems/graphql-2.5.8/lib/graphql/execution/interpreter/runtime.rb:473:in `block (2 levels) in evaluate_selection_with_resolved_keyword_args'
     # /usr/local/bundle/gems/graphql-2.5.8/lib/graphql/tracing/trace.rb:90:in `execute_field'
     # /usr/local/bundle/gems/graphql-2.5.8/lib/graphql/execution/interpreter/runtime.rb:472:in `block in evaluate_selection_with_resolved_keyword_args'
     # /usr/local/bundle/gems/graphql-2.5.8/lib/graphql/execution/interpreter/runtime.rb:818:in `call_method_on_directives'
     # /usr/local/bundle/gems/graphql-2.5.8/lib/graphql/execution/interpreter/runtime.rb:460:in `evaluate_selection_with_resolved_keyword_args'
     # /usr/local/bundle/gems/graphql-2.5.8/lib/graphql/execution/interpreter/runtime.rb:438:in `block in evaluate_selection_with_args'
     # /usr/local/bundle/gems/graphql-2.5.8/lib/graphql/execution/interpreter/runtime.rb:945:in `after_lazy'
     # /usr/local/bundle/gems/graphql-2.5.8/lib/graphql/execution/interpreter/runtime.rb:385:in `evaluate_selection_with_args'
     # /usr/local/bundle/gems/graphql-2.5.8/lib/graphql/execution/interpreter/runtime.rb:379:in `block in evaluate_selection'
     # /usr/local/bundle/gems/graphql-2.5.8/lib/graphql/execution/interpreter/arguments_cache.rb:46:in `block in dataload_for'
     # /usr/local/bundle/gems/graphql-2.5.8/lib/graphql/schema/member/has_arguments.rb:272:in `block (3 levels) in coerce_arguments'
     # /usr/local/bundle/gems/graphql-2.5.8/lib/graphql/dataloader.rb:300:in `block in spawn_job_fiber'
     # /usr/local/bundle/gems/graphql-2.5.8/lib/graphql/dataloader.rb:255:in `block in spawn_fiber'

Of course, this is not a problem with the Pundit integration, if I remove pundit_role, the code will crash a little later when trying to update an unknown "archived" attribute. The pundit_role is just an original problem that we encountered.

Versions

graphql version: 2.5.8
rails (or other framework): 8.0.2
other applicable versions (graphql-batch, etc)

Steps to reproduce

Create an interface, use it in loads: for the mutation argument, and try passing the ID of a record that doesn't implement that interface.

Expected behavior

An error message is returned: No object found for 'recordId:..'

Actual behavior

The record was successfully loaded and passed to the perform method in the mutation.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions