googleauth 0.8.0 → 0.8.1
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.
- checksums.yaml +4 -4
- data/.kokoro/build.sh +2 -34
- data/.kokoro/continuous/common.cfg +5 -0
- data/.kokoro/continuous/linux.cfg +1 -1
- data/.kokoro/osx.sh +2 -33
- data/.kokoro/presubmit/common.cfg +5 -0
- data/.kokoro/presubmit/linux.cfg +1 -1
- data/.kokoro/release.cfg +53 -0
- data/.kokoro/trampoline.sh +3 -23
- data/.kokoro/windows.sh +2 -30
- data/.rubocop.yml +7 -24
- data/CHANGELOG.md +24 -39
- data/Gemfile +14 -14
- data/README.md +21 -1
- data/Rakefile +84 -10
- data/googleauth.gemspec +23 -23
- data/lib/googleauth.rb +6 -6
- data/lib/googleauth/application_default.rb +11 -11
- data/lib/googleauth/client_id.rb +16 -16
- data/lib/googleauth/compute_engine.rb +27 -27
- data/lib/googleauth/credentials.rb +35 -37
- data/lib/googleauth/credentials_loader.rb +64 -67
- data/lib/googleauth/default_credentials.rb +18 -18
- data/lib/googleauth/iam.rb +9 -9
- data/lib/googleauth/json_key_reader.rb +6 -6
- data/lib/googleauth/scope_util.rb +11 -11
- data/lib/googleauth/service_account.rb +42 -42
- data/lib/googleauth/signet.rb +15 -17
- data/lib/googleauth/stores/file_token_store.rb +8 -8
- data/lib/googleauth/stores/redis_token_store.rb +17 -17
- data/lib/googleauth/token_store.rb +6 -6
- data/lib/googleauth/user_authorizer.rb +55 -59
- data/lib/googleauth/user_refresh.rb +27 -27
- data/lib/googleauth/version.rb +1 -1
- data/lib/googleauth/web_user_authorizer.rb +55 -56
- data/spec/googleauth/apply_auth_examples.rb +46 -46
- data/spec/googleauth/client_id_spec.rb +54 -54
- data/spec/googleauth/compute_engine_spec.rb +41 -41
- data/spec/googleauth/credentials_spec.rb +97 -97
- data/spec/googleauth/get_application_default_spec.rb +114 -114
- data/spec/googleauth/iam_spec.rb +25 -25
- data/spec/googleauth/scope_util_spec.rb +24 -24
- data/spec/googleauth/service_account_spec.rb +204 -194
- data/spec/googleauth/signet_spec.rb +37 -38
- data/spec/googleauth/stores/file_token_store_spec.rb +12 -12
- 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 +120 -121
- data/spec/googleauth/user_refresh_spec.rb +151 -146
- data/spec/googleauth/web_user_authorizer_spec.rb +66 -66
- data/spec/spec_helper.rb +19 -19
- metadata +4 -6
- data/.kokoro/common.cfg +0 -22
- data/.travis.yml +0 -40
|
@@ -27,81 +27,81 @@
|
|
|
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
|
|
40
|
-
require
|
|
41
|
-
require
|
|
42
|
-
require
|
|
43
|
-
require
|
|
34
|
+
require "apply_auth_examples"
|
|
35
|
+
require "fakefs/safe"
|
|
36
|
+
require "fileutils"
|
|
37
|
+
require "googleauth/service_account"
|
|
38
|
+
require "jwt"
|
|
39
|
+
require "multi_json"
|
|
40
|
+
require "openssl"
|
|
41
|
+
require "spec_helper"
|
|
42
|
+
require "tmpdir"
|
|
43
|
+
require "os"
|
|
44
44
|
|
|
45
45
|
include Google::Auth::CredentialsLoader
|
|
46
46
|
|
|
47
|
-
shared_examples
|
|
48
|
-
context
|
|
49
|
-
let(:test_uri) {
|
|
50
|
-
let(:auth_prefix) {
|
|
47
|
+
shared_examples "jwt header auth" do
|
|
48
|
+
context "when jwt_aud_uri is present" do
|
|
49
|
+
let(:test_uri) { "https://www.googleapis.com/myservice" }
|
|
50
|
+
let(:auth_prefix) { "Bearer " }
|
|
51
51
|
let(:auth_key) { ServiceAccountJwtHeaderCredentials::AUTH_METADATA_KEY }
|
|
52
52
|
let(:jwt_uri_key) { ServiceAccountJwtHeaderCredentials::JWT_AUD_URI_KEY }
|
|
53
53
|
|
|
54
|
-
def expect_is_encoded_jwt
|
|
54
|
+
def expect_is_encoded_jwt hdr
|
|
55
55
|
expect(hdr).to_not be_nil
|
|
56
56
|
expect(hdr.start_with?(auth_prefix)).to be true
|
|
57
57
|
authorization = hdr[auth_prefix.length..-1]
|
|
58
|
-
payload, = JWT.decode
|
|
59
|
-
expect(payload[
|
|
60
|
-
expect(payload[
|
|
58
|
+
payload, = JWT.decode authorization, @key.public_key, true, algorithm: "RS256"
|
|
59
|
+
expect(payload["aud"]).to eq(test_uri)
|
|
60
|
+
expect(payload["iss"]).to eq(client_email)
|
|
61
61
|
end
|
|
62
62
|
|
|
63
|
-
describe
|
|
64
|
-
it
|
|
65
|
-
md = { foo:
|
|
63
|
+
describe "#apply!" do
|
|
64
|
+
it "should update the target hash with a jwt token" do
|
|
65
|
+
md = { foo: "bar" }
|
|
66
66
|
md[jwt_uri_key] = test_uri
|
|
67
|
-
@client.apply!
|
|
67
|
+
@client.apply! md
|
|
68
68
|
auth_header = md[auth_key]
|
|
69
|
-
expect_is_encoded_jwt
|
|
69
|
+
expect_is_encoded_jwt auth_header
|
|
70
70
|
expect(md[jwt_uri_key]).to be_nil
|
|
71
71
|
end
|
|
72
72
|
end
|
|
73
73
|
|
|
74
|
-
describe
|
|
75
|
-
it
|
|
76
|
-
md = { foo:
|
|
74
|
+
describe "updater_proc" do
|
|
75
|
+
it "should provide a proc that updates a hash with a jwt token" do
|
|
76
|
+
md = { foo: "bar" }
|
|
77
77
|
md[jwt_uri_key] = test_uri
|
|
78
78
|
the_proc = @client.updater_proc
|
|
79
|
-
got = the_proc.call
|
|
79
|
+
got = the_proc.call md
|
|
80
80
|
auth_header = got[auth_key]
|
|
81
|
-
expect_is_encoded_jwt
|
|
81
|
+
expect_is_encoded_jwt auth_header
|
|
82
82
|
expect(got[jwt_uri_key]).to be_nil
|
|
83
83
|
expect(md[jwt_uri_key]).to_not be_nil
|
|
84
84
|
end
|
|
85
85
|
end
|
|
86
86
|
|
|
87
|
-
describe
|
|
88
|
-
it
|
|
89
|
-
md = { foo:
|
|
87
|
+
describe "#apply" do
|
|
88
|
+
it "should not update the original hash with a jwt token" do
|
|
89
|
+
md = { foo: "bar" }
|
|
90
90
|
md[jwt_uri_key] = test_uri
|
|
91
91
|
the_proc = @client.updater_proc
|
|
92
|
-
got = the_proc.call
|
|
92
|
+
got = the_proc.call md
|
|
93
93
|
auth_header = md[auth_key]
|
|
94
94
|
expect(auth_header).to be_nil
|
|
95
95
|
expect(got[jwt_uri_key]).to be_nil
|
|
96
96
|
expect(md[jwt_uri_key]).to_not be_nil
|
|
97
97
|
end
|
|
98
98
|
|
|
99
|
-
it
|
|
100
|
-
md = { foo:
|
|
99
|
+
it "should add a jwt token to the returned hash" do
|
|
100
|
+
md = { foo: "bar" }
|
|
101
101
|
md[jwt_uri_key] = test_uri
|
|
102
|
-
got = @client.apply
|
|
102
|
+
got = @client.apply md
|
|
103
103
|
auth_header = got[auth_key]
|
|
104
|
-
expect_is_encoded_jwt
|
|
104
|
+
expect_is_encoded_jwt auth_header
|
|
105
105
|
end
|
|
106
106
|
end
|
|
107
107
|
end
|
|
@@ -109,63 +109,63 @@ end
|
|
|
109
109
|
|
|
110
110
|
describe Google::Auth::ServiceAccountCredentials do
|
|
111
111
|
ServiceAccountCredentials = Google::Auth::ServiceAccountCredentials
|
|
112
|
-
let(:client_email) {
|
|
113
|
-
let
|
|
112
|
+
let(:client_email) { "app@developer.gserviceaccount.com" }
|
|
113
|
+
let :cred_json do
|
|
114
114
|
{
|
|
115
|
-
private_key_id:
|
|
116
|
-
private_key:
|
|
117
|
-
client_email:
|
|
118
|
-
client_id:
|
|
119
|
-
type:
|
|
120
|
-
project_id:
|
|
115
|
+
private_key_id: "a_private_key_id",
|
|
116
|
+
private_key: @key.to_pem,
|
|
117
|
+
client_email: client_email,
|
|
118
|
+
client_id: "app.apps.googleusercontent.com",
|
|
119
|
+
type: "service_account",
|
|
120
|
+
project_id: "a_project_id"
|
|
121
121
|
}
|
|
122
122
|
end
|
|
123
123
|
|
|
124
|
-
before
|
|
125
|
-
@key = OpenSSL::PKey::RSA.new
|
|
124
|
+
before :example do
|
|
125
|
+
@key = OpenSSL::PKey::RSA.new 2048
|
|
126
126
|
@client = ServiceAccountCredentials.make_creds(
|
|
127
127
|
json_key_io: StringIO.new(cred_json_text),
|
|
128
|
-
scope:
|
|
128
|
+
scope: "https://www.googleapis.com/auth/userinfo.profile"
|
|
129
129
|
)
|
|
130
130
|
end
|
|
131
131
|
|
|
132
|
-
def make_auth_stubs
|
|
133
|
-
access_token = opts[:access_token] ||
|
|
134
|
-
body = MultiJson.dump(
|
|
135
|
-
|
|
136
|
-
|
|
132
|
+
def make_auth_stubs opts = {}
|
|
133
|
+
access_token = opts[:access_token] || ""
|
|
134
|
+
body = MultiJson.dump("access_token" => access_token,
|
|
135
|
+
"token_type" => "Bearer",
|
|
136
|
+
"expires_in" => 3600)
|
|
137
137
|
blk = proc do |request|
|
|
138
|
-
params = Addressable::URI.form_unencode
|
|
139
|
-
_claim, _header = JWT.decode(params.assoc(
|
|
138
|
+
params = Addressable::URI.form_unencode request.body
|
|
139
|
+
_claim, _header = JWT.decode(params.assoc("assertion").last,
|
|
140
140
|
@key.public_key, true,
|
|
141
|
-
algorithm:
|
|
141
|
+
algorithm: "RS256")
|
|
142
142
|
end
|
|
143
|
-
stub_request(:post,
|
|
143
|
+
stub_request(:post, "https://www.googleapis.com/oauth2/v4/token")
|
|
144
144
|
.with(body: hash_including(
|
|
145
|
-
|
|
145
|
+
"grant_type" => "urn:ietf:params:oauth:grant-type:jwt-bearer"
|
|
146
146
|
),
|
|
147
147
|
&blk)
|
|
148
|
-
.to_return(body:
|
|
149
|
-
status:
|
|
150
|
-
headers: {
|
|
148
|
+
.to_return(body: body,
|
|
149
|
+
status: 200,
|
|
150
|
+
headers: { "Content-Type" => "application/json" })
|
|
151
151
|
end
|
|
152
152
|
|
|
153
153
|
def cred_json_text
|
|
154
|
-
MultiJson.dump
|
|
154
|
+
MultiJson.dump cred_json
|
|
155
155
|
end
|
|
156
156
|
|
|
157
|
-
it_behaves_like
|
|
157
|
+
it_behaves_like "apply/apply! are OK"
|
|
158
158
|
|
|
159
|
-
context
|
|
160
|
-
before
|
|
159
|
+
context "when scope is nil" do
|
|
160
|
+
before :example do
|
|
161
161
|
@client.scope = nil
|
|
162
162
|
end
|
|
163
163
|
|
|
164
|
-
it_behaves_like
|
|
164
|
+
it_behaves_like "jwt header auth"
|
|
165
165
|
end
|
|
166
166
|
|
|
167
|
-
describe
|
|
168
|
-
before
|
|
167
|
+
describe "#from_env" do
|
|
168
|
+
before :example do
|
|
169
169
|
@var_name = ENV_VAR
|
|
170
170
|
@credential_vars = [
|
|
171
171
|
ENV_VAR, PRIVATE_KEY_VAR, CLIENT_EMAIL_VAR, ACCOUNT_TYPE_VAR
|
|
@@ -174,56 +174,61 @@ describe Google::Auth::ServiceAccountCredentials do
|
|
|
174
174
|
@credential_vars.each { |var| @original_env_vals[var] = ENV[var] }
|
|
175
175
|
ENV[ACCOUNT_TYPE_VAR] = cred_json[:type]
|
|
176
176
|
|
|
177
|
-
@scope =
|
|
177
|
+
@scope = "https://www.googleapis.com/auth/userinfo.profile"
|
|
178
178
|
@clz = ServiceAccountCredentials
|
|
179
179
|
end
|
|
180
180
|
|
|
181
|
-
after
|
|
181
|
+
after :example do
|
|
182
182
|
@credential_vars.each { |var| ENV[var] = @original_env_vals[var] }
|
|
183
183
|
end
|
|
184
184
|
|
|
185
|
-
it
|
|
186
|
-
ENV.delete
|
|
185
|
+
it "returns nil if the GOOGLE_APPLICATION_CREDENTIALS is unset" do
|
|
186
|
+
ENV.delete @var_name unless ENV[@var_name].nil?
|
|
187
187
|
expect(ServiceAccountCredentials.from_env(@scope)).to be_nil
|
|
188
188
|
end
|
|
189
189
|
|
|
190
|
-
it
|
|
191
|
-
ENV
|
|
190
|
+
it "returns nil if the GOOGLE_APPLICATION_CREDENTIALS is empty" do
|
|
191
|
+
ENV[@var_name] = ""
|
|
192
|
+
expect(ServiceAccountCredentials.from_env(@scope)).to be_nil
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
it "fails if the GOOGLE_APPLICATION_CREDENTIALS path does not exist" do
|
|
196
|
+
ENV.delete @var_name unless ENV[@var_name].nil?
|
|
192
197
|
expect(ServiceAccountCredentials.from_env(@scope)).to be_nil
|
|
193
198
|
Dir.mktmpdir do |dir|
|
|
194
|
-
key_path = File.join
|
|
199
|
+
key_path = File.join dir, "does-not-exist"
|
|
195
200
|
ENV[@var_name] = key_path
|
|
196
|
-
expect { @clz.from_env
|
|
201
|
+
expect { @clz.from_env @scope }.to raise_error RuntimeError
|
|
197
202
|
end
|
|
198
203
|
end
|
|
199
204
|
|
|
200
|
-
it
|
|
205
|
+
it "succeeds when the GOOGLE_APPLICATION_CREDENTIALS file is valid" do
|
|
201
206
|
Dir.mktmpdir do |dir|
|
|
202
|
-
key_path = File.join
|
|
203
|
-
FileUtils.mkdir_p
|
|
204
|
-
File.write
|
|
207
|
+
key_path = File.join dir, "my_cert_file"
|
|
208
|
+
FileUtils.mkdir_p File.dirname(key_path)
|
|
209
|
+
File.write key_path, cred_json_text
|
|
205
210
|
ENV[@var_name] = key_path
|
|
206
211
|
expect(@clz.from_env(@scope)).to_not be_nil
|
|
207
212
|
end
|
|
208
213
|
end
|
|
209
214
|
|
|
210
|
-
it
|
|
211
|
-
|
|
215
|
+
it "succeeds when GOOGLE_PRIVATE_KEY and GOOGLE_CLIENT_EMAIL env vars are"\
|
|
216
|
+
" valid" do
|
|
212
217
|
ENV[PRIVATE_KEY_VAR] = cred_json[:private_key]
|
|
213
218
|
ENV[CLIENT_EMAIL_VAR] = cred_json[:client_email]
|
|
214
219
|
expect(@clz.from_env(@scope)).to_not be_nil
|
|
215
220
|
end
|
|
216
221
|
|
|
217
|
-
it
|
|
222
|
+
it "sets project_id when the PROJECT_ID_VAR env var is set" do
|
|
218
223
|
ENV[PRIVATE_KEY_VAR] = cred_json[:private_key]
|
|
219
224
|
ENV[CLIENT_EMAIL_VAR] = cred_json[:client_email]
|
|
220
225
|
ENV[PROJECT_ID_VAR] = cred_json[:project_id]
|
|
221
226
|
ENV[ENV_VAR] = nil
|
|
222
|
-
credentials = @clz.from_env
|
|
227
|
+
credentials = @clz.from_env @scope
|
|
223
228
|
expect(credentials.project_id).to eq(cred_json[:project_id])
|
|
224
229
|
end
|
|
225
230
|
|
|
226
|
-
it
|
|
231
|
+
it "succeeds when GOOGLE_PRIVATE_KEY is escaped" do
|
|
227
232
|
escaped_key = cred_json[:private_key].gsub "\n", '\n'
|
|
228
233
|
ENV[PRIVATE_KEY_VAR] = "\"#{escaped_key}\""
|
|
229
234
|
ENV[CLIENT_EMAIL_VAR] = cred_json[:client_email]
|
|
@@ -233,110 +238,110 @@ describe Google::Auth::ServiceAccountCredentials do
|
|
|
233
238
|
it "propagates default_connection option" do
|
|
234
239
|
ENV[PRIVATE_KEY_VAR] = cred_json[:private_key]
|
|
235
240
|
ENV[CLIENT_EMAIL_VAR] = cred_json[:client_email]
|
|
236
|
-
connection = Faraday.new
|
|
237
|
-
creds = @clz.from_env
|
|
241
|
+
connection = Faraday.new headers: { "User-Agent" => "hello" }
|
|
242
|
+
creds = @clz.from_env @scope, default_connection: connection
|
|
238
243
|
expect(creds.build_default_connection).to be connection
|
|
239
244
|
end
|
|
240
245
|
end
|
|
241
246
|
|
|
242
|
-
describe
|
|
243
|
-
before
|
|
244
|
-
@home = ENV[
|
|
245
|
-
@app_data = ENV[
|
|
246
|
-
@scope =
|
|
247
|
+
describe "#from_well_known_path" do
|
|
248
|
+
before :example do
|
|
249
|
+
@home = ENV["HOME"]
|
|
250
|
+
@app_data = ENV["APPDATA"]
|
|
251
|
+
@scope = "https://www.googleapis.com/auth/userinfo.profile"
|
|
247
252
|
@known_path = WELL_KNOWN_PATH
|
|
248
253
|
@clz = ServiceAccountCredentials
|
|
249
254
|
end
|
|
250
255
|
|
|
251
|
-
after
|
|
252
|
-
ENV[
|
|
253
|
-
ENV[
|
|
256
|
+
after :example do
|
|
257
|
+
ENV["HOME"] = @home unless @home == ENV["HOME"]
|
|
258
|
+
ENV["APPDATA"] = @app_data unless @app_data == ENV["APPDATA"]
|
|
254
259
|
end
|
|
255
260
|
|
|
256
|
-
it
|
|
257
|
-
ENV[
|
|
261
|
+
it "is nil if no file exists" do
|
|
262
|
+
ENV["HOME"] = File.dirname __FILE__
|
|
258
263
|
expect(ServiceAccountCredentials.from_well_known_path(@scope)).to be_nil
|
|
259
264
|
end
|
|
260
265
|
|
|
261
|
-
it
|
|
266
|
+
it "successfully loads the file when it is present" do
|
|
262
267
|
Dir.mktmpdir do |dir|
|
|
263
|
-
key_path = File.join
|
|
264
|
-
key_path = File.join
|
|
265
|
-
FileUtils.mkdir_p
|
|
266
|
-
File.write
|
|
267
|
-
ENV[
|
|
268
|
-
ENV[
|
|
268
|
+
key_path = File.join dir, ".config", @known_path
|
|
269
|
+
key_path = File.join dir, WELL_KNOWN_PATH if OS.windows?
|
|
270
|
+
FileUtils.mkdir_p File.dirname(key_path)
|
|
271
|
+
File.write key_path, cred_json_text
|
|
272
|
+
ENV["HOME"] = dir
|
|
273
|
+
ENV["APPDATA"] = dir
|
|
269
274
|
expect(@clz.from_well_known_path(@scope)).to_not be_nil
|
|
270
275
|
end
|
|
271
276
|
end
|
|
272
277
|
|
|
273
|
-
it
|
|
278
|
+
it "successfully sets project_id when file is present" do
|
|
274
279
|
Dir.mktmpdir do |dir|
|
|
275
|
-
key_path = File.join
|
|
276
|
-
key_path = File.join
|
|
277
|
-
FileUtils.mkdir_p
|
|
278
|
-
File.write
|
|
279
|
-
ENV[
|
|
280
|
-
ENV[
|
|
281
|
-
credentials = @clz.from_well_known_path
|
|
280
|
+
key_path = File.join dir, ".config", @known_path
|
|
281
|
+
key_path = File.join dir, WELL_KNOWN_PATH if OS.windows?
|
|
282
|
+
FileUtils.mkdir_p File.dirname(key_path)
|
|
283
|
+
File.write key_path, cred_json_text
|
|
284
|
+
ENV["HOME"] = dir
|
|
285
|
+
ENV["APPDATA"] = dir
|
|
286
|
+
credentials = @clz.from_well_known_path @scope
|
|
282
287
|
expect(credentials.project_id).to eq(cred_json[:project_id])
|
|
283
288
|
end
|
|
284
289
|
end
|
|
285
290
|
|
|
286
291
|
it "propagates default_connection option" do
|
|
287
292
|
Dir.mktmpdir do |dir|
|
|
288
|
-
key_path = File.join
|
|
289
|
-
key_path = File.join
|
|
290
|
-
FileUtils.mkdir_p
|
|
291
|
-
File.write
|
|
292
|
-
ENV[
|
|
293
|
-
ENV[
|
|
294
|
-
connection = Faraday.new
|
|
295
|
-
creds = @clz.from_well_known_path
|
|
293
|
+
key_path = File.join dir, ".config", @known_path
|
|
294
|
+
key_path = File.join dir, WELL_KNOWN_PATH if OS.windows?
|
|
295
|
+
FileUtils.mkdir_p File.dirname(key_path)
|
|
296
|
+
File.write key_path, cred_json_text
|
|
297
|
+
ENV["HOME"] = dir
|
|
298
|
+
ENV["APPDATA"] = dir
|
|
299
|
+
connection = Faraday.new headers: { "User-Agent" => "hello" }
|
|
300
|
+
creds = @clz.from_well_known_path @scope, default_connection: connection
|
|
296
301
|
expect(creds.build_default_connection).to be connection
|
|
297
302
|
end
|
|
298
303
|
end
|
|
299
304
|
end
|
|
300
305
|
|
|
301
|
-
describe
|
|
302
|
-
before
|
|
303
|
-
@scope =
|
|
304
|
-
@program_data = ENV[
|
|
305
|
-
@prefix = OS.windows? ?
|
|
306
|
-
@path = File.join
|
|
306
|
+
describe "#from_system_default_path" do
|
|
307
|
+
before :example do
|
|
308
|
+
@scope = "https://www.googleapis.com/auth/userinfo.profile"
|
|
309
|
+
@program_data = ENV["ProgramData"]
|
|
310
|
+
@prefix = OS.windows? ? "/etc/Google/Auth/" : "/etc/google/auth/"
|
|
311
|
+
@path = File.join @prefix, CREDENTIALS_FILE_NAME
|
|
307
312
|
@clz = ServiceAccountCredentials
|
|
308
313
|
end
|
|
309
314
|
|
|
310
|
-
after
|
|
311
|
-
ENV[
|
|
315
|
+
after :example do
|
|
316
|
+
ENV["ProgramData"] = @program_data
|
|
312
317
|
end
|
|
313
318
|
|
|
314
|
-
it
|
|
319
|
+
it "is nil if no file exists" do
|
|
315
320
|
FakeFS do
|
|
316
321
|
expect(ServiceAccountCredentials.from_system_default_path(@scope))
|
|
317
322
|
.to be_nil
|
|
318
323
|
end
|
|
319
324
|
end
|
|
320
325
|
|
|
321
|
-
it
|
|
326
|
+
it "successfully loads the file when it is present" do
|
|
322
327
|
FakeFS do
|
|
323
|
-
ENV[
|
|
324
|
-
FileUtils.mkdir_p
|
|
325
|
-
File.write
|
|
328
|
+
ENV["ProgramData"] = "/etc"
|
|
329
|
+
FileUtils.mkdir_p File.dirname(@path)
|
|
330
|
+
File.write @path, cred_json_text
|
|
326
331
|
expect(@clz.from_system_default_path(@scope)).to_not be_nil
|
|
327
|
-
File.delete
|
|
332
|
+
File.delete @path
|
|
328
333
|
end
|
|
329
334
|
end
|
|
330
335
|
|
|
331
336
|
it "propagates default_connection option" do
|
|
332
337
|
FakeFS do
|
|
333
|
-
ENV[
|
|
334
|
-
FileUtils.mkdir_p
|
|
335
|
-
File.write
|
|
336
|
-
connection = Faraday.new
|
|
337
|
-
creds = @clz.from_system_default_path
|
|
338
|
+
ENV["ProgramData"] = "/etc"
|
|
339
|
+
FileUtils.mkdir_p File.dirname(@path)
|
|
340
|
+
File.write @path, cred_json_text
|
|
341
|
+
connection = Faraday.new headers: { "User-Agent" => "hello" }
|
|
342
|
+
creds = @clz.from_system_default_path @scope, default_connection: connection
|
|
338
343
|
expect(creds.build_default_connection).to be connection
|
|
339
|
-
File.delete
|
|
344
|
+
File.delete @path
|
|
340
345
|
end
|
|
341
346
|
end
|
|
342
347
|
end
|
|
@@ -346,32 +351,32 @@ describe Google::Auth::ServiceAccountJwtHeaderCredentials do
|
|
|
346
351
|
ServiceAccountJwtHeaderCredentials =
|
|
347
352
|
Google::Auth::ServiceAccountJwtHeaderCredentials
|
|
348
353
|
|
|
349
|
-
let(:client_email) {
|
|
354
|
+
let(:client_email) { "app@developer.gserviceaccount.com" }
|
|
350
355
|
let(:clz) { Google::Auth::ServiceAccountJwtHeaderCredentials }
|
|
351
|
-
let
|
|
356
|
+
let :cred_json do
|
|
352
357
|
{
|
|
353
|
-
private_key_id:
|
|
354
|
-
private_key:
|
|
355
|
-
client_email:
|
|
356
|
-
client_id:
|
|
357
|
-
type:
|
|
358
|
-
project_id:
|
|
358
|
+
private_key_id: "a_private_key_id",
|
|
359
|
+
private_key: @key.to_pem,
|
|
360
|
+
client_email: client_email,
|
|
361
|
+
client_id: "app.apps.googleusercontent.com",
|
|
362
|
+
type: "service_account",
|
|
363
|
+
project_id: "a_project_id"
|
|
359
364
|
}
|
|
360
365
|
end
|
|
361
366
|
|
|
362
|
-
before
|
|
363
|
-
@key = OpenSSL::PKey::RSA.new
|
|
364
|
-
@client = clz.make_creds
|
|
367
|
+
before :example do
|
|
368
|
+
@key = OpenSSL::PKey::RSA.new 2048
|
|
369
|
+
@client = clz.make_creds json_key_io: StringIO.new(cred_json_text)
|
|
365
370
|
end
|
|
366
371
|
|
|
367
372
|
def cred_json_text
|
|
368
|
-
MultiJson.dump
|
|
373
|
+
MultiJson.dump cred_json
|
|
369
374
|
end
|
|
370
375
|
|
|
371
|
-
it_behaves_like
|
|
376
|
+
it_behaves_like "jwt header auth"
|
|
372
377
|
|
|
373
|
-
describe
|
|
374
|
-
before
|
|
378
|
+
describe "#from_env" do
|
|
379
|
+
before :example do
|
|
375
380
|
@var_name = ENV_VAR
|
|
376
381
|
@credential_vars = [
|
|
377
382
|
ENV_VAR, PRIVATE_KEY_VAR, CLIENT_EMAIL_VAR, ACCOUNT_TYPE_VAR
|
|
@@ -381,90 +386,95 @@ describe Google::Auth::ServiceAccountJwtHeaderCredentials do
|
|
|
381
386
|
ENV[ACCOUNT_TYPE_VAR] = cred_json[:type]
|
|
382
387
|
end
|
|
383
388
|
|
|
384
|
-
after
|
|
389
|
+
after :example do
|
|
385
390
|
@credential_vars.each { |var| ENV[var] = @original_env_vals[var] }
|
|
386
391
|
end
|
|
387
392
|
|
|
388
|
-
it
|
|
389
|
-
ENV.delete
|
|
393
|
+
it "returns nil if the GOOGLE_APPLICATION_CREDENTIALS is unset" do
|
|
394
|
+
ENV.delete @var_name unless ENV[@var_name].nil?
|
|
395
|
+
expect(clz.from_env).to be_nil
|
|
396
|
+
end
|
|
397
|
+
|
|
398
|
+
it "returns nil if the GOOGLE_APPLICATION_CREDENTIALS is empty" do
|
|
399
|
+
ENV[@var_name] = ""
|
|
390
400
|
expect(clz.from_env).to be_nil
|
|
391
401
|
end
|
|
392
402
|
|
|
393
|
-
it
|
|
394
|
-
ENV.delete
|
|
403
|
+
it "fails if the GOOGLE_APPLICATION_CREDENTIALS path does not exist" do
|
|
404
|
+
ENV.delete @var_name unless ENV[@var_name].nil?
|
|
395
405
|
expect(clz.from_env).to be_nil
|
|
396
406
|
Dir.mktmpdir do |dir|
|
|
397
|
-
key_path = File.join
|
|
407
|
+
key_path = File.join dir, "does-not-exist"
|
|
398
408
|
ENV[@var_name] = key_path
|
|
399
409
|
expect { clz.from_env }.to raise_error RuntimeError
|
|
400
410
|
end
|
|
401
411
|
end
|
|
402
412
|
|
|
403
|
-
it
|
|
413
|
+
it "succeeds when the GOOGLE_APPLICATION_CREDENTIALS file is valid" do
|
|
404
414
|
Dir.mktmpdir do |dir|
|
|
405
|
-
key_path = File.join
|
|
406
|
-
FileUtils.mkdir_p
|
|
407
|
-
File.write
|
|
415
|
+
key_path = File.join dir, "my_cert_file"
|
|
416
|
+
FileUtils.mkdir_p File.dirname(key_path)
|
|
417
|
+
File.write key_path, cred_json_text
|
|
408
418
|
ENV[@var_name] = key_path
|
|
409
419
|
expect(clz.from_env).to_not be_nil
|
|
410
420
|
end
|
|
411
421
|
end
|
|
412
422
|
|
|
413
|
-
it
|
|
414
|
-
|
|
423
|
+
it "succeeds when GOOGLE_PRIVATE_KEY and GOOGLE_CLIENT_EMAIL env vars are"\
|
|
424
|
+
" valid" do
|
|
415
425
|
ENV[PRIVATE_KEY_VAR] = cred_json[:private_key]
|
|
416
426
|
ENV[CLIENT_EMAIL_VAR] = cred_json[:client_email]
|
|
417
427
|
expect(clz.from_env(@scope)).to_not be_nil
|
|
418
428
|
end
|
|
419
429
|
|
|
420
|
-
it
|
|
430
|
+
it "sets project_id when the PROJECT_ID_VAR env var is set" do
|
|
421
431
|
ENV[PRIVATE_KEY_VAR] = cred_json[:private_key]
|
|
422
432
|
ENV[CLIENT_EMAIL_VAR] = cred_json[:client_email]
|
|
423
433
|
ENV[PROJECT_ID_VAR] = cred_json[:project_id]
|
|
424
434
|
ENV[ENV_VAR] = nil
|
|
425
|
-
credentials = clz.from_env
|
|
435
|
+
credentials = clz.from_env @scope
|
|
426
436
|
expect(credentials).to_not be_nil
|
|
427
437
|
expect(credentials.project_id).to eq(cred_json[:project_id])
|
|
428
438
|
end
|
|
429
439
|
end
|
|
430
440
|
|
|
431
|
-
describe
|
|
432
|
-
before
|
|
433
|
-
@home = ENV[
|
|
434
|
-
@app_data = ENV[
|
|
441
|
+
describe "#from_well_known_path" do
|
|
442
|
+
before :example do
|
|
443
|
+
@home = ENV["HOME"]
|
|
444
|
+
@app_data = ENV["APPDATA"]
|
|
435
445
|
end
|
|
436
446
|
|
|
437
|
-
after
|
|
438
|
-
ENV[
|
|
439
|
-
ENV[
|
|
447
|
+
after :example do
|
|
448
|
+
ENV["HOME"] = @home unless @home == ENV["HOME"]
|
|
449
|
+
ENV["APPDATA"] = @app_data unless @app_data == ENV["APPDATA"]
|
|
440
450
|
end
|
|
441
451
|
|
|
442
|
-
it
|
|
443
|
-
ENV[
|
|
452
|
+
it "is nil if no file exists" do
|
|
453
|
+
ENV["HOME"] = File.dirname __FILE__
|
|
444
454
|
expect(clz.from_well_known_path).to be_nil
|
|
445
455
|
end
|
|
446
456
|
|
|
447
|
-
it
|
|
457
|
+
it "successfully loads the file when it is present" do
|
|
448
458
|
Dir.mktmpdir do |dir|
|
|
449
|
-
key_path = File.join
|
|
450
|
-
key_path = File.join
|
|
451
|
-
FileUtils.mkdir_p
|
|
452
|
-
File.write
|
|
453
|
-
ENV[
|
|
454
|
-
ENV[
|
|
459
|
+
key_path = File.join dir, ".config", WELL_KNOWN_PATH
|
|
460
|
+
key_path = File.join dir, WELL_KNOWN_PATH if OS.windows?
|
|
461
|
+
FileUtils.mkdir_p File.dirname(key_path)
|
|
462
|
+
File.write key_path, cred_json_text
|
|
463
|
+
ENV["HOME"] = dir
|
|
464
|
+
ENV["APPDATA"] = dir
|
|
455
465
|
expect(clz.from_well_known_path).to_not be_nil
|
|
456
466
|
end
|
|
457
467
|
end
|
|
458
468
|
|
|
459
|
-
it
|
|
469
|
+
it "successfully sets project_id when file is present" do
|
|
460
470
|
Dir.mktmpdir do |dir|
|
|
461
|
-
key_path = File.join
|
|
462
|
-
key_path = File.join
|
|
463
|
-
FileUtils.mkdir_p
|
|
464
|
-
File.write
|
|
465
|
-
ENV[
|
|
466
|
-
ENV[
|
|
467
|
-
credentials = clz.from_well_known_path
|
|
471
|
+
key_path = File.join dir, ".config", WELL_KNOWN_PATH
|
|
472
|
+
key_path = File.join dir, WELL_KNOWN_PATH if OS.windows?
|
|
473
|
+
FileUtils.mkdir_p File.dirname(key_path)
|
|
474
|
+
File.write key_path, cred_json_text
|
|
475
|
+
ENV["HOME"] = dir
|
|
476
|
+
ENV["APPDATA"] = dir
|
|
477
|
+
credentials = clz.from_well_known_path @scope
|
|
468
478
|
expect(credentials.project_id).to eq(cred_json[:project_id])
|
|
469
479
|
end
|
|
470
480
|
end
|