Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ak no gh (do-not-megre-it) #1187

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ gem 'rack', '>= 2.1.4'
gem 'rack-contrib'
gem 'rack-cache', git: 'https://github.com/rtomayko/rack-cache'
gem 'rack-attack', '~> 5.0'
gem 'gh', git: 'https://github.com/travis-ci/gh'
gem 'bunny', '~> 2.9.2'
gem 'dalli'
gem 'pry'
Expand Down Expand Up @@ -56,6 +55,7 @@ gem 'opencensus-stackdriver'

gem 'faraday'
gem 'faraday_middleware'
gem 'net-http-persistent'

gem 'knapsack'

Expand Down
18 changes: 3 additions & 15 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,6 @@ GIT
rack-cache (1.11.0)
rack (>= 0.4)

GIT
remote: https://github.com/travis-ci/gh
revision: 66449dc14db5eee0a24a4dbcb85e52dd5b63513f
specs:
gh (0.15.2)
addressable (~> 2.4)
backports
faraday (~> 0.8)
multi_json (~> 1.0)
net-http-persistent (~> 2.9)
net-http-pipeline

GIT
remote: https://github.com/travis-ci/marginalia
revision: 46bbe301640efb5ea81828cb7deeaf874516de78
Expand Down Expand Up @@ -283,8 +271,8 @@ GEM
mustermann (1.1.1)
ruby2_keywords (~> 0.0.1)
nakayoshi_fork (0.0.4)
net-http-persistent (2.9.4)
net-http-pipeline (1.0.1)
net-http-persistent (4.0.0)
connection_pool (~> 2.2)
nokogiri (1.10.9)
mini_portile2 (~> 2.4.0)
opencensus (0.5.0)
Expand Down Expand Up @@ -439,7 +427,6 @@ DEPENDENCIES
fog-aws (~> 0.12.0)
fog-google (~> 0.4.2)
foreman
gh!
google-api-client (~> 0.9.4)
hashdiff
hashr
Expand All @@ -457,6 +444,7 @@ DEPENDENCIES
multi_json
mustermann
nakayoshi_fork
net-http-persistent
opencensus
opencensus-stackdriver
pg (~> 0.21)
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ https://api.travis-ci.org

## WARNING!!!!!
Master branch is designed for .com only. If you would like to deploy changes for .org please use org-only branch

## Requirements

You will need the following packages to get travis-api to work:
Expand Down
7 changes: 3 additions & 4 deletions bin/migrate-hooks
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ require 'date'
require 'stringio'
require 'thread'
require 'travis'
require 'travis/api/v3/github'
require 'travis/config/defaults'
require 'travis/model/repository'

Expand Down Expand Up @@ -55,7 +54,7 @@ class Migrate
ids = query.ids
ids.sort.reverse.each { |id| queue.push(id) }
puts "Queued #{ids.size} repos"

sleep 5

# Start num_workers threads and start running off the queue
Expand Down Expand Up @@ -115,13 +114,13 @@ class Migrate
puts "No webhook found but service hook found, syncing repo #{repo.slug} active attr"
puts "Save failed" unless repo.update(active: service_hook['active'])
end

# Only set webhook for repos with an active service hook
if (service_hook && service_hook['active'])
puts "Found active service hook for #{repo.slug}, setting webhook"
gh.set_hook(repo, true)
end

migrated = true
break
rescue => e
Expand Down
6 changes: 3 additions & 3 deletions config.ru
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ require 'travis/api/app'
require 'core_ext/module/load_constants'

models = Travis::Model.constants.map(&:to_s)
only = [/^(ActiveRecord|ActiveModel|Travis|GH|#{models.join('|')})/]
skip = ['Travis::Memory', 'GH::ResponseWrapper', 'Travis::Helpers::Legacy', 'GH::FaradayAdapter::EMSynchrony']
only = [/^(ActiveRecord|ActiveModel|Travis|#{models.join('|')})/]
skip = ['Travis::Memory', 'Travis::Helpers::Legacy']

[Travis::Api, Travis, GH].each do |target|
[Travis::Api, Travis].each do |target|
target.load_constants! :only => only, :skip => skip, :debug => false
end

Expand Down
1 change: 0 additions & 1 deletion lib/travis.rb
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ def setup(options = {})

Travis.logger.info("Setting up module Travis")

Github.setup
Services.register
Github::Services.register
end
Expand Down
1 change: 0 additions & 1 deletion lib/travis/api/app.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
require 'travis/api/attack'
require 'active_record'
require 'redis'
require 'gh'
require 'raven'
require 'raven/integrations/rack'
require 'sidekiq'
Expand Down
208 changes: 4 additions & 204 deletions lib/travis/api/app/endpoint/authorization.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@
require 'faraday_middleware'
require 'securerandom'
require 'travis/api/app'
require 'travis/github/education'
require 'travis/github/oauth'
require 'travis/remote_vcs/user'
require 'travis/remote_vcs/response_error'
require 'uri'
Expand Down Expand Up @@ -92,22 +90,20 @@ class Authorization < Endpoint
end

# For new provider method
# renew_access_token(token: params[:github_token], app_id: 1, provider: :github)
{ 'access_token' => github_to_travis(params[:github_token], app_id: 1, drop_token: true) }
renew_access_token(token: params[:github_token], app_id: 1, provider: :github)
end

# Endpoint for making sure user authorized Travis CI to access GitHub.
# Endpoint for making sure user authorized Travis CI to access VCS provider.
# There are no restrictions on where to redirect to after handshake.
# However, no information whatsoever is being sent with the redirect.
#
# Parameters:
#
# * **redirect_uri**: URI to redirect to after handshake.
get '/handshake/?:provider?' do
method = org? ? :handshake : :vcs_handshake
params[:provider] ||= 'github'
send(method) do |user, token, redirect_uri|
if target_ok? redirect_uri
vcs_handshake do |user, token, redirect_uri|
if target_ok?(redirect_uri)
content_type :html
data = { user: user, token: token, uri: redirect_uri }
erb(:post_payload, locals: data)
Expand Down Expand Up @@ -151,42 +147,6 @@ def log_with_request_id(line)
Travis.logger.info "#{line} <request_id=#{request_id}>"
end

def handshake
config = Travis.config.oauth2.to_h
endpoint = Addressable::URI.parse(config[:authorization_server])
values = {
client_id: config[:client_id],
scope: config[:scope],
redirect_uri: oauth_endpoint
}

log_with_request_id("[handshake] Starting handshake")

if params[:code]
unless state_ok?(params[:state])
log_with_request_id("[handshake] Handshake failed (state mismatch)")
handle_invalid_response
return
end

endpoint.path = config[:access_token_path]
values[:state] = params[:state]
values[:code] = params[:code]
values[:client_secret] = config[:client_secret]
github_token = get_token(endpoint.to_s, values)
user = user_for_github_token(github_token)
token = generate_token(user: user, app_id: 0)
payload = params[:state].split(":::", 2)[1]
update_first_login(user)
yield serialize_user(user), token, payload
else
values[:state] = create_state
endpoint.path = config[:authorize_path]
endpoint.query_values = values
redirect to(endpoint.to_s)
end
end

# VCS HANDSHAKE START

def remote_vcs_user
Expand Down Expand Up @@ -274,171 +234,11 @@ def handle_invalid_response
redirect to("https://#{Travis.config.host}/")
end

def create_state
state = SecureRandom.urlsafe_base64(16)
redis.sadd('github:states', state)
redis.expire('github:states', 1800)
payload = params[:origin] || params[:redirect_uri]
state << ":::" << payload if payload
response.set_cookie(cookie_name, state)
state
end

def state_ok?(state, provider = :github)
cookie_state = request.cookies[cookie_name(provider)]
state == cookie_state and redis.srem('github:states', state.to_s.split(":::", 1))
end

def github_to_travis(token, options = {})
drop_token = options.delete(:drop_token)
generate_token options.merge(user: user_for_github_token(token, drop_token))
end

class UserManager < Struct.new(:data, :token, :drop_token)
include User::Renaming

attr_accessor :user

def initialize(*)
super

@user = ::User.find_by_github_id(data['id'])
end

def info(attributes = {})
info = data.to_hash.slice('name', 'login', 'gravatar_id')
info.merge! attributes.stringify_keys
if Travis::Features.feature_active?(:education_data_sync) ||
(user && Travis::Features.owner_active?(:education_data_sync, user))
info['education'] = education
end
info['github_id'] ||= data['id']
info['vcs_id'] ||= data['id']
info
end

def user_exists?
user
end

def education
Travis::Github::Education.new(token.to_s).student?
end

def fetch
retried ||= false
info = drop_token ? self.info : self.info(github_oauth_token: token)

ActiveRecord::Base.transaction do
if user
ensure_token_is_available
rename_repos_owner(user.login, info['login'])
user.update_attributes info
else
self.user = ::User.create! info
end

Travis::Github::Oauth.update_scopes(user) # unless Travis.env == 'test'

nullify_logins(user.github_id, user.login)
end

user
rescue ActiveRecord::RecordNotUnique
unless retried
retried = true
retry
end
end

def ensure_token_is_available
unless user.tokens.first
user.create_a_token
end
end
end

def user_for_github_token(token, drop_token = false)
data = GH.with(token: token.to_s, client_id: nil) { GH['user'] }
scopes = parse_scopes data.headers['x-oauth-scopes']
manager = UserManager.new(data, token, drop_token)

unless acceptable?(scopes, drop_token)
# TODO: we should probably only redirect if this is a web
# oauth request, are there any other possibilities to
# consider?
url = Travis.config.oauth2.insufficient_access_redirect_url
url += "#existing-user" if manager.user_exists?
redirect to(url)
end

user = manager.fetch
if user.nil?
log_with_request_id("[handshake] Fetching user failed")
halt 403, 'not a Travis user'
end

Travis.run_service(:sync_user, user)

user
rescue GH::Error
# not a valid token actually, but we don't want to expose that info
halt 403, 'not a Travis user'
end

def get_token(endpoint, values)
# Get base URL for when we setup Faraday since otherwise it'll ignore no_proxy
url = URI.parse(endpoint)
base_url = "#{url.scheme}://#{url.host}"
http_options = {url: base_url, ssl: Travis.config.ssl.to_h.merge(Travis.config.github.ssl || {}).compact}

conn = Faraday.new(http_options) do |conn|
conn.request :json
conn.use :instrumentation
conn.use OpenCensus::Trace::Integrations::FaradayMiddleware if Travis::Api::App::Middleware::OpenCensus.enabled?
conn.adapter :net_http_persistent
end
response = conn.post(endpoint, values)

parameters = Addressable::URI.form_unencode(response.body)
token_info = parameters.assoc("access_token")

unless token_info
log_with_request_id("[handshake] Could not fetch token, github's response: status=#{response.status}, body=#{parameters.inspect} headers=#{response.headers.inspect}")
halt 401, 'could not resolve github token'
end
token_info.last
end

def parse_scopes(data)
data.gsub(/\s/,'').split(',') if data
end

def generate_token(options)
AccessToken.create(options).token
end

def acceptable?(scopes, lossy = false)
Travis::Github::Oauth.wanted_scopes.all? do |scope|
acceptable_scopes_for(scope, lossy).any? { |s| scopes.include? s }
end
end

def acceptable_scopes_for(scope, lossy = false)
scopes = case scope = scope.to_s
when /^(.+):/ then [$1, scope]
when 'public_repo' then [scope, 'repo']
else [scope]
end

if lossy
scopes << 'repo'
scopes << 'public_repo' if lossy and scope != 'repo'
end

scopes
end

def post_message(payload)
content_type :html
erb(:post_message, locals: payload)
Expand Down
1 change: 0 additions & 1 deletion lib/travis/api/app/endpoint/home.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ class Home < Endpoint
shorten_host: Travis.config.shorten_host,
assets: Travis.config.assets.to_h,
pusher: (Travis.config.pusher_ws || Travis.config.pusher.to_h || {}).to_hash.slice(:scheme, :host, :port, :path, :key, :secure, :private),
github: { api_url: GH.current.api_host.to_s, scopes: Travis.config.oauth2.try(:scope).to_s.split(?,) },
notifications: { webhook: { public_key: Travis.config.webhook.public_key } }
set :check_auth, false

Expand Down
Loading