Class: Clacky::Mcp::OAuth::Session

Inherits:
Object
  • Object
show all
Defined in:
lib/clacky/mcp/oauth/session.rb

Defined Under Namespace

Classes: Error, NotConnectedError

Constant Summary collapse

EXPIRY_SKEW =
60

Instance Method Summary collapse

Constructor Details

#initialize(store:, manager:, clock: nil) ⇒ Session

Returns a new instance of Session.



14
15
16
17
18
19
20
# File 'lib/clacky/mcp/oauth/session.rb', line 14

def initialize(store:, manager:, clock: nil)
  @store = store
  @manager = manager
  @clock = clock || -> { Time.now.to_i }
  @force_refresh = false
  @lock = Monitor.new
end

Instance Method Details

#authorization_headersObject



22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/clacky/mcp/oauth/session.rb', line 22

def authorization_headers
  @lock.synchronize do
    grant = @store.load
    raise NotConnectedError, "OAuth MCP is not connected; run `clacky mcp login SERVER`" unless grant

    if @force_refresh || expiring?(grant)
      grant = @manager.refresh(grant)
      @store.save(grant)
      @force_refresh = false
    end
    token = grant["access_token"].to_s
    raise Error, "stored OAuth grant has no access token; log in again" if token.empty?
    { "Authorization" => "Bearer #{token}" }
  end
rescue NotConnectedError, Error
  raise
rescue StandardError => e
  raise Error, "OAuth session failed (#{e.class}); log in again"
end

#connected?Boolean

Returns:

  • (Boolean)


62
63
64
65
66
# File 'lib/clacky/mcp/oauth/session.rb', line 62

def connected?
  !@store.load.nil?
rescue StandardError
  false
end

#inspectObject



78
79
80
# File 'lib/clacky/mcp/oauth/session.rb', line 78

def inspect
  "#<#{self.class} connected=#{connected?}>"
end

#invalidate!Object



42
43
44
# File 'lib/clacky/mcp/oauth/session.rb', line 42

def invalidate!
  @lock.synchronize { @force_refresh = true }
end

#loginObject



46
47
48
49
50
51
52
# File 'lib/clacky/mcp/oauth/session.rb', line 46

def 
  @lock.synchronize do
    grant = @manager.
    @force_refresh = false
    grant
  end
end

#logoutObject



54
55
56
57
58
59
60
# File 'lib/clacky/mcp/oauth/session.rb', line 54

def logout
  @lock.synchronize do
    @store.delete
    @force_refresh = false
  end
  true
end

#statusObject



68
69
70
71
72
73
74
75
76
# File 'lib/clacky/mcp/oauth/session.rb', line 68

def status
  grant = @store.load
  return { "connected" => false } unless grant
  {
    "connected" => true,
    "expires_at" => grant["expires_at"],
    "expired" => grant.fetch("expires_at", 0).to_i <= @clock.call
  }
end