126 lines
3.3 KiB
Ruby
126 lines
3.3 KiB
Ruby
require 'typhoeus'
|
|
require_dependency 'carto/oauth/github/config'
|
|
require_dependency 'carto/oauth/api'
|
|
|
|
module Carto
|
|
module Oauth
|
|
module Github
|
|
class Api < Carto::Oauth::Api
|
|
attr_reader :access_token
|
|
|
|
def student?
|
|
response = authenticated_request('GET', 'https://education.github.com/api/user')
|
|
if response
|
|
response['student']
|
|
else
|
|
log_error(message: 'Error checking GitHub student', access_token: access_token)
|
|
false
|
|
end
|
|
rescue StandardError => e
|
|
log_error(message: 'Error checking GitHub student', exception: e, access_token: access_token)
|
|
end
|
|
|
|
def user_params
|
|
{
|
|
username: username,
|
|
email: email,
|
|
github_user_id: id,
|
|
name: name
|
|
}
|
|
end
|
|
|
|
def user
|
|
user = User.where(github_user_id: id).first
|
|
unless user
|
|
user = User.where(email: email, github_user_id: nil).first
|
|
return false unless user
|
|
user.github_user_id = id
|
|
user.save
|
|
end
|
|
user
|
|
end
|
|
|
|
def hidden_fields
|
|
{
|
|
oauth_provider: 'github',
|
|
oauth_access_token: access_token,
|
|
'user[github_user_id]': id
|
|
}
|
|
end
|
|
|
|
def valid?(user)
|
|
id == user.github_user_id
|
|
end
|
|
|
|
private
|
|
|
|
def id
|
|
user_data['id']
|
|
end
|
|
|
|
def username
|
|
user_data['login']
|
|
end
|
|
|
|
def name
|
|
user_data['name']
|
|
end
|
|
|
|
def email
|
|
user_emails.find { |email| email['primary'] }['email']
|
|
end
|
|
|
|
def user_data
|
|
@user_data ||= authenticated_request('GET', 'https://api.github.com/user')
|
|
rescue StandardError => e
|
|
log_error(message: 'Error obtaining GitHub user data', exception: e, access_token: access_token)
|
|
nil
|
|
end
|
|
|
|
def user_emails
|
|
@user_emails ||= get_emails
|
|
end
|
|
|
|
def get_emails
|
|
authenticated_request('GET', 'https://api.github.com/user/emails').select { |email| email['verified'] }
|
|
rescue StandardError => e
|
|
log_error(message: 'Error obtaining GitHub user emails', exception: e, access_token: access_token)
|
|
nil
|
|
end
|
|
|
|
def authenticated_request(method, url, body: nil)
|
|
headers = {
|
|
'Accept' => 'application/json',
|
|
'Authorization' => "token #{@access_token}"
|
|
}
|
|
|
|
response = Typhoeus::Request.new(
|
|
url,
|
|
method: method,
|
|
ssl_verifypeer: true,
|
|
timeout: 5,
|
|
headers: headers,
|
|
body: body
|
|
).run
|
|
JSON.parse(response.body)
|
|
rescue StandardError => e
|
|
trace_info = {
|
|
message: 'Error in request to GitHub', exception: e,
|
|
request: { method: method, url: url, body: body, headers: headers }
|
|
}
|
|
if response
|
|
trace_info.merge!(response: {
|
|
code: response.code,
|
|
headers: response.headers,
|
|
body: response.body,
|
|
status: response.return_code
|
|
})
|
|
end
|
|
log_error(trace_info)
|
|
nil
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|