Merge branch 'master' into rkh-performance
This commit is contained in:
commit
1f3c1ae8ce
1
Gemfile
1
Gemfile
|
@ -7,6 +7,7 @@ gem 'travis-support', github: 'travis-ci/travis-support'
|
||||||
gem 'travis-core', github: 'travis-ci/travis-core', branch: 'sf-more-services'
|
gem 'travis-core', github: 'travis-ci/travis-core', branch: 'sf-more-services'
|
||||||
gem 'hubble', github: 'roidrage/hubble'
|
gem 'hubble', github: 'roidrage/hubble'
|
||||||
gem 'yard-sinatra', github: 'rkh/yard-sinatra'
|
gem 'yard-sinatra', github: 'rkh/yard-sinatra'
|
||||||
|
gem 'rack-contrib', github: 'rack/rack-contrib'
|
||||||
gem 'gh', github: 'rkh/gh'
|
gem 'gh', github: 'rkh/gh'
|
||||||
gem 'bunny'
|
gem 'bunny'
|
||||||
|
|
||||||
|
|
28
Gemfile.lock
28
Gemfile.lock
|
@ -4,6 +4,13 @@ GIT
|
||||||
specs:
|
specs:
|
||||||
micro_migrations (0.0.1)
|
micro_migrations (0.0.1)
|
||||||
|
|
||||||
|
GIT
|
||||||
|
remote: git://github.com/rack/rack-contrib.git
|
||||||
|
revision: b7e7c38fd02c3b5da91aa57af78b3f571c6ebcd0
|
||||||
|
specs:
|
||||||
|
rack-contrib (1.1.0)
|
||||||
|
rack (>= 0.9.1)
|
||||||
|
|
||||||
GIT
|
GIT
|
||||||
remote: git://github.com/rkh/gh.git
|
remote: git://github.com/rkh/gh.git
|
||||||
revision: affde20a4fecb1023f2e7031734b9386a76d22c2
|
revision: affde20a4fecb1023f2e7031734b9386a76d22c2
|
||||||
|
@ -25,15 +32,15 @@ GIT
|
||||||
|
|
||||||
GIT
|
GIT
|
||||||
remote: git://github.com/roidrage/hubble.git
|
remote: git://github.com/roidrage/hubble.git
|
||||||
revision: 8972b940a4f927927d2a4bdb250b3c98c04692a6
|
revision: f5e6301ac24eabeebaf8f4485d71cdcf93b2f3f8
|
||||||
specs:
|
specs:
|
||||||
hubble (0.1.2)
|
hubble (0.1.2)
|
||||||
faraday
|
faraday
|
||||||
json (~> 1.6.5)
|
json (~> 1.6)
|
||||||
|
|
||||||
GIT
|
GIT
|
||||||
remote: git://github.com/travis-ci/travis-core.git
|
remote: git://github.com/travis-ci/travis-core.git
|
||||||
revision: ea7a1678a0388e586ac4778a9b6ee56a11dfb0aa
|
revision: 6c974f0c0ad529748e95222c3145a0f085311ad1
|
||||||
branch: sf-more-services
|
branch: sf-more-services
|
||||||
specs:
|
specs:
|
||||||
travis-core (0.0.1)
|
travis-core (0.0.1)
|
||||||
|
@ -121,15 +128,15 @@ GEM
|
||||||
activesupport
|
activesupport
|
||||||
faraday (0.8.4)
|
faraday (0.8.4)
|
||||||
multipart-post (~> 1.1)
|
multipart-post (~> 1.1)
|
||||||
foreman (0.59.0)
|
foreman (0.60.0)
|
||||||
thor (>= 0.13.6)
|
thor (>= 0.13.6)
|
||||||
hashr (0.0.22)
|
hashr (0.0.22)
|
||||||
hike (1.2.1)
|
hike (1.2.1)
|
||||||
hitimes (1.1.1)
|
hitimes (1.1.1)
|
||||||
i18n (0.6.1)
|
i18n (0.6.1)
|
||||||
journey (1.0.4)
|
journey (1.0.4)
|
||||||
json (1.6.7)
|
json (1.7.5)
|
||||||
listen (0.5.1)
|
listen (0.5.2)
|
||||||
mail (2.4.4)
|
mail (2.4.4)
|
||||||
i18n (>= 0.4.0)
|
i18n (>= 0.4.0)
|
||||||
mime-types (~> 1.16)
|
mime-types (~> 1.16)
|
||||||
|
@ -140,7 +147,7 @@ GEM
|
||||||
avl_tree (~> 1.1.2)
|
avl_tree (~> 1.1.2)
|
||||||
hitimes (~> 1.1)
|
hitimes (~> 1.1)
|
||||||
mime-types (1.19)
|
mime-types (1.19)
|
||||||
mocha (0.12.4)
|
mocha (0.12.5)
|
||||||
metaclass (~> 0.0.1)
|
metaclass (~> 0.0.1)
|
||||||
multi_json (1.3.6)
|
multi_json (1.3.6)
|
||||||
multipart-post (1.1.5)
|
multipart-post (1.1.5)
|
||||||
|
@ -162,13 +169,11 @@ GEM
|
||||||
rack (1.4.1)
|
rack (1.4.1)
|
||||||
rack-cache (1.2)
|
rack-cache (1.2)
|
||||||
rack (>= 0.4)
|
rack (>= 0.4)
|
||||||
rack-contrib (1.1.0)
|
|
||||||
rack (>= 0.9.1)
|
|
||||||
rack-protection (1.2.0)
|
rack-protection (1.2.0)
|
||||||
rack
|
rack
|
||||||
rack-ssl (1.3.2)
|
rack-ssl (1.3.2)
|
||||||
rack
|
rack
|
||||||
rack-test (0.6.1)
|
rack-test (0.6.2)
|
||||||
rack (>= 1.0)
|
rack (>= 1.0)
|
||||||
railties (3.2.8)
|
railties (3.2.8)
|
||||||
actionpack (= 3.2.8)
|
actionpack (= 3.2.8)
|
||||||
|
@ -212,7 +217,7 @@ GEM
|
||||||
hike (~> 1.2)
|
hike (~> 1.2)
|
||||||
rack (~> 1.0)
|
rack (~> 1.0)
|
||||||
tilt (~> 1.1, != 1.3.0)
|
tilt (~> 1.1, != 1.3.0)
|
||||||
thin (1.4.1)
|
thin (1.5.0)
|
||||||
daemons (>= 1.0.9)
|
daemons (>= 1.0.9)
|
||||||
eventmachine (>= 0.12.6)
|
eventmachine (>= 0.12.6)
|
||||||
rack (>= 1.0.0)
|
rack (>= 1.0.0)
|
||||||
|
@ -235,6 +240,7 @@ DEPENDENCIES
|
||||||
hubble!
|
hubble!
|
||||||
micro_migrations!
|
micro_migrations!
|
||||||
mocha (~> 0.12)
|
mocha (~> 0.12)
|
||||||
|
rack-contrib!
|
||||||
rake (~> 0.9.2)
|
rake (~> 0.9.2)
|
||||||
rerun
|
rerun
|
||||||
rspec (~> 2.11)
|
rspec (~> 2.11)
|
||||||
|
|
39
config/newrelic.yml
Normal file
39
config/newrelic.yml
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
---
|
||||||
|
staging:
|
||||||
|
error_collector:
|
||||||
|
capture_source: true
|
||||||
|
enabled: true
|
||||||
|
ignore_errors: ActionController::RoutingError
|
||||||
|
apdex_t: 0.5
|
||||||
|
ssl: false
|
||||||
|
monitor_mode: true
|
||||||
|
license_key: <%= ENV["NEW_RELIC_LICENSE_KEY"] %>
|
||||||
|
developer_mode: false
|
||||||
|
app_name: <%= ENV["NEW_RELIC_APP_NAME"] %>
|
||||||
|
transaction_tracer:
|
||||||
|
record_sql: obfuscated
|
||||||
|
enabled: true
|
||||||
|
stack_trace_threshold: 0.5
|
||||||
|
transaction_threshold: apdex_f
|
||||||
|
capture_params: false
|
||||||
|
log_level: info
|
||||||
|
|
||||||
|
production:
|
||||||
|
error_collector:
|
||||||
|
capture_source: true
|
||||||
|
enabled: true
|
||||||
|
ignore_errors: ActionController::RoutingError
|
||||||
|
apdex_t: 0.5
|
||||||
|
ssl: false
|
||||||
|
monitor_mode: true
|
||||||
|
license_key: <%= ENV["NEW_RELIC_LICENSE_KEY"] %>
|
||||||
|
developer_mode: false
|
||||||
|
app_name: <%= ENV["NEW_RELIC_APP_NAME"] %>
|
||||||
|
transaction_tracer:
|
||||||
|
record_sql: obfuscated
|
||||||
|
enabled: true
|
||||||
|
stack_trace_threshold: 0.5
|
||||||
|
transaction_threshold: apdex_f
|
||||||
|
capture_params: false
|
||||||
|
log_level: info
|
||||||
|
|
|
@ -10,6 +10,9 @@ require 'rack/contrib'
|
||||||
require 'active_record'
|
require 'active_record'
|
||||||
require 'redis'
|
require 'redis'
|
||||||
require 'gh'
|
require 'gh'
|
||||||
|
require 'hubble'
|
||||||
|
require 'hubble/middleware'
|
||||||
|
require 'newrelic_rpm'
|
||||||
|
|
||||||
# Rack class implementing the HTTP API.
|
# Rack class implementing the HTTP API.
|
||||||
# Instances respond to #call.
|
# Instances respond to #call.
|
||||||
|
@ -51,8 +54,10 @@ class Travis::Api::App
|
||||||
|
|
||||||
def initialize
|
def initialize
|
||||||
@app = Rack::Builder.app do
|
@app = Rack::Builder.app do
|
||||||
|
use Hubble::Rescuer, env: Travis.env, codename: ENV['CODENAME'] if Endpoint.production? && ENV['HUBBLE_ENDPOINT']
|
||||||
use Rack::Protection::PathTraversal
|
use Rack::Protection::PathTraversal
|
||||||
use Rack::SSL if Endpoint.production?
|
use Rack::SSL if Endpoint.production?
|
||||||
|
use Rack::PostBodyContentTypeParser
|
||||||
use Rack::JSONP
|
use Rack::JSONP
|
||||||
use ActiveRecord::ConnectionAdapters::ConnectionManagement
|
use ActiveRecord::ConnectionAdapters::ConnectionManagement
|
||||||
|
|
||||||
|
@ -80,6 +85,7 @@ class Travis::Api::App
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.setup_travis
|
def self.setup_travis
|
||||||
|
Travis::Amqp.config = Travis.config.amqp
|
||||||
Travis::Database.connect
|
Travis::Database.connect
|
||||||
|
|
||||||
Travis::Services.constants.each do |name|
|
Travis::Services.constants.each do |name|
|
||||||
|
|
11
lib/travis/api/app/endpoint/accounts.rb
Normal file
11
lib/travis/api/app/endpoint/accounts.rb
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
require 'travis/api/app'
|
||||||
|
|
||||||
|
class Travis::Api::App
|
||||||
|
class Endpoint
|
||||||
|
class Accounts < Endpoint
|
||||||
|
get '/', scope: :private do
|
||||||
|
body service(:account).find_all, type: :accounts
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -115,7 +115,7 @@ class Travis::Api::App
|
||||||
get '/post_message' do
|
get '/post_message' do
|
||||||
handshake do |user, token, target_origin|
|
handshake do |user, token, target_origin|
|
||||||
halt 403, invalid_target(target_origin) unless target_ok? target_origin
|
halt 403, invalid_target(target_origin) unless target_ok? target_origin
|
||||||
rendered_user = Travis::Api.data(service(:user, user).find_one, type: :user, version: :v2)
|
rendered_user = Travis::Api.data(user, version: :v2)
|
||||||
post_message(token: token, user: rendered_user, target_origin: target_origin)
|
post_message(token: token, user: rendered_user, target_origin: target_origin)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -126,13 +126,18 @@ class Travis::Api::App
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
def oauth_endpoint
|
||||||
|
proxy = Travis.config.oauth2.proxy
|
||||||
|
proxy ? File.join(proxy, request.fullpath) : url
|
||||||
|
end
|
||||||
|
|
||||||
def handshake
|
def handshake
|
||||||
config = Travis.config.oauth2
|
config = Travis.config.oauth2
|
||||||
endpoint = Addressable::URI.parse(config.authorization_server)
|
endpoint = Addressable::URI.parse(config.authorization_server)
|
||||||
values = {
|
values = {
|
||||||
client_id: config.client_id,
|
client_id: config.client_id,
|
||||||
scope: config.scope,
|
scope: config.scope,
|
||||||
redirect_uri: url
|
redirect_uri: oauth_endpoint
|
||||||
}
|
}
|
||||||
|
|
||||||
if params[:code] and state_ok?(params[:state])
|
if params[:code] and state_ok?(params[:state])
|
||||||
|
@ -180,8 +185,8 @@ class Travis::Api::App
|
||||||
def user_for_github_token(token)
|
def user_for_github_token(token)
|
||||||
data = GH.with(token: token.to_s) { GH['user'] }
|
data = GH.with(token: token.to_s) { GH['user'] }
|
||||||
scopes = parse_scopes data.headers['x-oauth-scopes']
|
scopes = parse_scopes data.headers['x-oauth-scopes']
|
||||||
user = User.find_by_github_id(data['id'])
|
user = ::User.find_by_github_id(data['id'])
|
||||||
user ||= User.create! user_info(data, github_oauth_token: token)
|
user ||= ::User.create! user_info(data, github_oauth_token: token)
|
||||||
|
|
||||||
halt 403, 'not a Travis user' if user.nil?
|
halt 403, 'not a Travis user' if user.nil?
|
||||||
halt 403, 'insufficient access' unless acceptable? scopes
|
halt 403, 'insufficient access' unless acceptable? scopes
|
||||||
|
|
|
@ -5,14 +5,13 @@ class Travis::Api::App
|
||||||
# TODO: Add documentation.
|
# TODO: Add documentation.
|
||||||
class Hooks < Endpoint
|
class Hooks < Endpoint
|
||||||
# TODO: Add implementation and documentation.
|
# TODO: Add implementation and documentation.
|
||||||
# TODO scope: :private
|
get('/', scope: :private) do
|
||||||
get('/') do
|
|
||||||
body service(:hooks).find_all(params), type: :hooks
|
body service(:hooks).find_all(params), type: :hooks
|
||||||
end
|
end
|
||||||
|
|
||||||
# TODO: Add implementation and documentation.
|
# TODO: Add implementation and documentation.
|
||||||
put('/:id', scope: :admin) do
|
put('/:id', scope: :private) do
|
||||||
body service(:hooks).update(params)
|
body service(:hooks).update(params[:hook])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,61 +0,0 @@
|
||||||
require 'travis/api/app'
|
|
||||||
|
|
||||||
class Travis::Api::App
|
|
||||||
class Endpoint
|
|
||||||
class Profile < Endpoint
|
|
||||||
# Gives information about the currently logged in user.
|
|
||||||
#
|
|
||||||
# Example:
|
|
||||||
#
|
|
||||||
# {
|
|
||||||
# "user": {
|
|
||||||
# "email": "svenfuchs@artweb-design.de",
|
|
||||||
# "gravatar_id": "402602a60e500e85f2f5dc1ff3648ecb",
|
|
||||||
# "is_syncing": false,
|
|
||||||
# "locale": "de",
|
|
||||||
# "login": "svenfuchs",
|
|
||||||
# "name": "Sven Fuchs",
|
|
||||||
# "synced_at": "2012-08-14T22:11:21Z"
|
|
||||||
# }
|
|
||||||
# }
|
|
||||||
get '/', scope: :private do
|
|
||||||
body service(:user).find_one, type: :user
|
|
||||||
end
|
|
||||||
|
|
||||||
put '/', scope: :private do
|
|
||||||
raise NotImplementedError
|
|
||||||
update_locale if valid_locale?
|
|
||||||
'ok'
|
|
||||||
end
|
|
||||||
|
|
||||||
# TODO: Add implementation and documentation.
|
|
||||||
post '/sync', scope: :private do
|
|
||||||
sync_user(current_user)
|
|
||||||
204
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def sync_user(user)
|
|
||||||
unless user.is_syncing?
|
|
||||||
publisher = Travis::Amqp::Publisher.new('sync.user')
|
|
||||||
publisher.publish({ user_id: user.id }, type: 'sync')
|
|
||||||
user.update_column(:is_syncing, true)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def locale
|
|
||||||
params[:user][:locale]
|
|
||||||
end
|
|
||||||
|
|
||||||
def valid_locale?
|
|
||||||
I18n.available_locales.include?(locale.to_sym) # ???
|
|
||||||
end
|
|
||||||
|
|
||||||
def update_locale
|
|
||||||
current_user.update_attributes!(:locale => locale.to_s)
|
|
||||||
session[:locale] = locale # ???
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
43
lib/travis/api/app/endpoint/users.rb
Normal file
43
lib/travis/api/app/endpoint/users.rb
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
require 'travis/api/app'
|
||||||
|
|
||||||
|
class Travis::Api::App
|
||||||
|
class Endpoint
|
||||||
|
class Users < Endpoint
|
||||||
|
# Gives information about the currently logged in user.
|
||||||
|
#
|
||||||
|
# Example:
|
||||||
|
#
|
||||||
|
# {
|
||||||
|
# "user": {
|
||||||
|
# "name": "Sven Fuchs",
|
||||||
|
# "login": "svenfuchs",
|
||||||
|
# "email": "svenfuchs@artweb-design.de",
|
||||||
|
# "gravatar_id": "402602a60e500e85f2f5dc1ff3648ecb",
|
||||||
|
# "locale": "de",
|
||||||
|
# "is_syncing": false,
|
||||||
|
# "synced_at": "2012-08-14T22:11:21Z"
|
||||||
|
# }
|
||||||
|
# }
|
||||||
|
get '/:id?', scope: :private do
|
||||||
|
body current_user
|
||||||
|
end
|
||||||
|
|
||||||
|
put '/:id?', scope: :private do
|
||||||
|
service(:user).update_locale(locale)
|
||||||
|
204
|
||||||
|
end
|
||||||
|
|
||||||
|
# TODO: Add implementation and documentation.
|
||||||
|
post '/sync', scope: :private do
|
||||||
|
service(:user).sync
|
||||||
|
204
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def locale
|
||||||
|
params[:user][:locale]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -20,6 +20,8 @@ class Travis::Api::App
|
||||||
#
|
#
|
||||||
# Logging is set up by custom middleware
|
# Logging is set up by custom middleware
|
||||||
disable :protection, :logging, :setup
|
disable :protection, :logging, :setup
|
||||||
|
enable :raise_errors
|
||||||
|
# disable :dump_errors
|
||||||
register :subclass_tracker
|
register :subclass_tracker
|
||||||
helpers :json_renderer
|
helpers :json_renderer
|
||||||
end
|
end
|
||||||
|
|
24
spec/endpoint/accounts_spec.rb
Normal file
24
spec/endpoint/accounts_spec.rb
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
describe Travis::Api::App::Endpoint::Accounts do
|
||||||
|
include Travis::Testing::Stubs
|
||||||
|
let(:access_token) { Travis::Api::App::AccessToken.create(user: user, app_id: -1) }
|
||||||
|
|
||||||
|
before do
|
||||||
|
User.stubs(:find_by_github_id).returns(user)
|
||||||
|
User.stubs(:find).returns(user)
|
||||||
|
user.stubs(:repositories).returns(stub(administratable: stub(select: [repository])))
|
||||||
|
user.stubs(:attributes).returns(:id => user.id, :login => user.login, :name => user.name)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'includes accounts' do
|
||||||
|
get('/accounts', access_token: access_token.to_s).should be_ok
|
||||||
|
parsed_body['accounts'].should == [{
|
||||||
|
'id' => user.id,
|
||||||
|
'login' => user.login,
|
||||||
|
'name' => user.name,
|
||||||
|
'type' => 'user',
|
||||||
|
'reposCount' => nil
|
||||||
|
}]
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,6 +1,6 @@
|
||||||
require 'spec_helper'
|
require 'spec_helper'
|
||||||
|
|
||||||
describe Travis::Api::App::Endpoint::Profile do
|
describe Travis::Api::App::Endpoint::Users do
|
||||||
include Travis::Testing::Stubs
|
include Travis::Testing::Stubs
|
||||||
let(:access_token) { Travis::Api::App::AccessToken.create(user: user, app_id: -1) }
|
let(:access_token) { Travis::Api::App::AccessToken.create(user: user, app_id: -1) }
|
||||||
|
|
||||||
|
@ -11,11 +11,11 @@ describe Travis::Api::App::Endpoint::Profile do
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'needs to be authenticated' do
|
it 'needs to be authenticated' do
|
||||||
get('/profile').should_not be_ok
|
get('/users').should_not be_ok
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'replies with the current user' do
|
it 'replies with the current user' do
|
||||||
get('/profile', access_token: access_token.to_s).should be_ok
|
get('/users', access_token: access_token.to_s).should be_ok
|
||||||
parsed_body['user'].should == {
|
parsed_body['user'].should == {
|
||||||
'id' => user.id,
|
'id' => user.id,
|
||||||
'login' => user.login,
|
'login' => user.login,
|
||||||
|
@ -27,15 +27,4 @@ describe Travis::Api::App::Endpoint::Profile do
|
||||||
'synced_at' => user.synced_at.strftime('%Y-%m-%dT%H:%M:%SZ')
|
'synced_at' => user.synced_at.strftime('%Y-%m-%dT%H:%M:%SZ')
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'includes accounts' do
|
|
||||||
get('/profile', access_token: access_token.to_s).should be_ok
|
|
||||||
parsed_body['accounts'].should == [{
|
|
||||||
'id' => user.id,
|
|
||||||
'login' => user.login,
|
|
||||||
'name' => user.name,
|
|
||||||
'type' => 'user',
|
|
||||||
'reposCount' => nil
|
|
||||||
}]
|
|
||||||
end
|
|
||||||
end
|
end
|
Loading…
Reference in New Issue
Block a user