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.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. data/.kokoro/build.sh +2 -34
  3. data/.kokoro/continuous/common.cfg +5 -0
  4. data/.kokoro/continuous/linux.cfg +1 -1
  5. data/.kokoro/osx.sh +2 -33
  6. data/.kokoro/presubmit/common.cfg +5 -0
  7. data/.kokoro/presubmit/linux.cfg +1 -1
  8. data/.kokoro/release.cfg +53 -0
  9. data/.kokoro/trampoline.sh +3 -23
  10. data/.kokoro/windows.sh +2 -30
  11. data/.rubocop.yml +7 -24
  12. data/CHANGELOG.md +24 -39
  13. data/Gemfile +14 -14
  14. data/README.md +21 -1
  15. data/Rakefile +84 -10
  16. data/googleauth.gemspec +23 -23
  17. data/lib/googleauth.rb +6 -6
  18. data/lib/googleauth/application_default.rb +11 -11
  19. data/lib/googleauth/client_id.rb +16 -16
  20. data/lib/googleauth/compute_engine.rb +27 -27
  21. data/lib/googleauth/credentials.rb +35 -37
  22. data/lib/googleauth/credentials_loader.rb +64 -67
  23. data/lib/googleauth/default_credentials.rb +18 -18
  24. data/lib/googleauth/iam.rb +9 -9
  25. data/lib/googleauth/json_key_reader.rb +6 -6
  26. data/lib/googleauth/scope_util.rb +11 -11
  27. data/lib/googleauth/service_account.rb +42 -42
  28. data/lib/googleauth/signet.rb +15 -17
  29. data/lib/googleauth/stores/file_token_store.rb +8 -8
  30. data/lib/googleauth/stores/redis_token_store.rb +17 -17
  31. data/lib/googleauth/token_store.rb +6 -6
  32. data/lib/googleauth/user_authorizer.rb +55 -59
  33. data/lib/googleauth/user_refresh.rb +27 -27
  34. data/lib/googleauth/version.rb +1 -1
  35. data/lib/googleauth/web_user_authorizer.rb +55 -56
  36. data/spec/googleauth/apply_auth_examples.rb +46 -46
  37. data/spec/googleauth/client_id_spec.rb +54 -54
  38. data/spec/googleauth/compute_engine_spec.rb +41 -41
  39. data/spec/googleauth/credentials_spec.rb +97 -97
  40. data/spec/googleauth/get_application_default_spec.rb +114 -114
  41. data/spec/googleauth/iam_spec.rb +25 -25
  42. data/spec/googleauth/scope_util_spec.rb +24 -24
  43. data/spec/googleauth/service_account_spec.rb +204 -194
  44. data/spec/googleauth/signet_spec.rb +37 -38
  45. data/spec/googleauth/stores/file_token_store_spec.rb +12 -12
  46. data/spec/googleauth/stores/redis_token_store_spec.rb +11 -11
  47. data/spec/googleauth/stores/store_examples.rb +16 -16
  48. data/spec/googleauth/user_authorizer_spec.rb +120 -121
  49. data/spec/googleauth/user_refresh_spec.rb +151 -146
  50. data/spec/googleauth/web_user_authorizer_spec.rb +66 -66
  51. data/spec/spec_helper.rb +19 -19
  52. metadata +4 -6
  53. data/.kokoro/common.cfg +0 -22
  54. data/.travis.yml +0 -40
@@ -27,7 +27,7 @@
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
- require 'signet/oauth_2/client'
30
+ require "signet/oauth_2/client"
31
31
 
32
32
  module Signet
33
33
  # OAuth2 supports OAuth2 authentication.
@@ -38,24 +38,24 @@ module Signet
38
38
  # This reopens Client to add #apply and #apply! methods which update a
39
39
  # hash with the fetched authentication token.
40
40
  class Client
41
- def configure_connection(options)
41
+ def configure_connection options
42
42
  @connection_info =
43
43
  options[:connection_builder] || options[:default_connection]
44
44
  self
45
45
  end
46
46
 
47
47
  # Updates a_hash updated with the authentication token
48
- def apply!(a_hash, opts = {})
48
+ def apply! a_hash, opts = {}
49
49
  # fetch the access token there is currently not one, or if the client
50
50
  # has expired
51
- fetch_access_token!(opts) if access_token.nil? || expires_within?(60)
51
+ fetch_access_token! opts if access_token.nil? || expires_within?(60)
52
52
  a_hash[AUTH_METADATA_KEY] = "Bearer #{access_token}"
53
53
  end
54
54
 
55
55
  # Returns a clone of a_hash updated with the authentication token
56
- def apply(a_hash, opts = {})
56
+ def apply a_hash, opts = {}
57
57
  a_copy = a_hash.clone
58
- apply!(a_copy, opts)
58
+ apply! a_copy, opts
59
59
  a_copy
60
60
  end
61
61
 
@@ -65,18 +65,18 @@ module Signet
65
65
  lambda(&method(:apply))
66
66
  end
67
67
 
68
- def on_refresh(&block)
68
+ def on_refresh &block
69
69
  @refresh_listeners ||= []
70
70
  @refresh_listeners << block
71
71
  end
72
72
 
73
73
  alias orig_fetch_access_token! fetch_access_token!
74
- def fetch_access_token!(options = {})
74
+ def fetch_access_token! options = {}
75
75
  unless options[:connection]
76
76
  connection = build_default_connection
77
- options = options.merge(connection: connection) if connection
77
+ options = options.merge connection: connection if connection
78
78
  end
79
- info = orig_fetch_access_token!(options)
79
+ info = orig_fetch_access_token! options
80
80
  notify_refresh_listeners
81
81
  info
82
82
  end
@@ -84,7 +84,7 @@ module Signet
84
84
  def notify_refresh_listeners
85
85
  listeners = @refresh_listeners || []
86
86
  listeners.each do |block|
87
- block.call(self)
87
+ block.call self
88
88
  end
89
89
  end
90
90
 
@@ -98,15 +98,13 @@ module Signet
98
98
  end
99
99
  end
100
100
 
101
- def retry_with_error(max_retry_count = 5)
101
+ def retry_with_error max_retry_count = 5
102
102
  retry_count = 0
103
103
 
104
104
  begin
105
105
  yield
106
- rescue => e
107
- if e.is_a?(Signet::AuthorizationError) || e.is_a?(Signet::ParseError)
108
- raise e
109
- end
106
+ rescue StandardError => e
107
+ raise e if e.is_a?(Signet::AuthorizationError) || e.is_a?(Signet::ParseError)
110
108
 
111
109
  if retry_count < max_retry_count
112
110
  retry_count += 1
@@ -114,7 +112,7 @@ module Signet
114
112
  retry
115
113
  else
116
114
  msg = "Unexpected error: #{e.inspect}"
117
- raise(Signet::AuthorizationError, msg)
115
+ raise Signet::AuthorizationError, msg
118
116
  end
119
117
  end
120
118
  end
@@ -27,8 +27,8 @@
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
- require 'yaml/store'
31
- require 'googleauth/token_store'
30
+ require "yaml/store"
31
+ require "googleauth/token_store"
32
32
 
33
33
  module Google
34
34
  module Auth
@@ -39,24 +39,24 @@ module Google
39
39
  #
40
40
  # @param [String, File] file
41
41
  # Path to storage file
42
- def initialize(options = {})
42
+ def initialize options = {}
43
43
  path = options[:file]
44
- @store = YAML::Store.new(path)
44
+ @store = YAML::Store.new path
45
45
  end
46
46
 
47
47
  # (see Google::Auth::Stores::TokenStore#load)
48
- def load(id)
48
+ def load id
49
49
  @store.transaction { @store[id] }
50
50
  end
51
51
 
52
52
  # (see Google::Auth::Stores::TokenStore#store)
53
- def store(id, token)
53
+ def store id, token
54
54
  @store.transaction { @store[id] = token }
55
55
  end
56
56
 
57
57
  # (see Google::Auth::Stores::TokenStore#delete)
58
- def delete(id)
59
- @store.transaction { @store.delete(id) }
58
+ def delete id
59
+ @store.transaction { @store.delete id }
60
60
  end
61
61
  end
62
62
  end
@@ -27,8 +27,8 @@
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
- require 'redis'
31
- require 'googleauth/token_store'
30
+ require "redis"
31
+ require "googleauth/token_store"
32
32
 
33
33
  module Google
34
34
  module Auth
@@ -37,7 +37,7 @@ module Google
37
37
  # are stored as JSON using the supplied key, prefixed with
38
38
  # `g-user-token:`
39
39
  class RedisTokenStore < Google::Auth::TokenStore
40
- DEFAULT_KEY_PREFIX = 'g-user-token:'.freeze
40
+ DEFAULT_KEY_PREFIX = "g-user-token:".freeze
41
41
 
42
42
  # Create a new store with the supplied redis client.
43
43
  #
@@ -48,34 +48,34 @@ module Google
48
48
  # @note If no redis instance is provided, a new one is created and
49
49
  # the options passed through. You may include any other keys accepted
50
50
  # by `Redis.new`
51
- def initialize(options = {})
52
- redis = options.delete(:redis)
53
- prefix = options.delete(:prefix)
51
+ def initialize options = {}
52
+ redis = options.delete :redis
53
+ prefix = options.delete :prefix
54
54
  @redis = case redis
55
55
  when Redis
56
56
  redis
57
57
  else
58
- Redis.new(options)
58
+ Redis.new options
59
59
  end
60
60
  @prefix = prefix || DEFAULT_KEY_PREFIX
61
61
  end
62
62
 
63
63
  # (see Google::Auth::Stores::TokenStore#load)
64
- def load(id)
65
- key = key_for(id)
66
- @redis.get(key)
64
+ def load id
65
+ key = key_for id
66
+ @redis.get key
67
67
  end
68
68
 
69
69
  # (see Google::Auth::Stores::TokenStore#store)
70
- def store(id, token)
71
- key = key_for(id)
72
- @redis.set(key, token)
70
+ def store id, token
71
+ key = key_for id
72
+ @redis.set key, token
73
73
  end
74
74
 
75
75
  # (see Google::Auth::Stores::TokenStore#delete)
76
- def delete(id)
77
- key = key_for(id)
78
- @redis.del(key)
76
+ def delete id
77
+ key = key_for id
78
+ @redis.del key
79
79
  end
80
80
 
81
81
  private
@@ -86,7 +86,7 @@ module Google
86
86
  # ID of the token
87
87
  # @return [String]
88
88
  # Redis key
89
- def key_for(id)
89
+ def key_for id
90
90
  @prefix + id
91
91
  end
92
92
  end
@@ -43,8 +43,8 @@ module Google
43
43
  # ID of token data to load.
44
44
  # @return [String]
45
45
  # The loaded token data.
46
- def load(_id)
47
- raise 'Not implemented'
46
+ def load _id
47
+ raise "Not implemented"
48
48
  end
49
49
 
50
50
  # Put the token data into storage for the given ID.
@@ -53,16 +53,16 @@ module Google
53
53
  # ID of token data to store.
54
54
  # @param [String] token
55
55
  # The token data to store.
56
- def store(_id, _token)
57
- raise 'Not implemented'
56
+ def store _id, _token
57
+ raise "Not implemented"
58
58
  end
59
59
 
60
60
  # Remove the token data from storage for the given ID.
61
61
  #
62
62
  # @param [String] id
63
63
  # ID of the token data to delete
64
- def delete(_id)
65
- raise 'Not implemented'
64
+ def delete _id
65
+ raise "Not implemented"
66
66
  end
67
67
  end
68
68
  end
@@ -27,10 +27,10 @@
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
- require 'uri'
31
- require 'multi_json'
32
- require 'googleauth/signet'
33
- require 'googleauth/user_refresh'
30
+ require "uri"
31
+ require "multi_json"
32
+ require "googleauth/signet"
33
+ require "googleauth/user_refresh"
34
34
 
35
35
  module Google
36
36
  module Auth
@@ -53,11 +53,11 @@ module Google
53
53
  # ...
54
54
  class UserAuthorizer
55
55
  MISMATCHED_CLIENT_ID_ERROR =
56
- 'Token client ID of %s does not match configured client id %s'.freeze
57
- NIL_CLIENT_ID_ERROR = 'Client id can not be nil.'.freeze
58
- NIL_SCOPE_ERROR = 'Scope can not be nil.'.freeze
59
- NIL_USER_ID_ERROR = 'User ID can not be nil.'.freeze
60
- NIL_TOKEN_STORE_ERROR = 'Can not call method if token store is nil'.freeze
56
+ "Token client ID of %s does not match configured client id %s".freeze
57
+ NIL_CLIENT_ID_ERROR = "Client id can not be nil.".freeze
58
+ NIL_SCOPE_ERROR = "Scope can not be nil.".freeze
59
+ NIL_USER_ID_ERROR = "User ID can not be nil.".freeze
60
+ NIL_TOKEN_STORE_ERROR = "Can not call method if token store is nil".freeze
61
61
  MISSING_ABSOLUTE_URL_ERROR =
62
62
  'Absolute base url required for relative callback url "%s"'.freeze
63
63
 
@@ -72,14 +72,14 @@ module Google
72
72
  # @param [String] callback_uri
73
73
  # URL (either absolute or relative) of the auth callback.
74
74
  # Defaults to '/oauth2callback'
75
- def initialize(client_id, scope, token_store, callback_uri = nil)
75
+ def initialize client_id, scope, token_store, callback_uri = nil
76
76
  raise NIL_CLIENT_ID_ERROR if client_id.nil?
77
77
  raise NIL_SCOPE_ERROR if scope.nil?
78
78
 
79
79
  @client_id = client_id
80
80
  @scope = Array(scope)
81
81
  @token_store = token_store
82
- @callback_uri = callback_uri || '/oauth2callback'
82
+ @callback_uri = callback_uri || "/oauth2callback"
83
83
  end
84
84
 
85
85
  # Build the URL for requesting authorization.
@@ -97,20 +97,20 @@ module Google
97
97
  # nil.
98
98
  # @return [String]
99
99
  # Authorization url
100
- def get_authorization_url(options = {})
100
+ def get_authorization_url options = {}
101
101
  scope = options[:scope] || @scope
102
102
  credentials = UserRefreshCredentials.new(
103
- client_id: @client_id.id,
103
+ client_id: @client_id.id,
104
104
  client_secret: @client_id.secret,
105
- scope: scope
105
+ scope: scope
106
106
  )
107
- redirect_uri = redirect_uri_for(options[:base_url])
108
- url = credentials.authorization_uri(access_type: 'offline',
109
- redirect_uri: redirect_uri,
110
- approval_prompt: 'force',
111
- state: options[:state],
107
+ redirect_uri = redirect_uri_for options[:base_url]
108
+ url = credentials.authorization_uri(access_type: "offline",
109
+ redirect_uri: redirect_uri,
110
+ approval_prompt: "force",
111
+ state: options[:state],
112
112
  include_granted_scopes: true,
113
- login_hint: options[:login_hint])
113
+ login_hint: options[:login_hint])
114
114
  url.to_s
115
115
  end
116
116
 
@@ -123,28 +123,26 @@ module Google
123
123
  # the requested scopes
124
124
  # @return [Google::Auth::UserRefreshCredentials]
125
125
  # Stored credentials, nil if none present
126
- def get_credentials(user_id, scope = nil)
127
- saved_token = stored_token(user_id)
126
+ def get_credentials user_id, scope = nil
127
+ saved_token = stored_token user_id
128
128
  return nil if saved_token.nil?
129
- data = MultiJson.load(saved_token)
129
+ data = MultiJson.load saved_token
130
130
 
131
- if data.fetch('client_id', @client_id.id) != @client_id.id
132
- raise sprintf(MISMATCHED_CLIENT_ID_ERROR,
133
- data['client_id'], @client_id.id)
131
+ if data.fetch("client_id", @client_id.id) != @client_id.id
132
+ raise format(MISMATCHED_CLIENT_ID_ERROR,
133
+ data["client_id"], @client_id.id)
134
134
  end
135
135
 
136
136
  credentials = UserRefreshCredentials.new(
137
- client_id: @client_id.id,
137
+ client_id: @client_id.id,
138
138
  client_secret: @client_id.secret,
139
- scope: data['scope'] || @scope,
140
- access_token: data['access_token'],
141
- refresh_token: data['refresh_token'],
142
- expires_at: data.fetch('expiration_time_millis', 0) / 1000
139
+ scope: data["scope"] || @scope,
140
+ access_token: data["access_token"],
141
+ refresh_token: data["refresh_token"],
142
+ expires_at: data.fetch("expiration_time_millis", 0) / 1000
143
143
  )
144
144
  scope ||= @scope
145
- if credentials.includes_scope?(scope)
146
- return monitor_credentials(user_id, credentials)
147
- end
145
+ return monitor_credentials user_id, credentials if credentials.includes_scope? scope
148
146
  nil
149
147
  end
150
148
 
@@ -163,20 +161,20 @@ module Google
163
161
  # callback uri is a relative.
164
162
  # @return [Google::Auth::UserRefreshCredentials]
165
163
  # Credentials if exchange is successful
166
- def get_credentials_from_code(options = {})
164
+ def get_credentials_from_code options = {}
167
165
  user_id = options[:user_id]
168
166
  code = options[:code]
169
167
  scope = options[:scope] || @scope
170
168
  base_url = options[:base_url]
171
169
  credentials = UserRefreshCredentials.new(
172
- client_id: @client_id.id,
170
+ client_id: @client_id.id,
173
171
  client_secret: @client_id.secret,
174
- redirect_uri: redirect_uri_for(base_url),
175
- scope: scope
172
+ redirect_uri: redirect_uri_for(base_url),
173
+ scope: scope
176
174
  )
177
175
  credentials.code = code
178
176
  credentials.fetch_access_token!({})
179
- monitor_credentials(user_id, credentials)
177
+ monitor_credentials user_id, credentials
180
178
  end
181
179
 
182
180
  # Exchanges an authorization code returned in the oauth callback.
@@ -196,9 +194,9 @@ module Google
196
194
  # callback uri is a relative.
197
195
  # @return [Google::Auth::UserRefreshCredentials]
198
196
  # Credentials if exchange is successful
199
- def get_and_store_credentials_from_code(options = {})
200
- credentials = get_credentials_from_code(options)
201
- store_credentials(options[:user_id], credentials)
197
+ def get_and_store_credentials_from_code options = {}
198
+ credentials = get_credentials_from_code options
199
+ store_credentials options[:user_id], credentials
202
200
  end
203
201
 
204
202
  # Revokes a user's credentials. This both revokes the actual
@@ -206,11 +204,11 @@ module Google
206
204
  #
207
205
  # @param [String] user_id
208
206
  # Unique ID of the user for loading/storing credentials.
209
- def revoke_authorization(user_id)
210
- credentials = get_credentials(user_id)
207
+ def revoke_authorization user_id
208
+ credentials = get_credentials user_id
211
209
  if credentials
212
210
  begin
213
- @token_store.delete(user_id)
211
+ @token_store.delete user_id
214
212
  ensure
215
213
  credentials.revoke!
216
214
  end
@@ -226,15 +224,15 @@ module Google
226
224
  # Unique ID of the user for loading/storing credentials.
227
225
  # @param [Google::Auth::UserRefreshCredentials] credentials
228
226
  # Credentials to store.
229
- def store_credentials(user_id, credentials)
227
+ def store_credentials user_id, credentials
230
228
  json = MultiJson.dump(
231
- client_id: credentials.client_id,
232
- access_token: credentials.access_token,
233
- refresh_token: credentials.refresh_token,
234
- scope: credentials.scope,
229
+ client_id: credentials.client_id,
230
+ access_token: credentials.access_token,
231
+ refresh_token: credentials.refresh_token,
232
+ scope: credentials.scope,
235
233
  expiration_time_millis: credentials.expires_at.to_i * 1000
236
234
  )
237
- @token_store.store(user_id, json)
235
+ @token_store.store user_id, json
238
236
  credentials
239
237
  end
240
238
 
@@ -245,11 +243,11 @@ module Google
245
243
  # @param [String] user_id
246
244
  # Unique ID of the user for loading/storing credentials.
247
245
  # @return [String] The saved token from @token_store
248
- def stored_token(user_id)
246
+ def stored_token user_id
249
247
  raise NIL_USER_ID_ERROR if user_id.nil?
250
248
  raise NIL_TOKEN_STORE_ERROR if @token_store.nil?
251
249
 
252
- @token_store.load(user_id)
250
+ @token_store.load user_id
253
251
  end
254
252
 
255
253
  # Begin watching a credential for refreshes so the access token can be
@@ -259,9 +257,9 @@ module Google
259
257
  # Unique ID of the user for loading/storing credentials.
260
258
  # @param [Google::Auth::UserRefreshCredentials] credentials
261
259
  # Credentials to store.
262
- def monitor_credentials(user_id, credentials)
260
+ def monitor_credentials user_id, credentials
263
261
  credentials.on_refresh do |cred|
264
- store_credentials(user_id, cred)
262
+ store_credentials user_id, cred
265
263
  end
266
264
  credentials
267
265
  end
@@ -272,11 +270,9 @@ module Google
272
270
  # Absolute URL to resolve the callback against if necessary.
273
271
  # @return [String]
274
272
  # Redirect URI
275
- def redirect_uri_for(base_url)
273
+ def redirect_uri_for base_url
276
274
  return @callback_uri unless URI(@callback_uri).scheme.nil?
277
- if base_url.nil? || URI(base_url).scheme.nil?
278
- raise sprintf(MISSING_ABSOLUTE_URL_ERROR, @callback_uri)
279
- end
275
+ raise format(MISSING_ABSOLUTE_URL_ERROR, @callback_uri) if base_url.nil? || URI(base_url).scheme.nil?
280
276
  URI.join(base_url, @callback_uri).to_s
281
277
  end
282
278
  end