googleauth 0.4.2 → 0.5.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.
- 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
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ea1a2e263bd1d7876d89a72efe9c3a7d7059865c
|
4
|
+
data.tar.gz: d50f82ec16c2af13c46254705101efa26cc407c0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 56c038dfecebcf7239404231372e79fbd626f18cc833291ab83caaf81f8f3b8579b4ec7b38ceb670a0b44e8b155290333c52569ce664a52dc67bb08637a36fcd
|
7
|
+
data.tar.gz: d23147ecd1ba999174ead84aa967be369a6aa7c77f85505c18f600ab47b390fc356668bf495e38e49909beed9958e471bdb6148a2c58b202857d7ea713c06529
|
data/.rubocop_todo.yml
CHANGED
@@ -1,15 +1,32 @@
|
|
1
|
-
# This configuration was generated by
|
2
|
-
#
|
1
|
+
# This configuration was generated by
|
2
|
+
# `rubocop --auto-gen-config`
|
3
|
+
# on 2015-10-14 13:50:41 -0700 using RuboCop version 0.34.2.
|
3
4
|
# The point is for the user to remove these configuration records
|
4
5
|
# one by one as the offenses are removed from the code base.
|
5
6
|
# Note that changes in the inspected code, or installation of new
|
6
7
|
# versions of RuboCop, may require this file to be generated again.
|
7
8
|
|
8
|
-
# Offense count:
|
9
|
+
# Offense count: 4
|
9
10
|
Metrics/AbcSize:
|
10
|
-
Max:
|
11
|
+
Max: 27
|
11
12
|
|
12
|
-
# Offense count:
|
13
|
+
# Offense count: 1
|
14
|
+
# Configuration parameters: CountComments.
|
15
|
+
Metrics/ClassLength:
|
16
|
+
Max: 109
|
17
|
+
|
18
|
+
# Offense count: 1
|
19
|
+
Metrics/CyclomaticComplexity:
|
20
|
+
Max: 7
|
21
|
+
|
22
|
+
# Offense count: 16
|
13
23
|
# Configuration parameters: CountComments.
|
14
24
|
Metrics/MethodLength:
|
15
|
-
Max:
|
25
|
+
Max: 22
|
26
|
+
|
27
|
+
# Offense count: 2
|
28
|
+
# Configuration parameters: EnforcedStyle, SupportedStyles.
|
29
|
+
Style/FormatString:
|
30
|
+
Exclude:
|
31
|
+
- 'lib/googleauth/user_authorizer.rb'
|
32
|
+
- 'lib/googleauth/web_user_authorizer.rb'
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,8 +1,15 @@
|
|
1
|
+
## 0.5.0 (12/10/2015)
|
2
|
+
|
3
|
+
### Changes
|
4
|
+
|
5
|
+
* Initial support for user credentials ([@sqrrrl][])
|
6
|
+
* Update Signet to 0.7
|
7
|
+
|
1
8
|
## 0.4.2 (05/08/2015)
|
2
9
|
|
3
10
|
### Changes
|
4
11
|
|
5
|
-
* Updated UserRefreshCredentials hash to use string keys ([@
|
12
|
+
* Updated UserRefreshCredentials hash to use string keys ([@haabaato][])
|
6
13
|
[#36](https://github.com/google/google-auth-library-ruby/issues/36)
|
7
14
|
|
8
15
|
* Add support for a system default credentials file. ([@mr-salty][])
|
data/Gemfile
CHANGED
@@ -2,3 +2,23 @@ source 'https://rubygems.org'
|
|
2
2
|
|
3
3
|
# Specify your gem's dependencies in googleauth.gemspec
|
4
4
|
gemspec
|
5
|
+
|
6
|
+
group :development do
|
7
|
+
gem 'bundler', '~> 1.9'
|
8
|
+
gem 'simplecov', '~> 0.9'
|
9
|
+
gem 'coveralls', '~> 0.7'
|
10
|
+
gem 'fakefs', '~> 0.6'
|
11
|
+
gem 'rake', '~> 10.0'
|
12
|
+
gem 'rubocop', '~> 0.30'
|
13
|
+
gem 'rspec', '~> 3.0'
|
14
|
+
gem 'redis', '~> 3.2'
|
15
|
+
gem 'fakeredis', '~> 0.5'
|
16
|
+
gem 'webmock', '~> 1.21'
|
17
|
+
gem 'rack-test', '~> 0.6'
|
18
|
+
gem 'sinatra'
|
19
|
+
end
|
20
|
+
|
21
|
+
platforms :jruby do
|
22
|
+
group :development do
|
23
|
+
end
|
24
|
+
end
|
data/README.md
CHANGED
@@ -38,7 +38,8 @@ $ gem install googleauth
|
|
38
38
|
require 'googleauth'
|
39
39
|
|
40
40
|
# Get the environment configured authorization
|
41
|
-
scopes = ['https://www.googleapis.com/auth/cloud-platform',
|
41
|
+
scopes = ['https://www.googleapis.com/auth/cloud-platform',
|
42
|
+
'https://www.googleapis.com/auth/compute']
|
42
43
|
authorization = Google::Auth.get_application_default(scopes)
|
43
44
|
|
44
45
|
# Add the the access token obtained using the authorization to a hash, e.g
|
@@ -61,6 +62,84 @@ and authorization level for the application independent of the user. This is
|
|
61
62
|
the recommended approach to authorize calls to Cloud APIs, particularly when
|
62
63
|
you're building an application that uses Google Compute Engine.
|
63
64
|
|
65
|
+
## User Credentials
|
66
|
+
|
67
|
+
The library also provides support for requesting and storing user
|
68
|
+
credentials (3-Legged OAuth2.) Two implementations are currently available,
|
69
|
+
a generic authorizer useful for command line apps or custom integrations as
|
70
|
+
well as a web variant tailored toward Rack-based applications.
|
71
|
+
|
72
|
+
The authorizers are intended for authorization use cases. For sign-on,
|
73
|
+
see [Google Idenity Platform](https://developers.google.com/identity/)
|
74
|
+
|
75
|
+
### Example (Web)
|
76
|
+
|
77
|
+
```ruby
|
78
|
+
require 'googleauth'
|
79
|
+
require 'googleauth/web_user_authorizer'
|
80
|
+
require 'googleauth/stores/redis_token_store'
|
81
|
+
require 'redis'
|
82
|
+
|
83
|
+
client_id = Google::Auth::ClientId.from_file('/path/to/client_secrets.json')
|
84
|
+
scope = ['https://www.googleapis.com/auth/drive']
|
85
|
+
token_store = Google::Auth::Stores::RedisTokenStore.new(redis: Redis.new)
|
86
|
+
authorizer = Google::Auth::WebUserAuthorizer.new(
|
87
|
+
client_id, scope, token_store, '/oauth2callback')
|
88
|
+
|
89
|
+
|
90
|
+
get('/authorize') do
|
91
|
+
# NOTE: Assumes the user is already authenticated to the app
|
92
|
+
user_id = request.session['user_id']
|
93
|
+
credentials = authorizer.get_credentials(user_id, request)
|
94
|
+
if credentials.nil?
|
95
|
+
redirect authorizer.get_authorization_url(user_id: user_id, request: request)
|
96
|
+
end
|
97
|
+
# Credentials are valid, can call APIs
|
98
|
+
# ...
|
99
|
+
end
|
100
|
+
|
101
|
+
get('/oauth2callback') do
|
102
|
+
target_url = Google::Auth::WebUserAuthorizer.handle_auth_callback_deferred(
|
103
|
+
request)
|
104
|
+
redirect target_url
|
105
|
+
end
|
106
|
+
```
|
107
|
+
|
108
|
+
### Example (Command Line)
|
109
|
+
|
110
|
+
```ruby
|
111
|
+
require 'googleauth'
|
112
|
+
require 'googleauth/stores/file_token_store'
|
113
|
+
|
114
|
+
scope = 'https://www.googleapis.com/auth/drive'
|
115
|
+
client_id = Google::Auth::ClientId.from_file('/path/to/client_secrets.json')
|
116
|
+
token_store = Google::Auth::Stores::FileTokenStore.new(
|
117
|
+
:file => '/path/to/tokens.yaml')
|
118
|
+
authorizer = Google::Auth::UserAuthorizer.new(client_id, scope, token_store)
|
119
|
+
|
120
|
+
credentials = authorizer.get_credentials(user_id)
|
121
|
+
if credentials.nil?
|
122
|
+
url = authorizer.get_authorization_url(base_url: 'urn:ietf:wg:oauth:2.0:oob')
|
123
|
+
puts "Open #{url} in your browser and enter the resulting code:"
|
124
|
+
code = gets
|
125
|
+
credentials = authorizer.get_and_store_credentials_from_code(
|
126
|
+
user_id: user_id, code: code, base_url: OOB_URI)
|
127
|
+
end
|
128
|
+
|
129
|
+
# OK to use credentials
|
130
|
+
```
|
131
|
+
|
132
|
+
### Storage
|
133
|
+
|
134
|
+
Authorizers require a storage instance to manage long term persistence of
|
135
|
+
access and refresh tokens. Two storage implementations are included:
|
136
|
+
|
137
|
+
* Google::Auth::Stores::FileTokenStore
|
138
|
+
* Google::Auth::Stores::RedisTokenStore
|
139
|
+
|
140
|
+
Custom storage implementations can also be used. See
|
141
|
+
[token_store.rb](lib/googleauth/token_store.rb) for additional details.
|
142
|
+
|
64
143
|
## What about auth in google-apis-ruby-client?
|
65
144
|
|
66
145
|
The goal is for all auth done by
|
data/googleauth.gemspec
CHANGED
@@ -30,13 +30,5 @@ Gem::Specification.new do |s|
|
|
30
30
|
s.add_dependency 'jwt', '~> 1.4'
|
31
31
|
s.add_dependency 'memoist', '~> 0.12'
|
32
32
|
s.add_dependency 'multi_json', '~> 1.11'
|
33
|
-
s.add_dependency 'signet', '~> 0.
|
34
|
-
|
35
|
-
s.add_development_dependency 'bundler', '~> 1.9'
|
36
|
-
s.add_development_dependency 'simplecov', '~> 0.9'
|
37
|
-
s.add_development_dependency 'coveralls', '~> 0.7'
|
38
|
-
s.add_development_dependency 'fakefs', '~> 0.6'
|
39
|
-
s.add_development_dependency 'rake', '~> 10.0'
|
40
|
-
s.add_development_dependency 'rubocop', '~> 0.30'
|
41
|
-
s.add_development_dependency 'rspec', '~> 3.0'
|
33
|
+
s.add_dependency 'signet', '~> 0.7'
|
42
34
|
end
|
data/lib/googleauth.rb
CHANGED
@@ -34,6 +34,9 @@ require 'googleauth/credentials_loader'
|
|
34
34
|
require 'googleauth/compute_engine'
|
35
35
|
require 'googleauth/service_account'
|
36
36
|
require 'googleauth/user_refresh'
|
37
|
+
require 'googleauth/client_id'
|
38
|
+
require 'googleauth/user_authorizer'
|
39
|
+
require 'googleauth/web_user_authorizer'
|
37
40
|
|
38
41
|
module Google
|
39
42
|
# Module Auth provides classes that provide Google-specific authorization
|
@@ -56,11 +59,11 @@ END
|
|
56
59
|
json_key_io, scope = options.values_at(:json_key_io, :scope)
|
57
60
|
if json_key_io
|
58
61
|
json_key, clz = determine_creds_class(json_key_io)
|
59
|
-
clz.
|
60
|
-
|
62
|
+
clz.make_creds(json_key_io: StringIO.new(MultiJson.dump(json_key)),
|
63
|
+
scope: scope)
|
61
64
|
else
|
62
65
|
clz = read_creds
|
63
|
-
clz.
|
66
|
+
clz.make_creds(scope: scope)
|
64
67
|
end
|
65
68
|
end
|
66
69
|
|
@@ -0,0 +1,102 @@
|
|
1
|
+
# Copyright 2014, 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
|
+
require 'multi_json'
|
31
|
+
|
32
|
+
module Google
|
33
|
+
module Auth
|
34
|
+
# Representation of an application's identity for user authorization
|
35
|
+
# flows.
|
36
|
+
class ClientId
|
37
|
+
INSTALLED_APP = 'installed'
|
38
|
+
WEB_APP = 'web'
|
39
|
+
CLIENT_ID = 'client_id'
|
40
|
+
CLIENT_SECRET = 'client_secret'
|
41
|
+
MISSING_TOP_LEVEL_ELEMENT_ERROR =
|
42
|
+
"Expected top level property 'installed' or 'web' to be present."
|
43
|
+
|
44
|
+
# Text identifier of the client ID
|
45
|
+
# @return [String]
|
46
|
+
attr_reader :id
|
47
|
+
|
48
|
+
# Secret associated with the client ID
|
49
|
+
# @return [String]
|
50
|
+
attr_reader :secret
|
51
|
+
|
52
|
+
class << self
|
53
|
+
attr_accessor :default
|
54
|
+
end
|
55
|
+
|
56
|
+
# Initialize the Client ID
|
57
|
+
#
|
58
|
+
# @param [String] id
|
59
|
+
# Text identifier of the client ID
|
60
|
+
# @param [String] secret
|
61
|
+
# Secret associated with the client ID
|
62
|
+
# @note Direction instantion is discouraged to avoid embedding IDs
|
63
|
+
# & secrets in source. See {#from_file} to load from
|
64
|
+
# `client_secrets.json` files.
|
65
|
+
def initialize(id, secret)
|
66
|
+
fail 'Client id can not be nil' if id.nil?
|
67
|
+
fail 'Client secret can not be nil' if secret.nil?
|
68
|
+
@id = id
|
69
|
+
@secret = secret
|
70
|
+
end
|
71
|
+
|
72
|
+
# Constructs a Client ID from a JSON file downloaed from the
|
73
|
+
# Google Developers Console.
|
74
|
+
#
|
75
|
+
# @param [String, File] file
|
76
|
+
# Path of file to read from
|
77
|
+
# @return [Google::Auth::ClientID]
|
78
|
+
def self.from_file(file)
|
79
|
+
fail 'File can not be nil.' if file.nil?
|
80
|
+
File.open(file.to_s) do |f|
|
81
|
+
json = f.read
|
82
|
+
config = MultiJson.load(json)
|
83
|
+
from_hash(config)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
# Constructs a Client ID from a previously loaded JSON file. The hash
|
88
|
+
# structure should
|
89
|
+
# match the expected JSON format.
|
90
|
+
#
|
91
|
+
# @param [hash] config
|
92
|
+
# Parsed contents of the JSON file
|
93
|
+
# @return [Google::Auth::ClientID]
|
94
|
+
def self.from_hash(config)
|
95
|
+
fail 'Hash can not be nil.' if config.nil?
|
96
|
+
raw_detail = config[INSTALLED_APP] || config[WEB_APP]
|
97
|
+
fail MISSING_TOP_LEVEL_ELEMENT_ERROR if raw_detail.nil?
|
98
|
+
ClientId.new(raw_detail[CLIENT_ID], raw_detail[CLIENT_SECRET])
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
@@ -0,0 +1,61 @@
|
|
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
|
+
require 'googleauth/signet'
|
31
|
+
require 'googleauth/credentials_loader'
|
32
|
+
require 'multi_json'
|
33
|
+
|
34
|
+
module Google
|
35
|
+
module Auth
|
36
|
+
# Small utility for normalizing scopes into canonical form
|
37
|
+
module ScopeUtil
|
38
|
+
ALIASES = {
|
39
|
+
'email' => 'https://www.googleapis.com/auth/userinfo.email',
|
40
|
+
'profile' => 'https://www.googleapis.com/auth/userinfo.profile',
|
41
|
+
'openid' => 'https://www.googleapis.com/auth/plus.me'
|
42
|
+
}
|
43
|
+
|
44
|
+
def self.normalize(scope)
|
45
|
+
list = as_array(scope)
|
46
|
+
list.map { |item| ALIASES[item] || item }
|
47
|
+
end
|
48
|
+
|
49
|
+
def self.as_array(scope)
|
50
|
+
case scope
|
51
|
+
when Array
|
52
|
+
scope
|
53
|
+
when String
|
54
|
+
scope.split(' ')
|
55
|
+
else
|
56
|
+
fail 'Invalid scope value. Must be string or array'
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -49,33 +49,37 @@ module Google
|
|
49
49
|
TOKEN_CRED_URI = 'https://www.googleapis.com/oauth2/v3/token'
|
50
50
|
extend CredentialsLoader
|
51
51
|
|
52
|
-
#
|
53
|
-
# JSON key.
|
54
|
-
def self.read_json_key(json_key_io)
|
55
|
-
json_key = MultiJson.load(json_key_io.read)
|
56
|
-
fail 'missing client_email' unless json_key.key?('client_email')
|
57
|
-
fail 'missing private_key' unless json_key.key?('private_key')
|
58
|
-
[json_key['private_key'], json_key['client_email']]
|
59
|
-
end
|
60
|
-
|
61
|
-
# Initializes a ServiceAccountCredentials.
|
52
|
+
# Creates a ServiceAccountCredentials.
|
62
53
|
#
|
63
54
|
# @param json_key_io [IO] an IO from which the JSON key can be read
|
64
55
|
# @param scope [string|array|nil] the scope(s) to access
|
65
|
-
def
|
56
|
+
def self.make_creds(options = {})
|
66
57
|
json_key_io, scope = options.values_at(:json_key_io, :scope)
|
67
58
|
if json_key_io
|
68
|
-
private_key, client_email =
|
59
|
+
private_key, client_email = read_json_key(json_key_io)
|
69
60
|
else
|
70
61
|
private_key = ENV[CredentialsLoader::PRIVATE_KEY_VAR]
|
71
62
|
client_email = ENV[CredentialsLoader::CLIENT_EMAIL_VAR]
|
72
63
|
end
|
73
64
|
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
65
|
+
new(token_credential_uri: TOKEN_CRED_URI,
|
66
|
+
audience: TOKEN_CRED_URI,
|
67
|
+
scope: scope,
|
68
|
+
issuer: client_email,
|
69
|
+
signing_key: OpenSSL::PKey::RSA.new(private_key))
|
70
|
+
end
|
71
|
+
|
72
|
+
# Reads the private key and client email fields from the service account
|
73
|
+
# JSON key.
|
74
|
+
def self.read_json_key(json_key_io)
|
75
|
+
json_key = MultiJson.load(json_key_io.read)
|
76
|
+
fail 'missing client_email' unless json_key.key?('client_email')
|
77
|
+
fail 'missing private_key' unless json_key.key?('private_key')
|
78
|
+
[json_key['private_key'], json_key['client_email']]
|
79
|
+
end
|
80
|
+
|
81
|
+
def initialize(options = {})
|
82
|
+
super(options)
|
79
83
|
end
|
80
84
|
|
81
85
|
# Extends the base class.
|
@@ -97,7 +101,8 @@ module Google
|
|
97
101
|
client_email: @issuer
|
98
102
|
}
|
99
103
|
alt_clz = ServiceAccountJwtHeaderCredentials
|
100
|
-
|
104
|
+
key_io = StringIO.new(MultiJson.dump(cred_json))
|
105
|
+
alt = alt_clz.make_creds(json_key_io: key_io)
|
101
106
|
alt.apply!(a_hash)
|
102
107
|
end
|
103
108
|
end
|