From 7ac7c6ec6a64eed3394bd409014681a91a71bb40 Mon Sep 17 00:00:00 2001 From: exAspArk Date: Mon, 16 Mar 2020 10:57:42 -0400 Subject: [PATCH 1/3] Stop supporting GraphQL <= 1.7 and versions without the Interpreter --- .travis.yml | 36 +++-------- README.md | 12 ++++ graphql-1.7.gemfile | 8 --- graphql-guard.gemspec | 2 +- spec/fixtures/inline_schema.rb | 93 +++++++++------------------ spec/fixtures/policy_object_schema.rb | 87 ++++++++----------------- spec/graphql/guard_spec.rb | 21 ++---- spec/graphql/testing_spec.rb | 11 ---- spec/spec_helper.rb | 2 - 9 files changed, 85 insertions(+), 187 deletions(-) delete mode 100644 graphql-1.7.gemfile diff --git a/.travis.yml b/.travis.yml index 35aca92..269a9ea 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,29 +1,13 @@ sudo: false language: ruby before_install: gem install bundler -v 1.17.3 -matrix: - include: - - gemfile: graphql-1.7.gemfile - env: GRAPHQL_RUBY_VERSION=1_7 CI=true - rvm: 2.3.8 - - gemfile: graphql-latest.gemfile - env: GRAPHQL_RUBY_VERSION=LATEST CI=true - rvm: 2.3.8 - - gemfile: graphql-1.7.gemfile - env: GRAPHQL_RUBY_VERSION=1_7 CI=true - rvm: 2.4.5 - - gemfile: graphql-latest.gemfile - env: GRAPHQL_RUBY_VERSION=LATEST CI=true - rvm: 2.4.5 - - gemfile: graphql-1.7.gemfile - env: GRAPHQL_RUBY_VERSION=1_7 CI=true - rvm: 2.5.7 - - gemfile: graphql-latest.gemfile - env: GRAPHQL_RUBY_VERSION=LATEST CI=true - rvm: 2.5.7 - - gemfile: graphql-1.7.gemfile - env: GRAPHQL_RUBY_VERSION=1_7 CI=true - rvm: 2.6.5 - - gemfile: graphql-latest.gemfile - env: GRAPHQL_RUBY_VERSION=LATEST CI=true - rvm: 2.6.5 +rvm: + - 2.3.8 + - 2.4.9 + - 2.5.7 + - 2.6.5 + - 2.7.0 +env: + - CI=true +gemfile: + - graphql-latest.gemfile diff --git a/README.md b/README.md index df19715..b64d7cb 100644 --- a/README.md +++ b/README.md @@ -55,6 +55,8 @@ end # Define a schema Schema = GraphQL::Schema.define do + use GraphQL::Execution::Interpreter + use GraphQL::Analysis::AST query QueryType end @@ -68,6 +70,8 @@ Add `GraphQL::Guard` to your schema:
 Schema = GraphQL::Schema.define do
+  use GraphQL::Execution::Interpreter
+  use GraphQL::Analysis::AST
   query QueryType
   use GraphQL::Guard.new
 end
@@ -141,6 +145,8 @@ Pass this object to `GraphQL::Guard`:
 
 
 Schema = GraphQL::Schema.define do
+  use GraphQL::Execution::Interpreter
+  use GraphQL::Analysis::AST
   query QueryType
   use GraphQL::Guard.new(policy_object: GraphqlPolicy)
 end
@@ -184,6 +190,8 @@ PostType = GraphQL::ObjectType.define do
 end
 
 Schema = GraphQL::Schema.define do
+  use GraphQL::Execution::Interpreter
+  use GraphQL::Analysis::AST
   query QueryType
   use GraphQL::Guard.new(policy_object: GraphqlPolicy)
 end
@@ -249,6 +257,8 @@ You can change this behavior, by passing custom `not_authorized` lambda. For exa
 
 
 SchemaWithErrors = GraphQL::Schema.define do
+  use GraphQL::Execution::Interpreter
+  use GraphQL::Analysis::AST
   query QueryType
   use GraphQL::Guard.new(
     # By default it raises an error
@@ -301,6 +311,8 @@ class GraphqlPolicy
 end
 
 Schema = GraphQL::Schema.define do
+  use GraphQL::Execution::Interpreter
+  use GraphQL::Analysis::AST
   query QueryType
   mutation MutationType
 
diff --git a/graphql-1.7.gemfile b/graphql-1.7.gemfile
deleted file mode 100644
index e24d295..0000000
--- a/graphql-1.7.gemfile
+++ /dev/null
@@ -1,8 +0,0 @@
-source "https://rubygems.org"
-
-gem "pry"
-gem 'coveralls'
-
-gem "graphql", "~> 1.7.14"
-
-gemspec
diff --git a/graphql-guard.gemspec b/graphql-guard.gemspec
index 377f387..cd70074 100644
--- a/graphql-guard.gemspec
+++ b/graphql-guard.gemspec
@@ -26,6 +26,6 @@ Gem::Specification.new do |spec|
   spec.add_runtime_dependency "graphql", ">= 1.6.0", "< 2"
 
   spec.add_development_dependency "bundler", "~> 1.15"
-  spec.add_development_dependency "rake", "~> 10.0"
+  spec.add_development_dependency "rake", "~> 13.0"
   spec.add_development_dependency "rspec", "~> 3.0"
 end
diff --git a/spec/fixtures/inline_schema.rb b/spec/fixtures/inline_schema.rb
index 5b6a6fc..d2854a4 100644
--- a/spec/fixtures/inline_schema.rb
+++ b/spec/fixtures/inline_schema.rb
@@ -1,78 +1,45 @@
 # frozen_string_literal: true
 
 module Inline
-  case ENV['GRAPHQL_RUBY_VERSION']
-  when '1_7'
-    PostType = GraphQL::ObjectType.define do
-      name "Post"
-      guard ->(_post, _args, ctx) { ctx[:current_user].admin? }
-      field :id, !types.ID
-      field :title, types.String
-    end
-
-    QueryType = GraphQL::ObjectType.define do
-      name "Query"
-      field :posts, !types[!PostType] do
-        argument :userId, !types.ID
-        guard ->(_obj, args, ctx) { args[:userId] == ctx[:current_user].id }
-        resolve ->(_obj, args, _ctx) { Post.where(user_id: args[:userId]) }
-      end
+  class PostType < GraphQL::Schema::Object
+    guard ->(_post, _args, ctx) { ctx[:current_user].admin? }
+    field :id, ID, null: false
+    field :title, String, null: true
+  end
 
-      field :postsWithMask, !types[!PostType] do
-        argument :userId, !types.ID
-        mask ->(ctx) { ctx[:current_user].admin? }
-        resolve ->(_obj, args, _ctx) { Post.where(user_id: args[:userId]) }
-      end
+  class QueryType < GraphQL::Schema::Object
+    field :posts, [PostType], null: false do
+      argument :user_id, ID, required: true
+      guard ->(_obj, args, ctx) { args[:userId] == ctx[:current_user].id }
     end
 
-    Schema = GraphQL::Schema.define do
-      query QueryType
-      use GraphQL::Guard.new
+    field :posts_with_mask, [PostType], null: false do
+      argument :user_id, ID, required: true
+      mask ->(ctx) { ctx[:current_user].admin? }
     end
 
-    SchemaWithoutExceptions = GraphQL::Schema.define do
-      query QueryType
-      use GraphQL::Guard.new(not_authorized: ->(type, field) {
-        GraphQL::ExecutionError.new("Not authorized to access #{type}.#{field}")
-      })
+    def posts(user_id:)
+      Post.where(user_id: user_id)
     end
-  when 'LATEST'
-    class PostType < GraphQL::Schema::Object
-      guard ->(_post, _args, ctx) { ctx[:current_user].admin? }
-      field :id, ID, null: false
-      field :title, String, null: true
-    end
-
-    class QueryType < GraphQL::Schema::Object
-      field :posts, [PostType], null: false do
-        argument :user_id, ID, required: true
-        guard ->(_obj, args, ctx) { args[:userId] == ctx[:current_user].id }
-      end
-
-      field :posts_with_mask, [PostType], null: false do
-        argument :user_id, ID, required: true
-        mask ->(ctx) { ctx[:current_user].admin? }
-      end
 
-      def posts(user_id:)
-        Post.where(user_id: user_id)
-      end
-
-      def posts_with_mask(user_id:)
-        Post.where(user_id: user_id)
-      end
+    def posts_with_mask(user_id:)
+      Post.where(user_id: user_id)
     end
+  end
 
-    class Schema < GraphQL::Schema
-      query QueryType
-      use GraphQL::Guard.new
-    end
+  class Schema < GraphQL::Schema
+    use GraphQL::Execution::Interpreter
+    use GraphQL::Analysis::AST
+    query QueryType
+    use GraphQL::Guard.new
+  end
 
-    class SchemaWithoutExceptions < GraphQL::Schema
-      query QueryType
-      use GraphQL::Guard.new(not_authorized: ->(type, field) {
-        GraphQL::ExecutionError.new("Not authorized to access #{type}.#{field}")
-      })
-    end
+  class SchemaWithoutExceptions < GraphQL::Schema
+    use GraphQL::Execution::Interpreter
+    use GraphQL::Analysis::AST
+    query QueryType
+    use GraphQL::Guard.new(not_authorized: ->(type, field) {
+      GraphQL::ExecutionError.new("Not authorized to access #{type}.#{field}")
+    })
   end
 end
diff --git a/spec/fixtures/policy_object_schema.rb b/spec/fixtures/policy_object_schema.rb
index 9e2942c..9e43770 100644
--- a/spec/fixtures/policy_object_schema.rb
+++ b/spec/fixtures/policy_object_schema.rb
@@ -1,75 +1,40 @@
 # frozen_string_literal: true
 
 module PolicyObject
-  case ENV['GRAPHQL_RUBY_VERSION']
-  when '1_7'
-    PostType = GraphQL::ObjectType.define do
-      name "Post"
-      field :id, !types.ID
-      field :title, types.String
-    end
-
-    QueryType = GraphQL::ObjectType.define do
-      name "Query"
-      field :posts, !types[!PostType] do
-        argument :userId, !types.ID
-        resolve ->(_obj, args, _ctx) { Post.where(user_id: args[:userId]) }
-      end
-    end
-
-    class GraphqlPolicy
-      RULES = {
-        QueryType => {
-          posts: ->(_obj, args, ctx) { args[:userId] == ctx[:current_user].id }
-        },
-        PostType => {
-          '*': ->(_post, args, ctx) { ctx[:current_user].admin? }
-        }
-      }
-
-      def self.guard(type, field)
-        RULES.dig(type, field)
-      end
-    end
+  class PostType < GraphQL::Schema::Object
+    field :id, ID, null: false
+    field :title, String, null: true
+  end
 
-    Schema = GraphQL::Schema.define do
-      query QueryType
-      use GraphQL::Guard.new(policy_object: GraphqlPolicy)
-    end
-  when 'LATEST'
-    class PostType < GraphQL::Schema::Object
-      field :id, ID, null: false
-      field :title, String, null: true
+  class QueryType < GraphQL::Schema::Object
+    field :posts, [PostType], null: false do
+      argument :user_id, ID, required: true
     end
 
-    class QueryType < GraphQL::Schema::Object
-      field :posts, [PostType], null: false do
-        argument :user_id, ID, required: true
-      end
-
-      def posts(user_id:)
-        Post.where(user_id: user_id)
-      end
+    def posts(user_id:)
+      Post.where(user_id: user_id)
     end
+  end
 
-    class GraphqlPolicy
-      RULES = {
-        QueryType => {
-          posts: ->(_obj, args, ctx) { args[:userId] == ctx[:current_user].id }
-        },
-        PostType => {
-          '*': ->(_post, args, ctx) { ctx[:current_user].admin? }
-        }
+  class GraphqlPolicy
+    RULES = {
+      QueryType => {
+        posts: ->(_obj, args, ctx) { args[:userId] == ctx[:current_user].id }
+      },
+      PostType => {
+        '*': ->(_post, args, ctx) { ctx[:current_user].admin? }
       }
+    }
 
-      def self.guard(type, field)
-        RULES.dig(type.metadata[:type_class], field)
-      end
+    def self.guard(type, field)
+      RULES.dig(type.metadata[:type_class], field)
     end
+  end
 
-    class Schema < GraphQL::Schema
-      query QueryType
-      use GraphQL::Guard.new(policy_object: GraphqlPolicy)
-    end
+  class Schema < GraphQL::Schema
+    use GraphQL::Execution::Interpreter
+    use GraphQL::Analysis::AST
+    query QueryType
+    use GraphQL::Guard.new(policy_object: GraphqlPolicy)
   end
 end
diff --git a/spec/graphql/guard_spec.rb b/spec/graphql/guard_spec.rb
index 0b4dab0..2e984fb 100644
--- a/spec/graphql/guard_spec.rb
+++ b/spec/graphql/guard_spec.rb
@@ -67,21 +67,12 @@
 
       result = Inline::Schema.execute(query, variables: {'userId' => user.id}, context: {current_user: user})
 
-      case ENV['GRAPHQL_RUBY_VERSION']
-      when '1_7'
-        expect(result['errors']).to include({
-          "message" => "Field 'postsWithMask' doesn't exist on type 'Query'",
-          "locations" => [{"line" => 1, "column" => 23}],
-          "fields" => ["query", "postsWithMask"]
-        })
-      when 'LATEST'
-        expect(result['errors']).to include({
-          "message" => "Field 'postsWithMask' doesn't exist on type 'Query'",
-          "locations" => [{"line" => 1, "column" => 23}],
-          "path" => ["query", "postsWithMask"],
-          "extensions" =>  {"code" => "undefinedField", "typeName" => "Query", "fieldName" => "postsWithMask"}
-        })
-      end
+      expect(result['errors']).to include({
+        "message" => "Field 'postsWithMask' doesn't exist on type 'Query'",
+        "locations" => [{"line" => 1, "column" => 23}],
+        "path" => ["query", "postsWithMask"],
+        "extensions" =>  {"code" => "undefinedField", "typeName" => "Query", "fieldName" => "postsWithMask"}
+      })
     end
   end
 
diff --git a/spec/graphql/testing_spec.rb b/spec/graphql/testing_spec.rb
index 939c020..31df319 100644
--- a/spec/graphql/testing_spec.rb
+++ b/spec/graphql/testing_spec.rb
@@ -58,17 +58,6 @@
       }.to raise_error(GraphQL::Field::NoGuardError, "Guard lambda does not exist for Query.posts")
     end
 
-    if ENV['GRAPHQL_RUBY_VERSION'] == '1_7'
-    it 'raises an error if the field was fetched without guard' do
-      posts_field = PolicyObject::QueryType.get_field('posts')
-      user = User.new(id: '1', role: 'admin')
-
-      expect {
-        posts_field.guard(nil, {userId: user.id}, {current_user: user})
-      }.to raise_error(GraphQL::Field::NoGuardError, "Get your field by calling: Type.field_with_guard('posts')")
-    end
-    end
-
     it 'returns false for a not authorized field' do
       posts_field = PolicyObject::QueryType.field_with_guard('posts', PolicyObject::GraphqlPolicy)
       user = User.new(id: '1', role: 'admin')
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index 129e314..f19d8ec 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -2,8 +2,6 @@
 
 require "bundler/setup"
 
-ENV['GRAPHQL_RUBY_VERSION'] ||= 'LATEST'
-
 if ENV['CI']
   require 'simplecov'
   SimpleCov.add_filter('spec')

From 975c9e3f46aa5822920a353700d6163caf3d2937 Mon Sep 17 00:00:00 2001
From: exAspArk 
Date: Mon, 6 Apr 2020 13:47:11 -0400
Subject: [PATCH 2/3] Add support for GraphQL gem version 1.10+ with the
 Interpreter

---
 .travis.yml                                   |   4 +-
 Gemfile                                       |   5 +-
 README.md                                     | 106 +++++++-----------
 graphql-guard.gemspec                         |   4 +-
 graphql-latest.gemfile                        |   8 --
 lib/graphql/guard.rb                          |  89 +++++++--------
 lib/graphql/guard/field_extension.rb          |  16 +++
 lib/graphql/guard/testing.rb                  |  27 +----
 spec/fixtures/inline_schema.rb                |  11 +-
 .../inline_without_exceptions_schema.rb       |  29 +++++
 spec/fixtures/policy_object_schema.rb         |   4 +-
 spec/fixtures/without_interpreter_schema.rb   |  16 +++
 spec/graphql/guard_spec.rb                    |  29 +++--
 spec/graphql/testing_spec.rb                  |  10 +-
 14 files changed, 180 insertions(+), 178 deletions(-)
 delete mode 100644 graphql-latest.gemfile
 create mode 100644 lib/graphql/guard/field_extension.rb
 create mode 100644 spec/fixtures/inline_without_exceptions_schema.rb
 create mode 100644 spec/fixtures/without_interpreter_schema.rb

diff --git a/.travis.yml b/.travis.yml
index 269a9ea..3c7589c 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,6 +1,6 @@
 sudo: false
 language: ruby
-before_install: gem install bundler -v 1.17.3
+before_install: gem install bundler -v 2.1.4
 rvm:
   - 2.3.8
   - 2.4.9
@@ -9,5 +9,3 @@ rvm:
   - 2.7.0
 env:
   - CI=true
-gemfile:
-  - graphql-latest.gemfile
diff --git a/Gemfile b/Gemfile
index ade3400..e041f73 100644
--- a/Gemfile
+++ b/Gemfile
@@ -1,8 +1,9 @@
 source "https://rubygems.org"
 
-gem "pry"
-
 gem "graphql", "~> 1.10"
 
+gem "pry"
+gem 'coveralls'
+
 # Specify your gem's dependencies in graphql-guard.gemspec
 gemspec
diff --git a/README.md b/README.md
index b64d7cb..2dc0757 100644
--- a/README.md
+++ b/README.md
@@ -36,32 +36,31 @@ Define a GraphQL schema:
 
 ```ruby
 # Define a type
-PostType = GraphQL::ObjectType.define do
-  name "Post"
-
-  field :id, !types.ID
-  field :title, types.String
+class PostType < GraphQL::Schema::Object
+  field :id, ID, null: false
+  field :title, String, null: true
 end
 
 # Define a query
-QueryType = GraphQL::ObjectType.define do
-  name "Query"
+class QueryType < GraphQL::Schema::Object
+  field :posts, [PostType], null: false do
+    argument :user_id, ID, required: true
+  end
 
-  field :posts, !types[!PostType] do
-    argument :user_id, !types.ID
-    resolve ->(obj, args, ctx) { Post.where(user_id: args[:user_id]) }
+  def posts(user_id:)
+    Post.where(user_id: user_id)
   end
 end
 
 # Define a schema
-Schema = GraphQL::Schema.define do
+class Schema < GraphQL::Schema
   use GraphQL::Execution::Interpreter
   use GraphQL::Analysis::AST
   query QueryType
 end
 
 # Execute query
-Schema.execute(query, variables: { user_id: 1 }, context: { current_user: current_user })
+Schema.execute(query, variables: { userId: 1 }, context: { current_user: current_user })
 ```
 
 ### Inline policies
@@ -69,7 +68,7 @@ Schema.execute(query, variables: { user_id: 1 }, context: { current_user: curren
 Add `GraphQL::Guard` to your schema:
 
 
-Schema = GraphQL::Schema.define do
+class Schema < GraphQL::Schema
   use GraphQL::Execution::Interpreter
   use GraphQL::Analysis::AST
   query QueryType
@@ -80,22 +79,19 @@ end
 Now you can define `guard` for a field, which will check permissions before resolving the field:
 
 
-QueryType = GraphQL::ObjectType.define do
-  name "Query"
-
-  field :posts, !types[!PostType] do
-    argument :user_id, !types.ID
+class QueryType < GraphQL::Schema::Object
+  field :posts, [PostType], null: false do
+    argument :user_id, ID, required: true
     guard ->(obj, args, ctx) { args[:user_id] == ctx[:current_user].id }
-    ...
   end
+  ...
 end
 
You can also define `guard`, which will be executed for every `*` field in the type:
-PostType = GraphQL::ObjectType.define do
-  name "Post"
+class PostType < GraphQL::Schema::Object
   guard ->(obj, args, ctx) { ctx[:current_user].admin? }
   ...
 end
@@ -124,27 +120,10 @@ class GraphqlPolicy
 end
 
-With `graphql-ruby` gem version >= 1.8 and class-based type definitions, use `camelCased` field names in the policy object. -You'd also need to use `type.metadata` (related to [rmosolgo/graphql-ruby#1429](https://github.com/rmosolgo/graphql-ruby/issues/1429)) to get the type class: - -
-class GraphqlPolicy
-  RULES = {
-    MutationType => {
-      createPost: ->(obj, args, cts) { ctx[:current_user].admin? }
-    }
-  }
-
-  def self.guard(type, field)
-    RULES.dig(type.metadata[:type_class], field)
-  end
-end
-
- Pass this object to `GraphQL::Guard`:
-Schema = GraphQL::Schema.define do
+class Schema < GraphQL::Schema
   use GraphQL::Execution::Interpreter
   use GraphQL::Analysis::AST
   query QueryType
@@ -173,8 +152,8 @@ end
 class GraphqlPolicy
   RULES = {
     PostType => {
-      '*': ->(obj, args, ctx) { ctx[:current_user].admin? },                           # <=== 4
-      title: ->(obj, args, ctx) { ctx[:current_user].admin? }                          # <=== 2
+      '*': ->(obj, args, ctx) { ctx[:current_user].admin? },                                # <=== 4
+      title: ->(obj, args, ctx) { ctx[:current_user].admin? }                               # <=== 2
     }
   }
 
@@ -183,13 +162,12 @@ class GraphqlPolicy
   end
 end
 
-PostType = GraphQL::ObjectType.define do
-  name "Post"
-  guard ->(obj, args, ctx) { ctx[:current_user].admin? }                               # <=== 3
-  field :title, !types.String, guard: ->(obj, args, ctx) { ctx[:current_user].admin? } # <=== 1
+class PostType < GraphQL::Schema::Object
+  guard ->(obj, args, ctx) { ctx[:current_user].admin? }                                    # <=== 3
+  field :title, String, null: true, guard: ->(obj, args, ctx) { ctx[:current_user].admin? } # <=== 1
 end
 
-Schema = GraphQL::Schema.define do
+class Schema < GraphQL::Schema
   use GraphQL::Execution::Interpreter
   use GraphQL::Analysis::AST
   query QueryType
@@ -219,8 +197,7 @@ class Ability
 end
 
 # Use the ability in your guard
-PostType = GraphQL::ObjectType.define do
-  name "Post"
+class PostType < GraphQL::Schema::Object
   guard ->(post, args, ctx) { ctx[:current_ability].can?(:read, post) }
   ...
 end
@@ -240,8 +217,7 @@ class PostPolicy < ApplicationPolicy
 end
 
 # Use the ability in your guard
-PostType = GraphQL::ObjectType.define do
-  name "Post"
+class PostType < GraphQL::Schema::Object
   guard ->(post, args, ctx) { PostPolicy.new(ctx[:current_user], post).show? }
   ...
 end
@@ -256,16 +232,20 @@ By default `GraphQL::Guard` raises a `GraphQL::Guard::NotAuthorizedError` except
 You can change this behavior, by passing custom `not_authorized` lambda. For example:
 
 
-SchemaWithErrors = GraphQL::Schema.define do
+class SchemaWithErrors < GraphQL::Schema
   use GraphQL::Execution::Interpreter
   use GraphQL::Analysis::AST
   query QueryType
   use GraphQL::Guard.new(
     # By default it raises an error
-    # not_authorized: ->(type, field) { raise GraphQL::Guard::NotAuthorizedError.new("#{type}.#{field}") }
+    # not_authorized: ->(type, field) do
+    #   raise GraphQL::Guard::NotAuthorizedError.new("#{type.graphql_definition}.#{field}")
+    # end
 
     # Returns an error in the response
-    not_authorized: ->(type, field) { GraphQL::ExecutionError.new("Not authorized to access #{type}.#{field}") }
+    not_authorized: ->(type, field) do
+      GraphQL::ExecutionError.new("Not authorized to access #{type.graphql_definition}.#{field}")
+    end
   )
 end
 
@@ -310,7 +290,7 @@ class GraphqlPolicy end end -Schema = GraphQL::Schema.define do +class Schema < GraphQL::Schema use GraphQL::Execution::Interpreter use GraphQL::Analysis::AST query QueryType @@ -331,11 +311,9 @@ end It's possible to hide fields from being introspectable and accessible based on the context. For example:
-PostType = GraphQL::ObjectType.define do
-  name "Post"
-
-  field :id, !types.ID
-  field :title, types.String do
+class PostType < GraphQL::Schema::Object
+  field :id, ID, null: false
+  field :title, String, null: true do
     # The field "title" is accessible only for beta testers
     mask ->(ctx) { ctx[:current_user].beta_tester? }
   end
@@ -364,9 +342,8 @@ It's possible to test fields with `guard` in isolation:
 
 
 # Your type
-QueryType = GraphQL::ObjectType.define do
-  name "Query"
-  field :posts, !types[!PostType], guard ->(obj, args, ctx) { ... }
+class QueryType < GraphQL::Schema::Object
+  field :posts, [PostType], null: false, guard ->(obj, args, ctx) { ... }
 end
 
 # Your test
@@ -382,9 +359,8 @@ If you would like to test your fields with policy objects:
 
 
 # Your type
-QueryType = GraphQL::ObjectType.define do
-  name "Query"
-  field :posts, !types[!PostType]
+class QueryType < GraphQL::Schema::Object
+  field :posts, [PostType], null: false
 end
 
 # Your policy object
diff --git a/graphql-guard.gemspec b/graphql-guard.gemspec
index cd70074..f8dcec2 100644
--- a/graphql-guard.gemspec
+++ b/graphql-guard.gemspec
@@ -23,9 +23,9 @@ Gem::Specification.new do |spec|
 
   spec.required_ruby_version = '>= 2.1.0' # keyword args
 
-  spec.add_runtime_dependency "graphql", ">= 1.6.0", "< 2"
+  spec.add_runtime_dependency "graphql", ">= 1.10.0", "< 2"
 
-  spec.add_development_dependency "bundler", "~> 1.15"
+  spec.add_development_dependency "bundler", "~> 2.1"
   spec.add_development_dependency "rake", "~> 13.0"
   spec.add_development_dependency "rspec", "~> 3.0"
 end
diff --git a/graphql-latest.gemfile b/graphql-latest.gemfile
deleted file mode 100644
index 67ae9ad..0000000
--- a/graphql-latest.gemfile
+++ /dev/null
@@ -1,8 +0,0 @@
-source "https://rubygems.org"
-
-gem "pry"
-gem 'coveralls'
-
-gem "graphql", "~> 1.10"
-
-gemspec
diff --git a/lib/graphql/guard.rb b/lib/graphql/guard.rb
index b059293..26a33d3 100644
--- a/lib/graphql/guard.rb
+++ b/lib/graphql/guard.rb
@@ -1,14 +1,23 @@
 # frozen_string_literal: true
 
 require "graphql"
+require "graphql/guard/field_extension"
 require "graphql/guard/version"
 
 module GraphQL
   class Guard
+    NotAuthorizedError = Class.new(StandardError)
+
     ANY_FIELD_NAME = :'*'
-    DEFAULT_NOT_AUTHORIZED = ->(type, field) { raise NotAuthorizedError.new("Not authorized to access: #{type}.#{field}") }
 
-    NotAuthorizedError = Class.new(StandardError)
+    DEFAULT_NOT_AUTHORIZED = ->(type, field) do
+      raise NotAuthorizedError.new("Not authorized to access: #{type.graphql_definition}.#{field}")
+    end
+
+    MASKING_FILTER = ->(schema_member, ctx) do
+      mask = schema_member.graphql_definition.metadata[:mask]
+      mask ? mask.call(ctx) : true
+    end
 
     attr_reader :policy_object, :not_authorized
 
@@ -18,75 +27,53 @@ def initialize(policy_object: nil, not_authorized: DEFAULT_NOT_AUTHORIZED)
     end
 
     def use(schema_definition)
-      schema_definition.instrument(:field, self)
-      add_schema_masking!(schema_definition)
-    end
-
-    def instrument(type, field)
-      guard_proc = guard_proc(type, field)
-      return field unless guard_proc
-
-      old_resolve_proc = field.resolve_proc
-      new_resolve_proc = ->(object, arguments, context) do
-        authorized = guard_proc.call(object, arguments, context)
-
-        if authorized
-          old_resolve_proc.call(object, arguments, context)
-        else
-          not_authorized.call(type, field.name.to_sym)
+      if schema_definition.interpreter?
+        fields(schema_definition).each do |field|
+          field.type_class.extension(GraphQL::Guard::FieldExtension, guard_instance: self)
         end
+      else
+        raise "Please use the graphql gem version >= 1.10 with GraphQL::Execution::Interpreter"
       end
 
-      field.redefine { resolve(new_resolve_proc) }
+      add_schema_masking!(schema_definition)
     end
 
-    def guard_proc(type, field)
-      inline_field_guard(field) ||
+    def find_guard_proc(type, field)
+      inline_guard(field) ||
         policy_object_guard(type, field.name.to_sym) ||
-        inline_type_guard(type) ||
+        inline_guard(type) ||
         policy_object_guard(type, ANY_FIELD_NAME)
     end
 
     private
 
+    def fields(schema_definition)
+      schema_definition.types.values.flat_map { |type|
+        type.fields.values if type.name && type.respond_to?(:fields)
+      }.compact
+    end
+
     def add_schema_masking!(schema_definition)
-      default_filter_proc = Proc.new do
-        def default_filter
-          GraphQL::Filter.new(except: default_mask).merge(only: ->(schema_member, ctx) {
-            schema_member.metadata[:mask] ? schema_member.metadata[:mask].call(ctx) : true
-          })
+      schema_definition.class_eval do
+        def self.default_filter
+          GraphQL::Filter.new(except: default_mask).merge(only: MASKING_FILTER)
         end
       end
-
-      if schema_definition.is_a?(Class) # GraphQL-Ruby version >= 1.10
-        schema_definition.class_eval(&default_filter_proc)
-      else
-        schema_definition.target.instance_eval(&default_filter_proc)
-      end
     end
 
     def policy_object_guard(type, field_name)
-      policy_object && policy_object.guard(type, field_name)
+      @policy_object && @policy_object.guard(type.type_class, field_name)
     end
 
-    def inline_field_guard(field)
-      field.metadata[:guard]
-    end
-
-    def inline_type_guard(type)
-      type.metadata[:guard]
+    def inline_guard(type_or_field)
+      type_or_field.graphql_definition.metadata[:guard]
     end
   end
 end
 
-if GraphQL::ObjectType.respond_to?(:accepts_definitions) # GraphQL-Ruby version < 1.8
-  GraphQL::ObjectType.accepts_definitions(guard: GraphQL::Define.assign_metadata_key(:guard))
-  GraphQL::Field.accepts_definitions(guard: GraphQL::Define.assign_metadata_key(:guard))
-  GraphQL::Field.accepts_definitions(mask: GraphQL::Define.assign_metadata_key(:mask))
-end
-
-if defined?(GraphQL::Schema::Object) && GraphQL::Schema::Object.respond_to?(:accepts_definition) # GraphQL-Ruby version >= 1.8
-  GraphQL::Schema::Object.accepts_definition(:guard)
-  GraphQL::Schema::Field.accepts_definition(:guard)
-  GraphQL::Schema::Field.accepts_definition(:mask)
-end
+GraphQL::ObjectType.accepts_definitions(guard: GraphQL::Define.assign_metadata_key(:guard))
+GraphQL::Field.accepts_definitions(guard: GraphQL::Define.assign_metadata_key(:guard))
+GraphQL::Field.accepts_definitions(mask: GraphQL::Define.assign_metadata_key(:mask))
+GraphQL::Schema::Object.accepts_definition(:guard)
+GraphQL::Schema::Field.accepts_definition(:guard)
+GraphQL::Schema::Field.accepts_definition(:mask)
diff --git a/lib/graphql/guard/field_extension.rb b/lib/graphql/guard/field_extension.rb
new file mode 100644
index 0000000..c71f63f
--- /dev/null
+++ b/lib/graphql/guard/field_extension.rb
@@ -0,0 +1,16 @@
+module GraphQL
+  class Guard
+    class FieldExtension < GraphQL::Schema::FieldExtension
+      def resolve(object:, arguments:, **rest)
+        guard_proc = options[:guard_instance].find_guard_proc(field.owner, field)
+        return yield(object, arguments) unless guard_proc
+
+        if guard_proc.call(object, arguments, rest[:context])
+          yield(object, arguments)
+        else
+          options[:guard_instance].not_authorized.call(field.owner, field.name.to_sym)
+        end
+      end
+    end
+  end
+end
diff --git a/lib/graphql/guard/testing.rb b/lib/graphql/guard/testing.rb
index e944d10..7c447bb 100644
--- a/lib/graphql/guard/testing.rb
+++ b/lib/graphql/guard/testing.rb
@@ -5,32 +5,18 @@ class Field
     NoGuardError = Class.new(StandardError)
 
     def guard(*args)
-      raise NoGuardError.new("Get your field by calling: Type.field_with_guard('#{name}')") unless @__guard_type
-      guard_proc = @__guard_object.guard_proc(@__guard_type, self)
+      raise NoGuardError.new("Get your field by calling: Type.field_with_guard('#{name}')") unless @__guard_instance
+
+      guard_proc = @__guard_instance.find_guard_proc(@__guard_type, self)
       raise NoGuardError.new("Guard lambda does not exist for #{@__guard_type}.#{name}") unless guard_proc
 
       guard_proc.call(*args)
     end
 
-    def __policy_object=(policy_object)
+    def __set_guard_instance(policy_object, guard_type)
       @__policy_object = policy_object
-      @__guard_object = GraphQL::Guard.new(policy_object: policy_object)
-    end
-
-    def __guard_type=(guard_type)
       @__guard_type = guard_type
-    end
-  end
-
-  class ObjectType
-    def field_with_guard(field_name, policy_object = nil)
-      field = get_field(field_name)
-      return unless field
-
-      field.clone.tap do |f|
-        f.__policy_object = policy_object
-        f.__guard_type = self
-      end
+      @__guard_instance = GraphQL::Guard.new(policy_object: policy_object)
     end
   end
 
@@ -41,8 +27,7 @@ def self.field_with_guard(field_name, policy_object = nil)
         return unless field
 
         field.to_graphql.clone.tap do |f|
-          f.__policy_object = policy_object
-          f.__guard_type = self.to_graphql
+          f.__set_guard_instance(policy_object, self.to_graphql)
         end
       end
     end
diff --git a/spec/fixtures/inline_schema.rb b/spec/fixtures/inline_schema.rb
index d2854a4..9d52f53 100644
--- a/spec/fixtures/inline_schema.rb
+++ b/spec/fixtures/inline_schema.rb
@@ -10,7 +10,7 @@ class PostType < GraphQL::Schema::Object
   class QueryType < GraphQL::Schema::Object
     field :posts, [PostType], null: false do
       argument :user_id, ID, required: true
-      guard ->(_obj, args, ctx) { args[:userId] == ctx[:current_user].id }
+      guard ->(_obj, args, ctx) { args[:user_id] == ctx[:current_user].id }
     end
 
     field :posts_with_mask, [PostType], null: false do
@@ -33,13 +33,4 @@ class Schema < GraphQL::Schema
     query QueryType
     use GraphQL::Guard.new
   end
-
-  class SchemaWithoutExceptions < GraphQL::Schema
-    use GraphQL::Execution::Interpreter
-    use GraphQL::Analysis::AST
-    query QueryType
-    use GraphQL::Guard.new(not_authorized: ->(type, field) {
-      GraphQL::ExecutionError.new("Not authorized to access #{type}.#{field}")
-    })
-  end
 end
diff --git a/spec/fixtures/inline_without_exceptions_schema.rb b/spec/fixtures/inline_without_exceptions_schema.rb
new file mode 100644
index 0000000..1af7776
--- /dev/null
+++ b/spec/fixtures/inline_without_exceptions_schema.rb
@@ -0,0 +1,29 @@
+# frozen_string_literal: true
+
+module InlineWithoutExceptions
+  class PostType < GraphQL::Schema::Object
+    guard ->(_post, _args, ctx) { ctx[:current_user].admin? }
+    field :id, ID, null: false
+    field :title, String, null: true
+  end
+
+  class QueryType < GraphQL::Schema::Object
+    field :posts, [PostType], null: false do
+      argument :user_id, ID, required: true
+      guard ->(_obj, args, ctx) { args[:user_id] == ctx[:current_user].id }
+    end
+
+    def posts(user_id:)
+      Post.where(user_id: user_id)
+    end
+  end
+
+  class Schema < GraphQL::Schema
+    use GraphQL::Execution::Interpreter
+    use GraphQL::Analysis::AST
+    query QueryType
+    use GraphQL::Guard.new(not_authorized: ->(type, field) {
+      GraphQL::ExecutionError.new("Not authorized to access #{type.graphql_definition}.#{field}")
+    })
+  end
+end
diff --git a/spec/fixtures/policy_object_schema.rb b/spec/fixtures/policy_object_schema.rb
index 9e43770..fa9e67a 100644
--- a/spec/fixtures/policy_object_schema.rb
+++ b/spec/fixtures/policy_object_schema.rb
@@ -19,7 +19,7 @@ def posts(user_id:)
   class GraphqlPolicy
     RULES = {
       QueryType => {
-        posts: ->(_obj, args, ctx) { args[:userId] == ctx[:current_user].id }
+        posts: ->(_obj, args, ctx) { args[:user_id] == ctx[:current_user].id }
       },
       PostType => {
         '*': ->(_post, args, ctx) { ctx[:current_user].admin? }
@@ -27,7 +27,7 @@ class GraphqlPolicy
     }
 
     def self.guard(type, field)
-      RULES.dig(type.metadata[:type_class], field)
+      RULES.dig(type, field)
     end
   end
 
diff --git a/spec/fixtures/without_interpreter_schema.rb b/spec/fixtures/without_interpreter_schema.rb
new file mode 100644
index 0000000..c332bd1
--- /dev/null
+++ b/spec/fixtures/without_interpreter_schema.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+module WithoutInterpreter
+  class QueryType < GraphQL::Schema::Object
+    field :userIds, [String], null: false
+
+    def user_ids
+      ['1', '2']
+    end
+  end
+
+  class Schema < GraphQL::Schema
+    query QueryType
+    use GraphQL::Guard.new
+  end
+end
diff --git a/spec/graphql/guard_spec.rb b/spec/graphql/guard_spec.rb
index 2e984fb..5f7da88 100644
--- a/spec/graphql/guard_spec.rb
+++ b/spec/graphql/guard_spec.rb
@@ -5,6 +5,7 @@
 require 'fixtures/user'
 require 'fixtures/post'
 require 'fixtures/inline_schema'
+require 'fixtures/inline_without_exceptions_schema'
 require 'fixtures/policy_object_schema'
 
 RSpec.describe GraphQL::Guard do
@@ -13,7 +14,7 @@
       user = User.new(id: '1', role: 'admin')
       query = "query($userId: ID!) { posts(userId: $userId) { id title } }"
 
-      result = Inline::Schema.execute(query, variables: {'userId' => user.id}, context: {current_user: user})
+      result = Inline::Schema.execute(query, variables: {userId: user.id}, context: {current_user: user})
 
       expect(result).to eq({"data" => {"posts" => [{"id" => "1", "title" => "Post Title"}]}})
     end
@@ -23,7 +24,7 @@
       query = "query($userId: ID!) { posts(userId: $userId) { id title } }"
 
       expect {
-        Inline::Schema.execute(query, variables: {'userId' => '2'}, context: {current_user: user})
+        Inline::Schema.execute(query, variables: {userId: 2}, context: {current_user: user})
       }.to raise_error(GraphQL::Guard::NotAuthorizedError, 'Not authorized to access: Query.posts')
     end
 
@@ -32,7 +33,7 @@
       query = "query($userId: ID!) { posts(userId: $userId) { id title } }"
 
       expect {
-        Inline::Schema.execute(query, variables: {'userId' => '1'}, context: {current_user: user})
+        Inline::Schema.execute(query, variables: {userId: 1}, context: {current_user: user})
       }.to raise_error(GraphQL::Guard::NotAuthorizedError, 'Not authorized to access: Post.id')
     end
 
@@ -40,7 +41,7 @@
       user = User.new(id: '1', role: 'not_admin')
       query = "query($userId: ID!) { posts(userId: $userId) { id title } }"
 
-      result = Inline::SchemaWithoutExceptions.execute(query, variables: {'userId' => '1'}, context: {current_user: user})
+      result = InlineWithoutExceptions::Schema.execute(query, variables: {userId: 1}, context: {current_user: user})
 
       expect(result['errors']).to eq([{
         "message" => "Not authorized to access Post.id",
@@ -56,7 +57,7 @@
       user = User.new(id: '1', role: 'admin')
       query = "query($userId: ID!) { postsWithMask(userId: $userId) { id } }"
 
-      result = Inline::Schema.execute(query, variables: {'userId' => user.id}, context: {current_user: user})
+      result = Inline::Schema.execute(query, variables: {userId: user.id}, context: {current_user: user})
 
       expect(result.to_h).to eq({"data" => {"postsWithMask" => [{"id" => "1"}]}})
     end
@@ -65,7 +66,7 @@
       user = User.new(id: '1', role: 'not_admin')
       query = "query($userId: ID!) { postsWithMask(userId: $userId) { id } }"
 
-      result = Inline::Schema.execute(query, variables: {'userId' => user.id}, context: {current_user: user})
+      result = Inline::Schema.execute(query, variables: {userId: user.id}, context: {current_user: user})
 
       expect(result['errors']).to include({
         "message" => "Field 'postsWithMask' doesn't exist on type 'Query'",
@@ -81,7 +82,7 @@
       user = User.new(id: '1', role: 'admin')
       query = "query($userId: ID!) { posts(userId: $userId) { id title } }"
 
-      result = PolicyObject::Schema.execute(query, variables: {'userId' => user.id}, context: {current_user: user})
+      result = PolicyObject::Schema.execute(query, variables: {userId: user.id}, context: {current_user: user})
 
       expect(result).to eq({"data" => {"posts" => [{"id" => "1", "title" => "Post Title"}]}})
     end
@@ -91,7 +92,7 @@
       query = "query($userId: ID!) { posts(userId: $userId) { id title } }"
 
       expect {
-        PolicyObject::Schema.execute(query, variables: {'userId' => '2'}, context: {current_user: user})
+        PolicyObject::Schema.execute(query, variables: {userId: 2}, context: {current_user: user})
       }.to raise_error(GraphQL::Guard::NotAuthorizedError, 'Not authorized to access: Query.posts')
     end
 
@@ -100,8 +101,18 @@
       query = "query($userId: ID!) { posts(userId: $userId) { id title } }"
 
       expect {
-        PolicyObject::Schema.execute(query, variables: {'userId' => '1'}, context: {current_user: user})
+        PolicyObject::Schema.execute(query, variables: {userId: 1}, context: {current_user: user})
       }.to raise_error(GraphQL::Guard::NotAuthorizedError, 'Not authorized to access: Post.id')
     end
   end
+
+  context 'schema without interpreter' do
+    it 'raises an exception' do
+      query = "query { userIds }"
+
+      expect {
+        require 'fixtures/without_interpreter_schema'
+      }.to raise_error('Please use the graphql gem version >= 1.10 with GraphQL::Execution::Interpreter')
+    end
+  end
 end
diff --git a/spec/graphql/testing_spec.rb b/spec/graphql/testing_spec.rb
index 31df319..302f69f 100644
--- a/spec/graphql/testing_spec.rb
+++ b/spec/graphql/testing_spec.rb
@@ -15,7 +15,7 @@
       posts_field = Inline::QueryType.field_with_guard('posts')
       user = User.new(id: '1', role: 'admin')
 
-      result = posts_field.guard(nil, {userId: user.id}, {current_user: user})
+      result = posts_field.guard(nil, {user_id: user.id}, {current_user: user})
 
       expect(result).to eq(true)
     end
@@ -24,7 +24,7 @@
       posts_field = Inline::QueryType.field_with_guard('posts')
       user = User.new(id: '1', role: 'admin')
 
-      result = posts_field.guard(nil, {userId: '2'}, {current_user: user})
+      result = posts_field.guard(nil, {user_id: '2'}, {current_user: user})
 
       expect(result).to eq(false)
     end
@@ -44,7 +44,7 @@
       posts_field = PolicyObject::QueryType.field_with_guard('posts', PolicyObject::GraphqlPolicy)
       user = User.new(id: '1', role: 'admin')
 
-      result = posts_field.guard(nil, {userId: user.id}, {current_user: user})
+      result = posts_field.guard(nil, {user_id: user.id}, {current_user: user})
 
       expect(result).to eq(true)
     end
@@ -54,7 +54,7 @@
       user = User.new(id: '1', role: 'admin')
 
       expect {
-        posts_field.guard(nil, {userId: user.id}, {current_user: user})
+        posts_field.guard(nil, {user_id: user.id}, {current_user: user})
       }.to raise_error(GraphQL::Field::NoGuardError, "Guard lambda does not exist for Query.posts")
     end
 
@@ -62,7 +62,7 @@
       posts_field = PolicyObject::QueryType.field_with_guard('posts', PolicyObject::GraphqlPolicy)
       user = User.new(id: '1', role: 'admin')
 
-      result = posts_field.guard(nil, {userId: '2'}, {current_user: user})
+      result = posts_field.guard(nil, {user_id: '2'}, {current_user: user})
 
       expect(result).to eq(false)
     end

From 538a157a90930aa07f4b04c88f7f31e1bedfb003 Mon Sep 17 00:00:00 2001
From: exAspArk 
Date: Wed, 8 Apr 2020 11:35:24 -0400
Subject: [PATCH 3/3] Use trace GraphQL API instead of field extension

---
 lib/graphql/guard.rb                          | 32 +++++++++++++------
 lib/graphql/guard/field_extension.rb          | 16 ----------
 spec/fixtures/inline_schema.rb                |  9 ++++++
 .../inline_without_exceptions_schema.rb       | 29 -----------------
 spec/graphql/guard_spec.rb                    |  3 +-
 5 files changed, 32 insertions(+), 57 deletions(-)
 delete mode 100644 lib/graphql/guard/field_extension.rb
 delete mode 100644 spec/fixtures/inline_without_exceptions_schema.rb

diff --git a/lib/graphql/guard.rb b/lib/graphql/guard.rb
index 26a33d3..f94464d 100644
--- a/lib/graphql/guard.rb
+++ b/lib/graphql/guard.rb
@@ -1,7 +1,6 @@
 # frozen_string_literal: true
 
 require "graphql"
-require "graphql/guard/field_extension"
 require "graphql/guard/version"
 
 module GraphQL
@@ -9,6 +8,7 @@ class Guard
     NotAuthorizedError = Class.new(StandardError)
 
     ANY_FIELD_NAME = :'*'
+    EXECUTE_FIELD_EVENTS = %w[execute_field execute_field_lazy]
 
     DEFAULT_NOT_AUTHORIZED = ->(type, field) do
       raise NotAuthorizedError.new("Not authorized to access: #{type.graphql_definition}.#{field}")
@@ -28,9 +28,7 @@ def initialize(policy_object: nil, not_authorized: DEFAULT_NOT_AUTHORIZED)
 
     def use(schema_definition)
       if schema_definition.interpreter?
-        fields(schema_definition).each do |field|
-          field.type_class.extension(GraphQL::Guard::FieldExtension, guard_instance: self)
-        end
+        schema_definition.tracer(self)
       else
         raise "Please use the graphql gem version >= 1.10 with GraphQL::Execution::Interpreter"
       end
@@ -38,6 +36,14 @@ def use(schema_definition)
       add_schema_masking!(schema_definition)
     end
 
+    def trace(event, trace_data)
+      if EXECUTE_FIELD_EVENTS.include?(event)
+        ensure_guarded(trace_data) { yield }
+      else
+        yield
+      end
+    end
+
     def find_guard_proc(type, field)
       inline_guard(field) ||
         policy_object_guard(type, field.name.to_sym) ||
@@ -47,12 +53,6 @@ def find_guard_proc(type, field)
 
     private
 
-    def fields(schema_definition)
-      schema_definition.types.values.flat_map { |type|
-        type.fields.values if type.name && type.respond_to?(:fields)
-      }.compact
-    end
-
     def add_schema_masking!(schema_definition)
       schema_definition.class_eval do
         def self.default_filter
@@ -61,6 +61,18 @@ def self.default_filter
       end
     end
 
+    def ensure_guarded(trace_data)
+      field = trace_data[:field]
+      guard_proc = find_guard_proc(field.owner, field)
+      return yield unless guard_proc
+
+      if guard_proc.call(trace_data[:object], trace_data[:arguments], trace_data[:query].context)
+        yield
+      else
+        not_authorized.call(field.owner, field.name.to_sym)
+      end
+    end
+
     def policy_object_guard(type, field_name)
       @policy_object && @policy_object.guard(type.type_class, field_name)
     end
diff --git a/lib/graphql/guard/field_extension.rb b/lib/graphql/guard/field_extension.rb
deleted file mode 100644
index c71f63f..0000000
--- a/lib/graphql/guard/field_extension.rb
+++ /dev/null
@@ -1,16 +0,0 @@
-module GraphQL
-  class Guard
-    class FieldExtension < GraphQL::Schema::FieldExtension
-      def resolve(object:, arguments:, **rest)
-        guard_proc = options[:guard_instance].find_guard_proc(field.owner, field)
-        return yield(object, arguments) unless guard_proc
-
-        if guard_proc.call(object, arguments, rest[:context])
-          yield(object, arguments)
-        else
-          options[:guard_instance].not_authorized.call(field.owner, field.name.to_sym)
-        end
-      end
-    end
-  end
-end
diff --git a/spec/fixtures/inline_schema.rb b/spec/fixtures/inline_schema.rb
index 9d52f53..1b7d7ad 100644
--- a/spec/fixtures/inline_schema.rb
+++ b/spec/fixtures/inline_schema.rb
@@ -33,4 +33,13 @@ class Schema < GraphQL::Schema
     query QueryType
     use GraphQL::Guard.new
   end
+
+  class SchemaWithoutExceptions < GraphQL::Schema
+    use GraphQL::Execution::Interpreter
+    use GraphQL::Analysis::AST
+    query QueryType
+    use GraphQL::Guard.new(not_authorized: ->(type, field) {
+      GraphQL::ExecutionError.new("Not authorized to access #{type.graphql_definition}.#{field}")
+    })
+  end
 end
diff --git a/spec/fixtures/inline_without_exceptions_schema.rb b/spec/fixtures/inline_without_exceptions_schema.rb
deleted file mode 100644
index 1af7776..0000000
--- a/spec/fixtures/inline_without_exceptions_schema.rb
+++ /dev/null
@@ -1,29 +0,0 @@
-# frozen_string_literal: true
-
-module InlineWithoutExceptions
-  class PostType < GraphQL::Schema::Object
-    guard ->(_post, _args, ctx) { ctx[:current_user].admin? }
-    field :id, ID, null: false
-    field :title, String, null: true
-  end
-
-  class QueryType < GraphQL::Schema::Object
-    field :posts, [PostType], null: false do
-      argument :user_id, ID, required: true
-      guard ->(_obj, args, ctx) { args[:user_id] == ctx[:current_user].id }
-    end
-
-    def posts(user_id:)
-      Post.where(user_id: user_id)
-    end
-  end
-
-  class Schema < GraphQL::Schema
-    use GraphQL::Execution::Interpreter
-    use GraphQL::Analysis::AST
-    query QueryType
-    use GraphQL::Guard.new(not_authorized: ->(type, field) {
-      GraphQL::ExecutionError.new("Not authorized to access #{type.graphql_definition}.#{field}")
-    })
-  end
-end
diff --git a/spec/graphql/guard_spec.rb b/spec/graphql/guard_spec.rb
index 5f7da88..158394e 100644
--- a/spec/graphql/guard_spec.rb
+++ b/spec/graphql/guard_spec.rb
@@ -5,7 +5,6 @@
 require 'fixtures/user'
 require 'fixtures/post'
 require 'fixtures/inline_schema'
-require 'fixtures/inline_without_exceptions_schema'
 require 'fixtures/policy_object_schema'
 
 RSpec.describe GraphQL::Guard do
@@ -41,7 +40,7 @@
       user = User.new(id: '1', role: 'not_admin')
       query = "query($userId: ID!) { posts(userId: $userId) { id title } }"
 
-      result = InlineWithoutExceptions::Schema.execute(query, variables: {userId: 1}, context: {current_user: user})
+      result = Inline::SchemaWithoutExceptions.execute(query, variables: {userId: 1}, context: {current_user: user})
 
       expect(result['errors']).to eq([{
         "message" => "Not authorized to access Post.id",