2020-08-05 18:40:47 +02:00
|
|
|
class API::V2::Context < GraphQL::Query::Context
|
2022-04-11 22:35:51 +02:00
|
|
|
# This method is used to check if a given fragment is used in the given query.
|
|
|
|
# We need that in order to maintain backward compatibility for Types de Champ
|
|
|
|
# that we extended in later iterations of our schema.
|
|
|
|
def has_fragment?(fragment_name)
|
|
|
|
self[:has_fragment] ||= Hash.new do |hash, fragment_name|
|
|
|
|
visitor = HasFragment.new(query.document, fragment_name)
|
2020-12-18 11:16:18 +01:00
|
|
|
visitor.visit
|
2022-04-11 22:35:51 +02:00
|
|
|
hash[fragment_name] = visitor.found
|
2020-12-18 11:16:18 +01:00
|
|
|
end
|
2022-04-11 22:35:51 +02:00
|
|
|
self[:has_fragment][fragment_name]
|
2020-12-18 11:16:18 +01:00
|
|
|
end
|
|
|
|
|
2021-01-28 13:52:14 +01:00
|
|
|
def internal_use?
|
|
|
|
self[:internal_use]
|
|
|
|
end
|
|
|
|
|
|
|
|
def authorized_demarche?(demarche)
|
|
|
|
if internal_use?
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
|
|
|
|
# We are caching authorization logic because it is called for each node
|
|
|
|
# of the requested graph and can be expensive. Context is reset per request so it is safe.
|
|
|
|
self[:authorized] ||= Hash.new do |hash, demarche_id|
|
2022-11-30 10:14:23 +01:00
|
|
|
hash[demarche_id] = if self[:token]
|
|
|
|
APIToken.find_and_verify(self[:token], demarche.administrateurs).present?
|
|
|
|
elsif self[:administrateur_id]
|
|
|
|
demarche.administrateurs.map(&:id).include?(self[:administrateur_id])
|
2021-01-28 13:52:14 +01:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
self[:authorized][demarche.id]
|
|
|
|
end
|
|
|
|
|
2022-04-11 22:35:51 +02:00
|
|
|
# This is a query AST visitor that we use to check
|
|
|
|
# if a fragment with a given name is used in the given document.
|
|
|
|
# We check for both inline and standalone fragments.
|
2020-12-18 11:16:18 +01:00
|
|
|
class HasFragment < GraphQL::Language::Visitor
|
2022-04-11 22:35:51 +02:00
|
|
|
def initialize(document, fragment_name)
|
2020-12-18 11:16:18 +01:00
|
|
|
super(document)
|
2022-04-11 22:35:51 +02:00
|
|
|
@fragment_name = fragment_name.to_s
|
2020-12-18 11:16:18 +01:00
|
|
|
@found = false
|
|
|
|
end
|
|
|
|
|
|
|
|
attr_reader :found
|
|
|
|
|
|
|
|
def on_inline_fragment(node, parent)
|
2022-04-11 22:35:51 +02:00
|
|
|
if node.type.name == @fragment_name
|
|
|
|
@found = true
|
|
|
|
end
|
|
|
|
|
|
|
|
super
|
|
|
|
end
|
|
|
|
|
|
|
|
def on_fragment_definition(node, parent)
|
|
|
|
if node.type.name == @fragment_name
|
2020-12-18 11:16:18 +01:00
|
|
|
@found = true
|
|
|
|
end
|
|
|
|
|
|
|
|
super
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|