statelydb 0.13.0 → 0.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1518fe47ef69d7e171862c88f5b8a9425116dc1390623724dc95e285e960b728
4
- data.tar.gz: f5e9faad6e851892a695a47590e7430908e419b44c2f94a60087fec4c316c808
3
+ metadata.gz: a723737fdce6e8ad2bec8937cfd79f6d968df0fc3e9e747c64e18af9ce769601
4
+ data.tar.gz: 1f0279a8b9507f4cffacc360ab82e2289471a40de39bd3891f0c7db5c63877c6
5
5
  SHA512:
6
- metadata.gz: acc4be2621242c08236efdf8e1f9fa48090070c3c4ad12583481bc2a2df4ee5638fbb665059a0138a7bf53270bed8d6bf0f5290843dd5d488b71274f2a3284b8
7
- data.tar.gz: ddccab6882a70b7eab33c56893fd9cae614ee67c5343b0953f7af33d3fe487418eb00c3300d3a24ae6e14df88f5cf49609b9e1f4a966db10d646ab184c00a685
6
+ metadata.gz: 815835070a91366b18948afe145eb548ae4f6ecbc6559ed3b8193288cd1084b7ac1a416264b0769afea93f4a8c01e17b0474facb46fe90460b0b3db803466428
7
+ data.tar.gz: e0c75f31911432f2544c4097fbc0c7a1615624257e80495aef9e5b3a0dddc92dd9341683d24416c4a32ab19b8bd34a2d79abb577781d75ee41b55a02f2e2e11c
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+ # Generated by the protocol buffer compiler. DO NOT EDIT!
3
+ # source: auth/get_auth_token.proto
4
+
5
+ require 'google/protobuf'
6
+
7
+
8
+ descriptor_data = "\n\x19\x61uth/get_auth_token.proto\x12\x0cstately.auth\"B\n\x13GetAuthTokenRequest\x12\x1f\n\naccess_key\x18\x01 \x01(\tH\x00R\taccessKeyB\n\n\x08identity\"W\n\x14GetAuthTokenResponse\x12\x1d\n\nauth_token\x18\x01 \x01(\tR\tauthToken\x12 \n\x0c\x65xpires_in_s\x18\x02 \x01(\x04R\nexpiresInSBv\n\x10\x63om.stately.authB\x11GetAuthTokenProtoP\x01\xa2\x02\x03SAX\xaa\x02\x0cStately.Auth\xca\x02\x0cStately\\Auth\xe2\x02\x18Stately\\Auth\\GPBMetadata\xea\x02\rStately::Authb\x06proto3"
9
+
10
+ pool = Google::Protobuf::DescriptorPool.generated_pool
11
+ pool.add_serialized_file(descriptor_data)
12
+
13
+ module Stately
14
+ module Auth
15
+ GetAuthTokenRequest = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("stately.auth.GetAuthTokenRequest").msgclass
16
+ GetAuthTokenResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("stately.auth.GetAuthTokenResponse").msgclass
17
+ end
18
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+ # Generated by the protocol buffer compiler. DO NOT EDIT!
3
+ # source: auth/service.proto
4
+
5
+ require 'google/protobuf'
6
+
7
+ require 'api/auth/get_auth_token_pb'
8
+
9
+
10
+ descriptor_data = "\n\x12\x61uth/service.proto\x12\x0cstately.auth\x1a\x19\x61uth/get_auth_token.proto2i\n\x0b\x41uthService\x12Z\n\x0cGetAuthToken\x12!.stately.auth.GetAuthTokenRequest\x1a\".stately.auth.GetAuthTokenResponse\"\x03\x90\x02\x01\x42q\n\x10\x63om.stately.authB\x0cServiceProtoP\x01\xa2\x02\x03SAX\xaa\x02\x0cStately.Auth\xca\x02\x0cStately\\Auth\xe2\x02\x18Stately\\Auth\\GPBMetadata\xea\x02\rStately::Authb\x06proto3"
11
+
12
+ pool = Google::Protobuf::DescriptorPool.generated_pool
13
+ pool.add_serialized_file(descriptor_data)
14
+
15
+ module Stately
16
+ module Auth
17
+ end
18
+ end
@@ -0,0 +1,29 @@
1
+ # Generated by the protocol buffer compiler. DO NOT EDIT!
2
+ # Source: auth/service.proto for package 'Stately.Auth'
3
+
4
+ require 'grpc'
5
+ require 'api/auth/service_pb'
6
+
7
+ module Stately
8
+ module Auth
9
+ module AuthService
10
+ # AuthService is the service for vending access tokens used to connect to
11
+ # StatelyDB. This API is meant to be used from SDKs. Access Keys are created
12
+ # and managed from the stately.dbmanagement.UserService.
13
+ class Service
14
+
15
+ include ::GRPC::GenericService
16
+
17
+ self.marshal_class_method = :encode
18
+ self.unmarshal_class_method = :decode
19
+ self.service_name = 'stately.auth.AuthService'
20
+
21
+ # GetAuthToken returns a short-lived access token from some proof of
22
+ # identity. This operation will fail if the identity cannot be verified.
23
+ rpc :GetAuthToken, ::Stately::Auth::GetAuthTokenRequest, ::Stately::Auth::GetAuthTokenResponse
24
+ end
25
+
26
+ Stub = Service.rpc_stub_class
27
+ end
28
+ end
29
+ end
@@ -6,8 +6,10 @@ require "async/http/internet"
6
6
  require "async/semaphore"
7
7
  require "json"
8
8
  require "logger"
9
- require "weakref"
9
+ require "grpc"
10
10
  require_relative "token_provider"
11
+ require_relative "token_fetcher"
12
+ require_relative "../../error"
11
13
 
12
14
  LOGGER = Logger.new($stdout)
13
15
  LOGGER.level = Logger::WARN
@@ -22,20 +24,22 @@ module StatelyDB
22
24
  # which vends tokens from auth0 with the given client_id and client_secret.
23
25
  # It will default to using the values of `STATELY_CLIENT_ID` and `STATELY_CLIENT_SECRET` if
24
26
  # no credentials are explicitly passed and will throw an error if none are found.
25
- class Auth0TokenProvider < TokenProvider
27
+ class AuthTokenProvider < TokenProvider
26
28
  # @param [String] origin The origin of the OAuth server
27
29
  # @param [String] audience The OAuth Audience for the token
28
30
  # @param [String] client_secret The StatelyDB client secret credential
29
31
  # @param [String] client_id The StatelyDB client ID credential
32
+ # @param [String] access_key The StatelyDB access key credential
30
33
  def initialize(
31
34
  origin: "https://oauth.stately.cloud",
32
35
  audience: "api.stately.cloud",
33
- client_secret: ENV.fetch("STATELY_CLIENT_SECRET"),
34
- client_id: ENV.fetch("STATELY_CLIENT_ID")
36
+ client_secret: ENV.fetch("STATELY_CLIENT_SECRET", nil),
37
+ client_id: ENV.fetch("STATELY_CLIENT_ID", nil),
38
+ access_key: ENV.fetch("STATELY_ACCESS_KEY", nil)
35
39
  )
36
40
  super()
37
41
  @actor = Async::Actor.new(Actor.new(origin: origin, audience: audience,
38
- client_secret: client_secret, client_id: client_id))
42
+ client_secret: client_secret, client_id: client_id, access_key: access_key))
39
43
  # this initialization cannot happen in the constructor because it is async and must run on the event loop
40
44
  # which is not available in the constructor
41
45
  @actor.init
@@ -64,29 +68,41 @@ module StatelyDB
64
68
  origin:,
65
69
  audience:,
66
70
  client_secret:,
67
- client_id:
71
+ client_id:,
72
+ access_key:
68
73
  )
69
74
  super()
70
- @client = Async::HTTP::Client.new(Async::HTTP::Endpoint.parse(origin))
71
- @client_id = client_id
72
- @client_secret = client_secret
73
- @audience = audience
74
75
 
75
- @access_token = nil
76
- @expires_at_unix_secs = nil
76
+ @token_fetcher = nil
77
+ if !access_key.nil?
78
+ @token_fetcher = StatelyDB::Common::Auth::StatelyAccessTokenFetcher.new(origin: origin, access_key: access_key)
79
+ elsif !client_secret.nil? && !client_id.nil?
80
+ @token_fetcher = StatelyDB::Common::Auth::Auth0TokenFetcher.new(origin: origin, audience: audience,
81
+ client_secret: client_secret, client_id: client_id)
82
+ else
83
+ raise StatelyDB::Error.new("unable to find client credentials in STATELY_ACCESS_KEY or STATELY_CLIENT_ID and " \
84
+ "STATELY_CLIENT_SECRET environment variables. Either pass your credentials in " \
85
+ "explicitly or set these environment variables",
86
+ code: GRPC::Core::StatusCodes::UNAUTHENTICATED,
87
+ stately_code: "Unauthenticated")
88
+ end
89
+
90
+ @token_state = nil
77
91
  @pending_refresh = nil
78
92
  end
79
93
 
80
94
  # Initialize the actor. This runs on the actor thread which means
81
95
  # we can dispatch async operations here.
82
96
  def init
97
+ # disable the async lib logger. We do our own error handling and propagation
98
+ Console.logger.disable(Async::Task)
83
99
  refresh_token
84
100
  end
85
101
 
86
102
  # Close the token provider and kill any background operations
87
103
  def close
88
104
  @scheduled&.stop
89
- @client&.close
105
+ @token_fetcher&.close
90
106
  end
91
107
 
92
108
  # Get the current access token
@@ -94,8 +110,7 @@ module StatelyDB
94
110
  # @return [String] The current access token
95
111
  def get_token(force: false)
96
112
  if force
97
- @access_token = nil
98
- @expires_at_unix_secs = nil
113
+ @token_state = nil
99
114
  else
100
115
  token, ok = valid_access_token
101
116
  return token if ok
@@ -107,11 +122,10 @@ module StatelyDB
107
122
  # Get the current access token and whether it is valid
108
123
  # @return [Array] The current access token and whether it is valid
109
124
  def valid_access_token
110
- return "", false if @access_token.nil?
111
- return "", false if @expires_at_unix_secs.nil?
112
- return "", false if @expires_at_unix_secs < Time.now.to_i
125
+ return "", false if @token_state.nil?
126
+ return "", false if @token_state.expires_at_unix_secs < Time.now.to_i
113
127
 
114
- [@access_token, true]
128
+ [@token_state.token, true]
115
129
  end
116
130
 
117
131
  # Refresh the access token
@@ -151,19 +165,16 @@ module StatelyDB
151
165
  # @return [String] The new access token
152
166
  def refresh_token_impl
153
167
  Sync do
154
- resp_data = make_auth0_request
155
-
156
- new_access_token = resp_data["access_token"]
157
- new_expires_in_secs = resp_data["expires_in"]
168
+ token_result = @token_fetcher.fetch
169
+ new_expires_in_secs = token_result.expires_in_secs
158
170
  new_expires_at_unix_secs = Time.now.to_i + new_expires_in_secs
159
- if @expires_at_unix_secs.nil? || new_expires_at_unix_secs > @expires_at_unix_secs
160
171
 
161
- @access_token = new_access_token
162
- @expires_at_unix_secs = new_expires_at_unix_secs
172
+ # only update the token state if the new expiry is later than the current one
173
+ if @token_state.nil? || new_expires_at_unix_secs > @token_state.expires_at_unix_secs
174
+ @token_state = TokenState.new(token: token_result.token, expires_at_unix_secs: new_expires_at_unix_secs)
163
175
  else
164
-
165
- new_access_token = @access_token
166
- new_expires_in_secs = @expires_at_unix_secs - Time.now.to_i
176
+ # otherwise use the existing expiry time for scheduling the refresh
177
+ new_expires_in_secs = @token_state.expires_at_unix_secs - Time.now.to_i
167
178
  end
168
179
 
169
180
  # Schedule a refresh of the token ahead of the expiry time
@@ -182,24 +193,21 @@ module StatelyDB
182
193
  @scheduled = nil
183
194
  end
184
195
 
185
- new_access_token
196
+ @token_state.token
186
197
  end
187
198
  end
199
+ end
188
200
 
189
- def make_auth0_request
190
- headers = [["content-type", "application/json"]]
191
- body = JSON.dump({ "client_id" => @client_id, client_secret: @client_secret, audience: @audience,
192
- grant_type: DEFAULT_GRANT_TYPE })
193
- Sync do
194
- # TODO: Wrap this in a retry loop and parse errors like we
195
- # do in the Go SDK.
196
- response = @client.post("/oauth/token", headers, body)
197
- raise "Auth request failed" if response.status != 200
198
-
199
- JSON.parse(response.read)
200
- ensure
201
- response&.close
202
- end
201
+ # Persistent state for the token provider
202
+ class TokenState
203
+ attr_reader :token, :expires_at_unix_secs
204
+
205
+ # Create a new TokenState
206
+ # @param [String] token The access token
207
+ # @param [Integer] expires_at_unix_secs The unix timestamp when the token expires
208
+ def initialize(token:, expires_at_unix_secs:)
209
+ @token = token
210
+ @expires_at_unix_secs = expires_at_unix_secs
203
211
  end
204
212
  end
205
213
  end
@@ -11,7 +11,7 @@ module StatelyDB
11
11
  class Interceptor < GRPC::ClientInterceptor
12
12
  # @param [TokenProvider] token_provider The token provider to use for authentication
13
13
  def initialize(
14
- token_provider: Auth0TokenProvider.new
14
+ token_provider: AuthTokenProvider.new
15
15
  )
16
16
  super()
17
17
  @token_provider = token_provider
@@ -0,0 +1,104 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../net/conn"
4
+ require_relative "../error_interceptor"
5
+ require_relative "../../api/auth/service_services_pb"
6
+ require "grpc"
7
+
8
+ module StatelyDB
9
+ module Common
10
+ # A module for Stately Cloud auth code
11
+ module Auth
12
+ # Result from a token fetch operation
13
+ class TokenResult
14
+ attr_reader :token, :expires_in_secs
15
+
16
+ # Create a new TokenResult
17
+ # @param [String] token The access token
18
+ # @param [Integer] expires_in_secs The number of seconds until the token expires
19
+ def initialize(token:, expires_in_secs:)
20
+ @token = token
21
+ @expires_in_secs = expires_in_secs
22
+ end
23
+ end
24
+
25
+ # TokenFetcher is an abstract base class that should be extended
26
+ # for individual token fetcher implementations
27
+ class TokenFetcher
28
+ # Get the current access token
29
+ # @return [TokenResult] The fetched TokenResult
30
+ def fetch
31
+ raise "Not Implemented"
32
+ end
33
+
34
+ # Close the token provider and kill any background operations
35
+ def close
36
+ raise "Not Implemented"
37
+ end
38
+ end
39
+
40
+ # Auth0TokenFetcher is a TokenFetcher that fetches tokens from an Auth0 server
41
+ class Auth0TokenFetcher < TokenFetcher
42
+ # @param [String] origin The origin of the OAuth server
43
+ # @param [String] audience The OAuth Audience for the token
44
+ # @param [String] client_secret The StatelyDB client secret credential
45
+ # @param [String] client_id The StatelyDB client ID credential
46
+ def initialize(origin:, audience:, client_secret:, client_id:)
47
+ super()
48
+ @client = Async::HTTP::Client.new(Async::HTTP::Endpoint.parse(origin))
49
+ @audience = audience
50
+ @client_secret = client_secret
51
+ @client_id = client_id
52
+ end
53
+
54
+ # Fetch a new token from auth0
55
+ # @return [TokenResult] The fetched TokenResult
56
+ def fetch
57
+ headers = [["content-type", "application/json"]]
58
+ body = JSON.dump({ "client_id" => @client_id, client_secret: @client_secret, audience: @audience,
59
+ grant_type: DEFAULT_GRANT_TYPE })
60
+ Sync do
61
+ # TODO: Wrap this in a retry loop and parse errors like we
62
+ # do in the Go SDK.
63
+ response = @client.post("/oauth/token", headers, body)
64
+ raise "Auth request failed" if response.status != 200
65
+
66
+ resp_data = JSON.parse(response.read)
67
+ TokenResult.new(token: resp_data["access_token"], expires_in_secs: resp_data["expires_in"])
68
+ ensure
69
+ response&.close
70
+ end
71
+ end
72
+
73
+ def close
74
+ @client&.close
75
+ end
76
+ end
77
+
78
+ # StatelyAccessTokenFetcher is a TokenFetcher that fetches tokens from the StatelyDB API
79
+ class StatelyAccessTokenFetcher < TokenFetcher
80
+ # @param [String] origin The origin of the OAuth server
81
+ # @param [String] access_key The StatelyDB access key credential
82
+ def initialize(origin:, access_key:)
83
+ super()
84
+ @access_key = access_key
85
+ @channel = Common::Net.new_channel(endpoint: origin)
86
+ error_interceptor = Common::ErrorInterceptor.new
87
+ @stub = Stately::Auth::AuthService::Stub.new(nil, nil, channel_override: @channel,
88
+ interceptors: [error_interceptor])
89
+ end
90
+
91
+ # Fetch a new token from the StatelyDB API
92
+ # @return [TokenResult] The fetched TokenResult
93
+ def fetch
94
+ resp = @stub.get_auth_token(Stately::Auth::GetAuthTokenRequest.new(access_key: @access_key))
95
+ TokenResult.new(token: resp.auth_token, expires_in_secs: resp.expires_in_s)
96
+ end
97
+
98
+ def close
99
+ @channel&.close
100
+ end
101
+ end
102
+ end
103
+ end
104
+ end
data/lib/statelydb.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "api/db/service_services_pb"
4
- require "common/auth/auth0_token_provider"
4
+ require "common/auth/auth_token_provider"
5
5
  require "common/auth/interceptor"
6
6
  require "common/net/conn"
7
7
  require "common/error_interceptor"
@@ -30,7 +30,7 @@ module StatelyDB
30
30
  # @param region [String] the region to connect to.
31
31
  def initialize(store_id:,
32
32
  schema:,
33
- token_provider: Common::Auth::Auth0TokenProvider.new,
33
+ token_provider: Common::Auth::AuthTokenProvider.new,
34
34
  endpoint: nil,
35
35
  region: nil)
36
36
  if store_id.nil?
data/sig/statelydb.rbi CHANGED
@@ -213,7 +213,7 @@ module StatelyDB
213
213
  region: T.nilable(String)
214
214
  ).void
215
215
  end
216
- def initialize(store_id:, schema:, token_provider: Common::Auth::Auth0TokenProvider.new, endpoint: nil, region: nil); end
216
+ def initialize(store_id:, schema:, token_provider: Common::Auth::AuthTokenProvider.new, endpoint: nil, region: nil); end
217
217
 
218
218
  # _@return_ — nil
219
219
  sig { void }
@@ -479,7 +479,7 @@ module StatelyDB
479
479
  class Interceptor < GRPC::ClientInterceptor
480
480
  # _@param_ `token_provider` — The token provider to use for authentication
481
481
  sig { params(token_provider: TokenProvider).void }
482
- def initialize(token_provider: Auth0TokenProvider.new); end
482
+ def initialize(token_provider: AuthTokenProvider.new); end
483
483
 
484
484
  # gRPC client unary interceptor
485
485
  #
@@ -572,6 +572,86 @@ module StatelyDB
572
572
  def add_jwt_to_grpc_request(metadata:); end
573
573
  end
574
574
 
575
+ # Result from a token fetch operation
576
+ class TokenResult
577
+ # Create a new TokenResult
578
+ #
579
+ # _@param_ `token` — The access token
580
+ #
581
+ # _@param_ `expires_in_secs` — The number of seconds until the token expires
582
+ sig { params(token: String, expires_in_secs: Integer).void }
583
+ def initialize(token:, expires_in_secs:); end
584
+
585
+ # Returns the value of attribute token.
586
+ sig { returns(T.untyped) }
587
+ attr_reader :token
588
+
589
+ # Returns the value of attribute expires_in_secs.
590
+ sig { returns(T.untyped) }
591
+ attr_reader :expires_in_secs
592
+ end
593
+
594
+ # TokenFetcher is an abstract base class that should be extended
595
+ # for individual token fetcher implementations
596
+ class TokenFetcher
597
+ # Get the current access token
598
+ #
599
+ # _@return_ — The fetched TokenResult
600
+ sig { returns(TokenResult) }
601
+ def fetch; end
602
+
603
+ # Close the token provider and kill any background operations
604
+ sig { returns(T.untyped) }
605
+ def close; end
606
+ end
607
+
608
+ # Auth0TokenFetcher is a TokenFetcher that fetches tokens from an Auth0 server
609
+ class Auth0TokenFetcher < StatelyDB::Common::Auth::TokenFetcher
610
+ # _@param_ `origin` — The origin of the OAuth server
611
+ #
612
+ # _@param_ `audience` — The OAuth Audience for the token
613
+ #
614
+ # _@param_ `client_secret` — The StatelyDB client secret credential
615
+ #
616
+ # _@param_ `client_id` — The StatelyDB client ID credential
617
+ sig do
618
+ params(
619
+ origin: String,
620
+ audience: String,
621
+ client_secret: String,
622
+ client_id: String
623
+ ).void
624
+ end
625
+ def initialize(origin:, audience:, client_secret:, client_id:); end
626
+
627
+ # Fetch a new token from auth0
628
+ #
629
+ # _@return_ — The fetched TokenResult
630
+ sig { returns(TokenResult) }
631
+ def fetch; end
632
+
633
+ sig { returns(T.untyped) }
634
+ def close; end
635
+ end
636
+
637
+ # StatelyAccessTokenFetcher is a TokenFetcher that fetches tokens from the StatelyDB API
638
+ class StatelyAccessTokenFetcher < StatelyDB::Common::Auth::TokenFetcher
639
+ # _@param_ `origin` — The origin of the OAuth server
640
+ #
641
+ # _@param_ `access_key` — The StatelyDB access key credential
642
+ sig { params(origin: String, access_key: String).void }
643
+ def initialize(origin:, access_key:); end
644
+
645
+ # Fetch a new token from the StatelyDB API
646
+ #
647
+ # _@return_ — The fetched TokenResult
648
+ sig { returns(TokenResult) }
649
+ def fetch; end
650
+
651
+ sig { returns(T.untyped) }
652
+ def close; end
653
+ end
654
+
575
655
  # TokenProvider is an abstract base class that should be extended
576
656
  # for individual token provider implementations
577
657
  class TokenProvider
@@ -592,7 +672,7 @@ module StatelyDB
592
672
  # which vends tokens from auth0 with the given client_id and client_secret.
593
673
  # It will default to using the values of `STATELY_CLIENT_ID` and `STATELY_CLIENT_SECRET` if
594
674
  # no credentials are explicitly passed and will throw an error if none are found.
595
- class Auth0TokenProvider < StatelyDB::Common::Auth::TokenProvider
675
+ class AuthTokenProvider < StatelyDB::Common::Auth::TokenProvider
596
676
  # _@param_ `origin` — The origin of the OAuth server
597
677
  #
598
678
  # _@param_ `audience` — The OAuth Audience for the token
@@ -600,15 +680,18 @@ module StatelyDB
600
680
  # _@param_ `client_secret` — The StatelyDB client secret credential
601
681
  #
602
682
  # _@param_ `client_id` — The StatelyDB client ID credential
683
+ #
684
+ # _@param_ `access_key` — The StatelyDB access key credential
603
685
  sig do
604
686
  params(
605
687
  origin: String,
606
688
  audience: String,
607
689
  client_secret: String,
608
- client_id: String
690
+ client_id: String,
691
+ access_key: String
609
692
  ).void
610
693
  end
611
- def initialize(origin: "https://oauth.stately.cloud", audience: "api.stately.cloud", client_secret: ENV.fetch("STATELY_CLIENT_SECRET"), client_id: ENV.fetch("STATELY_CLIENT_ID")); end
694
+ def initialize(origin: "https://oauth.stately.cloud", audience: "api.stately.cloud", client_secret: ENV.fetch("STATELY_CLIENT_SECRET", nil), client_id: ENV.fetch("STATELY_CLIENT_ID", nil), access_key: ENV.fetch("STATELY_ACCESS_KEY", nil)); end
612
695
 
613
696
  # Close the token provider and kill any background operations
614
697
  # This just invokes the close method on the actor which should do the cleanup
@@ -636,10 +719,11 @@ module StatelyDB
636
719
  origin: String,
637
720
  audience: String,
638
721
  client_secret: String,
639
- client_id: String
722
+ client_id: String,
723
+ access_key: T.untyped
640
724
  ).void
641
725
  end
642
- def initialize(origin:, audience:, client_secret:, client_id:); end
726
+ def initialize(origin:, audience:, client_secret:, client_id:, access_key:); end
643
727
 
644
728
  # Initialize the actor. This runs on the actor thread which means
645
729
  # we can dispatch async operations here.
@@ -675,9 +759,25 @@ module StatelyDB
675
759
  # _@return_ — The new access token
676
760
  sig { returns(String) }
677
761
  def refresh_token_impl; end
762
+ end
763
+
764
+ # Persistent state for the token provider
765
+ class TokenState
766
+ # Create a new TokenState
767
+ #
768
+ # _@param_ `token` — The access token
769
+ #
770
+ # _@param_ `expires_at_unix_secs` — The unix timestamp when the token expires
771
+ sig { params(token: String, expires_at_unix_secs: Integer).void }
772
+ def initialize(token:, expires_at_unix_secs:); end
773
+
774
+ # Returns the value of attribute token.
775
+ sig { returns(T.untyped) }
776
+ attr_reader :token
678
777
 
778
+ # Returns the value of attribute expires_at_unix_secs.
679
779
  sig { returns(T.untyped) }
680
- def make_auth0_request; end
780
+ attr_reader :expires_at_unix_secs
681
781
  end
682
782
  end
683
783
  end
@@ -1069,6 +1169,22 @@ module Stately
1069
1169
  end
1070
1170
  end
1071
1171
 
1172
+ module Auth
1173
+ GetAuthTokenRequest = T.let(::Google::Protobuf::DescriptorPool.generated_pool.lookup("stately.auth.GetAuthTokenRequest").msgclass, T.untyped)
1174
+ GetAuthTokenResponse = T.let(::Google::Protobuf::DescriptorPool.generated_pool.lookup("stately.auth.GetAuthTokenResponse").msgclass, T.untyped)
1175
+
1176
+ module AuthService
1177
+ Stub = T.let(Service.rpc_stub_class, T.untyped)
1178
+
1179
+ # AuthService is the service for vending access tokens used to connect to
1180
+ # StatelyDB. This API is meant to be used from SDKs. Access Keys are created
1181
+ # and managed from the stately.dbmanagement.UserService.
1182
+ class Service
1183
+ include GRPC::GenericService
1184
+ end
1185
+ end
1186
+ end
1187
+
1072
1188
  module Errors
1073
1189
  StatelyErrorDetails = T.let(::Google::Protobuf::DescriptorPool.generated_pool.lookup("stately.errors.StatelyErrorDetails").msgclass, T.untyped)
1074
1190
  end
data/sig/statelydb.rbs CHANGED
@@ -496,6 +496,73 @@ module StatelyDB
496
496
  def add_jwt_to_grpc_request: (metadata: ::Hash[untyped, untyped]) -> void
497
497
  end
498
498
 
499
+ # Result from a token fetch operation
500
+ class TokenResult
501
+ # Create a new TokenResult
502
+ #
503
+ # _@param_ `token` — The access token
504
+ #
505
+ # _@param_ `expires_in_secs` — The number of seconds until the token expires
506
+ def initialize: (token: String, expires_in_secs: Integer) -> void
507
+
508
+ # Returns the value of attribute token.
509
+ attr_reader token: untyped
510
+
511
+ # Returns the value of attribute expires_in_secs.
512
+ attr_reader expires_in_secs: untyped
513
+ end
514
+
515
+ # TokenFetcher is an abstract base class that should be extended
516
+ # for individual token fetcher implementations
517
+ class TokenFetcher
518
+ # Get the current access token
519
+ #
520
+ # _@return_ — The fetched TokenResult
521
+ def fetch: () -> TokenResult
522
+
523
+ # Close the token provider and kill any background operations
524
+ def close: () -> untyped
525
+ end
526
+
527
+ # Auth0TokenFetcher is a TokenFetcher that fetches tokens from an Auth0 server
528
+ class Auth0TokenFetcher < StatelyDB::Common::Auth::TokenFetcher
529
+ # _@param_ `origin` — The origin of the OAuth server
530
+ #
531
+ # _@param_ `audience` — The OAuth Audience for the token
532
+ #
533
+ # _@param_ `client_secret` — The StatelyDB client secret credential
534
+ #
535
+ # _@param_ `client_id` — The StatelyDB client ID credential
536
+ def initialize: (
537
+ origin: String,
538
+ audience: String,
539
+ client_secret: String,
540
+ client_id: String
541
+ ) -> void
542
+
543
+ # Fetch a new token from auth0
544
+ #
545
+ # _@return_ — The fetched TokenResult
546
+ def fetch: () -> TokenResult
547
+
548
+ def close: () -> untyped
549
+ end
550
+
551
+ # StatelyAccessTokenFetcher is a TokenFetcher that fetches tokens from the StatelyDB API
552
+ class StatelyAccessTokenFetcher < StatelyDB::Common::Auth::TokenFetcher
553
+ # _@param_ `origin` — The origin of the OAuth server
554
+ #
555
+ # _@param_ `access_key` — The StatelyDB access key credential
556
+ def initialize: (origin: String, access_key: String) -> void
557
+
558
+ # Fetch a new token from the StatelyDB API
559
+ #
560
+ # _@return_ — The fetched TokenResult
561
+ def fetch: () -> TokenResult
562
+
563
+ def close: () -> untyped
564
+ end
565
+
499
566
  # TokenProvider is an abstract base class that should be extended
500
567
  # for individual token provider implementations
501
568
  class TokenProvider
@@ -514,7 +581,7 @@ module StatelyDB
514
581
  # which vends tokens from auth0 with the given client_id and client_secret.
515
582
  # It will default to using the values of `STATELY_CLIENT_ID` and `STATELY_CLIENT_SECRET` if
516
583
  # no credentials are explicitly passed and will throw an error if none are found.
517
- class Auth0TokenProvider < StatelyDB::Common::Auth::TokenProvider
584
+ class AuthTokenProvider < StatelyDB::Common::Auth::TokenProvider
518
585
  # _@param_ `origin` — The origin of the OAuth server
519
586
  #
520
587
  # _@param_ `audience` — The OAuth Audience for the token
@@ -522,11 +589,14 @@ module StatelyDB
522
589
  # _@param_ `client_secret` — The StatelyDB client secret credential
523
590
  #
524
591
  # _@param_ `client_id` — The StatelyDB client ID credential
592
+ #
593
+ # _@param_ `access_key` — The StatelyDB access key credential
525
594
  def initialize: (
526
595
  ?origin: String,
527
596
  ?audience: String,
528
597
  ?client_secret: String,
529
- ?client_id: String
598
+ ?client_id: String,
599
+ ?access_key: String
530
600
  ) -> void
531
601
 
532
602
  # Close the token provider and kill any background operations
@@ -552,7 +622,8 @@ module StatelyDB
552
622
  origin: String,
553
623
  audience: String,
554
624
  client_secret: String,
555
- client_id: String
625
+ client_id: String,
626
+ access_key: untyped
556
627
  ) -> void
557
628
 
558
629
  # Initialize the actor. This runs on the actor thread which means
@@ -583,8 +654,22 @@ module StatelyDB
583
654
  #
584
655
  # _@return_ — The new access token
585
656
  def refresh_token_impl: () -> String
657
+ end
586
658
 
587
- def make_auth0_request: () -> untyped
659
+ # Persistent state for the token provider
660
+ class TokenState
661
+ # Create a new TokenState
662
+ #
663
+ # _@param_ `token` — The access token
664
+ #
665
+ # _@param_ `expires_at_unix_secs` — The unix timestamp when the token expires
666
+ def initialize: (token: String, expires_at_unix_secs: Integer) -> void
667
+
668
+ # Returns the value of attribute token.
669
+ attr_reader token: untyped
670
+
671
+ # Returns the value of attribute expires_at_unix_secs.
672
+ attr_reader expires_at_unix_secs: untyped
588
673
  end
589
674
  end
590
675
  end
@@ -936,6 +1021,22 @@ module Stately
936
1021
  end
937
1022
  end
938
1023
 
1024
+ module Auth
1025
+ GetAuthTokenRequest: untyped
1026
+ GetAuthTokenResponse: untyped
1027
+
1028
+ module AuthService
1029
+ Stub: untyped
1030
+
1031
+ # AuthService is the service for vending access tokens used to connect to
1032
+ # StatelyDB. This API is meant to be used from SDKs. Access Keys are created
1033
+ # and managed from the stately.dbmanagement.UserService.
1034
+ class Service
1035
+ include GRPC::GenericService
1036
+ end
1037
+ end
1038
+ end
1039
+
939
1040
  module Errors
940
1041
  StatelyErrorDetails: untyped
941
1042
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: statelydb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.13.0
4
+ version: 0.14.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stately Cloud, Inc.
@@ -73,6 +73,9 @@ extensions: []
73
73
  extra_rdoc_files: []
74
74
  files:
75
75
  - README.md
76
+ - lib/api/auth/get_auth_token_pb.rb
77
+ - lib/api/auth/service_pb.rb
78
+ - lib/api/auth/service_services_pb.rb
76
79
  - lib/api/db/continue_list_pb.rb
77
80
  - lib/api/db/delete_pb.rb
78
81
  - lib/api/db/get_pb.rb
@@ -87,8 +90,9 @@ files:
87
90
  - lib/api/db/sync_list_pb.rb
88
91
  - lib/api/db/transaction_pb.rb
89
92
  - lib/api/errors/error_details_pb.rb
90
- - lib/common/auth/auth0_token_provider.rb
93
+ - lib/common/auth/auth_token_provider.rb
91
94
  - lib/common/auth/interceptor.rb
95
+ - lib/common/auth/token_fetcher.rb
92
96
  - lib/common/auth/token_provider.rb
93
97
  - lib/common/error_interceptor.rb
94
98
  - lib/common/net/conn.rb