googleauth 0.6.2 → 0.6.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: cb647efa48b73b48d9bf0aec7c572f944f31de67
4
- data.tar.gz: 915dd9da0fc858a9f4b9dbdceaa64228218ff87c
2
+ SHA256:
3
+ metadata.gz: 1528ae25e5c678b4b8be00b85095ee5f95ca83fdbcca2c7629cc429d80565e1c
4
+ data.tar.gz: cbc4aef5eea0fab23d0b529c8af5d9a2aa297c107e38e9fa1d220682d0f6fa61
5
5
  SHA512:
6
- metadata.gz: b35a1ef32bc166af59bc0d0f491768957ff8f7d7a2d7cb303b375cd8f0fb90f6fda87d9fec4749850ce589393b94d69d181c8606d32c5b9cee04c8f8cae2744c
7
- data.tar.gz: bc366d1b2a2dc4f49c4eced0ab9c2358070a47c88c3be922e36b68149f69f0b87ab215c8e6fa07c9677b3292664958f131a8efc3d3a36ce0a93c1c9a651bbdd1
6
+ metadata.gz: 13caa772bb5c2ebf1565f18160b59132839d5cd76560764cc235d2390df7b032196c6402fcd075e8356404a69d7970011bfde9904a86c20861a4a5031b221c81
7
+ data.tar.gz: e25c85dd789d8267e6c5aa4e7cd3041b5ce4185b97157cbee0b92e98a5a66c7cbd2dcdae459493d5b5f74d81e415958c764ab0ac4c998281bdc04b103363354a
@@ -13,7 +13,7 @@ Metrics/MethodLength:
13
13
  Max: 20
14
14
  Metrics/ClassLength:
15
15
  Enabled: false
16
- Style/IndentHeredoc:
16
+ Layout/IndentHeredoc:
17
17
  Enabled: false
18
18
  Style/FormatString:
19
19
  Enabled: false
@@ -1,3 +1,11 @@
1
+ ## 0.6.3 (2018/08/02)
2
+
3
+ * Resolve issue where token_store was being written to twice
4
+
5
+ ## 0.6.2 (2018/08/01)
6
+
7
+ * Add warning when using cloud sdk credentials
8
+
1
9
  ## 0.6.1 (2017/10/18)
2
10
 
3
11
  * Fix file permissions
@@ -0,0 +1,43 @@
1
+ # Contributor Code of Conduct
2
+
3
+ As contributors and maintainers of this project,
4
+ and in the interest of fostering an open and welcoming community,
5
+ we pledge to respect all people who contribute through reporting issues,
6
+ posting feature requests, updating documentation,
7
+ submitting pull requests or patches, and other activities.
8
+
9
+ We are committed to making participation in this project
10
+ a harassment-free experience for everyone,
11
+ regardless of level of experience, gender, gender identity and expression,
12
+ sexual orientation, disability, personal appearance,
13
+ body size, race, ethnicity, age, religion, or nationality.
14
+
15
+ Examples of unacceptable behavior by participants include:
16
+
17
+ * The use of sexualized language or imagery
18
+ * Personal attacks
19
+ * Trolling or insulting/derogatory comments
20
+ * Public or private harassment
21
+ * Publishing other's private information,
22
+ such as physical or electronic
23
+ addresses, without explicit permission
24
+ * Other unethical or unprofessional conduct.
25
+
26
+ Project maintainers have the right and responsibility to remove, edit, or reject
27
+ comments, commits, code, wiki edits, issues, and other contributions
28
+ that are not aligned to this Code of Conduct.
29
+ By adopting this Code of Conduct,
30
+ project maintainers commit themselves to fairly and consistently
31
+ applying these principles to every aspect of managing this project.
32
+ Project maintainers who do not follow or enforce the Code of Conduct
33
+ may be permanently removed from the project team.
34
+
35
+ This code of conduct applies both within project spaces and in public spaces
36
+ when an individual is representing the project or its community.
37
+
38
+ Instances of abusive, harassing, or otherwise unacceptable behavior
39
+ may be reported by opening an issue
40
+ or contacting one or more of the project maintainers.
41
+
42
+ This Code of Conduct is adapted from the [Contributor Covenant](http://contributor-covenant.org), version 1.2.0,
43
+ available at [http://contributor-covenant.org/version/1/2/0/](http://contributor-covenant.org/version/1/2/0/)
data/Gemfile CHANGED
@@ -8,6 +8,7 @@ group :development do
8
8
  gem 'coveralls', '~> 0.7'
9
9
  gem 'fakefs', '~> 0.6'
10
10
  gem 'fakeredis', '~> 0.5'
11
+ gem 'logging', '~> 2.0'
11
12
  gem 'rack-test', '~> 0.6'
12
13
  gem 'rake', '~> 10.0'
13
14
  gem 'redis', '~> 3.2'
data/README.md CHANGED
@@ -143,6 +143,15 @@ authorizer = Google::Auth::ServiceAccountCredentials.make_creds(
143
143
  authorizer.fetch_access_token!
144
144
  ```
145
145
 
146
+ ### Example (Environment Variables)
147
+
148
+ ```bash
149
+ export GOOGLE_ACCOUNT_TYPE=service_account
150
+ export GOOGLE_CLIENT_ID=000000000000000000000
151
+ export GOOGLE_CLIENT_EMAIL=xxxx@xxxx.iam.gserviceaccount.com
152
+ export GOOGLE_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----\n"
153
+ ```
154
+
146
155
  ### Storage
147
156
 
148
157
  Authorizers require a storage instance to manage long term persistence of
@@ -27,10 +27,9 @@ Gem::Specification.new do |s|
27
27
  s.platform = Gem::Platform::RUBY
28
28
 
29
29
  s.add_dependency 'faraday', '~> 0.12'
30
- s.add_dependency 'logging', '~> 2.0'
31
30
  s.add_dependency 'jwt', '>= 1.4', '< 3.0'
32
31
  s.add_dependency 'memoist', '~> 0.12'
33
32
  s.add_dependency 'multi_json', '~> 1.11'
34
- s.add_dependency 'os', '~> 0.9'
33
+ s.add_dependency 'os', '>= 0.9', '< 2.0'
35
34
  s.add_dependency 'signet', '~> 0.7'
36
35
  end
@@ -58,7 +58,11 @@ ERROR_MESSAGE
58
58
  DefaultCredentials.from_well_known_path(scope) ||
59
59
  DefaultCredentials.from_system_default_path(scope)
60
60
  return creds unless creds.nil?
61
- raise NOT_FOUND_ERROR unless GCECredentials.on_gce?(options)
61
+ unless GCECredentials.on_gce?(options)
62
+ # Clear cache of the result of GCECredentials.on_gce?
63
+ GCECredentials.unmemoize_all
64
+ raise NOT_FOUND_ERROR
65
+ end
62
66
  GCECredentials.new
63
67
  end
64
68
 
@@ -28,6 +28,7 @@
28
28
  # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
29
 
30
30
  require 'multi_json'
31
+ require 'googleauth/credentials_loader'
31
32
 
32
33
  module Google
33
34
  module Auth
@@ -63,13 +64,14 @@ module Google
63
64
  # & secrets in source. See {#from_file} to load from
64
65
  # `client_secrets.json` files.
65
66
  def initialize(id, secret)
67
+ CredentialsLoader.warn_if_cloud_sdk_credentials id
66
68
  raise 'Client id can not be nil' if id.nil?
67
69
  raise 'Client secret can not be nil' if secret.nil?
68
70
  @id = id
69
71
  @secret = secret
70
72
  end
71
73
 
72
- # Constructs a Client ID from a JSON file downloaed from the
74
+ # Constructs a Client ID from a JSON file downloaded from the
73
75
  # Google Developers Console.
74
76
  #
75
77
  # @param [String, File] file
@@ -79,7 +81,7 @@ module Google
79
81
  raise 'File can not be nil.' if file.nil?
80
82
  File.open(file.to_s) do |f|
81
83
  json = f.read
82
- config = MultiJson.load(json)
84
+ config = MultiJson.load json
83
85
  from_hash(config)
84
86
  end
85
87
  end
@@ -31,15 +31,15 @@ require 'forwardable'
31
31
  require 'json'
32
32
  require 'signet/oauth_2/client'
33
33
 
34
- require 'googleauth/default_credentials'
34
+ require 'googleauth/credentials_loader'
35
35
 
36
36
  module Google
37
37
  module Auth
38
38
  # This class is intended to be inherited by API-specific classes
39
39
  # which overrides the SCOPE constant.
40
40
  class Credentials
41
- TOKEN_CREDENTIAL_URI = 'https://accounts.google.com/o/oauth2/token'.freeze
42
- AUDIENCE = 'https://accounts.google.com/o/oauth2/token'.freeze
41
+ TOKEN_CREDENTIAL_URI = 'https://oauth2.googleapis.com/token'.freeze
42
+ AUDIENCE = 'https://oauth2.googleapis.com/token'.freeze
43
43
  SCOPE = [].freeze
44
44
  PATH_ENV_VARS = [].freeze
45
45
  JSON_ENV_VARS = [].freeze
@@ -68,6 +68,7 @@ module Google
68
68
  json['scope'] ||= scope
69
69
  @client = init_client json
70
70
  end
71
+ CredentialsLoader.warn_if_cloud_sdk_credentials @client.client_id
71
72
  @client.fetch_access_token!
72
73
  end
73
74
 
@@ -78,16 +79,16 @@ module Google
78
79
  def self.default(options = {})
79
80
  scope = options[:scope]
80
81
  # First try to find keyfile file from environment variables.
81
- client = from_path_vars(scope)
82
+ client = from_path_vars scope
82
83
 
83
84
  # Second try to find keyfile json from environment variables.
84
- client ||= from_json_vars(scope)
85
+ client ||= from_json_vars scope
85
86
 
86
87
  # Third try to find keyfile file from known file paths.
87
- client ||= from_default_paths(scope)
88
+ client ||= from_default_paths scope
88
89
 
89
90
  # Finally get instantiated client from Google::Auth
90
- client ||= from_application_default(scope)
91
+ client ||= from_application_default scope
91
92
  client
92
93
  end
93
94
 
@@ -57,6 +57,17 @@ module Google
57
57
  SYSTEM_DEFAULT_ERROR =
58
58
  'Unable to read the system default credential file'.freeze
59
59
 
60
+ CLOUD_SDK_CLIENT_ID = '764086051850-6qr4p6gpi6hn506pt8ejuq83di341hur.app'\
61
+ 's.googleusercontent.com'.freeze
62
+
63
+ CLOUD_SDK_CREDENTIALS_WARNING = 'Your application has authenticated '\
64
+ 'using end user credentials from Google Cloud SDK. We recommend that '\
65
+ 'most server applications use service accounts instead. If your '\
66
+ 'application continues to use end user credentials from Cloud SDK, '\
67
+ 'you might receive a "quota exceeded" or "API not enabled" error. For'\
68
+ ' more information about service accounts, see '\
69
+ 'https://cloud.google.com/docs/authentication/.'.freeze
70
+
60
71
  # make_creds proxies the construction of a credentials instance
61
72
  #
62
73
  # By default, it calls #new on the current class, but this behaviour can
@@ -119,6 +130,12 @@ module Google
119
130
  raise "#{SYSTEM_DEFAULT_ERROR}: #{e}"
120
131
  end
121
132
 
133
+ # Issues warning if cloud sdk client id is used
134
+ def warn_if_cloud_sdk_credentials(client_id)
135
+ warn CLOUD_SDK_CREDENTIALS_WARNING if client_id == CLOUD_SDK_CLIENT_ID
136
+ end
137
+ module_function :warn_if_cloud_sdk_credentials
138
+
122
139
  private
123
140
 
124
141
  def service_account_env_vars?
@@ -49,9 +49,11 @@ module Google
49
49
  json_key_io, scope = options.values_at(:json_key_io, :scope)
50
50
  if json_key_io
51
51
  json_key, clz = determine_creds_class(json_key_io)
52
+ warn_if_cloud_sdk_credentials json_key['client_id']
52
53
  clz.make_creds(json_key_io: StringIO.new(MultiJson.dump(json_key)),
53
54
  scope: scope)
54
55
  else
56
+ warn_if_cloud_sdk_credentials ENV[CLIENT_ID_VAR]
55
57
  clz = read_creds
56
58
  clz.make_creds(scope: scope)
57
59
  end
@@ -73,7 +75,7 @@ module Google
73
75
 
74
76
  # Reads the input json and determines which creds class to use.
75
77
  def self.determine_creds_class(json_key_io)
76
- json_key = MultiJson.load(json_key_io.read)
78
+ json_key = MultiJson.load json_key_io.read
77
79
  key = 'type'
78
80
  raise "the json is missing the '#{key}' field" unless json_key.key?(key)
79
81
  type = json_key[key]
@@ -0,0 +1,45 @@
1
+ # Copyright 2015, Google Inc.
2
+ # All rights reserved.
3
+ #
4
+ # Redistribution and use in source and binary forms, with or without
5
+ # modification, are permitted provided that the following conditions are
6
+ # met:
7
+ #
8
+ # * Redistributions of source code must retain the above copyright
9
+ # notice, this list of conditions and the following disclaimer.
10
+ # * Redistributions in binary form must reproduce the above
11
+ # copyright notice, this list of conditions and the following disclaimer
12
+ # in the documentation and/or other materials provided with the
13
+ # distribution.
14
+ # * Neither the name of Google Inc. nor the names of its
15
+ # contributors may be used to endorse or promote products derived from
16
+ # this software without specific prior written permission.
17
+ #
18
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19
+ # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20
+ # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21
+ # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22
+ # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23
+ # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24
+ # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25
+ # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26
+ # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27
+ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28
+ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
+
30
+ module Google
31
+ # Module Auth provides classes that provide Google-specific authorization
32
+ # used to access Google APIs.
33
+ module Auth
34
+ # JsonKeyReader contains the behaviour used to read private key and
35
+ # client email fields from the service account
36
+ module JsonKeyReader
37
+ def read_json_key(json_key_io)
38
+ json_key = MultiJson.load(json_key_io.read)
39
+ raise 'missing client_email' unless json_key.key?('client_email')
40
+ raise 'missing private_key' unless json_key.key?('private_key')
41
+ [json_key['private_key'], json_key['client_email']]
42
+ end
43
+ end
44
+ end
45
+ end
@@ -29,6 +29,7 @@
29
29
 
30
30
  require 'googleauth/signet'
31
31
  require 'googleauth/credentials_loader'
32
+ require 'googleauth/json_key_reader'
32
33
  require 'jwt'
33
34
  require 'multi_json'
34
35
  require 'stringio'
@@ -48,6 +49,7 @@ module Google
48
49
  class ServiceAccountCredentials < Signet::OAuth2::Client
49
50
  TOKEN_CRED_URI = 'https://www.googleapis.com/oauth2/v4/token'.freeze
50
51
  extend CredentialsLoader
52
+ extend JsonKeyReader
51
53
 
52
54
  # Creates a ServiceAccountCredentials.
53
55
  #
@@ -58,7 +60,7 @@ module Google
58
60
  if json_key_io
59
61
  private_key, client_email = read_json_key(json_key_io)
60
62
  else
61
- private_key = ENV[CredentialsLoader::PRIVATE_KEY_VAR]
63
+ private_key = unescape ENV[CredentialsLoader::PRIVATE_KEY_VAR]
62
64
  client_email = ENV[CredentialsLoader::CLIENT_EMAIL_VAR]
63
65
  end
64
66
 
@@ -69,13 +71,13 @@ module Google
69
71
  signing_key: OpenSSL::PKey::RSA.new(private_key))
70
72
  end
71
73
 
72
- # Reads the private key and client email fields from the service account
73
- # JSON key.
74
- def self.read_json_key(json_key_io)
75
- json_key = MultiJson.load(json_key_io.read)
76
- raise 'missing client_email' unless json_key.key?('client_email')
77
- raise 'missing private_key' unless json_key.key?('private_key')
78
- [json_key['private_key'], json_key['client_email']]
74
+ # Handles certain escape sequences that sometimes appear in input.
75
+ # Specifically, interprets the "\n" sequence for newline, and removes
76
+ # enclosing quotes.
77
+ def self.unescape(str)
78
+ str = str.gsub '\n', "\n"
79
+ str = str[1..-2] if str.start_with?('"') && str.end_with?('"')
80
+ str
79
81
  end
80
82
 
81
83
  def initialize(options = {})
@@ -123,6 +125,7 @@ module Google
123
125
  SIGNING_ALGORITHM = 'RS256'.freeze
124
126
  EXPIRY = 60
125
127
  extend CredentialsLoader
128
+ extend JsonKeyReader
126
129
 
127
130
  # make_creds proxies the construction of a credentials instance
128
131
  #
@@ -135,15 +138,6 @@ module Google
135
138
  new(json_key_io: args[0][:json_key_io])
136
139
  end
137
140
 
138
- # Reads the private key and client email fields from the service account
139
- # JSON key.
140
- def self.read_json_key(json_key_io)
141
- json_key = MultiJson.load(json_key_io.read)
142
- raise 'missing client_email' unless json_key.key?('client_email')
143
- raise 'missing private_key' unless json_key.key?('private_key')
144
- [json_key['private_key'], json_key['client_email']]
145
- end
146
-
147
141
  # Initializes a ServiceAccountJwtHeaderCredentials.
148
142
  #
149
143
  # @param json_key_io [IO] an IO from which the JSON key can be read
@@ -198,7 +198,6 @@ module Google
198
198
  # Credentials if exchange is successful
199
199
  def get_and_store_credentials_from_code(options = {})
200
200
  credentials = get_credentials_from_code(options)
201
- monitor_credentials(options[:user_id], credentials)
202
201
  store_credentials(options[:user_id], credentials)
203
202
  end
204
203
 
@@ -46,9 +46,9 @@ module Google
46
46
  #
47
47
  # cf [Application Default Credentials](http://goo.gl/mkAHpZ)
48
48
  class UserRefreshCredentials < Signet::OAuth2::Client
49
- TOKEN_CRED_URI = 'https://www.googleapis.com/oauth2/v4/token'.freeze
49
+ TOKEN_CRED_URI = 'https://oauth2.googleapis.com/token'.freeze
50
50
  AUTHORIZATION_URI = 'https://accounts.google.com/o/oauth2/auth'.freeze
51
- REVOKE_TOKEN_URI = 'https://accounts.google.com/o/oauth2/revoke'.freeze
51
+ REVOKE_TOKEN_URI = 'https://oauth2.googleapis.com/revoke'.freeze
52
52
  extend CredentialsLoader
53
53
 
54
54
  # Create a UserRefreshCredentials.
@@ -31,6 +31,6 @@ module Google
31
31
  # Module Auth provides classes that provide Google-specific authorization
32
32
  # used to access Google APIs.
33
33
  module Auth
34
- VERSION = '0.6.2'.freeze
34
+ VERSION = '0.6.3'.freeze
35
35
  end
36
36
  end
@@ -48,7 +48,7 @@ describe Google::Auth::ClientId do
48
48
 
49
49
  shared_examples 'it can successfully load client_id' do
50
50
  context 'loaded from hash' do
51
- let(:client_id) { Google::Auth::ClientId.from_hash(config) }
51
+ let(:client_id) { Google::Auth::ClientId.from_hash config }
52
52
 
53
53
  it_behaves_like 'it has a valid config'
54
54
  end
@@ -103,7 +103,7 @@ describe Google::Auth::ClientId do
103
103
  end
104
104
 
105
105
  it 'should raise error' do
106
- expect { Google::Auth::ClientId.from_hash(config) }.to raise_error(
106
+ expect { Google::Auth::ClientId.from_hash config }.to raise_error(
107
107
  /Expected top level property/
108
108
  )
109
109
  end
@@ -119,7 +119,7 @@ describe Google::Auth::ClientId do
119
119
  end
120
120
 
121
121
  it 'should raise error' do
122
- expect { Google::Auth::ClientId.from_hash(config) }.to raise_error(
122
+ expect { Google::Auth::ClientId.from_hash config }.to raise_error(
123
123
  /Client id can not be nil/
124
124
  )
125
125
  end
@@ -135,9 +135,26 @@ describe Google::Auth::ClientId do
135
135
  end
136
136
 
137
137
  it 'should raise error' do
138
- expect { Google::Auth::ClientId.from_hash(config) }.to raise_error(
138
+ expect { Google::Auth::ClientId.from_hash config }.to raise_error(
139
139
  /Client secret can not be nil/
140
140
  )
141
141
  end
142
142
  end
143
+
144
+ context 'with cloud sdk credentials' do
145
+ let(:config) do
146
+ {
147
+ 'web' => {
148
+ 'client_id' => Google::Auth::CredentialsLoader::CLOUD_SDK_CLIENT_ID,
149
+ 'client_secret' => 'notasecret'
150
+ }
151
+ }
152
+ end
153
+
154
+ it 'should raise warning' do
155
+ expect { Google::Auth::ClientId.from_hash config }.to output(
156
+ Google::Auth::CredentialsLoader::CLOUD_SDK_CREDENTIALS_WARNING + "\n"
157
+ ).to_stderr
158
+ end
159
+ end
143
160
  end
@@ -29,6 +29,7 @@
29
29
 
30
30
  require 'googleauth'
31
31
 
32
+
32
33
  # This test is testing the private class Google::Auth::Credentials. We want to
33
34
  # make sure that the passed in scope propogates to the Signet object. This means
34
35
  # testing the private API, which is generally frowned on.
@@ -46,9 +47,10 @@ describe Google::Auth::Credentials, :private do
46
47
  it 'uses a default scope' do
47
48
  mocked_signet = double('Signet::OAuth2::Client')
48
49
  allow(mocked_signet).to receive(:fetch_access_token!).and_return(true)
50
+ allow(mocked_signet).to receive(:client_id)
49
51
  allow(Signet::OAuth2::Client).to receive(:new) do |options|
50
- expect(options[:token_credential_uri]).to eq('https://accounts.google.com/o/oauth2/token')
51
- expect(options[:audience]).to eq('https://accounts.google.com/o/oauth2/token')
52
+ expect(options[:token_credential_uri]).to eq('https://oauth2.googleapis.com/token')
53
+ expect(options[:audience]).to eq('https://oauth2.googleapis.com/token')
52
54
  expect(options[:scope]).to eq([])
53
55
  expect(options[:issuer]).to eq(default_keyfile_hash['client_email'])
54
56
  expect(options[:signing_key]).to be_a_kind_of(OpenSSL::PKey::RSA)
@@ -62,9 +64,10 @@ describe Google::Auth::Credentials, :private do
62
64
  it 'uses a custom scope' do
63
65
  mocked_signet = double('Signet::OAuth2::Client')
64
66
  allow(mocked_signet).to receive(:fetch_access_token!).and_return(true)
67
+ allow(mocked_signet).to receive(:client_id)
65
68
  allow(Signet::OAuth2::Client).to receive(:new) do |options|
66
- expect(options[:token_credential_uri]).to eq('https://accounts.google.com/o/oauth2/token')
67
- expect(options[:audience]).to eq('https://accounts.google.com/o/oauth2/token')
69
+ expect(options[:token_credential_uri]).to eq('https://oauth2.googleapis.com/token')
70
+ expect(options[:audience]).to eq('https://oauth2.googleapis.com/token')
68
71
  expect(options[:scope]).to eq(['http://example.com/scope'])
69
72
  expect(options[:issuer]).to eq(default_keyfile_hash['client_email'])
70
73
  expect(options[:signing_key]).to be_a_kind_of(OpenSSL::PKey::RSA)
@@ -93,9 +96,10 @@ describe Google::Auth::Credentials, :private do
93
96
 
94
97
  mocked_signet = double('Signet::OAuth2::Client')
95
98
  allow(mocked_signet).to receive(:fetch_access_token!).and_return(true)
99
+ allow(mocked_signet).to receive(:client_id)
96
100
  allow(Signet::OAuth2::Client).to receive(:new) do |options|
97
- expect(options[:token_credential_uri]).to eq('https://accounts.google.com/o/oauth2/token')
98
- expect(options[:audience]).to eq('https://accounts.google.com/o/oauth2/token')
101
+ expect(options[:token_credential_uri]).to eq('https://oauth2.googleapis.com/token')
102
+ expect(options[:audience]).to eq('https://oauth2.googleapis.com/token')
99
103
  expect(options[:scope]).to eq(['http://example.com/scope'])
100
104
  expect(options[:issuer]).to eq(default_keyfile_hash['client_email'])
101
105
  expect(options[:signing_key]).to be_a_kind_of(OpenSSL::PKey::RSA)
@@ -124,9 +128,10 @@ describe Google::Auth::Credentials, :private do
124
128
 
125
129
  mocked_signet = double('Signet::OAuth2::Client')
126
130
  allow(mocked_signet).to receive(:fetch_access_token!).and_return(true)
131
+ allow(mocked_signet).to receive(:client_id)
127
132
  allow(Signet::OAuth2::Client).to receive(:new) do |options|
128
- expect(options[:token_credential_uri]).to eq('https://accounts.google.com/o/oauth2/token')
129
- expect(options[:audience]).to eq('https://accounts.google.com/o/oauth2/token')
133
+ expect(options[:token_credential_uri]).to eq('https://oauth2.googleapis.com/token')
134
+ expect(options[:audience]).to eq('https://oauth2.googleapis.com/token')
130
135
  expect(options[:scope]).to eq(['http://example.com/scope'])
131
136
  expect(options[:issuer]).to eq(default_keyfile_hash['client_email'])
132
137
  expect(options[:signing_key]).to be_a_kind_of(OpenSSL::PKey::RSA)
@@ -154,9 +159,10 @@ describe Google::Auth::Credentials, :private do
154
159
 
155
160
  mocked_signet = double('Signet::OAuth2::Client')
156
161
  allow(mocked_signet).to receive(:fetch_access_token!).and_return(true)
162
+ allow(mocked_signet).to receive(:client_id)
157
163
  allow(Signet::OAuth2::Client).to receive(:new) do |options|
158
- expect(options[:token_credential_uri]).to eq('https://accounts.google.com/o/oauth2/token')
159
- expect(options[:audience]).to eq('https://accounts.google.com/o/oauth2/token')
164
+ expect(options[:token_credential_uri]).to eq('https://oauth2.googleapis.com/token')
165
+ expect(options[:audience]).to eq('https://oauth2.googleapis.com/token')
160
166
  expect(options[:scope]).to eq(['http://example.com/scope'])
161
167
  expect(options[:issuer]).to eq(default_keyfile_hash['client_email'])
162
168
  expect(options[:signing_key]).to be_a_kind_of(OpenSSL::PKey::RSA)
@@ -185,9 +191,10 @@ describe Google::Auth::Credentials, :private do
185
191
 
186
192
  mocked_signet = double('Signet::OAuth2::Client')
187
193
  allow(mocked_signet).to receive(:fetch_access_token!).and_return(true)
194
+ allow(mocked_signet).to receive(:client_id)
188
195
  allow(Signet::OAuth2::Client).to receive(:new) do |options|
189
- expect(options[:token_credential_uri]).to eq('https://accounts.google.com/o/oauth2/token')
190
- expect(options[:audience]).to eq('https://accounts.google.com/o/oauth2/token')
196
+ expect(options[:token_credential_uri]).to eq('https://oauth2.googleapis.com/token')
197
+ expect(options[:audience]).to eq('https://oauth2.googleapis.com/token')
191
198
  expect(options[:scope]).to eq(['http://example.com/scope'])
192
199
  expect(options[:issuer]).to eq(default_keyfile_hash['client_email'])
193
200
  expect(options[:signing_key]).to be_a_kind_of(OpenSSL::PKey::RSA)
@@ -215,6 +222,7 @@ describe Google::Auth::Credentials, :private do
215
222
 
216
223
  mocked_signet = double('Signet::OAuth2::Client')
217
224
  allow(mocked_signet).to receive(:fetch_access_token!).and_return(true)
225
+ allow(mocked_signet).to receive(:client_id)
218
226
  allow(Google::Auth).to receive(:get_application_default) do |scope|
219
227
  expect(scope).to eq(TestCredentials::SCOPE)
220
228
 
@@ -223,8 +231,8 @@ describe Google::Auth::Credentials, :private do
223
231
  default_keyfile_hash
224
232
  end
225
233
  allow(Signet::OAuth2::Client).to receive(:new) do |options|
226
- expect(options[:token_credential_uri]).to eq('https://accounts.google.com/o/oauth2/token')
227
- expect(options[:audience]).to eq('https://accounts.google.com/o/oauth2/token')
234
+ expect(options[:token_credential_uri]).to eq('https://oauth2.googleapis.com/token')
235
+ expect(options[:audience]).to eq('https://oauth2.googleapis.com/token')
228
236
  expect(options[:scope]).to eq(['http://example.com/scope'])
229
237
  expect(options[:issuer]).to eq(default_keyfile_hash['client_email'])
230
238
  expect(options[:signing_key]).to be_a_kind_of(OpenSSL::PKey::RSA)
@@ -236,4 +244,16 @@ describe Google::Auth::Credentials, :private do
236
244
  expect(creds).to be_a_kind_of(TestCredentials)
237
245
  expect(creds.client).to eq(mocked_signet)
238
246
  end
247
+
248
+ it 'warns when cloud sdk credentials are used' do
249
+ mocked_signet = double('Signet::OAuth2::Client')
250
+ allow(mocked_signet).to receive(:fetch_access_token!).and_return(true)
251
+ allow(Signet::OAuth2::Client).to receive(:new) do |options|
252
+ mocked_signet
253
+ end
254
+ allow(mocked_signet).to receive(:client_id).and_return(Google::Auth::CredentialsLoader::CLOUD_SDK_CLIENT_ID)
255
+ expect { Google::Auth::Credentials.new default_keyfile_hash }.to output(
256
+ Google::Auth::CredentialsLoader::CLOUD_SDK_CREDENTIALS_WARNING + "\n"
257
+ ).to_stderr
258
+ end
239
259
  end
@@ -63,7 +63,7 @@ describe '#get_application_default' do
63
63
  Dir.mktmpdir do |dir|
64
64
  key_path = File.join(dir, 'does-not-exist')
65
65
  ENV[@var_name] = key_path
66
- expect { Google::Auth.get_application_default(@scope, options) }
66
+ expect { Google::Auth.get_application_default @scope, options }
67
67
  .to raise_error RuntimeError
68
68
  end
69
69
  end
@@ -76,7 +76,7 @@ describe '#get_application_default' do
76
76
  ENV.delete(@var_name) unless ENV[@var_name].nil? # no env var
77
77
  ENV['HOME'] = dir # no config present in this tmp dir
78
78
  expect do
79
- Google::Auth.get_application_default(@scope, options)
79
+ Google::Auth.get_application_default @scope, options
80
80
  end.to raise_error RuntimeError
81
81
  end
82
82
  expect(stub).to have_been_requested
@@ -90,7 +90,7 @@ describe '#get_application_default' do
90
90
  FileUtils.mkdir_p(File.dirname(key_path))
91
91
  File.write(key_path, cred_json_text)
92
92
  ENV[@var_name] = key_path
93
- expect(Google::Auth.get_application_default(@scope, options))
93
+ expect(Google::Auth.get_application_default @scope, options)
94
94
  .to_not be_nil
95
95
  end
96
96
  end
@@ -102,7 +102,7 @@ describe '#get_application_default' do
102
102
  FileUtils.mkdir_p(File.dirname(key_path))
103
103
  File.write(key_path, cred_json_text)
104
104
  ENV['HOME'] = dir
105
- expect(Google::Auth.get_application_default(@scope, options))
105
+ expect(Google::Auth.get_application_default @scope, options)
106
106
  .to_not be_nil
107
107
  end
108
108
  end
@@ -114,7 +114,7 @@ describe '#get_application_default' do
114
114
  FileUtils.mkdir_p(File.dirname(key_path))
115
115
  File.write(key_path, cred_json_text)
116
116
  ENV['HOME'] = dir
117
- expect(Google::Auth.get_application_default(nil, options)).to_not be_nil
117
+ expect(Google::Auth.get_application_default nil, options).to_not be_nil
118
118
  end
119
119
  end
120
120
 
@@ -125,7 +125,7 @@ describe '#get_application_default' do
125
125
  Dir.mktmpdir do |dir|
126
126
  ENV.delete(@var_name) unless ENV[@var_name].nil? # no env var
127
127
  ENV['HOME'] = dir # no config present in this tmp dir
128
- creds = Google::Auth.get_application_default(@scope, options)
128
+ creds = Google::Auth.get_application_default @scope, options
129
129
  expect(creds).to_not be_nil
130
130
  end
131
131
  expect(stub).to have_been_requested
@@ -137,7 +137,7 @@ describe '#get_application_default' do
137
137
  key_path = File.join('/etc/google/auth/', CREDENTIALS_FILE_NAME)
138
138
  FileUtils.mkdir_p(File.dirname(key_path))
139
139
  File.write(key_path, cred_json_text)
140
- expect(Google::Auth.get_application_default(@scope, options))
140
+ expect(Google::Auth.get_application_default @scope, options)
141
141
  .to_not be_nil
142
142
  File.delete(key_path)
143
143
  end
@@ -151,9 +151,22 @@ describe '#get_application_default' do
151
151
  ENV[CLIENT_SECRET_VAR] = cred_json[:client_secret]
152
152
  ENV[REFRESH_TOKEN_VAR] = cred_json[:refresh_token]
153
153
  ENV[ACCOUNT_TYPE_VAR] = cred_json[:type]
154
- expect(Google::Auth.get_application_default(@scope, options))
154
+ expect(Google::Auth.get_application_default @scope, options)
155
155
  .to_not be_nil
156
156
  end
157
+
158
+ it 'warns when using cloud sdk credentials' do
159
+ ENV.delete(@var_name) unless ENV[@var_name].nil? # no env var
160
+ ENV[PRIVATE_KEY_VAR] = cred_json[:private_key]
161
+ ENV[CLIENT_EMAIL_VAR] = cred_json[:client_email]
162
+ ENV[CLIENT_ID_VAR] = Google::Auth::CredentialsLoader::CLOUD_SDK_CLIENT_ID
163
+ ENV[CLIENT_SECRET_VAR] = cred_json[:client_secret]
164
+ ENV[REFRESH_TOKEN_VAR] = cred_json[:refresh_token]
165
+ ENV[ACCOUNT_TYPE_VAR] = cred_json[:type]
166
+ expect { Google::Auth.get_application_default @scope, options }.to output(
167
+ Google::Auth::CredentialsLoader::CLOUD_SDK_CREDENTIALS_WARNING + "\n"
168
+ ).to_stderr
169
+ end
157
170
  end
158
171
 
159
172
  describe 'when credential type is service account' do
@@ -216,7 +229,7 @@ describe '#get_application_default' do
216
229
  File.write(key_path, cred_json_text)
217
230
  ENV[@var_name] = key_path
218
231
  expect do
219
- Google::Auth.get_application_default(@scope, options)
232
+ Google::Auth.get_application_default @scope, options
220
233
  end.to raise_error RuntimeError
221
234
  end
222
235
  end
@@ -229,7 +242,7 @@ describe '#get_application_default' do
229
242
  File.write(key_path, cred_json_text)
230
243
  ENV['HOME'] = dir
231
244
  expect do
232
- Google::Auth.get_application_default(@scope, options)
245
+ Google::Auth.get_application_default @scope, options
233
246
  end.to raise_error RuntimeError
234
247
  end
235
248
  end
@@ -238,7 +251,7 @@ describe '#get_application_default' do
238
251
  ENV[PRIVATE_KEY_VAR] = cred_json[:private_key]
239
252
  ENV[CLIENT_EMAIL_VAR] = cred_json[:client_email]
240
253
  expect do
241
- Google::Auth.get_application_default(@scope, options)
254
+ Google::Auth.get_application_default @scope, options
242
255
  end.to raise_error RuntimeError
243
256
  end
244
257
  end
@@ -211,6 +211,13 @@ describe Google::Auth::ServiceAccountCredentials do
211
211
  ENV[CLIENT_EMAIL_VAR] = cred_json[:client_email]
212
212
  expect(@clz.from_env(@scope)).to_not be_nil
213
213
  end
214
+
215
+ it 'succeeds when GOOGLE_PRIVATE_KEY is escaped' do
216
+ escaped_key = cred_json[:private_key].gsub "\n", '\n'
217
+ ENV[PRIVATE_KEY_VAR] = "\"#{escaped_key}\""
218
+ ENV[CLIENT_EMAIL_VAR] = cred_json[:client_email]
219
+ expect(@clz.from_env(@scope)).to_not be_nil
220
+ end
214
221
  end
215
222
 
216
223
  describe '#from_well_known_path' do
@@ -41,10 +41,10 @@ describe Signet::OAuth2::Client do
41
41
  before(:example) do
42
42
  @key = OpenSSL::PKey::RSA.new(2048)
43
43
  @client = Signet::OAuth2::Client.new(
44
- token_credential_uri: 'https://accounts.google.com/o/oauth2/token',
44
+ token_credential_uri: 'https://oauth2.googleapis.com/token',
45
45
  scope: 'https://www.googleapis.com/auth/userinfo.profile',
46
46
  issuer: 'app@example.com',
47
- audience: 'https://accounts.google.com/o/oauth2/token',
47
+ audience: 'https://oauth2.googleapis.com/token',
48
48
  signing_key: @key
49
49
  )
50
50
  end
@@ -60,7 +60,7 @@ describe Signet::OAuth2::Client do
60
60
  @key.public_key, true,
61
61
  algorithm: 'RS256')
62
62
  end
63
- stub_request(:post, 'https://accounts.google.com/o/oauth2/token')
63
+ stub_request(:post, 'https://oauth2.googleapis.com/token')
64
64
  .with(body: hash_including(
65
65
  'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer'
66
66
  ), &blk)
@@ -242,7 +242,7 @@ describe Google::Auth::UserAuthorizer do
242
242
  end
243
243
 
244
244
  before(:example) do
245
- stub_request(:post, 'https://www.googleapis.com/oauth2/v4/token')
245
+ stub_request(:post, 'https://oauth2.googleapis.com/token')
246
246
  .to_return(body: token_json, status: 200, headers: {
247
247
  'Content-Type' => 'application/json'
248
248
  })
@@ -270,7 +270,7 @@ describe Google::Auth::UserAuthorizer do
270
270
 
271
271
  context 'with invalid authorization code' do
272
272
  before(:example) do
273
- stub_request(:post, 'https://www.googleapis.com/oauth2/v4/token')
273
+ stub_request(:post, 'https://oauth2.googleapis.com/token')
274
274
  .to_return(status: 400)
275
275
  end
276
276
 
@@ -300,7 +300,7 @@ describe Google::Auth::UserAuthorizer do
300
300
  before(:example) do
301
301
  token_store.store('user1', token_json)
302
302
  stub_request(
303
- :get, 'https://accounts.google.com/o/oauth2/revoke?token=refreshtoken'
303
+ :get, 'https://oauth2.googleapis.com/revoke?token=refreshtoken'
304
304
  )
305
305
  .to_return(status: 200)
306
306
  end
@@ -308,7 +308,7 @@ describe Google::Auth::UserAuthorizer do
308
308
  it 'should revoke the grant' do
309
309
  authorizer.revoke_authorization('user1')
310
310
  expect(a_request(
311
- :get, 'https://accounts.google.com/o/oauth2/revoke?token=refreshtoken'
311
+ :get, 'https://oauth2.googleapis.com/revoke?token=refreshtoken'
312
312
  ))
313
313
  .to have_been_made
314
314
  end
@@ -68,7 +68,7 @@ describe Google::Auth::UserRefreshCredentials do
68
68
  body = MultiJson.dump('access_token' => access_token,
69
69
  'token_type' => 'Bearer',
70
70
  'expires_in' => 3600)
71
- stub_request(:post, 'https://www.googleapis.com/oauth2/v4/token')
71
+ stub_request(:post, 'https://oauth2.googleapis.com/token')
72
72
  .with(body: hash_including('grant_type' => 'refresh_token'))
73
73
  .to_return(body: body,
74
74
  status: 200,
@@ -246,7 +246,7 @@ describe Google::Auth::UserRefreshCredentials do
246
246
 
247
247
  describe 'when revoking a refresh token' do
248
248
  let(:stub) do
249
- stub_request(:get, 'https://accounts.google.com/o/oauth2/revoke' \
249
+ stub_request(:get, 'https://oauth2.googleapis.com/revoke' \
250
250
  '?token=refreshtoken')
251
251
  .to_return(status: 200,
252
252
  headers: { 'Content-Type' => 'application/json' })
@@ -262,7 +262,7 @@ describe Google::Auth::UserRefreshCredentials do
262
262
 
263
263
  describe 'when revoking an access token' do
264
264
  let(:stub) do
265
- stub_request(:get, 'https://accounts.google.com/o/oauth2/revoke' \
265
+ stub_request(:get, 'https://oauth2.googleapis.com/revoke' \
266
266
  '?token=accesstoken')
267
267
  .to_return(status: 200,
268
268
  headers: { 'Content-Type' => 'application/json' })
@@ -280,7 +280,7 @@ describe Google::Auth::UserRefreshCredentials do
280
280
 
281
281
  describe 'when revoking an invalid token' do
282
282
  let(:stub) do
283
- stub_request(:get, 'https://accounts.google.com/o/oauth2/revoke' \
283
+ stub_request(:get, 'https://oauth2.googleapis.com/revoke' \
284
284
  '?token=refreshtoken')
285
285
  .to_return(status: 400,
286
286
  headers: { 'Content-Type' => 'application/json' })
@@ -294,7 +294,7 @@ describe Google::Auth::UserRefreshCredentials do
294
294
  end
295
295
  end
296
296
 
297
- describe 'when erros occurred with request' do
297
+ describe 'when errors occurred with request' do
298
298
  it 'should fail with Signet::AuthorizationError if request times out' do
299
299
  allow_any_instance_of(Faraday::Connection).to receive(:get)
300
300
  .and_raise(Faraday::TimeoutError)
@@ -107,7 +107,7 @@ describe Google::Auth::WebUserAuthorizer do
107
107
  end
108
108
 
109
109
  before(:example) do
110
- stub_request(:post, 'https://www.googleapis.com/oauth2/v4/token')
110
+ stub_request(:post, 'https://oauth2.googleapis.com/token')
111
111
  .to_return(body: token_json,
112
112
  status: 200,
113
113
  headers: { 'Content-Type' => 'application/json' })
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: googleauth
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.2
4
+ version: 0.6.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tim Emiola
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-11-10 00:00:00.000000000 Z
11
+ date: 2018-08-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday
@@ -24,20 +24,6 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0.12'
27
- - !ruby/object:Gem::Dependency
28
- name: logging
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - "~>"
32
- - !ruby/object:Gem::Version
33
- version: '2.0'
34
- type: :runtime
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - "~>"
39
- - !ruby/object:Gem::Version
40
- version: '2.0'
41
27
  - !ruby/object:Gem::Dependency
42
28
  name: jwt
43
29
  requirement: !ruby/object:Gem::Requirement
@@ -90,16 +76,22 @@ dependencies:
90
76
  name: os
91
77
  requirement: !ruby/object:Gem::Requirement
92
78
  requirements:
93
- - - "~>"
79
+ - - ">="
94
80
  - !ruby/object:Gem::Version
95
81
  version: '0.9'
82
+ - - "<"
83
+ - !ruby/object:Gem::Version
84
+ version: '2.0'
96
85
  type: :runtime
97
86
  prerelease: false
98
87
  version_requirements: !ruby/object:Gem::Requirement
99
88
  requirements:
100
- - - "~>"
89
+ - - ">="
101
90
  - !ruby/object:Gem::Version
102
91
  version: '0.9'
92
+ - - "<"
93
+ - !ruby/object:Gem::Version
94
+ version: '2.0'
103
95
  - !ruby/object:Gem::Dependency
104
96
  name: signet
105
97
  requirement: !ruby/object:Gem::Requirement
@@ -128,6 +120,7 @@ files:
128
120
  - ".rubocop.yml"
129
121
  - ".travis.yml"
130
122
  - CHANGELOG.md
123
+ - CODE_OF_CONDUCT.md
131
124
  - CONTRIBUTING.md
132
125
  - COPYING
133
126
  - Gemfile
@@ -142,6 +135,7 @@ files:
142
135
  - lib/googleauth/credentials_loader.rb
143
136
  - lib/googleauth/default_credentials.rb
144
137
  - lib/googleauth/iam.rb
138
+ - lib/googleauth/json_key_reader.rb
145
139
  - lib/googleauth/scope_util.rb
146
140
  - lib/googleauth/service_account.rb
147
141
  - lib/googleauth/signet.rb
@@ -188,7 +182,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
188
182
  version: '0'
189
183
  requirements: []
190
184
  rubyforge_project:
191
- rubygems_version: 2.4.8
185
+ rubygems_version: 2.7.6
192
186
  signing_key:
193
187
  specification_version: 4
194
188
  summary: Google Auth Library for Ruby