谷歌OAuth2服务器到服务器身份验证的问题

时间:2015-10-05 13:52:41

标签: ruby google-admin-sdk google-oauth2

我尝试从Google API管理SDK获取有关我的所有客户的信息,这些客户未启用两步验证,而我的身份验证问题是在我的ruby脚本中抛出Google OAuth2。服务器上我运行的脚本没有GUI,因此无法运行Web浏览器。我的剧本:

require 'google/api_client'
require 'google/api_client/client_secrets'
require 'google/api_client/auth/installed_app'
require 'google/api_client/auth/storage'
require 'google/api_client/auth/storages/file_store'
require 'fileutils'
require 'date'
require 'googleauth'
require 'openssl'
OpenSSL::SSL::VERIFY_PEER = OpenSSL::SSL::VERIFY_NONE


APPLICATION_NAME = '2stepauthcheck'
SERVICE_ACCOUNT_EMAIL_ADDRESS = 'use_my_own_email_from_dev_console@developer.gserviceaccount.com' # looks like 12345@developer.gserviceaccount.com
PATH_TO_KEY_FILE              = './2stepauthcheckp12.p12' # the path to the downloaded .p12 key file

date3 = (Date.today - 3)

client = Google::APIClient.new(:application_name => APPLICATION_NAME)
  client.authorization = Signet::OAuth2::Client.new(
    :token_credential_uri => 'https://accounts.google.com/o/oauth2/token',
    :audience             => 'https://accounts.google.com/o/oauth2/token',
    :scope                => 'https://www.googleapis.com/auth/admin.reports.usage.readonly',
    :issuer               => SERVICE_ACCOUNT_EMAIL_ADDRESS,
    :signing_key          => Google::APIClient::PKCS12.load_key(PATH_TO_KEY_FILE, 'notasecret')
).tap { |auth| auth.fetch_access_token! }

reports_api = client.discovered_api('admin', 'reports_v1')

def email_send(email)
  puts "Sending email"
  realname = email.sub(/@.*?$/, '').to_s.gsub(/(\S+)\.(\S+)/){ $1.to_s.capitalize + " " + $2.to_s.capitalize } #remove @domante from email address & create user name for email with capitalize letter with space
  #sent emails
  Mail.defaults {
    delivery_method  :smtp, :address    => "smtp.gmail.com",
                     :port       => 587,
                     :user_name  => 'admin@company.com',
                     :password   => '123password',
                     :enable_ssl => true

  }
  mail = Mail.new {
    to      "#{email}"
    from    'admin@company.com'
    subject '2 factor auth notification'
    text_part {
      body "Hi, #{realname} Turn on 2 factor authentication pls.\n"
    }
  }
  mail.deliver
  puts "Email sent"
end

# Put emails without 2 auth to array send_list.
results = client.execute!(
  :api_method => reports_api.user_usage_report.get,
  :parameters => { :userKey => 'all',
                   :date => date3.to_s,
                   :filds => 'parameters, entity',
                   :parameters => 'accounts:is_2sv_enrolled'})

black_list = [ "123@company.com"]

send_list = []

results.data.usageReports.each do |user|
  user.parameters.each do  |parameter|
    unless parameter['boolValue']
      send_list << user.entity.user_email
    end
  end
end

send_list.each do |email|
  if black_list.include?(email)
    next
  end
  puts email
#  email_send(email)
end

我有这样的输出:

/Users/val/.rvm/rubies/ruby-2.0.0-p481/bin/ruby -e $stdout.sync=true;$stderr.sync=true;load($0=ARGV.shift) /Users/val/Documents/projects/2authcheck2.rb
/Users/val/Documents/projects/2authcheck2.rb:12: warning: already initialized constant OpenSSL::SSL::VERIFY_PEER
/Users/val/.rvm/rubies/ruby-2.0.0-p481/lib/ruby/site_ruby/2.0.0/rubygems/core_ext/kernel_require.rb:126: warning: previous definition of VERIFY_PEER was here
/Users/val/.rvm/gems/ruby-2.0.0-p481/gems/google-api-client-0.8.6/lib/google/api_client.rb:662:in `block (2 levels) in execute!': Caller does not have access to the customers reporting data. (Google::APIClient::ClientError)
  from /Users/val/.rvm/gems/ruby-2.0.0-p481/gems/retriable-1.4.1/lib/retriable/retry.rb:27:in `perform'
  from /Users/val/.rvm/gems/ruby-2.0.0-p481/gems/retriable-1.4.1/lib/retriable.rb:15:in `retriable'
  from /Users/val/.rvm/gems/ruby-2.0.0-p481/gems/google-api-client-0.8.6/lib/google/api_client.rb:645:in `block in execute!'
  from /Users/val/.rvm/gems/ruby-2.0.0-p481/gems/retriable-1.4.1/lib/retriable/retry.rb:27:in `perform'
  from /Users/val/.rvm/gems/ruby-2.0.0-p481/gems/retriable-1.4.1/lib/retriable.rb:15:in `retriable'
  from /Users/val/.rvm/gems/ruby-2.0.0-p481/gems/google-api-client-0.8.6/lib/google/api_client.rb:636:in `execute!'
  from /Users/val/Documents/projects/devops-utils/it/2authcheck2.rb:92:in `<top (required)>'
  from -e:1:in `load'
  from -e:1:in `<main>'

Process finished with exit code 1

启用https://console.developers.google.com Admin SDK&amp; project 2stepauthcheck有服务帐户(在管理控制台中,授权API客户端与此API范围关联https://www.googleapis.com/auth/admin.directory.user.readonly

所以我的问题是为什么它无法访问客户报告数据?

1 个答案:

答案 0 :(得分:1)

根据Gerardo的建议我做了一些改变。这是一个完整的脚本:

#this script connect to admin reports and send email with notification that two-factor authentication should be on; script use oauth 2.0 for server to server applications
require 'google/api_client'
require 'google/api_client/client_secrets'
require 'google/api_client/auth/installed_app'
require 'google/api_client/auth/storage'
require 'google/api_client/auth/storages/file_store'
require 'fileutils'
require 'date'
require 'googleauth'
require 'mail'
require 'openssl'
OpenSSL::SSL::VERIFY_PEER = OpenSSL::SSL::VERIFY_NONE

# variables
date3 = (Date.today - 3)
APPLICATION_NAME = 'app_name' # name of the project in developers console https://console.developers.google.com/project
SERVICE_ACCOUNT_EMAIL_ADDRESS = '123@developer.gserviceaccount.com' # email address from developers console -> apis&auth -> credential -> sservice accounts; should looks like 12345@developer.gserviceaccount.com
PATH_TO_KEY_FILE              = './key.p12' # the path to the downloaded .p12 key file
CLIENT_ID = 'clientID.apps.googleusercontent.com' # from developers console
SCOPE = 'https://www.googleapis.com/auth/admin.reports.usage.readonly' # from https://developers.google.com/oauthplayground/
EMAIL = 'email@company.com' # email under which credential was created
key = Google::APIClient::KeyUtils.load_from_pkcs12('key.p12', 'notasecret') # make a key from .p12

# balack list emails arrays
black_list = [ "blacklist1@company.com", "blacklist2@company.com"]
send_list = [] # empty array for emails from api call results


# get the environment configured authorization
client = Google::APIClient.new({
                                   application_name: APPLICATION_NAME
                               })
# make authorization
client.authorization = Signet::OAuth2::Client.new(
    :token_credential_uri => 'https://accounts.google.com/o/oauth2/token',
    :audience => 'https://accounts.google.com/o/oauth2/token',
    :scope => SCOPE,
    :issuer => SERVICE_ACCOUNT_EMAIL_ADDRESS,
    :sub => EMAIL,
    :signing_key => key)
client.authorization.fetch_access_token!

# api discovery
reports_api = client.discovered_api('admin', 'reports_v1')

# send emails method
def email_send(email)
  puts "Sending email"
  realname = email.sub(/@.*?$/, '').to_s.gsub(/(\S+)\.(\S+)/){ $1.to_s.capitalize + " " + $2.to_s.capitalize } #remove @domante from email address & create user name for email with capitalize letter with space
  #sent emails
  Mail.defaults {
    delivery_method  :smtp, :address    => "smtp.gmail.com",
                     :port       => 587,
                     :user_name  => 'email@company.com',
                     :password   => 'pass',
                     :enable_ssl => true

  }
  mail = Mail.new {
    to      "#{email}"
    from    'email@company.com'
    subject '2 factor auth notification'
    text_part {
      body "Dear #{realname},\n
it looks as if you have not turned on the two-factor authentication.
Please see  the link to activation: https://accounts.google.com/SmsAuthConfig.\n"
    }
  }
  mail.deliver
  puts "Email sent"
end

# make call to api
results = client.execute!(
  :api_method => reports_api.user_usage_report.get,
  :parameters => { :userKey => 'all',
                   :date => date3.to_s,
                   :filds => 'parameters, entity',
                   :parameters => 'accounts:is_2sv_enrolled'})

# put emails without 2 auth to array send_list.
results.data.usageReports.each do |user|
  user.parameters.each do  |parameter|
    unless parameter['boolValue']
      send_list << user.entity.user_email
    end
  end
end

# send notification to emails exclud emails from blacklist
send_list.each do |email|
  if black_list.include?(email)
    next
  end
  puts email
  email_send(email)
end