googleauth 0.4.2 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop_todo.yml +23 -6
- data/.travis.yml +3 -0
- data/CHANGELOG.md +8 -1
- data/Gemfile +20 -0
- data/README.md +80 -1
- data/googleauth.gemspec +1 -9
- data/lib/googleauth.rb +6 -3
- data/lib/googleauth/client_id.rb +102 -0
- data/lib/googleauth/scope_util.rb +61 -0
- data/lib/googleauth/service_account.rb +23 -18
- data/lib/googleauth/signet.rb +20 -1
- data/lib/googleauth/stores/file_token_store.rb +64 -0
- data/lib/googleauth/stores/redis_token_store.rb +95 -0
- data/lib/googleauth/token_store.rb +69 -0
- data/lib/googleauth/user_authorizer.rb +273 -0
- data/lib/googleauth/user_refresh.rb +53 -16
- data/lib/googleauth/version.rb +1 -1
- data/lib/googleauth/web_user_authorizer.rb +289 -0
- data/spec/googleauth/apply_auth_examples.rb +36 -58
- data/spec/googleauth/client_id_spec.rb +140 -0
- data/spec/googleauth/compute_engine_spec.rb +34 -71
- data/spec/googleauth/get_application_default_spec.rb +26 -35
- data/spec/googleauth/scope_util_spec.rb +75 -0
- data/spec/googleauth/service_account_spec.rb +16 -11
- data/spec/googleauth/signet_spec.rb +14 -9
- data/spec/googleauth/stores/file_token_store_spec.rb +58 -0
- data/spec/googleauth/stores/redis_token_store_spec.rb +50 -0
- data/spec/googleauth/stores/store_examples.rb +58 -0
- data/spec/googleauth/user_authorizer_spec.rb +314 -0
- data/spec/googleauth/user_refresh_spec.rb +77 -13
- data/spec/googleauth/web_user_authorizer_spec.rb +159 -0
- data/spec/spec_helper.rb +33 -1
- metadata +37 -113
@@ -0,0 +1,140 @@
|
|
1
|
+
# Copyright 2015, Google Inc.
|
2
|
+
# All rights reserved.
|
3
|
+
#
|
4
|
+
# Redistribution and use in source and binary forms, with or without
|
5
|
+
# modification, are permitted provided that the following conditions are
|
6
|
+
# met:
|
7
|
+
#
|
8
|
+
# * Redistributions of source code must retain the above copyright
|
9
|
+
# notice, this list of conditions and the following disclaimer.
|
10
|
+
# * Redistributions in binary form must reproduce the above
|
11
|
+
# copyright notice, this list of conditions and the following disclaimer
|
12
|
+
# in the documentation and/or other materials provided with the
|
13
|
+
# distribution.
|
14
|
+
# * Neither the name of Google Inc. nor the names of its
|
15
|
+
# contributors may be used to endorse or promote products derived from
|
16
|
+
# this software without specific prior written permission.
|
17
|
+
#
|
18
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
19
|
+
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
20
|
+
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
21
|
+
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
22
|
+
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
23
|
+
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
24
|
+
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
25
|
+
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
26
|
+
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
27
|
+
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
28
|
+
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
29
|
+
|
30
|
+
spec_dir = File.expand_path(File.join(File.dirname(__FILE__)))
|
31
|
+
$LOAD_PATH.unshift(spec_dir)
|
32
|
+
$LOAD_PATH.uniq!
|
33
|
+
|
34
|
+
require 'spec_helper'
|
35
|
+
require 'fakefs/safe'
|
36
|
+
require 'googleauth'
|
37
|
+
|
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'
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'should include a valid secret' do
|
45
|
+
expect(client_id.secret).to eql 'notasecret'
|
46
|
+
end
|
47
|
+
end
|
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) }
|
52
|
+
|
53
|
+
it_behaves_like 'it has a valid config'
|
54
|
+
end
|
55
|
+
|
56
|
+
context 'loaded from file' do
|
57
|
+
file_path = '/client_secrets.json'
|
58
|
+
|
59
|
+
let(:client_id) do
|
60
|
+
FakeFS do
|
61
|
+
content = MultiJson.dump(config)
|
62
|
+
File.write(file_path, content)
|
63
|
+
Google::Auth::ClientId.from_file(file_path)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
it_behaves_like 'it has a valid config'
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
describe 'with web config' do
|
72
|
+
let(:config) do
|
73
|
+
{
|
74
|
+
'web' => {
|
75
|
+
'client_id' => 'abc@example.com',
|
76
|
+
'client_secret' => 'notasecret'
|
77
|
+
}
|
78
|
+
}
|
79
|
+
end
|
80
|
+
it_behaves_like 'it can successfully load client_id'
|
81
|
+
end
|
82
|
+
|
83
|
+
describe 'with installed app config' do
|
84
|
+
let(:config) do
|
85
|
+
{
|
86
|
+
'installed' => {
|
87
|
+
'client_id' => 'abc@example.com',
|
88
|
+
'client_secret' => 'notasecret'
|
89
|
+
}
|
90
|
+
}
|
91
|
+
end
|
92
|
+
it_behaves_like 'it can successfully load client_id'
|
93
|
+
end
|
94
|
+
|
95
|
+
context 'with missing top level property' do
|
96
|
+
let(:config) do
|
97
|
+
{
|
98
|
+
'notvalid' => {
|
99
|
+
'client_id' => 'abc@example.com',
|
100
|
+
'client_secret' => 'notasecret'
|
101
|
+
}
|
102
|
+
}
|
103
|
+
end
|
104
|
+
|
105
|
+
it 'should raise error' do
|
106
|
+
expect { Google::Auth::ClientId.from_hash(config) }.to raise_error(
|
107
|
+
/Expected top level property/)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
context 'with missing client id' do
|
112
|
+
let(:config) do
|
113
|
+
{
|
114
|
+
'web' => {
|
115
|
+
'client_secret' => 'notasecret'
|
116
|
+
}
|
117
|
+
}
|
118
|
+
end
|
119
|
+
|
120
|
+
it 'should raise error' do
|
121
|
+
expect { Google::Auth::ClientId.from_hash(config) }.to raise_error(
|
122
|
+
/Client id can not be nil/)
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
context 'with missing client secret' do
|
127
|
+
let(:config) do
|
128
|
+
{
|
129
|
+
'web' => {
|
130
|
+
'client_id' => 'abc@example.com'
|
131
|
+
}
|
132
|
+
}
|
133
|
+
end
|
134
|
+
|
135
|
+
it 'should raise error' do
|
136
|
+
expect { Google::Auth::ClientId.from_hash(config) }.to raise_error(
|
137
|
+
/Client secret can not be nil/)
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
@@ -37,7 +37,7 @@ require 'googleauth/compute_engine'
|
|
37
37
|
require 'spec_helper'
|
38
38
|
|
39
39
|
describe Google::Auth::GCECredentials do
|
40
|
-
MD_URI = '/computeMetadata/v1/instance/service-accounts/default/token'
|
40
|
+
MD_URI = 'http://169.254.169.254/computeMetadata/v1/instance/service-accounts/default/token'
|
41
41
|
GCECredentials = Google::Auth::GCECredentials
|
42
42
|
|
43
43
|
before(:example) do
|
@@ -46,16 +46,14 @@ describe Google::Auth::GCECredentials do
|
|
46
46
|
|
47
47
|
def make_auth_stubs(opts = {})
|
48
48
|
access_token = opts[:access_token] || ''
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
end
|
58
|
-
end
|
49
|
+
body = MultiJson.dump('access_token' => access_token,
|
50
|
+
'token_type' => 'Bearer',
|
51
|
+
'expires_in' => 3600)
|
52
|
+
stub_request(:get, MD_URI)
|
53
|
+
.with(headers: { 'Metadata-Flavor' => 'Google' })
|
54
|
+
.to_return(body: body,
|
55
|
+
status: 200,
|
56
|
+
headers: { 'Content-Type' => 'application/json' })
|
59
57
|
end
|
60
58
|
|
61
59
|
it_behaves_like 'apply/apply! are OK'
|
@@ -63,83 +61,48 @@ describe Google::Auth::GCECredentials do
|
|
63
61
|
context 'metadata is unavailable' do
|
64
62
|
describe '#fetch_access_token' do
|
65
63
|
it 'should fail if the metadata request returns a 404' do
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
'']
|
71
|
-
end
|
72
|
-
end
|
73
|
-
c = Faraday.new do |b|
|
74
|
-
b.adapter(:test, stubs)
|
75
|
-
end
|
76
|
-
blk = proc { @client.fetch_access_token!(connection: c) }
|
64
|
+
stub = stub_request(:get, MD_URI)
|
65
|
+
.to_return(status: 404,
|
66
|
+
headers: { 'Metadata-Flavor' => 'Google' })
|
67
|
+
blk = proc { @client.fetch_access_token! }
|
77
68
|
expect(&blk).to raise_error Signet::AuthorizationError
|
78
|
-
|
69
|
+
expect(stub).to have_been_requested
|
79
70
|
end
|
80
71
|
|
81
72
|
it 'should fail if the metadata request returns an unexpected code' do
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
'']
|
87
|
-
end
|
88
|
-
end
|
89
|
-
c = Faraday.new do |b|
|
90
|
-
b.adapter(:test, stubs)
|
91
|
-
end
|
92
|
-
blk = proc { @client.fetch_access_token!(connection: c) }
|
73
|
+
stub = stub_request(:get, MD_URI)
|
74
|
+
.to_return(status: 503,
|
75
|
+
headers: { 'Metadata-Flavor' => 'Google' })
|
76
|
+
blk = proc { @client.fetch_access_token! }
|
93
77
|
expect(&blk).to raise_error Signet::AuthorizationError
|
94
|
-
|
78
|
+
expect(stub).to have_been_requested
|
95
79
|
end
|
96
80
|
end
|
97
81
|
end
|
98
82
|
|
99
83
|
describe '#on_gce?' do
|
100
84
|
it 'should be true when Metadata-Flavor is Google' do
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
end
|
107
|
-
end
|
108
|
-
c = Faraday.new do |b|
|
109
|
-
b.adapter(:test, stubs)
|
110
|
-
end
|
111
|
-
expect(GCECredentials.on_gce?(connection: c)).to eq(true)
|
112
|
-
stubs.verify_stubbed_calls
|
85
|
+
stub = stub_request(:get, 'http://169.254.169.254')
|
86
|
+
.to_return(status: 200,
|
87
|
+
headers: { 'Metadata-Flavor' => 'Google' })
|
88
|
+
expect(GCECredentials.on_gce?({}, true)).to eq(true)
|
89
|
+
expect(stub).to have_been_requested
|
113
90
|
end
|
114
91
|
|
115
92
|
it 'should be false when Metadata-Flavor is not Google' do
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
end
|
122
|
-
end
|
123
|
-
c = Faraday.new do |b|
|
124
|
-
b.adapter(:test, stubs)
|
125
|
-
end
|
126
|
-
expect(GCECredentials.on_gce?(connection: c)).to eq(false)
|
127
|
-
stubs.verify_stubbed_calls
|
93
|
+
stub = stub_request(:get, 'http://169.254.169.254')
|
94
|
+
.to_return(status: 200,
|
95
|
+
headers: { 'Metadata-Flavor' => 'NotGoogle' })
|
96
|
+
expect(GCECredentials.on_gce?({}, true)).to eq(false)
|
97
|
+
expect(stub).to have_been_requested
|
128
98
|
end
|
129
99
|
|
130
100
|
it 'should be false if the response is not 200' do
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
end
|
137
|
-
end
|
138
|
-
c = Faraday.new do |b|
|
139
|
-
b.adapter(:test, stubs)
|
140
|
-
end
|
141
|
-
expect(GCECredentials.on_gce?(connection: c)).to eq(false)
|
142
|
-
stubs.verify_stubbed_calls
|
101
|
+
stub = stub_request(:get, 'http://169.254.169.254')
|
102
|
+
.to_return(status: 404,
|
103
|
+
headers: { 'Metadata-Flavor' => 'NotGoogle' })
|
104
|
+
expect(GCECredentials.on_gce?({}, true)).to eq(false)
|
105
|
+
expect(stub).to have_been_requested
|
143
106
|
end
|
144
107
|
end
|
145
108
|
end
|
@@ -37,6 +37,9 @@ require 'googleauth'
|
|
37
37
|
require 'spec_helper'
|
38
38
|
|
39
39
|
describe '#get_application_default' do
|
40
|
+
# Pass unique options each time to bypass memoization
|
41
|
+
let(:options) { |example| { dememoize: example } }
|
42
|
+
|
40
43
|
before(:example) do
|
41
44
|
@key = OpenSSL::PKey::RSA.new(2048)
|
42
45
|
@var_name = ENV_VAR
|
@@ -59,31 +62,24 @@ describe '#get_application_default' do
|
|
59
62
|
Dir.mktmpdir do |dir|
|
60
63
|
key_path = File.join(dir, 'does-not-exist')
|
61
64
|
ENV[@var_name] = key_path
|
62
|
-
expect { Google::Auth.get_application_default(@scope) }
|
65
|
+
expect { Google::Auth.get_application_default(@scope, options) }
|
63
66
|
.to raise_error RuntimeError
|
64
67
|
end
|
65
68
|
end
|
66
69
|
|
67
70
|
it 'fails without default file or env if not on compute engine' do
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
{ 'Metadata-Flavor' => 'Google' },
|
72
|
-
'']
|
73
|
-
end
|
74
|
-
end # GCE not detected
|
71
|
+
stub = stub_request(:get, 'http://169.254.169.254')
|
72
|
+
.to_return(status: 404,
|
73
|
+
headers: { 'Metadata-Flavor' => 'NotGoogle' })
|
75
74
|
Dir.mktmpdir do |dir|
|
76
75
|
ENV.delete(@var_name) unless ENV[@var_name].nil? # no env var
|
77
76
|
ENV['HOME'] = dir # no config present in this tmp dir
|
78
|
-
c = Faraday.new do |b|
|
79
|
-
b.adapter(:test, stubs)
|
80
|
-
end
|
81
77
|
blk = proc do
|
82
|
-
Google::Auth.get_application_default(@scope,
|
78
|
+
Google::Auth.get_application_default(@scope, options)
|
83
79
|
end
|
84
80
|
expect(&blk).to raise_error RuntimeError
|
85
81
|
end
|
86
|
-
|
82
|
+
expect(stub).to have_been_requested
|
87
83
|
end
|
88
84
|
end
|
89
85
|
|
@@ -94,7 +90,8 @@ describe '#get_application_default' do
|
|
94
90
|
FileUtils.mkdir_p(File.dirname(key_path))
|
95
91
|
File.write(key_path, cred_json_text)
|
96
92
|
ENV[@var_name] = key_path
|
97
|
-
expect(Google::Auth.get_application_default(@scope))
|
93
|
+
expect(Google::Auth.get_application_default(@scope, options))
|
94
|
+
.to_not be_nil
|
98
95
|
end
|
99
96
|
end
|
100
97
|
|
@@ -105,7 +102,8 @@ describe '#get_application_default' do
|
|
105
102
|
FileUtils.mkdir_p(File.dirname(key_path))
|
106
103
|
File.write(key_path, cred_json_text)
|
107
104
|
ENV['HOME'] = dir
|
108
|
-
expect(Google::Auth.get_application_default(@scope))
|
105
|
+
expect(Google::Auth.get_application_default(@scope, options))
|
106
|
+
.to_not be_nil
|
109
107
|
end
|
110
108
|
end
|
111
109
|
|
@@ -116,30 +114,21 @@ describe '#get_application_default' do
|
|
116
114
|
FileUtils.mkdir_p(File.dirname(key_path))
|
117
115
|
File.write(key_path, cred_json_text)
|
118
116
|
ENV['HOME'] = dir
|
119
|
-
expect(Google::Auth.get_application_default).to_not be_nil
|
117
|
+
expect(Google::Auth.get_application_default(nil, options)).to_not be_nil
|
120
118
|
end
|
121
119
|
end
|
122
120
|
|
123
121
|
it 'succeeds without default file or env if on compute engine' do
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
{ 'Metadata-Flavor' => 'Google' },
|
128
|
-
'']
|
129
|
-
end
|
130
|
-
end # GCE detected
|
122
|
+
stub = stub_request(:get, 'http://169.254.169.254')
|
123
|
+
.to_return(status: 200,
|
124
|
+
headers: { 'Metadata-Flavor' => 'Google' })
|
131
125
|
Dir.mktmpdir do |dir|
|
132
126
|
ENV.delete(@var_name) unless ENV[@var_name].nil? # no env var
|
133
127
|
ENV['HOME'] = dir # no config present in this tmp dir
|
134
|
-
|
135
|
-
b.adapter(:test, stubs)
|
136
|
-
end
|
137
|
-
creds = Google::Auth.get_application_default(
|
138
|
-
@scope,
|
139
|
-
connection: c)
|
128
|
+
creds = Google::Auth.get_application_default(@scope, options)
|
140
129
|
expect(creds).to_not be_nil
|
141
130
|
end
|
142
|
-
|
131
|
+
expect(stub).to have_been_requested
|
143
132
|
end
|
144
133
|
|
145
134
|
it 'succeeds with system default file' do
|
@@ -148,7 +137,8 @@ describe '#get_application_default' do
|
|
148
137
|
key_path = File.join('/etc/google/auth/', CREDENTIALS_FILE_NAME)
|
149
138
|
FileUtils.mkdir_p(File.dirname(key_path))
|
150
139
|
File.write(key_path, cred_json_text)
|
151
|
-
expect(Google::Auth.get_application_default(@scope))
|
140
|
+
expect(Google::Auth.get_application_default(@scope, options))
|
141
|
+
.to_not be_nil
|
152
142
|
File.delete(key_path)
|
153
143
|
end
|
154
144
|
end
|
@@ -161,7 +151,8 @@ describe '#get_application_default' do
|
|
161
151
|
ENV[CLIENT_SECRET_VAR] = cred_json[:client_secret]
|
162
152
|
ENV[REFRESH_TOKEN_VAR] = cred_json[:refresh_token]
|
163
153
|
ENV[ACCOUNT_TYPE_VAR] = cred_json[:type]
|
164
|
-
expect(Google::Auth.get_application_default(@scope))
|
154
|
+
expect(Google::Auth.get_application_default(@scope, options))
|
155
|
+
.to_not be_nil
|
165
156
|
end
|
166
157
|
end
|
167
158
|
|
@@ -225,7 +216,7 @@ describe '#get_application_default' do
|
|
225
216
|
File.write(key_path, cred_json_text)
|
226
217
|
ENV[@var_name] = key_path
|
227
218
|
blk = proc do
|
228
|
-
Google::Auth.get_application_default(@scope)
|
219
|
+
Google::Auth.get_application_default(@scope, options)
|
229
220
|
end
|
230
221
|
expect(&blk).to raise_error RuntimeError
|
231
222
|
end
|
@@ -239,7 +230,7 @@ describe '#get_application_default' do
|
|
239
230
|
File.write(key_path, cred_json_text)
|
240
231
|
ENV['HOME'] = dir
|
241
232
|
blk = proc do
|
242
|
-
Google::Auth.get_application_default(@scope)
|
233
|
+
Google::Auth.get_application_default(@scope, options)
|
243
234
|
end
|
244
235
|
expect(&blk).to raise_error RuntimeError
|
245
236
|
end
|
@@ -249,7 +240,7 @@ describe '#get_application_default' do
|
|
249
240
|
ENV[PRIVATE_KEY_VAR] = cred_json[:private_key]
|
250
241
|
ENV[CLIENT_EMAIL_VAR] = cred_json[:client_email]
|
251
242
|
blk = proc do
|
252
|
-
Google::Auth.get_application_default(@scope)
|
243
|
+
Google::Auth.get_application_default(@scope, options)
|
253
244
|
end
|
254
245
|
expect(&blk).to raise_error RuntimeError
|
255
246
|
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
# Copyright 2015, Google Inc.
|
2
|
+
# All rights reserved.
|
3
|
+
#
|
4
|
+
# Redistribution and use in source and binary forms, with or without
|
5
|
+
# modification, are permitted provided that the following conditions are
|
6
|
+
# met:
|
7
|
+
#
|
8
|
+
# * Redistributions of source code must retain the above copyright
|
9
|
+
# notice, this list of conditions and the following disclaimer.
|
10
|
+
# * Redistributions in binary form must reproduce the above
|
11
|
+
# copyright notice, this list of conditions and the following disclaimer
|
12
|
+
# in the documentation and/or other materials provided with the
|
13
|
+
# distribution.
|
14
|
+
# * Neither the name of Google Inc. nor the names of its
|
15
|
+
# contributors may be used to endorse or promote products derived from
|
16
|
+
# this software without specific prior written permission.
|
17
|
+
#
|
18
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
19
|
+
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
20
|
+
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
21
|
+
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
22
|
+
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
23
|
+
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
24
|
+
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
25
|
+
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
26
|
+
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
27
|
+
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
28
|
+
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
29
|
+
|
30
|
+
spec_dir = File.expand_path(File.join(File.dirname(__FILE__)))
|
31
|
+
$LOAD_PATH.unshift(spec_dir)
|
32
|
+
$LOAD_PATH.uniq!
|
33
|
+
|
34
|
+
require 'googleauth/scope_util'
|
35
|
+
|
36
|
+
describe Google::Auth::ScopeUtil do
|
37
|
+
shared_examples 'normalizes scopes' do
|
38
|
+
let(:normalized) { Google::Auth::ScopeUtil.normalize(source) }
|
39
|
+
|
40
|
+
it 'normalizes the email scope' do
|
41
|
+
expect(normalized).to include(
|
42
|
+
'https://www.googleapis.com/auth/userinfo.email')
|
43
|
+
expect(normalized).to_not include 'email'
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'normalizes the profile scope' do
|
47
|
+
expect(normalized).to include(
|
48
|
+
'https://www.googleapis.com/auth/userinfo.profile')
|
49
|
+
expect(normalized).to_not include 'profile'
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'normalizes the openid scope' do
|
53
|
+
expect(normalized).to include 'https://www.googleapis.com/auth/plus.me'
|
54
|
+
expect(normalized).to_not include 'openid'
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'leaves other other scopes as-is' do
|
58
|
+
expect(normalized).to include 'https://www.googleapis.com/auth/drive'
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
context 'with scope as string' do
|
63
|
+
let(:source) do
|
64
|
+
'email profile openid https://www.googleapis.com/auth/drive'
|
65
|
+
end
|
66
|
+
it_behaves_like 'normalizes scopes'
|
67
|
+
end
|
68
|
+
|
69
|
+
context 'with scope as Array' do
|
70
|
+
let(:source) do
|
71
|
+
%w(email profile openid https://www.googleapis.com/auth/drive)
|
72
|
+
end
|
73
|
+
it_behaves_like 'normalizes scopes'
|
74
|
+
end
|
75
|
+
end
|