statelydb 0.13.0 → 0.14.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/api/auth/get_auth_token_pb.rb +18 -0
- data/lib/api/auth/service_pb.rb +18 -0
- data/lib/api/auth/service_services_pb.rb +29 -0
- data/lib/common/auth/{auth0_token_provider.rb → auth_token_provider.rb} +52 -44
- data/lib/common/auth/interceptor.rb +1 -1
- data/lib/common/auth/token_fetcher.rb +104 -0
- data/lib/statelydb.rb +2 -2
- data/sig/statelydb.rbi +124 -8
- data/sig/statelydb.rbs +105 -4
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a723737fdce6e8ad2bec8937cfd79f6d968df0fc3e9e747c64e18af9ce769601
|
4
|
+
data.tar.gz: 1f0279a8b9507f4cffacc360ab82e2289471a40de39bd3891f0c7db5c63877c6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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 "
|
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
|
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
|
-
@
|
76
|
-
|
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
|
-
@
|
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
|
-
@
|
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 @
|
111
|
-
return "", false if @expires_at_unix_secs.
|
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
|
-
[@
|
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
|
-
|
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
|
-
|
162
|
-
|
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
|
-
|
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
|
-
|
196
|
+
@token_state.token
|
186
197
|
end
|
187
198
|
end
|
199
|
+
end
|
188
200
|
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
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:
|
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/
|
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::
|
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::
|
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:
|
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
|
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
|
-
|
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
|
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
|
-
|
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.
|
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/
|
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
|