Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Gem updates #456

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 5 additions & 6 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,17 @@ 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', '~> 2.0.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'

gem 'react-rails'

gem 'devise', '~> 4.8.0'
gem 'omniauth-bottlenose', git: 'https://github.com/CodeGrade/omniauth-bottlenose'
gem 'omniauth-oauth2', '~> 1.7.0'
gem 'devise', '~> 4.9.0'
gem 'omniauth-bottlenose', git: 'https://github.com/CodeGrade/omniauth-bottlenose', ref: '6202663'
gem 'omniauth-oauth2', '~> 1.8.0'
gem 'omniauth-rails_csrf_protection'

gem 'bootstrap_form', '>= 4.2.0'
Expand All @@ -44,7 +43,7 @@ gem 'pretender'
gem 'bootsnap', '>= 1.4.2', require: false

gem 'activerecord_json_validator', '~> 2.0'
gem 'json-schema', '~> 2.8'
gem 'json-schema', '~> 4.0'

gem 'listen', '~> 3.3'

Expand Down
30 changes: 14 additions & 16 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
GIT
remote: https://github.com/CodeGrade/omniauth-bottlenose
revision: 3e7c696c9b1da6823f5936a5bc7b061f3630720a
revision: 62026630bf96874214a3b20b2c859bad378a6d77
ref: 6202663
specs:
omniauth-bottlenose (0.1.0)
omniauth-oauth2 (~> 1.7.0)
omniauth-bottlenose (0.2.0)
omniauth-oauth2 (~> 1.8.0)

GEM
remote: https://rubygems.org/
Expand Down Expand Up @@ -114,7 +115,7 @@ GEM
database_cleaner-core (2.0.1)
date (3.3.3)
debug_inspector (1.1.0)
devise (4.8.1)
devise (4.9.2)
bcrypt (~> 3.0)
orm_adapter (~> 0.1)
railties (>= 4.1.0)
Expand All @@ -136,21 +137,19 @@ GEM
ffi (1.15.5)
globalid (1.1.0)
activesupport (>= 5.0)
graphql (1.12.24)
graphql (2.0.21)
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)
i18n (1.13.0)
concurrent-ruby (~> 1.0)
interception (0.5)
json (2.6.3)
json-schema (2.8.1)
addressable (>= 2.4)
json-schema (4.0.0)
addressable (>= 2.8)
json_schemer (0.2.24)
ecma-re-validator (~> 0.3)
hana (~> 1.3)
Expand Down Expand Up @@ -203,9 +202,9 @@ GEM
hashie (>= 3.4.6)
rack (>= 2.2.3)
rack-protection
omniauth-oauth2 (1.7.3)
omniauth-oauth2 (1.8.0)
oauth2 (>= 1.4, < 3)
omniauth (>= 1.9, < 3)
omniauth (~> 2.0)
omniauth-rails_csrf_protection (1.0.1)
actionpack (>= 4.2)
omniauth (~> 2.0)
Expand Down Expand Up @@ -363,17 +362,16 @@ DEPENDENCIES
byebug
capybara
database_cleaner
devise (~> 4.8.0)
devise (~> 4.9.0)
factory_bot_rails
graphql (~> 1.12.17)
graphql (~> 2.0.0)
graphql-batch
graphql-guard
headless
json-schema (~> 2.8)
json-schema (~> 4.0)
listen (~> 3.3)
minitest-reporters
omniauth-bottlenose!
omniauth-oauth2 (~> 1.7.0)
omniauth-oauth2 (~> 1.8.0)
omniauth-rails_csrf_protection
passenger (>= 5.3.2)
pg (>= 0.18, < 2.0)
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
4 changes: 2 additions & 2 deletions app/graphql/types/exam_version_type.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,15 @@ class ExamVersionType < Types::BaseObject
[ q, q.parts.map do |p| [p, p.body_items.to_a] end ]
end.flatten
all_qpbs.each do |qpb|
resolved = HourglassSchema.resolve_type(qpb.class, qpb, ctx)
resolved, _ = HourglassSchema.resolve_type(qpb.class, qpb, ctx)
Guards.cache(
ctx[:access_cache],
[resolved.name, qpb.id, :visible, ctx[:current_user].id],
ans,
)
end
[obj.object.rubrics, obj.object.db_references, obj.object.rubric_presets, obj.object.preset_comments].flatten.each do |r|
resolved = HourglassSchema.resolve_type(r.class, r, ctx)
resolved, _ = HourglassSchema.resolve_type(r.class, r, ctx)
Guards.cache(
ctx[:access_cache],
[resolved.name, r.id, :visible, ctx[:current_user].id],
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
4 changes: 2 additions & 2 deletions app/graphql/types/query_type.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ module Types
class QueryType < Types::BaseObject
# Add root-level fields here.
# They will be entry points for queries on your schema.
add_field(GraphQL::Types::Relay::NodeField)
add_field(GraphQL::Types::Relay::NodesField)
include GraphQL::Types::Relay::HasNodeField
include GraphQL::Types::Relay::HasNodesField

field :impersonating, Boolean, null: false
def impersonating
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
4 changes: 4 additions & 0 deletions lib/tasks/sample_data.rake
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ end
NUM_SIM_USERS = 1000

def create_simulation_users(lecture:, lab:, room:, exam_version:)
puts "Creating simulation users..."
(0..NUM_SIM_USERS).each do |i|
student = create(:user, username: "stresstest#{i}")
create(:student_registration, user: student, section: lecture)
Expand All @@ -26,13 +27,15 @@ end

def make_sample_data
ActiveRecord::Base.transaction do
puts "Loading sample data"
create(:admin, username: 'admin')
make_cs2500
make_cs3500
end
end

def make_cs2500
puts "Creating CS2500..."
fall2021 = create(:term, year: 2021, semester: Term.semesters['fall'])
cs2500 = create(:course, title: 'CS 2500', term: fall2021)
cs2500lec = create(:section, :lecture, course: cs2500)
Expand Down Expand Up @@ -82,6 +85,7 @@ def make_cs2500
end

def make_cs3500
puts "Creating CS3500..."
spring2022 = create(:term, year: 2022, semester: Term.semesters['spring'])
cs3500 = create(:course, title: 'CS 3500', term: spring2022)
cs3500lec = create(:section, :lecture, course: cs3500)
Expand Down