googleauth 1.7.0 → 1.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5437d56e0c86ce235d37a202af1a28219a9caeb0bc0f8abac5540cc1d73edf28
4
- data.tar.gz: f56369065e2abc56fb51abccc5003264f8c9ef3e745c202e06e5cb4c6b083d84
3
+ metadata.gz: 888e57705b33e87158d060b7b1569e54e00000428de35f979e7ffc9456cbb7b3
4
+ data.tar.gz: ac341b6c481df125091c1465b56642173591f5698baff6f4806b05216eca8802
5
5
  SHA512:
6
- metadata.gz: f350fb9178517f4782c1dcf08804f5b0ec6bb12ed6dd460ff9c7a875b5929146bf357d797a52cb976878ef25ca8e3439d90b41dfb0e44fbf0b1cfcdf1109ec85
7
- data.tar.gz: 5a1811530c2a2f5321937bdc90f157f7b55cf0b4c77c7c8f98e87474cfd22b06154987279003cefcb3f8cb400f690364078f9dd0302286f6cbd6d94afde826b3
6
+ metadata.gz: 0e9d2fd50c39bf83e86f9f31bbddb897d28ce908be1214849926c45ce7ad2fa0d8f48d70a01acc84c9fa49ddf1a3a3c0c5a87b9bdf1d3ae1b9430b739e709c67
7
+ data.tar.gz: f92483b4971ecc9d48a0b3656a76c694974c6b60153d6ea5ff0f1dd6c544da51b924aedbfa71956db2c1dada98a6cdaa632bb6f38c663e384acc8ebb3af8d1d2
data/CHANGELOG.md CHANGED
@@ -1,5 +1,14 @@
1
1
  # Release History
2
2
 
3
+ ### 1.8.0 (2023-09-07)
4
+
5
+ #### Features
6
+
7
+ * Pass additional parameters to auhtorization url ([#447](https://github.com/googleapis/google-auth-library-ruby/issues/447))
8
+ #### Documentation
9
+
10
+ * improve ADC related error and warning messages ([#449](https://github.com/googleapis/google-auth-library-ruby/issues/449))
11
+
3
12
  ### 1.7.0 (2023-07-14)
4
13
 
5
14
  #### Features
data/README.md CHANGED
@@ -243,6 +243,6 @@ hesitate to
243
243
  [ask questions](http://stackoverflow.com/questions/tagged/google-auth-library-ruby)
244
244
  about the client or APIs on [StackOverflow](http://stackoverflow.com).
245
245
 
246
- [application default credentials]: https://developers.google.com/accounts/docs/application-default-credentials
246
+ [application default credentials]: https://cloud.google.com/docs/authentication/provide-credentials-adc
247
247
  [contributing]: https://github.com/googleapis/google-auth-library-ruby/tree/main/.github/CONTRIBUTING.md
248
248
  [license]: https://github.com/googleapis/google-auth-library-ruby/tree/main/LICENSE
@@ -21,7 +21,7 @@ module Google
21
21
  module Auth
22
22
  NOT_FOUND_ERROR = <<~ERROR_MESSAGE.freeze
23
23
  Could not load the default credentials. Browse to
24
- https://developers.google.com/accounts/docs/application-default-credentials
24
+ https://cloud.google.com/docs/authentication/provide-credentials-adc
25
25
  for more information
26
26
  ERROR_MESSAGE
27
27
 
@@ -57,7 +57,7 @@ module Google
57
57
  return creds unless creds.nil?
58
58
  unless GCECredentials.on_gce? options
59
59
  # Clear cache of the result of GCECredentials.on_gce?
60
- GCECredentials.unmemoize_all
60
+ GCECredentials.reset_cache
61
61
  raise NOT_FOUND_ERROR
62
62
  end
63
63
  GCECredentials.new options.merge(scope: scope)
@@ -17,37 +17,52 @@ require "googleauth/credentials_loader"
17
17
 
18
18
  module Google
19
19
  module Auth
20
- # Representation of an application's identity for user authorization
21
- # flows.
20
+ ##
21
+ # Representation of an application's identity for user authorization flows.
22
+ #
22
23
  class ClientId
24
+ # Toplevel JSON key for the an installed app configuration.
25
+ # Must include client_id and client_secret subkeys if present.
23
26
  INSTALLED_APP = "installed".freeze
27
+ # Toplevel JSON key for the a webapp configuration.
28
+ # Must include client_id and client_secret subkeys if present.
24
29
  WEB_APP = "web".freeze
30
+ # JSON key for the client ID within an app configuration.
25
31
  CLIENT_ID = "client_id".freeze
32
+ # JSON key for the client secret within an app configuration.
26
33
  CLIENT_SECRET = "client_secret".freeze
34
+ # An error message raised when none of the expected toplevel properties
35
+ # can be found.
27
36
  MISSING_TOP_LEVEL_ELEMENT_ERROR =
28
37
  "Expected top level property 'installed' or 'web' to be present.".freeze
29
38
 
39
+ ##
30
40
  # Text identifier of the client ID
31
41
  # @return [String]
42
+ #
32
43
  attr_reader :id
33
44
 
45
+ ##
34
46
  # Secret associated with the client ID
35
47
  # @return [String]
48
+ #
36
49
  attr_reader :secret
37
50
 
38
51
  class << self
39
52
  attr_accessor :default
40
53
  end
41
54
 
42
- # Initialize the Client ID
55
+ ##
56
+ # Initialize the Client ID. Both id and secret must be non-nil.
43
57
  #
44
58
  # @param [String] id
45
59
  # Text identifier of the client ID
46
60
  # @param [String] secret
47
61
  # Secret associated with the client ID
48
- # @note Direction instantion is discouraged to avoid embedding IDs
49
- # & secrets in source. See {#from_file} to load from
62
+ # @note Direct instantiation is discouraged to avoid embedding IDs
63
+ # and secrets in source. See {#from_file} to load from
50
64
  # `client_secrets.json` files.
65
+ #
51
66
  def initialize id, secret
52
67
  CredentialsLoader.warn_if_cloud_sdk_credentials id
53
68
  raise "Client id can not be nil" if id.nil?
@@ -56,12 +71,14 @@ module Google
56
71
  @secret = secret
57
72
  end
58
73
 
74
+ ##
59
75
  # Constructs a Client ID from a JSON file downloaded from the
60
76
  # Google Developers Console.
61
77
  #
62
78
  # @param [String, File] file
63
79
  # Path of file to read from
64
80
  # @return [Google::Auth::ClientID]
81
+ #
65
82
  def self.from_file file
66
83
  raise "File can not be nil." if file.nil?
67
84
  File.open file.to_s do |f|
@@ -71,13 +88,14 @@ module Google
71
88
  end
72
89
  end
73
90
 
91
+ ##
74
92
  # Constructs a Client ID from a previously loaded JSON file. The hash
75
- # structure should
76
- # match the expected JSON format.
93
+ # structure should match the expected JSON format.
77
94
  #
78
95
  # @param [hash] config
79
96
  # Parsed contents of the JSON file
80
97
  # @return [Google::Auth::ClientID]
98
+ #
81
99
  def self.from_hash config
82
100
  raise "Hash can not be nil." if config.nil?
83
101
  raw_detail = config[INSTALLED_APP] || config[WEB_APP]
@@ -14,7 +14,6 @@
14
14
 
15
15
  require "faraday"
16
16
  require "googleauth/signet"
17
- require "memoist"
18
17
 
19
18
  module Google
20
19
  # Module Auth provides classes that provide Google-specific authorization
@@ -47,9 +46,9 @@ module Google
47
46
  # @private Unused and deprecated
48
47
  COMPUTE_CHECK_URI = "http://169.254.169.254".freeze
49
48
 
50
- class << self
51
- extend Memoist
49
+ @on_gce_cache = {}
52
50
 
51
+ class << self
53
52
  def metadata_host
54
53
  ENV.fetch "GCE_METADATA_HOST", DEFAULT_METADATA_HOST
55
54
  end
@@ -68,21 +67,30 @@ module Google
68
67
 
69
68
  # Detect if this appear to be a GCE instance, by checking if metadata
70
69
  # is available.
71
- def on_gce? options = {}
72
- # TODO: This should use google-cloud-env instead.
73
- c = options[:connection] || Faraday.default_connection
74
- headers = { "Metadata-Flavor" => "Google" }
75
- resp = c.get compute_check_uri, nil, headers do |req|
76
- req.options.timeout = 1.0
77
- req.options.open_timeout = 0.1
70
+ def on_gce? options = {}, reload = false # rubocop:disable Style/OptionalBooleanParameter
71
+ # We can follow OptionalBooleanParameter here because it's a public interface, we can't change it.
72
+ @on_gce_cache.delete options if reload
73
+ @on_gce_cache.fetch options do
74
+ @on_gce_cache[options] = begin
75
+ # TODO: This should use google-cloud-env instead.
76
+ c = options[:connection] || Faraday.default_connection
77
+ headers = { "Metadata-Flavor" => "Google" }
78
+ resp = c.get compute_check_uri, nil, headers do |req|
79
+ req.options.timeout = 1.0
80
+ req.options.open_timeout = 0.1
81
+ end
82
+ return false unless resp.status == 200
83
+ resp.headers["Metadata-Flavor"] == "Google"
84
+ rescue Faraday::TimeoutError, Faraday::ConnectionFailed
85
+ false
86
+ end
78
87
  end
79
- return false unless resp.status == 200
80
- resp.headers["Metadata-Flavor"] == "Google"
81
- rescue Faraday::TimeoutError, Faraday::ConnectionFailed
82
- false
83
88
  end
84
89
 
85
- memoize :on_gce?
90
+ def reset_cache
91
+ @on_gce_cache.clear
92
+ end
93
+ alias unmemoize_all reset_cache
86
94
  end
87
95
 
88
96
  # Overrides the super class method to change how access tokens are
@@ -50,10 +50,11 @@ module Google
50
50
  "s.googleusercontent.com".freeze
51
51
 
52
52
  CLOUD_SDK_CREDENTIALS_WARNING =
53
- "Your application has authenticated using end user credentials from Google Cloud SDK. We recommend that most " \
54
- "server applications use service accounts instead. If your application continues to use end user credentials " \
55
- 'from Cloud SDK, you might receive a "quota exceeded" or "API not enabled" error. For more information about ' \
56
- "service accounts, see https://cloud.google.com/docs/authentication/. To suppress this message, set the " \
53
+ "You are authenticating using user credentials." \
54
+ "For production, we recommend using service account credentials." \
55
+ "To learn more about service account credentials, see" \
56
+ "http://cloud.google.com/docs/authentication/external/set-up-adc-on-cloud " \
57
+ "To suppress this message, set the " \
57
58
  "GOOGLE_AUTH_SUPPRESS_CREDENTIALS_WARNINGS environment variable.".freeze
58
59
 
59
60
  # make_creds proxies the construction of a credentials instance
@@ -18,27 +18,60 @@ require "multi_json"
18
18
 
19
19
  module Google
20
20
  module Auth
21
- # Small utility for normalizing scopes into canonical form
21
+ ##
22
+ # Small utility for normalizing scopes into canonical form.
23
+ #
24
+ # The canonical form of scopes is as an array of strings, each in the form
25
+ # of a full URL. This utility converts space-delimited scope strings into
26
+ # this form, and handles a small number of common aliases.
27
+ #
28
+ # This is used by UserRefreshCredentials to verify that a credential grants
29
+ # a requested scope.
30
+ #
22
31
  module ScopeUtil
32
+ ##
33
+ # Aliases understood by this utility
34
+ #
23
35
  ALIASES = {
24
36
  "email" => "https://www.googleapis.com/auth/userinfo.email",
25
37
  "profile" => "https://www.googleapis.com/auth/userinfo.profile",
26
38
  "openid" => "https://www.googleapis.com/auth/plus.me"
27
39
  }.freeze
28
40
 
41
+ ##
42
+ # Normalize the input, which may be an array of scopes or a whitespace-
43
+ # delimited scope string. The output is always an array, even if a single
44
+ # scope is input.
45
+ #
46
+ # @param scope [String,Array<String>] Input scope(s)
47
+ # @return [Array<String>] An array of scopes in canonical form.
48
+ #
29
49
  def self.normalize scope
30
50
  list = as_array scope
31
51
  list.map { |item| ALIASES[item] || item }
32
52
  end
33
53
 
54
+ ##
55
+ # Ensure the input is an array. If a single string is passed in, splits
56
+ # it via whitespace. Does not interpret aliases.
57
+ #
58
+ # @param scope [String,Array<String>] Input scope(s)
59
+ # @return [Array<String>] Always an array of strings
60
+ # @raise ArgumentError If the input is not a string or array of strings
61
+ #
34
62
  def self.as_array scope
35
63
  case scope
36
64
  when Array
65
+ scope.each do |item|
66
+ unless item.is_a? String
67
+ raise ArgumentError, "Invalid scope value: #{item.inspect}. Must be string or array"
68
+ end
69
+ end
37
70
  scope
38
71
  when String
39
72
  scope.split
40
73
  else
41
- raise "Invalid scope value. Must be string or array"
74
+ raise ArgumentError, "Invalid scope value: #{scope.inspect}. Must be string or array"
42
75
  end
43
76
  end
44
77
  end
@@ -80,6 +80,8 @@ module Google
80
80
  # @param [String, Array<String>] scope
81
81
  # Authorization scope to request. Overrides the instance scopes if not
82
82
  # nil.
83
+ # @param [Hash] additional_parameters
84
+ # Additional query parameters to be added to the authorization URL.
83
85
  # @return [String]
84
86
  # Authorization url
85
87
  def get_authorization_url options = {}
@@ -87,7 +89,8 @@ module Google
87
89
  credentials = UserRefreshCredentials.new(
88
90
  client_id: @client_id.id,
89
91
  client_secret: @client_id.secret,
90
- scope: scope
92
+ scope: scope,
93
+ additional_parameters: options[:additional_parameters]
91
94
  )
92
95
  redirect_uri = redirect_uri_for options[:base_url]
93
96
  url = credentials.authorization_uri(access_type: "offline",
@@ -144,6 +147,9 @@ module Google
144
147
  # Absolute URL to resolve the configured callback uri against.
145
148
  # Required if the configured
146
149
  # callback uri is a relative.
150
+ # @param [Hash] additional_parameters
151
+ # Additional parameters to be added to the post body of token
152
+ # endpoint request.
147
153
  # @return [Google::Auth::UserRefreshCredentials]
148
154
  # Credentials if exchange is successful
149
155
  def get_credentials_from_code options = {}
@@ -152,10 +158,11 @@ module Google
152
158
  scope = options[:scope] || @scope
153
159
  base_url = options[:base_url]
154
160
  credentials = UserRefreshCredentials.new(
155
- client_id: @client_id.id,
156
- client_secret: @client_id.secret,
157
- redirect_uri: redirect_uri_for(base_url),
158
- scope: scope
161
+ client_id: @client_id.id,
162
+ client_secret: @client_id.secret,
163
+ redirect_uri: redirect_uri_for(base_url),
164
+ scope: scope,
165
+ additional_parameters: options[:additional_parameters]
159
166
  )
160
167
  credentials.code = code
161
168
  credentials.fetch_access_token!({})
@@ -16,6 +16,6 @@ module Google
16
16
  # Module Auth provides classes that provide Google-specific authorization
17
17
  # used to access Google APIs.
18
18
  module Auth
19
- VERSION = "1.7.0".freeze
19
+ VERSION = "1.8.0".freeze
20
20
  end
21
21
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: googleauth
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.7.0
4
+ version: 1.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tim Emiola
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-07-18 00:00:00.000000000 Z
11
+ date: 2023-09-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday
@@ -50,20 +50,6 @@ dependencies:
50
50
  - - "<"
51
51
  - !ruby/object:Gem::Version
52
52
  version: '3.0'
53
- - !ruby/object:Gem::Dependency
54
- name: memoist
55
- requirement: !ruby/object:Gem::Requirement
56
- requirements:
57
- - - "~>"
58
- - !ruby/object:Gem::Version
59
- version: '0.16'
60
- type: :runtime
61
- prerelease: false
62
- version_requirements: !ruby/object:Gem::Requirement
63
- requirements:
64
- - - "~>"
65
- - !ruby/object:Gem::Version
66
- version: '0.16'
67
53
  - !ruby/object:Gem::Dependency
68
54
  name: multi_json
69
55
  requirement: !ruby/object:Gem::Requirement
@@ -186,7 +172,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
186
172
  - !ruby/object:Gem::Version
187
173
  version: '0'
188
174
  requirements: []
189
- rubygems_version: 3.4.2
175
+ rubygems_version: 3.4.19
190
176
  signing_key:
191
177
  specification_version: 4
192
178
  summary: Google Auth Library for Ruby