googleauth 0.5.1 → 0.11.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (69) hide show
  1. checksums.yaml +5 -5
  2. data/{CONTRIBUTING.md → .github/CONTRIBUTING.md} +5 -4
  3. data/.github/ISSUE_TEMPLATE/bug_report.md +36 -0
  4. data/.github/ISSUE_TEMPLATE/feature_request.md +21 -0
  5. data/.github/ISSUE_TEMPLATE/support_request.md +7 -0
  6. data/.kokoro/build.bat +16 -0
  7. data/.kokoro/build.sh +4 -0
  8. data/.kokoro/continuous/common.cfg +24 -0
  9. data/.kokoro/continuous/linux.cfg +25 -0
  10. data/.kokoro/continuous/osx.cfg +8 -0
  11. data/.kokoro/continuous/post.cfg +30 -0
  12. data/.kokoro/continuous/windows.cfg +29 -0
  13. data/.kokoro/osx.sh +4 -0
  14. data/.kokoro/presubmit/common.cfg +24 -0
  15. data/.kokoro/presubmit/linux.cfg +24 -0
  16. data/.kokoro/presubmit/osx.cfg +8 -0
  17. data/.kokoro/presubmit/windows.cfg +29 -0
  18. data/.kokoro/release.cfg +94 -0
  19. data/.kokoro/trampoline.bat +10 -0
  20. data/.kokoro/trampoline.sh +4 -0
  21. data/.repo-metadata.json +5 -0
  22. data/.rubocop.yml +17 -1
  23. data/CHANGELOG.md +90 -19
  24. data/CODE_OF_CONDUCT.md +43 -0
  25. data/Gemfile +16 -13
  26. data/README.md +58 -18
  27. data/Rakefile +106 -10
  28. data/googleauth.gemspec +27 -25
  29. data/lib/googleauth/application_default.rb +81 -0
  30. data/lib/googleauth/client_id.rb +21 -19
  31. data/lib/googleauth/compute_engine.rb +40 -43
  32. data/lib/googleauth/credentials.rb +375 -0
  33. data/lib/googleauth/credentials_loader.rb +117 -43
  34. data/lib/googleauth/default_credentials.rb +93 -0
  35. data/lib/googleauth/iam.rb +11 -11
  36. data/lib/googleauth/json_key_reader.rb +46 -0
  37. data/lib/googleauth/scope_util.rb +12 -12
  38. data/lib/googleauth/service_account.rb +64 -62
  39. data/lib/googleauth/signet.rb +53 -12
  40. data/lib/googleauth/stores/file_token_store.rb +8 -8
  41. data/lib/googleauth/stores/redis_token_store.rb +22 -22
  42. data/lib/googleauth/token_store.rb +6 -6
  43. data/lib/googleauth/user_authorizer.rb +80 -68
  44. data/lib/googleauth/user_refresh.rb +44 -35
  45. data/lib/googleauth/version.rb +1 -1
  46. data/lib/googleauth/web_user_authorizer.rb +77 -68
  47. data/lib/googleauth.rb +6 -96
  48. data/rakelib/devsite_builder.rb +45 -0
  49. data/rakelib/link_checker.rb +64 -0
  50. data/rakelib/repo_metadata.rb +59 -0
  51. data/spec/googleauth/apply_auth_examples.rb +47 -46
  52. data/spec/googleauth/client_id_spec.rb +75 -55
  53. data/spec/googleauth/compute_engine_spec.rb +60 -43
  54. data/spec/googleauth/credentials_spec.rb +467 -0
  55. data/spec/googleauth/get_application_default_spec.rb +149 -111
  56. data/spec/googleauth/iam_spec.rb +25 -25
  57. data/spec/googleauth/scope_util_spec.rb +26 -24
  58. data/spec/googleauth/service_account_spec.rb +261 -143
  59. data/spec/googleauth/signet_spec.rb +93 -30
  60. data/spec/googleauth/stores/file_token_store_spec.rb +12 -13
  61. data/spec/googleauth/stores/redis_token_store_spec.rb +11 -11
  62. data/spec/googleauth/stores/store_examples.rb +16 -16
  63. data/spec/googleauth/user_authorizer_spec.rb +153 -124
  64. data/spec/googleauth/user_refresh_spec.rb +186 -121
  65. data/spec/googleauth/web_user_authorizer_spec.rb +82 -69
  66. data/spec/spec_helper.rb +21 -19
  67. metadata +75 -32
  68. data/.rubocop_todo.yml +0 -32
  69. data/.travis.yml +0 -37
data/lib/googleauth.rb CHANGED
@@ -27,99 +27,9 @@
27
27
  # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28
28
  # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
29
 
30
- require 'multi_json'
31
- require 'stringio'
32
-
33
- require 'googleauth/credentials_loader'
34
- require 'googleauth/compute_engine'
35
- require 'googleauth/service_account'
36
- require 'googleauth/user_refresh'
37
- require 'googleauth/client_id'
38
- require 'googleauth/user_authorizer'
39
- require 'googleauth/web_user_authorizer'
40
-
41
- module Google
42
- # Module Auth provides classes that provide Google-specific authorization
43
- # used to access Google APIs.
44
- module Auth
45
- NOT_FOUND_ERROR = <<END
46
- Could not load the default credentials. Browse to
47
- https://developers.google.com/accounts/docs/application-default-credentials
48
- for more information
49
- END
50
-
51
- # DefaultCredentials is used to preload the credentials file, to determine
52
- # which type of credentials should be loaded.
53
- class DefaultCredentials
54
- extend CredentialsLoader
55
-
56
- # override CredentialsLoader#make_creds to use the class determined by
57
- # loading the json.
58
- def self.make_creds(options = {})
59
- json_key_io, scope = options.values_at(:json_key_io, :scope)
60
- if json_key_io
61
- json_key, clz = determine_creds_class(json_key_io)
62
- clz.make_creds(json_key_io: StringIO.new(MultiJson.dump(json_key)),
63
- scope: scope)
64
- else
65
- clz = read_creds
66
- clz.make_creds(scope: scope)
67
- end
68
- end
69
-
70
- def self.read_creds
71
- env_var = CredentialsLoader::ACCOUNT_TYPE_VAR
72
- type = ENV[env_var]
73
- fail "#{ACCOUNT_TYPE_VAR} is undefined in env" unless type
74
- case type
75
- when 'service_account'
76
- ServiceAccountCredentials
77
- when 'authorized_user'
78
- UserRefreshCredentials
79
- else
80
- fail "credentials type '#{type}' is not supported"
81
- end
82
- end
83
-
84
- # Reads the input json and determines which creds class to use.
85
- def self.determine_creds_class(json_key_io)
86
- json_key = MultiJson.load(json_key_io.read)
87
- key = 'type'
88
- fail "the json is missing the '#{key}' field" unless json_key.key?(key)
89
- type = json_key[key]
90
- case type
91
- when 'service_account'
92
- [json_key, ServiceAccountCredentials]
93
- when 'authorized_user'
94
- [json_key, UserRefreshCredentials]
95
- else
96
- fail "credentials type '#{type}' is not supported"
97
- end
98
- end
99
- end
100
-
101
- # Obtains the default credentials implementation to use in this
102
- # environment.
103
- #
104
- # Use this to obtain the Application Default Credentials for accessing
105
- # Google APIs. Application Default Credentials are described in detail
106
- # at http://goo.gl/IUuyuX.
107
- #
108
- # If supplied, scope is used to create the credentials instance, when it can
109
- # be applied. E.g, on google compute engine and for user credentials the
110
- # scope is ignored.
111
- #
112
- # @param scope [string|array|nil] the scope(s) to access
113
- # @param options [hash] allows override of the connection being used
114
- def get_application_default(scope = nil, options = {})
115
- creds = DefaultCredentials.from_env(scope) ||
116
- DefaultCredentials.from_well_known_path(scope) ||
117
- DefaultCredentials.from_system_default_path(scope)
118
- return creds unless creds.nil?
119
- fail NOT_FOUND_ERROR unless GCECredentials.on_gce?(options)
120
- GCECredentials.new
121
- end
122
-
123
- module_function :get_application_default
124
- end
125
- end
30
+ require "googleauth/application_default"
31
+ require "googleauth/client_id"
32
+ require "googleauth/credentials"
33
+ require "googleauth/default_credentials"
34
+ require "googleauth/user_authorizer"
35
+ require "googleauth/web_user_authorizer"
@@ -0,0 +1,45 @@
1
+ require "pathname"
2
+
3
+ require_relative "repo_metadata.rb"
4
+
5
+ class DevsiteBuilder
6
+ def initialize master_dir = "."
7
+ @master_dir = Pathname.new master_dir
8
+ @output_dir = "doc"
9
+ @metadata = RepoMetadata.from_source "#{master_dir}/.repo-metadata.json"
10
+ end
11
+
12
+ def build
13
+ FileUtils.remove_dir @output_dir if Dir.exist? @output_dir
14
+ markup = "--markup markdown"
15
+
16
+ Dir.chdir @master_dir do
17
+ cmds = ["-o #{@output_dir}", markup]
18
+ cmd "yard --verbose #{cmds.join ' '}"
19
+ end
20
+ @metadata.build @master_dir + @output_dir
21
+ end
22
+
23
+ def upload
24
+ Dir.chdir @output_dir do
25
+ opts = [
26
+ "--credentials=#{ENV['KOKORO_KEYSTORE_DIR']}/73713_docuploader_service_account",
27
+ "--staging-bucket=#{ENV.fetch 'STAGING_BUCKET', 'docs-staging'}",
28
+ "--metadata-file=./docs.metadata"
29
+ ]
30
+ cmd "python3 -m docuploader upload . #{opts.join ' '}"
31
+ end
32
+ end
33
+
34
+ def publish
35
+ build
36
+ upload
37
+ end
38
+
39
+ def cmd line
40
+ puts line
41
+ output = `#{line}`
42
+ puts output
43
+ output
44
+ end
45
+ end
@@ -0,0 +1,64 @@
1
+ require "open3"
2
+
3
+ class LinkChecker
4
+ def initialize
5
+ @failed = false
6
+ end
7
+
8
+ def run
9
+ job_info
10
+ git_commit = ENV.fetch "KOKORO_GITHUB_COMMIT", "master"
11
+
12
+ markdown_files = Dir.glob "**/*.md"
13
+ broken_markdown_links = check_links markdown_files,
14
+ "https://github.com/googleapis/google-auth-library-ruby/tree/#{git_commit}",
15
+ " --skip '^(?!(\\Wruby.*google|.*google.*\\Wruby|.*cloud\\.google\\.com))'"
16
+
17
+ broken_devsite_links = check_links ["googleauth"],
18
+ "https://googleapis.dev/ruby",
19
+ "/latest/ --recurse --skip https:.*github.*"
20
+
21
+ puts_broken_links broken_markdown_links
22
+ puts_broken_links broken_devsite_links
23
+ end
24
+
25
+ def check_links location_list, base, tail
26
+ broken_links = Hash.new { |h, k| h[k] = [] }
27
+ location_list.each do |location|
28
+ out, err, st = Open3.capture3 "npx linkinator #{base}/#{location}#{tail}"
29
+ puts out
30
+ unless st.to_i.zero?
31
+ @failed = true
32
+ puts err
33
+ end
34
+ checked_links = out.split "\n"
35
+ checked_links.select! { |link| link =~ /\[\d+\]/ && !link.include?("[200]") }
36
+ unless checked_links.empty?
37
+ @failed = true
38
+ broken_links[location] += checked_links
39
+ end
40
+ end
41
+ broken_links
42
+ end
43
+
44
+ def puts_broken_links link_hash
45
+ link_hash.each do |location, links|
46
+ puts "#{location} contains the following broken links:"
47
+ links.each { |link| puts " #{link}" }
48
+ puts ""
49
+ end
50
+ end
51
+
52
+ def job_info
53
+ line_length = "Using Ruby - #{RUBY_VERSION}".length + 8
54
+ puts ""
55
+ puts "#" * line_length
56
+ puts "### Using Ruby - #{RUBY_VERSION} ###"
57
+ puts "#" * line_length
58
+ puts ""
59
+ end
60
+
61
+ def exit_status
62
+ @failed ? 1 : 0
63
+ end
64
+ end
@@ -0,0 +1,59 @@
1
+ require "json"
2
+
3
+ class RepoMetadata
4
+ attr_reader :data
5
+
6
+ def initialize data
7
+ @data = data
8
+ normalize_data!
9
+ end
10
+
11
+ def allowed_fields
12
+ [
13
+ "name", "version", "language", "distribution-name",
14
+ "product-page", "github-repository", "issue-tracker"
15
+ ]
16
+ end
17
+
18
+ def build output_directory
19
+ fields = @data.to_a.map { |kv| "--#{kv[0]} #{kv[1]}" }
20
+ Dir.chdir output_directory do
21
+ cmd "python3 -m docuploader create-metadata #{fields.join ' '}"
22
+ end
23
+ end
24
+
25
+ def normalize_data!
26
+ require_relative "../lib/googleauth/version.rb"
27
+
28
+ @data.delete_if { |k, _| !allowed_fields.include?(k) }
29
+ @data["version"] = "v#{Google::Auth::VERSION}"
30
+ end
31
+
32
+ def [] key
33
+ data[key]
34
+ end
35
+
36
+ def []= key, value
37
+ @data[key] = value
38
+ end
39
+
40
+ def cmd line
41
+ puts line
42
+ output = `#{line}`
43
+ puts output
44
+ output
45
+ end
46
+
47
+ def self.from_source source
48
+ if source.is_a? RepoMetadata
49
+ data = source.data
50
+ elsif source.is_a? Hash
51
+ data = source
52
+ elsif File.file? source
53
+ data = JSON.parse File.read(source)
54
+ else
55
+ raise "Source must be a path, hash, or RepoMetadata instance"
56
+ end
57
+ RepoMetadata.new data
58
+ end
59
+ end
@@ -27,14 +27,14 @@
27
27
  # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28
28
  # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
29
 
30
- spec_dir = File.expand_path(File.join(File.dirname(__FILE__)))
31
- $LOAD_PATH.unshift(spec_dir)
30
+ spec_dir = File.expand_path File.join(File.dirname(__FILE__))
31
+ $LOAD_PATH.unshift spec_dir
32
32
  $LOAD_PATH.uniq!
33
33
 
34
- require 'faraday'
35
- require 'spec_helper'
34
+ require "faraday"
35
+ require "spec_helper"
36
36
 
37
- shared_examples 'apply/apply! are OK' do
37
+ shared_examples "apply/apply! are OK" do
38
38
  let(:auth_key) { :authorization }
39
39
 
40
40
  # tests that use these examples need to define
@@ -43,102 +43,103 @@ shared_examples 'apply/apply! are OK' do
43
43
  #
44
44
  # @make_auth_stubs, which should stub out the expected http behaviour of the
45
45
  # auth client
46
- describe '#fetch_access_token' do
47
- let(:token) { '1/abcdef1234567890' }
48
- let(:stub) do
46
+ describe "#fetch_access_token" do
47
+ let(:token) { "1/abcdef1234567890" }
48
+ let :stub do
49
49
  make_auth_stubs access_token: token
50
50
  end
51
51
 
52
- it 'should set access_token to the fetched value' do
52
+ it "should set access_token to the fetched value" do
53
53
  stub
54
54
  @client.fetch_access_token!
55
55
  expect(@client.access_token).to eq(token)
56
56
  expect(stub).to have_been_requested
57
57
  end
58
58
 
59
- it 'should notify refresh listeners after updating' do
59
+ it "should notify refresh listeners after updating" do
60
60
  stub
61
61
  expect do |b|
62
62
  @client.on_refresh(&b)
63
63
  @client.fetch_access_token!
64
64
  end.to yield_with_args(have_attributes(
65
- access_token: '1/abcdef1234567890'))
65
+ access_token: "1/abcdef1234567890"
66
+ ))
66
67
  expect(stub).to have_been_requested
67
68
  end
68
69
  end
69
70
 
70
- describe '#apply!' do
71
- it 'should update the target hash with fetched access token' do
72
- token = '1/abcdef1234567890'
71
+ describe "#apply!" do
72
+ it "should update the target hash with fetched access token" do
73
+ token = "1/abcdef1234567890"
73
74
  stub = make_auth_stubs access_token: token
74
75
 
75
- md = { foo: 'bar' }
76
- @client.apply!(md)
77
- want = { :foo => 'bar', auth_key => "Bearer #{token}" }
76
+ md = { foo: "bar" }
77
+ @client.apply! md
78
+ want = { :foo => "bar", auth_key => "Bearer #{token}" }
78
79
  expect(md).to eq(want)
79
80
  expect(stub).to have_been_requested
80
81
  end
81
82
  end
82
83
 
83
- describe 'updater_proc' do
84
- it 'should provide a proc that updates a hash with the access token' do
85
- token = '1/abcdef1234567890'
84
+ describe "updater_proc" do
85
+ it "should provide a proc that updates a hash with the access token" do
86
+ token = "1/abcdef1234567890"
86
87
  stub = make_auth_stubs access_token: token
87
- md = { foo: 'bar' }
88
+ md = { foo: "bar" }
88
89
  the_proc = @client.updater_proc
89
- got = the_proc.call(md)
90
- want = { :foo => 'bar', auth_key => "Bearer #{token}" }
90
+ got = the_proc.call md
91
+ want = { :foo => "bar", auth_key => "Bearer #{token}" }
91
92
  expect(got).to eq(want)
92
93
  expect(stub).to have_been_requested
93
94
  end
94
95
  end
95
96
 
96
- describe '#apply' do
97
- it 'should not update the original hash with the access token' do
98
- token = '1/abcdef1234567890'
97
+ describe "#apply" do
98
+ it "should not update the original hash with the access token" do
99
+ token = "1/abcdef1234567890"
99
100
  stub = make_auth_stubs access_token: token
100
101
 
101
- md = { foo: 'bar' }
102
- @client.apply(md)
103
- want = { foo: 'bar' }
102
+ md = { foo: "bar" }
103
+ @client.apply md
104
+ want = { foo: "bar" }
104
105
  expect(md).to eq(want)
105
106
  expect(stub).to have_been_requested
106
107
  end
107
108
 
108
- it 'should add the token to the returned hash' do
109
- token = '1/abcdef1234567890'
109
+ it "should add the token to the returned hash" do
110
+ token = "1/abcdef1234567890"
110
111
  stub = make_auth_stubs access_token: token
111
112
 
112
- md = { foo: 'bar' }
113
- got = @client.apply(md)
114
- want = { :foo => 'bar', auth_key => "Bearer #{token}" }
113
+ md = { foo: "bar" }
114
+ got = @client.apply md
115
+ want = { :foo => "bar", auth_key => "Bearer #{token}" }
115
116
  expect(got).to eq(want)
116
117
  expect(stub).to have_been_requested
117
118
  end
118
119
 
119
- it 'should not fetch a new token if the current is not expired' do
120
- token = '1/abcdef1234567890'
120
+ it "should not fetch a new token if the current is not expired" do
121
+ token = "1/abcdef1234567890"
121
122
  stub = make_auth_stubs access_token: token
122
123
 
123
124
  n = 5 # arbitrary
124
125
  n.times do |_t|
125
- md = { foo: 'bar' }
126
- got = @client.apply(md)
127
- want = { :foo => 'bar', auth_key => "Bearer #{token}" }
126
+ md = { foo: "bar" }
127
+ got = @client.apply md
128
+ want = { :foo => "bar", auth_key => "Bearer #{token}" }
128
129
  expect(got).to eq(want)
129
130
  end
130
131
  expect(stub).to have_been_requested
131
132
  end
132
133
 
133
- it 'should fetch a new token if the current one is expired' do
134
- token_1 = '1/abcdef1234567890'
135
- token_2 = '2/abcdef1234567891'
134
+ it "should fetch a new token if the current one is expired" do
135
+ token1 = "1/abcdef1234567890"
136
+ token2 = "2/abcdef1234567891"
136
137
 
137
- [token_1, token_2].each do |t|
138
+ [token1, token2].each do |t|
138
139
  make_auth_stubs access_token: t
139
- md = { foo: 'bar' }
140
- got = @client.apply(md)
141
- want = { :foo => 'bar', auth_key => "Bearer #{t}" }
140
+ md = { foo: "bar" }
141
+ got = @client.apply md
142
+ want = { :foo => "bar", auth_key => "Bearer #{t}" }
142
143
  expect(got).to eq(want)
143
144
  @client.expires_at -= 3601 # default is to expire in 1hr
144
145
  end
@@ -27,114 +27,134 @@
27
27
  # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28
28
  # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
29
 
30
- spec_dir = File.expand_path(File.join(File.dirname(__FILE__)))
31
- $LOAD_PATH.unshift(spec_dir)
30
+ spec_dir = File.expand_path File.join(File.dirname(__FILE__))
31
+ $LOAD_PATH.unshift spec_dir
32
32
  $LOAD_PATH.uniq!
33
33
 
34
- require 'spec_helper'
35
- require 'fakefs/safe'
36
- require 'googleauth'
34
+ require "spec_helper"
35
+ require "fakefs/safe"
36
+ require "googleauth"
37
37
 
38
38
  describe Google::Auth::ClientId do
39
- shared_examples 'it has a valid config' do
40
- it 'should include a valid id' do
41
- expect(client_id.id).to eql 'abc@example.com'
39
+ shared_examples "it has a valid config" do
40
+ it "should include a valid id" do
41
+ expect(client_id.id).to eql "abc@example.com"
42
42
  end
43
43
 
44
- it 'should include a valid secret' do
45
- expect(client_id.secret).to eql 'notasecret'
44
+ it "should include a valid secret" do
45
+ expect(client_id.secret).to eql "notasecret"
46
46
  end
47
47
  end
48
48
 
49
- shared_examples 'it can successfully load client_id' do
50
- context 'loaded from hash' do
51
- let(:client_id) { Google::Auth::ClientId.from_hash(config) }
49
+ shared_examples "it can successfully load client_id" do
50
+ context "loaded from hash" do
51
+ let(:client_id) { Google::Auth::ClientId.from_hash config }
52
52
 
53
- it_behaves_like 'it has a valid config'
53
+ it_behaves_like "it has a valid config"
54
54
  end
55
55
 
56
- context 'loaded from file' do
57
- file_path = '/client_secrets.json'
56
+ context "loaded from file" do
57
+ file_path = "/client_secrets.json"
58
58
 
59
- let(:client_id) do
59
+ let :client_id do
60
60
  FakeFS do
61
- content = MultiJson.dump(config)
62
- File.write(file_path, content)
63
- Google::Auth::ClientId.from_file(file_path)
61
+ content = MultiJson.dump config
62
+ File.write file_path, content
63
+ Google::Auth::ClientId.from_file file_path
64
64
  end
65
65
  end
66
66
 
67
- it_behaves_like 'it has a valid config'
67
+ it_behaves_like "it has a valid config"
68
68
  end
69
69
  end
70
70
 
71
- describe 'with web config' do
72
- let(:config) do
71
+ describe "with web config" do
72
+ let :config do
73
73
  {
74
- 'web' => {
75
- 'client_id' => 'abc@example.com',
76
- 'client_secret' => 'notasecret'
74
+ "web" => {
75
+ "client_id" => "abc@example.com",
76
+ "client_secret" => "notasecret"
77
77
  }
78
78
  }
79
79
  end
80
- it_behaves_like 'it can successfully load client_id'
80
+ it_behaves_like "it can successfully load client_id"
81
81
  end
82
82
 
83
- describe 'with installed app config' do
84
- let(:config) do
83
+ describe "with installed app config" do
84
+ let :config do
85
85
  {
86
- 'installed' => {
87
- 'client_id' => 'abc@example.com',
88
- 'client_secret' => 'notasecret'
86
+ "installed" => {
87
+ "client_id" => "abc@example.com",
88
+ "client_secret" => "notasecret"
89
89
  }
90
90
  }
91
91
  end
92
- it_behaves_like 'it can successfully load client_id'
92
+ it_behaves_like "it can successfully load client_id"
93
93
  end
94
94
 
95
- context 'with missing top level property' do
96
- let(:config) do
95
+ context "with missing top level property" do
96
+ let :config do
97
97
  {
98
- 'notvalid' => {
99
- 'client_id' => 'abc@example.com',
100
- 'client_secret' => 'notasecret'
98
+ "notvalid" => {
99
+ "client_id" => "abc@example.com",
100
+ "client_secret" => "notasecret"
101
101
  }
102
102
  }
103
103
  end
104
104
 
105
- it 'should raise error' do
106
- expect { Google::Auth::ClientId.from_hash(config) }.to raise_error(
107
- /Expected top level property/)
105
+ it "should raise error" do
106
+ expect { Google::Auth::ClientId.from_hash config }.to raise_error(
107
+ /Expected top level property/
108
+ )
108
109
  end
109
110
  end
110
111
 
111
- context 'with missing client id' do
112
- let(:config) do
112
+ context "with missing client id" do
113
+ let :config do
113
114
  {
114
- 'web' => {
115
- 'client_secret' => 'notasecret'
115
+ "web" => {
116
+ "client_secret" => "notasecret"
116
117
  }
117
118
  }
118
119
  end
119
120
 
120
- it 'should raise error' do
121
- expect { Google::Auth::ClientId.from_hash(config) }.to raise_error(
122
- /Client id can not be nil/)
121
+ it "should raise error" do
122
+ expect { Google::Auth::ClientId.from_hash config }.to raise_error(
123
+ /Client id can not be nil/
124
+ )
123
125
  end
124
126
  end
125
127
 
126
- context 'with missing client secret' do
127
- let(:config) do
128
+ context "with missing client secret" do
129
+ let :config do
128
130
  {
129
- 'web' => {
130
- 'client_id' => 'abc@example.com'
131
+ "web" => {
132
+ "client_id" => "abc@example.com"
131
133
  }
132
134
  }
133
135
  end
134
136
 
135
- it 'should raise error' do
136
- expect { Google::Auth::ClientId.from_hash(config) }.to raise_error(
137
- /Client secret can not be nil/)
137
+ it "should raise error" do
138
+ expect { Google::Auth::ClientId.from_hash config }.to raise_error(
139
+ /Client secret can not be nil/
140
+ )
141
+ end
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
138
158
  end
139
159
  end
140
160
  end