Skip to content

Instantly share code, notes, and snippets.

@bibendi
Created May 5, 2021
Embed
What would you like to do?
class MutationRoot < Common::GraphQL::MutationRoot
with_options authenticate: true do
field :create_direct_upload, mutation: Mutations::CreateDirectUpload
end
with_options authenticate: true, user_checks: {completed: true} do
field :follow_user, mutation: Mutations::FollowUser
field :unfollow_user, mutation: Mutations::UnfollowUser
end
end
module Common
module GraphQL
class Field < ::GraphQL::Schema::Field
def initialize(*args, authenticate: false, user_checks: nil, **kwargs, &block)
@authenticate = authenticate
@user_checks = user_checks
super(*args, **kwargs, &block)
end
def authenticate?
!!@authenticate
end
def user_checks?
user_checks.is_a?(Hash) && !user_checks.empty?
end
def authorized?(object, args, context)
if user_checks?
authorize_user_checks(context[:current_user])
elsif authenticate?
authenticate!(context[:current_user])
end
super
end
private
attr_reader :user_checks
def authenticate!(user)
return unless user.nil?
raise ::GraphQL::ExecutionError.new(
"Unauthenticated access to the field #{graphql_name}",
extensions: {code: :unauthenticated, reason: :user_not_found}
)
end
def authorize_user_checks(user)
authenticate!(user)
user_checks.each do |check, expectation|
next if user.public_send("#{check}?") == expectation
raise ::GraphQL::ExecutionError.new(
"Unauthorized access to the field #{graphql_name}",
extensions: {code: :unauthorized, reason: "Expected user #{"not " unless expectation}to be #{check}"}
)
end
true
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment