Class: GraphQL::Schema::Warden

Inherits:
Object
  • Object
show all
Defined in:
lib/graphql/schema/warden.rb

Overview

Restrict access to a GraphQL::Schema with a user-defined mask.

The mask is object that responds to #visible?(schema_member).

When validating and executing a query, all access to schema members should go through a warden. If you access the schema directly, you may show a client something that it shouldn't be allowed to see.

Masks can be provided in #execute (or Query#initialize) with the mask: keyword.

Examples:

Hidding private fields

private_members = -> (member) { member.[:private] }
result = Schema.execute(query_string, except: private_members)

Custom mask implementation

# It must respond to `#call(member)`.
class MissingRequiredFlags
  def initialize(user)
    @user = user
  end

  # Return `false` if any required flags are missing
  def call(member)
    member.[:required_flags].any? do |flag|
      !@user.has_flag?(flag)
    end
  end
end

# Then, use the custom filter in query:
missing_required_flags = MissingRequiredFlags.new(current_user)

# This query can only access members which match the user's flags
result = Schema.execute(query_string, except: missing_required_flags)

Instance Method Summary collapse

Constructor Details

#initialize(schema, mask) ⇒ Warden

Returns a new instance of Warden.

Parameters:

  • schema (GraphQL::Schema)
  • mask (<#call(member)>)

    Objects are hidden when .call(member) returns true



42
43
44
45
# File 'lib/graphql/schema/warden.rb', line 42

def initialize(schema, mask)
  @mask = mask
  @schema = schema
end

Instance Method Details

#arguments(argument_owner) ⇒ Array<GraphQL::Argument>

Returns Visible arguments on argument_owner.

Parameters:

Returns:



85
86
87
# File 'lib/graphql/schema/warden.rb', line 85

def arguments(argument_owner)
  argument_owner.arguments.each_value.select { |a| visible_field?(a) }
end

#enum_values(enum_defn) ⇒ Array<GraphQL::EnumType::EnumValue>

Returns Visible members of enum_defn.

Returns:



90
91
92
# File 'lib/graphql/schema/warden.rb', line 90

def enum_values(enum_defn)
  enum_defn.values.each_value.select { |enum_value_defn| visible?(enum_value_defn) }
end

#fields(type_defn) ⇒ Array<GraphQL::Field>

Returns Fields on type_defn.

Parameters:

Returns:



79
80
81
# File 'lib/graphql/schema/warden.rb', line 79

def fields(type_defn)
  type_defn.all_fields.select { |f| visible_field?(f) }
end

#get_field(parent_type, field_name) ⇒ GraphQL::Field?

Returns The field named field_name on parent_type, if it exists.

Returns:

  • (GraphQL::Field, nil)

    The field named field_name on parent_type, if it exists



63
64
65
66
67
68
69
70
# File 'lib/graphql/schema/warden.rb', line 63

def get_field(parent_type, field_name)
  field_defn = @schema.get_field(parent_type, field_name)
  if field_defn && visible_field?(field_defn)
    field_defn
  else
    nil
  end
end

#get_type(type_name) ⇒ GraphQL::BaseType?

Returns The type named type_name, if it exists (else nil).

Returns:



53
54
55
56
57
58
59
60
# File 'lib/graphql/schema/warden.rb', line 53

def get_type(type_name)
  type_defn = @schema.types.fetch(type_name, nil)
  if type_defn && visible?(type_defn)
    type_defn
  else
    nil
  end
end

#input_fields(input_obj_type) ⇒ Array<GraphQL::Field>

Returns Visible input fields on input_obj_type.

Returns:



100
101
102
# File 'lib/graphql/schema/warden.rb', line 100

def input_fields(input_obj_type)
  input_obj_type.arguments.each_value.select { |f| visible_field?(f) }
end

#interfaces(obj_type) ⇒ Array<GraphQL::InterfaceType>

Returns Visible interfaces implemented by obj_type.

Returns:



95
96
97
# File 'lib/graphql/schema/warden.rb', line 95

def interfaces(obj_type)
  obj_type.interfaces.select { |t| visible?(t) }
end

#possible_types(type_defn) ⇒ Array<GraphQL::BaseType>

Returns The types which may be member of type_defn.

Returns:



73
74
75
# File 'lib/graphql/schema/warden.rb', line 73

def possible_types(type_defn)
  @schema.possible_types(type_defn).select { |t| visible?(t) }
end

#typesArray<GraphQL::BaseType>

Returns Visible types in the schema.

Returns:



48
49
50
# File 'lib/graphql/schema/warden.rb', line 48

def types
  @schema.types.each_value.select { |t| visible?(t) }
end