Skip to content

Instantly share code, notes, and snippets.

@ssnickolay
Created April 10, 2020 20:32
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ssnickolay/87271dcab70c0dce93a8939762e7c017 to your computer and use it in GitHub Desktop.
Save ssnickolay/87271dcab70c0dce93a8939762e7c017 to your computer and use it in GitHub Desktop.
Ensuring Policies are Used in Graphql Mutation
class BaseMutation < GraphQL::Schema::RelayClassicMutation
include Graphql::ResolverCallbacks
include ActionPolicy::GraphQL::Behaviour
def current_user
context[:current_user]
end
# Enforce mutation authorization.
# This callbacks verifies that `authorize!` method has been
# called in the mutation or authorization was skipped
# explicitly via `skip_authorization`.
after_resolve do
raise "Unauthorized mutation" unless @authorization_performed
end
def authorize!(*)
@authorization_performed = true
super
end
# Call this method if you don't need to authorize the mutation
def skip_authorization!
@authorization_performed = true
end
end
# Depends on graphql-ruby 1.9.* and action_policy-graphql
# Authored by @palkan
module ResolverCallbacks
def self.included(base)
base.include ActiveSupport::Callbacks
base.define_callbacks :resolve
base.resolve_method :resolve_with_callbacks
base.extend ClassMethods
end
def resolve_with_callbacks(**kwargs)
run_callbacks(:resolve) { resolve(**kwargs) }
end
module ClassMethods
def before_resolve(*args, &block)
set_callback :resolve, :before, *args, &block
end
def after_resolve(*args, &block)
set_callback :resolve, :after, *args, &block
end
end
end
class SampleMutation < BaseMutation
...
def resolve(post:, *attrs)
authorize! post, to: :create?
# business logic here
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment