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
@@ -27,45 +27,108 @@
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 'apply_auth_examples'
35
- require 'googleauth/signet'
36
- require 'jwt'
37
- require 'openssl'
38
- require 'spec_helper'
34
+ require "apply_auth_examples"
35
+ require "googleauth/signet"
36
+ require "jwt"
37
+ require "openssl"
38
+ require "spec_helper"
39
39
 
40
40
  describe Signet::OAuth2::Client do
41
- before(:example) do
42
- @key = OpenSSL::PKey::RSA.new(2048)
41
+ before :example do
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',
45
- scope: 'https://www.googleapis.com/auth/userinfo.profile',
46
- issuer: 'app@example.com',
47
- audience: 'https://accounts.google.com/o/oauth2/token',
48
- signing_key: @key)
44
+ token_credential_uri: "https://oauth2.googleapis.com/token",
45
+ scope: "https://www.googleapis.com/auth/userinfo.profile",
46
+ issuer: "app@example.com",
47
+ audience: "https://oauth2.googleapis.com/token",
48
+ signing_key: @key
49
+ )
49
50
  end
50
51
 
51
- def make_auth_stubs(opts)
52
- access_token = opts[:access_token] || ''
53
- body = MultiJson.dump('access_token' => access_token,
54
- 'token_type' => 'Bearer',
55
- 'expires_in' => 3600)
52
+ def make_auth_stubs opts
53
+ access_token = opts[:access_token] || ""
54
+ body = MultiJson.dump("access_token" => access_token,
55
+ "token_type" => "Bearer",
56
+ "expires_in" => 3600)
56
57
  blk = proc do |request|
57
- params = Addressable::URI.form_unencode(request.body)
58
- _claim, _header = JWT.decode(params.assoc('assertion').last,
59
- @key.public_key)
58
+ params = Addressable::URI.form_unencode request.body
59
+ _claim, _header = JWT.decode(params.assoc("assertion").last,
60
+ @key.public_key, true,
61
+ algorithm: "RS256")
60
62
  end
61
- stub_request(:post, 'https://accounts.google.com/o/oauth2/token')
62
- .with(body: hash_including(
63
- 'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer'),
64
- &blk)
65
- .to_return(body: body,
66
- status: 200,
67
- headers: { 'Content-Type' => 'application/json' })
63
+ with_params = { body: hash_including(
64
+ "grant_type" => "urn:ietf:params:oauth:grant-type:jwt-bearer"
65
+ ) }
66
+ with_params[:headers] = { "User-Agent" => opts[:user_agent] } if opts[:user_agent]
67
+ stub_request(:post, "https://oauth2.googleapis.com/token")
68
+ .with(with_params, &blk)
69
+ .to_return(body: body,
70
+ status: 200,
71
+ headers: { "Content-Type" => "application/json" })
68
72
  end
69
73
 
70
- it_behaves_like 'apply/apply! are OK'
74
+ it_behaves_like "apply/apply! are OK"
75
+
76
+ describe "#configure_connection" do
77
+ it "honors default_connection" do
78
+ token = "1/abcdef1234567890"
79
+ stub = make_auth_stubs access_token: token, user_agent: "RubyRocks/1.0"
80
+ conn = Faraday.new headers: { "User-Agent" => "RubyRocks/1.0" }
81
+ @client.configure_connection default_connection: conn
82
+ md = { foo: "bar" }
83
+ @client.apply! md
84
+ want = { foo: "bar", authorization: "Bearer #{token}" }
85
+ expect(md).to eq(want)
86
+ expect(stub).to have_been_requested
87
+ end
88
+
89
+ it "honors connection_builder" do
90
+ token = "1/abcdef1234567890"
91
+ stub = make_auth_stubs access_token: token, user_agent: "RubyRocks/2.0"
92
+ connection_builder = proc do
93
+ Faraday.new headers: { "User-Agent" => "RubyRocks/2.0" }
94
+ end
95
+ @client.configure_connection connection_builder: connection_builder
96
+ md = { foo: "bar" }
97
+ @client.apply! md
98
+ want = { foo: "bar", authorization: "Bearer #{token}" }
99
+ expect(md).to eq(want)
100
+ expect(stub).to have_been_requested
101
+ end
102
+ end
103
+
104
+ describe "#fetch_access_token!" do
105
+ it "retries when orig_fetch_access_token! raises Signet::RemoteServerError" do
106
+ mocked_responses = [:raise, :raise, "success"]
107
+ allow(@client).to receive(:orig_fetch_access_token!).exactly(3).times do
108
+ response = mocked_responses.shift
109
+ response == :raise ? raise(Signet::RemoteServerError) : response
110
+ end
111
+ expect(@client.fetch_access_token!).to eq("success")
112
+ end
113
+
114
+ it "raises when the max retry count is exceeded" do
115
+ mocked_responses = [:raise, :raise, :raise, :raise, :raise, :raise, "success"]
116
+ allow(@client).to receive(:orig_fetch_access_token!).exactly(6).times do
117
+ response = mocked_responses.shift
118
+ response == :raise ? raise(Signet::RemoteServerError) : response
119
+ end
120
+ expect { @client.fetch_access_token! }.to raise_error Signet::AuthorizationError
121
+ end
122
+
123
+ it "does not retry and raises right away if it encounters a Signet::AuthorizationError" do
124
+ allow(@client).to receive(:orig_fetch_access_token!).at_most(:once)
125
+ .and_raise(Signet::AuthorizationError.new("Some Message"))
126
+ expect { @client.fetch_access_token! }.to raise_error Signet::AuthorizationError
127
+ end
128
+
129
+ it "does not retry and raises right away if it encounters a Signet::ParseError" do
130
+ allow(@client).to receive(:orig_fetch_access_token!).at_most(:once).and_raise(Signet::ParseError)
131
+ expect { @client.fetch_access_token! }.to raise_error Signet::ParseError
132
+ end
133
+ end
71
134
  end
@@ -27,32 +27,31 @@
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 'googleauth'
35
- require 'googleauth/stores/file_token_store'
36
- require 'spec_helper'
37
- require 'fakefs/safe'
38
- require 'fakefs/spec_helpers'
39
- require 'googleauth/stores/store_examples'
34
+ require "googleauth"
35
+ require "googleauth/stores/file_token_store"
36
+ require "spec_helper"
37
+ require "fakefs/safe"
38
+ require "fakefs/spec_helpers"
39
+ require "googleauth/stores/store_examples"
40
40
 
41
41
  module FakeFS
42
42
  class File
43
43
  # FakeFS doesn't implement. And since we don't need to actually lock,
44
44
  # just stub out...
45
- def flock(*)
46
- end
45
+ def flock *; end
47
46
  end
48
47
  end
49
48
 
50
49
  describe Google::Auth::Stores::FileTokenStore do
51
50
  include FakeFS::SpecHelpers
52
51
 
53
- let(:store) do
54
- Google::Auth::Stores::FileTokenStore.new(file: '/tokens.yaml')
52
+ let :store do
53
+ Google::Auth::Stores::FileTokenStore.new file: "/tokens.yaml"
55
54
  end
56
55
 
57
- it_behaves_like 'token store'
56
+ it_behaves_like "token store"
58
57
  end
@@ -27,24 +27,24 @@
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 'googleauth'
35
- require 'googleauth/stores/redis_token_store'
36
- require 'spec_helper'
37
- require 'fakeredis/rspec'
38
- require 'googleauth/stores/store_examples'
34
+ require "googleauth"
35
+ require "googleauth/stores/redis_token_store"
36
+ require "spec_helper"
37
+ require "fakeredis/rspec"
38
+ require "googleauth/stores/store_examples"
39
39
 
40
40
  describe Google::Auth::Stores::RedisTokenStore do
41
- let(:redis) do
41
+ let :redis do
42
42
  Redis.new
43
43
  end
44
44
 
45
- let(:store) do
46
- Google::Auth::Stores::RedisTokenStore.new(redis: redis)
45
+ let :store do
46
+ Google::Auth::Stores::RedisTokenStore.new redis: redis
47
47
  end
48
48
 
49
- it_behaves_like 'token store'
49
+ it_behaves_like "token store"
50
50
  end
@@ -27,32 +27,32 @@
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'
34
+ require "spec_helper"
35
35
 
36
- shared_examples 'token store' do
37
- before(:each) do
38
- store.store('default', 'test')
36
+ shared_examples "token store" do
37
+ before :each do
38
+ store.store "default", "test"
39
39
  end
40
40
 
41
- it 'should return a stored value' do
42
- expect(store.load('default')).to eq 'test'
41
+ it "should return a stored value" do
42
+ expect(store.load("default")).to eq "test"
43
43
  end
44
44
 
45
- it 'should return nil for missing tokens' do
46
- expect(store.load('notavalidkey')).to be_nil
45
+ it "should return nil for missing tokens" do
46
+ expect(store.load("notavalidkey")).to be_nil
47
47
  end
48
48
 
49
- it 'should return nil for deleted tokens' do
50
- store.delete('default')
51
- expect(store.load('default')).to be_nil
49
+ it "should return nil for deleted tokens" do
50
+ store.delete "default"
51
+ expect(store.load("default")).to be_nil
52
52
  end
53
53
 
54
- it 'should save overwrite values on store' do
55
- store.store('default', 'test2')
56
- expect(store.load('default')).to eq 'test2'
54
+ it "should save overwrite values on store" do
55
+ store.store "default", "test2"
56
+ expect(store.load("default")).to eq "test2"
57
57
  end
58
58
  end