googleauth 0.5.1 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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