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:



44
45
46
47
48
# File 'lib/graphql/schema/warden.rb', line 44

def initialize(filter, context:, schema:)
  @schema = schema
  @context = context
  @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:



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

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.



129
130
131
# File 'lib/graphql/schema/warden.rb', line 129

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:



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

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:



105
106
107
108
# File 'lib/graphql/schema/warden.rb', line 105

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



81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/graphql/schema/warden.rb', line 81

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:



56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/graphql/schema/warden.rb', line 56

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:



124
125
126
127
# File 'lib/graphql/schema/warden.rb', line 124

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:



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

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

#reachable_type?(type_name) ⇒ Boolean

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 Boolean True if the type is visible and reachable in the schema

Returns:

  • (Boolean)

    Boolean True if the type is visible and reachable in the schema



75
76
77
78
# File 'lib/graphql/schema/warden.rb', line 75

def reachable_type?(type_name)
  type = get_type(type_name)
  type && reachable_type_set.include?(type)
end

#reachable_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 and reachable types in the schema

Returns:



70
71
72
# File 'lib/graphql/schema/warden.rb', line 70

def reachable_types
  @reachable_types ||= reachable_type_set.to_a
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.



133
134
135
136
137
138
139
140
# File 'lib/graphql/schema/warden.rb', line 133

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:



51
52
53
# File 'lib/graphql/schema/warden.rb', line 51

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