google-api-client 0.7.1 → 0.8.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.
Files changed (56) hide show
  1. checksums.yaml +13 -5
  2. data/CHANGELOG.md +14 -0
  3. data/Gemfile +0 -36
  4. data/README.md +12 -1
  5. data/Rakefile +1 -8
  6. data/google-api-client.gemspec +40 -0
  7. data/lib/google/api_client.rb +98 -30
  8. data/lib/google/api_client/auth/compute_service_account.rb +1 -1
  9. data/lib/google/api_client/auth/file_storage.rb +19 -44
  10. data/lib/google/api_client/auth/installed_app.rb +11 -7
  11. data/lib/google/api_client/auth/storage.rb +101 -0
  12. data/lib/google/api_client/auth/storages/file_store.rb +58 -0
  13. data/lib/google/api_client/auth/storages/redis_store.rb +54 -0
  14. data/lib/google/api_client/batch.rb +13 -11
  15. data/lib/google/api_client/charset.rb +33 -0
  16. data/lib/google/api_client/client_secrets.rb +9 -6
  17. data/lib/google/api_client/discovery/api.rb +3 -3
  18. data/lib/google/api_client/discovery/resource.rb +3 -3
  19. data/lib/google/api_client/discovery/schema.rb +3 -5
  20. data/lib/google/api_client/errors.rb +5 -0
  21. data/lib/google/api_client/railtie.rb +2 -1
  22. data/lib/google/api_client/request.rb +1 -2
  23. data/lib/google/api_client/result.rb +4 -2
  24. data/lib/google/api_client/service.rb +2 -2
  25. data/lib/google/api_client/service/batch.rb +7 -0
  26. data/lib/google/api_client/service/stub_generator.rb +4 -2
  27. data/lib/google/api_client/service_account.rb +3 -0
  28. data/lib/google/api_client/version.rb +8 -13
  29. data/spec/google/api_client/auth/storage_spec.rb +122 -0
  30. data/spec/google/api_client/auth/storages/file_store_spec.rb +40 -0
  31. data/spec/google/api_client/auth/storages/redis_store_spec.rb +70 -0
  32. data/spec/google/api_client/batch_spec.rb +29 -30
  33. data/spec/google/api_client/client_secrets_spec.rb +53 -0
  34. data/spec/google/api_client/discovery_spec.rb +101 -91
  35. data/spec/google/api_client/gzip_spec.rb +21 -9
  36. data/spec/google/api_client/media_spec.rb +31 -32
  37. data/spec/google/api_client/request_spec.rb +3 -4
  38. data/spec/google/api_client/result_spec.rb +51 -47
  39. data/spec/google/api_client/service_account_spec.rb +40 -35
  40. data/spec/google/api_client/service_spec.rb +144 -112
  41. data/spec/google/api_client/simple_file_store_spec.rb +30 -34
  42. data/spec/google/api_client_spec.rb +139 -40
  43. data/spec/spec_helper.rb +9 -1
  44. metadata +111 -88
  45. data/CONTRIBUTING.md +0 -32
  46. data/lib/cacerts.pem +0 -2183
  47. data/lib/google/inflection.rb +0 -28
  48. data/spec/fixtures/files/privatekey.p12 +0 -0
  49. data/spec/fixtures/files/sample.txt +0 -33
  50. data/spec/fixtures/files/secret.pem +0 -19
  51. data/tasks/gem.rake +0 -97
  52. data/tasks/git.rake +0 -45
  53. data/tasks/metrics.rake +0 -22
  54. data/tasks/spec.rake +0 -57
  55. data/tasks/wiki.rake +0 -82
  56. data/tasks/yard.rake +0 -29
checksums.yaml CHANGED
@@ -1,7 +1,15 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: f8c8eb2c42edad1bf6e5cfbee1d439954126190c
4
- data.tar.gz: fb2452e06f097f61268bd5249dc8fef45463b21a
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ YzhlMTg0N2Y1ZjlhYzcxYzM4MzM2Y2ZmMGI4NzEyNzJjMjlmYTEzYg==
5
+ data.tar.gz: !binary |-
6
+ MzcxZjIyMjAzODdlMTYxMzBhZWUxYzZjZDhiNjI1NzE1MTFkMjk5NQ==
5
7
  SHA512:
6
- metadata.gz: f93bdc644f5520cc99c072da4816b9af16d13a1694a103dbeeee39b6c16974f68c1780ff6232476bac434482adc6cdc09ff036b2a62c4eafd94977ab14855417
7
- data.tar.gz: 0d73c87dd66332a6782dd60b1aaef11ebc5d5fc440d86fe34996f661acc714dcb631e6c131be6002f1b76ba5a867ad456c5df15dd80be0b0f22a1b8137ed1837
8
+ metadata.gz: !binary |-
9
+ YzFlYThlNjUzZGI4ZTI2ZWZmY2FmMzQ1NTlmMDNlOTZkYzcxZWIwMmEzZDI5
10
+ ZjBiZjAxOTNmYzQ4YWRiM2VlNDgxOWMxODg2NzRmZWM3NTQwMTI2N2JjMmMy
11
+ YWRhYjAxNDNlY2Y2NjhhM2E2ZjMwMTQ1Mzc0NzliY2VmODc4NTY=
12
+ data.tar.gz: !binary |-
13
+ YWM2YjUzY2YyNDI1MmEwZTcxOTBiYmVjOWU4ZDQ1ZDY0MzYzMjBlZmMzMTVi
14
+ Y2IwN2UyZGVkYzdhMTNiNTA0ZDI4OTIxMGNiODQwNWJmYjA1ZmJhYTgzZDA1
15
+ OTkxZGE4NTIxODk3ZWZhNGRhZTc1OWEwZTRmZjEyOThiMWM0MDU=
@@ -1,3 +1,17 @@
1
+ # 0.8.0
2
+ * Refactored credential storage, added support for redis
3
+ * Update gem depdendencies
4
+ * Fixed retry logic to allow for auth retries independent of the overall number of retries
5
+ * Added `:force_encoding` option to set body content encoding based on the Content-Type header
6
+ * Batch requests with the service interface now inherit the service's connection
7
+ * `register_discover_document` now returns the API instance
8
+ * Added `:proxy` option to set Faraday's HTTP proxy setting
9
+ * Drop 1.8.x support
10
+ * Added `:faraday_options` option to allow passthrough settings to Faraday connection
11
+
12
+ # 0.7.1
13
+ * Minor fix to update gem dependencies
14
+
1
15
  # 0.7.0
2
16
  * Remove CLI
3
17
  * SUpport for automatic retires & backoff. Off by default, enable by setting `retries` on `APIClient`
data/Gemfile CHANGED
@@ -2,40 +2,4 @@ source 'https://rubygems.org'
2
2
 
3
3
  gemspec
4
4
 
5
- gem 'signet', '>= 0.5.0'
6
- gem 'addressable', '>= 2.3.2'
7
- gem 'uuidtools', '>= 2.1.0'
8
- gem 'autoparse', '>= 0.3.3'
9
- gem 'faraday', '>= 0.9.0'
10
- gem 'multi_json', '>= 1.0.0'
11
- gem 'extlib', '>= 0.9.15'
12
- gem 'jwt', '~> 0.1.5'
13
- gem 'retriable', '>= 1.4'
14
5
  gem 'jruby-openssl', :platforms => :jruby
15
-
16
- group :development do
17
- gem 'launchy', '>= 2.1.1'
18
- gem 'yard'
19
- gem 'kramdown'
20
- end
21
-
22
-
23
- platforms :rbx do
24
- gem 'rubysl', '~> 2.0'
25
- gem 'psych'
26
- end
27
-
28
-
29
- group :examples do
30
- gem 'sinatra'
31
- end
32
-
33
- group :test, :development do
34
- gem 'json', '~> 1.7.7'
35
- gem 'rake', '>= 0.9.0'
36
- gem 'rspec', '>= 2.11.0'
37
- gem 'rcov', '>= 0.9.9', :platform => :mri_18
38
- end
39
-
40
-
41
- gem 'idn', :platform => :mri_18
data/README.md CHANGED
@@ -15,6 +15,10 @@
15
15
  The Google API Ruby Client makes it trivial to discover and access supported
16
16
  APIs.
17
17
 
18
+ ## Alpha
19
+
20
+ This library is in Alpha. We will make an effort to support the library, but we reserve the right to make incompatible changes when necessary.
21
+
18
22
  ## Install
19
23
 
20
24
  Be sure `https://rubygems.org/` is in your gem sources.
@@ -83,8 +87,13 @@ drive = client.discovered_api('drive', 'v2')
83
87
  Locally cached discovery documents may be used as well. To load an API from a local file:
84
88
 
85
89
  ```ruby
90
+ # Output discovery document to JSON
91
+ File.open('my-api.json', 'w') do |f| f.puts MultiJson.dump(client.discovery_document('myapi', 'v1')) end
92
+
93
+ # Read discovery document and load API
86
94
  doc = File.read('my-api.json')
87
- my_api = client.register_discovery_document('myapi', 'v1', doc)
95
+ client.register_discovery_document('myapi', 'v1', doc)
96
+ my_api = client.discovered_api('myapi', 'v1')
88
97
  ```
89
98
 
90
99
  ### Authorization
@@ -114,6 +123,8 @@ in the credentials. Detailed instructions on how to enable delegation for your d
114
123
 
115
124
  The API client can automatically retry requests for recoverable errors. To enable retries, set the `client.retries` property to
116
125
  the number of additional attempts. To avoid flooding servers, retries invovle a 1 second delay that increases on each subsequent retry.
126
+ In the case of authentication token expiry, the API client will attempt to refresh the token and retry the failed operation - this
127
+ is a specific exception to the retry rules.
117
128
 
118
129
  The default value for retries is 0, but will be enabled by default in future releases.
119
130
 
data/Rakefile CHANGED
@@ -33,14 +33,7 @@ list = FileList[
33
33
  end
34
34
  PKG_FILES = list
35
35
 
36
- RCOV_ENABLED = !!(RUBY_PLATFORM != 'java' && RUBY_VERSION =~ /^1\.8/)
37
- if RCOV_ENABLED
38
- task :default => 'spec:rcov'
39
- else
40
- task :default => 'spec'
41
- end
36
+ task :default => 'spec'
42
37
 
43
38
  WINDOWS = (RUBY_PLATFORM =~ /mswin|win32|mingw|bccwin|cygwin/) rescue false
44
39
  SUDO = WINDOWS ? '' : ('sudo' unless ENV['SUDOLESS'])
45
-
46
- Dir['tasks/**/*.rake'].each { |rake| load rake }
@@ -0,0 +1,40 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.join(File.dirname(__FILE__), 'lib/google/api_client', 'version')
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = "google-api-client"
6
+ s.version = Google::APIClient::VERSION::STRING
7
+
8
+ s.required_rubygems_version = ">= 1.3.5"
9
+ s.require_paths = ["lib"]
10
+ s.authors = ["Bob Aman", "Steven Bazyl"]
11
+ s.license = "Apache-2.0"
12
+ s.description = "The Google API Ruby Client makes it trivial to discover and access supported APIs."
13
+ s.email = "sbazyl@google.com"
14
+ s.extra_rdoc_files = ["README.md"]
15
+ s.files = %w(google-api-client.gemspec Rakefile LICENSE CHANGELOG.md README.md Gemfile)
16
+ s.files += Dir.glob("lib/**/*.rb")
17
+ s.files += Dir.glob("spec/**/*.{rb,opts}")
18
+ s.files += Dir.glob("vendor/**/*.rb")
19
+ s.files += Dir.glob("tasks/**/*")
20
+ s.files += Dir.glob("website/**/*")
21
+ s.homepage = "https://github.com/google/google-api-ruby-client/"
22
+ s.rdoc_options = ["--main", "README.md"]
23
+ s.summary = "The Google API Ruby Client makes it trivial to discover and access Google's REST APIs."
24
+
25
+ s.add_runtime_dependency 'addressable', '~> 2.3'
26
+ s.add_runtime_dependency 'signet', '~> 0.6'
27
+ s.add_runtime_dependency 'faraday', '~> 0.9'
28
+ s.add_runtime_dependency 'multi_json', '~> 1.10'
29
+ s.add_runtime_dependency 'autoparse', "~> 0.3"
30
+ s.add_runtime_dependency 'extlib', '~> 0.9'
31
+ s.add_runtime_dependency 'launchy', '~> 2.4'
32
+ s.add_runtime_dependency 'retriable', '~> 1.4'
33
+ s.add_runtime_dependency 'activesupport', '>= 3.2'
34
+
35
+ s.add_development_dependency 'rake', '~> 10.0'
36
+ s.add_development_dependency 'yard', '~> 0.8'
37
+ s.add_development_dependency 'rspec', '~> 3.1'
38
+ s.add_development_dependency 'kramdown', '~> 1.5'
39
+ s.add_development_dependency 'simplecov', '~> 0.9'
40
+ end
@@ -31,8 +31,9 @@ require 'google/api_client/media'
31
31
  require 'google/api_client/service_account'
32
32
  require 'google/api_client/batch'
33
33
  require 'google/api_client/gzip'
34
+ require 'google/api_client/charset'
34
35
  require 'google/api_client/client_secrets'
35
- require 'google/api_client/railtie' if defined?(Rails::Railtie)
36
+ require 'google/api_client/railtie' if defined?(Rails)
36
37
 
37
38
  module Google
38
39
 
@@ -75,6 +76,11 @@ module Google
75
76
  # @option options [String] :ca_file
76
77
  # Optional set of root certificates to use when validating SSL connections.
77
78
  # By default, a bundled set of trusted roots will be used.
79
+ # @options options[Hash] :force_encoding
80
+ # Experimental option. True if response body should be force encoded into the charset
81
+ # specified in the Content-Type header. Mostly intended for compressed content.
82
+ # @options options[Hash] :faraday_options
83
+ # Pass through of options to set on the Faraday connection
78
84
  def initialize(options={})
79
85
  logger.debug { "#{self.class} - Initializing client with options #{options}" }
80
86
 
@@ -97,6 +103,9 @@ module Google
97
103
  else
98
104
  logger.warn { "#{self.class} - Please provide :application_name and :application_version when initializing the client" }
99
105
  end
106
+
107
+ proxy = options[:proxy] || Object::ENV["http_proxy"]
108
+
100
109
  self.user_agent = options[:user_agent] || (
101
110
  "#{application_string} " +
102
111
  "google-api-ruby-client/#{Google::APIClient::VERSION::STRING} #{ENV::OS_VERSION} (gzip)"
@@ -109,17 +118,25 @@ module Google
109
118
  self.key = options[:key]
110
119
  self.user_ip = options[:user_ip]
111
120
  self.retries = options.fetch(:retries) { 0 }
121
+ self.expired_auth_retry = options.fetch(:expired_auth_retry) { true }
112
122
  @discovery_uris = {}
113
123
  @discovery_documents = {}
114
124
  @discovered_apis = {}
115
125
  ca_file = options[:ca_file] || File.expand_path('../../cacerts.pem', __FILE__)
116
126
  self.connection = Faraday.new do |faraday|
127
+ faraday.response :charset if options[:force_encoding]
117
128
  faraday.response :gzip
118
129
  faraday.options.params_encoder = Faraday::FlatParamsEncoder
119
130
  faraday.ssl.ca_file = ca_file
120
131
  faraday.ssl.verify = true
132
+ faraday.proxy proxy
121
133
  faraday.adapter Faraday.default_adapter
122
- end
134
+ if options[:faraday_option].is_a?(Hash)
135
+ options[:faraday_option].each_pair do |option, value|
136
+ faraday.options.send("#{option}=", value)
137
+ end
138
+ end
139
+ end
123
140
  return self
124
141
  end
125
142
 
@@ -239,6 +256,13 @@ module Google
239
256
  # Number of retries
240
257
  attr_accessor :retries
241
258
 
259
+ ##
260
+ # Whether or not an expired auth token should be re-acquired
261
+ # (and the operation retried) regardless of retries setting
262
+ # @return [Boolean]
263
+ # Auto retry on auth expiry
264
+ attr_accessor :expired_auth_retry
265
+
242
266
  ##
243
267
  # Returns the URI for the directory document.
244
268
  #
@@ -254,10 +278,12 @@ module Google
254
278
  # @param [String, Symbol] api The API name.
255
279
  # @param [String] version The desired version of the API.
256
280
  # @param [Addressable::URI] uri The URI of the discovery document.
281
+ # @return [Google::APIClient::API] The service object.
257
282
  def register_discovery_uri(api, version, uri)
258
283
  api = api.to_s
259
284
  version = version || 'v1'
260
285
  @discovery_uris["#{api}:#{version}"] = uri
286
+ discovered_api(api, version)
261
287
  end
262
288
 
263
289
  ##
@@ -286,6 +312,7 @@ module Google
286
312
  # @param [String] version The desired version of the API.
287
313
  # @param [String, StringIO] discovery_document
288
314
  # The contents of the discovery document.
315
+ # @return [Google::APIClient::API] The service object.
289
316
  def register_discovery_document(api, version, discovery_document)
290
317
  api = api.to_s
291
318
  version = version || 'v1'
@@ -300,6 +327,7 @@ module Google
300
327
  end
301
328
  @discovery_documents["#{api}:#{version}"] =
302
329
  MultiJson.load(discovery_document)
330
+ discovered_api(api, version)
303
331
  end
304
332
 
305
333
  ##
@@ -591,35 +619,42 @@ module Google
591
619
 
592
620
  connection = options[:connection] || self.connection
593
621
  request.authorization = options[:authorization] || self.authorization unless options[:authenticated] == false
622
+
594
623
  tries = 1 + (options[:retries] || self.retries)
624
+ attempt = 0
625
+
595
626
  Retriable.retriable :tries => tries,
596
- :on => [TransmissionError],
627
+ :on => [TransmissionError],
628
+ :on_retry => client_error_handler,
597
629
  :interval => lambda {|attempts| (2 ** attempts) + rand} do
598
- result = request.send(connection, true)
599
-
600
- case result.status
601
- when 200...300
602
- result
603
- when 301, 302, 303, 307
604
- request = generate_request(request.to_hash.merge({
605
- :uri => result.headers['location'],
606
- :api_method => nil
607
- }))
608
- raise RedirectError.new(result.headers['location'], result)
609
- when 400...500
610
- if result.status == 401 && request.authorization.respond_to?(:refresh_token) && auto_refresh_token
611
- begin
612
- logger.debug("Attempting refresh of access token & retry of request")
613
- request.authorization.fetch_access_token!
614
- rescue Signet::AuthorizationError
615
- # Ignore since we want the original error
616
- end
617
- end
618
- raise ClientError.new(result.error_message || "A client error has occurred", result)
619
- when 500...600
620
- raise ServerError.new(result.error_message || "A server error has occurred", result)
621
- else
622
- raise TransmissionError.new(result.error_message || "A transmission error has occurred", result)
630
+ attempt += 1
631
+
632
+ # This 2nd level retriable only catches auth errors, and supports 1 retry, which allows
633
+ # auth to be re-attempted without having to retry all sorts of other failures like
634
+ # NotFound, etc
635
+ Retriable.retriable :tries => ((expired_auth_retry || tries > 1) && attempt == 1) ? 2 : 1,
636
+ :on => [AuthorizationError],
637
+ :on_retry => authorization_error_handler(request.authorization) do
638
+ result = request.send(connection, true)
639
+
640
+ case result.status
641
+ when 200...300
642
+ result
643
+ when 301, 302, 303, 307
644
+ request = generate_request(request.to_hash.merge({
645
+ :uri => result.headers['location'],
646
+ :api_method => nil
647
+ }))
648
+ raise RedirectError.new(result.headers['location'], result)
649
+ when 401
650
+ raise AuthorizationError.new(result.error_message || 'Invalid/Expired Authentication', result)
651
+ when 400, 402...500
652
+ raise ClientError.new(result.error_message || "A client error has occurred", result)
653
+ when 500...600
654
+ raise ServerError.new(result.error_message || "A server error has occurred", result)
655
+ else
656
+ raise TransmissionError.new(result.error_message || "A transmission error has occurred", result)
657
+ end
623
658
  end
624
659
  end
625
660
  end
@@ -665,8 +700,41 @@ module Google
665
700
  return Addressable::Template.new(@base_uri + template).expand(mapping)
666
701
  end
667
702
 
703
+
704
+ ##
705
+ # Returns on proc for special processing of retries for authorization errors
706
+ # Only 401s should be retried and only if the credentials are refreshable
707
+ #
708
+ # @param [#fetch_access_token!] authorization
709
+ # OAuth 2 credentials
710
+ # @return [Proc]
711
+ def authorization_error_handler(authorization)
712
+ can_refresh = authorization.respond_to?(:refresh_token) && auto_refresh_token
713
+ Proc.new do |exception, tries|
714
+ next unless exception.kind_of?(AuthorizationError)
715
+ if can_refresh
716
+ begin
717
+ logger.debug("Attempting refresh of access token & retry of request")
718
+ authorization.fetch_access_token!
719
+ next
720
+ rescue Signet::AuthorizationError
721
+ end
722
+ end
723
+ raise exception
724
+ end
725
+ end
726
+
727
+ ##
728
+ # Returns on proc for special processing of retries as not all client errors
729
+ # are recoverable. Only 401s should be retried (via authorization_error_handler)
730
+ #
731
+ # @return [Proc]
732
+ def client_error_handler
733
+ Proc.new do |exception, tries|
734
+ raise exception if exception.kind_of?(ClientError)
735
+ end
736
+ end
737
+
668
738
  end
669
739
 
670
740
  end
671
-
672
- require 'google/api_client/version'
@@ -21,7 +21,7 @@ module Google
21
21
  def fetch_access_token(options={})
22
22
  connection = options[:connection] || Faraday.default_connection
23
23
  response = connection.get 'http://metadata/computeMetadata/v1beta1/instance/service-accounts/default/token'
24
- Signet::OAuth2.parse_json_credentials(response.body)
24
+ Signet::OAuth2.parse_credentials(response.body, response.headers['content-type'])
25
25
  end
26
26
  end
27
27
  end
@@ -12,47 +12,39 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
- require 'json'
16
15
  require 'signet/oauth_2/client'
16
+ require_relative 'storage'
17
+ require_relative 'storages/file_store'
17
18
 
18
19
  module Google
19
20
  class APIClient
21
+
20
22
  ##
21
23
  # Represents cached OAuth 2 tokens stored on local disk in a
22
24
  # JSON serialized file. Meant to resemble the serialized format
23
25
  # http://google-api-python-client.googlecode.com/hg/docs/epy/oauth2client.file.Storage-class.html
24
26
  #
27
+ # @deprecated
28
+ # Use {Google::APIClient::Storage} and {Google::APIClient::FileStore} instead
29
+ #
25
30
  class FileStorage
26
- # @return [String] Path to the credentials file.
27
- attr_accessor :path
28
31
 
29
- # @return [Signet::OAuth2::Client] Path to the credentials file.
30
- attr_reader :authorization
32
+ attr_accessor :storage,
33
+ :path
31
34
 
32
- ##
33
- # Initializes the FileStorage object.
34
- #
35
- # @param [String] path
36
- # Path to the credentials file.
37
35
  def initialize(path)
38
36
  @path = path
39
- self.load_credentials
37
+ store = Google::APIClient::FileStore.new(@path)
38
+ @storage = Google::APIClient::Storage.new(store)
39
+ @storage.authorize
40
40
  end
41
41
 
42
- ##
43
- # Attempt to read in credentials from the specified file.
44
42
  def load_credentials
45
- if File.exist? self.path
46
- File.open(self.path, 'r') do |file|
47
- cached_credentials = JSON.load(file)
48
- @authorization = Signet::OAuth2::Client.new(cached_credentials)
49
- @authorization.issued_at = Time.at(cached_credentials['issued_at'])
50
- if @authorization.expired?
51
- @authorization.fetch_access_token!
52
- self.write_credentials
53
- end
54
- end
55
- end
43
+ storage.authorize
44
+ end
45
+
46
+ def authorization
47
+ storage.authorization
56
48
  end
57
49
 
58
50
  ##
@@ -61,26 +53,9 @@ module Google
61
53
  # @param [Signet::OAuth2::Client] authorization
62
54
  # Optional authorization instance. If not provided, the authorization
63
55
  # already associated with this instance will be written.
64
- def write_credentials(authorization=nil)
65
- @authorization = authorization unless authorization.nil?
66
-
67
- unless @authorization.refresh_token.nil?
68
- hash = {}
69
- %w'access_token
70
- authorization_uri
71
- client_id
72
- client_secret
73
- expires_in
74
- refresh_token
75
- token_credential_uri'.each do |var|
76
- hash[var] = @authorization.instance_variable_get("@#{var}")
77
- end
78
- hash['issued_at'] = @authorization.issued_at.to_i
79
-
80
- File.open(self.path, 'w', 0600) do |file|
81
- file.write(hash.to_json)
82
- end
83
- end
56
+ def write_credentials(auth=nil)
57
+ self.authorization = auth unless auth.nil?
58
+ storage.write_credentials(self.authorization)
84
59
  end
85
60
  end
86
61
  end