74 lines
2.1 KiB
Ruby
74 lines
2.1 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
module Gitlab
|
|
module Graphql
|
|
module Authorize
|
|
class ConnectionFilterExtension < GraphQL::Schema::FieldExtension
|
|
class Redactor
|
|
include ::Gitlab::Graphql::Laziness
|
|
|
|
def initialize(type, context, resolver)
|
|
@type = type
|
|
@context = context
|
|
@resolver = resolver
|
|
end
|
|
|
|
def redact(nodes)
|
|
perform_before_authorize_action(nodes)
|
|
remove_unauthorized(nodes)
|
|
|
|
nodes
|
|
end
|
|
|
|
def active?
|
|
# some scalar types (such as integers) do not respond to :authorized?
|
|
return false unless @type.respond_to?(:authorized?)
|
|
|
|
auth = @type.try(:authorization)
|
|
|
|
auth.nil? || auth.any?
|
|
end
|
|
|
|
private
|
|
|
|
def perform_before_authorize_action(nodes)
|
|
before_connection_authorization_block = @resolver&.before_connection_authorization_block
|
|
return unless before_connection_authorization_block.respond_to?(:call)
|
|
|
|
before_connection_authorization_block.call(nodes, @context[:current_user])
|
|
end
|
|
|
|
def remove_unauthorized(nodes)
|
|
nodes
|
|
.map! { |lazy| force(lazy) }
|
|
.keep_if { |forced| @type.authorized?(forced, @context) }
|
|
end
|
|
end
|
|
|
|
def after_resolve(value:, context:, **rest)
|
|
return value if value.is_a?(GraphQL::Execution::Execute::Skip)
|
|
|
|
if @field.connection?
|
|
redact_connection(value, context)
|
|
elsif @field.type.list?
|
|
redact_list(value.to_a, context) unless value.nil?
|
|
end
|
|
|
|
value
|
|
end
|
|
|
|
def redact_connection(conn, context)
|
|
redactor = Redactor.new(@field.type.unwrap.node_type, context, @field.resolver)
|
|
return unless redactor.active?
|
|
|
|
conn.redactor = redactor if conn.respond_to?(:redactor=)
|
|
end
|
|
|
|
def redact_list(list, context)
|
|
redactor = Redactor.new(@field.type.unwrap, context, @field.resolver)
|
|
redactor.redact(list) if redactor.active?
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|