diff --git a/lib/travis/api/app/extensions/scoping.rb b/lib/travis/api/app/extensions/scoping.rb index 626bdbb2..2e1624d3 100644 --- a/lib/travis/api/app/extensions/scoping.rb +++ b/lib/travis/api/app/extensions/scoping.rb @@ -18,23 +18,32 @@ class Travis::Api::App app.helpers(Helpers) end - def scope(name) + def scope(*names) condition do - name = settings.default_scope if name == :default + names = [settings.default_scope] if names == [:default] scopes = env['travis.access_token'].try(:scopes) || settings.anonymous_scopes - headers['X-OAuth-Scopes'] = scopes.map(&:to_s).join(',') - headers['X-Accepted-OAuth-Scopes'] = name.to_s - if scopes.include? name - env['travis.scope'] = name - headers['Vary'] = 'Accept' - headers['Vary'] << ', Authorization' unless public? - true - elsif env['travis.access_token'] - pass { halt 403, "insufficient access" } - else - pass { halt 401, "no access token supplied" } + result = names.any? do |name| + if scopes.include? name + headers['X-OAuth-Scopes'] = scopes.map(&:to_s).join(',') + headers['X-Accepted-OAuth-Scopes'] = name.to_s + + env['travis.scope'] = name + headers['Vary'] = 'Accept' + headers['Vary'] << ', Authorization' unless public? + true + end end + + if !result + if env['travis.access_token'] + pass { halt 403, "insufficient access" } + else + pass { halt 401, "no access token supplied" } + end + end + + result end end diff --git a/spec/integration/responders_spec.rb b/spec/integration/responders_spec.rb index 8624b486..2dc2cb78 100644 --- a/spec/integration/responders_spec.rb +++ b/spec/integration/responders_spec.rb @@ -23,7 +23,7 @@ describe 'App' do end end - it '' do + it 'runs responder when rendering the response with respond_with' do response = get '/foo/hash', {}, 'HTTP_ACCEPT' => 'application/json' JSON.parse(response.body).should == { 'foo' => 'bar', 'extra' => 'moar!' } end diff --git a/spec/integration/scopes_spec.rb b/spec/integration/scopes_spec.rb new file mode 100644 index 00000000..d5b13576 --- /dev/null +++ b/spec/integration/scopes_spec.rb @@ -0,0 +1,32 @@ +require 'spec_helper' + +describe 'App' do + before do + FactoryGirl.create(:test, :number => '3.1', :queue => 'builds.common') + + add_endpoint '/foo' do + get '/hash', scope: [:foo, :bar] do + respond_with foo: 'bar' + end + end + end + + it 'checks if token has one of the required scopes' do + token = Travis::Api::App::AccessToken.new(app_id: 1, user_id: 2, scopes: [:foo]).tap(&:save) + + response = get '/foo/hash', {}, 'HTTP_ACCEPT' => 'application/json', 'HTTP_AUTHORIZATION' => "token #{token.token}" + response.should be_successful + response.headers['X-Accepted-OAuth-Scopes'].should == 'foo' + + token = Travis::Api::App::AccessToken.new(app_id: 1, user_id: 2, scopes: [:bar]).tap(&:save) + + response = get '/foo/hash', {}, 'HTTP_ACCEPT' => 'application/json', 'HTTP_AUTHORIZATION' => "token #{token.token}" + response.should be_successful + response.headers['X-Accepted-OAuth-Scopes'].should == 'bar' + + token = Travis::Api::App::AccessToken.new(app_id: 1, user_id: 2, scopes: [:baz]).tap(&:save) + + response = get '/foo/hash', {}, 'HTTP_ACCEPT' => 'application/json', 'HTTP_AUTHORIZATION' => "token #{token.token}" + response.status.should == 403 + end +end