Class: GraphQL::Schema::Warden Private
- Inherits:
-
Object
- Object
- GraphQL::Schema::Warden
- 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 visible?
implementations.
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.
Defined Under Namespace
Classes: NullWarden, PassThruWarden, VisibilityProfile
Instance Attribute Summary collapse
-
#skip_warning ⇒ Object
writeonly
private
Class Method Summary collapse
-
.from_context(context) ⇒ Object
private
-
.types_from_context(context) ⇒ Object
private
-
.use(schema) ⇒ Object
private
-
.visible_entry?(visibility_method, entry, context, warden = Warden.from_context(context)) ⇒ Object?
private
Instance Method Summary collapse
-
#arguments(argument_owner, ctx = nil) ⇒ Array<GraphQL::Argument>
private
Visible arguments on
argument_owner
. -
#directives ⇒ Object
private
-
#enum_values(enum_defn) ⇒ Array<GraphQL::EnumType::EnumValue>
private
Visible members of
enum_defn
. -
#fields(type_defn) ⇒ Array<GraphQL::Field>
private
Fields on
type_defn
. -
#get_argument(parent_type, argument_name) ⇒ GraphQL::Argument?
private
The argument named
argument_name
onparent_type
, if it exists and is visible. -
#get_field(parent_type, field_name) ⇒ GraphQL::Field?
private
The field named
field_name
onparent_type
, if it exists. -
#get_type(type_name) ⇒ GraphQL::BaseType?
private
The type named
type_name
, if it exists (elsenil
). -
#initialize(context:, schema:) ⇒ Warden
constructor
private
A new instance of Warden.
-
#interface_type_memberships(obj_type, _ctx = nil) ⇒ Object
private
-
#interfaces(obj_type) ⇒ Array<GraphQL::InterfaceType>
private
Visible interfaces implemented by
obj_type
. -
#loadable?(type, _ctx) ⇒ Boolean
private
True if this type is used for
loads:
but not in the schema otherwise and not explicitly hidden. -
#loadable_possible_types(abstract_type, _ctx) ⇒ Object
private
This abstract type was determined to be used for
loads
only. -
#possible_types(type_defn) ⇒ Array<GraphQL::BaseType>
private
The types which may be member of
type_defn
. -
#reachable_type?(type_name) ⇒ Boolean
private
Boolean True if the type is visible and reachable in the schema.
-
#reachable_types ⇒ Array<GraphQL::BaseType>
private
Visible and reachable types in the schema.
-
#root_type_for_operation(op_name) ⇒ Object
private
-
#types ⇒ Hash<String, GraphQL::BaseType>
private
Visible types in the schema.
-
#visibility_profile ⇒ Object
private
-
#visible_argument?(arg_defn, _ctx = nil) ⇒ Boolean
private
-
#visible_enum_value?(enum_value, _ctx = nil) ⇒ Boolean
private
-
#visible_field?(field_defn, _ctx = nil, owner = field_defn.owner) ⇒ Boolean
private
-
#visible_type?(type_defn, _ctx = nil) ⇒ Boolean
private
-
#visible_type_membership?(type_membership, _ctx = nil) ⇒ Boolean
private
Constructor Details
#initialize(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.
200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 |
# File 'lib/graphql/schema/warden.rb', line 200 def initialize(context:, schema:) @schema = schema # Cache these to avoid repeated hits to the inheritance chain when one isn't present @query = @schema.query @mutation = @schema.mutation @subscription = @schema.subscription @context = context @visibility_cache = read_through { |m| check_visible(schema, m) } # Initialize all ivars to improve object shape consistency: @types = @visible_types = @reachable_types = @visible_parent_fields = @visible_possible_types = @visible_fields = @visible_arguments = @visible_enum_arrays = @visible_enum_values = @visible_interfaces = @type_visibility = @type_memberships = @visible_and_reachable_type = @unions = @unfiltered_interfaces = @reachable_type_set = @visibility_profile = @loadable_possible_types = nil @skip_warning = schema.plugins.any? { |(plugin, _opts)| plugin == GraphQL::Schema::Warden } end |
Instance Attribute Details
#skip_warning=(value) ⇒ Object (writeonly)
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.
218 219 220 |
# File 'lib/graphql/schema/warden.rb', line 218 def skip_warning=(value) @skip_warning = value end |
Class Method Details
.from_context(context) ⇒ 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.
15 16 17 18 19 20 |
# File 'lib/graphql/schema/warden.rb', line 15 def self.from_context(context) context.warden || PassThruWarden rescue NoMethodError # this might be a hash which won't respond to #warden PassThruWarden end |
.types_from_context(context) ⇒ 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.
22 23 24 25 26 27 |
# File 'lib/graphql/schema/warden.rb', line 22 def self.types_from_context(context) context.types || PassThruWarden rescue NoMethodError # this might be a hash which won't respond to #warden PassThruWarden end |
.use(schema) ⇒ 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.
29 30 31 |
# File 'lib/graphql/schema/warden.rb', line 29 def self.use(schema) # no-op end |
.visible_entry?(visibility_method, entry, context, warden = Warden.from_context(context)) ⇒ 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.
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
# File 'lib/graphql/schema/warden.rb', line 39 def self.visible_entry?(visibility_method, entry, context, warden = Warden.from_context(context)) if entry.is_a?(Array) visible_item = nil entry.each do |item| if warden.public_send(visibility_method, item, context) if visible_item.nil? visible_item = item else raise DuplicateNamesError.new( duplicated_name: item.path, duplicated_definition_1: visible_item.inspect, duplicated_definition_2: item.inspect ) end end end visible_item elsif warden.public_send(visibility_method, entry, context) entry else nil end end |
Instance Method Details
#arguments(argument_owner, ctx = nil) ⇒ 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
.
318 319 320 321 322 323 324 325 326 327 328 329 330 |
# File 'lib/graphql/schema/warden.rb', line 318 def arguments(argument_owner, ctx = nil) @visible_arguments ||= read_through { |o| args = o.arguments(@context) if !args.empty? args = args.values args.select! { |a| visible_argument?(a, @context) } args else EmptyObjects::EMPTY_ARRAY end } @visible_arguments[argument_owner] end |
#directives ⇒ 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.
361 362 363 |
# File 'lib/graphql/schema/warden.rb', line 361 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
.
333 334 335 336 337 338 339 340 341 342 |
# File 'lib/graphql/schema/warden.rb', line 333 def enum_values(enum_defn) @visible_enum_arrays ||= read_through { |e| values = e.enum_values(@context) if values.size == 0 raise GraphQL::Schema::Enum::MissingValuesError.new(e) end values } @visible_enum_arrays[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
.
311 312 313 314 |
# File 'lib/graphql/schema/warden.rb', line 311 def fields(type_defn) @visible_fields ||= read_through { |t| @schema.get_fields(t, @context).values } @visible_fields[type_defn] end |
#get_argument(parent_type, argument_name) ⇒ 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 The argument named argument_name
on parent_type
, if it exists and is visible.
295 296 297 298 |
# File 'lib/graphql/schema/warden.rb', line 295 def get_argument(parent_type, argument_name) argument = parent_type.get_argument(argument_name, @context) return argument if argument && visible_argument?(argument, @context) 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.
279 280 281 282 283 284 285 286 287 288 289 290 291 292 |
# File 'lib/graphql/schema/warden.rb', line 279 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, @context) if field_defn && visible_field?(field_defn, nil, type) 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
).
254 255 256 257 258 259 260 261 262 263 264 265 |
# File 'lib/graphql/schema/warden.rb', line 254 def get_type(type_name) @visible_types ||= read_through do |name| type_defn = @schema.get_type(name, @context, false) if type_defn && visible_and_reachable_type?(type_defn) type_defn else nil end end @visible_types[type_name] end |
#interface_type_memberships(obj_type, _ctx = nil) ⇒ 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.
398 399 400 401 402 403 |
# File 'lib/graphql/schema/warden.rb', line 398 def interface_type_memberships(obj_type, _ctx = nil) @type_memberships ||= read_through do |obj_t| obj_t.interface_type_memberships end @type_memberships[obj_type] 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
.
350 351 352 353 354 355 356 357 358 359 |
# File 'lib/graphql/schema/warden.rb', line 350 def interfaces(obj_type) @visible_interfaces ||= read_through { |t| ints = t.interfaces(@context) if !ints.empty? ints.select! { |i| visible_type?(i) } end ints } @visible_interfaces[obj_type] end |
#loadable?(type, _ctx) ⇒ 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 True if this type is used for loads:
but not in the schema otherwise and not explicitly hidden.
234 235 236 237 238 |
# File 'lib/graphql/schema/warden.rb', line 234 def loadable?(type, _ctx) visible_type?(type) && !referenced?(type) && (type.respond_to?(:interfaces) ? interfaces(type).all? { |i| loadable?(i, _ctx) } : true) end |
#loadable_possible_types(abstract_type, _ctx) ⇒ 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.
This abstract type was determined to be used for loads
only.
All its possible types are valid possibilities here – no filtering.
242 243 244 245 246 247 248 249 250 251 |
# File 'lib/graphql/schema/warden.rb', line 242 def loadable_possible_types(abstract_type, _ctx) @loadable_possible_types ||= read_through do |t| if t.is_a?(Class) # union t.possible_types else @schema.possible_types(abstract_type) end end @loadable_possible_types[abstract_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
.
301 302 303 304 305 306 307 |
# File 'lib/graphql/schema/warden.rb', line 301 def possible_types(type_defn) @visible_possible_types ||= read_through { |type_defn| pt = @schema.possible_types(type_defn, @context, false) pt.select { |t| visible_and_reachable_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.
273 274 275 276 |
# File 'lib/graphql/schema/warden.rb', line 273 def reachable_type?(type_name) type = get_type(type_name) # rubocop:disable Development/ContextIsPassedCop -- `self` is query-aware type && reachable_type_set.include?(type) end |
#reachable_types ⇒ 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 Visible and reachable types in the schema.
268 269 270 |
# File 'lib/graphql/schema/warden.rb', line 268 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.
365 366 367 368 369 370 371 372 |
# File 'lib/graphql/schema/warden.rb', line 365 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 |
#types ⇒ Hash<String, 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.
221 222 223 224 225 226 227 228 229 230 231 |
# File 'lib/graphql/schema/warden.rb', line 221 def types @types ||= begin vis_types = {} @schema.types(@context).each do |n, t| if visible_and_reachable_type?(t) vis_types[n] = t end end vis_types end end |
#visibility_profile ⇒ 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.
116 117 118 |
# File 'lib/graphql/schema/warden.rb', line 116 def visibility_profile @visibility_profile ||= VisibilityProfile.new(self) end |
#visible_argument?(arg_defn, _ctx = nil) ⇒ 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.
385 386 387 |
# File 'lib/graphql/schema/warden.rb', line 385 def visible_argument?(arg_defn, _ctx = nil) visible?(arg_defn) && visible_and_reachable_type?(arg_defn.type.unwrap) end |
#visible_enum_value?(enum_value, _ctx = nil) ⇒ 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.
344 345 346 347 |
# File 'lib/graphql/schema/warden.rb', line 344 def visible_enum_value?(enum_value, _ctx = nil) @visible_enum_values ||= read_through { |ev| visible?(ev) } @visible_enum_values[enum_value] end |
#visible_field?(field_defn, _ctx = nil, owner = field_defn.owner) ⇒ 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.
375 376 377 378 379 380 381 382 383 |
# File 'lib/graphql/schema/warden.rb', line 375 def visible_field?(field_defn, _ctx = nil, owner = field_defn.owner) # This field is visible in its own right visible?(field_defn) && # This field's return type is visible visible_and_reachable_type?(field_defn.type.unwrap) && # This field is either defined on this object type, # or the interface it's inherited from is also visible ((field_defn.respond_to?(:owner) && field_defn.owner == owner) || field_on_visible_interface?(field_defn, owner)) end |
#visible_type?(type_defn, _ctx = nil) ⇒ 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.
389 390 391 392 |
# File 'lib/graphql/schema/warden.rb', line 389 def visible_type?(type_defn, _ctx = nil) @type_visibility ||= read_through { |type_defn| visible?(type_defn) } @type_visibility[type_defn] end |
#visible_type_membership?(type_membership, _ctx = nil) ⇒ 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.
394 395 396 |
# File 'lib/graphql/schema/warden.rb', line 394 def visible_type_membership?(type_membership, _ctx = nil) visible?(type_membership) end |