Merge pull request #76 from shicholas/update_tests

added ruby 2.3 to travis w/ other small changes.
This commit is contained in:
Tim Emiola 2016-07-14 08:02:49 +09:00 committed by GitHub
commit 37ed189b2e
25 changed files with 199 additions and 160 deletions

View File

@ -1,6 +1,7 @@
sudo: false
language: ruby
rvm:
- 2.3
- 2.2
- 2.0.0
- 2.1

View File

@ -42,7 +42,7 @@ module Google
# Module Auth provides classes that provide Google-specific authorization
# used to access Google APIs.
module Auth
NOT_FOUND_ERROR = <<END
NOT_FOUND_ERROR = <<END.freeze
Could not load the default credentials. Browse to
https://developers.google.com/accounts/docs/application-default-credentials
for more information
@ -70,14 +70,14 @@ END
def self.read_creds
env_var = CredentialsLoader::ACCOUNT_TYPE_VAR
type = ENV[env_var]
fail "#{env_var} is undefined in env" unless type
raise "#{env_var} is undefined in env" unless type
case type
when 'service_account'
ServiceAccountCredentials
when 'authorized_user'
UserRefreshCredentials
else
fail "credentials type '#{type}' is not supported"
raise "credentials type '#{type}' is not supported"
end
end
@ -85,7 +85,7 @@ END
def self.determine_creds_class(json_key_io)
json_key = MultiJson.load(json_key_io.read)
key = 'type'
fail "the json is missing the '#{key}' field" unless json_key.key?(key)
raise "the json is missing the '#{key}' field" unless json_key.key?(key)
type = json_key[key]
case type
when 'service_account'
@ -93,7 +93,7 @@ END
when 'authorized_user'
[json_key, UserRefreshCredentials]
else
fail "credentials type '#{type}' is not supported"
raise "credentials type '#{type}' is not supported"
end
end
end
@ -116,7 +116,7 @@ END
DefaultCredentials.from_well_known_path(scope) ||
DefaultCredentials.from_system_default_path(scope)
return creds unless creds.nil?
fail NOT_FOUND_ERROR unless GCECredentials.on_gce?(options)
raise NOT_FOUND_ERROR unless GCECredentials.on_gce?(options)
GCECredentials.new
end

View File

@ -34,12 +34,12 @@ module Google
# Representation of an application's identity for user authorization
# flows.
class ClientId
INSTALLED_APP = 'installed'
WEB_APP = 'web'
CLIENT_ID = 'client_id'
CLIENT_SECRET = 'client_secret'
INSTALLED_APP = 'installed'.freeze
WEB_APP = 'web'.freeze
CLIENT_ID = 'client_id'.freeze
CLIENT_SECRET = 'client_secret'.freeze
MISSING_TOP_LEVEL_ELEMENT_ERROR =
"Expected top level property 'installed' or 'web' to be present."
"Expected top level property 'installed' or 'web' to be present.".freeze
# Text identifier of the client ID
# @return [String]
@ -63,8 +63,8 @@ module Google
# & secrets in source. See {#from_file} to load from
# `client_secrets.json` files.
def initialize(id, secret)
fail 'Client id can not be nil' if id.nil?
fail 'Client secret can not be nil' if secret.nil?
raise 'Client id can not be nil' if id.nil?
raise 'Client secret can not be nil' if secret.nil?
@id = id
@secret = secret
end
@ -76,7 +76,7 @@ module Google
# Path of file to read from
# @return [Google::Auth::ClientID]
def self.from_file(file)
fail 'File can not be nil.' if file.nil?
raise 'File can not be nil.' if file.nil?
File.open(file.to_s) do |f|
json = f.read
config = MultiJson.load(json)
@ -92,9 +92,9 @@ module Google
# Parsed contents of the JSON file
# @return [Google::Auth::ClientID]
def self.from_hash(config)
fail 'Hash can not be nil.' if config.nil?
raise 'Hash can not be nil.' if config.nil?
raw_detail = config[INSTALLED_APP] || config[WEB_APP]
fail MISSING_TOP_LEVEL_ELEMENT_ERROR if raw_detail.nil?
raise MISSING_TOP_LEVEL_ELEMENT_ERROR if raw_detail.nil?
ClientId.new(raw_detail[CLIENT_ID], raw_detail[CLIENT_SECRET])
end
end

View File

@ -35,13 +35,13 @@ module Google
# Module Auth provides classes that provide Google-specific authorization
# used to access Google APIs.
module Auth
NO_METADATA_SERVER_ERROR = <<END
NO_METADATA_SERVER_ERROR = <<END.freeze
Error code 404 trying to get security access token
from Compute Engine metadata for the default service account. This
may be because the virtual machine instance does not have permission
scopes specified.
END
UNEXPECTED_ERROR_SUFFIX = <<END
UNEXPECTED_ERROR_SUFFIX = <<END.freeze
trying to get security access token from Compute Engine metadata for
the default service account
END
@ -52,8 +52,8 @@ END
# The IP Address is used in the URIs to speed up failures on non-GCE
# systems.
COMPUTE_AUTH_TOKEN_URI = 'http://169.254.169.254/computeMetadata/v1/'\
'instance/service-accounts/default/token'
COMPUTE_CHECK_URI = 'http://169.254.169.254'
'instance/service-accounts/default/token'.freeze
COMPUTE_CHECK_URI = 'http://169.254.169.254'.freeze
class << self
extend Memoist
@ -94,10 +94,10 @@ END
Signet::OAuth2.parse_credentials(resp.body,
resp.headers['content-type'])
when 404
fail(Signet::AuthorizationError, NO_METADATA_SERVER_ERROR)
raise(Signet::AuthorizationError, NO_METADATA_SERVER_ERROR)
else
msg = "Unexpected error code #{resp.status}" + UNEXPECTED_ERROR_SUFFIX
fail(Signet::AuthorizationError, msg)
raise(Signet::AuthorizationError, msg)
end
end
end

View File

@ -39,22 +39,23 @@ module Google
# credentials files on the file system.
module CredentialsLoader
extend Memoist
ENV_VAR = 'GOOGLE_APPLICATION_CREDENTIALS'
ENV_VAR = 'GOOGLE_APPLICATION_CREDENTIALS'.freeze
PRIVATE_KEY_VAR = 'GOOGLE_PRIVATE_KEY'
CLIENT_EMAIL_VAR = 'GOOGLE_CLIENT_EMAIL'
CLIENT_ID_VAR = 'GOOGLE_CLIENT_ID'
CLIENT_SECRET_VAR = 'GOOGLE_CLIENT_SECRET'
REFRESH_TOKEN_VAR = 'GOOGLE_REFRESH_TOKEN'
ACCOUNT_TYPE_VAR = 'GOOGLE_ACCOUNT_TYPE'
PRIVATE_KEY_VAR = 'GOOGLE_PRIVATE_KEY'.freeze
CLIENT_EMAIL_VAR = 'GOOGLE_CLIENT_EMAIL'.freeze
CLIENT_ID_VAR = 'GOOGLE_CLIENT_ID'.freeze
CLIENT_SECRET_VAR = 'GOOGLE_CLIENT_SECRET'.freeze
REFRESH_TOKEN_VAR = 'GOOGLE_REFRESH_TOKEN'.freeze
ACCOUNT_TYPE_VAR = 'GOOGLE_ACCOUNT_TYPE'.freeze
CREDENTIALS_FILE_NAME = 'application_default_credentials.json'
CREDENTIALS_FILE_NAME = 'application_default_credentials.json'.freeze
NOT_FOUND_ERROR =
"Unable to read the credential file specified by #{ENV_VAR}"
WELL_KNOWN_PATH = "gcloud/#{CREDENTIALS_FILE_NAME}"
WELL_KNOWN_ERROR = 'Unable to read the default credential file'
"Unable to read the credential file specified by #{ENV_VAR}".freeze
WELL_KNOWN_PATH = "gcloud/#{CREDENTIALS_FILE_NAME}".freeze
WELL_KNOWN_ERROR = 'Unable to read the default credential file'.freeze
SYSTEM_DEFAULT_ERROR = 'Unable to read the system default credential file'
SYSTEM_DEFAULT_ERROR =
'Unable to read the system default credential file'.freeze
# make_creds proxies the construction of a credentials instance
#
@ -71,7 +72,7 @@ module Google
def from_env(scope = nil)
if ENV.key?(ENV_VAR)
path = ENV[ENV_VAR]
fail "file #{path} does not exist" unless File.exist?(path)
raise "file #{path} does not exist" unless File.exist?(path)
File.open(path) do |f|
return make_creds(json_key_io: f, scope: scope)
end

View File

@ -37,16 +37,16 @@ module Google
module Auth
# Authenticates requests using IAM credentials.
class IAMCredentials
SELECTOR_KEY = 'x-goog-iam-authority-selector'
TOKEN_KEY = 'x-goog-iam-authorization-token'
SELECTOR_KEY = 'x-goog-iam-authority-selector'.freeze
TOKEN_KEY = 'x-goog-iam-authorization-token'.freeze
# Initializes an IAMCredentials.
#
# @param selector the IAM selector.
# @param token the IAM token.
def initialize(selector, token)
fail TypeError unless selector.is_a? String
fail TypeError unless token.is_a? String
raise TypeError unless selector.is_a? String
raise TypeError unless token.is_a? String
@selector = selector
@token = token
end

View File

@ -39,7 +39,7 @@ module Google
'email' => 'https://www.googleapis.com/auth/userinfo.email',
'profile' => 'https://www.googleapis.com/auth/userinfo.profile',
'openid' => 'https://www.googleapis.com/auth/plus.me'
}
}.freeze
def self.normalize(scope)
list = as_array(scope)
@ -53,7 +53,7 @@ module Google
when String
scope.split(' ')
else
fail 'Invalid scope value. Must be string or array'
raise 'Invalid scope value. Must be string or array'
end
end
end

View File

@ -46,7 +46,7 @@ module Google
#
# cf [Application Default Credentials](http://goo.gl/mkAHpZ)
class ServiceAccountCredentials < Signet::OAuth2::Client
TOKEN_CRED_URI = 'https://www.googleapis.com/oauth2/v3/token'
TOKEN_CRED_URI = 'https://www.googleapis.com/oauth2/v3/token'.freeze
extend CredentialsLoader
# Creates a ServiceAccountCredentials.
@ -73,8 +73,8 @@ module Google
# JSON key.
def self.read_json_key(json_key_io)
json_key = MultiJson.load(json_key_io.read)
fail 'missing client_email' unless json_key.key?('client_email')
fail 'missing private_key' unless json_key.key?('private_key')
raise 'missing client_email' unless json_key.key?('client_email')
raise 'missing private_key' unless json_key.key?('private_key')
[json_key['private_key'], json_key['client_email']]
end
@ -119,8 +119,8 @@ module Google
class ServiceAccountJwtHeaderCredentials
JWT_AUD_URI_KEY = :jwt_aud_uri
AUTH_METADATA_KEY = Signet::OAuth2::AUTH_METADATA_KEY
TOKEN_CRED_URI = 'https://www.googleapis.com/oauth2/v3/token'
SIGNING_ALGORITHM = 'RS256'
TOKEN_CRED_URI = 'https://www.googleapis.com/oauth2/v3/token'.freeze
SIGNING_ALGORITHM = 'RS256'.freeze
EXPIRY = 60
extend CredentialsLoader
@ -139,8 +139,8 @@ module Google
# JSON key.
def self.read_json_key(json_key_io)
json_key = MultiJson.load(json_key_io.read)
fail 'missing client_email' unless json_key.key?('client_email')
fail 'missing private_key' unless json_key.key?('private_key')
raise 'missing client_email' unless json_key.key?('client_email')
raise 'missing private_key' unless json_key.key?('private_key')
[json_key['private_key'], json_key['client_email']]
end

View File

@ -64,7 +64,7 @@ module Signet
@refresh_listeners << block
end
alias_method :orig_fetch_access_token!, :fetch_access_token!
alias orig_fetch_access_token! fetch_access_token!
def fetch_access_token!(options = {})
info = orig_fetch_access_token!(options)
notify_refresh_listeners

View File

@ -37,7 +37,7 @@ module Google
# are stored as JSON using the supplied key, prefixed with
# `g-user-token:`
class RedisTokenStore < Google::Auth::TokenStore
DEFAULT_KEY_PREFIX = 'g-user-token:'
DEFAULT_KEY_PREFIX = 'g-user-token:'.freeze
# Create a new store with the supplied redis client.
#
@ -51,11 +51,11 @@ module Google
def initialize(options = {})
redis = options.delete(:redis)
prefix = options.delete(:prefix)
case redis
@redis = case redis
when Redis
@redis = redis
redis
else
@redis = Redis.new(options)
Redis.new(options)
end
@prefix = prefix || DEFAULT_KEY_PREFIX
end

View File

@ -44,7 +44,7 @@ module Google
# @return [String]
# The loaded token data.
def load(_id)
fail 'Not implemented'
raise 'Not implemented'
end
# Put the token data into storage for the given ID.
@ -54,7 +54,7 @@ module Google
# @param [String] token
# The token data to store.
def store(_id, _token)
fail 'Not implemented'
raise 'Not implemented'
end
# Remove the token data from storage for the given ID.
@ -62,7 +62,7 @@ module Google
# @param [String] id
# ID of the token data to delete
def delete(_id)
fail 'Not implemented'
raise 'Not implemented'
end
end
end

View File

@ -32,6 +32,7 @@ require 'multi_json'
require 'googleauth/signet'
require 'googleauth/user_refresh'
# rubocop:disable ClassLength
module Google
module Auth
# Handles an interactive 3-Legged-OAuth2 (3LO) user consent authorization.
@ -53,13 +54,13 @@ module Google
# ...
class UserAuthorizer
MISMATCHED_CLIENT_ID_ERROR =
'Token client ID of %s does not match configured client id %s'
NIL_CLIENT_ID_ERROR = 'Client id can not be nil.'
NIL_SCOPE_ERROR = 'Scope can not be nil.'
NIL_USER_ID_ERROR = 'User ID can not be nil.'
NIL_TOKEN_STORE_ERROR = 'Can not call method if token store is nil'
'Token client ID of %s does not match configured client id %s'.freeze
NIL_CLIENT_ID_ERROR = 'Client id can not be nil.'.freeze
NIL_SCOPE_ERROR = 'Scope can not be nil.'.freeze
NIL_USER_ID_ERROR = 'User ID can not be nil.'.freeze
NIL_TOKEN_STORE_ERROR = 'Can not call method if token store is nil'.freeze
MISSING_ABSOLUTE_URL_ERROR =
'Absolute base url required for relative callback url "%s"'
'Absolute base url required for relative callback url "%s"'.freeze
# Initialize the authorizer
#
@ -73,8 +74,8 @@ module Google
# URL (either absolute or relative) of the auth callback.
# Defaults to '/oauth2callback'
def initialize(client_id, scope, token_store, callback_uri = nil)
fail NIL_CLIENT_ID_ERROR if client_id.nil?
fail NIL_SCOPE_ERROR if scope.nil?
raise NIL_CLIENT_ID_ERROR if client_id.nil?
raise NIL_SCOPE_ERROR if scope.nil?
@client_id = client_id
@scope = Array(scope)
@ -102,7 +103,8 @@ module Google
credentials = UserRefreshCredentials.new(
client_id: @client_id.id,
client_secret: @client_id.secret,
scope: scope)
scope: scope
)
redirect_uri = redirect_uri_for(options[:base_url])
url = credentials.authorization_uri(access_type: 'offline',
redirect_uri: redirect_uri,
@ -123,8 +125,8 @@ module Google
# @return [Google::Auth::UserRefreshCredentials]
# Stored credentials, nil if none present
def get_credentials(user_id, scope = nil)
fail NIL_USER_ID_ERROR if user_id.nil?
fail NIL_TOKEN_STORE_ERROR if @token_store.nil?
raise NIL_USER_ID_ERROR if user_id.nil?
raise NIL_TOKEN_STORE_ERROR if @token_store.nil?
scope ||= @scope
saved_token = @token_store.load(user_id)
@ -132,7 +134,7 @@ module Google
data = MultiJson.load(saved_token)
if data.fetch('client_id', @client_id.id) != @client_id.id
fail sprintf(MISMATCHED_CLIENT_ID_ERROR,
raise sprintf(MISMATCHED_CLIENT_ID_ERROR,
data['client_id'], @client_id.id)
end
@ -142,10 +144,10 @@ module Google
scope: data['scope'] || @scope,
access_token: data['access_token'],
refresh_token: data['refresh_token'],
expires_at: data.fetch('expiration_time_millis', 0) / 1000)
expires_at: data.fetch('expiration_time_millis', 0) / 1000
)
if credentials.includes_scope?(scope)
monitor_credentials(user_id, credentials)
return credentials
return monitor_credentials(user_id, credentials)
end
nil
end
@ -174,7 +176,8 @@ module Google
client_id: @client_id.id,
client_secret: @client_id.secret,
redirect_uri: redirect_uri_for(base_url),
scope: scope)
scope: scope
)
credentials.code = code
credentials.fetch_access_token!({})
monitor_credentials(user_id, credentials)
@ -234,7 +237,8 @@ module Google
access_token: credentials.access_token,
refresh_token: credentials.refresh_token,
scope: credentials.scope,
expiration_time_millis: (credentials.expires_at.to_i) * 1000)
expiration_time_millis: credentials.expires_at.to_i * 1000
)
@token_store.store(user_id, json)
credentials
end
@ -263,11 +267,13 @@ module Google
# Redirect URI
def redirect_uri_for(base_url)
return @callback_uri unless URI(@callback_uri).scheme.nil?
fail sprintf(
raise sprintf(
MISSING_ABSOLUTE_URL_ERROR,
@callback_uri) if base_url.nil? || URI(base_url).scheme.nil?
@callback_uri
) if base_url.nil? || URI(base_url).scheme.nil?
URI.join(base_url, @callback_uri).to_s
end
end
end
end
# rubocop:enable ClassLength

View File

@ -46,9 +46,9 @@ module Google
#
# cf [Application Default Credentials](http://goo.gl/mkAHpZ)
class UserRefreshCredentials < Signet::OAuth2::Client
TOKEN_CRED_URI = 'https://www.googleapis.com/oauth2/v3/token'
AUTHORIZATION_URI = 'https://accounts.google.com/o/oauth2/auth'
REVOKE_TOKEN_URI = 'https://accounts.google.com/o/oauth2/revoke'
TOKEN_CRED_URI = 'https://www.googleapis.com/oauth2/v3/token'.freeze
AUTHORIZATION_URI = 'https://accounts.google.com/o/oauth2/auth'.freeze
REVOKE_TOKEN_URI = 'https://accounts.google.com/o/oauth2/revoke'.freeze
extend CredentialsLoader
# Create a UserRefreshCredentials.
@ -77,7 +77,7 @@ module Google
json_key = MultiJson.load(json_key_io.read)
wanted = %w(client_id client_secret refresh_token)
wanted.each do |key|
fail "the json is missing the #{key} field" unless json_key.key?(key)
raise "the json is missing the #{key} field" unless json_key.key?(key)
end
json_key
end
@ -99,7 +99,7 @@ module Google
self.refresh_token = nil
self.expires_at = 0
else
fail(Signet::AuthorizationError,
raise(Signet::AuthorizationError,
"Unexpected error code #{resp.status}")
end
end

View File

@ -31,6 +31,6 @@ module Google
# Module Auth provides classes that provide Google-specific authorization
# used to access Google APIs.
module Auth
VERSION = '0.5.1'
VERSION = '0.5.2'.freeze
end
end

View File

@ -66,20 +66,21 @@ module Google
# @see {Google::Auth::ControllerHelpers}
# @note Requires sessions are enabled
class WebUserAuthorizer < Google::Auth::UserAuthorizer
STATE_PARAM = 'state'
AUTH_CODE_KEY = 'code'
ERROR_CODE_KEY = 'error'
SESSION_ID_KEY = 'session_id'
CALLBACK_STATE_KEY = 'g-auth-callback'
CURRENT_URI_KEY = 'current_uri'
XSRF_KEY = 'g-xsrf-token'
SCOPE_KEY = 'scope'
STATE_PARAM = 'state'.freeze
AUTH_CODE_KEY = 'code'.freeze
ERROR_CODE_KEY = 'error'.freeze
SESSION_ID_KEY = 'session_id'.freeze
CALLBACK_STATE_KEY = 'g-auth-callback'.freeze
CURRENT_URI_KEY = 'current_uri'.freeze
XSRF_KEY = 'g-xsrf-token'.freeze
SCOPE_KEY = 'scope'.freeze
NIL_REQUEST_ERROR = 'Request is required.'
NIL_SESSION_ERROR = 'Sessions must be enabled'
MISSING_AUTH_CODE_ERROR = 'Missing authorization code in request'
AUTHORIZATION_ERROR = 'Authorization error: %s'
INVALID_STATE_TOKEN_ERROR = 'State token does not match expected value'
NIL_REQUEST_ERROR = 'Request is required.'.freeze
NIL_SESSION_ERROR = 'Sessions must be enabled'.freeze
MISSING_AUTH_CODE_ERROR = 'Missing authorization code in request'.freeze
AUTHORIZATION_ERROR = 'Authorization error: %s'.freeze
INVALID_STATE_TOKEN_ERROR =
'State token does not match expected value'.freeze
class << self
attr_accessor :default
@ -128,13 +129,15 @@ module Google
# credentials & next URL to redirect to
def handle_auth_callback(user_id, request)
callback_state, redirect_uri = WebUserAuthorizer.extract_callback_state(
request)
request
)
WebUserAuthorizer.validate_callback_state(callback_state, request)
credentials = get_and_store_credentials_from_code(
user_id: user_id,
code: callback_state[AUTH_CODE_KEY],
scope: callback_state[SCOPE_KEY],
base_url: request.url)
base_url: request.url
)
[credentials, redirect_uri]
end
@ -156,14 +159,15 @@ module Google
def get_authorization_url(options = {})
options = options.dup
request = options[:request]
fail NIL_REQUEST_ERROR if request.nil?
fail NIL_SESSION_ERROR if request.session.nil?
raise NIL_REQUEST_ERROR if request.nil?
raise NIL_SESSION_ERROR if request.session.nil?
redirect_to = options[:redirect_to] || request.url
request.session[XSRF_KEY] = SecureRandom.base64
options[:state] = MultiJson.dump(
SESSION_ID_KEY => request.session[XSRF_KEY],
CURRENT_URI_KEY => redirect_to)
CURRENT_URI_KEY => redirect_to
)
options[:base_url] = request.url
super(options)
end
@ -193,7 +197,8 @@ module Google
user_id: user_id,
code: callback_state[AUTH_CODE_KEY],
scope: callback_state[SCOPE_KEY],
base_url: request.url)
base_url: request.url
)
else
super(user_id, scope)
end
@ -223,12 +228,12 @@ module Google
# Current request
def self.validate_callback_state(state, request)
if state[AUTH_CODE_KEY].nil?
fail Signet::AuthorizationError, MISSING_AUTH_CODE_ERROR
raise Signet::AuthorizationError, MISSING_AUTH_CODE_ERROR
elsif state[ERROR_CODE_KEY]
fail Signet::AuthorizationError,
raise Signet::AuthorizationError,
sprintf(AUTHORIZATION_ERROR, state[ERROR_CODE_KEY])
elsif request.session[XSRF_KEY] != state[SESSION_ID_KEY]
fail Signet::AuthorizationError, INVALID_STATE_TOKEN_ERROR
raise Signet::AuthorizationError, INVALID_STATE_TOKEN_ERROR
end
end
@ -254,7 +259,7 @@ module Google
#
# @see {Google::Auth::WebUserAuthorizer}
class CallbackApp
LOCATION_HEADER = 'Location'
LOCATION_HEADER = 'Location'.freeze
REDIR_STATUS = 302
ERROR_STATUS = 500

View File

@ -62,7 +62,8 @@ shared_examples 'apply/apply! are OK' do
@client.on_refresh(&b)
@client.fetch_access_token!
end.to yield_with_args(have_attributes(
access_token: '1/abcdef1234567890'))
access_token: '1/abcdef1234567890'
))
expect(stub).to have_been_requested
end
end

View File

@ -104,7 +104,8 @@ describe Google::Auth::ClientId do
it 'should raise error' do
expect { Google::Auth::ClientId.from_hash(config) }.to raise_error(
/Expected top level property/)
/Expected top level property/
)
end
end
@ -119,7 +120,8 @@ describe Google::Auth::ClientId do
it 'should raise error' do
expect { Google::Auth::ClientId.from_hash(config) }.to raise_error(
/Client id can not be nil/)
/Client id can not be nil/
)
end
end
@ -134,7 +136,8 @@ describe Google::Auth::ClientId do
it 'should raise error' do
expect { Google::Auth::ClientId.from_hash(config) }.to raise_error(
/Client secret can not be nil/)
/Client secret can not be nil/
)
end
end
end

View File

@ -37,7 +37,7 @@ require 'googleauth/compute_engine'
require 'spec_helper'
describe Google::Auth::GCECredentials do
MD_URI = 'http://169.254.169.254/computeMetadata/v1/instance/service-accounts/default/token'
MD_URI = 'http://169.254.169.254/computeMetadata/v1/instance/service-accounts/default/token'.freeze
GCECredentials = Google::Auth::GCECredentials
before(:example) do
@ -64,8 +64,8 @@ describe Google::Auth::GCECredentials do
stub = stub_request(:get, MD_URI)
.to_return(status: 404,
headers: { 'Metadata-Flavor' => 'Google' })
blk = proc { @client.fetch_access_token! }
expect(&blk).to raise_error Signet::AuthorizationError
expect { @client.fetch_access_token! }
.to raise_error Signet::AuthorizationError
expect(stub).to have_been_requested
end
@ -73,8 +73,8 @@ describe Google::Auth::GCECredentials do
stub = stub_request(:get, MD_URI)
.to_return(status: 503,
headers: { 'Metadata-Flavor' => 'Google' })
blk = proc { @client.fetch_access_token! }
expect(&blk).to raise_error Signet::AuthorizationError
expect { @client.fetch_access_token! }
.to raise_error Signet::AuthorizationError
expect(stub).to have_been_requested
end
end

View File

@ -45,7 +45,8 @@ describe '#get_application_default' do
@var_name = ENV_VAR
@credential_vars = [
ENV_VAR, PRIVATE_KEY_VAR, CLIENT_EMAIL_VAR, CLIENT_ID_VAR,
CLIENT_SECRET_VAR, REFRESH_TOKEN_VAR, ACCOUNT_TYPE_VAR]
CLIENT_SECRET_VAR, REFRESH_TOKEN_VAR, ACCOUNT_TYPE_VAR
]
@original_env_vals = {}
@credential_vars.each { |var| @original_env_vals[var] = ENV[var] }
@home = ENV['HOME']
@ -74,10 +75,9 @@ describe '#get_application_default' do
Dir.mktmpdir do |dir|
ENV.delete(@var_name) unless ENV[@var_name].nil? # no env var
ENV['HOME'] = dir # no config present in this tmp dir
blk = proc do
expect do
Google::Auth.get_application_default(@scope, options)
end
expect(&blk).to raise_error RuntimeError
end.to raise_error RuntimeError
end
expect(stub).to have_been_requested
end
@ -215,10 +215,9 @@ describe '#get_application_default' do
FileUtils.mkdir_p(File.dirname(key_path))
File.write(key_path, cred_json_text)
ENV[@var_name] = key_path
blk = proc do
expect do
Google::Auth.get_application_default(@scope, options)
end
expect(&blk).to raise_error RuntimeError
end.to raise_error RuntimeError
end
end
@ -229,20 +228,18 @@ describe '#get_application_default' do
FileUtils.mkdir_p(File.dirname(key_path))
File.write(key_path, cred_json_text)
ENV['HOME'] = dir
blk = proc do
expect do
Google::Auth.get_application_default(@scope, options)
end
expect(&blk).to raise_error RuntimeError
end.to raise_error RuntimeError
end
end
it 'fails if env vars are set' do
ENV[PRIVATE_KEY_VAR] = cred_json[:private_key]
ENV[CLIENT_EMAIL_VAR] = cred_json[:client_email]
blk = proc do
expect do
Google::Auth.get_application_default(@scope, options)
end
expect(&blk).to raise_error RuntimeError
end.to raise_error RuntimeError
end
end
end

View File

@ -39,13 +39,15 @@ describe Google::Auth::ScopeUtil do
it 'normalizes the email scope' do
expect(normalized).to include(
'https://www.googleapis.com/auth/userinfo.email')
'https://www.googleapis.com/auth/userinfo.email'
)
expect(normalized).to_not include 'email'
end
it 'normalizes the profile scope' do
expect(normalized).to include(
'https://www.googleapis.com/auth/userinfo.profile')
'https://www.googleapis.com/auth/userinfo.profile'
)
expect(normalized).to_not include 'profile'
end

View File

@ -139,7 +139,8 @@ describe Google::Auth::ServiceAccountCredentials do
end
stub_request(:post, 'https://www.googleapis.com/oauth2/v3/token')
.with(body: hash_including(
'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer'),
'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer'
),
&blk)
.to_return(body: body,
status: 200,
@ -164,7 +165,8 @@ describe Google::Auth::ServiceAccountCredentials do
before(:example) do
@var_name = ENV_VAR
@credential_vars = [
ENV_VAR, PRIVATE_KEY_VAR, CLIENT_EMAIL_VAR, ACCOUNT_TYPE_VAR]
ENV_VAR, PRIVATE_KEY_VAR, CLIENT_EMAIL_VAR, ACCOUNT_TYPE_VAR
]
@original_env_vals = {}
@credential_vars.each { |var| @original_env_vals[var] = ENV[var] }
ENV[ACCOUNT_TYPE_VAR] = cred_json[:type]
@ -294,7 +296,8 @@ describe Google::Auth::ServiceAccountJwtHeaderCredentials do
before(:example) do
@var_name = ENV_VAR
@credential_vars = [
ENV_VAR, PRIVATE_KEY_VAR, CLIENT_EMAIL_VAR, ACCOUNT_TYPE_VAR]
ENV_VAR, PRIVATE_KEY_VAR, CLIENT_EMAIL_VAR, ACCOUNT_TYPE_VAR
]
@original_env_vals = {}
@credential_vars.each { |var| @original_env_vals[var] = ENV[var] }
ENV[ACCOUNT_TYPE_VAR] = cred_json[:type]

View File

@ -45,7 +45,8 @@ describe Signet::OAuth2::Client do
scope: 'https://www.googleapis.com/auth/userinfo.profile',
issuer: 'app@example.com',
audience: 'https://accounts.google.com/o/oauth2/token',
signing_key: @key)
signing_key: @key
)
end
def make_auth_stubs(opts)
@ -60,8 +61,8 @@ describe Signet::OAuth2::Client do
end
stub_request(:post, 'https://accounts.google.com/o/oauth2/token')
.with(body: hash_including(
'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer'),
&blk)
'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer'
), &blk)
.to_return(body: body,
status: 200,
headers: { 'Content-Type' => 'application/json' })

View File

@ -82,7 +82,8 @@ describe Google::Auth::UserAuthorizer do
it 'should include the callback uri' do
expect(URI(uri).query).to match(
%r{redirect_uri=https://www.example.com/oauth/callback})
%r{redirect_uri=https://www.example.com/oauth/callback}
)
end
it 'should include the scope' do
@ -139,7 +140,8 @@ describe Google::Auth::UserAuthorizer do
MultiJson.dump(
access_token: 'accesstoken',
refresh_token: 'refreshtoken',
expiration_time_millis: 1_441_234_742_000)
expiration_time_millis: 1_441_234_742_000
)
end
context 'with a valid user id' do
@ -150,7 +152,8 @@ describe Google::Auth::UserAuthorizer do
it 'should return an instance of UserRefreshCredentials' do
expect(credentials).to be_instance_of(
Google::Auth::UserRefreshCredentials)
Google::Auth::UserRefreshCredentials
)
end
it 'should return credentials with a valid refresh token' do
@ -226,7 +229,8 @@ describe Google::Auth::UserAuthorizer do
it 'should persist the expiry as milliseconds' do
expected_expiry = expiry * 1000
expect(MultiJson.load(token_json)['expiration_time_millis']).to eql(
expected_expiry)
expected_expiry
)
end
end
@ -240,12 +244,14 @@ describe Google::Auth::UserAuthorizer do
before(:example) do
stub_request(:post, 'https://www.googleapis.com/oauth2/v3/token')
.to_return(body: token_json, status: 200, headers: {
'Content-Type' => 'application/json' })
'Content-Type' => 'application/json'
})
end
it 'should exchange a code for credentials' do
credentials = authorizer.get_credentials_from_code(
user_id: 'user1', code: 'code')
user_id: 'user1', code: 'code'
)
expect(credentials.access_token).to eq '1/abc123'
end
@ -256,7 +262,8 @@ describe Google::Auth::UserAuthorizer do
it 'should store credentials when requested' do
authorizer.get_and_store_credentials_from_code(
user_id: 'user1', code: 'code')
user_id: 'user1', code: 'code'
)
expect(token_store.load('user1')).to_not be_nil
end
end
@ -286,20 +293,23 @@ describe Google::Auth::UserAuthorizer do
MultiJson.dump(
access_token: 'accesstoken',
refresh_token: 'refreshtoken',
expiration_time_millis: 1_441_234_742_000)
expiration_time_millis: 1_441_234_742_000
)
end
before(:example) do
token_store.store('user1', token_json)
stub_request(
:get, 'https://accounts.google.com/o/oauth2/revoke?token=refreshtoken')
:get, 'https://accounts.google.com/o/oauth2/revoke?token=refreshtoken'
)
.to_return(status: 200)
end
it 'should revoke the grant' do
authorizer.revoke_authorization('user1')
expect(a_request(
:get, 'https://accounts.google.com/o/oauth2/revoke?token=refreshtoken'))
:get, 'https://accounts.google.com/o/oauth2/revoke?token=refreshtoken'
))
.to have_been_made
end

View File

@ -87,7 +87,8 @@ describe Google::Auth::UserRefreshCredentials do
@var_name = ENV_VAR
@credential_vars = [
ENV_VAR, CLIENT_ID_VAR, CLIENT_SECRET_VAR, REFRESH_TOKEN_VAR,
ACCOUNT_TYPE_VAR]
ACCOUNT_TYPE_VAR
]
@original_env_vals = {}
@credential_vars.each { |var| @original_env_vals[var] = ENV[var] }
@scope = 'https://www.googleapis.com/auth/userinfo.profile'
@ -288,7 +289,8 @@ describe Google::Auth::UserRefreshCredentials do
it 'raises an authorization error' do
stub
expect { @client.revoke! }.to raise_error(
Signet::AuthorizationError)
Signet::AuthorizationError
)
end
end
end

View File

@ -52,13 +52,15 @@ describe Google::Auth::WebUserAuthorizer do
let(:env) do
Rack::MockRequest.env_for(
'http://example.com:8080/test',
'REMOTE_ADDR' => '10.10.10.10')
'REMOTE_ADDR' => '10.10.10.10'
)
end
let(:request) { Rack::Request.new(env) }
it 'should include current url in state' do
url = authorizer.get_authorization_url(request: request)
expect(url).to match(
%r{%22current_uri%22:%22http://example.com:8080/test%22})
%r{%22current_uri%22:%22http://example.com:8080/test%22}
)
end
it 'should include request forgery token in state' do
@ -76,20 +78,23 @@ describe Google::Auth::WebUserAuthorizer do
it 'should resolve callback against base URL' do
url = authorizer.get_authorization_url(request: request)
expect(url).to match(
%r{redirect_uri=http://example.com:8080/oauth2callback})
%r{redirect_uri=http://example.com:8080/oauth2callback}
)
end
it 'should allow overriding the current URL' do
url = authorizer.get_authorization_url(
request: request,
redirect_to: '/foo')
redirect_to: '/foo'
)
expect(url).to match %r{%22current_uri%22:%22/foo%22}
end
it 'should pass through login hint' do
url = authorizer.get_authorization_url(
request: request,
login_hint: 'user@example.com')
login_hint: 'user@example.com'
)
expect(url).to match(/login_hint=user@example.com/)
end
end
@ -113,7 +118,8 @@ describe Google::Auth::WebUserAuthorizer do
'http://example.com:8080/oauth2callback?code=authcode&'\
'state=%7B%22current_uri%22%3A%22%2Ffoo%22%2C%22'\
'session_id%22%3A%22abc%22%7D',
'REMOTE_ADDR' => '10.10.10.10')
'REMOTE_ADDR' => '10.10.10.10'
)
end
let(:request) { Rack::Request.new(env) }
@ -123,7 +129,8 @@ describe Google::Auth::WebUserAuthorizer do
it 'should return credentials when valid code present' do
expect(credentials).to be_instance_of(
Google::Auth::UserRefreshCredentials)
Google::Auth::UserRefreshCredentials
)
end
it 'should return next URL to redirect to' do