Class: Attio::OAuth::Token

Inherits:
Object
  • Object
show all
Defined in:
lib/attio/oauth/token.rb

Overview

Represents an OAuth access token with refresh capabilities

Defined Under Namespace

Classes: InvalidTokenError

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(attributes = {}) ⇒ Token

Returns a new instance of Token.



10
11
12
13
14
15
16
17
18
19
20
21
22
23
# File 'lib/attio/oauth/token.rb', line 10

def initialize(attributes = {})
  # Since this doesn't inherit from Resources::Base, we need to normalize
  normalized_attrs = normalize_attributes(attributes)
  @access_token = normalized_attrs[:access_token]
  @refresh_token = normalized_attrs[:refresh_token]
  @token_type = normalized_attrs[:token_type] || "Bearer"
  @expires_in = normalized_attrs[:expires_in]&.to_i
  @scope = parse_scope(normalized_attrs[:scope])
  @created_at = normalized_attrs[:created_at] || Time.now.utc
  @client = normalized_attrs[:client]

  calculate_expiration!
  validate!
end

Instance Attribute Details

#access_tokenObject (readonly)

Returns the value of attribute access_token.



7
8
9
# File 'lib/attio/oauth/token.rb', line 7

def access_token
  @access_token
end

#clientObject (readonly)

Returns the value of attribute client.



7
8
9
# File 'lib/attio/oauth/token.rb', line 7

def client
  @client
end

#created_atObject (readonly)

Returns the value of attribute created_at.



7
8
9
# File 'lib/attio/oauth/token.rb', line 7

def created_at
  @created_at
end

#expires_atObject (readonly)

Returns the value of attribute expires_at.



7
8
9
# File 'lib/attio/oauth/token.rb', line 7

def expires_at
  @expires_at
end

#expires_inObject (readonly)

Returns the value of attribute expires_in.



7
8
9
# File 'lib/attio/oauth/token.rb', line 7

def expires_in
  @expires_in
end

#refresh_tokenObject (readonly)

Returns the value of attribute refresh_token.



7
8
9
# File 'lib/attio/oauth/token.rb', line 7

def refresh_token
  @refresh_token
end

#scopeObject (readonly)

Returns the value of attribute scope.



7
8
9
# File 'lib/attio/oauth/token.rb', line 7

def scope
  @scope
end

#token_typeObject (readonly)

Returns the value of attribute token_type.



7
8
9
# File 'lib/attio/oauth/token.rb', line 7

def token_type
  @token_type
end

Class Method Details

.load(identifier = nil) ⇒ Object

Load token from secure storage (class method)



102
103
104
105
106
# File 'lib/attio/oauth/token.rb', line 102

def self.load(identifier = nil)
  # Default implementation returns nil
  # Subclasses can implement secure retrieval
  nil
end

Instance Method Details

#authorization_headerObject

Authorization header value



85
86
87
# File 'lib/attio/oauth/token.rb', line 85

def authorization_header
  "#{@token_type} #{@access_token}"
end

#expired?Boolean

Returns:

  • (Boolean)


25
26
27
28
# File 'lib/attio/oauth/token.rb', line 25

def expired?
  return false if @expires_at.nil?
  Time.now.utc >= @expires_at
end

#expires_soon?(threshold = 300) ⇒ Boolean

Returns:

  • (Boolean)


30
31
32
33
# File 'lib/attio/oauth/token.rb', line 30

def expires_soon?(threshold = 300)
  return false if @expires_at.nil?
  Time.now.utc >= (@expires_at - threshold)
end

#has_scope?(scope) ⇒ Boolean

Check if token has specific scope

Returns:

  • (Boolean)


90
91
92
# File 'lib/attio/oauth/token.rb', line 90

def has_scope?(scope)
  @scope.include?(scope.to_s)
end

#inspectString

Human-readable representation with masked token

Returns:

  • (String)

    Inspection string with partially masked token



76
77
78
79
80
81
82
# File 'lib/attio/oauth/token.rb', line 76

def inspect
  scope_str = @scope.is_a?(Array) ? @scope.join(" ") : @scope.to_s
  "#<#{self.class.name}:#{object_id} " \
    "token=#{@access_token ? "***" + @access_token[-4..] : "nil"} " \
    "expires_at=#{@expires_at&.iso8601} " \
    "scope=#{scope_str}>"
end

#refresh!Object

Raises:



35
36
37
38
39
40
41
42
# File 'lib/attio/oauth/token.rb', line 35

def refresh!
  raise InvalidTokenError, "No refresh token available" unless @refresh_token
  raise InvalidTokenError, "No OAuth client configured" unless @client

  new_token = @client.refresh_token(@refresh_token)
  update_from(new_token)
  self
end

#revoke!Object

Raises:



44
45
46
47
48
49
50
51
# File 'lib/attio/oauth/token.rb', line 44

def revoke!
  raise InvalidTokenError, "No OAuth client configured" unless @client

  @client.revoke_token(self)
  @access_token = nil
  @refresh_token = nil
  true
end

#saveObject

Store token securely (subclasses can override)



95
96
97
98
99
# File 'lib/attio/oauth/token.rb', line 95

def save
  # Default implementation does nothing
  # Subclasses can implement secure storage
  self
end

#to_hHash

Convert token to hash representation

Returns:

  • (Hash)

    Token attributes as a hash



55
56
57
58
59
60
61
62
63
64
65
# File 'lib/attio/oauth/token.rb', line 55

def to_h
  {
    access_token: @access_token,
    refresh_token: @refresh_token,
    token_type: @token_type,
    expires_in: @expires_in,
    expires_at: @expires_at&.iso8601,
    scope: @scope,
    created_at: @created_at.iso8601
  }.compact
end

#to_json(*opts) ⇒ String

Convert token to JSON string

Parameters:

  • opts (Hash)

    Options to pass to JSON.generate

Returns:

  • (String)

    JSON representation of the token



70
71
72
# File 'lib/attio/oauth/token.rb', line 70

def to_json(*opts)
  JSON.generate(to_h, *opts)
end