Class: GraphQL::Authorization::Instrumentation

Inherits:
Object
  • Object
show all
Defined in:
lib/graphql/authorization/instrumentation.rb

Instance Method Summary collapse

Constructor Details

#initialize(always_allow_execute: false) ⇒ Instrumentation

Returns a new instance of Instrumentation.



5
6
7
# File 'lib/graphql/authorization/instrumentation.rb', line 5

def initialize(always_allow_execute: false)
  @always_allow_execute = always_allow_execute
end

Instance Method Details

#baseTypeOf(type) ⇒ Object

returns the essential type of a potentially wrapped type (i.e., list or non-null)



10
11
12
13
14
15
16
# File 'lib/graphql/authorization/instrumentation.rb', line 10

def baseTypeOf(type)
  if type.class == GraphQL::NonNullType || type.class == GraphQL::ListType
    baseTypeOf(type.of_type)
  else
    type
  end
end

#instrument(type, field) ⇒ Object



22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/graphql/authorization/instrumentation.rb', line 22

def instrument(type, field)
  fieldType = baseTypeOf(field.type)
  old_resolve_proc = field.resolve_proc
  new_resolve_proc = lambda do |obj, args, ctx|
    unless ctx[:ability] == :root
      raise GraphQL::Authorization::Unauthorized, "not authorized to execute #{fieldType.name}" unless ctx[:ability].canExecute(fieldType, toSymKeys(args.to_h)) || @always_allow_execute
      raise GraphQL::Authorization::Unauthorized, "not authorized to access #{field.name} on #{type.name}" unless ctx[:ability].canAccess(type, field.name.to_sym, obj, toSymKeys(args.to_h))
    end
    old_resolve_proc.call(obj, args, ctx)
  end

  # Return a copy of `field`, with a new resolve proc
  field.redefine do
    resolve(new_resolve_proc)
  end
end

#toSymKeys(hash) ⇒ Object



18
19
20
# File 'lib/graphql/authorization/instrumentation.rb', line 18

def toSymKeys(hash)
  hash.map { |key, value| [key.to_sym, value] }.to_h
end