Skip to content

Commit

Permalink
upgrade graphql to latest 1.0, remove graphql-guard
Browse files Browse the repository at this point in the history
  • Loading branch information
kylesferrazza committed May 7, 2023
1 parent c4330de commit 02225e3
Show file tree
Hide file tree
Showing 8 changed files with 68 additions and 28 deletions.
3 changes: 1 addition & 2 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,8 @@ gem 'rails', '~> 6.1'
# Use postgresql as the database for Active Record
gem 'pg', '>= 0.18', '< 2.0'

gem 'graphql', '~> 1.12.17'
gem 'graphql', '~> 1.0'
gem 'graphql-batch'
gem 'graphql-guard'

# Transpile app-like JavaScript. Read more: https://github.com/rails/webpacker
gem 'webpacker', '~> 6.0.0.rc.5'
Expand Down
7 changes: 2 additions & 5 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -137,12 +137,10 @@ GEM
ffi (1.15.5)
globalid (1.1.0)
activesupport (>= 5.0)
graphql (1.12.24)
graphql (1.13.19)
graphql-batch (0.5.2)
graphql (>= 1.10, < 3)
promise.rb (~> 0.7.2)
graphql-guard (2.0.0)
graphql (>= 1.10.0, < 2)
hana (1.3.7)
hashie (5.0.0)
headless (2.3.1)
Expand Down Expand Up @@ -366,9 +364,8 @@ DEPENDENCIES
database_cleaner
devise (~> 4.9.0)
factory_bot_rails
graphql (~> 1.12.17)
graphql (~> 1.0)
graphql-batch
graphql-guard
headless
json-schema (~> 4.0)
listen (~> 3.3)
Expand Down
20 changes: 10 additions & 10 deletions app/graphql/hourglass_schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@ class HourglassSchema < GraphQL::Schema
# Feedback and error messages in development mode will be
# more informative than in production/test modes.
if Rails.env.development?
use GraphQL::Guard.new(
not_authorized: lambda do |type, field|
GraphQL::ExecutionError.new("Not authorized to access #{type}.#{field}")
end,
)
# use GraphQL::Guard.new(
# not_authorized: lambda do |type, field|
# GraphQL::ExecutionError.new("Not authorized to access #{type}.#{field}")
# end,
# )

def self.unauthorized_object(error)
# Add a top-level error to the response instead of returning nil:
Expand All @@ -38,11 +38,11 @@ def self.execute(query_str = nil, **kwargs)
super(query_str, **kwargs)
end
else
use GraphQL::Guard.new(
not_authorized: lambda do |type, field|
GraphQL::ExecutionError.new("You do not have permission to view that data.")
end,
)
# use GraphQL::Guard.new(
# not_authorized: lambda do |type, field|
# GraphQL::ExecutionError.new("You do not have permission to view that data.")
# end,
# )

def self.unauthorized_object(error)
# Add a top-level error to the response instead of returning nil:
Expand Down
13 changes: 13 additions & 0 deletions app/graphql/types/base_field.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,18 @@
module Types
class BaseField < GraphQL::Schema::Field
argument_class Types::BaseArgument
def guard(proc)
@guard_proc = proc
end

def authorized?(obj, args, ctx)
return true unless @guard_proc

wrapped = Types::GuardWrapper.new(self, obj)
answer = @guard_proc.call(wrapped, args, ctx)
return true if answer

raise GraphQL::ExecutionError, "Not authorized to access #{self.owner_type.graphql_name}.#{self.graphql_name}."
end
end
end
23 changes: 23 additions & 0 deletions app/graphql/types/base_object.rb
Original file line number Diff line number Diff line change
@@ -1,10 +1,33 @@
# frozen_string_literal: true

module Types
class GuardWrapper
attr_accessor :class, :object

def initialize(cls, object)
@class = cls
@object = object
end
end

# The base class of Hourglass objects returned by GraphQL
class BaseObject < GraphQL::Schema::Object
field_class Types::BaseField

def self.guard(proc)
@guard_proc = proc
end

def self.authorized?(obj, ctx)
return true unless @guard_proc

wrapped = Types::GuardWrapper.new(self, obj)
answer = @guard_proc.call(wrapped, nil, ctx)
return true if answer

raise GraphQL::ExecutionError, "You do not have permission to view that information."
end

module Guards
def self.exam_role(user, ctx)
ctx[:access_cache]&.dig(:role_for_exam, user.id) || Exam.roles[:no_reg]
Expand Down
1 change: 0 additions & 1 deletion app/graphql/types/grading_comment_type.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,5 @@ def bnum
field :message, String, null: false
field :points, Float, null: false
field :creator, Types::UserType, null: false
field :preset_comment, Types::PresetCommentType, null: true
end
end
28 changes: 18 additions & 10 deletions app/graphql/types/grading_lock_type.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,31 @@
module Types
class GradingLockType < Types::BaseObject
implements GraphQL::Types::Relay::Node
global_id_field :id
field :id, ID, null: false, guard: ->(_obj, _args, _ctx) { true }
global_id_field :id

guard Guards::VISIBILITY
guard Guards::ALL_STAFF

field :registration, Types::RegistrationType, null: false
field :registration, Types::RegistrationType, null: false do
guard Guards::VISIBILITY
end
def registration
RecordLoader.for(Registration).load(object.registration_id)
end
field :grader, Types::UserType, null: true, guard: ->(obj, _args, ctx) {
obj.object.grader_id.nil? || obj.object.visible_to?(ctx[:current_user], Guards.exam_role(ctx[:current_user], ctx), Guards.course_role(ctx[:current_user], ctx))
}

field :grader, Types::UserType, null: true do
guard ->(obj, _args, ctx) {
obj.object.grader_id.nil? || obj.object.visible_to?(ctx[:current_user], Guards.exam_role(ctx[:current_user], ctx), Guards.course_role(ctx[:current_user], ctx))
}
end
def grader
RecordLoader.for(User).load(object.grader_id)
end
field :completed_by, Types::UserType, null: true, guard: ->(obj, _args, ctx) {
obj.object.completed_by_id.nil? || obj.object.visible_to?(ctx[:current_user], Guards.exam_role(ctx[:current_user], ctx), Guards.course_role(ctx[:current_user], ctx))
}

field :completed_by, Types::UserType, null: true do
guard ->(obj, _args, ctx) {
obj.object.completed_by_id.nil? || obj.object.visible_to?(ctx[:current_user], Guards.exam_role(ctx[:current_user], ctx), Guards.course_role(ctx[:current_user], ctx))
}
end
def completed_by
RecordLoader.for(User).load(object.completed_by_id)
end
Expand All @@ -29,6 +36,7 @@ def completed_by
def qnum
RecordLoader.for(Question).load(object.question_id).then{|q| q.index}
end

field :pnum, Integer, null: false
def pnum
RecordLoader.for(Part).load(object.part_id).then{|q| q.index}
Expand Down
1 change: 1 addition & 0 deletions app/models/grading_lock.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ def valid_qp

delegate :exam_version, to: :registration
delegate :exam, to: :registration
delegate :course, to: :exam

scope :incomplete, -> { where(completed_by: nil) }
scope :complete, -> { where.not(completed_by: nil) }
Expand Down

0 comments on commit 02225e3

Please sign in to comment.