diff --git a/lib/travis/api/v3.rb b/lib/travis/api/v3.rb index 8e0d3909..221df59b 100644 --- a/lib/travis/api/v3.rb +++ b/lib/travis/api/v3.rb @@ -37,4 +37,3 @@ module Travis end end end - diff --git a/lib/travis/api/v3/result.rb b/lib/travis/api/v3/result.rb index 7f8d2b0d..c6875af1 100644 --- a/lib/travis/api/v3/result.rb +++ b/lib/travis/api/v3/result.rb @@ -1,8 +1,9 @@ module Travis::API::V3 class Result - attr_accessor :access_control, :type, :resource, :status, :href, :meta_data + attr_accessor :access_control, :type, :resource, :status, :href, :meta_data, :warnings def initialize(access_control, type, resource = [], status: 200, **meta_data) + @warnings = [] @access_control, @type, @resource, @status, @meta_data = access_control, type, resource, status, meta_data end @@ -10,6 +11,15 @@ module Travis::API::V3 super or method.to_sym == type.to_sym end + def warn(message, **info) + warnings << { :@type => 'warning'.freeze, :message => message, **info } + end + + def ignored_param(param, reason: nil, **info) + message = reason ? "query parameter #{param} #{reason}, ignored" : "query parameter #{param} ignored" + warn(message, warning_type: :ignored_parameter, parameter: param, **info) + end + def <<(value) resource << value self @@ -19,7 +29,7 @@ module Travis::API::V3 href = self.href href = V3.location(env) if href.nil? and env['REQUEST_METHOD'.freeze] == 'GET'.freeze include = params['include'.freeze].to_s.split(?,.freeze) - Renderer[type].render(resource, + add_info Renderer[type].render(resource, href: href, script_name: env['SCRIPT_NAME'.freeze], include: include, @@ -27,6 +37,14 @@ module Travis::API::V3 meta_data: meta_data) end + def add_info(payload) + if warnings.any? + payload = { :@warnings => [] }.merge!(payload) unless payload.include? :@warnings + payload[:@warnings].concat(warnings) + end + payload + end + def method_missing(method, *args) return super unless method.to_sym == type.to_sym raise ArgumentError, 'wrong number of arguments (1 for 0)'.freeze if args.any? diff --git a/lib/travis/api/v3/router.rb b/lib/travis/api/v3/router.rb index 1c89ffd4..8e39fc15 100644 --- a/lib/travis/api/v3/router.rb +++ b/lib/travis/api/v3/router.rb @@ -16,8 +16,11 @@ module Travis::API::V3 raise NotFound unless factory - service = factory.new(access_control, factory.filter_params(env_params).merge(params)) + filtered = factory.filter_params(env_params) + service = factory.new(access_control, filtered.merge(params)) result = service.run + + env_params.each_key { |key| result.ignored_param(key, reason: "not whitelisted".freeze) unless filtered.include?(key) } render(result, env_params, env) rescue Error => error result = Result.new(access_control, :error, error) diff --git a/spec/v3/services/owner/find_spec.rb b/spec/v3/services/owner/find_spec.rb index 66d3feca..fd8fc6fa 100644 --- a/spec/v3/services/owner/find_spec.rb +++ b/spec/v3/services/owner/find_spec.rb @@ -130,14 +130,19 @@ describe Travis::API::V3::Services::Owner::Find do before { get("/v3/owner/example-org?organization.id=#{other.id}") } example { expect(last_response).to be_ok } example { expect(JSON.load(body)).to be == { - "@type" => "organization", - "@href" => "/v3/org/#{org.id}", - "@permissions" => { "read"=>true, "sync"=>false }, - "id" => org.id, - "login" => "example-org", - "name" => nil, - "github_id" => nil, - "avatar_url" => nil + "@type" => "organization", + "@href" => "/v3/org/#{org.id}", + "@permissions" => { "read"=>true, "sync"=>false }, + "id" => org.id, + "login" => "example-org", + "name" => nil, + "github_id" => nil, + "avatar_url" => nil, + "@warnings" => [{ + "@type" => "warning", + "message" => "query parameter organization.id not whitelisted, ignored", + "warning_type" => "ignored_parameter", + "parameter" => "organization.id"}] }} end end @@ -198,7 +203,12 @@ describe Travis::API::V3::Services::Owner::Find do "github_id" => nil, "avatar_url" => nil, "is_syncing" => nil, - "synced_at" => nil + "synced_at" => nil, + "@warnings" => [{ + "@type" => "warning", + "message" => "query parameter user.id not whitelisted, ignored", + "warning_type" => "ignored_parameter", + "parameter" => "user.id"}] }} end end