class GraphQL::Schema::Warden

@api private
result = Schema.execute(query_string, except: missing_required_flags)
# This query can only access members which match the user’s flags
missing_required_flags = MissingRequiredFlags.new(current_user)
# Then, use the custom filter in query:<br><br>end<br>end<br>end<br>!@user.has_flag?(flag)<br>member.metadata.any? do |flag|
def call(member, ctx)
# Return ‘false` if any required flags are missing
end
@user = user
def initialize(user)
class MissingRequiredFlags
# It must respond to `#call(member)`.
@example Custom mask implementation
result = Schema.execute(query_string, except: private_members)
private_members = -> (member, ctx) { member.metadata }
@example Hidding private fields
Masks can be provided in {Schema#execute} (or {Query#initialize}) with the `mask:` keyword.
you may show a client something that it shouldn’t be allowed to see.
should go through a warden. If you access the schema directly,
When validating and executing a query, all access to schema members
The mask is object that responds to ‘#visible?(schema_member)`.
Restrict access to a {GraphQL::Schema} with a user-defined mask.

def arguments(argument_owner)

Returns:
  • (Array) - Visible arguments on `argument_owner`

Parameters:
  • argument_owner (GraphQL::Field, GraphQL::InputObjectType) --
def arguments(argument_owner)
  @visible_arguments ||= read_through { |o| o.arguments.each_value.select { |a| visible_field?(a) } }
  @visible_arguments[argument_owner]
end

def directives

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

def enum_values(enum_defn)

Returns:
  • (Array) - Visible members of `enum_defn`
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

def fields(type_defn)

Returns:
  • (Array) - Fields on `type_defn`

Parameters:
  • type_defn (GraphQL::ObjectType, GraphQL::InterfaceType) --
def fields(type_defn)
  @visible_fields ||= read_through { |t| t.all_fields.select { |f| visible_field?(f) } }
  @visible_fields[type_defn]
end

def get_field(parent_type, field_name)

Returns:
  • (GraphQL::Field, nil) - The field named `field_name` on `parent_type`, if it exists
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

def get_type(type_name)

Returns:
  • (GraphQL::BaseType, nil) - The type named `type_name`, if it exists (else `nil`)
def get_type(type_name)
  @visible_types ||= read_through do |name|
    type_defn = @schema.types.fetch(name, nil)
    if type_defn && visible?(type_defn)
      type_defn
    else
      nil
    end
  end
  @visible_types[type_name]
end

def initialize(mask, context:, schema:)

Parameters:
  • deep_check (Boolean) --
  • schema (GraphQL::Schema) --
  • context (GraphQL::Query::Context) --
  • mask (<#call(member)>) -- Objects are hidden when `.call(member, ctx)` returns true
def initialize(mask, context:, schema:)
  @schema = schema
  @visibility_cache = read_through { |m| !mask.call(m, context) }
end

def interfaces(obj_type)

Returns:
  • (Array) - Visible interfaces implemented by `obj_type`
def interfaces(obj_type)
  @visible_interfaces ||= read_through { |t| t.interfaces.select { |i| visible?(i) } }
  @visible_interfaces[obj_type]
end

def possible_types(type_defn)

Returns:
  • (Array) - The types which may be member of `type_defn`
def possible_types(type_defn)
  @visible_possible_types ||= read_through { |type_defn| @schema.possible_types(type_defn).select { |t| visible?(t) } }
  @visible_possible_types[type_defn]
end

def read_through

def read_through
  Hash.new { |h, k| h[k] = yield(k) }
end

def root_type_for_operation(op_name)

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

def types

Returns:
  • (Array) - Visible types in the schema
def types
  @types ||= @schema.types.each_value.select { |t| visible?(t) }
end

def visible?(member)

def visible?(member)
  @visibility_cache[member]
end

def visible_field?(field_defn)

def visible_field?(field_defn)
  visible?(field_defn) && visible?(field_defn.type.unwrap)
end