diff --git a/Gemfile b/Gemfile index 9334227c..ce0fe1b8 100644 --- a/Gemfile +++ b/Gemfile @@ -33,6 +33,7 @@ gem 'skylight', '~> 0.6.0.beta.1' gem 'stackprof' gem 'jemalloc' +gem 'customerio' group :test do gem 'rspec', '~> 2.13' diff --git a/Gemfile.lock b/Gemfile.lock index 9353a43e..d587bd84 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -50,7 +50,7 @@ GIT GIT remote: git://github.com/travis-ci/travis-core.git - revision: 6ce83e05afc07d412195d226b77a896e2b652146 + revision: 90c2d1b67935f20fd117bc6d9bc02783312e27ba specs: travis-core (0.0.1) actionmailer (~> 3.2.19) @@ -157,6 +157,9 @@ GEM composite_primary_keys (5.0.14) activerecord (~> 3.2.0, >= 3.2.9) connection_pool (2.1.1) + customerio (0.6.1) + httparty (>= 0.5, < 0.12) + multi_json (~> 1.0) dalli (2.7.2) data_migrations (0.0.1) activerecord @@ -187,6 +190,9 @@ GEM hashr (0.0.22) hike (1.2.3) hitimes (1.2.3) + httparty (0.11.0) + multi_json (~> 1.0) + multi_xml (>= 0.5.2) httpclient (2.7.0.1) i18n (0.7.0) ice_nine (0.11.1) @@ -215,6 +221,7 @@ GEM mocha (0.14.0) metaclass (~> 0.0.1) multi_json (1.11.2) + multi_xml (0.5.5) multipart-post (2.0.0) net-http-persistent (2.9.4) net-http-pipeline (1.0.1) @@ -315,7 +322,7 @@ GEM treetop (1.4.15) polyglot polyglot (>= 0.3.1) - tzinfo (0.3.45) + tzinfo (0.3.46) unicorn (4.8.3) kgio (~> 2.6) rack @@ -335,6 +342,7 @@ PLATFORMS DEPENDENCIES active_model_serializers bunny (~> 0.8.0) + customerio dalli database_cleaner (~> 0.8.0) factory_girl (~> 2.4.0) @@ -369,3 +377,6 @@ DEPENDENCIES travis-yaml! unicorn yard-sinatra! + +BUNDLED WITH + 1.10.6 diff --git a/lib/travis/api/app/endpoint/authorization.rb b/lib/travis/api/app/endpoint/authorization.rb index 41b06e75..441032c0 100644 --- a/lib/travis/api/app/endpoint/authorization.rb +++ b/lib/travis/api/app/endpoint/authorization.rb @@ -2,6 +2,7 @@ require 'travis/api/app' require 'addressable/uri' require 'faraday' require 'securerandom' +require 'customerio' class Travis::Api::App class Endpoint @@ -95,6 +96,7 @@ class Travis::Api::App # * **redirect_uri**: URI to redirect to after handshake. get '/handshake' do handshake do |user, token, redirect_uri| + if target_ok? redirect_uri content_type :html data = { user: user, token: token, uri: redirect_uri } @@ -156,6 +158,33 @@ class Travis::Api::App halt 403, "you are currently not allowed to perform this request. please contact support@travis-ci.com." end + # update first login date if not set + def update_first_login(user) + unless user.first_logged_in_at + user.update_attributes(first_logged_in_at: Time.now) + end + end + + def update_customerio(user) + return unless Travis.config.customerio.site_id + + # send event to customer.io + payload = { + :id => user.id, + :name => user.name, + :login => user.login, + :email => primary_email_for_user(user.github_oauth_token), + :created_at => user.created_at.to_i, + :github_id => user.github_id, + :education => user.education, + :first_logged_in_at => user.first_logged_in_at.to_i + } + + customerio.identify(payload) + rescue StandardError => e + Travis.logger.error "Could not update Customer.io for User: #{user.id}:#{user.login} with message:#{e.message}" + end + def serialize_user(user) rendered = Travis::Api.data(user, version: :v2) rendered['user'].merge('token' => user.tokens.first.try(:token).to_s) @@ -185,6 +214,8 @@ class Travis::Api::App 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) + update_customerio(user) yield serialize_user(user), token, payload else values[:state] = create_state @@ -194,6 +225,7 @@ class Travis::Api::App end end + def create_state state = SecureRandom.urlsafe_base64(16) redis.sadd('github:states', state) @@ -223,6 +255,7 @@ class Travis::Api::App super @user = ::User.find_by_github_id(data['id']) + end def info(attributes = {}) @@ -353,6 +386,15 @@ class Travis::Api::App def allowed_https_targets @allowed_https_targets ||= Travis.config.auth.target_origin.to_s.split(',') end + + def primary_email_for_user(oauth_token) + # check for the users primary email address (we don't store this info) + GH.with(token: oauth_token, client_id: nil) { GH['user/emails'] }.select { |e| e['primary'] }.first['email'] + end + + def customerio + Customerio::Client.new(Travis.config.customerio.site_id, Travis.config.customerio.api_key, :json => true) + end end end end