googleauth 0.5.1 → 0.11.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/{CONTRIBUTING.md → .github/CONTRIBUTING.md} +5 -4
- data/.github/ISSUE_TEMPLATE/bug_report.md +36 -0
- data/.github/ISSUE_TEMPLATE/feature_request.md +21 -0
- data/.github/ISSUE_TEMPLATE/support_request.md +7 -0
- data/.kokoro/build.bat +16 -0
- data/.kokoro/build.sh +4 -0
- data/.kokoro/continuous/common.cfg +24 -0
- data/.kokoro/continuous/linux.cfg +25 -0
- data/.kokoro/continuous/osx.cfg +8 -0
- data/.kokoro/continuous/post.cfg +30 -0
- data/.kokoro/continuous/windows.cfg +29 -0
- data/.kokoro/osx.sh +4 -0
- data/.kokoro/presubmit/common.cfg +24 -0
- data/.kokoro/presubmit/linux.cfg +24 -0
- data/.kokoro/presubmit/osx.cfg +8 -0
- data/.kokoro/presubmit/windows.cfg +29 -0
- data/.kokoro/release.cfg +94 -0
- data/.kokoro/trampoline.bat +10 -0
- data/.kokoro/trampoline.sh +4 -0
- data/.repo-metadata.json +5 -0
- data/.rubocop.yml +17 -1
- data/CHANGELOG.md +90 -19
- data/CODE_OF_CONDUCT.md +43 -0
- data/Gemfile +16 -13
- data/README.md +58 -18
- data/Rakefile +106 -10
- data/googleauth.gemspec +27 -25
- data/lib/googleauth/application_default.rb +81 -0
- data/lib/googleauth/client_id.rb +21 -19
- data/lib/googleauth/compute_engine.rb +40 -43
- data/lib/googleauth/credentials.rb +375 -0
- data/lib/googleauth/credentials_loader.rb +117 -43
- data/lib/googleauth/default_credentials.rb +93 -0
- data/lib/googleauth/iam.rb +11 -11
- data/lib/googleauth/json_key_reader.rb +46 -0
- data/lib/googleauth/scope_util.rb +12 -12
- data/lib/googleauth/service_account.rb +64 -62
- data/lib/googleauth/signet.rb +53 -12
- data/lib/googleauth/stores/file_token_store.rb +8 -8
- data/lib/googleauth/stores/redis_token_store.rb +22 -22
- data/lib/googleauth/token_store.rb +6 -6
- data/lib/googleauth/user_authorizer.rb +80 -68
- data/lib/googleauth/user_refresh.rb +44 -35
- data/lib/googleauth/version.rb +1 -1
- data/lib/googleauth/web_user_authorizer.rb +77 -68
- data/lib/googleauth.rb +6 -96
- data/rakelib/devsite_builder.rb +45 -0
- data/rakelib/link_checker.rb +64 -0
- data/rakelib/repo_metadata.rb +59 -0
- data/spec/googleauth/apply_auth_examples.rb +47 -46
- data/spec/googleauth/client_id_spec.rb +75 -55
- data/spec/googleauth/compute_engine_spec.rb +60 -43
- data/spec/googleauth/credentials_spec.rb +467 -0
- data/spec/googleauth/get_application_default_spec.rb +149 -111
- data/spec/googleauth/iam_spec.rb +25 -25
- data/spec/googleauth/scope_util_spec.rb +26 -24
- data/spec/googleauth/service_account_spec.rb +261 -143
- data/spec/googleauth/signet_spec.rb +93 -30
- data/spec/googleauth/stores/file_token_store_spec.rb +12 -13
- data/spec/googleauth/stores/redis_token_store_spec.rb +11 -11
- data/spec/googleauth/stores/store_examples.rb +16 -16
- data/spec/googleauth/user_authorizer_spec.rb +153 -124
- data/spec/googleauth/user_refresh_spec.rb +186 -121
- data/spec/googleauth/web_user_authorizer_spec.rb +82 -69
- data/spec/spec_helper.rb +21 -19
- metadata +75 -32
- data/.rubocop_todo.yml +0 -32
- 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
|
31
|
-
$LOAD_PATH.unshift
|
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
|
35
|
-
require
|
36
|
-
require
|
37
|
-
require
|
38
|
-
require
|
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
|
42
|
-
@key = OpenSSL::PKey::RSA.new
|
41
|
+
before :example do
|
42
|
+
@key = OpenSSL::PKey::RSA.new 2048
|
43
43
|
@client = Signet::OAuth2::Client.new(
|
44
|
-
token_credential_uri:
|
45
|
-
scope:
|
46
|
-
issuer:
|
47
|
-
audience:
|
48
|
-
signing_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
|
52
|
-
access_token = opts[:access_token] ||
|
53
|
-
body = MultiJson.dump(
|
54
|
-
|
55
|
-
|
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
|
58
|
-
_claim, _header = JWT.decode(params.assoc(
|
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
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
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
|
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
|
31
|
-
$LOAD_PATH.unshift
|
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
|
35
|
-
require
|
36
|
-
require
|
37
|
-
require
|
38
|
-
require
|
39
|
-
require
|
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
|
54
|
-
Google::Auth::Stores::FileTokenStore.new
|
52
|
+
let :store do
|
53
|
+
Google::Auth::Stores::FileTokenStore.new file: "/tokens.yaml"
|
55
54
|
end
|
56
55
|
|
57
|
-
it_behaves_like
|
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
|
31
|
-
$LOAD_PATH.unshift
|
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
|
35
|
-
require
|
36
|
-
require
|
37
|
-
require
|
38
|
-
require
|
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
|
41
|
+
let :redis do
|
42
42
|
Redis.new
|
43
43
|
end
|
44
44
|
|
45
|
-
let
|
46
|
-
Google::Auth::Stores::RedisTokenStore.new
|
45
|
+
let :store do
|
46
|
+
Google::Auth::Stores::RedisTokenStore.new redis: redis
|
47
47
|
end
|
48
48
|
|
49
|
-
it_behaves_like
|
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
|
31
|
-
$LOAD_PATH.unshift
|
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
|
34
|
+
require "spec_helper"
|
35
35
|
|
36
|
-
shared_examples
|
37
|
-
before
|
38
|
-
store.store
|
36
|
+
shared_examples "token store" do
|
37
|
+
before :each do
|
38
|
+
store.store "default", "test"
|
39
39
|
end
|
40
40
|
|
41
|
-
it
|
42
|
-
expect(store.load(
|
41
|
+
it "should return a stored value" do
|
42
|
+
expect(store.load("default")).to eq "test"
|
43
43
|
end
|
44
44
|
|
45
|
-
it
|
46
|
-
expect(store.load(
|
45
|
+
it "should return nil for missing tokens" do
|
46
|
+
expect(store.load("notavalidkey")).to be_nil
|
47
47
|
end
|
48
48
|
|
49
|
-
it
|
50
|
-
store.delete
|
51
|
-
expect(store.load(
|
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
|
55
|
-
store.store
|
56
|
-
expect(store.load(
|
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
|