From 9c0cd8979a54e553b8422f19e5be5e5b0aafe683 Mon Sep 17 00:00:00 2001 From: Paul Chavard Date: Tue, 21 Feb 2023 16:06:39 +0100 Subject: [PATCH] fix(graphql): context should correctly preserve demarche authorization state --- app/graphql/api/v2/context.rb | 8 ++++---- spec/graphql/demarche_spec.rb | 25 +++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/app/graphql/api/v2/context.rb b/app/graphql/api/v2/context.rb index 0b23f1212..294387a61 100644 --- a/app/graphql/api/v2/context.rb +++ b/app/graphql/api/v2/context.rb @@ -42,10 +42,10 @@ class API::V2::Context < GraphQL::Query::Context 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| - hash[demarche_id] = if self[:administrateur_id] + self[:authorized] ||= {} + + if self[:authorized][demarche.id].nil? + self[:authorized][demarche.id] = if self[:administrateur_id] demarche.administrateurs.map(&:id).include?(self[:administrateur_id]) elsif self[:token] APIToken.find_and_verify(self[:token], demarche.administrateurs).present? diff --git a/spec/graphql/demarche_spec.rb b/spec/graphql/demarche_spec.rb index 29dc4de85..db60988d0 100644 --- a/spec/graphql/demarche_spec.rb +++ b/spec/graphql/demarche_spec.rb @@ -8,6 +8,24 @@ RSpec.describe Types::DemarcheType, type: :graphql do let(:data) { subject['data'].deep_symbolize_keys } let(:errors) { subject['errors'].deep_symbolize_keys } + describe 'context should correctly preserve demarche authorization state' do + let(:query) { DEMARCHE_QUERY } + let(:admin) { create(:administrateur) } + let(:procedure) { create(:procedure, administrateurs: [admin]) } + + let(:other_admin_procedure) { create(:procedure) } + let(:context) { { administrateur_id: admin.id } } + let(:variables) { { number: procedure.id } } + + it do + result = API::V2::Schema.execute(query, variables: variables, context: context) + graphql_context = result.context + + expect(graphql_context.authorized_demarche?(procedure)).to be_truthy + expect(graphql_context.authorized_demarche?(other_admin_procedure)).to be_falsey + end + end + describe 'demarche with clone' do let(:procedure) { create(:procedure, types_de_champ_public: [{ type: :yes_no }]) } let(:procedure_clone) { procedure.clone(procedure.administrateurs.first, false) } @@ -23,6 +41,13 @@ RSpec.describe Types::DemarcheType, type: :graphql do expect(procedure.draft_revision.types_de_champ_public.first.stable_id).to eq(procedure_clone.draft_revision.types_de_champ_public.first.stable_id) } end + DEMARCHE_QUERY = <<-GRAPHQL + query($number: Int!) { + demarche(number: $number) { + number + } + } + GRAPHQL DEMARCHE_WITH_CHAMP_DESCRIPTORS_QUERY = <<-GRAPHQL query($number: Int!) {