From 716bd1f8e603010418c3b8f36df13ffba6946bc4 Mon Sep 17 00:00:00 2001 From: Konstantin Haase Date: Mon, 5 Oct 2015 17:49:10 +0200 Subject: [PATCH] v3: don't have recursive recursiveness trigger endless db queries, fixes travis-pro/team-teal#497 --- lib/travis/api/v3/query.rb | 8 +++++++- lib/travis/api/v3/renderer/collection_renderer.rb | 12 +++++++++--- .../services/repositories/for_current_user_spec.rb | 6 ++++++ 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/lib/travis/api/v3/query.rb b/lib/travis/api/v3/query.rb index 84a31da9..8cdcb521 100644 --- a/lib/travis/api/v3/query.rb +++ b/lib/travis/api/v3/query.rb @@ -54,7 +54,13 @@ module Travis::API::V3 def includes?(key) @includes ||= @params['include'.freeze].to_s.split(?,.freeze) - key.include?(?.) ? @includes.include?(key) : @includes.any? { |k| k.start_with? key } + key = key.to_s if key.is_a? Symbol + + if key.is_a? String + key.include?(?.) ? @includes.include?(key) : @includes.any? { |k| k.start_with? key } + else + @includes.any? { |k| key === k } + end end def bool(value) diff --git a/lib/travis/api/v3/renderer/collection_renderer.rb b/lib/travis/api/v3/renderer/collection_renderer.rb index 2a072426..23b09629 100644 --- a/lib/travis/api/v3/renderer/collection_renderer.rb +++ b/lib/travis/api/v3/renderer/collection_renderer.rb @@ -21,13 +21,14 @@ module Travis::API::V3 available_attributes << value end - attr_reader :href, :options, :list, :included, :meta_data + attr_reader :href, :options, :list, :included, :include, :meta_data - def initialize(list, href: nil, included: [], meta_data: {}, **options) + def initialize(list, href: nil, included: [], include: [], meta_data: {}, **options) @href = href @options = options @list = list @included = included + @include = include @meta_data = meta_data end @@ -49,13 +50,18 @@ module Travis::API::V3 result = fields included = self.included.dup result[collection_key] = list.map do |entry| - rendered = render_entry(entry, included: included, mode: representation, **options) + rendered = render_entry(entry, included: included, include: filtered_include, mode: representation, **options) included << entry rendered end result end + def filtered_include + key = collection_key.to_s + include.reject { |entry| entry.split(?..freeze, 2).last == key } + end + def representation :standard end diff --git a/spec/v3/services/repositories/for_current_user_spec.rb b/spec/v3/services/repositories/for_current_user_spec.rb index 79138a7c..72c43777 100644 --- a/spec/v3/services/repositories/for_current_user_spec.rb +++ b/spec/v3/services/repositories/for_current_user_spec.rb @@ -89,6 +89,12 @@ describe Travis::API::V3::Services::Repositories::ForCurrentUser do }} end + describe "don't nest list of repositories inside a list of repositories even if the user asks for it. user has no idea what they are doing" do + before { get("/v3/repos?include=user.repositories", {}, headers) } + example { expect(last_response).to be_ok } + example { expect(JSON.load(body)['repositories'].first['owner']['repositories']).to be_nil } + end + describe "filter: private=false" do before { get("/v3/repos", {"repository.private" => "false"}, headers) } example { expect(last_response) .to be_ok }