Class: GraphQL::Schema::Warden Private

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

Overview

This class is part of a private API. You should avoid using this class if possible, as it may be removed or be changed in the future.

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

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.

Examples:

Hidding private fields

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

Custom filter 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, ctx)
    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)

Direct Known Subclasses

Query::NullContext::NullWarden

Instance Method Summary collapse

Constructor Details

#initialize(filter, context:, schema:) ⇒ Warden

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns a new instance of Warden.

Parameters:



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

def initialize(filter, context:, schema:)
  @schema = schema
  @visibility_cache = read_through { |m| filter.call(m, context) }
end

Instance Method Details

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

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns Visible arguments on argument_owner.

Parameters:

Returns:



97
98
99
100
# File 'lib/graphql/schema/warden.rb', line 97

def arguments(argument_owner)
  @visible_arguments ||= read_through { |o| o.arguments.each_value.select { |a| visible_field?(a) } }
  @visible_arguments[argument_owner]
end

#directivesObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



114
115
116
# File 'lib/graphql/schema/warden.rb', line 114

def directives
  @schema.directives.each_value.select { |d| visible?(d) }
end

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

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns Visible members of enum_defn.

Returns:



103
104
105
106
# File 'lib/graphql/schema/warden.rb', line 103

def enum_values(enum_defn)
  @visible_enum_values ||= read_through { |e| e.values.each_value.select { |enum_value_defn| visible?(enum_value_defn) } }
  @visible_enum_values[enum_defn]
end

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

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns Fields on type_defn.

Parameters:

Returns:



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

def fields(type_defn)
  @visible_fields ||= read_through { |t| @schema.get_fields(t).each_value.select { |f| visible_field?(f) } }
  @visible_fields[type_defn]
end

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

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

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



66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/graphql/schema/warden.rb', line 66

def get_field(parent_type, field_name)

  @visible_parent_fields ||= read_through do |type|
    read_through do |f_name|
      field_defn = @schema.get_field(type, f_name)
      if field_defn && visible_field?(field_defn)
        field_defn
      else
        nil
      end
    end
  end

  @visible_parent_fields[parent_type][field_name]
end

#get_type(type_name) ⇒ GraphQL::BaseType?

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

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

Returns:



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

def get_type(type_name)
  @visible_types ||= read_through do |name|
    type_defn = @schema.types.fetch(name, nil)
    if type_defn && visible_type?(type_defn)
      type_defn
    else
      nil
    end
  end

  @visible_types[type_name]
end

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

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns Visible interfaces implemented by obj_type.

Returns:



109
110
111
112
# File 'lib/graphql/schema/warden.rb', line 109

def interfaces(obj_type)
  @visible_interfaces ||= read_through { |t| t.interfaces.select { |i| visible?(i) } }
  @visible_interfaces[obj_type]
end

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

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns The types which may be member of type_defn.

Returns:



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

def possible_types(type_defn)
  @visible_possible_types ||= read_through { |type_defn| @schema.possible_types(type_defn).select { |t| visible_type?(t) } }
  @visible_possible_types[type_defn]
end

#root_type_for_operation(op_name) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



118
119
120
121
122
123
124
125
# File 'lib/graphql/schema/warden.rb', line 118

def root_type_for_operation(op_name)
  root_type = @schema.root_type_for_operation(op_name)
  if root_type && visible?(root_type)
    root_type
  else
    nil
  end
end

#typesArray<GraphQL::BaseType>

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns Visible types in the schema.

Returns:



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

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