googleauth 1.2.0 → 1.11.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/CHANGELOG.md +99 -0
 - data/README.md +49 -8
 - data/lib/googleauth/application_default.rb +5 -9
 - data/lib/googleauth/base_client.rb +80 -0
 - data/lib/googleauth/client_id.rb +25 -8
 - data/lib/googleauth/compute_engine.rb +65 -35
 - data/lib/googleauth/credentials.rb +32 -30
 - data/lib/googleauth/credentials_loader.rb +6 -14
 - data/lib/googleauth/default_credentials.rb +5 -2
 - data/lib/googleauth/external_account/aws_credentials.rb +378 -0
 - data/lib/googleauth/external_account/base_credentials.rb +159 -0
 - data/lib/googleauth/external_account/external_account_utils.rb +103 -0
 - data/lib/googleauth/external_account/identity_pool_credentials.rb +118 -0
 - data/lib/googleauth/external_account/pluggable_credentials.rb +156 -0
 - data/lib/googleauth/external_account.rb +94 -0
 - data/lib/googleauth/helpers/connection.rb +35 -0
 - data/lib/googleauth/id_tokens/key_sources.rb +9 -10
 - data/lib/googleauth/id_tokens.rb +2 -2
 - data/lib/googleauth/json_key_reader.rb +2 -1
 - data/lib/googleauth/oauth2/sts_client.rb +109 -0
 - data/lib/googleauth/scope_util.rb +35 -2
 - data/lib/googleauth/service_account.rb +25 -11
 - data/lib/googleauth/signet.rb +14 -38
 - data/lib/googleauth/user_authorizer.rb +66 -9
 - data/lib/googleauth/user_refresh.rb +4 -2
 - data/lib/googleauth/version.rb +1 -1
 - data/lib/googleauth/web_user_authorizer.rb +19 -8
 - metadata +29 -20
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
2 
     | 
    
         
             
            SHA256:
         
     | 
| 
       3 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       4 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: 4912a601c0a234fa9faf150d7461cab993f775b715f6ac7d19db017ceae74e6d
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: e08da21e12d58260944079d068a04099fa0c812eb486e760a3ab12dd002700f4
         
     | 
| 
       5 
5 
     | 
    
         
             
            SHA512:
         
     | 
| 
       6 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       7 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: b0346fcaf38cb783fd4d22f0734994298d63dfa1a89fd34df4d4f42b87160de410e34c93ab4773c3bbaf03b41160f10e3fd5bc0fa137d1ab6fb5dce15f72ba53
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: c5ff10a04491e9f56dff9bcea24c67398e67713efc89c2d378075621da837b59c5fdbd36c0b97d5753fd0358befe8ce2ceacc86af1cce0a1c54d609d916903c6
         
     | 
    
        data/CHANGELOG.md
    CHANGED
    
    | 
         @@ -1,5 +1,104 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            # Release History
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
      
 3 
     | 
    
         
            +
            ### 1.11.0 (2024-02-09)
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            #### Features
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            * Deprecate the positional argument for callback_uri, and introduce keyword argument instead ([#475](https://github.com/googleapis/google-auth-library-ruby/issues/475)) 
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            ### 1.10.0 (2024-02-08)
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
            #### Features
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
            * add PKCE to 3 Legged OAuth exchange ([#471](https://github.com/googleapis/google-auth-library-ruby/issues/471)) 
         
     | 
| 
      
 14 
     | 
    
         
            +
            #### Bug Fixes
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
            * Client library credentials provide correct self-signed JWT and external account behavior when loading from a file path or JSON data ([#474](https://github.com/googleapis/google-auth-library-ruby/issues/474)) 
         
     | 
| 
      
 17 
     | 
    
         
            +
            * Prioritize universe domain specified in GCECredentials arguments over metadata-fetched value ([#472](https://github.com/googleapis/google-auth-library-ruby/issues/472)) 
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
            ### 1.9.2 (2024-01-25)
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
            #### Bug Fixes
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
            * Prevent access tokens from being fetched at service account construction in the self-signed-jwt case ([#467](https://github.com/googleapis/google-auth-library-ruby/issues/467)) 
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
            ### 1.9.1 (2023-12-12)
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
            #### Bug Fixes
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
            * update expires_in for cached metadata-retrieved tokens ([#464](https://github.com/googleapis/google-auth-library-ruby/issues/464)) 
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
            ### 1.9.0 (2023-12-07)
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
            #### Features
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
            * Include universe_domain in credentials ([#460](https://github.com/googleapis/google-auth-library-ruby/issues/460)) 
         
     | 
| 
      
 36 
     | 
    
         
            +
            * Use google-cloud-env for more robust Metadata Service access ([#459](https://github.com/googleapis/google-auth-library-ruby/issues/459)) 
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
            ### 1.8.1 (2023-09-19)
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
            #### Documentation
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
            * improve ADC related error and warning messages ([#452](https://github.com/googleapis/google-auth-library-ruby/issues/452)) 
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
            ### 1.8.0 (2023-09-07)
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
            #### Features
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
            * Pass additional parameters to auhtorization url ([#447](https://github.com/googleapis/google-auth-library-ruby/issues/447)) 
         
     | 
| 
      
 49 
     | 
    
         
            +
            #### Documentation
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
            * improve ADC related error and warning messages ([#449](https://github.com/googleapis/google-auth-library-ruby/issues/449)) 
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
            ### 1.7.0 (2023-07-14)
         
     | 
| 
      
 54 
     | 
    
         
            +
             
     | 
| 
      
 55 
     | 
    
         
            +
            #### Features
         
     | 
| 
      
 56 
     | 
    
         
            +
             
     | 
| 
      
 57 
     | 
    
         
            +
            * Adding support for pluggable auth credentials ([#437](https://github.com/googleapis/google-auth-library-ruby/issues/437)) 
         
     | 
| 
      
 58 
     | 
    
         
            +
            #### Documentation
         
     | 
| 
      
 59 
     | 
    
         
            +
             
     | 
| 
      
 60 
     | 
    
         
            +
            * fixed iss argument and description in comments of IDTokens ([#438](https://github.com/googleapis/google-auth-library-ruby/issues/438)) 
         
     | 
| 
      
 61 
     | 
    
         
            +
             
     | 
| 
      
 62 
     | 
    
         
            +
            ### 1.6.0 (2023-06-20)
         
     | 
| 
      
 63 
     | 
    
         
            +
             
     | 
| 
      
 64 
     | 
    
         
            +
            #### Features
         
     | 
| 
      
 65 
     | 
    
         
            +
             
     | 
| 
      
 66 
     | 
    
         
            +
            * adding identity pool credentials ([#433](https://github.com/googleapis/google-auth-library-ruby/issues/433)) 
         
     | 
| 
      
 67 
     | 
    
         
            +
            #### Documentation
         
     | 
| 
      
 68 
     | 
    
         
            +
             
     | 
| 
      
 69 
     | 
    
         
            +
            * deprecation message for discontinuing command line auth flow ([#435](https://github.com/googleapis/google-auth-library-ruby/issues/435)) 
         
     | 
| 
      
 70 
     | 
    
         
            +
             
     | 
| 
      
 71 
     | 
    
         
            +
            ### 1.5.2 (2023-04-13)
         
     | 
| 
      
 72 
     | 
    
         
            +
             
     | 
| 
      
 73 
     | 
    
         
            +
            #### Bug Fixes
         
     | 
| 
      
 74 
     | 
    
         
            +
             
     | 
| 
      
 75 
     | 
    
         
            +
            * AWS IMDSV2 session token fetching shall call PUT method instead of GET ([#429](https://github.com/googleapis/google-auth-library-ruby/issues/429)) 
         
     | 
| 
      
 76 
     | 
    
         
            +
            * GCECredentials - Allow retrieval of ID token ([#425](https://github.com/googleapis/google-auth-library-ruby/issues/425)) 
         
     | 
| 
      
 77 
     | 
    
         
            +
             
     | 
| 
      
 78 
     | 
    
         
            +
            ### 1.5.1 (2023-04-10)
         
     | 
| 
      
 79 
     | 
    
         
            +
             
     | 
| 
      
 80 
     | 
    
         
            +
            #### Bug Fixes
         
     | 
| 
      
 81 
     | 
    
         
            +
             
     | 
| 
      
 82 
     | 
    
         
            +
            * Remove external account config validation ([#427](https://github.com/googleapis/google-auth-library-ruby/issues/427)) 
         
     | 
| 
      
 83 
     | 
    
         
            +
             
     | 
| 
      
 84 
     | 
    
         
            +
            ### 1.5.0 (2023-03-21)
         
     | 
| 
      
 85 
     | 
    
         
            +
             
     | 
| 
      
 86 
     | 
    
         
            +
            #### Features
         
     | 
| 
      
 87 
     | 
    
         
            +
             
     | 
| 
      
 88 
     | 
    
         
            +
            * Add support for AWS Workload Identity Federation ([#418](https://github.com/googleapis/google-auth-library-ruby/issues/418)) 
         
     | 
| 
      
 89 
     | 
    
         
            +
             
     | 
| 
      
 90 
     | 
    
         
            +
            ### 1.4.0 (2022-12-14)
         
     | 
| 
      
 91 
     | 
    
         
            +
             
     | 
| 
      
 92 
     | 
    
         
            +
            #### Features
         
     | 
| 
      
 93 
     | 
    
         
            +
             
     | 
| 
      
 94 
     | 
    
         
            +
            * make new_jwt_token public in order to fetch raw token directly ([#405](https://github.com/googleapis/google-auth-library-ruby/issues/405)) 
         
     | 
| 
      
 95 
     | 
    
         
            +
             
     | 
| 
      
 96 
     | 
    
         
            +
            ### 1.3.0 (2022-10-18)
         
     | 
| 
      
 97 
     | 
    
         
            +
             
     | 
| 
      
 98 
     | 
    
         
            +
            #### Features
         
     | 
| 
      
 99 
     | 
    
         
            +
             
     | 
| 
      
 100 
     | 
    
         
            +
            * Use OpenSSL 3.0 compatible interfaces for IDTokens ([#397](https://github.com/googleapis/google-auth-library-ruby/issues/397)) 
         
     | 
| 
      
 101 
     | 
    
         
            +
             
     | 
| 
       3 
102 
     | 
    
         
             
            ### 1.2.0 (2022-06-23)
         
     | 
| 
       4 
103 
     | 
    
         | 
| 
       5 
104 
     | 
    
         
             
            * Updated minimum Ruby version to 2.6
         
     | 
    
        data/README.md
    CHANGED
    
    | 
         @@ -97,7 +97,48 @@ get('/oauth2callback') do 
     | 
|
| 
       97 
97 
     | 
    
         
             
            end
         
     | 
| 
       98 
98 
     | 
    
         
             
            ```
         
     | 
| 
       99 
99 
     | 
    
         | 
| 
       100 
     | 
    
         
            -
            ### Example ( 
     | 
| 
      
 100 
     | 
    
         
            +
            ### Example (Web with PKCE)
         
     | 
| 
      
 101 
     | 
    
         
            +
             
     | 
| 
      
 102 
     | 
    
         
            +
            Proof Key for Code Exchange (PKCE) is an [RFC](https://www.rfc-editor.org/rfc/rfc7636) that aims to prevent malicious operating system processes from hijacking an OAUTH 2.0 exchange. PKCE mitigates the above vulnerability by including `code_challenge` and `code_challenge_method` parameters in the Authorization Request and a `code_verifier` parameter in the Access Token Request.
         
     | 
| 
      
 103 
     | 
    
         
            +
             
     | 
| 
      
 104 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 105 
     | 
    
         
            +
            require 'googleauth'
         
     | 
| 
      
 106 
     | 
    
         
            +
            require 'googleauth/web_user_authorizer'
         
     | 
| 
      
 107 
     | 
    
         
            +
            require 'googleauth/stores/redis_token_store'
         
     | 
| 
      
 108 
     | 
    
         
            +
            require 'redis'
         
     | 
| 
      
 109 
     | 
    
         
            +
             
     | 
| 
      
 110 
     | 
    
         
            +
            client_id = Google::Auth::ClientId.from_file('/path/to/client_secrets.json')
         
     | 
| 
      
 111 
     | 
    
         
            +
            scope = ['https://www.googleapis.com/auth/drive']
         
     | 
| 
      
 112 
     | 
    
         
            +
            token_store = Google::Auth::Stores::RedisTokenStore.new(redis: Redis.new)
         
     | 
| 
      
 113 
     | 
    
         
            +
            authorizer = Google::Auth::WebUserAuthorizer.new(
         
     | 
| 
      
 114 
     | 
    
         
            +
              client_id, scope, token_store, '/oauth2callback')
         
     | 
| 
      
 115 
     | 
    
         
            +
             
     | 
| 
      
 116 
     | 
    
         
            +
             
     | 
| 
      
 117 
     | 
    
         
            +
            get('/authorize') do
         
     | 
| 
      
 118 
     | 
    
         
            +
              # NOTE: Assumes the user is already authenticated to the app
         
     | 
| 
      
 119 
     | 
    
         
            +
              user_id = request.session['user_id']
         
     | 
| 
      
 120 
     | 
    
         
            +
              # User needs to take care of generating the code_verifier and storing it in
         
     | 
| 
      
 121 
     | 
    
         
            +
              # the session.
         
     | 
| 
      
 122 
     | 
    
         
            +
              request.session['code_verifier'] ||= Google::Auth::WebUserAuthorizer.generate_code_verifier
         
     | 
| 
      
 123 
     | 
    
         
            +
              authorizer.code_verifier = request.session['code_verifier']
         
     | 
| 
      
 124 
     | 
    
         
            +
              credentials = authorizer.get_credentials(user_id, request)
         
     | 
| 
      
 125 
     | 
    
         
            +
              if credentials.nil?
         
     | 
| 
      
 126 
     | 
    
         
            +
                redirect authorizer.get_authorization_url(login_hint: user_id, request: request)
         
     | 
| 
      
 127 
     | 
    
         
            +
              end
         
     | 
| 
      
 128 
     | 
    
         
            +
              # Credentials are valid, can call APIs
         
     | 
| 
      
 129 
     | 
    
         
            +
              # ...
         
     | 
| 
      
 130 
     | 
    
         
            +
            end
         
     | 
| 
      
 131 
     | 
    
         
            +
             
     | 
| 
      
 132 
     | 
    
         
            +
            get('/oauth2callback') do
         
     | 
| 
      
 133 
     | 
    
         
            +
              target_url = Google::Auth::WebUserAuthorizer.handle_auth_callback_deferred(
         
     | 
| 
      
 134 
     | 
    
         
            +
                request)
         
     | 
| 
      
 135 
     | 
    
         
            +
              redirect target_url
         
     | 
| 
      
 136 
     | 
    
         
            +
            end
         
     | 
| 
      
 137 
     | 
    
         
            +
            ```
         
     | 
| 
      
 138 
     | 
    
         
            +
             
     | 
| 
      
 139 
     | 
    
         
            +
            ### Example (Command Line) [Deprecated]
         
     | 
| 
      
 140 
     | 
    
         
            +
             
     | 
| 
      
 141 
     | 
    
         
            +
            The Google Auth OOB flow has been discontiued on January 31, 2023. The OOB flow is a legacy flow that is no longer considered secure. To continue using Google Auth, please migrate your applications to a more secure flow. For more information on how to do this, please refer to this [OOB Migration](https://developers.google.com/identity/protocols/oauth2/resources/oob-migration) guide.
         
     | 
| 
       101 
142 
     | 
    
         | 
| 
       102 
143 
     | 
    
         
             
            ```ruby
         
     | 
| 
       103 
144 
     | 
    
         
             
            require 'googleauth'
         
     | 
| 
         @@ -215,14 +256,14 @@ Custom storage implementations can also be used. See 
     | 
|
| 
       215 
256 
     | 
    
         | 
| 
       216 
257 
     | 
    
         
             
            ## Supported Ruby Versions
         
     | 
| 
       217 
258 
     | 
    
         | 
| 
       218 
     | 
    
         
            -
            This library is supported on Ruby 2. 
     | 
| 
      
 259 
     | 
    
         
            +
            This library is supported on Ruby 2.6+.
         
     | 
| 
       219 
260 
     | 
    
         | 
| 
       220 
261 
     | 
    
         
             
            Google provides official support for Ruby versions that are actively supported
         
     | 
| 
       221 
     | 
    
         
            -
            by Ruby Core—that is, Ruby versions that are either in normal maintenance or 
     | 
| 
       222 
     | 
    
         
            -
            security maintenance, and not end of life.  
     | 
| 
       223 
     | 
    
         
            -
             
     | 
| 
       224 
     | 
    
         
            -
             
     | 
| 
       225 
     | 
    
         
            -
             
     | 
| 
      
 262 
     | 
    
         
            +
            by Ruby Core—that is, Ruby versions that are either in normal maintenance or
         
     | 
| 
      
 263 
     | 
    
         
            +
            in security maintenance, and not end of life. Older versions of Ruby _may_
         
     | 
| 
      
 264 
     | 
    
         
            +
            still work, but are unsupported and not recommended. See
         
     | 
| 
      
 265 
     | 
    
         
            +
            https://www.ruby-lang.org/en/downloads/branches/ for details about the Ruby
         
     | 
| 
      
 266 
     | 
    
         
            +
            support schedule.
         
     | 
| 
       226 
267 
     | 
    
         | 
| 
       227 
268 
     | 
    
         
             
            ## License
         
     | 
| 
       228 
269 
     | 
    
         | 
| 
         @@ -241,6 +282,6 @@ hesitate to 
     | 
|
| 
       241 
282 
     | 
    
         
             
            [ask questions](http://stackoverflow.com/questions/tagged/google-auth-library-ruby)
         
     | 
| 
       242 
283 
     | 
    
         
             
            about the client or APIs on [StackOverflow](http://stackoverflow.com).
         
     | 
| 
       243 
284 
     | 
    
         | 
| 
       244 
     | 
    
         
            -
            [application default credentials]: https:// 
     | 
| 
      
 285 
     | 
    
         
            +
            [application default credentials]: https://cloud.google.com/docs/authentication/provide-credentials-adc
         
     | 
| 
       245 
286 
     | 
    
         
             
            [contributing]: https://github.com/googleapis/google-auth-library-ruby/tree/main/.github/CONTRIBUTING.md
         
     | 
| 
       246 
287 
     | 
    
         
             
            [license]: https://github.com/googleapis/google-auth-library-ruby/tree/main/LICENSE
         
     | 
| 
         @@ -20,9 +20,9 @@ module Google 
     | 
|
| 
       20 
20 
     | 
    
         
             
              # used to access Google APIs.
         
     | 
| 
       21 
21 
     | 
    
         
             
              module Auth
         
     | 
| 
       22 
22 
     | 
    
         
             
                NOT_FOUND_ERROR = <<~ERROR_MESSAGE.freeze
         
     | 
| 
       23 
     | 
    
         
            -
                   
     | 
| 
       24 
     | 
    
         
            -
                   
     | 
| 
       25 
     | 
    
         
            -
                   
     | 
| 
      
 23 
     | 
    
         
            +
                  Your credentials were not found. To set up Application Default
         
     | 
| 
      
 24 
     | 
    
         
            +
                  Credentials for your environment, see
         
     | 
| 
      
 25 
     | 
    
         
            +
                  https://cloud.google.com/docs/authentication/external/set-up-adc
         
     | 
| 
       26 
26 
     | 
    
         
             
                ERROR_MESSAGE
         
     | 
| 
       27 
27 
     | 
    
         | 
| 
       28 
28 
     | 
    
         
             
                module_function
         
     | 
| 
         @@ -55,12 +55,8 @@ module Google 
     | 
|
| 
       55 
55 
     | 
    
         
             
                          DefaultCredentials.from_well_known_path(scope, options) ||
         
     | 
| 
       56 
56 
     | 
    
         
             
                          DefaultCredentials.from_system_default_path(scope, options)
         
     | 
| 
       57 
57 
     | 
    
         
             
                  return creds unless creds.nil?
         
     | 
| 
       58 
     | 
    
         
            -
                  unless GCECredentials.on_gce? options
         
     | 
| 
       59 
     | 
    
         
            -
             
     | 
| 
       60 
     | 
    
         
            -
                    GCECredentials.unmemoize_all
         
     | 
| 
       61 
     | 
    
         
            -
                    raise NOT_FOUND_ERROR
         
     | 
| 
       62 
     | 
    
         
            -
                  end
         
     | 
| 
       63 
     | 
    
         
            -
                  GCECredentials.new scope: scope
         
     | 
| 
      
 58 
     | 
    
         
            +
                  raise NOT_FOUND_ERROR unless GCECredentials.on_gce? options
         
     | 
| 
      
 59 
     | 
    
         
            +
                  GCECredentials.new options.merge(scope: scope)
         
     | 
| 
       64 
60 
     | 
    
         
             
                end
         
     | 
| 
       65 
61 
     | 
    
         
             
              end
         
     | 
| 
       66 
62 
     | 
    
         
             
            end
         
     | 
| 
         @@ -0,0 +1,80 @@ 
     | 
|
| 
      
 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 
     | 
    
         
            +
            module Google
         
     | 
| 
      
 16 
     | 
    
         
            +
              # Module Auth provides classes that provide Google-specific authorization
         
     | 
| 
      
 17 
     | 
    
         
            +
              # used to access Google APIs.
         
     | 
| 
      
 18 
     | 
    
         
            +
              module Auth
         
     | 
| 
      
 19 
     | 
    
         
            +
                # BaseClient is a class used to contain common methods that are required by any
         
     | 
| 
      
 20 
     | 
    
         
            +
                # Credentials Client, including AwsCredentials, ServiceAccountCredentials,
         
     | 
| 
      
 21 
     | 
    
         
            +
                # and UserRefreshCredentials. This is a superclass of Signet::OAuth2::Client
         
     | 
| 
      
 22 
     | 
    
         
            +
                # and has been created to create a generic interface for all credentials clients
         
     | 
| 
      
 23 
     | 
    
         
            +
                # to use, including ones which do not inherit from Signet::OAuth2::Client.
         
     | 
| 
      
 24 
     | 
    
         
            +
                module BaseClient
         
     | 
| 
      
 25 
     | 
    
         
            +
                  AUTH_METADATA_KEY = :authorization
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
                  # Updates a_hash updated with the authentication token
         
     | 
| 
      
 28 
     | 
    
         
            +
                  def apply! a_hash, opts = {}
         
     | 
| 
      
 29 
     | 
    
         
            +
                    # fetch the access token there is currently not one, or if the client
         
     | 
| 
      
 30 
     | 
    
         
            +
                    # has expired
         
     | 
| 
      
 31 
     | 
    
         
            +
                    fetch_access_token! opts if needs_access_token?
         
     | 
| 
      
 32 
     | 
    
         
            +
                    a_hash[AUTH_METADATA_KEY] = "Bearer #{send token_type}"
         
     | 
| 
      
 33 
     | 
    
         
            +
                  end
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
                  # Returns a clone of a_hash updated with the authentication token
         
     | 
| 
      
 36 
     | 
    
         
            +
                  def apply a_hash, opts = {}
         
     | 
| 
      
 37 
     | 
    
         
            +
                    a_copy = a_hash.clone
         
     | 
| 
      
 38 
     | 
    
         
            +
                    apply! a_copy, opts
         
     | 
| 
      
 39 
     | 
    
         
            +
                    a_copy
         
     | 
| 
      
 40 
     | 
    
         
            +
                  end
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
                  # Whether the id_token or access_token is missing or about to expire.
         
     | 
| 
      
 43 
     | 
    
         
            +
                  def needs_access_token?
         
     | 
| 
      
 44 
     | 
    
         
            +
                    send(token_type).nil? || expires_within?(60)
         
     | 
| 
      
 45 
     | 
    
         
            +
                  end
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
                  # Returns a reference to the #apply method, suitable for passing as
         
     | 
| 
      
 48 
     | 
    
         
            +
                  # a closure
         
     | 
| 
      
 49 
     | 
    
         
            +
                  def updater_proc
         
     | 
| 
      
 50 
     | 
    
         
            +
                    proc { |a_hash, opts = {}| apply a_hash, opts }
         
     | 
| 
      
 51 
     | 
    
         
            +
                  end
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
                  def on_refresh &block
         
     | 
| 
      
 54 
     | 
    
         
            +
                    @refresh_listeners = [] unless defined? @refresh_listeners
         
     | 
| 
      
 55 
     | 
    
         
            +
                    @refresh_listeners << block
         
     | 
| 
      
 56 
     | 
    
         
            +
                  end
         
     | 
| 
      
 57 
     | 
    
         
            +
             
     | 
| 
      
 58 
     | 
    
         
            +
                  def notify_refresh_listeners
         
     | 
| 
      
 59 
     | 
    
         
            +
                    listeners = defined?(@refresh_listeners) ? @refresh_listeners : []
         
     | 
| 
      
 60 
     | 
    
         
            +
                    listeners.each do |block|
         
     | 
| 
      
 61 
     | 
    
         
            +
                      block.call self
         
     | 
| 
      
 62 
     | 
    
         
            +
                    end
         
     | 
| 
      
 63 
     | 
    
         
            +
                  end
         
     | 
| 
      
 64 
     | 
    
         
            +
             
     | 
| 
      
 65 
     | 
    
         
            +
                  def expires_within?
         
     | 
| 
      
 66 
     | 
    
         
            +
                    raise NotImplementedError
         
     | 
| 
      
 67 
     | 
    
         
            +
                  end
         
     | 
| 
      
 68 
     | 
    
         
            +
             
     | 
| 
      
 69 
     | 
    
         
            +
                  private
         
     | 
| 
      
 70 
     | 
    
         
            +
             
     | 
| 
      
 71 
     | 
    
         
            +
                  def token_type
         
     | 
| 
      
 72 
     | 
    
         
            +
                    raise NotImplementedError
         
     | 
| 
      
 73 
     | 
    
         
            +
                  end
         
     | 
| 
      
 74 
     | 
    
         
            +
             
     | 
| 
      
 75 
     | 
    
         
            +
                  def fetch_access_token!
         
     | 
| 
      
 76 
     | 
    
         
            +
                    raise NotImplementedError
         
     | 
| 
      
 77 
     | 
    
         
            +
                  end
         
     | 
| 
      
 78 
     | 
    
         
            +
                end
         
     | 
| 
      
 79 
     | 
    
         
            +
              end
         
     | 
| 
      
 80 
     | 
    
         
            +
            end
         
     | 
    
        data/lib/googleauth/client_id.rb
    CHANGED
    
    | 
         @@ -17,51 +17,67 @@ require "googleauth/credentials_loader" 
     | 
|
| 
       17 
17 
     | 
    
         | 
| 
       18 
18 
     | 
    
         
             
            module Google
         
     | 
| 
       19 
19 
     | 
    
         
             
              module Auth
         
     | 
| 
       20 
     | 
    
         
            -
                 
     | 
| 
       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 
     | 
    
         
            -
                   
     | 
| 
      
 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  
     | 
| 
       49 
     | 
    
         
            -
                  #        
     | 
| 
      
 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 
     | 
    
         
            -
                    CredentialsLoader.warn_if_cloud_sdk_credentials id
         
     | 
| 
       53 
67 
     | 
    
         
             
                    raise "Client id can not be nil" if id.nil?
         
     | 
| 
       54 
68 
     | 
    
         
             
                    raise "Client secret can not be nil" if secret.nil?
         
     | 
| 
       55 
69 
     | 
    
         
             
                    @id = id
         
     | 
| 
       56 
70 
     | 
    
         
             
                    @secret = secret
         
     | 
| 
       57 
71 
     | 
    
         
             
                  end
         
     | 
| 
       58 
72 
     | 
    
         | 
| 
      
 73 
     | 
    
         
            +
                  ##
         
     | 
| 
       59 
74 
     | 
    
         
             
                  # Constructs a Client ID from a JSON file downloaded from the
         
     | 
| 
       60 
75 
     | 
    
         
             
                  # Google Developers Console.
         
     | 
| 
       61 
76 
     | 
    
         
             
                  #
         
     | 
| 
       62 
77 
     | 
    
         
             
                  # @param [String, File] file
         
     | 
| 
       63 
78 
     | 
    
         
             
                  #  Path of file to read from
         
     | 
| 
       64 
79 
     | 
    
         
             
                  # @return [Google::Auth::ClientID]
         
     | 
| 
      
 80 
     | 
    
         
            +
                  #
         
     | 
| 
       65 
81 
     | 
    
         
             
                  def self.from_file file
         
     | 
| 
       66 
82 
     | 
    
         
             
                    raise "File can not be nil." if file.nil?
         
     | 
| 
       67 
83 
     | 
    
         
             
                    File.open file.to_s do |f|
         
     | 
| 
         @@ -71,13 +87,14 @@ module Google 
     | 
|
| 
       71 
87 
     | 
    
         
             
                    end
         
     | 
| 
       72 
88 
     | 
    
         
             
                  end
         
     | 
| 
       73 
89 
     | 
    
         | 
| 
      
 90 
     | 
    
         
            +
                  ##
         
     | 
| 
       74 
91 
     | 
    
         
             
                  # Constructs a Client ID from a previously loaded JSON file. The hash
         
     | 
| 
       75 
     | 
    
         
            -
                  # structure should
         
     | 
| 
       76 
     | 
    
         
            -
                  # match the expected JSON format.
         
     | 
| 
      
 92 
     | 
    
         
            +
                  # structure should match the expected JSON format.
         
     | 
| 
       77 
93 
     | 
    
         
             
                  #
         
     | 
| 
       78 
94 
     | 
    
         
             
                  # @param [hash] config
         
     | 
| 
       79 
95 
     | 
    
         
             
                  #  Parsed contents of the JSON file
         
     | 
| 
       80 
96 
     | 
    
         
             
                  # @return [Google::Auth::ClientID]
         
     | 
| 
      
 97 
     | 
    
         
            +
                  #
         
     | 
| 
       81 
98 
     | 
    
         
             
                  def self.from_hash config
         
     | 
| 
       82 
99 
     | 
    
         
             
                    raise "Hash can not be nil." if config.nil?
         
     | 
| 
       83 
100 
     | 
    
         
             
                    raw_detail = config[INSTALLED_APP] || config[WEB_APP]
         
     | 
| 
         @@ -12,9 +12,8 @@ 
     | 
|
| 
       12 
12 
     | 
    
         
             
            # See the License for the specific language governing permissions and
         
     | 
| 
       13 
13 
     | 
    
         
             
            # limitations under the License.
         
     | 
| 
       14 
14 
     | 
    
         | 
| 
       15 
     | 
    
         
            -
            require " 
     | 
| 
      
 15 
     | 
    
         
            +
            require "google-cloud-env"
         
     | 
| 
       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
         
     | 
| 
         @@ -34,74 +33,77 @@ module Google 
     | 
|
| 
       34 
33 
     | 
    
         
             
                # Extends Signet::OAuth2::Client so that the auth token is obtained from
         
     | 
| 
       35 
34 
     | 
    
         
             
                # the GCE metadata server.
         
     | 
| 
       36 
35 
     | 
    
         
             
                class GCECredentials < Signet::OAuth2::Client
         
     | 
| 
       37 
     | 
    
         
            -
                  #  
     | 
| 
       38 
     | 
    
         
            -
                  # systems.
         
     | 
| 
      
 36 
     | 
    
         
            +
                  # @private Unused and deprecated but retained to prevent breaking changes
         
     | 
| 
       39 
37 
     | 
    
         
             
                  DEFAULT_METADATA_HOST = "169.254.169.254".freeze
         
     | 
| 
       40 
38 
     | 
    
         | 
| 
       41 
     | 
    
         
            -
                  # @private Unused and deprecated
         
     | 
| 
      
 39 
     | 
    
         
            +
                  # @private Unused and deprecated but retained to prevent breaking changes
         
     | 
| 
       42 
40 
     | 
    
         
             
                  COMPUTE_AUTH_TOKEN_URI =
         
     | 
| 
       43 
41 
     | 
    
         
             
                    "http://169.254.169.254/computeMetadata/v1/instance/service-accounts/default/token".freeze
         
     | 
| 
       44 
     | 
    
         
            -
                  # @private Unused and deprecated
         
     | 
| 
      
 42 
     | 
    
         
            +
                  # @private Unused and deprecated but retained to prevent breaking changes
         
     | 
| 
       45 
43 
     | 
    
         
             
                  COMPUTE_ID_TOKEN_URI =
         
     | 
| 
       46 
44 
     | 
    
         
             
                    "http://169.254.169.254/computeMetadata/v1/instance/service-accounts/default/identity".freeze
         
     | 
| 
       47 
     | 
    
         
            -
                  # @private Unused and deprecated
         
     | 
| 
      
 45 
     | 
    
         
            +
                  # @private Unused and deprecated but retained to prevent breaking changes
         
     | 
| 
       48 
46 
     | 
    
         
             
                  COMPUTE_CHECK_URI = "http://169.254.169.254".freeze
         
     | 
| 
       49 
47 
     | 
    
         | 
| 
       50 
48 
     | 
    
         
             
                  class << self
         
     | 
| 
       51 
     | 
    
         
            -
                     
     | 
| 
       52 
     | 
    
         
            -
             
     | 
| 
      
 49 
     | 
    
         
            +
                    # @private Unused and deprecated
         
     | 
| 
       53 
50 
     | 
    
         
             
                    def metadata_host
         
     | 
| 
       54 
51 
     | 
    
         
             
                      ENV.fetch "GCE_METADATA_HOST", DEFAULT_METADATA_HOST
         
     | 
| 
       55 
52 
     | 
    
         
             
                    end
         
     | 
| 
       56 
53 
     | 
    
         | 
| 
      
 54 
     | 
    
         
            +
                    # @private Unused and deprecated
         
     | 
| 
       57 
55 
     | 
    
         
             
                    def compute_check_uri
         
     | 
| 
       58 
56 
     | 
    
         
             
                      "http://#{metadata_host}".freeze
         
     | 
| 
       59 
57 
     | 
    
         
             
                    end
         
     | 
| 
       60 
58 
     | 
    
         | 
| 
      
 59 
     | 
    
         
            +
                    # @private Unused and deprecated
         
     | 
| 
       61 
60 
     | 
    
         
             
                    def compute_auth_token_uri
         
     | 
| 
       62 
61 
     | 
    
         
             
                      "#{compute_check_uri}/computeMetadata/v1/instance/service-accounts/default/token".freeze
         
     | 
| 
       63 
62 
     | 
    
         
             
                    end
         
     | 
| 
       64 
63 
     | 
    
         | 
| 
      
 64 
     | 
    
         
            +
                    # @private Unused and deprecated
         
     | 
| 
       65 
65 
     | 
    
         
             
                    def compute_id_token_uri
         
     | 
| 
       66 
66 
     | 
    
         
             
                      "#{compute_check_uri}/computeMetadata/v1/instance/service-accounts/default/identity".freeze
         
     | 
| 
       67 
67 
     | 
    
         
             
                    end
         
     | 
| 
       68 
68 
     | 
    
         | 
| 
       69 
69 
     | 
    
         
             
                    # Detect if this appear to be a GCE instance, by checking if metadata
         
     | 
| 
       70 
70 
     | 
    
         
             
                    # is available.
         
     | 
| 
       71 
     | 
    
         
            -
                     
     | 
| 
       72 
     | 
    
         
            -
             
     | 
| 
       73 
     | 
    
         
            -
                       
     | 
| 
       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
         
     | 
| 
       78 
     | 
    
         
            -
                      end
         
     | 
| 
       79 
     | 
    
         
            -
                      return false unless resp.status == 200
         
     | 
| 
       80 
     | 
    
         
            -
                      resp.headers["Metadata-Flavor"] == "Google"
         
     | 
| 
       81 
     | 
    
         
            -
                    rescue Faraday::TimeoutError, Faraday::ConnectionFailed
         
     | 
| 
       82 
     | 
    
         
            -
                      false
         
     | 
| 
      
 71 
     | 
    
         
            +
                    # The parameters are deprecated and unused.
         
     | 
| 
      
 72 
     | 
    
         
            +
                    def on_gce? _options = {}, _reload = false # rubocop:disable Style/OptionalBooleanParameter
         
     | 
| 
      
 73 
     | 
    
         
            +
                      Google::Cloud.env.metadata?
         
     | 
| 
       83 
74 
     | 
    
         
             
                    end
         
     | 
| 
       84 
75 
     | 
    
         | 
| 
       85 
     | 
    
         
            -
                     
     | 
| 
      
 76 
     | 
    
         
            +
                    def reset_cache
         
     | 
| 
      
 77 
     | 
    
         
            +
                      Google::Cloud.env.compute_metadata.reset_existence!
         
     | 
| 
      
 78 
     | 
    
         
            +
                      Google::Cloud.env.compute_metadata.cache.expire_all!
         
     | 
| 
      
 79 
     | 
    
         
            +
                    end
         
     | 
| 
      
 80 
     | 
    
         
            +
                    alias unmemoize_all reset_cache
         
     | 
| 
      
 81 
     | 
    
         
            +
                  end
         
     | 
| 
      
 82 
     | 
    
         
            +
             
     | 
| 
      
 83 
     | 
    
         
            +
                  # Construct a GCECredentials
         
     | 
| 
      
 84 
     | 
    
         
            +
                  def initialize options = {}
         
     | 
| 
      
 85 
     | 
    
         
            +
                    # Override the constructor to remember whether the universe domain was
         
     | 
| 
      
 86 
     | 
    
         
            +
                    # overridden by a constructor argument.
         
     | 
| 
      
 87 
     | 
    
         
            +
                    @universe_domain_overridden = options["universe_domain"] || options[:universe_domain] ? true : false
         
     | 
| 
      
 88 
     | 
    
         
            +
                    super options
         
     | 
| 
       86 
89 
     | 
    
         
             
                  end
         
     | 
| 
       87 
90 
     | 
    
         | 
| 
       88 
91 
     | 
    
         
             
                  # Overrides the super class method to change how access tokens are
         
     | 
| 
       89 
92 
     | 
    
         
             
                  # fetched.
         
     | 
| 
       90 
     | 
    
         
            -
                  def fetch_access_token  
     | 
| 
       91 
     | 
    
         
            -
                     
     | 
| 
       92 
     | 
    
         
            -
             
     | 
| 
       93 
     | 
    
         
            -
                       
     | 
| 
       94 
     | 
    
         
            -
             
     | 
| 
       95 
     | 
    
         
            -
                      query 
     | 
| 
       96 
     | 
    
         
            -
                       
     | 
| 
      
 93 
     | 
    
         
            +
                  def fetch_access_token _options = {}
         
     | 
| 
      
 94 
     | 
    
         
            +
                    if token_type == :id_token
         
     | 
| 
      
 95 
     | 
    
         
            +
                      query = { "audience" => target_audience, "format" => "full" }
         
     | 
| 
      
 96 
     | 
    
         
            +
                      entry = "service-accounts/default/identity"
         
     | 
| 
      
 97 
     | 
    
         
            +
                    else
         
     | 
| 
      
 98 
     | 
    
         
            +
                      query = {}
         
     | 
| 
      
 99 
     | 
    
         
            +
                      entry = "service-accounts/default/token"
         
     | 
| 
      
 100 
     | 
    
         
            +
                    end
         
     | 
| 
      
 101 
     | 
    
         
            +
                    query[:scopes] = Array(scope).join "," if scope
         
     | 
| 
      
 102 
     | 
    
         
            +
                    begin
         
     | 
| 
      
 103 
     | 
    
         
            +
                      resp = Google::Cloud.env.lookup_metadata_response "instance", entry, query: query
         
     | 
| 
       97 
104 
     | 
    
         
             
                      case resp.status
         
     | 
| 
       98 
105 
     | 
    
         
             
                      when 200
         
     | 
| 
       99 
     | 
    
         
            -
                         
     | 
| 
       100 
     | 
    
         
            -
                        if ["text/html", "application/text"].include? content_type
         
     | 
| 
       101 
     | 
    
         
            -
                          { (target_audience ? "id_token" : "access_token") => resp.body }
         
     | 
| 
       102 
     | 
    
         
            -
                        else
         
     | 
| 
       103 
     | 
    
         
            -
                          Signet::OAuth2.parse_credentials resp.body, content_type
         
     | 
| 
       104 
     | 
    
         
            -
                        end
         
     | 
| 
      
 106 
     | 
    
         
            +
                        build_token_hash resp.body, resp.headers["content-type"], resp.retrieval_monotonic_time
         
     | 
| 
       105 
107 
     | 
    
         
             
                      when 403, 500
         
     | 
| 
       106 
108 
     | 
    
         
             
                        msg = "Unexpected error code #{resp.status} #{UNEXPECTED_ERROR_SUFFIX}"
         
     | 
| 
       107 
109 
     | 
    
         
             
                        raise Signet::UnexpectedStatusError, msg
         
     | 
| 
         @@ -111,7 +113,35 @@ module Google 
     | 
|
| 
       111 
113 
     | 
    
         
             
                        msg = "Unexpected error code #{resp.status} #{UNEXPECTED_ERROR_SUFFIX}"
         
     | 
| 
       112 
114 
     | 
    
         
             
                        raise Signet::AuthorizationError, msg
         
     | 
| 
       113 
115 
     | 
    
         
             
                      end
         
     | 
| 
      
 116 
     | 
    
         
            +
                    rescue Google::Cloud::Env::MetadataServerNotResponding => e
         
     | 
| 
      
 117 
     | 
    
         
            +
                      raise Signet::AuthorizationError, e.message
         
     | 
| 
      
 118 
     | 
    
         
            +
                    end
         
     | 
| 
      
 119 
     | 
    
         
            +
                  end
         
     | 
| 
      
 120 
     | 
    
         
            +
             
     | 
| 
      
 121 
     | 
    
         
            +
                  private
         
     | 
| 
      
 122 
     | 
    
         
            +
             
     | 
| 
      
 123 
     | 
    
         
            +
                  def build_token_hash body, content_type, retrieval_time
         
     | 
| 
      
 124 
     | 
    
         
            +
                    hash =
         
     | 
| 
      
 125 
     | 
    
         
            +
                      if ["text/html", "application/text"].include? content_type
         
     | 
| 
      
 126 
     | 
    
         
            +
                        { token_type.to_s => body }
         
     | 
| 
      
 127 
     | 
    
         
            +
                      else
         
     | 
| 
      
 128 
     | 
    
         
            +
                        Signet::OAuth2.parse_credentials body, content_type
         
     | 
| 
      
 129 
     | 
    
         
            +
                      end
         
     | 
| 
      
 130 
     | 
    
         
            +
                    unless @universe_domain_overridden
         
     | 
| 
      
 131 
     | 
    
         
            +
                      universe_domain = Google::Cloud.env.lookup_metadata "universe", "universe_domain"
         
     | 
| 
      
 132 
     | 
    
         
            +
                      universe_domain = "googleapis.com" if !universe_domain || universe_domain.empty?
         
     | 
| 
      
 133 
     | 
    
         
            +
                      hash["universe_domain"] = universe_domain.strip
         
     | 
| 
      
 134 
     | 
    
         
            +
                    end
         
     | 
| 
      
 135 
     | 
    
         
            +
                    # The response might have been cached, which means expires_in might be
         
     | 
| 
      
 136 
     | 
    
         
            +
                    # stale. Update it based on the time since the data was retrieved.
         
     | 
| 
      
 137 
     | 
    
         
            +
                    # We also ensure expires_in is conservative; subtracting at least 1
         
     | 
| 
      
 138 
     | 
    
         
            +
                    # second to offset any skew from metadata server latency.
         
     | 
| 
      
 139 
     | 
    
         
            +
                    if hash["expires_in"].is_a? Numeric
         
     | 
| 
      
 140 
     | 
    
         
            +
                      offset = 1 + (Process.clock_gettime(Process::CLOCK_MONOTONIC) - retrieval_time).round
         
     | 
| 
      
 141 
     | 
    
         
            +
                      hash["expires_in"] -= offset if offset.positive?
         
     | 
| 
      
 142 
     | 
    
         
            +
                      hash["expires_in"] = 0 if hash["expires_in"].negative?
         
     | 
| 
       114 
143 
     | 
    
         
             
                    end
         
     | 
| 
      
 144 
     | 
    
         
            +
                    hash
         
     | 
| 
       115 
145 
     | 
    
         
             
                  end
         
     | 
| 
       116 
146 
     | 
    
         
             
                end
         
     | 
| 
       117 
147 
     | 
    
         
             
              end
         
     |