googleauth 1.6.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: 146d1c41b29049fb35b0cc5c4934a811eb547f3d3000a95e3fbd8a24fc2b86bb
4
- data.tar.gz: cb613b51160da7a51c545728ce03dac8977fee8f1806b72eca97997d28645450
3
+ metadata.gz: 888e57705b33e87158d060b7b1569e54e00000428de35f979e7ffc9456cbb7b3
4
+ data.tar.gz: ac341b6c481df125091c1465b56642173591f5698baff6f4806b05216eca8802
5
5
  SHA512:
6
- metadata.gz: 39289ca31ac785dffbb151a71c6b8337d442db75e3d2d3fcfa94a4c5656076c5965c3beb09e55cc80996c189af170f9208dbb84df6adbb9b385ede36850ea6aa
7
- data.tar.gz: 442083ee198a5ae04f8924f2360b1512eff862d12f66327d22195dbd75c5475b8d912701d7e41ab21b7c6ceae8f196b229b1f376cf69cb36846f5787f52eeb37
6
+ metadata.gz: 0e9d2fd50c39bf83e86f9f31bbddb897d28ce908be1214849926c45ce7ad2fa0d8f48d70a01acc84c9fa49ddf1a3a3c0c5a87b9bdf1d3ae1b9430b739e709c67
7
+ data.tar.gz: f92483b4971ecc9d48a0b3656a76c694974c6b60153d6ea5ff0f1dd6c544da51b924aedbfa71956db2c1dada98a6cdaa632bb6f38c663e384acc8ebb3af8d1d2
data/CHANGELOG.md CHANGED
@@ -1,5 +1,23 @@
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
+
12
+ ### 1.7.0 (2023-07-14)
13
+
14
+ #### Features
15
+
16
+ * Adding support for pluggable auth credentials ([#437](https://github.com/googleapis/google-auth-library-ruby/issues/437))
17
+ #### Documentation
18
+
19
+ * fixed iss argument and description in comments of IDTokens ([#438](https://github.com/googleapis/google-auth-library-ruby/issues/438))
20
+
3
21
  ### 1.6.0 (2023-06-20)
4
22
 
5
23
  #### 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
@@ -86,6 +86,17 @@ module Google
86
86
  raise "Invalid time value #{time}"
87
87
  end
88
88
  end
89
+
90
+ def service_account_email
91
+ return nil if @service_account_impersonation_url.nil?
92
+ start_idx = @service_account_impersonation_url.rindex "/"
93
+ end_idx = @service_account_impersonation_url.index ":generateAccessToken"
94
+ if start_idx != -1 && end_idx != -1 && start_idx < end_idx
95
+ start_idx += 1
96
+ return @service_account_impersonation_url[start_idx..end_idx]
97
+ end
98
+ nil
99
+ end
89
100
  end
90
101
  end
91
102
  end
@@ -0,0 +1,156 @@
1
+ # Copyright 2023 Google, Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ require "open3"
16
+ require "time"
17
+ require "googleauth/external_account/base_credentials"
18
+ require "googleauth/external_account/external_account_utils"
19
+
20
+ module Google
21
+ # Module Auth provides classes that provide Google-specific authorization used to access Google APIs.
22
+ module Auth
23
+ module ExternalAccount
24
+ # This module handles the retrieval of credentials from Google Cloud by utilizing the any 3PI
25
+ # provider then exchanging the credentials for a short-lived Google Cloud access token.
26
+ class PluggableAuthCredentials
27
+ # constant for pluggable auth enablement in environment variable.
28
+ ENABLE_PLUGGABLE_ENV = "GOOGLE_EXTERNAL_ACCOUNT_ALLOW_EXECUTABLES".freeze
29
+ EXECUTABLE_SUPPORTED_MAX_VERSION = 1
30
+ EXECUTABLE_TIMEOUT_MILLIS_DEFAULT = 30 * 1000
31
+ EXECUTABLE_TIMEOUT_MILLIS_LOWER_BOUND = 5 * 1000
32
+ EXECUTABLE_TIMEOUT_MILLIS_UPPER_BOUND = 120 * 1000
33
+ ID_TOKEN_TYPE = ["urn:ietf:params:oauth:token-type:jwt", "urn:ietf:params:oauth:token-type:id_token"].freeze
34
+
35
+ include Google::Auth::ExternalAccount::BaseCredentials
36
+ include Google::Auth::ExternalAccount::ExternalAccountUtils
37
+ extend CredentialsLoader
38
+
39
+ # Will always be nil, but method still gets used.
40
+ attr_reader :client_id
41
+
42
+ # Initialize from options map.
43
+ #
44
+ # @param [string] audience
45
+ # @param [hash{symbol => value}] credential_source
46
+ # credential_source is a hash that contains either source file or url.
47
+ # credential_source_format is either text or json. To define how we parse the credential response.
48
+ #
49
+ def initialize options = {}
50
+ base_setup options
51
+
52
+ @audience = options[:audience]
53
+ @credential_source = options[:credential_source] || {}
54
+ @credential_source_executable = @credential_source[:executable]
55
+ raise "Missing excutable source. An 'executable' must be provided" if @credential_source_executable.nil?
56
+ @credential_source_executable_command = @credential_source_executable[:command]
57
+ if @credential_source_executable_command.nil?
58
+ raise "Missing command field. Executable command must be provided."
59
+ end
60
+ @credential_source_executable_timeout_millis = @credential_source_executable[:timeout_millis] ||
61
+ EXECUTABLE_TIMEOUT_MILLIS_DEFAULT
62
+ if @credential_source_executable_timeout_millis < EXECUTABLE_TIMEOUT_MILLIS_LOWER_BOUND ||
63
+ @credential_source_executable_timeout_millis > EXECUTABLE_TIMEOUT_MILLIS_UPPER_BOUND
64
+ raise "Timeout must be between 5 and 120 seconds."
65
+ end
66
+ @credential_source_executable_output_file = @credential_source_executable[:output_file]
67
+ end
68
+
69
+ def retrieve_subject_token!
70
+ unless ENV[ENABLE_PLUGGABLE_ENV] == "1"
71
+ raise "Executables need to be explicitly allowed (set GOOGLE_EXTERNAL_ACCOUNT_ALLOW_EXECUTABLES to '1') " \
72
+ "to run."
73
+ end
74
+ # check output file first
75
+ subject_token = load_subject_token_from_output_file
76
+ return subject_token unless subject_token.nil?
77
+ # environment variable injection
78
+ env = inject_environment_variables
79
+ output = subprocess_with_timeout env, @credential_source_executable_command,
80
+ @credential_source_executable_timeout_millis
81
+ response = MultiJson.load output, symbolize_keys: true
82
+ parse_subject_token response
83
+ end
84
+
85
+ private
86
+
87
+ def load_subject_token_from_output_file
88
+ return nil if @credential_source_executable_output_file.nil?
89
+ return nil unless File.exist? @credential_source_executable_output_file
90
+ begin
91
+ content = File.read @credential_source_executable_output_file, encoding: "utf-8"
92
+ response = MultiJson.load content, symbolize_keys: true
93
+ rescue StandardError
94
+ return nil
95
+ end
96
+ begin
97
+ subject_token = parse_subject_token response
98
+ rescue StandardError => e
99
+ return nil if e.message.match(/The token returned by the executable is expired/)
100
+ raise e
101
+ end
102
+ subject_token
103
+ end
104
+
105
+ def parse_subject_token response
106
+ validate_response_schema response
107
+ unless response[:success]
108
+ if response[:code].nil? || response[:message].nil?
109
+ raise "Error code and message fields are required in the response."
110
+ end
111
+ raise "Executable returned unsuccessful response: code: #{response[:code]}, message: #{response[:message]}."
112
+ end
113
+ if response[:expiration_time] && response[:expiration_time] < Time.now.to_i
114
+ raise "The token returned by the executable is expired."
115
+ end
116
+ raise "The executable response is missing the token_type field." if response[:token_type].nil?
117
+ return response[:id_token] if ID_TOKEN_TYPE.include? response[:token_type]
118
+ return response[:saml_response] if response[:token_type] == "urn:ietf:params:oauth:token-type:saml2"
119
+ raise "Executable returned unsupported token type."
120
+ end
121
+
122
+ def validate_response_schema response
123
+ raise "The executable response is missing the version field." if response[:version].nil?
124
+ if response[:version] > EXECUTABLE_SUPPORTED_MAX_VERSION
125
+ raise "Executable returned unsupported version #{response[:version]}."
126
+ end
127
+ raise "The executable response is missing the success field." if response[:success].nil?
128
+ end
129
+
130
+ def inject_environment_variables
131
+ env = ENV.to_h
132
+ env["GOOGLE_EXTERNAL_ACCOUNT_AUDIENCE"] = @audience
133
+ env["GOOGLE_EXTERNAL_ACCOUNT_TOKEN_TYPE"] = @subject_token_type
134
+ env["GOOGLE_EXTERNAL_ACCOUNT_INTERACTIVE"] = "0" # only non-interactive mode we support.
135
+ unless @service_account_impersonation_url.nil?
136
+ env["GOOGLE_EXTERNAL_ACCOUNT_IMPERSONATED_EMAIL"] = service_account_email
137
+ end
138
+ unless @credential_source_executable_output_file.nil?
139
+ env["GOOGLE_EXTERNAL_ACCOUNT_OUTPUT_FILE"] = @credential_source_executable_output_file
140
+ end
141
+ env
142
+ end
143
+
144
+ def subprocess_with_timeout environment_vars, command, timeout_seconds
145
+ Timeout.timeout timeout_seconds do
146
+ output, error, status = Open3.capture3 environment_vars, command
147
+ unless status.success?
148
+ raise "Executable exited with non-zero return code #{status.exitstatus}. Error: #{output}, #{error}"
149
+ end
150
+ output
151
+ end
152
+ end
153
+ end
154
+ end
155
+ end
156
+ end
@@ -17,6 +17,7 @@ require "uri"
17
17
  require "googleauth/credentials_loader"
18
18
  require "googleauth/external_account/aws_credentials"
19
19
  require "googleauth/external_account/identity_pool_credentials"
20
+ require "googleauth/external_account/pluggable_credentials"
20
21
 
21
22
  module Google
22
23
  # Module Auth provides classes that provide Google-specific authorization
@@ -80,6 +81,9 @@ module Google
80
81
  unless user_creds[:credential_source][:file].nil? && user_creds[:credential_source][:url].nil?
81
82
  return Google::Auth::ExternalAccount::IdentityPoolCredentials.new user_creds
82
83
  end
84
+ unless user_creds[:credential_source][:executable].nil?
85
+ return Google::Auth::ExternalAccount::PluggableAuthCredentials.new user_creds
86
+ end
83
87
  raise INVALID_EXTERNAL_ACCOUNT_TYPE
84
88
  end
85
89
  end
@@ -153,7 +153,7 @@ module Google
153
153
  # one of the provided values, or the verification will fail with
154
154
  # {Google::Auth::IDToken::AuthorizedPartyMismatchError}. If `nil`
155
155
  # (the default), no azp checking is performed.
156
- # @param aud [String,Array<String>,nil] The expected audience. At least
156
+ # @param iss [String,Array<String>,nil] The expected issuer. At least
157
157
  # one `iss` field in the token must match at least one of the
158
158
  # provided issuers, or the verification will fail with
159
159
  # {Google::Auth::IDToken::IssuerMismatchError}. If `nil`, no issuer
@@ -191,7 +191,7 @@ module Google
191
191
  # one of the provided values, or the verification will fail with
192
192
  # {Google::Auth::IDToken::AuthorizedPartyMismatchError}. If `nil`
193
193
  # (the default), no azp checking is performed.
194
- # @param aud [String,Array<String>,nil] The expected audience. At least
194
+ # @param iss [String,Array<String>,nil] The expected issuer. At least
195
195
  # one `iss` field in the token must match at least one of the
196
196
  # provided issuers, or the verification will fail with
197
197
  # {Google::Auth::IDToken::IssuerMismatchError}. If `nil`, no issuer
@@ -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.6.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.6.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-06-23 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
@@ -145,6 +131,7 @@ files:
145
131
  - lib/googleauth/external_account/base_credentials.rb
146
132
  - lib/googleauth/external_account/external_account_utils.rb
147
133
  - lib/googleauth/external_account/identity_pool_credentials.rb
134
+ - lib/googleauth/external_account/pluggable_credentials.rb
148
135
  - lib/googleauth/helpers/connection.rb
149
136
  - lib/googleauth/iam.rb
150
137
  - lib/googleauth/id_tokens.rb
@@ -185,7 +172,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
185
172
  - !ruby/object:Gem::Version
186
173
  version: '0'
187
174
  requirements: []
188
- rubygems_version: 3.4.2
175
+ rubygems_version: 3.4.19
189
176
  signing_key:
190
177
  specification_version: 4
191
178
  summary: Google Auth Library for Ruby