Class: OAuth2::AccessToken — Documentation by YARD 0.9.45

# Class: OAuth2::AccessToken

Inherits:
  Object
  - Object
  - OAuth2::AccessToken
  show all

Includes:
  FilteredAttributes

Defined in:
  lib/oauth2/access_token.rb

## Overview

rubocop:disable Metrics/ClassLength

## Constant Summary collapse

TOKEN_KEYS_STR =

      %w[access_token id_token token accessToken idToken].freeze

TOKEN_KEYS_SYM =

      %i[access_token id_token token accessToken idToken].freeze

TOKEN_KEY_LOOKUP =

      TOKEN_KEYS_STR + TOKEN_KEYS_SYM

## Instance Attribute Summary collapse

- #client ⇒ Object readonly

  Returns the value of attribute client.

- #expires_at ⇒ Object readonly

  Returns the value of attribute expires_at.

- #expires_in ⇒ Object readonly

  Returns the value of attribute expires_in.

- #expires_latency ⇒ Object readonly

  Returns the value of attribute expires_latency.

- #options ⇒ Object

  Returns the value of attribute options.

- #params ⇒ Object readonly

  Returns the value of attribute params.

- #refresh_token ⇒ Object

  Returns the value of attribute refresh_token.

- #response ⇒ Object

  Returns the value of attribute response.

- #token ⇒ Object readonly

  Returns the value of attribute token.

## Class Method Summary collapse

- .from_hash(client, hash) ⇒ OAuth2::AccessToken

  Initializes an AccessToken from a Hash.

- .from_kvform(client, kvform) ⇒ AccessToken

  Initializes an AccessToken from a key/value application/x-www-form-urlencoded string.

## Instance Method Summary collapse

- #[](key) ⇒ Object

  Indexer to additional params present in token response.

- #delete(path, opts = {}, &block) ⇒ Object

  Make a DELETE request with the Access Token.

- #expired? ⇒ Boolean

  Check if token is expired.

- #expires? ⇒ Boolean

  Whether the token expires.

- #get(path, opts = {}, &block) ⇒ Object

  Make a GET request with the Access Token.

- #headers ⇒ Object

  Get the headers hash (includes Authorization token).

- #initialize(client, token, opts = {}) ⇒ AccessToken constructor

  Initialize an AccessToken.

- #patch(path, opts = {}, &block) ⇒ Object

  Make a PATCH request with the Access Token.

- #post(path, opts = {}, &block) ⇒ Object

  Make a POST request with the Access Token.

- #put(path, opts = {}, &block) ⇒ Object

  Make a PUT request with the Access Token.

- #refresh(params = {}, access_token_opts = {}) {|opts| ... } ⇒ OAuth2::AccessToken (also: #refresh!)

  Refreshes the current Access Token.

- #request(verb, path, opts = {}) {|req| ... } ⇒ OAuth2::Response

  Make a request with the Access Token.

- #revoke(params = {}) {|req| ... } ⇒ OAuth2::Response (also: #revoke!)

  Revokes the token at the authorization server.

- #to_hash ⇒ Hash

  Convert AccessToken to a hash which can be used to rebuild itself with AccessToken.from_hash.

## Constructor Details

### #initialize(client, token, opts = {}) ⇒ `AccessToken`

Note:

For “soon-to-expire”/”clock-skew” functionality see the `:expires_latency` option.

Note:

If no token is provided, the AccessToken will be considered invalid.
This is to prevent the possibility of a token being accidentally
created with no token value.
If you want to create an AccessToken with no token value,
you can pass in an empty string or nil for the token value.
If you want to create an AccessToken with no token value and
no refresh token, you can pass in an empty string or nil for the
token value and nil for the refresh token, and `raise_errors: false`.

Initialize an AccessToken

#### Examples:

#####

Verb-dependent Hash mode

    # Send token in query for GET, in header for POST/DELETE, in body for PUT/PATCH
    OAuth2::AccessToken.new(client, token, mode: {get: :query, post: :header, delete: :header, put: :body, patch: :body})

Parameters:

- client (`Client`) —

  the OAuth2::Client instance

- token (`String`) —

  the Access Token value (optional, may not be used in refresh flows)

- opts (`Hash`) (defaults to: `{}`) —

  the options to create the Access Token with

Options Hash (`opts`):

- :refresh_token (`String`) — default: `nil` —

  the refresh_token value

- :expires_in (`FixNum`, `String`) — default: `nil` —

  the number of seconds in which the AccessToken will expire

- :expires_at (`FixNum`, `String`) — default: `nil` —

  the epoch time in seconds in which AccessToken will expire

- :expires_latency (`FixNum`, `String`) — default: `nil` —

  the number of seconds by which AccessToken validity will be reduced to offset latency, @version 2.0+

- :mode (`Symbol`, `Hash`, `or callable`) — default: `:header` —

  the transmission mode of the Access Token parameter value:
  either one of :header, :body or :query; or a Hash with verb symbols as keys mapping to one of these symbols
  (e.g., `{get: :query, post: :header, delete: :header}`); or a callable that accepts a request-verb parameter
  and returns one of these three symbols.

- :header_format (`String`) — default: `'Bearer %s'` —

  the string format to use for the Authorization header

- :param_name (`String`) — default: `'access_token'` —

  the parameter name to use for transmission of the
  Access Token value in :body or :query transmission mode

- :token_name (`String`) — default: `nil` —

  the name of the response parameter that identifies the access token
  When nil one of TOKEN_KEY_LOOKUP will be used

    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    # File 'lib/oauth2/access_token.rb', line 150

    def initialize(client, token, opts = {})
      @client = client
      @token = token.to_s
      opts = opts.dup
      %i[refresh_token expires_in expires_at expires_latency].each do |arg|
        instance_variable_set("@#{arg}", opts.delete(arg) || opts.delete(arg.to_s))
      end
      no_tokens = (@token.nil? || @token.empty?) && (@refresh_token.nil? || @refresh_token.empty?)
      if no_tokens
        if @client.options[:raise_errors]
          raise Error.new({
            error: "OAuth2::AccessToken has no token",
            error_description: "Options are: #{opts.inspect}",
          })
        elsif !OAuth2.config.silence_no_tokens_warning
          warn("OAuth2::AccessToken has no token")
        end
      end
      # @option opts [Fixnum, String] :expires is deprecated
      @expires_in ||= opts.delete("expires")
      @expires_in &&= @expires_in.to_i
      @expires_at &&= convert_expires_at(@expires_at)
      @expires_latency &&= @expires_latency.to_i
      @expires_at ||= Time.now.to_i + @expires_in if @expires_in && !@expires_in.zero?
      @expires_at -= @expires_latency if @expires_latency
      @options = {
        mode: opts.delete(:mode) || :header,
        header_format: opts.delete(:header_format) || "Bearer %s",
        param_name: opts.delete(:param_name) || "access_token",
      }
      @options[:token_name] = opts.delete(:token_name) if opts.key?(:token_name)

      @params = opts
    end

## Instance Attribute Details

### #client ⇒ `Object` (readonly)

Returns the value of attribute client.

    26
    27
    28
    # File 'lib/oauth2/access_token.rb', line 26

    def client
      @client
    end

### #expires_at ⇒ `Object` (readonly)

Returns the value of attribute expires_at.

    26
    27
    28
    # File 'lib/oauth2/access_token.rb', line 26

    def expires_at
      @expires_at
    end

### #expires_in ⇒ `Object` (readonly)

Returns the value of attribute expires_in.

    26
    27
    28
    # File 'lib/oauth2/access_token.rb', line 26

    def expires_in
      @expires_in
    end

### #expires_latency ⇒ `Object` (readonly)

Returns the value of attribute expires_latency.

    26
    27
    28
    # File 'lib/oauth2/access_token.rb', line 26

    def expires_latency
      @expires_latency
    end

### #options ⇒ `Object`

Returns the value of attribute options.

    27
    28
    29
    # File 'lib/oauth2/access_token.rb', line 27

    def options
      @options
    end

### #params ⇒ `Object` (readonly)

Returns the value of attribute params.

    26
    27
    28
    # File 'lib/oauth2/access_token.rb', line 26

    def params
      @params
    end

### #refresh_token ⇒ `Object`

Returns the value of attribute refresh_token.

    27
    28
    29
    # File 'lib/oauth2/access_token.rb', line 27

    def refresh_token
      @refresh_token
    end

### #response ⇒ `Object`

Returns the value of attribute response.

    27
    28
    29
    # File 'lib/oauth2/access_token.rb', line 27

    def response
      @response
    end

### #token ⇒ `Object` (readonly)

Returns the value of attribute token.

    26
    27
    28
    # File 'lib/oauth2/access_token.rb', line 26

    def token
      @token
    end

## Class Method Details

### .from_hash(client, hash) ⇒ `OAuth2::AccessToken`

Note:

The method will use the first found token key in the following order:
‘access_token’, ‘id_token’, ‘token’ (or their symbolic versions)

Note:

If multiple token keys are present, a warning will be issued unless
OAuth2.config.silence_extra_tokens_warning is true

Note:

If no token keys are present, a warning will be issued unless
OAuth2.config.silence_no_tokens_warning is true

Note:

For “soon-to-expire”/”clock-skew” functionality see the `:expires_latency` option.

Note:

If snaky key conversion is being used, token_name needs to match the converted key.

Initializes an AccessToken from a Hash

#### Examples:

    hash = { 'access_token' => 'token_value', 'refresh_token' => 'refresh_value' }
    access_token = OAuth2::AccessToken.from_hash(client, hash)

Parameters:

- client (`OAuth2::Client`) —

  the OAuth2::Client instance

- hash (`Hash`) —

  a hash containing the token and other properties

Options Hash (`hash`):

- 'access_token' (`String`) —

  the access token value

- 'id_token' (`String`) —

  alternative key for the access token value

- 'token' (`String`) —

  alternative key for the access token value

- 'refresh_token' (`String`) — default: `optional` —

  the refresh token value

- 'expires_in' (`Integer`, `String`) — default: `optional` —

  number of seconds until token expires

- 'expires_at' (`Integer`, `String`) — default: `optional` —

  epoch time in seconds when token expires

- 'expires_latency' (`Integer`, `String`) — default: `optional` —

  seconds to reduce token validity by

Returns:

- (`OAuth2::AccessToken`) —

  the initialized AccessToken

    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    # File 'lib/oauth2/access_token.rb', line 57

    def from_hash(client, hash)
      fresh = hash.dup
      # If token_name is present, then use that key name
      if fresh.key?(:token_name)
        t_key = fresh[:token_name]
        no_tokens_warning(fresh, t_key)
      else
        # Otherwise, if one of the supported default keys is present, use whichever has precedence
        supported_keys = TOKEN_KEY_LOOKUP & fresh.keys
        t_key = supported_keys[0]
        extra_tokens_warning(supported_keys, t_key)
      end
      # simplecov:disable
      # TODO: Get rid of this branching logic when dropping Hashie < v3.2
      token = extract_token_value(fresh, t_key)
      # simplecov:enable
      new(client, token, fresh)
    end

### .from_kvform(client, kvform) ⇒ `AccessToken`

Initializes an AccessToken from a key/value application/x-www-form-urlencoded string

Parameters:

- client (`Client`) —

  the OAuth2::Client instance

- kvform (`String`) —

  the application/x-www-form-urlencoded string

Returns:

- (`AccessToken`) —

  the initialized AccessToken

    81
    82
    83
    # File 'lib/oauth2/access_token.rb', line 81

    def from_kvform(client, kvform)
      from_hash(client, Rack::Utils.parse_query(kvform))
    end

## Instance Method Details

### #[](key) ⇒ `Object`

Indexer to additional params present in token response

Parameters:

- key (`String`) —

  entry key to Hash

    188
    189
    190
    # File 'lib/oauth2/access_token.rb', line 188

    def [](key)
      @params[key]
    end

### #delete(path, opts = {}, &block) ⇒ `Object`

Make a DELETE request with the Access Token

See Also:

- #request

    370
    371
    372
    # File 'lib/oauth2/access_token.rb', line 370

    def delete(path, opts = {}, &block)
      request(:delete, path, opts, &block)
    end

### #expired? ⇒ `Boolean`

Check if token is expired

Returns:

- (`Boolean`) —

  true if the token is expired, false otherwise

    202
    203
    204
    # File 'lib/oauth2/access_token.rb', line 202

    def expired?
      expires? && (expires_at <= Time.now.to_i)
    end

### #expires? ⇒ `Boolean`

Whether the token expires

Returns:

- (`Boolean`)

    195
    196
    197
    # File 'lib/oauth2/access_token.rb', line 195

    def expires?
      !!@expires_at
    end

### #get(path, opts = {}, &block) ⇒ `Object`

Make a GET request with the Access Token

See Also:

- #request

    342
    343
    344
    # File 'lib/oauth2/access_token.rb', line 342

    def get(path, opts = {}, &block)
      request(:get, path, opts, &block)
    end

### #headers ⇒ `Object`

Get the headers hash (includes Authorization token)

    375
    376
    377
    # File 'lib/oauth2/access_token.rb', line 375

    def headers
      {"Authorization" => options[:header_format] % token}
    end

### #patch(path, opts = {}, &block) ⇒ `Object`

Make a PATCH request with the Access Token

See Also:

- #request

    363
    364
    365
    # File 'lib/oauth2/access_token.rb', line 363

    def patch(path, opts = {}, &block)
      request(:patch, path, opts, &block)
    end

### #post(path, opts = {}, &block) ⇒ `Object`

Make a POST request with the Access Token

See Also:

- #request

    349
    350
    351
    # File 'lib/oauth2/access_token.rb', line 349

    def post(path, opts = {}, &block)
      request(:post, path, opts, &block)
    end

### #put(path, opts = {}, &block) ⇒ `Object`

Make a PUT request with the Access Token

See Also:

- #request

    356
    357
    358
    # File 'lib/oauth2/access_token.rb', line 356

    def put(path, opts = {}, &block)
      request(:put, path, opts, &block)
    end

### #refresh(params = {}, access_token_opts = {}) {|opts| ... } ⇒ `OAuth2::AccessToken` Also known as: refresh!

Note:

current token’s options are carried over to the new AccessToken

Refreshes the current Access Token

Parameters:

- params (`Hash`) (defaults to: `{}`) —

  additional params to pass to the refresh token request

- access_token_opts (`Hash`) (defaults to: `{}`) —

  options that will be passed to the AccessToken initialization

Yields:

- (`opts`) —

  The block to modify the refresh token request options

Yield Parameters:

- opts (`Hash`) —

  The options hash that can be modified

Returns:

- (`OAuth2::AccessToken`) —

  a new AccessToken instance

Raises:

- (`OAuth2::Error`)

    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    # File 'lib/oauth2/access_token.rb', line 217

    def refresh(params = {}, access_token_opts = {}, &block)
      raise OAuth2::Error.new({error: "A refresh_token is not available"}) unless refresh_token

      params[:grant_type] = "refresh_token"
      params[:refresh_token] = refresh_token
      new_token = @client.get_token(params, access_token_opts, &block)
      new_token.options = options
      if new_token.refresh_token
        # Keep it if there is one
      else
        new_token.refresh_token = refresh_token
      end
      new_token
    end

### #request(verb, path, opts = {}) {|req| ... } ⇒ `OAuth2::Response`

Make a request with the Access Token

Parameters:

- verb (`Symbol`) —

  the HTTP request method

- path (`String`) —

  the HTTP URL path of the request

- opts (`Hash`) (defaults to: `{}`) —

  the options to make the request with

Options Hash (`opts`):

- :params (`Hash`) —

  additional URL parameters

- :body (`Hash`, `String`) —

  the request body

- :headers (`Hash`) —

  request headers

Yields:

- (`req`) —

  The block to modify the request

Yield Parameters:

- req (`Faraday::Request`) —

  The request object that can be modified

Returns:

- (`OAuth2::Response`) —

  the response from the request

See Also:

- Client#request

    334
    335
    336
    337
    # File 'lib/oauth2/access_token.rb', line 334

    def request(verb, path, opts = {}, &block)
      configure_authentication!(opts, verb)
      @client.request(verb, path, opts, &block)
    end

### #revoke(params = {}) {|req| ... } ⇒ `OAuth2::Response` Also known as: revoke!

Note:

If the token passed to the request
is an access token, the server MAY revoke the respective refresh
token as well.

Note:

If the token passed to the request
is a refresh token and the authorization server supports the
revocation of access tokens, then the authorization server SHOULD
also invalidate all access tokens based on the same authorization
grant

Note:

If the server responds with HTTP status code 503, your code must
assume the token still exists and may retry after a reasonable delay.
The server may include a “Retry-After” header in the response to
indicate how long the service is expected to be unavailable to the
requesting client.

Revokes the token at the authorization server

Parameters:

- params (`Hash`) (defaults to: `{}`) —

  additional parameters to be sent during revocation

Options Hash (`params`):

- :token_type_hint (`String`, `Symbol`, `nil`) — default: `'access_token' or 'refresh_token'` —

  hint about which token to revoke

- :token_method (`Symbol`) — default: `:post_with_query_string` —

  overrides OAuth2::Client#options[:token_method]

Yields:

- (`req`) —

  The block is passed the request being made, allowing customization

Yield Parameters:

- req (`Faraday::Request`) —

  The request object that can be modified

Returns:

- (`OAuth2::Response`) —

  OAuth2::Response instance

Raises:

- (`OAuth2::Error`) —

  if token_type_hint is invalid or the specified token is not available

See Also:

- https://datatracker.ietf.org/doc/html/rfc7009
- https://datatracker.ietf.org/doc/html/rfc7009#section-2.1

    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    # File 'lib/oauth2/access_token.rb', line 266

    def revoke(params = {}, &block)
      token_type_hint_orig = params.delete(:token_type_hint)
      token_type_hint = nil
      revoke_token = case token_type_hint_orig
      when "access_token", :access_token
        token_type_hint = "access_token"
        token
      when "refresh_token", :refresh_token
        token_type_hint = "refresh_token"
        refresh_token
      when nil
        if token
          token_type_hint = "access_token"
          token
        elsif refresh_token
          token_type_hint = "refresh_token"
          refresh_token
        end
      else
        raise OAuth2::Error.new({error: "token_type_hint must be one of [nil, :refresh_token, :access_token], so if you need something else consider using a subclass or entirely custom AccessToken class."})
      end
      raise OAuth2::Error.new({error: "#{token_type_hint || "unknown token type"} is not available for revoking"}) unless revoke_token && !revoke_token.empty?

      @client.revoke_token(revoke_token, token_type_hint, params, &block)
    end

### #to_hash ⇒ `Hash`

Note:

Don’t return expires_latency because it has already been deducted from expires_at

Convert AccessToken to a hash which can be used to rebuild itself with AccessToken.from_hash

Returns:

- (`Hash`) —

  a hash of AccessToken property values

    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    # File 'lib/oauth2/access_token.rb', line 300

    def to_hash
      hsh = {
        access_token: token,
        refresh_token: refresh_token,
        expires_at: expires_at,
        mode: options[:mode],
        header_format: options[:header_format],
        param_name: options[:param_name],
      }
      hsh[:token_name] = options[:token_name] if options.key?(:token_name)
      # TODO: Switch when dropping Ruby < 2.5 support
      # params.transform_keys(&:to_sym) # Ruby 2.5 only
      # Old Ruby transform_keys alternative:
      sheesh = @params.each_with_object({}) { |(key, value), memo|
        memo[key.to_sym] = value
      }
      sheesh.merge(hsh)
    end