|
require "bundler/inline" |
|
|
|
gemfile do |
|
gem "graphql" |
|
gem "graphql-pro" |
|
gem "pundit" |
|
gem "ostruct" |
|
end |
|
|
|
Post = Data.define(:id) |
|
|
|
class PunditExampleSchema < GraphQL::Schema |
|
class Post < GraphQL::Schema::Object |
|
field :id, ID |
|
end |
|
|
|
class Comment < GraphQL::Schema::Object |
|
field :message, String |
|
end |
|
|
|
class BaseArgument < GraphQL::Schema::Argument |
|
include GraphQL::Pro::PunditIntegration::ArgumentIntegration |
|
end |
|
class CreateComment < GraphQL::Schema::Mutation |
|
include GraphQL::Pro::PunditIntegration::MutationIntegration |
|
pundit_role nil |
|
|
|
class CreateCommentPolicy |
|
def initialize(user, object) |
|
@user = user |
|
@object = object |
|
end |
|
|
|
def create_comment? |
|
@user.post_ids.include?(@object.id) |
|
end |
|
end |
|
|
|
argument_class BaseArgument |
|
# This will cause `PostPolicy#create_comment?` to be called: |
|
argument :post_id, ID, loads: Post, pundit_policy_class: CreateCommentPolicy, pundit_role: :create_comment |
|
argument :message, String, pundit_role: nil |
|
field :comment, Comment |
|
|
|
def resolve(post:, message:) |
|
{ comment: { message: message } } |
|
end |
|
end |
|
|
|
class Mutation < GraphQL::Schema::Object |
|
field :create_comment, mutation: CreateComment |
|
end |
|
|
|
def self.object_from_id(id, ctx) |
|
::Post.new(id: id) |
|
end |
|
|
|
def self.resolve_type(abs_t, obj, ctx) |
|
Post |
|
end |
|
|
|
mutation(Mutation) |
|
|
|
def self.unauthorized_object(*) |
|
raise GraphQL::ExecutionError, "You don't have permission for that" |
|
end |
|
end |
|
|
|
query_str = "mutation($id: ID!) { createComment(postId: $id, message: \"Great job\") { comment { message } } }" |
|
# Permitted |
|
pp PunditExampleSchema.execute(query_str, variables: { id: "1" }, context: { current_user: OpenStruct.new(post_ids: ["1", "2", "3"] )}).to_h |
|
# {"data" => {"createComment" => {"comment" => {"message" => "Great job"}}}} |
|
|
|
# Not permitted |
|
pp PunditExampleSchema.execute(query_str, variables: { id: "1" }, context: { current_user: OpenStruct.new(post_ids: ["4", "5", "6"] )}).to_h |
|
# {"errors" => [{"message" => "You don't have permission for that", "locations" => [{"line" => 1, "column" => 22}], "path" => ["createComment"]}], "data" => {"createComment" => nil}} |